forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
....@@ -18,6 +18,7 @@
1818 #include <linux/completion.h>
1919 #include <linux/delay.h>
2020 #include <linux/dma-mapping.h>
21
+#include <linux/dmaengine.h>
2122 #include <linux/errno.h>
2223 #include <linux/init.h>
2324 #include <linux/interrupt.h>
....@@ -79,14 +80,136 @@
7980 DMM_PAT_DESCR__2, DMM_PAT_DESCR__3},
8081 };
8182
83
+static int dmm_dma_copy(struct dmm *dmm, dma_addr_t src, dma_addr_t dst)
84
+{
85
+ struct dma_async_tx_descriptor *tx;
86
+ enum dma_status status;
87
+ dma_cookie_t cookie;
88
+
89
+ tx = dmaengine_prep_dma_memcpy(dmm->wa_dma_chan, dst, src, 4, 0);
90
+ if (!tx) {
91
+ dev_err(dmm->dev, "Failed to prepare DMA memcpy\n");
92
+ return -EIO;
93
+ }
94
+
95
+ cookie = tx->tx_submit(tx);
96
+ if (dma_submit_error(cookie)) {
97
+ dev_err(dmm->dev, "Failed to do DMA tx_submit\n");
98
+ return -EIO;
99
+ }
100
+
101
+ status = dma_sync_wait(dmm->wa_dma_chan, cookie);
102
+ if (status != DMA_COMPLETE)
103
+ dev_err(dmm->dev, "i878 wa DMA copy failure\n");
104
+
105
+ dmaengine_terminate_all(dmm->wa_dma_chan);
106
+ return 0;
107
+}
108
+
109
+static u32 dmm_read_wa(struct dmm *dmm, u32 reg)
110
+{
111
+ dma_addr_t src, dst;
112
+ int r;
113
+
114
+ src = dmm->phys_base + reg;
115
+ dst = dmm->wa_dma_handle;
116
+
117
+ r = dmm_dma_copy(dmm, src, dst);
118
+ if (r) {
119
+ dev_err(dmm->dev, "sDMA read transfer timeout\n");
120
+ return readl(dmm->base + reg);
121
+ }
122
+
123
+ /*
124
+ * As per i878 workaround, the DMA is used to access the DMM registers.
125
+ * Make sure that the readl is not moved by the compiler or the CPU
126
+ * earlier than the DMA finished writing the value to memory.
127
+ */
128
+ rmb();
129
+ return readl(dmm->wa_dma_data);
130
+}
131
+
132
+static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg)
133
+{
134
+ dma_addr_t src, dst;
135
+ int r;
136
+
137
+ writel(val, dmm->wa_dma_data);
138
+ /*
139
+ * As per i878 workaround, the DMA is used to access the DMM registers.
140
+ * Make sure that the writel is not moved by the compiler or the CPU, so
141
+ * the data will be in place before we start the DMA to do the actual
142
+ * register write.
143
+ */
144
+ wmb();
145
+
146
+ src = dmm->wa_dma_handle;
147
+ dst = dmm->phys_base + reg;
148
+
149
+ r = dmm_dma_copy(dmm, src, dst);
150
+ if (r) {
151
+ dev_err(dmm->dev, "sDMA write transfer timeout\n");
152
+ writel(val, dmm->base + reg);
153
+ }
154
+}
155
+
82156 static u32 dmm_read(struct dmm *dmm, u32 reg)
83157 {
84
- return readl(dmm->base + reg);
158
+ if (dmm->dmm_workaround) {
159
+ u32 v;
160
+ unsigned long flags;
161
+
162
+ spin_lock_irqsave(&dmm->wa_lock, flags);
163
+ v = dmm_read_wa(dmm, reg);
164
+ spin_unlock_irqrestore(&dmm->wa_lock, flags);
165
+
166
+ return v;
167
+ } else {
168
+ return readl(dmm->base + reg);
169
+ }
85170 }
86171
87172 static void dmm_write(struct dmm *dmm, u32 val, u32 reg)
88173 {
89
- writel(val, dmm->base + reg);
174
+ if (dmm->dmm_workaround) {
175
+ unsigned long flags;
176
+
177
+ spin_lock_irqsave(&dmm->wa_lock, flags);
178
+ dmm_write_wa(dmm, val, reg);
179
+ spin_unlock_irqrestore(&dmm->wa_lock, flags);
180
+ } else {
181
+ writel(val, dmm->base + reg);
182
+ }
183
+}
184
+
185
+static int dmm_workaround_init(struct dmm *dmm)
186
+{
187
+ dma_cap_mask_t mask;
188
+
189
+ spin_lock_init(&dmm->wa_lock);
190
+
191
+ dmm->wa_dma_data = dma_alloc_coherent(dmm->dev, sizeof(u32),
192
+ &dmm->wa_dma_handle, GFP_KERNEL);
193
+ if (!dmm->wa_dma_data)
194
+ return -ENOMEM;
195
+
196
+ dma_cap_zero(mask);
197
+ dma_cap_set(DMA_MEMCPY, mask);
198
+
199
+ dmm->wa_dma_chan = dma_request_channel(mask, NULL, NULL);
200
+ if (!dmm->wa_dma_chan) {
201
+ dma_free_coherent(dmm->dev, 4, dmm->wa_dma_data, dmm->wa_dma_handle);
202
+ return -ENODEV;
203
+ }
204
+
205
+ return 0;
206
+}
207
+
208
+static void dmm_workaround_uninit(struct dmm *dmm)
209
+{
210
+ dma_release_channel(dmm->wa_dma_chan);
211
+
212
+ dma_free_coherent(dmm->dev, 4, dmm->wa_dma_data, dmm->wa_dma_handle);
90213 }
91214
92215 /* simple allocator to grab next 16 byte aligned memory from txn */
....@@ -614,6 +737,10 @@
614737 unsigned long flags;
615738
616739 if (omap_dmm) {
740
+ /* Disable all enabled interrupts */
741
+ dmm_write(omap_dmm, 0x7e7e7e7e, DMM_PAT_IRQENABLE_CLR);
742
+ free_irq(omap_dmm->irq, omap_dmm);
743
+
617744 /* free all area regions */
618745 spin_lock_irqsave(&list_lock, flags);
619746 list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head,
....@@ -636,8 +763,8 @@
636763 if (omap_dmm->dummy_page)
637764 __free_page(omap_dmm->dummy_page);
638765
639
- if (omap_dmm->irq > 0)
640
- free_irq(omap_dmm->irq, omap_dmm);
766
+ if (omap_dmm->dmm_workaround)
767
+ dmm_workaround_uninit(omap_dmm);
641768
642769 iounmap(omap_dmm->base);
643770 kfree(omap_dmm);
....@@ -684,6 +811,7 @@
684811 goto fail;
685812 }
686813
814
+ omap_dmm->phys_base = mem->start;
687815 omap_dmm->base = ioremap(mem->start, SZ_2K);
688816
689817 if (!omap_dmm->base) {
....@@ -698,6 +826,22 @@
698826 }
699827
700828 omap_dmm->dev = &dev->dev;
829
+
830
+ if (of_machine_is_compatible("ti,dra7")) {
831
+ /*
832
+ * DRA7 Errata i878 says that MPU should not be used to access
833
+ * RAM and DMM at the same time. As it's not possible to prevent
834
+ * MPU accessing RAM, we need to access DMM via a proxy.
835
+ */
836
+ if (!dmm_workaround_init(omap_dmm)) {
837
+ omap_dmm->dmm_workaround = true;
838
+ dev_info(&dev->dev,
839
+ "workaround for errata i878 in use\n");
840
+ } else {
841
+ dev_warn(&dev->dev,
842
+ "failed to initialize work-around for i878\n");
843
+ }
844
+ }
701845
702846 hwinfo = dmm_read(omap_dmm, DMM_PAT_HWINFO);
703847 omap_dmm->num_engines = (hwinfo >> 24) & 0x1F;
....@@ -724,24 +868,6 @@
724868 dmm_write(omap_dmm, 0x80000000, DMM_PAT_VIEW_MAP_BASE);
725869 dmm_write(omap_dmm, 0x88888888, DMM_TILER_OR__0);
726870 dmm_write(omap_dmm, 0x88888888, DMM_TILER_OR__1);
727
-
728
- ret = request_irq(omap_dmm->irq, omap_dmm_irq_handler, IRQF_SHARED,
729
- "omap_dmm_irq_handler", omap_dmm);
730
-
731
- if (ret) {
732
- dev_err(&dev->dev, "couldn't register IRQ %d, error %d\n",
733
- omap_dmm->irq, ret);
734
- omap_dmm->irq = -1;
735
- goto fail;
736
- }
737
-
738
- /* Enable all interrupts for each refill engine except
739
- * ERR_LUT_MISS<n> (which is just advisory, and we don't care
740
- * about because we want to be able to refill live scanout
741
- * buffers for accelerated pan/scroll) and FILL_DSC<n> which
742
- * we just generally don't care about.
743
- */
744
- dmm_write(omap_dmm, 0x7e7e7e7e, DMM_PAT_IRQENABLE_SET);
745871
746872 omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
747873 if (!omap_dmm->dummy_page) {
....@@ -835,6 +961,24 @@
835961 .p1.y = omap_dmm->container_height - 1,
836962 };
837963
964
+ ret = request_irq(omap_dmm->irq, omap_dmm_irq_handler, IRQF_SHARED,
965
+ "omap_dmm_irq_handler", omap_dmm);
966
+
967
+ if (ret) {
968
+ dev_err(&dev->dev, "couldn't register IRQ %d, error %d\n",
969
+ omap_dmm->irq, ret);
970
+ omap_dmm->irq = -1;
971
+ goto fail;
972
+ }
973
+
974
+ /* Enable all interrupts for each refill engine except
975
+ * ERR_LUT_MISS<n> (which is just advisory, and we don't care
976
+ * about because we want to be able to refill live scanout
977
+ * buffers for accelerated pan/scroll) and FILL_DSC<n> which
978
+ * we just generally don't care about.
979
+ */
980
+ dmm_write(omap_dmm, 0x7e7e7e7e, DMM_PAT_IRQENABLE_SET);
981
+
838982 /* initialize all LUTs to dummy page entries */
839983 for (i = 0; i < omap_dmm->num_lut; i++) {
840984 area.tcm = omap_dmm->tcm[i];