Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2014 MediaTek Inc.
0004  * Author: Jie Qiu <jie.qiu@mediatek.com>
0005  */
0006 
0007 #include <linux/clk.h>
0008 #include <linux/component.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/kernel.h>
0011 #include <linux/media-bus-format.h>
0012 #include <linux/of.h>
0013 #include <linux/of_device.h>
0014 #include <linux/of_gpio.h>
0015 #include <linux/of_graph.h>
0016 #include <linux/pinctrl/consumer.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/types.h>
0019 
0020 #include <video/videomode.h>
0021 
0022 #include <drm/drm_atomic_helper.h>
0023 #include <drm/drm_bridge.h>
0024 #include <drm/drm_bridge_connector.h>
0025 #include <drm/drm_crtc.h>
0026 #include <drm/drm_edid.h>
0027 #include <drm/drm_of.h>
0028 #include <drm/drm_simple_kms_helper.h>
0029 
0030 #include "mtk_disp_drv.h"
0031 #include "mtk_dpi_regs.h"
0032 #include "mtk_drm_ddp_comp.h"
0033 
0034 enum mtk_dpi_out_bit_num {
0035     MTK_DPI_OUT_BIT_NUM_8BITS,
0036     MTK_DPI_OUT_BIT_NUM_10BITS,
0037     MTK_DPI_OUT_BIT_NUM_12BITS,
0038     MTK_DPI_OUT_BIT_NUM_16BITS
0039 };
0040 
0041 enum mtk_dpi_out_yc_map {
0042     MTK_DPI_OUT_YC_MAP_RGB,
0043     MTK_DPI_OUT_YC_MAP_CYCY,
0044     MTK_DPI_OUT_YC_MAP_YCYC,
0045     MTK_DPI_OUT_YC_MAP_CY,
0046     MTK_DPI_OUT_YC_MAP_YC
0047 };
0048 
0049 enum mtk_dpi_out_channel_swap {
0050     MTK_DPI_OUT_CHANNEL_SWAP_RGB,
0051     MTK_DPI_OUT_CHANNEL_SWAP_GBR,
0052     MTK_DPI_OUT_CHANNEL_SWAP_BRG,
0053     MTK_DPI_OUT_CHANNEL_SWAP_RBG,
0054     MTK_DPI_OUT_CHANNEL_SWAP_GRB,
0055     MTK_DPI_OUT_CHANNEL_SWAP_BGR
0056 };
0057 
0058 enum mtk_dpi_out_color_format {
0059     MTK_DPI_COLOR_FORMAT_RGB,
0060     MTK_DPI_COLOR_FORMAT_YCBCR_422
0061 };
0062 
0063 struct mtk_dpi {
0064     struct drm_encoder encoder;
0065     struct drm_bridge bridge;
0066     struct drm_bridge *next_bridge;
0067     struct drm_connector *connector;
0068     void __iomem *regs;
0069     struct device *dev;
0070     struct clk *engine_clk;
0071     struct clk *pixel_clk;
0072     struct clk *tvd_clk;
0073     int irq;
0074     struct drm_display_mode mode;
0075     const struct mtk_dpi_conf *conf;
0076     enum mtk_dpi_out_color_format color_format;
0077     enum mtk_dpi_out_yc_map yc_map;
0078     enum mtk_dpi_out_bit_num bit_num;
0079     enum mtk_dpi_out_channel_swap channel_swap;
0080     struct pinctrl *pinctrl;
0081     struct pinctrl_state *pins_gpio;
0082     struct pinctrl_state *pins_dpi;
0083     u32 output_fmt;
0084     int refcount;
0085 };
0086 
0087 static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
0088 {
0089     return container_of(b, struct mtk_dpi, bridge);
0090 }
0091 
0092 enum mtk_dpi_polarity {
0093     MTK_DPI_POLARITY_RISING,
0094     MTK_DPI_POLARITY_FALLING,
0095 };
0096 
0097 struct mtk_dpi_polarities {
0098     enum mtk_dpi_polarity de_pol;
0099     enum mtk_dpi_polarity ck_pol;
0100     enum mtk_dpi_polarity hsync_pol;
0101     enum mtk_dpi_polarity vsync_pol;
0102 };
0103 
0104 struct mtk_dpi_sync_param {
0105     u32 sync_width;
0106     u32 front_porch;
0107     u32 back_porch;
0108     bool shift_half_line;
0109 };
0110 
0111 struct mtk_dpi_yc_limit {
0112     u16 y_top;
0113     u16 y_bottom;
0114     u16 c_top;
0115     u16 c_bottom;
0116 };
0117 
0118 /**
0119  * struct mtk_dpi_conf - Configuration of mediatek dpi.
0120  * @cal_factor: Callback function to calculate factor value.
0121  * @reg_h_fre_con: Register address of frequency control.
0122  * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
0123  * @edge_sel_en: Enable of edge selection.
0124  * @output_fmts: Array of supported output formats.
0125  * @num_output_fmts: Quantity of supported output formats.
0126  * @is_ck_de_pol: Support CK/DE polarity.
0127  * @swap_input_support: Support input swap function.
0128  * @support_direct_pin: IP supports direct connection to dpi panels.
0129  * @input_2pixel: Input pixel of dp_intf is 2 pixel per round, so enable this
0130  *        config to enable this feature.
0131  * @dimension_mask: Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
0132  *          (no shift).
0133  * @hvsize_mask: Mask of HSIZE and VSIZE mask (no shift).
0134  * @channel_swap_shift: Shift value of channel swap.
0135  * @yuv422_en_bit: Enable bit of yuv422.
0136  * @csc_enable_bit: Enable bit of CSC.
0137  * @pixels_per_iter: Quantity of transferred pixels per iteration.
0138  */
0139 struct mtk_dpi_conf {
0140     unsigned int (*cal_factor)(int clock);
0141     u32 reg_h_fre_con;
0142     u32 max_clock_khz;
0143     bool edge_sel_en;
0144     const u32 *output_fmts;
0145     u32 num_output_fmts;
0146     bool is_ck_de_pol;
0147     bool swap_input_support;
0148     bool support_direct_pin;
0149     bool input_2pixel;
0150     u32 dimension_mask;
0151     u32 hvsize_mask;
0152     u32 channel_swap_shift;
0153     u32 yuv422_en_bit;
0154     u32 csc_enable_bit;
0155     u32 pixels_per_iter;
0156 };
0157 
0158 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
0159 {
0160     u32 tmp = readl(dpi->regs + offset) & ~mask;
0161 
0162     tmp |= (val & mask);
0163     writel(tmp, dpi->regs + offset);
0164 }
0165 
0166 static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
0167 {
0168     mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
0169 }
0170 
0171 static void mtk_dpi_enable(struct mtk_dpi *dpi)
0172 {
0173     mtk_dpi_mask(dpi, DPI_EN, EN, EN);
0174 }
0175 
0176 static void mtk_dpi_disable(struct mtk_dpi *dpi)
0177 {
0178     mtk_dpi_mask(dpi, DPI_EN, 0, EN);
0179 }
0180 
0181 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
0182                  struct mtk_dpi_sync_param *sync)
0183 {
0184     mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, sync->sync_width << HPW,
0185              dpi->conf->dimension_mask << HPW);
0186     mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->back_porch << HBP,
0187              dpi->conf->dimension_mask << HBP);
0188     mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
0189              dpi->conf->dimension_mask << HFP);
0190 }
0191 
0192 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
0193                  struct mtk_dpi_sync_param *sync,
0194                  u32 width_addr, u32 porch_addr)
0195 {
0196     mtk_dpi_mask(dpi, width_addr,
0197              sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
0198              VSYNC_HALF_LINE_MASK);
0199     mtk_dpi_mask(dpi, width_addr,
0200              sync->sync_width << VSYNC_WIDTH_SHIFT,
0201              dpi->conf->dimension_mask << VSYNC_WIDTH_SHIFT);
0202     mtk_dpi_mask(dpi, porch_addr,
0203              sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
0204              dpi->conf->dimension_mask << VSYNC_BACK_PORCH_SHIFT);
0205     mtk_dpi_mask(dpi, porch_addr,
0206              sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
0207              dpi->conf->dimension_mask << VSYNC_FRONT_PORCH_SHIFT);
0208 }
0209 
0210 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
0211                       struct mtk_dpi_sync_param *sync)
0212 {
0213     mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH);
0214 }
0215 
0216 static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi,
0217                        struct mtk_dpi_sync_param *sync)
0218 {
0219     mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN,
0220                  DPI_TGEN_VPORCH_LEVEN);
0221 }
0222 
0223 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi,
0224                       struct mtk_dpi_sync_param *sync)
0225 {
0226     mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD,
0227                  DPI_TGEN_VPORCH_RODD);
0228 }
0229 
0230 static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi,
0231                        struct mtk_dpi_sync_param *sync)
0232 {
0233     mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN,
0234                  DPI_TGEN_VPORCH_REVEN);
0235 }
0236 
0237 static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
0238                    struct mtk_dpi_polarities *dpi_pol)
0239 {
0240     unsigned int pol;
0241     unsigned int mask;
0242 
0243     mask = HSYNC_POL | VSYNC_POL;
0244     pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
0245           (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
0246     if (dpi->conf->is_ck_de_pol) {
0247         mask |= CK_POL | DE_POL;
0248         pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
0249             0 : CK_POL) |
0250                (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
0251             0 : DE_POL);
0252     }
0253 
0254     mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
0255 }
0256 
0257 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
0258 {
0259     mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
0260 }
0261 
0262 static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
0263 {
0264     mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN);
0265 }
0266 
0267 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
0268 {
0269     mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
0270              dpi->conf->hvsize_mask << HSIZE);
0271     mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
0272              dpi->conf->hvsize_mask << VSIZE);
0273 }
0274 
0275 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
0276 {
0277     struct mtk_dpi_yc_limit limit;
0278 
0279     if (drm_default_rgb_quant_range(&dpi->mode) ==
0280         HDMI_QUANTIZATION_RANGE_LIMITED) {
0281         limit.y_bottom = 0x10;
0282         limit.y_top = 0xfe0;
0283         limit.c_bottom = 0x10;
0284         limit.c_top = 0xfe0;
0285     } else {
0286         limit.y_bottom = 0;
0287         limit.y_top = 0xfff;
0288         limit.c_bottom = 0;
0289         limit.c_top = 0xfff;
0290     }
0291 
0292     mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_bottom << Y_LIMINT_BOT,
0293              Y_LIMINT_BOT_MASK);
0294     mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_top << Y_LIMINT_TOP,
0295              Y_LIMINT_TOP_MASK);
0296     mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_bottom << C_LIMIT_BOT,
0297              C_LIMIT_BOT_MASK);
0298     mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_top << C_LIMIT_TOP,
0299              C_LIMIT_TOP_MASK);
0300 }
0301 
0302 static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
0303                    enum mtk_dpi_out_bit_num num)
0304 {
0305     u32 val;
0306 
0307     switch (num) {
0308     case MTK_DPI_OUT_BIT_NUM_8BITS:
0309         val = OUT_BIT_8;
0310         break;
0311     case MTK_DPI_OUT_BIT_NUM_10BITS:
0312         val = OUT_BIT_10;
0313         break;
0314     case MTK_DPI_OUT_BIT_NUM_12BITS:
0315         val = OUT_BIT_12;
0316         break;
0317     case MTK_DPI_OUT_BIT_NUM_16BITS:
0318         val = OUT_BIT_16;
0319         break;
0320     default:
0321         val = OUT_BIT_8;
0322         break;
0323     }
0324     mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
0325              OUT_BIT_MASK);
0326 }
0327 
0328 static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
0329                   enum mtk_dpi_out_yc_map map)
0330 {
0331     u32 val;
0332 
0333     switch (map) {
0334     case MTK_DPI_OUT_YC_MAP_RGB:
0335         val = YC_MAP_RGB;
0336         break;
0337     case MTK_DPI_OUT_YC_MAP_CYCY:
0338         val = YC_MAP_CYCY;
0339         break;
0340     case MTK_DPI_OUT_YC_MAP_YCYC:
0341         val = YC_MAP_YCYC;
0342         break;
0343     case MTK_DPI_OUT_YC_MAP_CY:
0344         val = YC_MAP_CY;
0345         break;
0346     case MTK_DPI_OUT_YC_MAP_YC:
0347         val = YC_MAP_YC;
0348         break;
0349     default:
0350         val = YC_MAP_RGB;
0351         break;
0352     }
0353 
0354     mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK);
0355 }
0356 
0357 static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
0358                     enum mtk_dpi_out_channel_swap swap)
0359 {
0360     u32 val;
0361 
0362     switch (swap) {
0363     case MTK_DPI_OUT_CHANNEL_SWAP_RGB:
0364         val = SWAP_RGB;
0365         break;
0366     case MTK_DPI_OUT_CHANNEL_SWAP_GBR:
0367         val = SWAP_GBR;
0368         break;
0369     case MTK_DPI_OUT_CHANNEL_SWAP_BRG:
0370         val = SWAP_BRG;
0371         break;
0372     case MTK_DPI_OUT_CHANNEL_SWAP_RBG:
0373         val = SWAP_RBG;
0374         break;
0375     case MTK_DPI_OUT_CHANNEL_SWAP_GRB:
0376         val = SWAP_GRB;
0377         break;
0378     case MTK_DPI_OUT_CHANNEL_SWAP_BGR:
0379         val = SWAP_BGR;
0380         break;
0381     default:
0382         val = SWAP_RGB;
0383         break;
0384     }
0385 
0386     mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
0387              val << dpi->conf->channel_swap_shift,
0388              CH_SWAP_MASK << dpi->conf->channel_swap_shift);
0389 }
0390 
0391 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
0392 {
0393     mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
0394              dpi->conf->yuv422_en_bit);
0395 }
0396 
0397 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
0398 {
0399     mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
0400              dpi->conf->csc_enable_bit);
0401 }
0402 
0403 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
0404 {
0405     mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP);
0406 }
0407 
0408 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
0409 {
0410     mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
0411 }
0412 
0413 static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
0414 {
0415     if (dpi->conf->edge_sel_en)
0416         mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
0417 }
0418 
0419 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
0420                     enum mtk_dpi_out_color_format format)
0421 {
0422     mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
0423 
0424     if (format == MTK_DPI_COLOR_FORMAT_YCBCR_422) {
0425         mtk_dpi_config_yuv422_enable(dpi, true);
0426         mtk_dpi_config_csc_enable(dpi, true);
0427 
0428         /*
0429          * If height is smaller than 720, we need to use RGB_TO_BT601
0430          * to transfer to yuv422. Otherwise, we use RGB_TO_JPEG.
0431          */
0432         mtk_dpi_mask(dpi, DPI_MATRIX_SET, dpi->mode.hdisplay <= 720 ?
0433                  MATRIX_SEL_RGB_TO_BT601 : MATRIX_SEL_RGB_TO_JPEG,
0434                  INT_MATRIX_SEL_MASK);
0435     } else {
0436         mtk_dpi_config_yuv422_enable(dpi, false);
0437         mtk_dpi_config_csc_enable(dpi, false);
0438         if (dpi->conf->swap_input_support)
0439             mtk_dpi_config_swap_input(dpi, false);
0440     }
0441 }
0442 
0443 static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
0444 {
0445     if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
0446         (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
0447         mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE,
0448                  DDR_EN | DDR_4PHASE);
0449         mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
0450                  dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE ?
0451                  EDGE_SEL : 0, EDGE_SEL);
0452     } else {
0453         mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE, 0);
0454     }
0455 }
0456 
0457 static void mtk_dpi_power_off(struct mtk_dpi *dpi)
0458 {
0459     if (WARN_ON(dpi->refcount == 0))
0460         return;
0461 
0462     if (--dpi->refcount != 0)
0463         return;
0464 
0465     if (dpi->pinctrl && dpi->pins_gpio)
0466         pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
0467 
0468     mtk_dpi_disable(dpi);
0469     clk_disable_unprepare(dpi->pixel_clk);
0470     clk_disable_unprepare(dpi->engine_clk);
0471 }
0472 
0473 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
0474 {
0475     int ret;
0476 
0477     if (++dpi->refcount != 1)
0478         return 0;
0479 
0480     ret = clk_prepare_enable(dpi->engine_clk);
0481     if (ret) {
0482         dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
0483         goto err_refcount;
0484     }
0485 
0486     ret = clk_prepare_enable(dpi->pixel_clk);
0487     if (ret) {
0488         dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
0489         goto err_pixel;
0490     }
0491 
0492     if (dpi->pinctrl && dpi->pins_dpi)
0493         pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
0494 
0495     return 0;
0496 
0497 err_pixel:
0498     clk_disable_unprepare(dpi->engine_clk);
0499 err_refcount:
0500     dpi->refcount--;
0501     return ret;
0502 }
0503 
0504 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
0505                     struct drm_display_mode *mode)
0506 {
0507     struct mtk_dpi_polarities dpi_pol;
0508     struct mtk_dpi_sync_param hsync;
0509     struct mtk_dpi_sync_param vsync_lodd = { 0 };
0510     struct mtk_dpi_sync_param vsync_leven = { 0 };
0511     struct mtk_dpi_sync_param vsync_rodd = { 0 };
0512     struct mtk_dpi_sync_param vsync_reven = { 0 };
0513     struct videomode vm = { 0 };
0514     unsigned long pll_rate;
0515     unsigned int factor;
0516 
0517     /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
0518     factor = dpi->conf->cal_factor(mode->clock);
0519     drm_display_mode_to_videomode(mode, &vm);
0520     pll_rate = vm.pixelclock * factor;
0521 
0522     dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
0523         pll_rate, vm.pixelclock);
0524 
0525     clk_set_rate(dpi->tvd_clk, pll_rate);
0526     pll_rate = clk_get_rate(dpi->tvd_clk);
0527 
0528     /*
0529      * Depending on the IP version, we may output a different amount of
0530      * pixels for each iteration: divide the clock by this number and
0531      * adjust the display porches accordingly.
0532      */
0533     vm.pixelclock = pll_rate / factor;
0534     vm.pixelclock /= dpi->conf->pixels_per_iter;
0535 
0536     if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
0537         (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
0538         clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
0539     else
0540         clk_set_rate(dpi->pixel_clk, vm.pixelclock);
0541 
0542 
0543     vm.pixelclock = clk_get_rate(dpi->pixel_clk);
0544 
0545     dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
0546         pll_rate, vm.pixelclock);
0547 
0548     dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
0549     dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
0550     dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
0551                 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
0552     dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
0553                 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
0554 
0555     /*
0556      * Depending on the IP version, we may output a different amount of
0557      * pixels for each iteration: divide the clock by this number and
0558      * adjust the display porches accordingly.
0559      */
0560     hsync.sync_width = vm.hsync_len / dpi->conf->pixels_per_iter;
0561     hsync.back_porch = vm.hback_porch / dpi->conf->pixels_per_iter;
0562     hsync.front_porch = vm.hfront_porch / dpi->conf->pixels_per_iter;
0563 
0564     hsync.shift_half_line = false;
0565     vsync_lodd.sync_width = vm.vsync_len;
0566     vsync_lodd.back_porch = vm.vback_porch;
0567     vsync_lodd.front_porch = vm.vfront_porch;
0568     vsync_lodd.shift_half_line = false;
0569 
0570     if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
0571         mode->flags & DRM_MODE_FLAG_3D_MASK) {
0572         vsync_leven = vsync_lodd;
0573         vsync_rodd = vsync_lodd;
0574         vsync_reven = vsync_lodd;
0575         vsync_leven.shift_half_line = true;
0576         vsync_reven.shift_half_line = true;
0577     } else if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
0578            !(mode->flags & DRM_MODE_FLAG_3D_MASK)) {
0579         vsync_leven = vsync_lodd;
0580         vsync_leven.shift_half_line = true;
0581     } else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) &&
0582            mode->flags & DRM_MODE_FLAG_3D_MASK) {
0583         vsync_rodd = vsync_lodd;
0584     }
0585     mtk_dpi_sw_reset(dpi, true);
0586     mtk_dpi_config_pol(dpi, &dpi_pol);
0587 
0588     mtk_dpi_config_hsync(dpi, &hsync);
0589     mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
0590     mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
0591     mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
0592     mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
0593 
0594     mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
0595     mtk_dpi_config_interface(dpi, !!(vm.flags &
0596                      DISPLAY_FLAGS_INTERLACED));
0597     if (vm.flags & DISPLAY_FLAGS_INTERLACED)
0598         mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1);
0599     else
0600         mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
0601 
0602     mtk_dpi_config_channel_limit(dpi);
0603     mtk_dpi_config_bit_num(dpi, dpi->bit_num);
0604     mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
0605     mtk_dpi_config_color_format(dpi, dpi->color_format);
0606     if (dpi->conf->support_direct_pin) {
0607         mtk_dpi_config_yc_map(dpi, dpi->yc_map);
0608         mtk_dpi_config_2n_h_fre(dpi);
0609         mtk_dpi_dual_edge(dpi);
0610         mtk_dpi_config_disable_edge(dpi);
0611     }
0612     if (dpi->conf->input_2pixel) {
0613         mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
0614                  DPINTF_INPUT_2P_EN);
0615     }
0616     mtk_dpi_sw_reset(dpi, false);
0617 
0618     return 0;
0619 }
0620 
0621 static u32 *mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
0622                               struct drm_bridge_state *bridge_state,
0623                               struct drm_crtc_state *crtc_state,
0624                               struct drm_connector_state *conn_state,
0625                               unsigned int *num_output_fmts)
0626 {
0627     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0628     u32 *output_fmts;
0629 
0630     *num_output_fmts = 0;
0631 
0632     if (!dpi->conf->output_fmts) {
0633         dev_err(dpi->dev, "output_fmts should not be null\n");
0634         return NULL;
0635     }
0636 
0637     output_fmts = kcalloc(dpi->conf->num_output_fmts, sizeof(*output_fmts),
0638                  GFP_KERNEL);
0639     if (!output_fmts)
0640         return NULL;
0641 
0642     *num_output_fmts = dpi->conf->num_output_fmts;
0643 
0644     memcpy(output_fmts, dpi->conf->output_fmts,
0645            sizeof(*output_fmts) * dpi->conf->num_output_fmts);
0646 
0647     return output_fmts;
0648 }
0649 
0650 static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
0651                              struct drm_bridge_state *bridge_state,
0652                              struct drm_crtc_state *crtc_state,
0653                              struct drm_connector_state *conn_state,
0654                              u32 output_fmt,
0655                              unsigned int *num_input_fmts)
0656 {
0657     u32 *input_fmts;
0658 
0659     *num_input_fmts = 0;
0660 
0661     input_fmts = kcalloc(1, sizeof(*input_fmts),
0662                  GFP_KERNEL);
0663     if (!input_fmts)
0664         return NULL;
0665 
0666     *num_input_fmts = 1;
0667     input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
0668 
0669     return input_fmts;
0670 }
0671 
0672 static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
0673                        struct drm_bridge_state *bridge_state,
0674                        struct drm_crtc_state *crtc_state,
0675                        struct drm_connector_state *conn_state)
0676 {
0677     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0678     unsigned int out_bus_format;
0679 
0680     out_bus_format = bridge_state->output_bus_cfg.format;
0681 
0682     if (out_bus_format == MEDIA_BUS_FMT_FIXED)
0683         if (dpi->conf->num_output_fmts)
0684             out_bus_format = dpi->conf->output_fmts[0];
0685 
0686     dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
0687         bridge_state->input_bus_cfg.format,
0688         bridge_state->output_bus_cfg.format);
0689 
0690     dpi->output_fmt = out_bus_format;
0691     dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
0692     dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
0693     dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
0694     if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
0695         dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422;
0696     else
0697         dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
0698 
0699     return 0;
0700 }
0701 
0702 static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
0703                  enum drm_bridge_attach_flags flags)
0704 {
0705     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0706 
0707     return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
0708                  &dpi->bridge, flags);
0709 }
0710 
0711 static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge,
0712                 const struct drm_display_mode *mode,
0713                 const struct drm_display_mode *adjusted_mode)
0714 {
0715     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0716 
0717     drm_mode_copy(&dpi->mode, adjusted_mode);
0718 }
0719 
0720 static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
0721 {
0722     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0723 
0724     mtk_dpi_power_off(dpi);
0725 }
0726 
0727 static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
0728 {
0729     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0730 
0731     mtk_dpi_power_on(dpi);
0732     mtk_dpi_set_display_mode(dpi, &dpi->mode);
0733     mtk_dpi_enable(dpi);
0734 }
0735 
0736 static enum drm_mode_status
0737 mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
0738               const struct drm_display_info *info,
0739               const struct drm_display_mode *mode)
0740 {
0741     struct mtk_dpi *dpi = bridge_to_dpi(bridge);
0742 
0743     if (mode->clock > dpi->conf->max_clock_khz)
0744         return MODE_CLOCK_HIGH;
0745 
0746     return MODE_OK;
0747 }
0748 
0749 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
0750     .attach = mtk_dpi_bridge_attach,
0751     .mode_set = mtk_dpi_bridge_mode_set,
0752     .mode_valid = mtk_dpi_bridge_mode_valid,
0753     .disable = mtk_dpi_bridge_disable,
0754     .enable = mtk_dpi_bridge_enable,
0755     .atomic_check = mtk_dpi_bridge_atomic_check,
0756     .atomic_get_output_bus_fmts = mtk_dpi_bridge_atomic_get_output_bus_fmts,
0757     .atomic_get_input_bus_fmts = mtk_dpi_bridge_atomic_get_input_bus_fmts,
0758     .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
0759     .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
0760     .atomic_reset = drm_atomic_helper_bridge_reset,
0761 };
0762 
0763 void mtk_dpi_start(struct device *dev)
0764 {
0765     struct mtk_dpi *dpi = dev_get_drvdata(dev);
0766 
0767     mtk_dpi_power_on(dpi);
0768 }
0769 
0770 void mtk_dpi_stop(struct device *dev)
0771 {
0772     struct mtk_dpi *dpi = dev_get_drvdata(dev);
0773 
0774     mtk_dpi_power_off(dpi);
0775 }
0776 
0777 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
0778 {
0779     struct mtk_dpi *dpi = dev_get_drvdata(dev);
0780     struct drm_device *drm_dev = data;
0781     int ret;
0782 
0783     ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
0784                       DRM_MODE_ENCODER_TMDS);
0785     if (ret) {
0786         dev_err(dev, "Failed to initialize decoder: %d\n", ret);
0787         return ret;
0788     }
0789 
0790     dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->dev);
0791 
0792     ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL,
0793                 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
0794     if (ret)
0795         goto err_cleanup;
0796 
0797     dpi->connector = drm_bridge_connector_init(drm_dev, &dpi->encoder);
0798     if (IS_ERR(dpi->connector)) {
0799         dev_err(dev, "Unable to create bridge connector\n");
0800         ret = PTR_ERR(dpi->connector);
0801         goto err_cleanup;
0802     }
0803     drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
0804 
0805     return 0;
0806 
0807 err_cleanup:
0808     drm_encoder_cleanup(&dpi->encoder);
0809     return ret;
0810 }
0811 
0812 static void mtk_dpi_unbind(struct device *dev, struct device *master,
0813                void *data)
0814 {
0815     struct mtk_dpi *dpi = dev_get_drvdata(dev);
0816 
0817     drm_encoder_cleanup(&dpi->encoder);
0818 }
0819 
0820 static const struct component_ops mtk_dpi_component_ops = {
0821     .bind = mtk_dpi_bind,
0822     .unbind = mtk_dpi_unbind,
0823 };
0824 
0825 static unsigned int mt8173_calculate_factor(int clock)
0826 {
0827     if (clock <= 27000)
0828         return 3 << 4;
0829     else if (clock <= 84000)
0830         return 3 << 3;
0831     else if (clock <= 167000)
0832         return 3 << 2;
0833     else
0834         return 3 << 1;
0835 }
0836 
0837 static unsigned int mt2701_calculate_factor(int clock)
0838 {
0839     if (clock <= 64000)
0840         return 4;
0841     else if (clock <= 128000)
0842         return 2;
0843     else
0844         return 1;
0845 }
0846 
0847 static unsigned int mt8183_calculate_factor(int clock)
0848 {
0849     if (clock <= 27000)
0850         return 8;
0851     else if (clock <= 167000)
0852         return 4;
0853     else
0854         return 2;
0855 }
0856 
0857 static unsigned int mt8195_dpintf_calculate_factor(int clock)
0858 {
0859     if (clock < 70000)
0860         return 4;
0861     else if (clock < 200000)
0862         return 2;
0863     else
0864         return 1;
0865 }
0866 
0867 static const u32 mt8173_output_fmts[] = {
0868     MEDIA_BUS_FMT_RGB888_1X24,
0869 };
0870 
0871 static const u32 mt8183_output_fmts[] = {
0872     MEDIA_BUS_FMT_RGB888_2X12_LE,
0873     MEDIA_BUS_FMT_RGB888_2X12_BE,
0874 };
0875 
0876 static const u32 mt8195_output_fmts[] = {
0877     MEDIA_BUS_FMT_RGB888_1X24,
0878     MEDIA_BUS_FMT_YUYV8_1X16,
0879 };
0880 
0881 static const struct mtk_dpi_conf mt8173_conf = {
0882     .cal_factor = mt8173_calculate_factor,
0883     .reg_h_fre_con = 0xe0,
0884     .max_clock_khz = 300000,
0885     .output_fmts = mt8173_output_fmts,
0886     .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
0887     .pixels_per_iter = 1,
0888     .is_ck_de_pol = true,
0889     .swap_input_support = true,
0890     .support_direct_pin = true,
0891     .dimension_mask = HPW_MASK,
0892     .hvsize_mask = HSIZE_MASK,
0893     .channel_swap_shift = CH_SWAP,
0894     .yuv422_en_bit = YUV422_EN,
0895     .csc_enable_bit = CSC_ENABLE,
0896 };
0897 
0898 static const struct mtk_dpi_conf mt2701_conf = {
0899     .cal_factor = mt2701_calculate_factor,
0900     .reg_h_fre_con = 0xb0,
0901     .edge_sel_en = true,
0902     .max_clock_khz = 150000,
0903     .output_fmts = mt8173_output_fmts,
0904     .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
0905     .pixels_per_iter = 1,
0906     .is_ck_de_pol = true,
0907     .swap_input_support = true,
0908     .support_direct_pin = true,
0909     .dimension_mask = HPW_MASK,
0910     .hvsize_mask = HSIZE_MASK,
0911     .channel_swap_shift = CH_SWAP,
0912     .yuv422_en_bit = YUV422_EN,
0913     .csc_enable_bit = CSC_ENABLE,
0914 };
0915 
0916 static const struct mtk_dpi_conf mt8183_conf = {
0917     .cal_factor = mt8183_calculate_factor,
0918     .reg_h_fre_con = 0xe0,
0919     .max_clock_khz = 100000,
0920     .output_fmts = mt8183_output_fmts,
0921     .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
0922     .pixels_per_iter = 1,
0923     .is_ck_de_pol = true,
0924     .swap_input_support = true,
0925     .support_direct_pin = true,
0926     .dimension_mask = HPW_MASK,
0927     .hvsize_mask = HSIZE_MASK,
0928     .channel_swap_shift = CH_SWAP,
0929     .yuv422_en_bit = YUV422_EN,
0930     .csc_enable_bit = CSC_ENABLE,
0931 };
0932 
0933 static const struct mtk_dpi_conf mt8192_conf = {
0934     .cal_factor = mt8183_calculate_factor,
0935     .reg_h_fre_con = 0xe0,
0936     .max_clock_khz = 150000,
0937     .output_fmts = mt8183_output_fmts,
0938     .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
0939     .pixels_per_iter = 1,
0940     .is_ck_de_pol = true,
0941     .swap_input_support = true,
0942     .support_direct_pin = true,
0943     .dimension_mask = HPW_MASK,
0944     .hvsize_mask = HSIZE_MASK,
0945     .channel_swap_shift = CH_SWAP,
0946     .yuv422_en_bit = YUV422_EN,
0947     .csc_enable_bit = CSC_ENABLE,
0948 };
0949 
0950 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
0951     .cal_factor = mt8195_dpintf_calculate_factor,
0952     .max_clock_khz = 600000,
0953     .output_fmts = mt8195_output_fmts,
0954     .num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
0955     .pixels_per_iter = 4,
0956     .input_2pixel = true,
0957     .dimension_mask = DPINTF_HPW_MASK,
0958     .hvsize_mask = DPINTF_HSIZE_MASK,
0959     .channel_swap_shift = DPINTF_CH_SWAP,
0960     .yuv422_en_bit = DPINTF_YUV422_EN,
0961     .csc_enable_bit = DPINTF_CSC_ENABLE,
0962 };
0963 
0964 static int mtk_dpi_probe(struct platform_device *pdev)
0965 {
0966     struct device *dev = &pdev->dev;
0967     struct mtk_dpi *dpi;
0968     struct resource *mem;
0969     int ret;
0970 
0971     dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
0972     if (!dpi)
0973         return -ENOMEM;
0974 
0975     dpi->dev = dev;
0976     dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
0977     dpi->output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
0978 
0979     dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
0980     if (IS_ERR(dpi->pinctrl)) {
0981         dpi->pinctrl = NULL;
0982         dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
0983     }
0984     if (dpi->pinctrl) {
0985         dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep");
0986         if (IS_ERR(dpi->pins_gpio)) {
0987             dpi->pins_gpio = NULL;
0988             dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n");
0989         }
0990         if (dpi->pins_gpio)
0991             pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
0992 
0993         dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default");
0994         if (IS_ERR(dpi->pins_dpi)) {
0995             dpi->pins_dpi = NULL;
0996             dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
0997         }
0998     }
0999     mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1000     dpi->regs = devm_ioremap_resource(dev, mem);
1001     if (IS_ERR(dpi->regs)) {
1002         ret = PTR_ERR(dpi->regs);
1003         dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
1004         return ret;
1005     }
1006 
1007     dpi->engine_clk = devm_clk_get(dev, "engine");
1008     if (IS_ERR(dpi->engine_clk)) {
1009         ret = PTR_ERR(dpi->engine_clk);
1010         if (ret != -EPROBE_DEFER)
1011             dev_err(dev, "Failed to get engine clock: %d\n", ret);
1012 
1013         return ret;
1014     }
1015 
1016     dpi->pixel_clk = devm_clk_get(dev, "pixel");
1017     if (IS_ERR(dpi->pixel_clk)) {
1018         ret = PTR_ERR(dpi->pixel_clk);
1019         if (ret != -EPROBE_DEFER)
1020             dev_err(dev, "Failed to get pixel clock: %d\n", ret);
1021 
1022         return ret;
1023     }
1024 
1025     dpi->tvd_clk = devm_clk_get(dev, "pll");
1026     if (IS_ERR(dpi->tvd_clk)) {
1027         ret = PTR_ERR(dpi->tvd_clk);
1028         if (ret != -EPROBE_DEFER)
1029             dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
1030 
1031         return ret;
1032     }
1033 
1034     dpi->irq = platform_get_irq(pdev, 0);
1035     if (dpi->irq <= 0)
1036         return -EINVAL;
1037 
1038     ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
1039                       NULL, &dpi->next_bridge);
1040     if (ret)
1041         return ret;
1042 
1043     dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
1044 
1045     platform_set_drvdata(pdev, dpi);
1046 
1047     dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
1048     dpi->bridge.of_node = dev->of_node;
1049     dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
1050 
1051     drm_bridge_add(&dpi->bridge);
1052 
1053     ret = component_add(dev, &mtk_dpi_component_ops);
1054     if (ret) {
1055         drm_bridge_remove(&dpi->bridge);
1056         dev_err(dev, "Failed to add component: %d\n", ret);
1057         return ret;
1058     }
1059 
1060     return 0;
1061 }
1062 
1063 static int mtk_dpi_remove(struct platform_device *pdev)
1064 {
1065     struct mtk_dpi *dpi = platform_get_drvdata(pdev);
1066 
1067     component_del(&pdev->dev, &mtk_dpi_component_ops);
1068     drm_bridge_remove(&dpi->bridge);
1069 
1070     return 0;
1071 }
1072 
1073 static const struct of_device_id mtk_dpi_of_ids[] = {
1074     { .compatible = "mediatek,mt2701-dpi",
1075       .data = &mt2701_conf,
1076     },
1077     { .compatible = "mediatek,mt8173-dpi",
1078       .data = &mt8173_conf,
1079     },
1080     { .compatible = "mediatek,mt8183-dpi",
1081       .data = &mt8183_conf,
1082     },
1083     { .compatible = "mediatek,mt8192-dpi",
1084       .data = &mt8192_conf,
1085     },
1086     { .compatible = "mediatek,mt8195-dp-intf",
1087       .data = &mt8195_dpintf_conf,
1088     },
1089     { },
1090 };
1091 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
1092 
1093 struct platform_driver mtk_dpi_driver = {
1094     .probe = mtk_dpi_probe,
1095     .remove = mtk_dpi_remove,
1096     .driver = {
1097         .name = "mediatek-dpi",
1098         .of_match_table = mtk_dpi_of_ids,
1099     },
1100 };