brintos

brintos / linux-shallow public Read only

0
0
Text · 4.0 KiB · 3aa7dc2 Raw
169 lines · c
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)2/*3 * Microsemi Ocelot Switch driver4 *5 * Copyright (c) 2017 Microsemi Corporation6 */7#include <linux/io.h>8#include <linux/kernel.h>9#include <linux/platform_device.h>10 11#include "ocelot.h"12 13int __ocelot_bulk_read_ix(struct ocelot *ocelot, enum ocelot_reg reg,14			  u32 offset, void *buf, int count)15{16	enum ocelot_target target;17	u32 addr;18 19	ocelot_reg_to_target_addr(ocelot, reg, &target, &addr);20	WARN_ON(!target);21 22	return regmap_bulk_read(ocelot->targets[target], addr + offset,23				buf, count);24}25EXPORT_SYMBOL_GPL(__ocelot_bulk_read_ix);26 27u32 __ocelot_read_ix(struct ocelot *ocelot, enum ocelot_reg reg, u32 offset)28{29	enum ocelot_target target;30	u32 addr, val;31 32	ocelot_reg_to_target_addr(ocelot, reg, &target, &addr);33	WARN_ON(!target);34 35	regmap_read(ocelot->targets[target], addr + offset, &val);36	return val;37}38EXPORT_SYMBOL_GPL(__ocelot_read_ix);39 40void __ocelot_write_ix(struct ocelot *ocelot, u32 val, enum ocelot_reg reg,41		       u32 offset)42{43	enum ocelot_target target;44	u32 addr;45 46	ocelot_reg_to_target_addr(ocelot, reg, &target, &addr);47	WARN_ON(!target);48 49	regmap_write(ocelot->targets[target], addr + offset, val);50}51EXPORT_SYMBOL_GPL(__ocelot_write_ix);52 53void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask,54		     enum ocelot_reg reg, u32 offset)55{56	enum ocelot_target target;57	u32 addr;58 59	ocelot_reg_to_target_addr(ocelot, reg, &target, &addr);60	WARN_ON(!target);61 62	regmap_update_bits(ocelot->targets[target], addr + offset, mask, val);63}64EXPORT_SYMBOL_GPL(__ocelot_rmw_ix);65 66u32 ocelot_port_readl(struct ocelot_port *port, enum ocelot_reg reg)67{68	struct ocelot *ocelot = port->ocelot;69	u16 target = reg >> TARGET_OFFSET;70	u32 val;71 72	WARN_ON(!target);73 74	regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);75	return val;76}77EXPORT_SYMBOL_GPL(ocelot_port_readl);78 79void ocelot_port_writel(struct ocelot_port *port, u32 val, enum ocelot_reg reg)80{81	struct ocelot *ocelot = port->ocelot;82	u16 target = reg >> TARGET_OFFSET;83 84	WARN_ON(!target);85 86	regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);87}88EXPORT_SYMBOL_GPL(ocelot_port_writel);89 90void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask,91		      enum ocelot_reg reg)92{93	u32 cur = ocelot_port_readl(port, reg);94 95	ocelot_port_writel(port, (cur & (~mask)) | val, reg);96}97EXPORT_SYMBOL_GPL(ocelot_port_rmwl);98 99u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,100			    u32 reg, u32 offset)101{102	u32 val;103 104	regmap_read(ocelot->targets[target],105		    ocelot->map[target][reg] + offset, &val);106	return val;107}108 109void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,110			      u32 val, u32 reg, u32 offset)111{112	regmap_write(ocelot->targets[target],113		     ocelot->map[target][reg] + offset, val);114}115 116int ocelot_regfields_init(struct ocelot *ocelot,117			  const struct reg_field *const regfields)118{119	unsigned int i;120	u16 target;121 122	for (i = 0; i < REGFIELD_MAX; i++) {123		struct reg_field regfield = {};124		u32 reg = regfields[i].reg;125 126		if (!reg)127			continue;128 129		target = regfields[i].reg >> TARGET_OFFSET;130 131		regfield.reg = ocelot->map[target][reg & REG_MASK];132		regfield.lsb = regfields[i].lsb;133		regfield.msb = regfields[i].msb;134		regfield.id_size = regfields[i].id_size;135		regfield.id_offset = regfields[i].id_offset;136 137		ocelot->regfields[i] =138		devm_regmap_field_alloc(ocelot->dev,139					ocelot->targets[target],140					regfield);141 142		if (IS_ERR(ocelot->regfields[i]))143			return PTR_ERR(ocelot->regfields[i]);144	}145 146	return 0;147}148EXPORT_SYMBOL_GPL(ocelot_regfields_init);149 150static struct regmap_config ocelot_regmap_config = {151	.reg_bits	= 32,152	.val_bits	= 32,153	.reg_stride	= 4,154};155 156struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res)157{158	void __iomem *regs;159 160	regs = devm_ioremap_resource(ocelot->dev, res);161	if (IS_ERR(regs))162		return ERR_CAST(regs);163 164	ocelot_regmap_config.name = res->name;165 166	return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config);167}168EXPORT_SYMBOL_GPL(ocelot_regmap_init);169