forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.2 KiB
136 lines
3.2 KiB
/* SPDX-License-Identifier: GPL-2.0+ |
|
* Microchip Sparx5 SerDes driver |
|
* |
|
* Copyright (c) 2020 Microchip Technology Inc. |
|
*/ |
|
|
|
#ifndef _SPARX5_SERDES_H_ |
|
#define _SPARX5_SERDES_H_ |
|
|
|
#include "sparx5_serdes_regs.h" |
|
|
|
#define SPX5_SERDES_MAX 33 |
|
|
|
enum sparx5_serdes_type { |
|
SPX5_SDT_6G = 6, |
|
SPX5_SDT_10G = 10, |
|
SPX5_SDT_25G = 25, |
|
}; |
|
|
|
enum sparx5_serdes_mode { |
|
SPX5_SD_MODE_NONE, |
|
SPX5_SD_MODE_2G5, |
|
SPX5_SD_MODE_QSGMII, |
|
SPX5_SD_MODE_100FX, |
|
SPX5_SD_MODE_1000BASEX, |
|
SPX5_SD_MODE_SFI, |
|
}; |
|
|
|
struct sparx5_serdes_private { |
|
struct device *dev; |
|
void __iomem *regs[NUM_TARGETS]; |
|
struct phy *phys[SPX5_SERDES_MAX]; |
|
bool cmu_enabled; |
|
unsigned long coreclock; |
|
}; |
|
|
|
struct sparx5_serdes_macro { |
|
struct sparx5_serdes_private *priv; |
|
u32 sidx; |
|
u32 stpidx; |
|
enum sparx5_serdes_type serdestype; |
|
enum sparx5_serdes_mode serdesmode; |
|
phy_interface_t portmode; |
|
int speed; |
|
enum phy_media media; |
|
}; |
|
|
|
/* Read, Write and modify registers content. |
|
* The register definition macros start at the id |
|
*/ |
|
static inline void __iomem *sdx5_addr(void __iomem *base[], |
|
int id, int tinst, int tcnt, |
|
int gbase, int ginst, |
|
int gcnt, int gwidth, |
|
int raddr, int rinst, |
|
int rcnt, int rwidth) |
|
{ |
|
WARN_ON((tinst) >= tcnt); |
|
WARN_ON((ginst) >= gcnt); |
|
WARN_ON((rinst) >= rcnt); |
|
return base[id + (tinst)] + |
|
gbase + ((ginst) * gwidth) + |
|
raddr + ((rinst) * rwidth); |
|
} |
|
|
|
static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base, |
|
int gbase, int ginst, |
|
int gcnt, int gwidth, |
|
int raddr, int rinst, |
|
int rcnt, int rwidth) |
|
{ |
|
WARN_ON((ginst) >= gcnt); |
|
WARN_ON((rinst) >= rcnt); |
|
return base + |
|
gbase + ((ginst) * gwidth) + |
|
raddr + ((rinst) * rwidth); |
|
} |
|
|
|
static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv, |
|
int id, int tinst, int tcnt, |
|
int gbase, int ginst, int gcnt, int gwidth, |
|
int raddr, int rinst, int rcnt, int rwidth) |
|
{ |
|
u32 nval; |
|
void __iomem *addr = |
|
sdx5_addr(priv->regs, id, tinst, tcnt, |
|
gbase, ginst, gcnt, gwidth, |
|
raddr, rinst, rcnt, rwidth); |
|
nval = readl(addr); |
|
nval = (nval & ~mask) | (val & mask); |
|
writel(nval, addr); |
|
} |
|
|
|
static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem, |
|
int id, int tinst, int tcnt, |
|
int gbase, int ginst, int gcnt, int gwidth, |
|
int raddr, int rinst, int rcnt, int rwidth) |
|
{ |
|
u32 nval; |
|
void __iomem *addr = |
|
sdx5_inst_baseaddr(iomem, |
|
gbase, ginst, gcnt, gwidth, |
|
raddr, rinst, rcnt, rwidth); |
|
nval = readl(addr); |
|
nval = (nval & ~mask) | (val & mask); |
|
writel(nval, addr); |
|
} |
|
|
|
static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr) |
|
{ |
|
u32 nval; |
|
|
|
nval = readl(addr); |
|
nval = (nval & ~mask) | (val & mask); |
|
writel(nval, addr); |
|
} |
|
|
|
static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv, |
|
int id, int tinst) |
|
{ |
|
return priv->regs[id + tinst]; |
|
} |
|
|
|
static inline void __iomem *sdx5_inst_addr(void __iomem *iomem, |
|
int id, int tinst, int tcnt, |
|
int gbase, |
|
int ginst, int gcnt, int gwidth, |
|
int raddr, |
|
int rinst, int rcnt, int rwidth) |
|
{ |
|
return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth, |
|
raddr, rinst, rcnt, rwidth); |
|
} |
|
|
|
|
|
#endif /* _SPARX5_SERDES_REGS_H_ */
|
|
|