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_regmap_init(struct ocelot *ocelot, struct resource *res) 101 { 102 void __iomem *regs; 103 104 regs = devm_ioremap_resource(ocelot->dev, res); 105 if (IS_ERR(regs)) 106 return ERR_CAST(regs); 107 108 ocelot_regmap_config.name = res->name; 109 110 return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config); 111 } 112 EXPORT_SYMBOL(ocelot_regmap_init); 113