]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
dd1ecf4276d39fd19240477f421b0356c8b77884
[linux.git] / drivers / gpu / drm / arm / display / komeda / d71 / d71_dev.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4  * Author: James.Qian.Wang <james.qian.wang@arm.com>
5  *
6  */
7
8 #include <drm/drm_print.h>
9 #include "d71_dev.h"
10 #include "malidp_io.h"
11
12 static u64 get_lpu_event(struct d71_pipeline *d71_pipeline)
13 {
14         u32 __iomem *reg = d71_pipeline->lpu_addr;
15         u32 status, raw_status;
16         u64 evts = 0ULL;
17
18         raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
19         if (raw_status & LPU_IRQ_IBSY)
20                 evts |= KOMEDA_EVENT_IBSY;
21         if (raw_status & LPU_IRQ_EOW)
22                 evts |= KOMEDA_EVENT_EOW;
23
24         if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY)) {
25                 u32 restore = 0, tbu_status;
26                 /* Check error of LPU status */
27                 status = malidp_read32(reg, BLK_STATUS);
28                 if (status & LPU_STATUS_AXIE) {
29                         restore |= LPU_STATUS_AXIE;
30                         evts |= KOMEDA_ERR_AXIE;
31                 }
32                 if (status & LPU_STATUS_ACE0) {
33                         restore |= LPU_STATUS_ACE0;
34                         evts |= KOMEDA_ERR_ACE0;
35                 }
36                 if (status & LPU_STATUS_ACE1) {
37                         restore |= LPU_STATUS_ACE1;
38                         evts |= KOMEDA_ERR_ACE1;
39                 }
40                 if (status & LPU_STATUS_ACE2) {
41                         restore |= LPU_STATUS_ACE2;
42                         evts |= KOMEDA_ERR_ACE2;
43                 }
44                 if (status & LPU_STATUS_ACE3) {
45                         restore |= LPU_STATUS_ACE3;
46                         evts |= KOMEDA_ERR_ACE3;
47                 }
48                 if (restore != 0)
49                         malidp_write32_mask(reg, BLK_STATUS, restore, 0);
50
51                 restore = 0;
52                 /* Check errors of TBU status */
53                 tbu_status = malidp_read32(reg, LPU_TBU_STATUS);
54                 if (tbu_status & LPU_TBU_STATUS_TCF) {
55                         restore |= LPU_TBU_STATUS_TCF;
56                         evts |= KOMEDA_ERR_TCF;
57                 }
58                 if (tbu_status & LPU_TBU_STATUS_TTNG) {
59                         restore |= LPU_TBU_STATUS_TTNG;
60                         evts |= KOMEDA_ERR_TTNG;
61                 }
62                 if (tbu_status & LPU_TBU_STATUS_TITR) {
63                         restore |= LPU_TBU_STATUS_TITR;
64                         evts |= KOMEDA_ERR_TITR;
65                 }
66                 if (tbu_status & LPU_TBU_STATUS_TEMR) {
67                         restore |= LPU_TBU_STATUS_TEMR;
68                         evts |= KOMEDA_ERR_TEMR;
69                 }
70                 if (tbu_status & LPU_TBU_STATUS_TTF) {
71                         restore |= LPU_TBU_STATUS_TTF;
72                         evts |= KOMEDA_ERR_TTF;
73                 }
74                 if (restore != 0)
75                         malidp_write32_mask(reg, LPU_TBU_STATUS, restore, 0);
76         }
77
78         malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
79         return evts;
80 }
81
82 static u64 get_cu_event(struct d71_pipeline *d71_pipeline)
83 {
84         u32 __iomem *reg = d71_pipeline->cu_addr;
85         u32 status, raw_status;
86         u64 evts = 0ULL;
87
88         raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
89         if (raw_status & CU_IRQ_OVR)
90                 evts |= KOMEDA_EVENT_OVR;
91
92         if (raw_status & (CU_IRQ_ERR | CU_IRQ_OVR)) {
93                 status = malidp_read32(reg, BLK_STATUS) & 0x7FFFFFFF;
94                 if (status & CU_STATUS_CPE)
95                         evts |= KOMEDA_ERR_CPE;
96                 if (status & CU_STATUS_ZME)
97                         evts |= KOMEDA_ERR_ZME;
98                 if (status & CU_STATUS_CFGE)
99                         evts |= KOMEDA_ERR_CFGE;
100                 if (status)
101                         malidp_write32_mask(reg, BLK_STATUS, status, 0);
102         }
103
104         malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
105
106         return evts;
107 }
108
109 static u64 get_dou_event(struct d71_pipeline *d71_pipeline)
110 {
111         u32 __iomem *reg = d71_pipeline->dou_addr;
112         u32 status, raw_status;
113         u64 evts = 0ULL;
114
115         raw_status = malidp_read32(reg, BLK_IRQ_RAW_STATUS);
116         if (raw_status & DOU_IRQ_PL0)
117                 evts |= KOMEDA_EVENT_VSYNC;
118         if (raw_status & DOU_IRQ_UND)
119                 evts |= KOMEDA_EVENT_URUN;
120
121         if (raw_status & (DOU_IRQ_ERR | DOU_IRQ_UND)) {
122                 u32 restore  = 0;
123
124                 status = malidp_read32(reg, BLK_STATUS);
125                 if (status & DOU_STATUS_DRIFTTO) {
126                         restore |= DOU_STATUS_DRIFTTO;
127                         evts |= KOMEDA_ERR_DRIFTTO;
128                 }
129                 if (status & DOU_STATUS_FRAMETO) {
130                         restore |= DOU_STATUS_FRAMETO;
131                         evts |= KOMEDA_ERR_FRAMETO;
132                 }
133                 if (status & DOU_STATUS_TETO) {
134                         restore |= DOU_STATUS_TETO;
135                         evts |= KOMEDA_ERR_TETO;
136                 }
137                 if (status & DOU_STATUS_CSCE) {
138                         restore |= DOU_STATUS_CSCE;
139                         evts |= KOMEDA_ERR_CSCE;
140                 }
141
142                 if (restore != 0)
143                         malidp_write32_mask(reg, BLK_STATUS, restore, 0);
144         }
145
146         malidp_write32(reg, BLK_IRQ_CLEAR, raw_status);
147         return evts;
148 }
149
150 static u64 get_pipeline_event(struct d71_pipeline *d71_pipeline, u32 gcu_status)
151 {
152         u32 evts = 0ULL;
153
154         if (gcu_status & (GLB_IRQ_STATUS_LPU0 | GLB_IRQ_STATUS_LPU1))
155                 evts |= get_lpu_event(d71_pipeline);
156
157         if (gcu_status & (GLB_IRQ_STATUS_CU0 | GLB_IRQ_STATUS_CU1))
158                 evts |= get_cu_event(d71_pipeline);
159
160         if (gcu_status & (GLB_IRQ_STATUS_DOU0 | GLB_IRQ_STATUS_DOU1))
161                 evts |= get_dou_event(d71_pipeline);
162
163         return evts;
164 }
165
166 static irqreturn_t
167 d71_irq_handler(struct komeda_dev *mdev, struct komeda_events *evts)
168 {
169         struct d71_dev *d71 = mdev->chip_data;
170         u32 status, gcu_status, raw_status;
171
172         gcu_status = malidp_read32(d71->gcu_addr, GLB_IRQ_STATUS);
173
174         if (gcu_status & GLB_IRQ_STATUS_GCU) {
175                 raw_status = malidp_read32(d71->gcu_addr, BLK_IRQ_RAW_STATUS);
176                 if (raw_status & GCU_IRQ_CVAL0)
177                         evts->pipes[0] |= KOMEDA_EVENT_FLIP;
178                 if (raw_status & GCU_IRQ_CVAL1)
179                         evts->pipes[1] |= KOMEDA_EVENT_FLIP;
180                 if (raw_status & GCU_IRQ_ERR) {
181                         status = malidp_read32(d71->gcu_addr, BLK_STATUS);
182                         if (status & GCU_STATUS_MERR) {
183                                 evts->global |= KOMEDA_ERR_MERR;
184                                 malidp_write32_mask(d71->gcu_addr, BLK_STATUS,
185                                                     GCU_STATUS_MERR, 0);
186                         }
187                 }
188
189                 malidp_write32(d71->gcu_addr, BLK_IRQ_CLEAR, raw_status);
190         }
191
192         if (gcu_status & GLB_IRQ_STATUS_PIPE0)
193                 evts->pipes[0] |= get_pipeline_event(d71->pipes[0], gcu_status);
194
195         if (gcu_status & GLB_IRQ_STATUS_PIPE1)
196                 evts->pipes[1] |= get_pipeline_event(d71->pipes[1], gcu_status);
197
198         return IRQ_RETVAL(gcu_status);
199 }
200
201 #define ENABLED_GCU_IRQS        (GCU_IRQ_CVAL0 | GCU_IRQ_CVAL1 | \
202                                  GCU_IRQ_MODE | GCU_IRQ_ERR)
203 #define ENABLED_LPU_IRQS        (LPU_IRQ_IBSY | LPU_IRQ_ERR | LPU_IRQ_EOW)
204 #define ENABLED_CU_IRQS         (CU_IRQ_OVR | CU_IRQ_ERR)
205 #define ENABLED_DOU_IRQS        (DOU_IRQ_UND | DOU_IRQ_ERR)
206
207 static int d71_enable_irq(struct komeda_dev *mdev)
208 {
209         struct d71_dev *d71 = mdev->chip_data;
210         struct d71_pipeline *pipe;
211         u32 i;
212
213         malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK,
214                             ENABLED_GCU_IRQS, ENABLED_GCU_IRQS);
215         for (i = 0; i < d71->num_pipelines; i++) {
216                 pipe = d71->pipes[i];
217                 malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
218                                     ENABLED_CU_IRQS, ENABLED_CU_IRQS);
219                 malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
220                                     ENABLED_LPU_IRQS, ENABLED_LPU_IRQS);
221                 malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
222                                     ENABLED_DOU_IRQS, ENABLED_DOU_IRQS);
223         }
224         return 0;
225 }
226
227 static int d71_disable_irq(struct komeda_dev *mdev)
228 {
229         struct d71_dev *d71 = mdev->chip_data;
230         struct d71_pipeline *pipe;
231         u32 i;
232
233         malidp_write32_mask(d71->gcu_addr, BLK_IRQ_MASK, ENABLED_GCU_IRQS, 0);
234         for (i = 0; i < d71->num_pipelines; i++) {
235                 pipe = d71->pipes[i];
236                 malidp_write32_mask(pipe->cu_addr,  BLK_IRQ_MASK,
237                                     ENABLED_CU_IRQS, 0);
238                 malidp_write32_mask(pipe->lpu_addr, BLK_IRQ_MASK,
239                                     ENABLED_LPU_IRQS, 0);
240                 malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
241                                     ENABLED_DOU_IRQS, 0);
242         }
243         return 0;
244 }
245
246 static void d71_on_off_vblank(struct komeda_dev *mdev, int master_pipe, bool on)
247 {
248         struct d71_dev *d71 = mdev->chip_data;
249         struct d71_pipeline *pipe = d71->pipes[master_pipe];
250
251         malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
252                             DOU_IRQ_PL0, on ? DOU_IRQ_PL0 : 0);
253 }
254
255 static int to_d71_opmode(int core_mode)
256 {
257         switch (core_mode) {
258         case KOMEDA_MODE_DISP0:
259                 return DO0_ACTIVE_MODE;
260         case KOMEDA_MODE_DISP1:
261                 return DO1_ACTIVE_MODE;
262         case KOMEDA_MODE_DUAL_DISP:
263                 return DO01_ACTIVE_MODE;
264         case KOMEDA_MODE_INACTIVE:
265                 return INACTIVE_MODE;
266         default:
267                 WARN(1, "Unknown operation mode");
268                 return INACTIVE_MODE;
269         }
270 }
271
272 static int d71_change_opmode(struct komeda_dev *mdev, int new_mode)
273 {
274         struct d71_dev *d71 = mdev->chip_data;
275         u32 opmode = to_d71_opmode(new_mode);
276         int ret;
277
278         malidp_write32_mask(d71->gcu_addr, BLK_CONTROL, 0x7, opmode);
279
280         ret = dp_wait_cond(((malidp_read32(d71->gcu_addr, BLK_CONTROL) & 0x7) == opmode),
281                            100, 1000, 10000);
282
283         return ret;
284 }
285
286 static void d71_flush(struct komeda_dev *mdev,
287                       int master_pipe, u32 active_pipes)
288 {
289         struct d71_dev *d71 = mdev->chip_data;
290         u32 reg_offset = (master_pipe == 0) ?
291                          GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1;
292
293         malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL);
294 }
295
296 static int d71_reset(struct d71_dev *d71)
297 {
298         u32 __iomem *gcu = d71->gcu_addr;
299         int ret;
300
301         malidp_write32_mask(gcu, BLK_CONTROL,
302                             GCU_CONTROL_SRST, GCU_CONTROL_SRST);
303
304         ret = dp_wait_cond(!(malidp_read32(gcu, BLK_CONTROL) & GCU_CONTROL_SRST),
305                            100, 1000, 10000);
306
307         return ret;
308 }
309
310 void d71_read_block_header(u32 __iomem *reg, struct block_header *blk)
311 {
312         int i;
313
314         blk->block_info = malidp_read32(reg, BLK_BLOCK_INFO);
315         if (BLOCK_INFO_BLK_TYPE(blk->block_info) == D71_BLK_TYPE_RESERVED)
316                 return;
317
318         blk->pipeline_info = malidp_read32(reg, BLK_PIPELINE_INFO);
319
320         /* get valid input and output ids */
321         for (i = 0; i < PIPELINE_INFO_N_VALID_INPUTS(blk->pipeline_info); i++)
322                 blk->input_ids[i] = malidp_read32(reg + i, BLK_VALID_INPUT_ID0);
323         for (i = 0; i < PIPELINE_INFO_N_OUTPUTS(blk->pipeline_info); i++)
324                 blk->output_ids[i] = malidp_read32(reg + i, BLK_OUTPUT_ID0);
325 }
326
327 static void d71_cleanup(struct komeda_dev *mdev)
328 {
329         struct d71_dev *d71 = mdev->chip_data;
330
331         if (!d71)
332                 return;
333
334         devm_kfree(mdev->dev, d71);
335         mdev->chip_data = NULL;
336 }
337
338 static int d71_enum_resources(struct komeda_dev *mdev)
339 {
340         struct d71_dev *d71;
341         struct komeda_pipeline *pipe;
342         struct block_header blk;
343         u32 __iomem *blk_base;
344         u32 i, value, offset;
345         int err;
346
347         d71 = devm_kzalloc(mdev->dev, sizeof(*d71), GFP_KERNEL);
348         if (!d71)
349                 return -ENOMEM;
350
351         mdev->chip_data = d71;
352         d71->mdev = mdev;
353         d71->gcu_addr = mdev->reg_base;
354         d71->periph_addr = mdev->reg_base + (D71_BLOCK_OFFSET_PERIPH >> 2);
355
356         err = d71_reset(d71);
357         if (err) {
358                 DRM_ERROR("Fail to reset d71 device.\n");
359                 goto err_cleanup;
360         }
361
362         /* probe GCU */
363         value = malidp_read32(d71->gcu_addr, GLB_CORE_INFO);
364         d71->num_blocks = value & 0xFF;
365         d71->num_pipelines = (value >> 8) & 0x7;
366
367         if (d71->num_pipelines > D71_MAX_PIPELINE) {
368                 DRM_ERROR("d71 supports %d pipelines, but got: %d.\n",
369                           D71_MAX_PIPELINE, d71->num_pipelines);
370                 err = -EINVAL;
371                 goto err_cleanup;
372         }
373
374         /* Only the legacy HW has the periph block, the newer merges the periph
375          * into GCU
376          */
377         value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
378         if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
379                 d71->periph_addr = NULL;
380
381         if (d71->periph_addr) {
382                 /* probe PERIPHERAL in legacy HW */
383                 value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);
384
385                 d71->max_line_size      = value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
386                 d71->max_vsize          = 4096;
387                 d71->num_rich_layers    = value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
388                 d71->supports_dual_link = !!(value & PERIPH_SPLIT_EN);
389                 d71->integrates_tbu     = !!(value & PERIPH_TBU_EN);
390         } else {
391                 value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
392                 d71->max_line_size      = GCU_MAX_LINE_SIZE(value);
393                 d71->max_vsize          = GCU_MAX_NUM_LINES(value);
394
395                 value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
396                 d71->num_rich_layers    = GCU_NUM_RICH_LAYERS(value);
397                 d71->supports_dual_link = GCU_DISPLAY_SPLIT_EN(value);
398                 d71->integrates_tbu     = GCU_DISPLAY_TBU_EN(value);
399         }
400
401         for (i = 0; i < d71->num_pipelines; i++) {
402                 pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
403                                            &d71_pipeline_funcs);
404                 if (IS_ERR(pipe)) {
405                         err = PTR_ERR(pipe);
406                         goto err_cleanup;
407                 }
408
409                 /* D71 HW doesn't update shadow registers when display output
410                  * is turning off, so when we disable all pipeline components
411                  * together with display output disable by one flush or one
412                  * operation, the disable operation updated registers will not
413                  * be flush to or valid in HW, which may leads problem.
414                  * To workaround this problem, introduce a two phase disable.
415                  * Phase1: Disabling components with display is on to make sure
416                  *         the disable can be flushed to HW.
417                  * Phase2: Only turn-off display output.
418                  */
419                 value = KOMEDA_PIPELINE_IMPROCS |
420                         BIT(KOMEDA_COMPONENT_TIMING_CTRLR);
421
422                 pipe->standalone_disabled_comps = value;
423
424                 d71->pipes[i] = to_d71_pipeline(pipe);
425         }
426
427         /* loop the register blks and probe.
428          * NOTE: d71->num_blocks includes reserved blocks.
429          * d71->num_blocks = GCU + valid blocks + reserved blocks
430          */
431         i = 1; /* exclude GCU */
432         offset = D71_BLOCK_SIZE; /* skip GCU */
433         while (i < d71->num_blocks) {
434                 blk_base = mdev->reg_base + (offset >> 2);
435
436                 d71_read_block_header(blk_base, &blk);
437                 if (BLOCK_INFO_BLK_TYPE(blk.block_info) != D71_BLK_TYPE_RESERVED) {
438                         err = d71_probe_block(d71, &blk, blk_base);
439                         if (err)
440                                 goto err_cleanup;
441                 }
442
443                 i++;
444                 offset += D71_BLOCK_SIZE;
445         }
446
447         DRM_DEBUG("total %d (out of %d) blocks are found.\n",
448                   i, d71->num_blocks);
449
450         return 0;
451
452 err_cleanup:
453         d71_cleanup(mdev);
454         return err;
455 }
456
457 #define __HW_ID(__group, __format) \
458         ((((__group) & 0x7) << 3) | ((__format) & 0x7))
459
460 #define RICH            KOMEDA_FMT_RICH_LAYER
461 #define SIMPLE          KOMEDA_FMT_SIMPLE_LAYER
462 #define RICH_SIMPLE     (KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_SIMPLE_LAYER)
463 #define RICH_WB         (KOMEDA_FMT_RICH_LAYER | KOMEDA_FMT_WB_LAYER)
464 #define RICH_SIMPLE_WB  (RICH_SIMPLE | KOMEDA_FMT_WB_LAYER)
465
466 #define Rot_0           DRM_MODE_ROTATE_0
467 #define Flip_H_V        (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y | Rot_0)
468 #define Rot_ALL_H_V     (DRM_MODE_ROTATE_MASK | Flip_H_V)
469
470 #define LYT_NM          BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)
471 #define LYT_WB          BIT(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
472 #define LYT_NM_WB       (LYT_NM | LYT_WB)
473
474 #define AFB_TH          AFBC(_TILED | _SPARSE)
475 #define AFB_TH_SC_YTR   AFBC(_TILED | _SC | _SPARSE | _YTR)
476 #define AFB_TH_SC_YTR_BS AFBC(_TILED | _SC | _SPARSE | _YTR | _SPLIT)
477
478 static struct komeda_format_caps d71_format_caps_table[] = {
479         /*   HW_ID    |        fourcc         |   layer_types |   rots    | afbc_layouts | afbc_features */
480         /* ABGR_2101010*/
481         {__HW_ID(0, 0), DRM_FORMAT_ARGB2101010, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
482         {__HW_ID(0, 1), DRM_FORMAT_ABGR2101010, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
483         {__HW_ID(0, 1), DRM_FORMAT_ABGR2101010, RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
484         {__HW_ID(0, 2), DRM_FORMAT_RGBA1010102, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
485         {__HW_ID(0, 3), DRM_FORMAT_BGRA1010102, RICH_SIMPLE_WB, Flip_H_V,               0, 0},
486         /* ABGR_8888*/
487         {__HW_ID(1, 0), DRM_FORMAT_ARGB8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
488         {__HW_ID(1, 1), DRM_FORMAT_ABGR8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
489         {__HW_ID(1, 1), DRM_FORMAT_ABGR8888,    RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
490         {__HW_ID(1, 2), DRM_FORMAT_RGBA8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
491         {__HW_ID(1, 3), DRM_FORMAT_BGRA8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
492         /* XBGB_8888 */
493         {__HW_ID(2, 0), DRM_FORMAT_XRGB8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
494         {__HW_ID(2, 1), DRM_FORMAT_XBGR8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
495         {__HW_ID(2, 2), DRM_FORMAT_RGBX8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
496         {__HW_ID(2, 3), DRM_FORMAT_BGRX8888,    RICH_SIMPLE_WB, Flip_H_V,               0, 0},
497         /* BGR_888 */ /* none-afbc RGB888 doesn't support rotation and flip */
498         {__HW_ID(3, 0), DRM_FORMAT_RGB888,      RICH_SIMPLE_WB, Rot_0,                  0, 0},
499         {__HW_ID(3, 1), DRM_FORMAT_BGR888,      RICH_SIMPLE_WB, Rot_0,                  0, 0},
500         {__HW_ID(3, 1), DRM_FORMAT_BGR888,      RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR_BS}, /* afbc */
501         /* BGR 16bpp */
502         {__HW_ID(4, 0), DRM_FORMAT_RGBA5551,    RICH_SIMPLE,    Flip_H_V,               0, 0},
503         {__HW_ID(4, 1), DRM_FORMAT_ABGR1555,    RICH_SIMPLE,    Flip_H_V,               0, 0},
504         {__HW_ID(4, 1), DRM_FORMAT_ABGR1555,    RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
505         {__HW_ID(4, 2), DRM_FORMAT_RGB565,      RICH_SIMPLE,    Flip_H_V,               0, 0},
506         {__HW_ID(4, 3), DRM_FORMAT_BGR565,      RICH_SIMPLE,    Flip_H_V,               0, 0},
507         {__HW_ID(4, 3), DRM_FORMAT_BGR565,      RICH_SIMPLE,    Rot_ALL_H_V,    LYT_NM_WB, AFB_TH_SC_YTR}, /* afbc */
508         {__HW_ID(4, 4), DRM_FORMAT_R8,          SIMPLE,         Rot_0,                  0, 0},
509         /* YUV 444/422/420 8bit  */
510         {__HW_ID(5, 1), DRM_FORMAT_YUYV,        RICH,           Rot_ALL_H_V,    LYT_NM, AFB_TH}, /* afbc */
511         {__HW_ID(5, 2), DRM_FORMAT_YUYV,        RICH,           Flip_H_V,               0, 0},
512         {__HW_ID(5, 3), DRM_FORMAT_UYVY,        RICH,           Flip_H_V,               0, 0},
513         {__HW_ID(5, 6), DRM_FORMAT_NV12,        RICH,           Flip_H_V,               0, 0},
514         {__HW_ID(5, 6), DRM_FORMAT_YUV420_8BIT, RICH,           Rot_ALL_H_V,    LYT_NM, AFB_TH}, /* afbc */
515         {__HW_ID(5, 7), DRM_FORMAT_YUV420,      RICH,           Flip_H_V,               0, 0},
516         /* YUV 10bit*/
517         {__HW_ID(6, 6), DRM_FORMAT_X0L2,        RICH,           Flip_H_V,               0, 0},
518         {__HW_ID(6, 7), DRM_FORMAT_P010,        RICH,           Flip_H_V,               0, 0},
519         {__HW_ID(6, 7), DRM_FORMAT_YUV420_10BIT, RICH,          Rot_ALL_H_V,    LYT_NM, AFB_TH},
520 };
521
522 static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
523                                      u32 layer_type, u64 modifier, u32 rot)
524 {
525         uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
526
527         if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
528             drm_rotation_90_or_270(rot)) {
529                 DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
530                 return false;
531         }
532
533         return true;
534 }
535
536 static void d71_init_fmt_tbl(struct komeda_dev *mdev)
537 {
538         struct komeda_format_caps_table *table = &mdev->fmt_tbl;
539
540         table->format_caps = d71_format_caps_table;
541         table->format_mod_supported = d71_format_mod_supported;
542         table->n_formats = ARRAY_SIZE(d71_format_caps_table);
543 }
544
545 static int d71_connect_iommu(struct komeda_dev *mdev)
546 {
547         struct d71_dev *d71 = mdev->chip_data;
548         u32 __iomem *reg = d71->gcu_addr;
549         u32 check_bits = (d71->num_pipelines == 2) ?
550                          GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
551         int i, ret;
552
553         if (!d71->integrates_tbu)
554                 return -1;
555
556         malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
557
558         ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
559                         100, 1000, 1000);
560         if (ret < 0) {
561                 DRM_ERROR("timed out connecting to TCU!\n");
562                 malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
563                 return ret;
564         }
565
566         for (i = 0; i < d71->num_pipelines; i++)
567                 malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
568                                     LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
569         return 0;
570 }
571
572 static int d71_disconnect_iommu(struct komeda_dev *mdev)
573 {
574         struct d71_dev *d71 = mdev->chip_data;
575         u32 __iomem *reg = d71->gcu_addr;
576         u32 check_bits = (d71->num_pipelines == 2) ?
577                          GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
578         int ret;
579
580         malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
581
582         ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
583                         100, 1000, 1000);
584         if (ret < 0) {
585                 DRM_ERROR("timed out disconnecting from TCU!\n");
586                 malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
587         }
588
589         return ret;
590 }
591
592 static const struct komeda_dev_funcs d71_chip_funcs = {
593         .init_format_table      = d71_init_fmt_tbl,
594         .enum_resources         = d71_enum_resources,
595         .cleanup                = d71_cleanup,
596         .irq_handler            = d71_irq_handler,
597         .enable_irq             = d71_enable_irq,
598         .disable_irq            = d71_disable_irq,
599         .on_off_vblank          = d71_on_off_vblank,
600         .change_opmode          = d71_change_opmode,
601         .flush                  = d71_flush,
602         .connect_iommu          = d71_connect_iommu,
603         .disconnect_iommu       = d71_disconnect_iommu,
604         .dump_register          = d71_dump,
605 };
606
607 const struct komeda_dev_funcs *
608 d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
609 {
610         const struct komeda_dev_funcs *funcs;
611         u32 product_id;
612
613         chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
614
615         product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
616
617         switch (product_id) {
618         case MALIDP_D71_PRODUCT_ID:
619         case MALIDP_D32_PRODUCT_ID:
620                 funcs = &d71_chip_funcs;
621                 break;
622         default:
623                 DRM_ERROR("Unsupported product: 0x%x\n", product_id);
624                 return NULL;
625         }
626
627         chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
628         chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
629         chip->bus_width = D71_BUS_WIDTH_16_BYTES;
630
631         return funcs;
632 }