1
2
3
4#include <linux/acpi.h>
5#include <linux/clk.h>
6#include <linux/slab.h>
7#include <linux/dma-mapping.h>
8#include <linux/io.h>
9#include <linux/module.h>
10#include <linux/of.h>
11#include <linux/of_platform.h>
12#include <linux/pinctrl/consumer.h>
13#include <linux/platform_device.h>
14#include <linux/qcom-geni-se.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#define MAX_CLK_PERF_LEVEL 32
81#define NUM_AHB_CLKS 2
82
83
84
85
86
87
88
89
90struct geni_wrapper {
91 struct device *dev;
92 void __iomem *base;
93 struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
94};
95
96static const char * const icc_path_names[] = {"qup-core", "qup-config",
97 "qup-memory"};
98
99#define QUP_HW_VER_REG 0x4
100
101
102#define GENI_INIT_CFG_REVISION 0x0
103#define GENI_S_INIT_CFG_REVISION 0x4
104#define GENI_OUTPUT_CTRL 0x24
105#define GENI_CGC_CTRL 0x28
106#define GENI_CLK_CTRL_RO 0x60
107#define GENI_FW_S_REVISION_RO 0x6c
108#define SE_GENI_BYTE_GRAN 0x254
109#define SE_GENI_TX_PACKING_CFG0 0x260
110#define SE_GENI_TX_PACKING_CFG1 0x264
111#define SE_GENI_RX_PACKING_CFG0 0x284
112#define SE_GENI_RX_PACKING_CFG1 0x288
113#define SE_GENI_M_GP_LENGTH 0x910
114#define SE_GENI_S_GP_LENGTH 0x914
115#define SE_DMA_TX_PTR_L 0xc30
116#define SE_DMA_TX_PTR_H 0xc34
117#define SE_DMA_TX_ATTR 0xc38
118#define SE_DMA_TX_LEN 0xc3c
119#define SE_DMA_TX_IRQ_EN 0xc48
120#define SE_DMA_TX_IRQ_EN_SET 0xc4c
121#define SE_DMA_TX_IRQ_EN_CLR 0xc50
122#define SE_DMA_TX_LEN_IN 0xc54
123#define SE_DMA_TX_MAX_BURST 0xc5c
124#define SE_DMA_RX_PTR_L 0xd30
125#define SE_DMA_RX_PTR_H 0xd34
126#define SE_DMA_RX_ATTR 0xd38
127#define SE_DMA_RX_LEN 0xd3c
128#define SE_DMA_RX_IRQ_EN 0xd48
129#define SE_DMA_RX_IRQ_EN_SET 0xd4c
130#define SE_DMA_RX_IRQ_EN_CLR 0xd50
131#define SE_DMA_RX_LEN_IN 0xd54
132#define SE_DMA_RX_MAX_BURST 0xd5c
133#define SE_DMA_RX_FLUSH 0xd60
134#define SE_GSI_EVENT_EN 0xe18
135#define SE_IRQ_EN 0xe1c
136#define SE_DMA_GENERAL_CFG 0xe30
137
138
139#define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0)
140
141
142#define CFG_AHB_CLK_CGC_ON BIT(0)
143#define CFG_AHB_WR_ACLK_CGC_ON BIT(1)
144#define DATA_AHB_CLK_CGC_ON BIT(2)
145#define SCLK_CGC_ON BIT(3)
146#define TX_CLK_CGC_ON BIT(4)
147#define RX_CLK_CGC_ON BIT(5)
148#define EXT_CLK_CGC_ON BIT(6)
149#define PROG_RAM_HCLK_OFF BIT(8)
150#define PROG_RAM_SCLK_OFF BIT(9)
151#define DEFAULT_CGC_EN GENMASK(6, 0)
152
153
154#define DMA_RX_EVENT_EN BIT(0)
155#define DMA_TX_EVENT_EN BIT(1)
156#define GENI_M_EVENT_EN BIT(2)
157#define GENI_S_EVENT_EN BIT(3)
158
159
160#define DMA_RX_IRQ_EN BIT(0)
161#define DMA_TX_IRQ_EN BIT(1)
162#define GENI_M_IRQ_EN BIT(2)
163#define GENI_S_IRQ_EN BIT(3)
164
165
166#define DMA_RX_CLK_CGC_ON BIT(0)
167#define DMA_TX_CLK_CGC_ON BIT(1)
168#define DMA_AHB_SLV_CFG_ON BIT(2)
169#define AHB_SEC_SLV_CLK_CGC_ON BIT(3)
170#define DUMMY_RX_NON_BUFFERABLE BIT(4)
171#define RX_DMA_ZERO_PADDING_EN BIT(5)
172#define RX_DMA_IRQ_DELAY_MSK GENMASK(8, 6)
173#define RX_DMA_IRQ_DELAY_SHFT 6
174
175
176
177
178
179
180
181u32 geni_se_get_qup_hw_version(struct geni_se *se)
182{
183 struct geni_wrapper *wrapper = se->wrapper;
184
185 return readl_relaxed(wrapper->base + QUP_HW_VER_REG);
186}
187EXPORT_SYMBOL(geni_se_get_qup_hw_version);
188
189static void geni_se_io_set_mode(void __iomem *base)
190{
191 u32 val;
192
193 val = readl_relaxed(base + SE_IRQ_EN);
194 val |= GENI_M_IRQ_EN | GENI_S_IRQ_EN;
195 val |= DMA_TX_IRQ_EN | DMA_RX_IRQ_EN;
196 writel_relaxed(val, base + SE_IRQ_EN);
197
198 val = readl_relaxed(base + SE_GENI_DMA_MODE_EN);
199 val &= ~GENI_DMA_MODE_EN;
200 writel_relaxed(val, base + SE_GENI_DMA_MODE_EN);
201
202 writel_relaxed(0, base + SE_GSI_EVENT_EN);
203}
204
205static void geni_se_io_init(void __iomem *base)
206{
207 u32 val;
208
209 val = readl_relaxed(base + GENI_CGC_CTRL);
210 val |= DEFAULT_CGC_EN;
211 writel_relaxed(val, base + GENI_CGC_CTRL);
212
213 val = readl_relaxed(base + SE_DMA_GENERAL_CFG);
214 val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON;
215 val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
216 writel_relaxed(val, base + SE_DMA_GENERAL_CFG);
217
218 writel_relaxed(DEFAULT_IO_OUTPUT_CTRL_MSK, base + GENI_OUTPUT_CTRL);
219 writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
220}
221
222static void geni_se_irq_clear(struct geni_se *se)
223{
224 writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
225 writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
226 writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
227 writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
228 writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
229 writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
230}
231
232
233
234
235
236
237
238
239
240
241void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
242{
243 u32 val;
244
245 geni_se_irq_clear(se);
246 geni_se_io_init(se->base);
247 geni_se_io_set_mode(se->base);
248
249 writel_relaxed(rx_wm, se->base + SE_GENI_RX_WATERMARK_REG);
250 writel_relaxed(rx_rfr, se->base + SE_GENI_RX_RFR_WATERMARK_REG);
251
252 val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
253 val |= M_COMMON_GENI_M_IRQ_EN;
254 writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
255
256 val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
257 val |= S_COMMON_GENI_S_IRQ_EN;
258 writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
259}
260EXPORT_SYMBOL(geni_se_init);
261
262static void geni_se_select_fifo_mode(struct geni_se *se)
263{
264 u32 proto = geni_se_read_proto(se);
265 u32 val, val_old;
266
267 geni_se_irq_clear(se);
268
269
270
271
272
273
274
275
276
277
278
279 if (proto != GENI_SE_UART) {
280 val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
281 val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
282 val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
283 if (val != val_old)
284 writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
285
286 val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
287 val |= S_CMD_DONE_EN;
288 if (val != val_old)
289 writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
290 }
291
292 val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
293 val &= ~GENI_DMA_MODE_EN;
294 if (val != val_old)
295 writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
296}
297
298static void geni_se_select_dma_mode(struct geni_se *se)
299{
300 u32 proto = geni_se_read_proto(se);
301 u32 val, val_old;
302
303 geni_se_irq_clear(se);
304
305 if (proto != GENI_SE_UART) {
306 val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
307 val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
308 val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
309 if (val != val_old)
310 writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
311
312 val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
313 val &= ~S_CMD_DONE_EN;
314 if (val != val_old)
315 writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
316 }
317
318 val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
319 val |= GENI_DMA_MODE_EN;
320 if (val != val_old)
321 writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
322}
323
324static void geni_se_select_gpi_mode(struct geni_se *se)
325{
326 u32 val;
327
328 geni_se_irq_clear(se);
329
330 writel(0, se->base + SE_IRQ_EN);
331
332 val = readl(se->base + SE_GENI_S_IRQ_EN);
333 val &= ~S_CMD_DONE_EN;
334 writel(val, se->base + SE_GENI_S_IRQ_EN);
335
336 val = readl(se->base + SE_GENI_M_IRQ_EN);
337 val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN |
338 M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
339 writel(val, se->base + SE_GENI_M_IRQ_EN);
340
341 writel(GENI_DMA_MODE_EN, se->base + SE_GENI_DMA_MODE_EN);
342
343 val = readl(se->base + SE_GSI_EVENT_EN);
344 val |= (DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | GENI_M_EVENT_EN | GENI_S_EVENT_EN);
345 writel(val, se->base + SE_GSI_EVENT_EN);
346}
347
348
349
350
351
352
353void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
354{
355 WARN_ON(mode != GENI_SE_FIFO && mode != GENI_SE_DMA && mode != GENI_GPI_DMA);
356
357 switch (mode) {
358 case GENI_SE_FIFO:
359 geni_se_select_fifo_mode(se);
360 break;
361 case GENI_SE_DMA:
362 geni_se_select_dma_mode(se);
363 break;
364 case GENI_GPI_DMA:
365 geni_se_select_gpi_mode(se);
366 break;
367 case GENI_SE_INVALID:
368 default:
369 break;
370 }
371}
372EXPORT_SYMBOL(geni_se_select_mode);
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418#define NUM_PACKING_VECTORS 4
419#define PACKING_START_SHIFT 5
420#define PACKING_DIR_SHIFT 4
421#define PACKING_LEN_SHIFT 1
422#define PACKING_STOP_BIT BIT(0)
423#define PACKING_VECTOR_SHIFT 10
424
425
426
427
428
429
430
431
432
433
434
435
436void geni_se_config_packing(struct geni_se *se, int bpw, int pack_words,
437 bool msb_to_lsb, bool tx_cfg, bool rx_cfg)
438{
439 u32 cfg0, cfg1, cfg[NUM_PACKING_VECTORS] = {0};
440 int len;
441 int temp_bpw = bpw;
442 int idx_start = msb_to_lsb ? bpw - 1 : 0;
443 int idx = idx_start;
444 int idx_delta = msb_to_lsb ? -BITS_PER_BYTE : BITS_PER_BYTE;
445 int ceil_bpw = ALIGN(bpw, BITS_PER_BYTE);
446 int iter = (ceil_bpw * pack_words) / BITS_PER_BYTE;
447 int i;
448
449 if (iter <= 0 || iter > NUM_PACKING_VECTORS)
450 return;
451
452 for (i = 0; i < iter; i++) {
453 len = min_t(int, temp_bpw, BITS_PER_BYTE) - 1;
454 cfg[i] = idx << PACKING_START_SHIFT;
455 cfg[i] |= msb_to_lsb << PACKING_DIR_SHIFT;
456 cfg[i] |= len << PACKING_LEN_SHIFT;
457
458 if (temp_bpw <= BITS_PER_BYTE) {
459 idx = ((i + 1) * BITS_PER_BYTE) + idx_start;
460 temp_bpw = bpw;
461 } else {
462 idx = idx + idx_delta;
463 temp_bpw = temp_bpw - BITS_PER_BYTE;
464 }
465 }
466 cfg[iter - 1] |= PACKING_STOP_BIT;
467 cfg0 = cfg[0] | (cfg[1] << PACKING_VECTOR_SHIFT);
468 cfg1 = cfg[2] | (cfg[3] << PACKING_VECTOR_SHIFT);
469
470 if (tx_cfg) {
471 writel_relaxed(cfg0, se->base + SE_GENI_TX_PACKING_CFG0);
472 writel_relaxed(cfg1, se->base + SE_GENI_TX_PACKING_CFG1);
473 }
474 if (rx_cfg) {
475 writel_relaxed(cfg0, se->base + SE_GENI_RX_PACKING_CFG0);
476 writel_relaxed(cfg1, se->base + SE_GENI_RX_PACKING_CFG1);
477 }
478
479
480
481
482
483
484
485
486 if (pack_words || bpw == 32)
487 writel_relaxed(bpw / 16, se->base + SE_GENI_BYTE_GRAN);
488}
489EXPORT_SYMBOL(geni_se_config_packing);
490
491static void geni_se_clks_off(struct geni_se *se)
492{
493 struct geni_wrapper *wrapper = se->wrapper;
494
495 clk_disable_unprepare(se->clk);
496 clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks),
497 wrapper->ahb_clks);
498}
499
500
501
502
503
504
505
506
507int geni_se_resources_off(struct geni_se *se)
508{
509 int ret;
510
511 if (has_acpi_companion(se->dev))
512 return 0;
513
514 ret = pinctrl_pm_select_sleep_state(se->dev);
515 if (ret)
516 return ret;
517
518 geni_se_clks_off(se);
519 return 0;
520}
521EXPORT_SYMBOL(geni_se_resources_off);
522
523static int geni_se_clks_on(struct geni_se *se)
524{
525 int ret;
526 struct geni_wrapper *wrapper = se->wrapper;
527
528 ret = clk_bulk_prepare_enable(ARRAY_SIZE(wrapper->ahb_clks),
529 wrapper->ahb_clks);
530 if (ret)
531 return ret;
532
533 ret = clk_prepare_enable(se->clk);
534 if (ret)
535 clk_bulk_disable_unprepare(ARRAY_SIZE(wrapper->ahb_clks),
536 wrapper->ahb_clks);
537 return ret;
538}
539
540
541
542
543
544
545
546
547int geni_se_resources_on(struct geni_se *se)
548{
549 int ret;
550
551 if (has_acpi_companion(se->dev))
552 return 0;
553
554 ret = geni_se_clks_on(se);
555 if (ret)
556 return ret;
557
558 ret = pinctrl_pm_select_default_state(se->dev);
559 if (ret)
560 geni_se_clks_off(se);
561
562 return ret;
563}
564EXPORT_SYMBOL(geni_se_resources_on);
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl)
580{
581 long freq = 0;
582 int i;
583
584 if (se->clk_perf_tbl) {
585 *tbl = se->clk_perf_tbl;
586 return se->num_clk_levels;
587 }
588
589 se->clk_perf_tbl = devm_kcalloc(se->dev, MAX_CLK_PERF_LEVEL,
590 sizeof(*se->clk_perf_tbl),
591 GFP_KERNEL);
592 if (!se->clk_perf_tbl)
593 return -ENOMEM;
594
595 for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) {
596 freq = clk_round_rate(se->clk, freq + 1);
597 if (freq <= 0 || freq == se->clk_perf_tbl[i - 1])
598 break;
599 se->clk_perf_tbl[i] = freq;
600 }
601 se->num_clk_levels = i;
602 *tbl = se->clk_perf_tbl;
603 return se->num_clk_levels;
604}
605EXPORT_SYMBOL(geni_se_clk_tbl_get);
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
627 unsigned int *index, unsigned long *res_freq,
628 bool exact)
629{
630 unsigned long *tbl;
631 int num_clk_levels;
632 int i;
633 unsigned long best_delta;
634 unsigned long new_delta;
635 unsigned int divider;
636
637 num_clk_levels = geni_se_clk_tbl_get(se, &tbl);
638 if (num_clk_levels < 0)
639 return num_clk_levels;
640
641 if (num_clk_levels == 0)
642 return -EINVAL;
643
644 best_delta = ULONG_MAX;
645 for (i = 0; i < num_clk_levels; i++) {
646 divider = DIV_ROUND_UP(tbl[i], req_freq);
647 new_delta = req_freq - tbl[i] / divider;
648 if (new_delta < best_delta) {
649
650 *index = i;
651 *res_freq = tbl[i];
652
653
654 if (new_delta == 0)
655 return 0;
656
657
658 best_delta = new_delta;
659 }
660 }
661
662 if (exact)
663 return -EINVAL;
664
665 return 0;
666}
667EXPORT_SYMBOL(geni_se_clk_freq_match);
668
669#define GENI_SE_DMA_DONE_EN BIT(0)
670#define GENI_SE_DMA_EOT_EN BIT(1)
671#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
672#define GENI_SE_DMA_EOT_BUF BIT(0)
673
674
675
676
677
678
679
680
681
682
683
684int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
685 dma_addr_t *iova)
686{
687 struct geni_wrapper *wrapper = se->wrapper;
688 u32 val;
689
690 if (!wrapper)
691 return -EINVAL;
692
693 *iova = dma_map_single(wrapper->dev, buf, len, DMA_TO_DEVICE);
694 if (dma_mapping_error(wrapper->dev, *iova))
695 return -EIO;
696
697 val = GENI_SE_DMA_DONE_EN;
698 val |= GENI_SE_DMA_EOT_EN;
699 val |= GENI_SE_DMA_AHB_ERR_EN;
700 writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
701 writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
702 writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
703 writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
704 writel(len, se->base + SE_DMA_TX_LEN);
705 return 0;
706}
707EXPORT_SYMBOL(geni_se_tx_dma_prep);
708
709
710
711
712
713
714
715
716
717
718
719
720int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
721 dma_addr_t *iova)
722{
723 struct geni_wrapper *wrapper = se->wrapper;
724 u32 val;
725
726 if (!wrapper)
727 return -EINVAL;
728
729 *iova = dma_map_single(wrapper->dev, buf, len, DMA_FROM_DEVICE);
730 if (dma_mapping_error(wrapper->dev, *iova))
731 return -EIO;
732
733 val = GENI_SE_DMA_DONE_EN;
734 val |= GENI_SE_DMA_EOT_EN;
735 val |= GENI_SE_DMA_AHB_ERR_EN;
736 writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
737 writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_RX_PTR_L);
738 writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
739
740 writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
741 writel(len, se->base + SE_DMA_RX_LEN);
742 return 0;
743}
744EXPORT_SYMBOL(geni_se_rx_dma_prep);
745
746
747
748
749
750
751
752
753
754void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
755{
756 struct geni_wrapper *wrapper = se->wrapper;
757
758 if (!dma_mapping_error(wrapper->dev, iova))
759 dma_unmap_single(wrapper->dev, iova, len, DMA_TO_DEVICE);
760}
761EXPORT_SYMBOL(geni_se_tx_dma_unprep);
762
763
764
765
766
767
768
769
770
771void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
772{
773 struct geni_wrapper *wrapper = se->wrapper;
774
775 if (!dma_mapping_error(wrapper->dev, iova))
776 dma_unmap_single(wrapper->dev, iova, len, DMA_FROM_DEVICE);
777}
778EXPORT_SYMBOL(geni_se_rx_dma_unprep);
779
780int geni_icc_get(struct geni_se *se, const char *icc_ddr)
781{
782 int i, err;
783 const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
784
785 if (has_acpi_companion(se->dev))
786 return 0;
787
788 for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
789 if (!icc_names[i])
790 continue;
791
792 se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
793 if (IS_ERR(se->icc_paths[i].path))
794 goto err;
795 }
796
797 return 0;
798
799err:
800 err = PTR_ERR(se->icc_paths[i].path);
801 if (err != -EPROBE_DEFER)
802 dev_err_ratelimited(se->dev, "Failed to get ICC path '%s': %d\n",
803 icc_names[i], err);
804 return err;
805
806}
807EXPORT_SYMBOL(geni_icc_get);
808
809int geni_icc_set_bw(struct geni_se *se)
810{
811 int i, ret;
812
813 for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
814 ret = icc_set_bw(se->icc_paths[i].path,
815 se->icc_paths[i].avg_bw, se->icc_paths[i].avg_bw);
816 if (ret) {
817 dev_err_ratelimited(se->dev, "ICC BW voting failed on path '%s': %d\n",
818 icc_path_names[i], ret);
819 return ret;
820 }
821 }
822
823 return 0;
824}
825EXPORT_SYMBOL(geni_icc_set_bw);
826
827void geni_icc_set_tag(struct geni_se *se, u32 tag)
828{
829 int i;
830
831 for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++)
832 icc_set_tag(se->icc_paths[i].path, tag);
833}
834EXPORT_SYMBOL(geni_icc_set_tag);
835
836
837int geni_icc_enable(struct geni_se *se)
838{
839 int i, ret;
840
841 for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
842 ret = icc_enable(se->icc_paths[i].path);
843 if (ret) {
844 dev_err_ratelimited(se->dev, "ICC enable failed on path '%s': %d\n",
845 icc_path_names[i], ret);
846 return ret;
847 }
848 }
849
850 return 0;
851}
852EXPORT_SYMBOL(geni_icc_enable);
853
854int geni_icc_disable(struct geni_se *se)
855{
856 int i, ret;
857
858 for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
859 ret = icc_disable(se->icc_paths[i].path);
860 if (ret) {
861 dev_err_ratelimited(se->dev, "ICC disable failed on path '%s': %d\n",
862 icc_path_names[i], ret);
863 return ret;
864 }
865 }
866
867 return 0;
868}
869EXPORT_SYMBOL(geni_icc_disable);
870
871static int geni_se_probe(struct platform_device *pdev)
872{
873 struct device *dev = &pdev->dev;
874 struct resource *res;
875 struct geni_wrapper *wrapper;
876 int ret;
877
878 wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
879 if (!wrapper)
880 return -ENOMEM;
881
882 wrapper->dev = dev;
883 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
884 wrapper->base = devm_ioremap_resource(dev, res);
885 if (IS_ERR(wrapper->base))
886 return PTR_ERR(wrapper->base);
887
888 if (!has_acpi_companion(&pdev->dev)) {
889 wrapper->ahb_clks[0].id = "m-ahb";
890 wrapper->ahb_clks[1].id = "s-ahb";
891 ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks);
892 if (ret) {
893 dev_err(dev, "Err getting AHB clks %d\n", ret);
894 return ret;
895 }
896 }
897
898 dev_set_drvdata(dev, wrapper);
899 dev_dbg(dev, "GENI SE Driver probed\n");
900 return devm_of_platform_populate(dev);
901}
902
903static const struct of_device_id geni_se_dt_match[] = {
904 { .compatible = "qcom,geni-se-qup", },
905 {}
906};
907MODULE_DEVICE_TABLE(of, geni_se_dt_match);
908
909static struct platform_driver geni_se_driver = {
910 .driver = {
911 .name = "geni_se_qup",
912 .of_match_table = geni_se_dt_match,
913 },
914 .probe = geni_se_probe,
915};
916module_platform_driver(geni_se_driver);
917
918MODULE_DESCRIPTION("GENI Serial Engine Driver");
919MODULE_LICENSE("GPL v2");
920