aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2014-11-14 10:37:39 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2014-11-17 06:19:27 -0500
commit3ff9027ca6b00e194d2eae353febf7233cfcc1ea (patch)
tree57a9c2af5f00837a2b4d22fa661e1ac6791e045b
parentbbf914300509f038c807360d755bd606785be6c9 (diff)
can: c_can: Add syscon/regmap RAMINIT mechanism
Some TI SoCs like DRA7 have a RAMINIT register specification different from the other AMxx SoCs and as expected by the existing driver. To add more insanity, this register is shared with other IPs like DSS, PCIe and PWM. Provides a more generic mechanism to specify the RAMINIT register location and START/DONE bit position and use the syscon/regmap framework to access the register. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--Documentation/devicetree/bindings/net/can/c_can.txt3
-rw-r--r--drivers/net/can/c_can/c_can.h10
-rw-r--r--drivers/net/can/c_can/c_can_platform.c109
3 files changed, 81 insertions, 41 deletions
diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
index 8f1ae81228e3..a3ca3ee53546 100644
--- a/Documentation/devicetree/bindings/net/can/c_can.txt
+++ b/Documentation/devicetree/bindings/net/can/c_can.txt
@@ -12,6 +12,9 @@ Required properties:
12Optional properties: 12Optional properties:
13- ti,hwmods : Must be "d_can<n>" or "c_can<n>", n being the 13- ti,hwmods : Must be "d_can<n>" or "c_can<n>", n being the
14 instance number 14 instance number
15- syscon-raminit : Handle to system control region that contains the
16 RAMINIT register, register offset to the RAMINIT
17 register and the CAN instance number (0 offset).
15 18
16Note: "ti,hwmods" field is used to fetch the base address and irq 19Note: "ti,hwmods" field is used to fetch the base address and irq
17resources from TI, omap hwmod data base during device registration. 20resources from TI, omap hwmod data base during device registration.
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index 3f111f4f0f6e..28a73d14ea8d 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -183,6 +183,13 @@ struct c_can_driver_data {
183 bool raminit_pulse; /* If set, sets and clears START bit (pulse) */ 183 bool raminit_pulse; /* If set, sets and clears START bit (pulse) */
184}; 184};
185 185
186/* Out of band RAMINIT register access via syscon regmap */
187struct c_can_raminit {
188 struct regmap *syscon; /* for raminit ctrl. reg. access */
189 unsigned int reg; /* register index within syscon */
190 struct raminit_bits bits;
191};
192
186/* c_can private data structure */ 193/* c_can private data structure */
187struct c_can_priv { 194struct c_can_priv {
188 struct can_priv can; /* must be the first member */ 195 struct can_priv can; /* must be the first member */
@@ -200,8 +207,7 @@ struct c_can_priv {
200 const u16 *regs; 207 const u16 *regs;
201 void *priv; /* for board-specific data */ 208 void *priv; /* for board-specific data */
202 enum c_can_dev_id type; 209 enum c_can_dev_id type;
203 u32 __iomem *raminit_ctrlreg; 210 struct c_can_raminit raminit_sys; /* RAMINIT via syscon regmap */
204 int instance;
205 void (*raminit) (const struct c_can_priv *priv, bool enable); 211 void (*raminit) (const struct c_can_priv *priv, bool enable);
206 u32 comm_rcv_high; 212 u32 comm_rcv_high;
207 u32 rxmasked; 213 u32 rxmasked;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 44c293926f78..1fbfa1d59c29 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -32,14 +32,13 @@
32#include <linux/clk.h> 32#include <linux/clk.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/of_device.h> 34#include <linux/of_device.h>
35#include <linux/mfd/syscon.h>
36#include <linux/regmap.h>
35 37
36#include <linux/can/dev.h> 38#include <linux/can/dev.h>
37 39
38#include "c_can.h" 40#include "c_can.h"
39 41
40#define CAN_RAMINIT_START_MASK(i) (0x001 << (i))
41#define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i))
42#define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i))
43#define DCAN_RAM_INIT_BIT (1 << 3) 42#define DCAN_RAM_INIT_BIT (1 << 3)
44static DEFINE_SPINLOCK(raminit_lock); 43static DEFINE_SPINLOCK(raminit_lock);
45/* 44/*
@@ -72,48 +71,57 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
72 writew(val, priv->base + 2 * priv->regs[index]); 71 writew(val, priv->base + 2 * priv->regs[index]);
73} 72}
74 73
75static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask, 74static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
76 u32 val) 75 u32 mask, u32 val)
77{ 76{
77 const struct c_can_raminit *raminit = &priv->raminit_sys;
78 int timeout = 0; 78 int timeout = 0;
79 u32 ctrl = 0;
79 80
80 /* We look only at the bits of our instance. */ 81 /* We look only at the bits of our instance. */
81 val &= mask; 82 val &= mask;
82 while ((readl(priv->raminit_ctrlreg) & mask) != val) { 83 do {
83 udelay(1); 84 udelay(1);
84 timeout++; 85 timeout++;
85 86
87 regmap_read(raminit->syscon, raminit->reg, &ctrl);
86 if (timeout == 1000) { 88 if (timeout == 1000) {
87 dev_err(&priv->dev->dev, "%s: time out\n", __func__); 89 dev_err(&priv->dev->dev, "%s: time out\n", __func__);
88 break; 90 break;
89 } 91 }
90 } 92 } while ((ctrl & mask) != val);
91} 93}
92 94
93static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable) 95static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
94{ 96{
95 u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance); 97 const struct c_can_raminit *raminit = &priv->raminit_sys;
96 u32 ctrl; 98 u32 ctrl = 0;
99 u32 mask;
97 100
98 spin_lock(&raminit_lock); 101 spin_lock(&raminit_lock);
99 102
100 ctrl = readl(priv->raminit_ctrlreg); 103 mask = 1 << raminit->bits.start | 1 << raminit->bits.done;
104 regmap_read(raminit->syscon, raminit->reg, &ctrl);
105
101 /* We clear the done and start bit first. The start bit is 106 /* We clear the done and start bit first. The start bit is
102 * looking at the 0 -> transition, but is not self clearing; 107 * looking at the 0 -> transition, but is not self clearing;
103 * And we clear the init done bit as well. 108 * And we clear the init done bit as well.
109 * NOTE: DONE must be written with 1 to clear it.
104 */ 110 */
105 ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance); 111 ctrl &= ~(1 << raminit->bits.start);
106 ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); 112 ctrl |= 1 << raminit->bits.done;
107 writel(ctrl, priv->raminit_ctrlreg); 113 regmap_write(raminit->syscon, raminit->reg, ctrl);
108 ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance); 114
109 c_can_hw_raminit_wait_ti(priv, mask, ctrl); 115 ctrl &= ~(1 << raminit->bits.done);
116 c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
110 117
111 if (enable) { 118 if (enable) {
112 /* Set start bit and wait for the done bit. */ 119 /* Set start bit and wait for the done bit. */
113 ctrl |= CAN_RAMINIT_START_MASK(priv->instance); 120 ctrl |= 1 << raminit->bits.start;
114 writel(ctrl, priv->raminit_ctrlreg); 121 regmap_write(raminit->syscon, raminit->reg, ctrl);
115 ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); 122
116 c_can_hw_raminit_wait_ti(priv, mask, ctrl); 123 ctrl |= 1 << raminit->bits.done;
124 c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
117 } 125 }
118 spin_unlock(&raminit_lock); 126 spin_unlock(&raminit_lock);
119} 127}
@@ -207,10 +215,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
207 struct net_device *dev; 215 struct net_device *dev;
208 struct c_can_priv *priv; 216 struct c_can_priv *priv;
209 const struct of_device_id *match; 217 const struct of_device_id *match;
210 struct resource *mem, *res; 218 struct resource *mem;
211 int irq; 219 int irq;
212 struct clk *clk; 220 struct clk *clk;
213 const struct c_can_driver_data *drvdata; 221 const struct c_can_driver_data *drvdata;
222 struct device_node *np = pdev->dev.of_node;
214 223
215 match = of_match_device(c_can_of_table, &pdev->dev); 224 match = of_match_device(c_can_of_table, &pdev->dev);
216 if (match) { 225 if (match) {
@@ -278,27 +287,49 @@ static int c_can_plat_probe(struct platform_device *pdev)
278 priv->read_reg32 = d_can_plat_read_reg32; 287 priv->read_reg32 = d_can_plat_read_reg32;
279 priv->write_reg32 = d_can_plat_write_reg32; 288 priv->write_reg32 = d_can_plat_write_reg32;
280 289
281 if (pdev->dev.of_node) 290 /* Check if we need custom RAMINIT via syscon. Mostly for TI
282 priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can"); 291 * platforms. Only supported with DT boot.
283 else
284 priv->instance = pdev->id;
285
286 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
287 /* Not all D_CAN modules have a separate register for the D_CAN
288 * RAM initialization. Use default RAM init bit in D_CAN module
289 * if not specified in DT.
290 */ 292 */
291 if (!res) { 293 if (np && of_property_read_bool(np, "syscon-raminit")) {
294 u32 id;
295 struct c_can_raminit *raminit = &priv->raminit_sys;
296
297 ret = -EINVAL;
298 raminit->syscon = syscon_regmap_lookup_by_phandle(np,
299 "syscon-raminit");
300 if (IS_ERR(raminit->syscon)) {
301 /* can fail with -EPROBE_DEFER */
302 ret = PTR_ERR(raminit->syscon);
303 free_c_can_dev(dev);
304 return ret;
305 }
306
307 if (of_property_read_u32_index(np, "syscon-raminit", 1,
308 &raminit->reg)) {
309 dev_err(&pdev->dev,
310 "couldn't get the RAMINIT reg. offset!\n");
311 goto exit_free_device;
312 }
313
314 if (of_property_read_u32_index(np, "syscon-raminit", 2,
315 &id)) {
316 dev_err(&pdev->dev,
317 "couldn't get the CAN instance ID\n");
318 goto exit_free_device;
319 }
320
321 if (id >= drvdata->raminit_num) {
322 dev_err(&pdev->dev,
323 "Invalid CAN instance ID\n");
324 goto exit_free_device;
325 }
326
327 raminit->bits = drvdata->raminit_bits[id];
328
329 priv->raminit = c_can_hw_raminit_syscon;
330 } else {
292 priv->raminit = c_can_hw_raminit; 331 priv->raminit = c_can_hw_raminit;
293 break;
294 } 332 }
295
296 priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
297 resource_size(res));
298 if (!priv->raminit_ctrlreg || priv->instance < 0)
299 dev_info(&pdev->dev, "control memory is not used for raminit\n");
300 else
301 priv->raminit = c_can_hw_raminit_ti;
302 break; 333 break;
303 default: 334 default:
304 ret = -EINVAL; 335 ret = -EINVAL;