Merge branch 'for-6.9/amd-sfh' into for-linus
[sfrench/cifs-2.6.git] / drivers / leds / leds-sun50i-a100.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021-2023 Samuel Holland <samuel@sholland.org>
4  *
5  * Partly based on drivers/leds/leds-turris-omnia.c, which is:
6  *     Copyright (c) 2020 by Marek BehĂșn <kabel@kernel.org>
7  */
8
9 #include <linux/bitfield.h>
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/dmaengine.h>
14 #include <linux/interrupt.h>
15 #include <linux/io.h>
16 #include <linux/led-class-multicolor.h>
17 #include <linux/leds.h>
18 #include <linux/mod_devicetable.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm.h>
22 #include <linux/property.h>
23 #include <linux/reset.h>
24 #include <linux/spinlock.h>
25
26 #define LEDC_CTRL_REG                   0x0000
27 #define LEDC_CTRL_REG_DATA_LENGTH               GENMASK(28, 16)
28 #define LEDC_CTRL_REG_RGB_MODE                  GENMASK(8, 6)
29 #define LEDC_CTRL_REG_LEDC_EN                   BIT(0)
30 #define LEDC_T01_TIMING_CTRL_REG        0x0004
31 #define LEDC_T01_TIMING_CTRL_REG_T1H            GENMASK(26, 21)
32 #define LEDC_T01_TIMING_CTRL_REG_T1L            GENMASK(20, 16)
33 #define LEDC_T01_TIMING_CTRL_REG_T0H            GENMASK(10, 6)
34 #define LEDC_T01_TIMING_CTRL_REG_T0L            GENMASK(5, 0)
35 #define LEDC_RESET_TIMING_CTRL_REG      0x000c
36 #define LEDC_RESET_TIMING_CTRL_REG_TR           GENMASK(28, 16)
37 #define LEDC_RESET_TIMING_CTRL_REG_LED_NUM      GENMASK(9, 0)
38 #define LEDC_DATA_REG                   0x0014
39 #define LEDC_DMA_CTRL_REG               0x0018
40 #define LEDC_DMA_CTRL_REG_DMA_EN                BIT(5)
41 #define LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL       GENMASK(4, 0)
42 #define LEDC_INT_CTRL_REG               0x001c
43 #define LEDC_INT_CTRL_REG_GLOBAL_INT_EN         BIT(5)
44 #define LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN    BIT(1)
45 #define LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN   BIT(0)
46 #define LEDC_INT_STS_REG                0x0020
47 #define LEDC_INT_STS_REG_FIFO_WLW               GENMASK(15, 10)
48 #define LEDC_INT_STS_REG_FIFO_CPUREQ_INT        BIT(1)
49 #define LEDC_INT_STS_REG_TRANS_FINISH_INT       BIT(0)
50
51 #define LEDC_FIFO_DEPTH                 32U
52 #define LEDC_MAX_LEDS                   1024
53 #define LEDC_CHANNELS_PER_LED           3 /* RGB */
54
55 #define LEDS_TO_BYTES(n)                ((n) * sizeof(u32))
56
57 struct sun50i_a100_ledc_led {
58         struct led_classdev_mc mc_cdev;
59         struct mc_subled subled_info[LEDC_CHANNELS_PER_LED];
60         u32 addr;
61 };
62
63 #define to_ledc_led(mc) container_of(mc, struct sun50i_a100_ledc_led, mc_cdev)
64
65 struct sun50i_a100_ledc_timing {
66         u32 t0h_ns;
67         u32 t0l_ns;
68         u32 t1h_ns;
69         u32 t1l_ns;
70         u32 treset_ns;
71 };
72
73 struct sun50i_a100_ledc {
74         struct device *dev;
75         void __iomem *base;
76         struct clk *bus_clk;
77         struct clk *mod_clk;
78         struct reset_control *reset;
79
80         u32 *buffer;
81         struct dma_chan *dma_chan;
82         dma_addr_t dma_handle;
83         unsigned int pio_length;
84         unsigned int pio_offset;
85
86         spinlock_t lock;
87         unsigned int next_length;
88         bool xfer_active;
89
90         u32 format;
91         struct sun50i_a100_ledc_timing timing;
92
93         u32 max_addr;
94         u32 num_leds;
95         struct sun50i_a100_ledc_led leds[] __counted_by(num_leds);
96 };
97
98 static int sun50i_a100_ledc_dma_xfer(struct sun50i_a100_ledc *priv, unsigned int length)
99 {
100         struct dma_async_tx_descriptor *desc;
101         dma_cookie_t cookie;
102
103         desc = dmaengine_prep_slave_single(priv->dma_chan, priv->dma_handle,
104                                            LEDS_TO_BYTES(length), DMA_MEM_TO_DEV, 0);
105         if (!desc)
106                 return -ENOMEM;
107
108         cookie = dmaengine_submit(desc);
109         if (dma_submit_error(cookie))
110                 return -EIO;
111
112         dma_async_issue_pending(priv->dma_chan);
113
114         return 0;
115 }
116
117 static void sun50i_a100_ledc_pio_xfer(struct sun50i_a100_ledc *priv, unsigned int fifo_used)
118 {
119         unsigned int burst, length, offset;
120         u32 control;
121
122         length = priv->pio_length;
123         offset = priv->pio_offset;
124         burst  = min(length, LEDC_FIFO_DEPTH - fifo_used);
125
126         iowrite32_rep(priv->base + LEDC_DATA_REG, priv->buffer + offset, burst);
127
128         if (burst < length) {
129                 priv->pio_length = length - burst;
130                 priv->pio_offset = offset + burst;
131
132                 if (!offset) {
133                         control = readl(priv->base + LEDC_INT_CTRL_REG);
134                         control |= LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN;
135                         writel(control, priv->base + LEDC_INT_CTRL_REG);
136                 }
137         } else {
138                 /* Disable the request IRQ once all data is written. */
139                 control = readl(priv->base + LEDC_INT_CTRL_REG);
140                 control &= ~LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN;
141                 writel(control, priv->base + LEDC_INT_CTRL_REG);
142         }
143 }
144
145 static void sun50i_a100_ledc_start_xfer(struct sun50i_a100_ledc *priv, unsigned int length)
146 {
147         bool use_dma = false;
148         u32 control;
149
150         if (priv->dma_chan && length > LEDC_FIFO_DEPTH) {
151                 int ret;
152
153                 ret = sun50i_a100_ledc_dma_xfer(priv, length);
154                 if (ret)
155                         dev_warn(priv->dev, "Failed to set up DMA (%d), using PIO\n", ret);
156                 else
157                         use_dma = true;
158         }
159
160         /* The DMA trigger level must be at least the burst length. */
161         control = FIELD_PREP(LEDC_DMA_CTRL_REG_DMA_EN, use_dma) |
162                   FIELD_PREP_CONST(LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL, LEDC_FIFO_DEPTH / 2);
163         writel(control, priv->base + LEDC_DMA_CTRL_REG);
164
165         control = readl(priv->base + LEDC_CTRL_REG);
166         control &= ~LEDC_CTRL_REG_DATA_LENGTH;
167         control |= FIELD_PREP(LEDC_CTRL_REG_DATA_LENGTH, length) | LEDC_CTRL_REG_LEDC_EN;
168         writel(control, priv->base + LEDC_CTRL_REG);
169
170         if (!use_dma) {
171                 /* The FIFO is empty when starting a new transfer. */
172                 unsigned int fifo_used = 0;
173
174                 priv->pio_length = length;
175                 priv->pio_offset = 0;
176
177                 sun50i_a100_ledc_pio_xfer(priv, fifo_used);
178         }
179 }
180
181 static irqreturn_t sun50i_a100_ledc_irq(int irq, void *data)
182 {
183         struct sun50i_a100_ledc *priv = data;
184         u32 status;
185
186         status = readl(priv->base + LEDC_INT_STS_REG);
187
188         if (status & LEDC_INT_STS_REG_TRANS_FINISH_INT) {
189                 unsigned int next_length;
190
191                 spin_lock(&priv->lock);
192
193                 /* If another transfer is queued, dequeue and start it. */
194                 next_length = priv->next_length;
195                 if (next_length)
196                         priv->next_length = 0;
197                 else
198                         priv->xfer_active = false;
199
200                 spin_unlock(&priv->lock);
201
202                 if (next_length)
203                         sun50i_a100_ledc_start_xfer(priv, next_length);
204         } else if (status & LEDC_INT_STS_REG_FIFO_CPUREQ_INT) {
205                 /* Continue the current transfer. */
206                 sun50i_a100_ledc_pio_xfer(priv, FIELD_GET(LEDC_INT_STS_REG_FIFO_WLW, status));
207         }
208
209         /* Clear the W1C status bits. */
210         writel(status, priv->base + LEDC_INT_STS_REG);
211
212         return IRQ_HANDLED;
213 }
214
215 static void sun50i_a100_ledc_brightness_set(struct led_classdev *cdev,
216                                             enum led_brightness brightness)
217 {
218         struct sun50i_a100_ledc *priv = dev_get_drvdata(cdev->dev->parent);
219         struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
220         struct sun50i_a100_ledc_led *led = to_ledc_led(mc_cdev);
221         unsigned int next_length;
222         unsigned long flags;
223         bool xfer_active;
224
225         led_mc_calc_color_components(mc_cdev, brightness);
226
227         priv->buffer[led->addr] = led->subled_info[0].brightness << 16 |
228                                   led->subled_info[1].brightness <<  8 |
229                                   led->subled_info[2].brightness;
230
231         spin_lock_irqsave(&priv->lock, flags);
232
233         /* Start, enqueue, or extend an enqueued transfer, as appropriate. */
234         next_length = max(priv->next_length, led->addr + 1);
235         xfer_active = priv->xfer_active;
236         if (xfer_active)
237                 priv->next_length = next_length;
238         else
239                 priv->xfer_active = true;
240
241         spin_unlock_irqrestore(&priv->lock, flags);
242
243         if (!xfer_active)
244                 sun50i_a100_ledc_start_xfer(priv, next_length);
245 }
246
247 static const char *const sun50i_a100_ledc_formats[] = {
248         "rgb", "rbg", "grb", "gbr", "brg", "bgr",
249 };
250
251 static int sun50i_a100_ledc_parse_format(struct device *dev,
252                                          struct sun50i_a100_ledc *priv)
253 {
254         const char *format = "grb";
255         u32 i;
256
257         device_property_read_string(dev, "allwinner,pixel-format", &format);
258
259         for (i = 0; i < ARRAY_SIZE(sun50i_a100_ledc_formats); i++) {
260                 if (!strcmp(format, sun50i_a100_ledc_formats[i])) {
261                         priv->format = i;
262                         return 0;
263                 }
264         }
265
266         return dev_err_probe(dev, -EINVAL, "Bad pixel format '%s'\n", format);
267 }
268
269 static void sun50i_a100_ledc_set_format(struct sun50i_a100_ledc *priv)
270 {
271         u32 control;
272
273         control = readl(priv->base + LEDC_CTRL_REG);
274         control &= ~LEDC_CTRL_REG_RGB_MODE;
275         control |= FIELD_PREP(LEDC_CTRL_REG_RGB_MODE, priv->format);
276         writel(control, priv->base + LEDC_CTRL_REG);
277 }
278
279 static const struct sun50i_a100_ledc_timing sun50i_a100_ledc_default_timing = {
280         .t0h_ns = 336,
281         .t0l_ns = 840,
282         .t1h_ns = 882,
283         .t1l_ns = 294,
284         .treset_ns = 300000,
285 };
286
287 static int sun50i_a100_ledc_parse_timing(struct device *dev,
288                                          struct sun50i_a100_ledc *priv)
289 {
290         struct sun50i_a100_ledc_timing *timing = &priv->timing;
291
292         *timing = sun50i_a100_ledc_default_timing;
293
294         device_property_read_u32(dev, "allwinner,t0h-ns", &timing->t0h_ns);
295         device_property_read_u32(dev, "allwinner,t0l-ns", &timing->t0l_ns);
296         device_property_read_u32(dev, "allwinner,t1h-ns", &timing->t1h_ns);
297         device_property_read_u32(dev, "allwinner,t1l-ns", &timing->t1l_ns);
298         device_property_read_u32(dev, "allwinner,treset-ns", &timing->treset_ns);
299
300         return 0;
301 }
302
303 static void sun50i_a100_ledc_set_timing(struct sun50i_a100_ledc *priv)
304 {
305         const struct sun50i_a100_ledc_timing *timing = &priv->timing;
306         unsigned long mod_freq = clk_get_rate(priv->mod_clk);
307         u32 cycle_ns;
308         u32 control;
309
310         if (!mod_freq)
311                 return;
312
313         cycle_ns = NSEC_PER_SEC / mod_freq;
314         control = FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T1H, timing->t1h_ns / cycle_ns) |
315                   FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T1L, timing->t1l_ns / cycle_ns) |
316                   FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T0H, timing->t0h_ns / cycle_ns) |
317                   FIELD_PREP(LEDC_T01_TIMING_CTRL_REG_T0L, timing->t0l_ns / cycle_ns);
318         writel(control, priv->base + LEDC_T01_TIMING_CTRL_REG);
319
320         control = FIELD_PREP(LEDC_RESET_TIMING_CTRL_REG_TR, timing->treset_ns / cycle_ns) |
321                   FIELD_PREP(LEDC_RESET_TIMING_CTRL_REG_LED_NUM, priv->max_addr);
322         writel(control, priv->base + LEDC_RESET_TIMING_CTRL_REG);
323 }
324
325 static int sun50i_a100_ledc_resume(struct device *dev)
326 {
327         struct sun50i_a100_ledc *priv = dev_get_drvdata(dev);
328         int ret;
329
330         ret = reset_control_deassert(priv->reset);
331         if (ret)
332                 return ret;
333
334         ret = clk_prepare_enable(priv->bus_clk);
335         if (ret)
336                 goto err_assert_reset;
337
338         ret = clk_prepare_enable(priv->mod_clk);
339         if (ret)
340                 goto err_disable_bus_clk;
341
342         sun50i_a100_ledc_set_format(priv);
343         sun50i_a100_ledc_set_timing(priv);
344
345         writel(LEDC_INT_CTRL_REG_GLOBAL_INT_EN | LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN,
346                priv->base + LEDC_INT_CTRL_REG);
347
348         return 0;
349
350 err_disable_bus_clk:
351         clk_disable_unprepare(priv->bus_clk);
352 err_assert_reset:
353         reset_control_assert(priv->reset);
354
355         return ret;
356 }
357
358 static int sun50i_a100_ledc_suspend(struct device *dev)
359 {
360         struct sun50i_a100_ledc *priv = dev_get_drvdata(dev);
361
362         /* Wait for all transfers to complete. */
363         for (;;) {
364                 unsigned long flags;
365                 bool xfer_active;
366
367                 spin_lock_irqsave(&priv->lock, flags);
368                 xfer_active = priv->xfer_active;
369                 spin_unlock_irqrestore(&priv->lock, flags);
370                 if (!xfer_active)
371                         break;
372
373                 msleep(1);
374         }
375
376         clk_disable_unprepare(priv->mod_clk);
377         clk_disable_unprepare(priv->bus_clk);
378         reset_control_assert(priv->reset);
379
380         return 0;
381 }
382
383 static void sun50i_a100_ledc_dma_cleanup(void *data)
384 {
385         struct sun50i_a100_ledc *priv = data;
386
387         dma_release_channel(priv->dma_chan);
388 }
389
390 static int sun50i_a100_ledc_probe(struct platform_device *pdev)
391 {
392         struct dma_slave_config dma_cfg = {};
393         struct led_init_data init_data = {};
394         struct sun50i_a100_ledc_led *led;
395         struct device *dev = &pdev->dev;
396         struct sun50i_a100_ledc *priv;
397         struct fwnode_handle *child;
398         struct resource *mem;
399         u32 max_addr = 0;
400         u32 num_leds = 0;
401         int irq, ret;
402
403         /*
404          * The maximum LED address must be known in sun50i_a100_ledc_resume() before
405          * class device registration, so parse and validate the subnodes up front.
406          */
407         device_for_each_child_node(dev, child) {
408                 u32 addr, color;
409
410                 ret = fwnode_property_read_u32(child, "reg", &addr);
411                 if (ret || addr >= LEDC_MAX_LEDS) {
412                         fwnode_handle_put(child);
413                         return dev_err_probe(dev, -EINVAL, "'reg' must be between 0 and %d\n",
414                                              LEDC_MAX_LEDS - 1);
415                 }
416
417                 ret = fwnode_property_read_u32(child, "color", &color);
418                 if (ret || color != LED_COLOR_ID_RGB) {
419                         fwnode_handle_put(child);
420                         return dev_err_probe(dev, -EINVAL, "'color' must be LED_COLOR_ID_RGB\n");
421                 }
422
423                 max_addr = max(max_addr, addr);
424                 num_leds++;
425         }
426
427         if (!num_leds)
428                 return -ENODEV;
429
430         priv = devm_kzalloc(dev, struct_size(priv, leds, num_leds), GFP_KERNEL);
431         if (!priv)
432                 return -ENOMEM;
433
434         priv->dev = dev;
435         priv->max_addr = max_addr;
436         priv->num_leds = num_leds;
437         spin_lock_init(&priv->lock);
438         dev_set_drvdata(dev, priv);
439
440         ret = sun50i_a100_ledc_parse_format(dev, priv);
441         if (ret)
442                 return ret;
443
444         ret = sun50i_a100_ledc_parse_timing(dev, priv);
445         if (ret)
446                 return ret;
447
448         priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
449         if (IS_ERR(priv->base))
450                 return PTR_ERR(priv->base);
451
452         priv->bus_clk = devm_clk_get(dev, "bus");
453         if (IS_ERR(priv->bus_clk))
454                 return PTR_ERR(priv->bus_clk);
455
456         priv->mod_clk = devm_clk_get(dev, "mod");
457         if (IS_ERR(priv->mod_clk))
458                 return PTR_ERR(priv->mod_clk);
459
460         priv->reset = devm_reset_control_get_exclusive(dev, NULL);
461         if (IS_ERR(priv->reset))
462                 return PTR_ERR(priv->reset);
463
464         priv->dma_chan = dma_request_chan(dev, "tx");
465         if (IS_ERR(priv->dma_chan)) {
466                 if (PTR_ERR(priv->dma_chan) != -ENODEV)
467                         return PTR_ERR(priv->dma_chan);
468
469                 priv->dma_chan = NULL;
470
471                 priv->buffer = devm_kzalloc(dev, LEDS_TO_BYTES(LEDC_MAX_LEDS), GFP_KERNEL);
472                 if (!priv->buffer)
473                         return -ENOMEM;
474         } else {
475                 ret = devm_add_action_or_reset(dev, sun50i_a100_ledc_dma_cleanup, priv);
476                 if (ret)
477                         return ret;
478
479                 dma_cfg.dst_addr        = mem->start + LEDC_DATA_REG;
480                 dma_cfg.dst_addr_width  = DMA_SLAVE_BUSWIDTH_4_BYTES;
481                 dma_cfg.dst_maxburst    = LEDC_FIFO_DEPTH / 2;
482
483                 ret = dmaengine_slave_config(priv->dma_chan, &dma_cfg);
484                 if (ret)
485                         return ret;
486
487                 priv->buffer = dmam_alloc_attrs(dmaengine_get_dma_device(priv->dma_chan),
488                                                 LEDS_TO_BYTES(LEDC_MAX_LEDS), &priv->dma_handle,
489                                                 GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
490                 if (!priv->buffer)
491                         return -ENOMEM;
492         }
493
494         irq = platform_get_irq(pdev, 0);
495         if (irq < 0)
496                 return irq;
497
498         ret = devm_request_irq(dev, irq, sun50i_a100_ledc_irq, 0, dev_name(dev), priv);
499         if (ret)
500                 return ret;
501
502         ret = sun50i_a100_ledc_resume(dev);
503         if (ret)
504                 return ret;
505
506         led = priv->leds;
507         device_for_each_child_node(dev, child) {
508                 struct led_classdev *cdev;
509
510                 /* The node was already validated above. */
511                 fwnode_property_read_u32(child, "reg", &led->addr);
512
513                 led->subled_info[0].color_index = LED_COLOR_ID_RED;
514                 led->subled_info[0].channel = 0;
515                 led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
516                 led->subled_info[1].channel = 1;
517                 led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
518                 led->subled_info[2].channel = 2;
519
520                 led->mc_cdev.num_colors = ARRAY_SIZE(led->subled_info);
521                 led->mc_cdev.subled_info = led->subled_info;
522
523                 cdev = &led->mc_cdev.led_cdev;
524                 cdev->max_brightness = U8_MAX;
525                 cdev->brightness_set = sun50i_a100_ledc_brightness_set;
526
527                 init_data.fwnode = child;
528
529                 ret = led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data);
530                 if (ret) {
531                         dev_err_probe(dev, ret, "Failed to register multicolor LED %u", led->addr);
532                         goto err_put_child;
533                 }
534
535                 led++;
536         }
537
538         dev_info(dev, "Registered %u LEDs\n", num_leds);
539
540         return 0;
541
542 err_put_child:
543         fwnode_handle_put(child);
544         while (led-- > priv->leds)
545                 led_classdev_multicolor_unregister(&led->mc_cdev);
546         sun50i_a100_ledc_suspend(&pdev->dev);
547
548         return ret;
549 }
550
551 static void sun50i_a100_ledc_remove(struct platform_device *pdev)
552 {
553         struct sun50i_a100_ledc *priv = platform_get_drvdata(pdev);
554
555         for (u32 i = 0; i < priv->num_leds; i++)
556                 led_classdev_multicolor_unregister(&priv->leds[i].mc_cdev);
557         sun50i_a100_ledc_suspend(&pdev->dev);
558 }
559
560 static const struct of_device_id sun50i_a100_ledc_of_match[] = {
561         { .compatible = "allwinner,sun50i-a100-ledc" },
562         {}
563 };
564 MODULE_DEVICE_TABLE(of, sun50i_a100_ledc_of_match);
565
566 static DEFINE_SIMPLE_DEV_PM_OPS(sun50i_a100_ledc_pm,
567                                 sun50i_a100_ledc_suspend,
568                                 sun50i_a100_ledc_resume);
569
570 static struct platform_driver sun50i_a100_ledc_driver = {
571         .probe          = sun50i_a100_ledc_probe,
572         .remove_new     = sun50i_a100_ledc_remove,
573         .shutdown       = sun50i_a100_ledc_remove,
574         .driver         = {
575                 .name           = "sun50i-a100-ledc",
576                 .of_match_table = sun50i_a100_ledc_of_match,
577                 .pm             = pm_ptr(&sun50i_a100_ledc_pm),
578         },
579 };
580 module_platform_driver(sun50i_a100_ledc_driver);
581
582 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
583 MODULE_DESCRIPTION("Allwinner A100 LED controller driver");
584 MODULE_LICENSE("GPL");