hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/soc/qcom/qcom-geni-se.c
....@@ -1,6 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
22 // Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
33
4
+#include <linux/acpi.h>
45 #include <linux/clk.h>
56 #include <linux/slab.h>
67 #include <linux/dma-mapping.h>
....@@ -90,6 +91,9 @@
9091 void __iomem *base;
9192 struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
9293 };
94
+
95
+static const char * const icc_path_names[] = {"qup-core", "qup-config",
96
+ "qup-memory"};
9397
9498 #define QUP_HW_VER_REG 0x4
9599
....@@ -215,6 +219,16 @@
215219 writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
216220 }
217221
222
+static 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
+
218232 /**
219233 * geni_se_init() - Initialize the GENI serial engine
220234 * @se: Pointer to the concerned serial engine.
....@@ -228,6 +242,7 @@
228242 {
229243 u32 val;
230244
245
+ geni_se_irq_clear(se);
231246 geni_se_io_init(se->base);
232247 geni_se_io_set_mode(se->base);
233248
....@@ -249,12 +264,7 @@
249264 u32 proto = geni_se_read_proto(se);
250265 u32 val;
251266
252
- writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
253
- writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
254
- writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
255
- writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
256
- writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
257
- writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
267
+ geni_se_irq_clear(se);
258268
259269 val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
260270 if (proto != GENI_SE_UART) {
....@@ -278,12 +288,7 @@
278288 u32 proto = geni_se_read_proto(se);
279289 u32 val;
280290
281
- writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
282
- writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
283
- writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
284
- writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
285
- writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
286
- writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
291
+ geni_se_irq_clear(se);
287292
288293 val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
289294 if (proto != GENI_SE_UART) {
....@@ -462,6 +467,9 @@
462467 {
463468 int ret;
464469
470
+ if (has_acpi_companion(se->dev))
471
+ return 0;
472
+
465473 ret = pinctrl_pm_select_sleep_state(se->dev);
466474 if (ret)
467475 return ret;
....@@ -498,6 +506,9 @@
498506 int geni_se_resources_on(struct geni_se *se)
499507 {
500508 int ret;
509
+
510
+ if (has_acpi_companion(se->dev))
511
+ return 0;
501512
502513 ret = geni_se_clks_on(se);
503514 if (ret)
....@@ -635,6 +646,9 @@
635646 struct geni_wrapper *wrapper = se->wrapper;
636647 u32 val;
637648
649
+ if (!wrapper)
650
+ return -EINVAL;
651
+
638652 *iova = dma_map_single(wrapper->dev, buf, len, DMA_TO_DEVICE);
639653 if (dma_mapping_error(wrapper->dev, *iova))
640654 return -EIO;
....@@ -667,6 +681,9 @@
667681 {
668682 struct geni_wrapper *wrapper = se->wrapper;
669683 u32 val;
684
+
685
+ if (!wrapper)
686
+ return -EINVAL;
670687
671688 *iova = dma_map_single(wrapper->dev, buf, len, DMA_FROM_DEVICE);
672689 if (dma_mapping_error(wrapper->dev, *iova))
....@@ -719,6 +736,97 @@
719736 }
720737 EXPORT_SYMBOL(geni_se_rx_dma_unprep);
721738
739
+int geni_icc_get(struct geni_se *se, const char *icc_ddr)
740
+{
741
+ int i, err;
742
+ const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
743
+
744
+ if (has_acpi_companion(se->dev))
745
+ return 0;
746
+
747
+ for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
748
+ if (!icc_names[i])
749
+ continue;
750
+
751
+ se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
752
+ if (IS_ERR(se->icc_paths[i].path))
753
+ goto err;
754
+ }
755
+
756
+ return 0;
757
+
758
+err:
759
+ err = PTR_ERR(se->icc_paths[i].path);
760
+ if (err != -EPROBE_DEFER)
761
+ dev_err_ratelimited(se->dev, "Failed to get ICC path '%s': %d\n",
762
+ icc_names[i], err);
763
+ return err;
764
+
765
+}
766
+EXPORT_SYMBOL(geni_icc_get);
767
+
768
+int geni_icc_set_bw(struct geni_se *se)
769
+{
770
+ int i, ret;
771
+
772
+ for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
773
+ ret = icc_set_bw(se->icc_paths[i].path,
774
+ se->icc_paths[i].avg_bw, se->icc_paths[i].avg_bw);
775
+ if (ret) {
776
+ dev_err_ratelimited(se->dev, "ICC BW voting failed on path '%s': %d\n",
777
+ icc_path_names[i], ret);
778
+ return ret;
779
+ }
780
+ }
781
+
782
+ return 0;
783
+}
784
+EXPORT_SYMBOL(geni_icc_set_bw);
785
+
786
+void geni_icc_set_tag(struct geni_se *se, u32 tag)
787
+{
788
+ int i;
789
+
790
+ for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++)
791
+ icc_set_tag(se->icc_paths[i].path, tag);
792
+}
793
+EXPORT_SYMBOL(geni_icc_set_tag);
794
+
795
+/* To do: Replace this by icc_bulk_enable once it's implemented in ICC core */
796
+int geni_icc_enable(struct geni_se *se)
797
+{
798
+ int i, ret;
799
+
800
+ for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
801
+ ret = icc_enable(se->icc_paths[i].path);
802
+ if (ret) {
803
+ dev_err_ratelimited(se->dev, "ICC enable failed on path '%s': %d\n",
804
+ icc_path_names[i], ret);
805
+ return ret;
806
+ }
807
+ }
808
+
809
+ return 0;
810
+}
811
+EXPORT_SYMBOL(geni_icc_enable);
812
+
813
+int geni_icc_disable(struct geni_se *se)
814
+{
815
+ int i, ret;
816
+
817
+ for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
818
+ ret = icc_disable(se->icc_paths[i].path);
819
+ if (ret) {
820
+ dev_err_ratelimited(se->dev, "ICC disable failed on path '%s': %d\n",
821
+ icc_path_names[i], ret);
822
+ return ret;
823
+ }
824
+ }
825
+
826
+ return 0;
827
+}
828
+EXPORT_SYMBOL(geni_icc_disable);
829
+
722830 static int geni_se_probe(struct platform_device *pdev)
723831 {
724832 struct device *dev = &pdev->dev;
....@@ -736,12 +844,14 @@
736844 if (IS_ERR(wrapper->base))
737845 return PTR_ERR(wrapper->base);
738846
739
- wrapper->ahb_clks[0].id = "m-ahb";
740
- wrapper->ahb_clks[1].id = "s-ahb";
741
- ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks);
742
- if (ret) {
743
- dev_err(dev, "Err getting AHB clks %d\n", ret);
744
- return ret;
847
+ if (!has_acpi_companion(&pdev->dev)) {
848
+ wrapper->ahb_clks[0].id = "m-ahb";
849
+ wrapper->ahb_clks[1].id = "s-ahb";
850
+ ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks);
851
+ if (ret) {
852
+ dev_err(dev, "Err getting AHB clks %d\n", ret);
853
+ return ret;
854
+ }
745855 }
746856
747857 dev_set_drvdata(dev, wrapper);