]> Git Repo - linux.git/blob - drivers/gpu/drm/mediatek/mtk_dpi.c
Merge tag 'fsnotify_for_v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / mediatek / mtk_dpi.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2014 MediaTek Inc.
4  * Author: Jie Qiu <[email protected]>
5  */
6
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/of_gpio.h>
14 #include <linux/of_graph.h>
15 #include <linux/pinctrl/consumer.h>
16 #include <linux/platform_device.h>
17 #include <linux/types.h>
18
19 #include <video/videomode.h>
20
21 #include <drm/drm_atomic_helper.h>
22 #include <drm/drm_bridge.h>
23 #include <drm/drm_crtc.h>
24 #include <drm/drm_of.h>
25 #include <drm/drm_simple_kms_helper.h>
26
27 #include "mtk_dpi_regs.h"
28 #include "mtk_drm_ddp_comp.h"
29
30 enum mtk_dpi_out_bit_num {
31         MTK_DPI_OUT_BIT_NUM_8BITS,
32         MTK_DPI_OUT_BIT_NUM_10BITS,
33         MTK_DPI_OUT_BIT_NUM_12BITS,
34         MTK_DPI_OUT_BIT_NUM_16BITS
35 };
36
37 enum mtk_dpi_out_yc_map {
38         MTK_DPI_OUT_YC_MAP_RGB,
39         MTK_DPI_OUT_YC_MAP_CYCY,
40         MTK_DPI_OUT_YC_MAP_YCYC,
41         MTK_DPI_OUT_YC_MAP_CY,
42         MTK_DPI_OUT_YC_MAP_YC
43 };
44
45 enum mtk_dpi_out_channel_swap {
46         MTK_DPI_OUT_CHANNEL_SWAP_RGB,
47         MTK_DPI_OUT_CHANNEL_SWAP_GBR,
48         MTK_DPI_OUT_CHANNEL_SWAP_BRG,
49         MTK_DPI_OUT_CHANNEL_SWAP_RBG,
50         MTK_DPI_OUT_CHANNEL_SWAP_GRB,
51         MTK_DPI_OUT_CHANNEL_SWAP_BGR
52 };
53
54 enum mtk_dpi_out_color_format {
55         MTK_DPI_COLOR_FORMAT_RGB,
56         MTK_DPI_COLOR_FORMAT_RGB_FULL,
57         MTK_DPI_COLOR_FORMAT_YCBCR_444,
58         MTK_DPI_COLOR_FORMAT_YCBCR_422,
59         MTK_DPI_COLOR_FORMAT_XV_YCC,
60         MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL,
61         MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
62 };
63
64 struct mtk_dpi {
65         struct mtk_ddp_comp ddp_comp;
66         struct drm_encoder encoder;
67         struct drm_bridge bridge;
68         struct drm_bridge *next_bridge;
69         void __iomem *regs;
70         struct device *dev;
71         struct clk *engine_clk;
72         struct clk *pixel_clk;
73         struct clk *tvd_clk;
74         int irq;
75         struct drm_display_mode mode;
76         const struct mtk_dpi_conf *conf;
77         enum mtk_dpi_out_color_format color_format;
78         enum mtk_dpi_out_yc_map yc_map;
79         enum mtk_dpi_out_bit_num bit_num;
80         enum mtk_dpi_out_channel_swap channel_swap;
81         struct pinctrl *pinctrl;
82         struct pinctrl_state *pins_gpio;
83         struct pinctrl_state *pins_dpi;
84         int refcount;
85 };
86
87 static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
88 {
89         return container_of(b, struct mtk_dpi, bridge);
90 }
91
92 enum mtk_dpi_polarity {
93         MTK_DPI_POLARITY_RISING,
94         MTK_DPI_POLARITY_FALLING,
95 };
96
97 struct mtk_dpi_polarities {
98         enum mtk_dpi_polarity de_pol;
99         enum mtk_dpi_polarity ck_pol;
100         enum mtk_dpi_polarity hsync_pol;
101         enum mtk_dpi_polarity vsync_pol;
102 };
103
104 struct mtk_dpi_sync_param {
105         u32 sync_width;
106         u32 front_porch;
107         u32 back_porch;
108         bool shift_half_line;
109 };
110
111 struct mtk_dpi_yc_limit {
112         u16 y_top;
113         u16 y_bottom;
114         u16 c_top;
115         u16 c_bottom;
116 };
117
118 struct mtk_dpi_conf {
119         unsigned int (*cal_factor)(int clock);
120         u32 reg_h_fre_con;
121         bool edge_sel_en;
122 };
123
124 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
125 {
126         u32 tmp = readl(dpi->regs + offset) & ~mask;
127
128         tmp |= (val & mask);
129         writel(tmp, dpi->regs + offset);
130 }
131
132 static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
133 {
134         mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
135 }
136
137 static void mtk_dpi_enable(struct mtk_dpi *dpi)
138 {
139         mtk_dpi_mask(dpi, DPI_EN, EN, EN);
140 }
141
142 static void mtk_dpi_disable(struct mtk_dpi *dpi)
143 {
144         mtk_dpi_mask(dpi, DPI_EN, 0, EN);
145 }
146
147 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
148                                  struct mtk_dpi_sync_param *sync)
149 {
150         mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
151                      sync->sync_width << HPW, HPW_MASK);
152         mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
153                      sync->back_porch << HBP, HBP_MASK);
154         mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
155                      HFP_MASK);
156 }
157
158 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
159                                  struct mtk_dpi_sync_param *sync,
160                                  u32 width_addr, u32 porch_addr)
161 {
162         mtk_dpi_mask(dpi, width_addr,
163                      sync->sync_width << VSYNC_WIDTH_SHIFT,
164                      VSYNC_WIDTH_MASK);
165         mtk_dpi_mask(dpi, width_addr,
166                      sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
167                      VSYNC_HALF_LINE_MASK);
168         mtk_dpi_mask(dpi, porch_addr,
169                      sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
170                      VSYNC_BACK_PORCH_MASK);
171         mtk_dpi_mask(dpi, porch_addr,
172                      sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
173                      VSYNC_FRONT_PORCH_MASK);
174 }
175
176 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
177                                       struct mtk_dpi_sync_param *sync)
178 {
179         mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH);
180 }
181
182 static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi,
183                                        struct mtk_dpi_sync_param *sync)
184 {
185         mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN,
186                              DPI_TGEN_VPORCH_LEVEN);
187 }
188
189 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi,
190                                       struct mtk_dpi_sync_param *sync)
191 {
192         mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD,
193                              DPI_TGEN_VPORCH_RODD);
194 }
195
196 static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi,
197                                        struct mtk_dpi_sync_param *sync)
198 {
199         mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN,
200                              DPI_TGEN_VPORCH_REVEN);
201 }
202
203 static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
204                                struct mtk_dpi_polarities *dpi_pol)
205 {
206         unsigned int pol;
207
208         pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
209               (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
210               (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
211               (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
212         mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
213                      CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
214 }
215
216 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
217 {
218         mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
219 }
220
221 static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
222 {
223         mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN);
224 }
225
226 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
227 {
228         mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
229         mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
230 }
231
232 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
233                                          struct mtk_dpi_yc_limit *limit)
234 {
235         mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
236                      Y_LIMINT_BOT_MASK);
237         mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
238                      Y_LIMINT_TOP_MASK);
239         mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_bottom << C_LIMIT_BOT,
240                      C_LIMIT_BOT_MASK);
241         mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_top << C_LIMIT_TOP,
242                      C_LIMIT_TOP_MASK);
243 }
244
245 static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
246                                    enum mtk_dpi_out_bit_num num)
247 {
248         u32 val;
249
250         switch (num) {
251         case MTK_DPI_OUT_BIT_NUM_8BITS:
252                 val = OUT_BIT_8;
253                 break;
254         case MTK_DPI_OUT_BIT_NUM_10BITS:
255                 val = OUT_BIT_10;
256                 break;
257         case MTK_DPI_OUT_BIT_NUM_12BITS:
258                 val = OUT_BIT_12;
259                 break;
260         case MTK_DPI_OUT_BIT_NUM_16BITS:
261                 val = OUT_BIT_16;
262                 break;
263         default:
264                 val = OUT_BIT_8;
265                 break;
266         }
267         mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
268                      OUT_BIT_MASK);
269 }
270
271 static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
272                                   enum mtk_dpi_out_yc_map map)
273 {
274         u32 val;
275
276         switch (map) {
277         case MTK_DPI_OUT_YC_MAP_RGB:
278                 val = YC_MAP_RGB;
279                 break;
280         case MTK_DPI_OUT_YC_MAP_CYCY:
281                 val = YC_MAP_CYCY;
282                 break;
283         case MTK_DPI_OUT_YC_MAP_YCYC:
284                 val = YC_MAP_YCYC;
285                 break;
286         case MTK_DPI_OUT_YC_MAP_CY:
287                 val = YC_MAP_CY;
288                 break;
289         case MTK_DPI_OUT_YC_MAP_YC:
290                 val = YC_MAP_YC;
291                 break;
292         default:
293                 val = YC_MAP_RGB;
294                 break;
295         }
296
297         mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK);
298 }
299
300 static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
301                                         enum mtk_dpi_out_channel_swap swap)
302 {
303         u32 val;
304
305         switch (swap) {
306         case MTK_DPI_OUT_CHANNEL_SWAP_RGB:
307                 val = SWAP_RGB;
308                 break;
309         case MTK_DPI_OUT_CHANNEL_SWAP_GBR:
310                 val = SWAP_GBR;
311                 break;
312         case MTK_DPI_OUT_CHANNEL_SWAP_BRG:
313                 val = SWAP_BRG;
314                 break;
315         case MTK_DPI_OUT_CHANNEL_SWAP_RBG:
316                 val = SWAP_RBG;
317                 break;
318         case MTK_DPI_OUT_CHANNEL_SWAP_GRB:
319                 val = SWAP_GRB;
320                 break;
321         case MTK_DPI_OUT_CHANNEL_SWAP_BGR:
322                 val = SWAP_BGR;
323                 break;
324         default:
325                 val = SWAP_RGB;
326                 break;
327         }
328
329         mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
330 }
331
332 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
333 {
334         mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
335 }
336
337 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
338 {
339         mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
340 }
341
342 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
343 {
344         mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP);
345 }
346
347 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
348 {
349         mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
350 }
351
352 static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
353 {
354         if (dpi->conf->edge_sel_en)
355                 mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
356 }
357
358 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
359                                         enum mtk_dpi_out_color_format format)
360 {
361         if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
362             (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
363                 mtk_dpi_config_yuv422_enable(dpi, false);
364                 mtk_dpi_config_csc_enable(dpi, true);
365                 mtk_dpi_config_swap_input(dpi, false);
366                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
367         } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
368                    (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
369                 mtk_dpi_config_yuv422_enable(dpi, true);
370                 mtk_dpi_config_csc_enable(dpi, true);
371                 mtk_dpi_config_swap_input(dpi, true);
372                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
373         } else {
374                 mtk_dpi_config_yuv422_enable(dpi, false);
375                 mtk_dpi_config_csc_enable(dpi, false);
376                 mtk_dpi_config_swap_input(dpi, false);
377                 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
378         }
379 }
380
381 static void mtk_dpi_power_off(struct mtk_dpi *dpi)
382 {
383         if (WARN_ON(dpi->refcount == 0))
384                 return;
385
386         if (--dpi->refcount != 0)
387                 return;
388
389         if (dpi->pinctrl && dpi->pins_gpio)
390                 pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
391
392         mtk_dpi_disable(dpi);
393         clk_disable_unprepare(dpi->pixel_clk);
394         clk_disable_unprepare(dpi->engine_clk);
395 }
396
397 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
398 {
399         int ret;
400
401         if (++dpi->refcount != 1)
402                 return 0;
403
404         ret = clk_prepare_enable(dpi->engine_clk);
405         if (ret) {
406                 dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
407                 goto err_refcount;
408         }
409
410         ret = clk_prepare_enable(dpi->pixel_clk);
411         if (ret) {
412                 dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
413                 goto err_pixel;
414         }
415
416         if (dpi->pinctrl && dpi->pins_dpi)
417                 pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
418
419         mtk_dpi_enable(dpi);
420         return 0;
421
422 err_pixel:
423         clk_disable_unprepare(dpi->engine_clk);
424 err_refcount:
425         dpi->refcount--;
426         return ret;
427 }
428
429 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
430                                     struct drm_display_mode *mode)
431 {
432         struct mtk_dpi_yc_limit limit;
433         struct mtk_dpi_polarities dpi_pol;
434         struct mtk_dpi_sync_param hsync;
435         struct mtk_dpi_sync_param vsync_lodd = { 0 };
436         struct mtk_dpi_sync_param vsync_leven = { 0 };
437         struct mtk_dpi_sync_param vsync_rodd = { 0 };
438         struct mtk_dpi_sync_param vsync_reven = { 0 };
439         struct videomode vm = { 0 };
440         unsigned long pll_rate;
441         unsigned int factor;
442
443         /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
444         factor = dpi->conf->cal_factor(mode->clock);
445         drm_display_mode_to_videomode(mode, &vm);
446         pll_rate = vm.pixelclock * factor;
447
448         dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
449                 pll_rate, vm.pixelclock);
450
451         clk_set_rate(dpi->tvd_clk, pll_rate);
452         pll_rate = clk_get_rate(dpi->tvd_clk);
453
454         vm.pixelclock = pll_rate / factor;
455         clk_set_rate(dpi->pixel_clk, vm.pixelclock);
456         vm.pixelclock = clk_get_rate(dpi->pixel_clk);
457
458         dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
459                 pll_rate, vm.pixelclock);
460
461         limit.c_bottom = 0x0010;
462         limit.c_top = 0x0FE0;
463         limit.y_bottom = 0x0010;
464         limit.y_top = 0x0FE0;
465
466         dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
467         dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
468         dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
469                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
470         dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
471                             MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
472         hsync.sync_width = vm.hsync_len;
473         hsync.back_porch = vm.hback_porch;
474         hsync.front_porch = vm.hfront_porch;
475         hsync.shift_half_line = false;
476         vsync_lodd.sync_width = vm.vsync_len;
477         vsync_lodd.back_porch = vm.vback_porch;
478         vsync_lodd.front_porch = vm.vfront_porch;
479         vsync_lodd.shift_half_line = false;
480
481         if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
482             mode->flags & DRM_MODE_FLAG_3D_MASK) {
483                 vsync_leven = vsync_lodd;
484                 vsync_rodd = vsync_lodd;
485                 vsync_reven = vsync_lodd;
486                 vsync_leven.shift_half_line = true;
487                 vsync_reven.shift_half_line = true;
488         } else if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
489                    !(mode->flags & DRM_MODE_FLAG_3D_MASK)) {
490                 vsync_leven = vsync_lodd;
491                 vsync_leven.shift_half_line = true;
492         } else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) &&
493                    mode->flags & DRM_MODE_FLAG_3D_MASK) {
494                 vsync_rodd = vsync_lodd;
495         }
496         mtk_dpi_sw_reset(dpi, true);
497         mtk_dpi_config_pol(dpi, &dpi_pol);
498
499         mtk_dpi_config_hsync(dpi, &hsync);
500         mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
501         mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
502         mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
503         mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
504
505         mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
506         mtk_dpi_config_interface(dpi, !!(vm.flags &
507                                          DISPLAY_FLAGS_INTERLACED));
508         if (vm.flags & DISPLAY_FLAGS_INTERLACED)
509                 mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1);
510         else
511                 mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
512
513         mtk_dpi_config_channel_limit(dpi, &limit);
514         mtk_dpi_config_bit_num(dpi, dpi->bit_num);
515         mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
516         mtk_dpi_config_yc_map(dpi, dpi->yc_map);
517         mtk_dpi_config_color_format(dpi, dpi->color_format);
518         mtk_dpi_config_2n_h_fre(dpi);
519         mtk_dpi_config_disable_edge(dpi);
520         mtk_dpi_sw_reset(dpi, false);
521
522         return 0;
523 }
524
525 static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
526                                  enum drm_bridge_attach_flags flags)
527 {
528         struct mtk_dpi *dpi = bridge_to_dpi(bridge);
529
530         return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
531                                  &dpi->bridge, flags);
532 }
533
534 static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge,
535                                 const struct drm_display_mode *mode,
536                                 const struct drm_display_mode *adjusted_mode)
537 {
538         struct mtk_dpi *dpi = bridge_to_dpi(bridge);
539
540         drm_mode_copy(&dpi->mode, adjusted_mode);
541 }
542
543 static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
544 {
545         struct mtk_dpi *dpi = bridge_to_dpi(bridge);
546
547         mtk_dpi_power_off(dpi);
548 }
549
550 static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
551 {
552         struct mtk_dpi *dpi = bridge_to_dpi(bridge);
553
554         mtk_dpi_power_on(dpi);
555         mtk_dpi_set_display_mode(dpi, &dpi->mode);
556 }
557
558 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
559         .attach = mtk_dpi_bridge_attach,
560         .mode_set = mtk_dpi_bridge_mode_set,
561         .disable = mtk_dpi_bridge_disable,
562         .enable = mtk_dpi_bridge_enable,
563 };
564
565 static void mtk_dpi_start(struct mtk_ddp_comp *comp)
566 {
567         struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
568
569         mtk_dpi_power_on(dpi);
570 }
571
572 static void mtk_dpi_stop(struct mtk_ddp_comp *comp)
573 {
574         struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
575
576         mtk_dpi_power_off(dpi);
577 }
578
579 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = {
580         .start = mtk_dpi_start,
581         .stop = mtk_dpi_stop,
582 };
583
584 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
585 {
586         struct mtk_dpi *dpi = dev_get_drvdata(dev);
587         struct drm_device *drm_dev = data;
588         int ret;
589
590         ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp);
591         if (ret < 0) {
592                 dev_err(dev, "Failed to register component %pOF: %d\n",
593                         dev->of_node, ret);
594                 return ret;
595         }
596
597         ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
598                                       DRM_MODE_ENCODER_TMDS);
599         if (ret) {
600                 dev_err(dev, "Failed to initialize decoder: %d\n", ret);
601                 goto err_unregister;
602         }
603
604         dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp);
605
606         ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, 0);
607         if (ret) {
608                 dev_err(dev, "Failed to attach bridge: %d\n", ret);
609                 goto err_cleanup;
610         }
611
612         dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
613         dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
614         dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
615         dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
616
617         return 0;
618
619 err_cleanup:
620         drm_encoder_cleanup(&dpi->encoder);
621 err_unregister:
622         mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
623         return ret;
624 }
625
626 static void mtk_dpi_unbind(struct device *dev, struct device *master,
627                            void *data)
628 {
629         struct mtk_dpi *dpi = dev_get_drvdata(dev);
630         struct drm_device *drm_dev = data;
631
632         drm_encoder_cleanup(&dpi->encoder);
633         mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
634 }
635
636 static const struct component_ops mtk_dpi_component_ops = {
637         .bind = mtk_dpi_bind,
638         .unbind = mtk_dpi_unbind,
639 };
640
641 static unsigned int mt8173_calculate_factor(int clock)
642 {
643         if (clock <= 27000)
644                 return 3 << 4;
645         else if (clock <= 84000)
646                 return 3 << 3;
647         else if (clock <= 167000)
648                 return 3 << 2;
649         else
650                 return 3 << 1;
651 }
652
653 static unsigned int mt2701_calculate_factor(int clock)
654 {
655         if (clock <= 64000)
656                 return 4;
657         else if (clock <= 128000)
658                 return 2;
659         else
660                 return 1;
661 }
662
663 static unsigned int mt8183_calculate_factor(int clock)
664 {
665         if (clock <= 27000)
666                 return 8;
667         else if (clock <= 167000)
668                 return 4;
669         else
670                 return 2;
671 }
672
673 static const struct mtk_dpi_conf mt8173_conf = {
674         .cal_factor = mt8173_calculate_factor,
675         .reg_h_fre_con = 0xe0,
676 };
677
678 static const struct mtk_dpi_conf mt2701_conf = {
679         .cal_factor = mt2701_calculate_factor,
680         .reg_h_fre_con = 0xb0,
681         .edge_sel_en = true,
682 };
683
684 static const struct mtk_dpi_conf mt8183_conf = {
685         .cal_factor = mt8183_calculate_factor,
686         .reg_h_fre_con = 0xe0,
687 };
688
689 static int mtk_dpi_probe(struct platform_device *pdev)
690 {
691         struct device *dev = &pdev->dev;
692         struct mtk_dpi *dpi;
693         struct resource *mem;
694         int comp_id;
695         int ret;
696
697         dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
698         if (!dpi)
699                 return -ENOMEM;
700
701         dpi->dev = dev;
702         dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
703
704         dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
705         if (IS_ERR(dpi->pinctrl)) {
706                 dpi->pinctrl = NULL;
707                 dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
708         }
709         if (dpi->pinctrl) {
710                 dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep");
711                 if (IS_ERR(dpi->pins_gpio)) {
712                         dpi->pins_gpio = NULL;
713                         dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n");
714                 }
715                 if (dpi->pins_gpio)
716                         pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
717
718                 dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default");
719                 if (IS_ERR(dpi->pins_dpi)) {
720                         dpi->pins_dpi = NULL;
721                         dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
722                 }
723         }
724         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
725         dpi->regs = devm_ioremap_resource(dev, mem);
726         if (IS_ERR(dpi->regs)) {
727                 ret = PTR_ERR(dpi->regs);
728                 dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
729                 return ret;
730         }
731
732         dpi->engine_clk = devm_clk_get(dev, "engine");
733         if (IS_ERR(dpi->engine_clk)) {
734                 ret = PTR_ERR(dpi->engine_clk);
735                 if (ret != -EPROBE_DEFER)
736                         dev_err(dev, "Failed to get engine clock: %d\n", ret);
737
738                 return ret;
739         }
740
741         dpi->pixel_clk = devm_clk_get(dev, "pixel");
742         if (IS_ERR(dpi->pixel_clk)) {
743                 ret = PTR_ERR(dpi->pixel_clk);
744                 if (ret != -EPROBE_DEFER)
745                         dev_err(dev, "Failed to get pixel clock: %d\n", ret);
746
747                 return ret;
748         }
749
750         dpi->tvd_clk = devm_clk_get(dev, "pll");
751         if (IS_ERR(dpi->tvd_clk)) {
752                 ret = PTR_ERR(dpi->tvd_clk);
753                 if (ret != -EPROBE_DEFER)
754                         dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
755
756                 return ret;
757         }
758
759         dpi->irq = platform_get_irq(pdev, 0);
760         if (dpi->irq <= 0) {
761                 dev_err(dev, "Failed to get irq: %d\n", dpi->irq);
762                 return -EINVAL;
763         }
764
765         ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
766                                           NULL, &dpi->next_bridge);
767         if (ret)
768                 return ret;
769
770         dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
771
772         comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
773         if (comp_id < 0) {
774                 dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
775                 return comp_id;
776         }
777
778         ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id,
779                                 &mtk_dpi_funcs);
780         if (ret) {
781                 dev_err(dev, "Failed to initialize component: %d\n", ret);
782                 return ret;
783         }
784
785         platform_set_drvdata(pdev, dpi);
786
787         dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
788         dpi->bridge.of_node = dev->of_node;
789         dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
790
791         drm_bridge_add(&dpi->bridge);
792
793         ret = component_add(dev, &mtk_dpi_component_ops);
794         if (ret) {
795                 drm_bridge_remove(&dpi->bridge);
796                 dev_err(dev, "Failed to add component: %d\n", ret);
797                 return ret;
798         }
799
800         return 0;
801 }
802
803 static int mtk_dpi_remove(struct platform_device *pdev)
804 {
805         struct mtk_dpi *dpi = platform_get_drvdata(pdev);
806
807         component_del(&pdev->dev, &mtk_dpi_component_ops);
808         drm_bridge_remove(&dpi->bridge);
809
810         return 0;
811 }
812
813 static const struct of_device_id mtk_dpi_of_ids[] = {
814         { .compatible = "mediatek,mt2701-dpi",
815           .data = &mt2701_conf,
816         },
817         { .compatible = "mediatek,mt8173-dpi",
818           .data = &mt8173_conf,
819         },
820         { .compatible = "mediatek,mt8183-dpi",
821           .data = &mt8183_conf,
822         },
823         { },
824 };
825
826 struct platform_driver mtk_dpi_driver = {
827         .probe = mtk_dpi_probe,
828         .remove = mtk_dpi_remove,
829         .driver = {
830                 .name = "mediatek-dpi",
831                 .of_match_table = mtk_dpi_of_ids,
832         },
833 };
This page took 0.081043 seconds and 4 git commands to generate.