diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml index b4c28e96dd55..cf24434854ff 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml @@ -36,6 +36,7 @@ properties: - mediatek,mt8188-disp-aal - mediatek,mt8192-disp-aal - mediatek,mt8195-disp-aal + - mediatek,mt8365-disp-aal - const: mediatek,mt8183-disp-aal reg: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml index 8c2a737237f2..9f8366763831 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml @@ -24,6 +24,9 @@ properties: - enum: - mediatek,mt8183-disp-ccorr - mediatek,mt8192-disp-ccorr + - items: + - const: mediatek,mt8365-disp-ccorr + - const: mediatek,mt8183-disp-ccorr - items: - enum: - mediatek,mt8186-disp-ccorr diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml index b886ca0d89ea..7df786bbad20 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml @@ -40,6 +40,7 @@ properties: - mediatek,mt8188-disp-color - mediatek,mt8192-disp-color - mediatek,mt8195-disp-color + - mediatek,mt8365-disp-color - const: mediatek,mt8173-disp-color reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml index 1588b3f7cec7..6fceb1f95d2a 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml @@ -30,6 +30,7 @@ properties: - mediatek,mt8188-disp-dither - mediatek,mt8192-disp-dither - mediatek,mt8195-disp-dither + - mediatek,mt8365-disp-dither - const: mediatek,mt8183-disp-dither reg: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml index 803c00f26206..5ca7679d5427 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml @@ -31,6 +31,10 @@ properties: - enum: - mediatek,mt6795-dpi - const: mediatek,mt8183-dpi + - items: + - enum: + - mediatek,mt8365-dpi + - const: mediatek,mt8192-dpi reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml index 8611319bed2e..a7aa8fcb0dd1 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml @@ -37,6 +37,7 @@ properties: - items: - enum: - mediatek,mt8195-dsi + - mediatek,mt8365-dsi - const: mediatek,mt8183-dsi reg: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml index b8b8e83ebc3f..6823d3ce5049 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml @@ -35,6 +35,7 @@ properties: - mediatek,mt8188-disp-gamma - mediatek,mt8192-disp-gamma - mediatek,mt8195-disp-gamma + - mediatek,mt8365-disp-gamma - const: mediatek,mt8183-disp-gamma - items: - enum: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml index c471a181d125..d55611c7ce5e 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml @@ -44,6 +44,7 @@ properties: - items: - enum: - mediatek,mt8186-disp-ovl + - mediatek,mt8365-disp-ovl - const: mediatek,mt8192-disp-ovl reg: diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml index 39dbb5c8bcf8..4cadb245d028 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml @@ -45,6 +45,7 @@ properties: - enum: - mediatek,mt8186-disp-rdma - mediatek,mt8192-disp-rdma + - mediatek,mt8365-disp-rdma - const: mediatek,mt8183-disp-rdma reg: diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c index 8519e9bade36..2de248443147 100644 --- a/drivers/gpu/drm/mediatek/mtk_cec.c +++ b/drivers/gpu/drm/mediatek/mtk_cec.c @@ -195,18 +195,14 @@ static int mtk_cec_probe(struct platform_device *pdev) spin_lock_init(&cec->lock); cec->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(cec->regs)) { - ret = PTR_ERR(cec->regs); - dev_err(dev, "Failed to ioremap cec: %d\n", ret); - return ret; - } + if (IS_ERR(cec->regs)) + return dev_err_probe(dev, PTR_ERR(cec->regs), + "Failed to ioremap cec\n"); cec->clk = devm_clk_get(dev, NULL); - if (IS_ERR(cec->clk)) { - ret = PTR_ERR(cec->clk); - dev_err(dev, "Failed to get cec clock: %d\n", ret); - return ret; - } + if (IS_ERR(cec->clk)) + return dev_err_probe(dev, PTR_ERR(cec->clk), + "Failed to get cec clock\n"); cec->irq = platform_get_irq(pdev, 0); if (cec->irq < 0) @@ -216,16 +212,12 @@ static int mtk_cec_probe(struct platform_device *pdev) mtk_cec_htplg_isr_thread, IRQF_SHARED | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "hdmi hpd", dev); - if (ret) { - dev_err(dev, "Failed to register cec irq: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to register cec irq\n"); ret = clk_prepare_enable(cec->clk); - if (ret) { - dev_err(dev, "Failed to enable cec clock: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to enable cec clock\n"); mtk_cec_htplg_irq_init(cec); mtk_cec_htplg_irq_enable(cec); diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c index 17b036411292..be66d94be361 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c @@ -514,29 +514,42 @@ static bool mtk_ddp_comp_find(struct device *dev, return false; } -static unsigned int mtk_ddp_comp_find_in_route(struct device *dev, - const struct mtk_drm_route *routes, - unsigned int num_routes, - struct mtk_ddp_comp *ddp_comp) +static int mtk_ddp_comp_find_in_route(struct device *dev, + const struct mtk_drm_route *routes, + unsigned int num_routes, + struct mtk_ddp_comp *ddp_comp) { - int ret; unsigned int i; - if (!routes) { - ret = -EINVAL; - goto err; - } + if (!routes) + return -EINVAL; for (i = 0; i < num_routes; i++) if (dev == ddp_comp[routes[i].route_ddp].dev) return BIT(routes[i].crtc_id); - ret = -ENODEV; -err: + return -ENODEV; +} - DRM_INFO("Failed to find comp in ddp table, ret = %d\n", ret); +static bool mtk_ddp_path_available(const unsigned int *path, + unsigned int path_len, + struct device_node **comp_node) +{ + unsigned int i; - return 0; + if (!path || !path_len) + return false; + + for (i = 0U; i < path_len; i++) { + /* OVL_ADAPTOR doesn't have a device node */ + if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR) + continue; + + if (!comp_node[path[i]]) + return false; + } + + return true; } int mtk_ddp_comp_get_id(struct device_node *node, @@ -554,31 +567,53 @@ int mtk_ddp_comp_get_id(struct device_node *node, return -EINVAL; } -unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev) +int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev) { struct mtk_drm_private *private = drm->dev_private; - unsigned int ret = 0; + const struct mtk_mmsys_driver_data *data; + struct mtk_drm_private *priv_n; + int i = 0, j; + int ret; - if (mtk_ddp_comp_find(dev, - private->data->main_path, - private->data->main_len, - private->ddp_comp)) - ret = BIT(0); - else if (mtk_ddp_comp_find(dev, - private->data->ext_path, - private->data->ext_len, - private->ddp_comp)) - ret = BIT(1); - else if (mtk_ddp_comp_find(dev, - private->data->third_path, - private->data->third_len, - private->ddp_comp)) - ret = BIT(2); - else - ret = mtk_ddp_comp_find_in_route(dev, - private->data->conn_routes, - private->data->num_conn_routes, - private->ddp_comp); + for (j = 0; j < private->data->mmsys_dev_num; j++) { + priv_n = private->all_drm_private[j]; + data = priv_n->data; + + if (mtk_ddp_path_available(data->main_path, data->main_len, + priv_n->comp_node)) { + if (mtk_ddp_comp_find(dev, data->main_path, + data->main_len, + priv_n->ddp_comp)) + return BIT(i); + i++; + } + + if (mtk_ddp_path_available(data->ext_path, data->ext_len, + priv_n->comp_node)) { + if (mtk_ddp_comp_find(dev, data->ext_path, + data->ext_len, + priv_n->ddp_comp)) + return BIT(i); + i++; + } + + if (mtk_ddp_path_available(data->third_path, data->third_len, + priv_n->comp_node)) { + if (mtk_ddp_comp_find(dev, data->third_path, + data->third_len, + priv_n->ddp_comp)) + return BIT(i); + i++; + } + } + + ret = mtk_ddp_comp_find_in_route(dev, + private->data->conn_routes, + private->data->num_conn_routes, + private->ddp_comp); + + if (ret < 0) + DRM_INFO("Failed to find comp in ddp table, ret = %d\n", ret); return ret; } @@ -593,7 +628,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, int ret; #endif - if (comp_id < 0 || comp_id >= DDP_COMPONENT_DRM_ID_MAX) + if (comp_id >= DDP_COMPONENT_DRM_ID_MAX) return -EINVAL; type = mtk_ddp_matches[comp_id].type; diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h index 26236691ce4c..ecf6dc283cd7 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h @@ -192,7 +192,11 @@ unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp) if (comp->funcs && comp->funcs->supported_rotations) return comp->funcs->supported_rotations(comp->dev); - return 0; + /* + * In order to pass IGT tests, DRM_MODE_ROTATE_0 is required when + * rotation is not supported. + */ + return DRM_MODE_ROTATE_0; } static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp) @@ -326,7 +330,7 @@ static inline void mtk_ddp_comp_encoder_index_set(struct mtk_ddp_comp *comp) int mtk_ddp_comp_get_id(struct device_node *node, enum mtk_ddp_comp_type comp_type); -unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev); +int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev); int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp, unsigned int comp_id); enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c index 3ce8f32b06d5..59fb9a08d54b 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c @@ -175,16 +175,14 @@ static int mtk_disp_aal_probe(struct platform_device *pdev) return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get aal clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get aal clk\n"); priv->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap aal\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap aal\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); @@ -197,9 +195,9 @@ static int mtk_disp_aal_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_aal_component_ops); if (ret) - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_disp_aal_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c index df35e90dd25f..9b75727e0861 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c @@ -160,16 +160,14 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev) return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get ccorr clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get ccorr clk\n"); priv->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap ccorr\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap ccorr\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); @@ -182,9 +180,9 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_ccorr_component_ops); if (ret) - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_disp_ccorr_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 7f0085be5671..2fd5e7dc9e24 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -104,17 +104,15 @@ static int mtk_disp_color_probe(struct platform_device *pdev) return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get color clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get color clk\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap color\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap color\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) @@ -126,9 +124,9 @@ static int mtk_disp_color_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_color_component_ops); if (ret) - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_disp_color_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c index ca8d1f3aca03..f0b38817ba6c 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -264,17 +264,15 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev) return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get gamma clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get gamma clk\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap gamma\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap gamma\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); @@ -287,9 +285,9 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_gamma_component_ops); if (ret) - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_disp_gamma_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 77c057e0e671..435e5d9c8520 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -316,22 +316,19 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap merge\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap merge\n"); priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get merge clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get merge clk\n"); priv->async_clk = devm_clk_get_optional(dev, "merge_async"); - if (IS_ERR(priv->async_clk)) { - dev_err(dev, "failed to get merge async clock\n"); - return PTR_ERR(priv->async_clk); - } + if (IS_ERR(priv->async_clk)) + return dev_err_probe(dev, PTR_ERR(priv->async_clk), + "failed to get merge async clock\n"); if (priv->async_clk) { priv->reset_ctl = devm_reset_control_get_optional_exclusive(dev, NULL); @@ -354,9 +351,9 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_merge_component_ops); if (ret != 0) - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_disp_merge_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index b552a02d7eae..9d6d9fd8342e 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -38,10 +38,15 @@ #define DISP_REG_OVL_PITCH_MSB(n) (0x0040 + 0x20 * (n)) #define OVL_PITCH_MSB_2ND_SUBBUF BIT(16) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) +#define OVL_CONST_BLEND BIT(28) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040 -#define DISP_REG_OVL_CLRFMT_EXT 0x02D0 +#define DISP_REG_OVL_CLRFMT_EXT 0x02d0 +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(n) (GENMASK(1, 0) << (4 * (n))) +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, n) ((depth) << (4 * (n))) +#define OVL_CON_CLRFMT_8_BIT (0) +#define OVL_CON_CLRFMT_10_BIT (1) #define DISP_REG_OVL_ADDR_MT8173 0x0f40 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) #define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04) @@ -54,23 +59,39 @@ #define OVL_CON_BYTE_SWAP BIT(24) #define OVL_CON_MTX_YUV_TO_RGB (6 << 16) #define OVL_CON_CLRFMT_RGB (1 << 12) -#define OVL_CON_CLRFMT_RGBA8888 (2 << 12) -#define OVL_CON_CLRFMT_ARGB8888 (3 << 12) +#define OVL_CON_CLRFMT_ARGB8888 (2 << 12) +#define OVL_CON_CLRFMT_RGBA8888 (3 << 12) +#define OVL_CON_CLRFMT_ABGR8888 (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP) +#define OVL_CON_CLRFMT_BGRA8888 (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP) #define OVL_CON_CLRFMT_UYVY (4 << 12) #define OVL_CON_CLRFMT_YUYV (5 << 12) #define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ 0 : OVL_CON_CLRFMT_RGB) #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ OVL_CON_CLRFMT_RGB : 0) -#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl)) -#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl)) -#define OVL_CON_CLRFMT_8_BIT 0x00 -#define OVL_CON_CLRFMT_10_BIT 0x01 #define OVL_CON_AEN BIT(8) #define OVL_CON_ALPHA 0xff #define OVL_CON_VIRT_FLIP BIT(9) #define OVL_CON_HORZ_FLIP BIT(10) +#define OVL_COLOR_ALPHA GENMASK(31, 24) + +static inline bool is_10bit_rgb(u32 fmt) +{ + switch (fmt) { + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_BGRA1010102: + return true; + } + return false; +} + static const u32 mt8173_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, @@ -88,12 +109,20 @@ static const u32 mt8173_formats[] = { static const u32 mt8195_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010, DRM_FORMAT_BGRX8888, DRM_FORMAT_BGRA8888, + DRM_FORMAT_BGRX1010102, DRM_FORMAT_BGRA1010102, DRM_FORMAT_ABGR8888, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_RGBX1010102, + DRM_FORMAT_RGBA1010102, DRM_FORMAT_RGB888, DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, @@ -244,24 +273,17 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format, struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); - unsigned int reg; unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT; if (!ovl->data->supports_clrfmt_ext) return; - reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT); - reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx); - - if (format == DRM_FORMAT_RGBA1010102 || - format == DRM_FORMAT_BGRA1010102 || - format == DRM_FORMAT_ARGB2101010) + if (is_10bit_rgb(format)) bit_depth = OVL_CON_CLRFMT_10_BIT; - reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx); - - mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg, - ovl->regs, DISP_REG_OVL_CLRFMT_EXT); + mtk_ddp_write_mask(cmdq_pkt, OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx), + &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT, + OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx)); } void mtk_ovl_config(struct device *dev, unsigned int w, @@ -273,7 +295,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w, if (w != 0 && h != 0) mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_SIZE); - mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR); + + /* + * The background color must be opaque black (ARGB), + * otherwise the alpha blending will have no effect + */ + mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg, + ovl->regs, DISP_REG_OVL_ROI_BGCLR); mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST); @@ -296,27 +324,20 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx, struct mtk_plane_state *mtk_state) { struct drm_plane_state *state = &mtk_state->base; - unsigned int rotation = 0; - rotation = drm_rotation_simplify(state->rotation, - DRM_MODE_ROTATE_0 | - DRM_MODE_REFLECT_X | - DRM_MODE_REFLECT_Y); - rotation &= ~DRM_MODE_ROTATE_0; - - /* We can only do reflection, not rotation */ - if ((rotation & DRM_MODE_ROTATE_MASK) != 0) + /* check if any unsupported rotation is set */ + if (state->rotation & ~mtk_ovl_supported_rotations(dev)) return -EINVAL; /* * TODO: Rotating/reflecting YUV buffers is not supported at this time. * Only RGB[AX] variants are supported. + * Since DRM_MODE_ROTATE_0 means "no rotation", we should not + * reject layers with this property. */ - if (state->fb->format->is_yuv && rotation != 0) + if (state->fb->format->is_yuv && (state->rotation & ~DRM_MODE_ROTATE_0)) return -EINVAL; - state->rotation = rotation; - return 0; } @@ -375,18 +396,24 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP; case DRM_FORMAT_RGBX8888: case DRM_FORMAT_RGBA8888: - return OVL_CON_CLRFMT_ARGB8888; + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_RGBA1010102: + return OVL_CON_CLRFMT_RGBA8888; case DRM_FORMAT_BGRX8888: case DRM_FORMAT_BGRA8888: + case DRM_FORMAT_BGRX1010102: case DRM_FORMAT_BGRA1010102: - return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP; + return OVL_CON_CLRFMT_BGRA8888; case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_ARGB2101010: - return OVL_CON_CLRFMT_RGBA8888; + return OVL_CON_CLRFMT_ARGB8888; case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: - return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP; + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + return OVL_CON_CLRFMT_ABGR8888; case DRM_FORMAT_UYVY: return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB; case DRM_FORMAT_YUYV: @@ -407,6 +434,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, unsigned int fmt = pending->format; unsigned int offset = (pending->y << 16) | pending->x; unsigned int src_size = (pending->height << 16) | pending->width; + unsigned int ignore_pixel_alpha = 0; unsigned int con; bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; union overlay_pitch { @@ -425,8 +453,18 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, } con = ovl_fmt_convert(ovl, fmt); - if (state->base.fb && state->base.fb->format->has_alpha) - con |= OVL_CON_AEN | OVL_CON_ALPHA; + if (state->base.fb) { + con |= OVL_CON_AEN; + con |= state->base.alpha & OVL_CON_ALPHA; + } + + /* CONST_BLD must be enabled for XRGB formats although the alpha channel + * can be ignored, or OVL will still read the value from memory. + * For RGB888 related formats, whether CONST_BLD is enabled or not won't + * affect the result. Therefore we use !has_alpha as the condition. + */ + if (state->base.fb && !state->base.fb->format->has_alpha) + ignore_pixel_alpha = OVL_CONST_BLEND; if (pending->rotation & DRM_MODE_REFLECT_Y) { con |= OVL_CON_VIRT_FLIP; @@ -443,8 +481,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CON(idx)); - mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs, - DISP_REG_OVL_PITCH(idx)); + mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha, + &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx)); mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_SRC_SIZE(idx)); mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs, @@ -523,17 +561,15 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) return irq; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get ovl clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get ovl clk\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap ovl\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap ovl\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) @@ -545,20 +581,18 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler, IRQF_TRIGGER_NONE, dev_name(dev), priv); - if (ret < 0) { - dev_err(dev, "Failed to request irq %d: %d\n", irq, ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq); pm_runtime_enable(dev); ret = component_add(dev, &mtk_disp_ovl_component_ops); if (ret) { pm_runtime_disable(dev); - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); } - return ret; + return 0; } static void mtk_disp_ovl_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index 02dd7dcdfedb..1a2a73757370 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -158,7 +158,7 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx, merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx]; ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]; - if (!pending->enable) { + if (!pending->enable || !pending->width || !pending->height) { mtk_merge_stop_cmdq(merge, cmdq_pkt); mtk_mdp_rdma_stop(rdma_l, cmdq_pkt); mtk_mdp_rdma_stop(rdma_r, cmdq_pkt); @@ -612,10 +612,10 @@ static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_ovl_adaptor_comp_ops); if (ret != 0) { pm_runtime_disable(dev); - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); } - return ret; + return 0; } static void mtk_disp_ovl_adaptor_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 7b1a6e631200..634bbba5d43f 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -326,17 +326,15 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) return irq; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get rdma clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get rdma clk\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap rdma\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap rdma\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) @@ -347,10 +345,9 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) ret = of_property_read_u32(dev->of_node, "mediatek,rdma-fifo-size", &priv->fifo_size); - if (ret) { - dev_err(dev, "Failed to get rdma fifo size\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "Failed to get rdma fifo size\n"); } /* Disable and clear pending interrupts */ @@ -359,10 +356,8 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) ret = devm_request_irq(dev, irq, mtk_disp_rdma_irq_handler, IRQF_TRIGGER_NONE, dev_name(dev), priv); - if (ret < 0) { - dev_err(dev, "Failed to request irq %d: %d\n", irq, ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq); priv->data = of_device_get_match_data(dev); @@ -373,10 +368,10 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_disp_rdma_component_ops); if (ret) { pm_runtime_disable(dev); - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); } - return ret; + return 0; } static void mtk_disp_rdma_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 536366956447..d8796a904eca 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2073,9 +2073,15 @@ static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge, */ const struct edid *edid = drm_edid_raw(drm_edid); struct cea_sad *sads; + int ret; - audio_caps->sad_count = drm_edid_to_sad(edid, &sads); - kfree(sads); + ret = drm_edid_to_sad(edid, &sads); + /* Ignore any errors */ + if (ret < 0) + ret = 0; + if (ret) + kfree(sads); + audio_caps->sad_count = ret; /* * FIXME: This should use connector->display_info.has_audio from @@ -2655,11 +2661,9 @@ static int mtk_dp_probe(struct platform_device *pdev) mutex_init(&mtk_dp->update_plugged_status_lock); ret = mtk_dp_register_audio_driver(dev); - if (ret) { - dev_err(dev, "Failed to register audio driver: %d\n", - ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "Failed to register audio driver\n"); } ret = mtk_dp_register_phy(mtk_dp); diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index bfe8653005db..a08d20654954 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -805,7 +805,10 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) return ret; } - dpi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm_dev, dpi->dev); + ret = mtk_find_possible_crtcs(drm_dev, dpi->dev); + if (ret < 0) + goto err_cleanup; + dpi->encoder.possible_crtcs = ret; ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index c73f6e7c34cf..ae5c6ec24a1e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -294,6 +294,9 @@ static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = { .conn_routes = mt8188_mtk_ddp_main_routes, .num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes), .mmsys_dev_num = 2, + .max_width = 8191, + .min_width = 1, + .min_height = 1, }; static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { @@ -308,6 +311,9 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = { .main_path = mt8195_mtk_ddp_main, .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main), .mmsys_dev_num = 2, + .max_width = 8191, + .min_width = 1, + .min_height = 1, }; static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = { @@ -315,6 +321,9 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = { .ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext), .mmsys_id = 1, .mmsys_dev_num = 2, + .max_width = 8191, + .min_width = 2, /* 2-pixel align when ethdr is bypassed */ + .min_height = 1, }; static const struct of_device_id mtk_drm_of_ids[] = { @@ -493,6 +502,15 @@ static int mtk_drm_kms_init(struct drm_device *drm) for (j = 0; j < private->data->mmsys_dev_num; j++) { priv_n = private->all_drm_private[j]; + if (priv_n->data->max_width) + drm->mode_config.max_width = priv_n->data->max_width; + + if (priv_n->data->min_width) + drm->mode_config.min_width = priv_n->data->min_width; + + if (priv_n->data->min_height) + drm->mode_config.min_height = priv_n->data->min_height; + if (i == CRTC_MAIN && priv_n->data->main_len) { ret = mtk_crtc_create(drm, priv_n->data->main_path, priv_n->data->main_len, j, @@ -520,6 +538,10 @@ static int mtk_drm_kms_init(struct drm_device *drm) } } + /* IGT will check if the cursor size is configured */ + drm->mode_config.cursor_width = drm->mode_config.max_width; + drm->mode_config.cursor_height = drm->mode_config.max_height; + /* Use OVL device for all DMA memory allocations */ crtc = drm_crtc_from_index(drm, 0); if (crtc) @@ -743,6 +765,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8192-disp-ovl", .data = (void *)MTK_DISP_OVL }, + { .compatible = "mediatek,mt8195-disp-ovl", + .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8183-disp-ovl-2l", .data = (void *)MTK_DISP_OVL_2L }, { .compatible = "mediatek,mt8192-disp-ovl-2l", diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index 78d698ede1bf..ce897984de51 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h @@ -46,6 +46,10 @@ struct mtk_mmsys_driver_data { bool shadow_register; unsigned int mmsys_id; unsigned int mmsys_dev_num; + + u16 max_width; + u16 min_width; + u16 min_height; }; struct mtk_drm_private { diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index c255559cc56e..b6e3c011a12d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -837,7 +837,10 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi) return ret; } - dsi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm, dsi->host.dev); + ret = mtk_find_possible_crtcs(drm, dsi->host.dev); + if (ret < 0) + goto err_cleanup_encoder; + dsi->encoder.possible_crtcs = ret; ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c index 156c6ff547e8..9dfd13d32dfa 100644 --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c @@ -50,7 +50,6 @@ #define MIXER_INX_MODE_BYPASS 0 #define MIXER_INX_MODE_EVEN_EXTEND 1 -#define DEFAULT_9BIT_ALPHA 0x100 #define MIXER_ALPHA_AEN BIT(8) #define MIXER_ALPHA 0xff #define ETHDR_CLK_NUM 13 @@ -154,22 +153,38 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x; unsigned int align_width = ALIGN_DOWN(pending->width, 2); unsigned int alpha_con = 0; + bool replace_src_a = false; dev_dbg(dev, "%s+ idx:%d", __func__, idx); if (idx >= 4) return; - if (!pending->enable) { + if (!pending->enable || !pending->width || !pending->height) { + /* + * instead of disabling layer with MIX_SRC_CON directly + * set the size to 0 to avoid screen shift due to mixer + * mode switch (hardware behavior) + */ mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx)); return; } - if (state->base.fb && state->base.fb->format->has_alpha) - alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA; + if (state->base.fb) { + alpha_con |= MIXER_ALPHA_AEN; + alpha_con |= state->base.alpha & MIXER_ALPHA; + } - mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true, - DEFAULT_9BIT_ALPHA, + if (state->base.fb && !state->base.fb->format->has_alpha) { + /* + * Mixer doesn't support CONST_BLD mode, + * use a trick to make the output equivalent + */ + replace_src_a = true; + } + + mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a, + MIXER_ALPHA, pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND : MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt); @@ -325,25 +340,24 @@ static int mtk_ethdr_probe(struct platform_device *pdev) if (priv->irq) { ret = devm_request_irq(dev, priv->irq, mtk_ethdr_irq_handler, IRQF_TRIGGER_NONE, dev_name(dev), priv); - if (ret < 0) { - dev_err(dev, "Failed to request irq %d: %d\n", priv->irq, ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, + "Failed to request irq %d\n", + priv->irq); } priv->reset_ctl = devm_reset_control_array_get_optional_exclusive(dev); - if (IS_ERR(priv->reset_ctl)) { - dev_err_probe(dev, PTR_ERR(priv->reset_ctl), "cannot get ethdr reset control\n"); - return PTR_ERR(priv->reset_ctl); - } + if (IS_ERR(priv->reset_ctl)) + return dev_err_probe(dev, PTR_ERR(priv->reset_ctl), + "cannot get ethdr reset control\n"); platform_set_drvdata(pdev, priv); ret = component_add(dev, &mtk_ethdr_component_ops); if (ret) - dev_notice(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); - return ret; + return 0; } static void mtk_ethdr_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 0a90fe448d14..7687f673964e 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1702,26 +1702,22 @@ static int mtk_hdmi_probe(struct platform_device *pdev) return ret; hdmi->phy = devm_phy_get(dev, "hdmi"); - if (IS_ERR(hdmi->phy)) { - ret = PTR_ERR(hdmi->phy); - dev_err(dev, "Failed to get HDMI PHY: %d\n", ret); - return ret; - } + if (IS_ERR(hdmi->phy)) + return dev_err_probe(dev, PTR_ERR(hdmi->phy), + "Failed to get HDMI PHY\n"); mutex_init(&hdmi->update_plugged_status_lock); platform_set_drvdata(pdev, hdmi); ret = mtk_hdmi_output_init(hdmi); - if (ret) { - dev_err(dev, "Failed to initialize hdmi output\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "Failed to initialize hdmi output\n"); ret = mtk_hdmi_register_audio_driver(dev); - if (ret) { - dev_err(dev, "Failed to register audio driver: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "Failed to register audio driver\n"); hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs; hdmi->bridge.of_node = pdev->dev.of_node; @@ -1732,15 +1728,12 @@ static int mtk_hdmi_probe(struct platform_device *pdev) ret = mtk_hdmi_clk_enable_audio(hdmi); if (ret) { - dev_err(dev, "Failed to enable audio clocks: %d\n", ret); - goto err_bridge_remove; + drm_bridge_remove(&hdmi->bridge); + return dev_err_probe(dev, ret, + "Failed to enable audio clocks\n"); } return 0; - -err_bridge_remove: - drm_bridge_remove(&hdmi->bridge); - return ret; } static void mtk_hdmi_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c index 52d55861f954..8e60631d4cd2 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c @@ -279,20 +279,17 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev) return -ENOMEM; ddc->clk = devm_clk_get(dev, "ddc-i2c"); - if (IS_ERR(ddc->clk)) { - dev_err(dev, "get ddc_clk failed: %p ,\n", ddc->clk); - return PTR_ERR(ddc->clk); - } + if (IS_ERR(ddc->clk)) + return dev_err_probe(dev, PTR_ERR(ddc->clk), + "get ddc_clk failed\n"); ddc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); if (IS_ERR(ddc->regs)) return PTR_ERR(ddc->regs); ret = clk_prepare_enable(ddc->clk); - if (ret) { - dev_err(dev, "enable ddc clk failed!\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "enable ddc clk failed!\n"); strscpy(ddc->adap.name, "mediatek-hdmi-ddc", sizeof(ddc->adap.name)); ddc->adap.owner = THIS_MODULE; @@ -304,8 +301,8 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev) ret = i2c_add_adapter(&ddc->adap); if (ret < 0) { - dev_err(dev, "failed to add bus to i2c core\n"); - goto err_clk_disable; + clk_disable_unprepare(ddc->clk); + return dev_err_probe(dev, ret, "failed to add bus to i2c core\n"); } platform_set_drvdata(pdev, ddc); @@ -316,10 +313,6 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev) &mem->end); return 0; - -err_clk_disable: - clk_disable_unprepare(ddc->clk); - return ret; } static void mtk_hdmi_ddc_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c index 925cbb7471ec..7c1a8c796833 100644 --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -301,16 +301,14 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->regs)) { - dev_err(dev, "failed to ioremap rdma\n"); - return PTR_ERR(priv->regs); - } + if (IS_ERR(priv->regs)) + return dev_err_probe(dev, PTR_ERR(priv->regs), + "failed to ioremap rdma\n"); priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get rdma clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get rdma clk\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); @@ -324,9 +322,9 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev) ret = component_add(dev, &mtk_mdp_rdma_component_ops); if (ret != 0) { pm_runtime_disable(dev); - dev_err(dev, "Failed to add component: %d\n", ret); + return dev_err_probe(dev, ret, "Failed to add component\n"); } - return ret; + return 0; } static void mtk_mdp_rdma_remove(struct platform_device *pdev) diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c index 85bc6768b6bc..4bebd13a07bd 100644 --- a/drivers/gpu/drm/mediatek/mtk_padding.c +++ b/drivers/gpu/drm/mediatek/mtk_padding.c @@ -103,23 +103,19 @@ static int mtk_padding_probe(struct platform_device *pdev) return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - dev_err(dev, "failed to get clk\n"); - return PTR_ERR(priv->clk); - } + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "failed to get clk\n"); priv->reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->reg)) { - dev_err(dev, "failed to do ioremap\n"); - return PTR_ERR(priv->reg); - } + if (IS_ERR(priv->reg)) + return dev_err_probe(dev, PTR_ERR(priv->reg), + "failed to do ioremap\n"); #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); - if (ret) { - dev_err(dev, "failed to get gce client reg\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to get gce client reg\n"); #endif platform_set_drvdata(pdev, priv); @@ -137,10 +133,9 @@ static int mtk_padding_probe(struct platform_device *pdev) return 0; } -static int mtk_padding_remove(struct platform_device *pdev) +static void mtk_padding_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_padding_component_ops); - return 0; } static const struct of_device_id mtk_padding_driver_dt_match[] = { @@ -151,7 +146,7 @@ MODULE_DEVICE_TABLE(of, mtk_padding_driver_dt_match); struct platform_driver mtk_padding_driver = { .probe = mtk_padding_probe, - .remove = mtk_padding_remove, + .remove_new = mtk_padding_remove, .driver = { .name = "mediatek-disp-padding", .of_match_table = mtk_padding_driver_dt_match, diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c index 4625deb21d40..1723d4333f37 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_plane.c @@ -227,6 +227,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, plane->state->src_y = new_state->src_y; plane->state->src_h = new_state->src_h; plane->state->src_w = new_state->src_w; + plane->state->dst.x1 = new_state->dst.x1; + plane->state->dst.y1 = new_state->dst.y1; mtk_plane_update_new_state(new_state, new_plane_state); swap(plane->state->fb, new_state->fb); @@ -336,7 +338,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, return err; } - if (supported_rotations & ~DRM_MODE_ROTATE_0) { + if (supported_rotations) { err = drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, supported_rotations);