0001
0002
0003
0004
0005
0006
0007 #include <linux/io.h>
0008 #include <linux/kernel.h>
0009 #include <linux/platform_device.h>
0010
0011 #include "ocelot.h"
0012
0013 int __ocelot_bulk_read_ix(struct ocelot *ocelot, u32 reg, u32 offset, void *buf,
0014 int count)
0015 {
0016 u16 target = reg >> TARGET_OFFSET;
0017
0018 WARN_ON(!target);
0019
0020 return regmap_bulk_read(ocelot->targets[target],
0021 ocelot->map[target][reg & REG_MASK] + offset,
0022 buf, count);
0023 }
0024 EXPORT_SYMBOL_GPL(__ocelot_bulk_read_ix);
0025
0026 u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset)
0027 {
0028 u16 target = reg >> TARGET_OFFSET;
0029 u32 val;
0030
0031 WARN_ON(!target);
0032
0033 regmap_read(ocelot->targets[target],
0034 ocelot->map[target][reg & REG_MASK] + offset, &val);
0035 return val;
0036 }
0037 EXPORT_SYMBOL_GPL(__ocelot_read_ix);
0038
0039 void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
0040 {
0041 u16 target = reg >> TARGET_OFFSET;
0042
0043 WARN_ON(!target);
0044
0045 regmap_write(ocelot->targets[target],
0046 ocelot->map[target][reg & REG_MASK] + offset, val);
0047 }
0048 EXPORT_SYMBOL_GPL(__ocelot_write_ix);
0049
0050 void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
0051 u32 offset)
0052 {
0053 u16 target = reg >> TARGET_OFFSET;
0054
0055 WARN_ON(!target);
0056
0057 regmap_update_bits(ocelot->targets[target],
0058 ocelot->map[target][reg & REG_MASK] + offset,
0059 mask, val);
0060 }
0061 EXPORT_SYMBOL_GPL(__ocelot_rmw_ix);
0062
0063 u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
0064 {
0065 struct ocelot *ocelot = port->ocelot;
0066 u16 target = reg >> TARGET_OFFSET;
0067 u32 val;
0068
0069 WARN_ON(!target);
0070
0071 regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
0072 return val;
0073 }
0074 EXPORT_SYMBOL_GPL(ocelot_port_readl);
0075
0076 void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
0077 {
0078 struct ocelot *ocelot = port->ocelot;
0079 u16 target = reg >> TARGET_OFFSET;
0080
0081 WARN_ON(!target);
0082
0083 regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
0084 }
0085 EXPORT_SYMBOL_GPL(ocelot_port_writel);
0086
0087 void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, u32 reg)
0088 {
0089 u32 cur = ocelot_port_readl(port, reg);
0090
0091 ocelot_port_writel(port, (cur & (~mask)) | val, reg);
0092 }
0093 EXPORT_SYMBOL_GPL(ocelot_port_rmwl);
0094
0095 u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
0096 u32 reg, u32 offset)
0097 {
0098 u32 val;
0099
0100 regmap_read(ocelot->targets[target],
0101 ocelot->map[target][reg] + offset, &val);
0102 return val;
0103 }
0104
0105 void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
0106 u32 val, u32 reg, u32 offset)
0107 {
0108 regmap_write(ocelot->targets[target],
0109 ocelot->map[target][reg] + offset, val);
0110 }
0111
0112 int ocelot_regfields_init(struct ocelot *ocelot,
0113 const struct reg_field *const regfields)
0114 {
0115 unsigned int i;
0116 u16 target;
0117
0118 for (i = 0; i < REGFIELD_MAX; i++) {
0119 struct reg_field regfield = {};
0120 u32 reg = regfields[i].reg;
0121
0122 if (!reg)
0123 continue;
0124
0125 target = regfields[i].reg >> TARGET_OFFSET;
0126
0127 regfield.reg = ocelot->map[target][reg & REG_MASK];
0128 regfield.lsb = regfields[i].lsb;
0129 regfield.msb = regfields[i].msb;
0130 regfield.id_size = regfields[i].id_size;
0131 regfield.id_offset = regfields[i].id_offset;
0132
0133 ocelot->regfields[i] =
0134 devm_regmap_field_alloc(ocelot->dev,
0135 ocelot->targets[target],
0136 regfield);
0137
0138 if (IS_ERR(ocelot->regfields[i]))
0139 return PTR_ERR(ocelot->regfields[i]);
0140 }
0141
0142 return 0;
0143 }
0144 EXPORT_SYMBOL_GPL(ocelot_regfields_init);
0145
0146 static struct regmap_config ocelot_regmap_config = {
0147 .reg_bits = 32,
0148 .val_bits = 32,
0149 .reg_stride = 4,
0150 };
0151
0152 struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res)
0153 {
0154 void __iomem *regs;
0155
0156 regs = devm_ioremap_resource(ocelot->dev, res);
0157 if (IS_ERR(regs))
0158 return ERR_CAST(regs);
0159
0160 ocelot_regmap_config.name = res->name;
0161
0162 return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config);
0163 }
0164 EXPORT_SYMBOL_GPL(ocelot_regmap_init);