diff options
author | Richard Cochran <richardcochran@gmail.com> | 2012-11-14 09:07:56 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-14 22:09:06 -0500 |
commit | 549985ee9c723fea8fd7759b5046fb8249896d50 (patch) | |
tree | 9207050df4ddd14cd94ab216dd5e006cba98d544 /drivers/net/ethernet/ti/cpsw.c | |
parent | 1fb19aa730e400e474b562c55227849060549733 (diff) |
cpsw: simplify the setup of the register pointers
Instead of having a host of different register offsets in the device tree,
this patch simplifies the CPSW code by letting the driver set the proper
register offsets automatically, based on the CPSW version.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw.c')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 242 |
1 files changed, 103 insertions, 139 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 7007abaf8c82..0da9c753c567 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -80,6 +80,29 @@ do { \ #define CPSW_VERSION_1 0x19010a #define CPSW_VERSION_2 0x19010c + +#define HOST_PORT_NUM 0 +#define SLIVER_SIZE 0x40 + +#define CPSW1_HOST_PORT_OFFSET 0x028 +#define CPSW1_SLAVE_OFFSET 0x050 +#define CPSW1_SLAVE_SIZE 0x040 +#define CPSW1_CPDMA_OFFSET 0x100 +#define CPSW1_STATERAM_OFFSET 0x200 +#define CPSW1_CPTS_OFFSET 0x500 +#define CPSW1_ALE_OFFSET 0x600 +#define CPSW1_SLIVER_OFFSET 0x700 + +#define CPSW2_HOST_PORT_OFFSET 0x108 +#define CPSW2_SLAVE_OFFSET 0x200 +#define CPSW2_SLAVE_SIZE 0x100 +#define CPSW2_CPDMA_OFFSET 0x800 +#define CPSW2_STATERAM_OFFSET 0xa00 +#define CPSW2_CPTS_OFFSET 0xc00 +#define CPSW2_ALE_OFFSET 0xd00 +#define CPSW2_SLIVER_OFFSET 0xd80 +#define CPSW2_BD_OFFSET 0x2000 + #define CPDMA_RXTHRESH 0x0c0 #define CPDMA_RXFREE 0x0e0 #define CPDMA_TXHDP 0x00 @@ -87,21 +110,6 @@ do { \ #define CPDMA_TXCP 0x40 #define CPDMA_RXCP 0x60 -#define cpsw_dma_regs(base, offset) \ - (void __iomem *)((base) + (offset)) -#define cpsw_dma_rxthresh(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_RXTHRESH) -#define cpsw_dma_rxfree(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_RXFREE) -#define cpsw_dma_txhdp(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_TXHDP) -#define cpsw_dma_rxhdp(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_RXHDP) -#define cpsw_dma_txcp(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_TXCP) -#define cpsw_dma_rxcp(base, offset) \ - (void __iomem *)((base) + (offset) + CPDMA_RXCP) - #define CPSW_POLL_WEIGHT 64 #define CPSW_MIN_PACKET_SIZE 60 #define CPSW_MAX_PACKET_SIZE (1500 + 14 + 4 + 4) @@ -629,8 +637,7 @@ static int cpsw_ndo_open(struct net_device *ndev) pm_runtime_get_sync(&priv->pdev->dev); - reg = __raw_readl(&priv->regs->id_ver); - priv->version = reg; + reg = priv->version; dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), @@ -995,15 +1002,16 @@ static const struct ethtool_ops cpsw_ethtool_ops = { .get_ts_info = cpsw_get_ts_info, }; -static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) +static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, + u32 slave_reg_ofs, u32 sliver_reg_ofs) { void __iomem *regs = priv->regs; int slave_num = slave->slave_num; struct cpsw_slave_data *data = priv->data.slave_data + slave_num; slave->data = data; - slave->regs = regs + data->slave_reg_ofs; - slave->sliver = regs + data->sliver_reg_ofs; + slave->regs = regs + slave_reg_ofs; + slave->sliver = regs + sliver_reg_ofs; } static int cpsw_probe_dt(struct cpsw_platform_data *data, @@ -1051,8 +1059,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, return -EINVAL; } - data->no_bd_ram = of_property_read_bool(node, "no_bd_ram"); - if (of_property_read_u32(node, "cpdma_channels", &prop)) { pr_err("Missing cpdma_channels property in the DT.\n"); ret = -EINVAL; @@ -1060,34 +1066,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } data->channels = prop; - if (of_property_read_u32(node, "host_port_no", &prop)) { - pr_err("Missing host_port_no property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->host_port_num = prop; - - if (of_property_read_u32(node, "cpdma_reg_ofs", &prop)) { - pr_err("Missing cpdma_reg_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->cpdma_reg_ofs = prop; - - if (of_property_read_u32(node, "cpdma_sram_ofs", &prop)) { - pr_err("Missing cpdma_sram_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->cpdma_sram_ofs = prop; - - if (of_property_read_u32(node, "ale_reg_ofs", &prop)) { - pr_err("Missing ale_reg_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->ale_reg_ofs = prop; - if (of_property_read_u32(node, "ale_entries", &prop)) { pr_err("Missing ale_entries property in the DT.\n"); ret = -EINVAL; @@ -1095,34 +1073,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } data->ale_entries = prop; - if (of_property_read_u32(node, "host_port_reg_ofs", &prop)) { - pr_err("Missing host_port_reg_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->host_port_reg_ofs = prop; - - if (of_property_read_u32(node, "hw_stats_reg_ofs", &prop)) { - pr_err("Missing hw_stats_reg_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->hw_stats_reg_ofs = prop; - - if (of_property_read_u32(node, "cpts_reg_ofs", &prop)) { - pr_err("Missing cpts_reg_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->cpts_reg_ofs = prop; - - if (of_property_read_u32(node, "bd_ram_ofs", &prop)) { - pr_err("Missing bd_ram_ofs property in the DT.\n"); - ret = -EINVAL; - goto error_ret; - } - data->bd_ram_ofs = prop; - if (of_property_read_u32(node, "bd_ram_size", &prop)) { pr_err("Missing bd_ram_size property in the DT.\n"); ret = -EINVAL; @@ -1144,33 +1094,34 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, } data->mac_control = prop; + /* + * Populate all the child nodes here... + */ + ret = of_platform_populate(node, NULL, NULL, &pdev->dev); + /* We do not want to force this, as in some cases may not have child */ + if (ret) + pr_warn("Doesn't have any child node\n"); + for_each_node_by_name(slave_node, "slave") { struct cpsw_slave_data *slave_data = data->slave_data + i; - const char *phy_id = NULL; const void *mac_addr = NULL; - - if (of_property_read_string(slave_node, "phy_id", &phy_id)) { + u32 phyid; + int lenp; + const __be32 *parp; + struct device_node *mdio_node; + struct platform_device *mdio; + + parp = of_get_property(slave_node, "phy_id", &lenp); + if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) { pr_err("Missing slave[%d] phy_id property\n", i); ret = -EINVAL; goto error_ret; } - slave_data->phy_id = phy_id; - - if (of_property_read_u32(slave_node, "slave_reg_ofs", &prop)) { - pr_err("Missing slave[%d] slave_reg_ofs property\n", i); - ret = -EINVAL; - goto error_ret; - } - slave_data->slave_reg_ofs = prop; - - if (of_property_read_u32(slave_node, "sliver_reg_ofs", - &prop)) { - pr_err("Missing slave[%d] sliver_reg_ofs property\n", - i); - ret = -EINVAL; - goto error_ret; - } - slave_data->sliver_reg_ofs = prop; + mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); + phyid = be32_to_cpup(parp+1); + mdio = of_find_device_by_node(mdio_node); + snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), + PHY_ID_FMT, mdio->name, phyid); mac_addr = of_get_mac_address(slave_node); if (mac_addr) @@ -1179,14 +1130,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, i++; } - /* - * Populate all the child nodes here... - */ - ret = of_platform_populate(node, NULL, NULL, &pdev->dev); - /* We do not want to force this, as in some cases may not have child */ - if (ret) - pr_warn("Doesn't have any child node\n"); - return 0; error_ret: @@ -1201,8 +1144,9 @@ static int __devinit cpsw_probe(struct platform_device *pdev) struct cpsw_priv *priv; struct cpdma_params dma_params; struct cpsw_ale_params ale_params; - void __iomem *regs; + void __iomem *ss_regs, *wr_regs; struct resource *res; + u32 slave_offset, sliver_offset, slave_size; int ret = 0, i, k = 0; ndev = alloc_etherdev(sizeof(struct cpsw_priv)); @@ -1270,15 +1214,14 @@ static int __devinit cpsw_probe(struct platform_device *pdev) ret = -ENXIO; goto clean_clk_ret; } - regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); - if (!regs) { + ss_regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); + if (!ss_regs) { dev_err(priv->dev, "unable to map i/o region\n"); goto clean_cpsw_iores_ret; } - priv->regs = regs; - priv->host_port = data->host_port_num; - priv->host_port_regs = regs + data->host_port_reg_ofs; - priv->cpts.reg = regs + data->cpts_reg_ofs; + priv->regs = ss_regs; + priv->version = __raw_readl(&priv->regs->id_ver); + priv->host_port = HOST_PORT_NUM; priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!priv->cpsw_wr_res) { @@ -1292,32 +1235,59 @@ static int __devinit cpsw_probe(struct platform_device *pdev) ret = -ENXIO; goto clean_iomap_ret; } - regs = ioremap(priv->cpsw_wr_res->start, + wr_regs = ioremap(priv->cpsw_wr_res->start, resource_size(priv->cpsw_wr_res)); - if (!regs) { + if (!wr_regs) { dev_err(priv->dev, "unable to map i/o region\n"); goto clean_cpsw_wr_iores_ret; } - priv->wr_regs = regs; - - for_each_slave(priv, cpsw_slave_init, priv); + priv->wr_regs = wr_regs; memset(&dma_params, 0, sizeof(dma_params)); + memset(&ale_params, 0, sizeof(ale_params)); + + switch (priv->version) { + case CPSW_VERSION_1: + priv->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET; + priv->cpts.reg = ss_regs + CPSW1_CPTS_OFFSET; + dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET; + dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET; + ale_params.ale_regs = ss_regs + CPSW1_ALE_OFFSET; + slave_offset = CPSW1_SLAVE_OFFSET; + slave_size = CPSW1_SLAVE_SIZE; + sliver_offset = CPSW1_SLIVER_OFFSET; + dma_params.desc_mem_phys = 0; + break; + case CPSW_VERSION_2: + priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET; + priv->cpts.reg = ss_regs + CPSW2_CPTS_OFFSET; + dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET; + dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET; + ale_params.ale_regs = ss_regs + CPSW2_ALE_OFFSET; + slave_offset = CPSW2_SLAVE_OFFSET; + slave_size = CPSW2_SLAVE_SIZE; + sliver_offset = CPSW2_SLIVER_OFFSET; + dma_params.desc_mem_phys = + (u32 __force) priv->cpsw_res->start + CPSW2_BD_OFFSET; + break; + default: + dev_err(priv->dev, "unknown version 0x%08x\n", priv->version); + ret = -ENODEV; + goto clean_cpsw_wr_iores_ret; + } + for (i = 0; i < priv->data.slaves; i++) { + struct cpsw_slave *slave = &priv->slaves[i]; + cpsw_slave_init(slave, priv, slave_offset, sliver_offset); + slave_offset += slave_size; + sliver_offset += SLIVER_SIZE; + } + dma_params.dev = &pdev->dev; - dma_params.dmaregs = cpsw_dma_regs((u32)priv->regs, - data->cpdma_reg_ofs); - dma_params.rxthresh = cpsw_dma_rxthresh((u32)priv->regs, - data->cpdma_reg_ofs); - dma_params.rxfree = cpsw_dma_rxfree((u32)priv->regs, - data->cpdma_reg_ofs); - dma_params.txhdp = cpsw_dma_txhdp((u32)priv->regs, - data->cpdma_sram_ofs); - dma_params.rxhdp = cpsw_dma_rxhdp((u32)priv->regs, - data->cpdma_sram_ofs); - dma_params.txcp = cpsw_dma_txcp((u32)priv->regs, - data->cpdma_sram_ofs); - dma_params.rxcp = cpsw_dma_rxcp((u32)priv->regs, - data->cpdma_sram_ofs); + dma_params.rxthresh = dma_params.dmaregs + CPDMA_RXTHRESH; + dma_params.rxfree = dma_params.dmaregs + CPDMA_RXFREE; + dma_params.rxhdp = dma_params.txhdp + CPDMA_RXHDP; + dma_params.txcp = dma_params.txhdp + CPDMA_TXCP; + dma_params.rxcp = dma_params.txhdp + CPDMA_RXCP; dma_params.num_chan = data->channels; dma_params.has_soft_reset = true; @@ -1325,10 +1295,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev) dma_params.desc_mem_size = data->bd_ram_size; dma_params.desc_align = 16; dma_params.has_ext_regs = true; - dma_params.desc_mem_phys = data->no_bd_ram ? 0 : - (u32 __force)priv->cpsw_res->start + data->bd_ram_ofs; - dma_params.desc_hw_addr = data->hw_ram_addr ? - data->hw_ram_addr : dma_params.desc_mem_phys ; + dma_params.desc_hw_addr = dma_params.desc_mem_phys; priv->dma = cpdma_ctlr_create(&dma_params); if (!priv->dma) { @@ -1348,10 +1315,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev) goto clean_dma_ret; } - memset(&ale_params, 0, sizeof(ale_params)); ale_params.dev = &ndev->dev; - ale_params.ale_regs = (void *)((u32)priv->regs) + - ((u32)data->ale_reg_ofs); ale_params.ale_ageout = ale_ageout; ale_params.ale_entries = data->ale_entries; ale_params.ale_ports = data->slaves; |