aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2012-11-14 04:07:56 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-14 22:09:06 -0500
commit549985ee9c723fea8fd7759b5046fb8249896d50 (patch)
tree9207050df4ddd14cd94ab216dd5e006cba98d544 /drivers/net
parent1fb19aa730e400e474b562c55227849060549733 (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')
-rw-r--r--drivers/net/ethernet/ti/cpsw.c242
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 { \
80 80
81#define CPSW_VERSION_1 0x19010a 81#define CPSW_VERSION_1 0x19010a
82#define CPSW_VERSION_2 0x19010c 82#define CPSW_VERSION_2 0x19010c
83
84#define HOST_PORT_NUM 0
85#define SLIVER_SIZE 0x40
86
87#define CPSW1_HOST_PORT_OFFSET 0x028
88#define CPSW1_SLAVE_OFFSET 0x050
89#define CPSW1_SLAVE_SIZE 0x040
90#define CPSW1_CPDMA_OFFSET 0x100
91#define CPSW1_STATERAM_OFFSET 0x200
92#define CPSW1_CPTS_OFFSET 0x500
93#define CPSW1_ALE_OFFSET 0x600
94#define CPSW1_SLIVER_OFFSET 0x700
95
96#define CPSW2_HOST_PORT_OFFSET 0x108
97#define CPSW2_SLAVE_OFFSET 0x200
98#define CPSW2_SLAVE_SIZE 0x100
99#define CPSW2_CPDMA_OFFSET 0x800
100#define CPSW2_STATERAM_OFFSET 0xa00
101#define CPSW2_CPTS_OFFSET 0xc00
102#define CPSW2_ALE_OFFSET 0xd00
103#define CPSW2_SLIVER_OFFSET 0xd80
104#define CPSW2_BD_OFFSET 0x2000
105
83#define CPDMA_RXTHRESH 0x0c0 106#define CPDMA_RXTHRESH 0x0c0
84#define CPDMA_RXFREE 0x0e0 107#define CPDMA_RXFREE 0x0e0
85#define CPDMA_TXHDP 0x00 108#define CPDMA_TXHDP 0x00
@@ -87,21 +110,6 @@ do { \
87#define CPDMA_TXCP 0x40 110#define CPDMA_TXCP 0x40
88#define CPDMA_RXCP 0x60 111#define CPDMA_RXCP 0x60
89 112
90#define cpsw_dma_regs(base, offset) \
91 (void __iomem *)((base) + (offset))
92#define cpsw_dma_rxthresh(base, offset) \
93 (void __iomem *)((base) + (offset) + CPDMA_RXTHRESH)
94#define cpsw_dma_rxfree(base, offset) \
95 (void __iomem *)((base) + (offset) + CPDMA_RXFREE)
96#define cpsw_dma_txhdp(base, offset) \
97 (void __iomem *)((base) + (offset) + CPDMA_TXHDP)
98#define cpsw_dma_rxhdp(base, offset) \
99 (void __iomem *)((base) + (offset) + CPDMA_RXHDP)
100#define cpsw_dma_txcp(base, offset) \
101 (void __iomem *)((base) + (offset) + CPDMA_TXCP)
102#define cpsw_dma_rxcp(base, offset) \
103 (void __iomem *)((base) + (offset) + CPDMA_RXCP)
104
105#define CPSW_POLL_WEIGHT 64 113#define CPSW_POLL_WEIGHT 64
106#define CPSW_MIN_PACKET_SIZE 60 114#define CPSW_MIN_PACKET_SIZE 60
107#define CPSW_MAX_PACKET_SIZE (1500 + 14 + 4 + 4) 115#define CPSW_MAX_PACKET_SIZE (1500 + 14 + 4 + 4)
@@ -629,8 +637,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
629 637
630 pm_runtime_get_sync(&priv->pdev->dev); 638 pm_runtime_get_sync(&priv->pdev->dev);
631 639
632 reg = __raw_readl(&priv->regs->id_ver); 640 reg = priv->version;
633 priv->version = reg;
634 641
635 dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", 642 dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n",
636 CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), 643 CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg),
@@ -995,15 +1002,16 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
995 .get_ts_info = cpsw_get_ts_info, 1002 .get_ts_info = cpsw_get_ts_info,
996}; 1003};
997 1004
998static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) 1005static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
1006 u32 slave_reg_ofs, u32 sliver_reg_ofs)
999{ 1007{
1000 void __iomem *regs = priv->regs; 1008 void __iomem *regs = priv->regs;
1001 int slave_num = slave->slave_num; 1009 int slave_num = slave->slave_num;
1002 struct cpsw_slave_data *data = priv->data.slave_data + slave_num; 1010 struct cpsw_slave_data *data = priv->data.slave_data + slave_num;
1003 1011
1004 slave->data = data; 1012 slave->data = data;
1005 slave->regs = regs + data->slave_reg_ofs; 1013 slave->regs = regs + slave_reg_ofs;
1006 slave->sliver = regs + data->sliver_reg_ofs; 1014 slave->sliver = regs + sliver_reg_ofs;
1007} 1015}
1008 1016
1009static int cpsw_probe_dt(struct cpsw_platform_data *data, 1017static int cpsw_probe_dt(struct cpsw_platform_data *data,
@@ -1051,8 +1059,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1051 return -EINVAL; 1059 return -EINVAL;
1052 } 1060 }
1053 1061
1054 data->no_bd_ram = of_property_read_bool(node, "no_bd_ram");
1055
1056 if (of_property_read_u32(node, "cpdma_channels", &prop)) { 1062 if (of_property_read_u32(node, "cpdma_channels", &prop)) {
1057 pr_err("Missing cpdma_channels property in the DT.\n"); 1063 pr_err("Missing cpdma_channels property in the DT.\n");
1058 ret = -EINVAL; 1064 ret = -EINVAL;
@@ -1060,34 +1066,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1060 } 1066 }
1061 data->channels = prop; 1067 data->channels = prop;
1062 1068
1063 if (of_property_read_u32(node, "host_port_no", &prop)) {
1064 pr_err("Missing host_port_no property in the DT.\n");
1065 ret = -EINVAL;
1066 goto error_ret;
1067 }
1068 data->host_port_num = prop;
1069
1070 if (of_property_read_u32(node, "cpdma_reg_ofs", &prop)) {
1071 pr_err("Missing cpdma_reg_ofs property in the DT.\n");
1072 ret = -EINVAL;
1073 goto error_ret;
1074 }
1075 data->cpdma_reg_ofs = prop;
1076
1077 if (of_property_read_u32(node, "cpdma_sram_ofs", &prop)) {
1078 pr_err("Missing cpdma_sram_ofs property in the DT.\n");
1079 ret = -EINVAL;
1080 goto error_ret;
1081 }
1082 data->cpdma_sram_ofs = prop;
1083
1084 if (of_property_read_u32(node, "ale_reg_ofs", &prop)) {
1085 pr_err("Missing ale_reg_ofs property in the DT.\n");
1086 ret = -EINVAL;
1087 goto error_ret;
1088 }
1089 data->ale_reg_ofs = prop;
1090
1091 if (of_property_read_u32(node, "ale_entries", &prop)) { 1069 if (of_property_read_u32(node, "ale_entries", &prop)) {
1092 pr_err("Missing ale_entries property in the DT.\n"); 1070 pr_err("Missing ale_entries property in the DT.\n");
1093 ret = -EINVAL; 1071 ret = -EINVAL;
@@ -1095,34 +1073,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1095 } 1073 }
1096 data->ale_entries = prop; 1074 data->ale_entries = prop;
1097 1075
1098 if (of_property_read_u32(node, "host_port_reg_ofs", &prop)) {
1099 pr_err("Missing host_port_reg_ofs property in the DT.\n");
1100 ret = -EINVAL;
1101 goto error_ret;
1102 }
1103 data->host_port_reg_ofs = prop;
1104
1105 if (of_property_read_u32(node, "hw_stats_reg_ofs", &prop)) {
1106 pr_err("Missing hw_stats_reg_ofs property in the DT.\n");
1107 ret = -EINVAL;
1108 goto error_ret;
1109 }
1110 data->hw_stats_reg_ofs = prop;
1111
1112 if (of_property_read_u32(node, "cpts_reg_ofs", &prop)) {
1113 pr_err("Missing cpts_reg_ofs property in the DT.\n");
1114 ret = -EINVAL;
1115 goto error_ret;
1116 }
1117 data->cpts_reg_ofs = prop;
1118
1119 if (of_property_read_u32(node, "bd_ram_ofs", &prop)) {
1120 pr_err("Missing bd_ram_ofs property in the DT.\n");
1121 ret = -EINVAL;
1122 goto error_ret;
1123 }
1124 data->bd_ram_ofs = prop;
1125
1126 if (of_property_read_u32(node, "bd_ram_size", &prop)) { 1076 if (of_property_read_u32(node, "bd_ram_size", &prop)) {
1127 pr_err("Missing bd_ram_size property in the DT.\n"); 1077 pr_err("Missing bd_ram_size property in the DT.\n");
1128 ret = -EINVAL; 1078 ret = -EINVAL;
@@ -1144,33 +1094,34 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1144 } 1094 }
1145 data->mac_control = prop; 1095 data->mac_control = prop;
1146 1096
1097 /*
1098 * Populate all the child nodes here...
1099 */
1100 ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
1101 /* We do not want to force this, as in some cases may not have child */
1102 if (ret)
1103 pr_warn("Doesn't have any child node\n");
1104
1147 for_each_node_by_name(slave_node, "slave") { 1105 for_each_node_by_name(slave_node, "slave") {
1148 struct cpsw_slave_data *slave_data = data->slave_data + i; 1106 struct cpsw_slave_data *slave_data = data->slave_data + i;
1149 const char *phy_id = NULL;
1150 const void *mac_addr = NULL; 1107 const void *mac_addr = NULL;
1151 1108 u32 phyid;
1152 if (of_property_read_string(slave_node, "phy_id", &phy_id)) { 1109 int lenp;
1110 const __be32 *parp;
1111 struct device_node *mdio_node;
1112 struct platform_device *mdio;
1113
1114 parp = of_get_property(slave_node, "phy_id", &lenp);
1115 if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
1153 pr_err("Missing slave[%d] phy_id property\n", i); 1116 pr_err("Missing slave[%d] phy_id property\n", i);
1154 ret = -EINVAL; 1117 ret = -EINVAL;
1155 goto error_ret; 1118 goto error_ret;
1156 } 1119 }
1157 slave_data->phy_id = phy_id; 1120 mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
1158 1121 phyid = be32_to_cpup(parp+1);
1159 if (of_property_read_u32(slave_node, "slave_reg_ofs", &prop)) { 1122 mdio = of_find_device_by_node(mdio_node);
1160 pr_err("Missing slave[%d] slave_reg_ofs property\n", i); 1123 snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
1161 ret = -EINVAL; 1124 PHY_ID_FMT, mdio->name, phyid);
1162 goto error_ret;
1163 }
1164 slave_data->slave_reg_ofs = prop;
1165
1166 if (of_property_read_u32(slave_node, "sliver_reg_ofs",
1167 &prop)) {
1168 pr_err("Missing slave[%d] sliver_reg_ofs property\n",
1169 i);
1170 ret = -EINVAL;
1171 goto error_ret;
1172 }
1173 slave_data->sliver_reg_ofs = prop;
1174 1125
1175 mac_addr = of_get_mac_address(slave_node); 1126 mac_addr = of_get_mac_address(slave_node);
1176 if (mac_addr) 1127 if (mac_addr)
@@ -1179,14 +1130,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
1179 i++; 1130 i++;
1180 } 1131 }
1181 1132
1182 /*
1183 * Populate all the child nodes here...
1184 */
1185 ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
1186 /* We do not want to force this, as in some cases may not have child */
1187 if (ret)
1188 pr_warn("Doesn't have any child node\n");
1189
1190 return 0; 1133 return 0;
1191 1134
1192error_ret: 1135error_ret:
@@ -1201,8 +1144,9 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
1201 struct cpsw_priv *priv; 1144 struct cpsw_priv *priv;
1202 struct cpdma_params dma_params; 1145 struct cpdma_params dma_params;
1203 struct cpsw_ale_params ale_params; 1146 struct cpsw_ale_params ale_params;
1204 void __iomem *regs; 1147 void __iomem *ss_regs, *wr_regs;
1205 struct resource *res; 1148 struct resource *res;
1149 u32 slave_offset, sliver_offset, slave_size;
1206 int ret = 0, i, k = 0; 1150 int ret = 0, i, k = 0;
1207 1151
1208 ndev = alloc_etherdev(sizeof(struct cpsw_priv)); 1152 ndev = alloc_etherdev(sizeof(struct cpsw_priv));
@@ -1270,15 +1214,14 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
1270 ret = -ENXIO; 1214 ret = -ENXIO;
1271 goto clean_clk_ret; 1215 goto clean_clk_ret;
1272 } 1216 }
1273 regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); 1217 ss_regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res));
1274 if (!regs) { 1218 if (!ss_regs) {
1275 dev_err(priv->dev, "unable to map i/o region\n"); 1219 dev_err(priv->dev, "unable to map i/o region\n");
1276 goto clean_cpsw_iores_ret; 1220 goto clean_cpsw_iores_ret;
1277 } 1221 }
1278 priv->regs = regs; 1222 priv->regs = ss_regs;
1279 priv->host_port = data->host_port_num; 1223 priv->version = __raw_readl(&priv->regs->id_ver);
1280 priv->host_port_regs = regs + data->host_port_reg_ofs; 1224 priv->host_port = HOST_PORT_NUM;
1281 priv->cpts.reg = regs + data->cpts_reg_ofs;
1282 1225
1283 priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1226 priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1284 if (!priv->cpsw_wr_res) { 1227 if (!priv->cpsw_wr_res) {
@@ -1292,32 +1235,59 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
1292 ret = -ENXIO; 1235 ret = -ENXIO;
1293 goto clean_iomap_ret; 1236 goto clean_iomap_ret;
1294 } 1237 }
1295 regs = ioremap(priv->cpsw_wr_res->start, 1238 wr_regs = ioremap(priv->cpsw_wr_res->start,
1296 resource_size(priv->cpsw_wr_res)); 1239 resource_size(priv->cpsw_wr_res));
1297 if (!regs) { 1240 if (!wr_regs) {
1298 dev_err(priv->dev, "unable to map i/o region\n"); 1241 dev_err(priv->dev, "unable to map i/o region\n");
1299 goto clean_cpsw_wr_iores_ret; 1242 goto clean_cpsw_wr_iores_ret;
1300 } 1243 }
1301 priv->wr_regs = regs; 1244 priv->wr_regs = wr_regs;
1302
1303 for_each_slave(priv, cpsw_slave_init, priv);
1304 1245
1305 memset(&dma_params, 0, sizeof(dma_params)); 1246 memset(&dma_params, 0, sizeof(dma_params));
1247 memset(&ale_params, 0, sizeof(ale_params));
1248
1249 switch (priv->version) {
1250 case CPSW_VERSION_1:
1251 priv->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
1252 priv->cpts.reg = ss_regs + CPSW1_CPTS_OFFSET;
1253 dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET;
1254 dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET;
1255 ale_params.ale_regs = ss_regs + CPSW1_ALE_OFFSET;
1256 slave_offset = CPSW1_SLAVE_OFFSET;
1257 slave_size = CPSW1_SLAVE_SIZE;
1258 sliver_offset = CPSW1_SLIVER_OFFSET;
1259 dma_params.desc_mem_phys = 0;
1260 break;
1261 case CPSW_VERSION_2:
1262 priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
1263 priv->cpts.reg = ss_regs + CPSW2_CPTS_OFFSET;
1264 dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET;
1265 dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET;
1266 ale_params.ale_regs = ss_regs + CPSW2_ALE_OFFSET;
1267 slave_offset = CPSW2_SLAVE_OFFSET;
1268 slave_size = CPSW2_SLAVE_SIZE;
1269 sliver_offset = CPSW2_SLIVER_OFFSET;
1270 dma_params.desc_mem_phys =
1271 (u32 __force) priv->cpsw_res->start + CPSW2_BD_OFFSET;
1272 break;
1273 default:
1274 dev_err(priv->dev, "unknown version 0x%08x\n", priv->version);
1275 ret = -ENODEV;
1276 goto clean_cpsw_wr_iores_ret;
1277 }
1278 for (i = 0; i < priv->data.slaves; i++) {
1279 struct cpsw_slave *slave = &priv->slaves[i];
1280 cpsw_slave_init(slave, priv, slave_offset, sliver_offset);
1281 slave_offset += slave_size;
1282 sliver_offset += SLIVER_SIZE;
1283 }
1284
1306 dma_params.dev = &pdev->dev; 1285 dma_params.dev = &pdev->dev;
1307 dma_params.dmaregs = cpsw_dma_regs((u32)priv->regs, 1286 dma_params.rxthresh = dma_params.dmaregs + CPDMA_RXTHRESH;
1308 data->cpdma_reg_ofs); 1287 dma_params.rxfree = dma_params.dmaregs + CPDMA_RXFREE;
1309 dma_params.rxthresh = cpsw_dma_rxthresh((u32)priv->regs, 1288 dma_params.rxhdp = dma_params.txhdp + CPDMA_RXHDP;
1310 data->cpdma_reg_ofs); 1289 dma_params.txcp = dma_params.txhdp + CPDMA_TXCP;
1311 dma_params.rxfree = cpsw_dma_rxfree((u32)priv->regs, 1290 dma_params.rxcp = dma_params.txhdp + CPDMA_RXCP;
1312 data->cpdma_reg_ofs);
1313 dma_params.txhdp = cpsw_dma_txhdp((u32)priv->regs,
1314 data->cpdma_sram_ofs);
1315 dma_params.rxhdp = cpsw_dma_rxhdp((u32)priv->regs,
1316 data->cpdma_sram_ofs);
1317 dma_params.txcp = cpsw_dma_txcp((u32)priv->regs,
1318 data->cpdma_sram_ofs);
1319 dma_params.rxcp = cpsw_dma_rxcp((u32)priv->regs,
1320 data->cpdma_sram_ofs);
1321 1291
1322 dma_params.num_chan = data->channels; 1292 dma_params.num_chan = data->channels;
1323 dma_params.has_soft_reset = true; 1293 dma_params.has_soft_reset = true;
@@ -1325,10 +1295,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
1325 dma_params.desc_mem_size = data->bd_ram_size; 1295 dma_params.desc_mem_size = data->bd_ram_size;
1326 dma_params.desc_align = 16; 1296 dma_params.desc_align = 16;
1327 dma_params.has_ext_regs = true; 1297 dma_params.has_ext_regs = true;
1328 dma_params.desc_mem_phys = data->no_bd_ram ? 0 : 1298 dma_params.desc_hw_addr = dma_params.desc_mem_phys;
1329 (u32 __force)priv->cpsw_res->start + data->bd_ram_ofs;
1330 dma_params.desc_hw_addr = data->hw_ram_addr ?
1331 data->hw_ram_addr : dma_params.desc_mem_phys ;
1332 1299
1333 priv->dma = cpdma_ctlr_create(&dma_params); 1300 priv->dma = cpdma_ctlr_create(&dma_params);
1334 if (!priv->dma) { 1301 if (!priv->dma) {
@@ -1348,10 +1315,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
1348 goto clean_dma_ret; 1315 goto clean_dma_ret;
1349 } 1316 }
1350 1317
1351 memset(&ale_params, 0, sizeof(ale_params));
1352 ale_params.dev = &ndev->dev; 1318 ale_params.dev = &ndev->dev;
1353 ale_params.ale_regs = (void *)((u32)priv->regs) +
1354 ((u32)data->ale_reg_ofs);
1355 ale_params.ale_ageout = ale_ageout; 1319 ale_params.ale_ageout = ale_ageout;
1356 ale_params.ale_entries = data->ale_entries; 1320 ale_params.ale_entries = data->ale_entries;
1357 ale_params.ale_ports = data->slaves; 1321 ale_params.ale_ports = data->slaves;