]>
Commit | Line | Data |
---|---|---|
a556c76a AB |
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 | ||
259630e0 | 100 | struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res) |
a556c76a | 101 | { |
a556c76a AB |
102 | void __iomem *regs; |
103 | ||
a556c76a AB |
104 | regs = devm_ioremap_resource(ocelot->dev, res); |
105 | if (IS_ERR(regs)) | |
106 | return ERR_CAST(regs); | |
107 | ||
259630e0 CM |
108 | ocelot_regmap_config.name = res->name; |
109 | ||
110 | return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config); | |
a556c76a | 111 | } |
259630e0 | 112 | EXPORT_SYMBOL(ocelot_regmap_init); |