diff options
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot_io.c')
| -rw-r--r-- | drivers/net/ethernet/mscc/ocelot_io.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c new file mode 100644 index 000000000000..c6db8ad31fdf --- /dev/null +++ b/drivers/net/ethernet/mscc/ocelot_io.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
| 2 | /* | ||
| 3 | * Microsemi Ocelot Switch driver | ||
| 4 | * | ||
| 5 | * Copyright (c) 2017 Microsemi Corporation | ||
| 6 | */ | ||
| 7 | #include <linux/io.h> | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/platform_device.h> | ||
| 10 | |||
| 11 | #include "ocelot.h" | ||
| 12 | |||
| 13 | u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset) | ||
| 14 | { | ||
| 15 | u16 target = reg >> TARGET_OFFSET; | ||
| 16 | u32 val; | ||
| 17 | |||
| 18 | WARN_ON(!target); | ||
| 19 | |||
| 20 | regmap_read(ocelot->targets[target], | ||
| 21 | ocelot->map[target][reg & REG_MASK] + offset, &val); | ||
| 22 | return val; | ||
| 23 | } | ||
| 24 | EXPORT_SYMBOL(__ocelot_read_ix); | ||
| 25 | |||
| 26 | void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset) | ||
| 27 | { | ||
| 28 | u16 target = reg >> TARGET_OFFSET; | ||
| 29 | |||
| 30 | WARN_ON(!target); | ||
| 31 | |||
| 32 | regmap_write(ocelot->targets[target], | ||
| 33 | ocelot->map[target][reg & REG_MASK] + offset, val); | ||
| 34 | } | ||
| 35 | EXPORT_SYMBOL(__ocelot_write_ix); | ||
| 36 | |||
| 37 | void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, | ||
| 38 | u32 offset) | ||
| 39 | { | ||
| 40 | u16 target = reg >> TARGET_OFFSET; | ||
| 41 | |||
| 42 | WARN_ON(!target); | ||
| 43 | |||
| 44 | regmap_update_bits(ocelot->targets[target], | ||
| 45 | ocelot->map[target][reg & REG_MASK] + offset, | ||
| 46 | mask, val); | ||
| 47 | } | ||
| 48 | EXPORT_SYMBOL(__ocelot_rmw_ix); | ||
| 49 | |||
| 50 | u32 ocelot_port_readl(struct ocelot_port *port, u32 reg) | ||
| 51 | { | ||
| 52 | return readl(port->regs + reg); | ||
| 53 | } | ||
| 54 | EXPORT_SYMBOL(ocelot_port_readl); | ||
| 55 | |||
| 56 | void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg) | ||
| 57 | { | ||
| 58 | writel(val, port->regs + reg); | ||
| 59 | } | ||
| 60 | EXPORT_SYMBOL(ocelot_port_writel); | ||
| 61 | |||
| 62 | int ocelot_regfields_init(struct ocelot *ocelot, | ||
| 63 | const struct reg_field *const regfields) | ||
| 64 | { | ||
| 65 | unsigned int i; | ||
| 66 | u16 target; | ||
| 67 | |||
| 68 | for (i = 0; i < REGFIELD_MAX; i++) { | ||
| 69 | struct reg_field regfield = {}; | ||
| 70 | u32 reg = regfields[i].reg; | ||
| 71 | |||
| 72 | if (!reg) | ||
| 73 | continue; | ||
| 74 | |||
| 75 | target = regfields[i].reg >> TARGET_OFFSET; | ||
| 76 | |||
| 77 | regfield.reg = ocelot->map[target][reg & REG_MASK]; | ||
| 78 | regfield.lsb = regfields[i].lsb; | ||
| 79 | regfield.msb = regfields[i].msb; | ||
| 80 | |||
| 81 | ocelot->regfields[i] = | ||
| 82 | devm_regmap_field_alloc(ocelot->dev, | ||
| 83 | ocelot->targets[target], | ||
| 84 | regfield); | ||
| 85 | |||
| 86 | if (IS_ERR(ocelot->regfields[i])) | ||
| 87 | return PTR_ERR(ocelot->regfields[i]); | ||
| 88 | } | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | EXPORT_SYMBOL(ocelot_regfields_init); | ||
| 93 | |||
| 94 | static struct regmap_config ocelot_regmap_config = { | ||
| 95 | .reg_bits = 32, | ||
| 96 | .val_bits = 32, | ||
| 97 | .reg_stride = 4, | ||
| 98 | }; | ||
| 99 | |||
| 100 | struct regmap *ocelot_io_platform_init(struct ocelot *ocelot, | ||
| 101 | struct platform_device *pdev, | ||
| 102 | const char *name) | ||
| 103 | { | ||
| 104 | struct resource *res; | ||
| 105 | void __iomem *regs; | ||
| 106 | |||
| 107 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); | ||
| 108 | regs = devm_ioremap_resource(ocelot->dev, res); | ||
| 109 | if (IS_ERR(regs)) | ||
| 110 | return ERR_CAST(regs); | ||
| 111 | |||
| 112 | ocelot_regmap_config.name = name; | ||
| 113 | return devm_regmap_init_mmio(ocelot->dev, regs, | ||
| 114 | &ocelot_regmap_config); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL(ocelot_io_platform_init); | ||
