Skip to content

Commit bbfc7e2

Browse files
rogerqdavem330
authored andcommitted
net: ethernet: ti: cpsw_ale: use regfields for ALE registers
Map the entire ALE registerspace using regmap. Add regfields for Major and Minor Version fields. Signed-off-by: Roger Quadros <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da70d18 commit bbfc7e2

File tree

2 files changed

+79
-22
lines changed

2 files changed

+79
-22
lines changed

drivers/net/ethernet/ti/cpsw_ale.c

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/kernel.h>
1111
#include <linux/module.h>
1212
#include <linux/platform_device.h>
13+
#include <linux/regmap.h>
1314
#include <linux/seq_file.h>
1415
#include <linux/slab.h>
1516
#include <linux/err.h>
@@ -76,15 +77,15 @@ enum {
7677
* @dev_id: ALE version/SoC id
7778
* @features: features supported by ALE
7879
* @tbl_entries: number of ALE entries
79-
* @major_ver_mask: mask of ALE Major Version Value in ALE_IDVER reg.
80+
* @reg_fields: pointer to array of register field configuration
8081
* @nu_switch_ale: NU Switch ALE
8182
* @vlan_entry_tbl: ALE vlan entry fields description tbl
8283
*/
8384
struct cpsw_ale_dev_id {
8485
const char *dev_id;
8586
u32 features;
8687
u32 tbl_entries;
87-
u32 major_ver_mask;
88+
const struct reg_field *reg_fields;
8889
bool nu_switch_ale;
8990
const struct ale_entry_fld *vlan_entry_tbl;
9091
};
@@ -1292,54 +1293,66 @@ void cpsw_ale_stop(struct cpsw_ale *ale)
12921293
cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0);
12931294
}
12941295

1296+
static const struct reg_field ale_fields_cpsw[] = {
1297+
/* CPSW_ALE_IDVER_REG */
1298+
[MINOR_VER] = REG_FIELD(ALE_IDVER, 0, 7),
1299+
[MAJOR_VER] = REG_FIELD(ALE_IDVER, 8, 15),
1300+
};
1301+
1302+
static const struct reg_field ale_fields_cpsw_nu[] = {
1303+
/* CPSW_ALE_IDVER_REG */
1304+
[MINOR_VER] = REG_FIELD(ALE_IDVER, 0, 7),
1305+
[MAJOR_VER] = REG_FIELD(ALE_IDVER, 8, 10),
1306+
};
1307+
12951308
static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
12961309
{
12971310
/* am3/4/5, dra7. dm814x, 66ak2hk-gbe */
12981311
.dev_id = "cpsw",
12991312
.tbl_entries = 1024,
1300-
.major_ver_mask = 0xff,
1313+
.reg_fields = ale_fields_cpsw,
13011314
.vlan_entry_tbl = vlan_entry_cpsw,
13021315
},
13031316
{
13041317
/* 66ak2h_xgbe */
13051318
.dev_id = "66ak2h-xgbe",
13061319
.tbl_entries = 2048,
1307-
.major_ver_mask = 0xff,
1320+
.reg_fields = ale_fields_cpsw,
13081321
.vlan_entry_tbl = vlan_entry_cpsw,
13091322
},
13101323
{
13111324
.dev_id = "66ak2el",
13121325
.features = CPSW_ALE_F_STATUS_REG,
1313-
.major_ver_mask = 0x7,
1326+
.reg_fields = ale_fields_cpsw_nu,
13141327
.nu_switch_ale = true,
13151328
.vlan_entry_tbl = vlan_entry_nu,
13161329
},
13171330
{
13181331
.dev_id = "66ak2g",
13191332
.features = CPSW_ALE_F_STATUS_REG,
13201333
.tbl_entries = 64,
1321-
.major_ver_mask = 0x7,
1334+
.reg_fields = ale_fields_cpsw_nu,
13221335
.nu_switch_ale = true,
13231336
.vlan_entry_tbl = vlan_entry_nu,
13241337
},
13251338
{
13261339
.dev_id = "am65x-cpsw2g",
13271340
.features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
13281341
.tbl_entries = 64,
1329-
.major_ver_mask = 0x7,
1342+
.reg_fields = ale_fields_cpsw_nu,
13301343
.nu_switch_ale = true,
13311344
.vlan_entry_tbl = vlan_entry_nu,
13321345
},
13331346
{
13341347
.dev_id = "j721e-cpswxg",
13351348
.features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1336-
.major_ver_mask = 0x7,
1349+
.reg_fields = ale_fields_cpsw_nu,
13371350
.vlan_entry_tbl = vlan_entry_k3_cpswxg,
13381351
},
13391352
{
13401353
.dev_id = "am64-cpswxg",
13411354
.features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
1342-
.major_ver_mask = 0x7,
1355+
.reg_fields = ale_fields_cpsw_nu,
13431356
.vlan_entry_tbl = vlan_entry_k3_cpswxg,
13441357
.tbl_entries = 512,
13451358
},
@@ -1361,41 +1374,76 @@ cpsw_ale_dev_id *cpsw_ale_match_id(const struct cpsw_ale_dev_id *id,
13611374
return NULL;
13621375
}
13631376

1377+
static const struct regmap_config ale_regmap_cfg = {
1378+
.reg_bits = 32,
1379+
.val_bits = 32,
1380+
.reg_stride = 4,
1381+
.name = "cpsw-ale",
1382+
};
1383+
1384+
static int cpsw_ale_regfield_init(struct cpsw_ale *ale)
1385+
{
1386+
const struct reg_field *reg_fields = ale->params.reg_fields;
1387+
struct device *dev = ale->params.dev;
1388+
struct regmap *regmap = ale->regmap;
1389+
int i;
1390+
1391+
for (i = 0; i < ALE_FIELDS_MAX; i++) {
1392+
ale->fields[i] = devm_regmap_field_alloc(dev, regmap,
1393+
reg_fields[i]);
1394+
if (IS_ERR(ale->fields[i])) {
1395+
dev_err(dev, "Unable to allocate regmap field %d\n", i);
1396+
return PTR_ERR(ale->fields[i]);
1397+
}
1398+
}
1399+
1400+
return 0;
1401+
}
1402+
13641403
struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
13651404
{
13661405
const struct cpsw_ale_dev_id *ale_dev_id;
1406+
u32 ale_entries, rev_major, rev_minor;
13671407
struct cpsw_ale *ale;
1368-
u32 rev, ale_entries;
1408+
int ret;
13691409

13701410
ale_dev_id = cpsw_ale_match_id(cpsw_ale_id_match, params->dev_id);
13711411
if (!ale_dev_id)
13721412
return ERR_PTR(-EINVAL);
13731413

13741414
params->ale_entries = ale_dev_id->tbl_entries;
1375-
params->major_ver_mask = ale_dev_id->major_ver_mask;
13761415
params->nu_switch_ale = ale_dev_id->nu_switch_ale;
1416+
params->reg_fields = ale_dev_id->reg_fields;
13771417

13781418
ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
13791419
if (!ale)
13801420
return ERR_PTR(-ENOMEM);
1421+
ale->regmap = devm_regmap_init_mmio(params->dev, params->ale_regs,
1422+
&ale_regmap_cfg);
1423+
if (IS_ERR(ale->regmap)) {
1424+
dev_err(params->dev, "Couldn't create CPSW ALE regmap\n");
1425+
return ERR_PTR(-ENOMEM);
1426+
}
1427+
1428+
ale->params = *params;
1429+
ret = cpsw_ale_regfield_init(ale);
1430+
if (ret)
1431+
return ERR_PTR(ret);
13811432

13821433
ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID,
13831434
GFP_KERNEL);
13841435
if (!ale->p0_untag_vid_mask)
13851436
return ERR_PTR(-ENOMEM);
13861437

1387-
ale->params = *params;
13881438
ale->ageout = ale->params.ale_ageout * HZ;
13891439
ale->features = ale_dev_id->features;
13901440
ale->vlan_entry_tbl = ale_dev_id->vlan_entry_tbl;
13911441

1392-
rev = readl_relaxed(ale->params.ale_regs + ALE_IDVER);
1393-
ale->version =
1394-
(ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) |
1395-
ALE_VERSION_MINOR(rev);
1442+
regmap_field_read(ale->fields[MINOR_VER], &rev_minor);
1443+
regmap_field_read(ale->fields[MAJOR_VER], &rev_major);
1444+
ale->version = rev_major << 8 | rev_minor;
13961445
dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n",
1397-
ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask),
1398-
ALE_VERSION_MINOR(rev));
1446+
rev_major, rev_minor);
13991447

14001448
if (ale->features & CPSW_ALE_F_STATUS_REG &&
14011449
!ale->params.ale_entries) {

drivers/net/ethernet/ti/cpsw_ale.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#ifndef __TI_CPSW_ALE_H__
99
#define __TI_CPSW_ALE_H__
1010

11+
struct reg_fields;
12+
1113
struct cpsw_ale_params {
1214
struct device *dev;
1315
void __iomem *ale_regs;
@@ -20,19 +22,26 @@ struct cpsw_ale_params {
2022
* to identify this hardware.
2123
*/
2224
bool nu_switch_ale;
23-
/* mask bit used in NU Switch ALE is 3 bits instead of 8 bits. So
24-
* pass it from caller.
25-
*/
26-
u32 major_ver_mask;
25+
const struct reg_field *reg_fields;
2726
const char *dev_id;
2827
unsigned long bus_freq;
2928
};
3029

3130
struct ale_entry_fld;
31+
struct regmap;
32+
33+
enum ale_fields {
34+
MINOR_VER,
35+
MAJOR_VER,
36+
/* terminator */
37+
ALE_FIELDS_MAX,
38+
};
3239

3340
struct cpsw_ale {
3441
struct cpsw_ale_params params;
3542
struct timer_list timer;
43+
struct regmap *regmap;
44+
struct regmap_field *fields[ALE_FIELDS_MAX];
3645
unsigned long ageout;
3746
u32 version;
3847
u32 features;

0 commit comments

Comments
 (0)