Commit 611d4d16 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'mediatek-drm-next-20251120' of...

Merge tag 'mediatek-drm-next-20251120' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux

 into drm-next

Mediatek DRM Next - 20251120

1. Fix probe resource leaks
2. Add support for MT8195/88 HDMIv2 and DDCv2
3. Fix CCORR mtk_ctm_s31_32_to_s1_n function issue
4. Fix device node reference leak in mtk_dp_dt_parse()

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Link: https://patch.msgid.link/20251119233202.10034-1-chunkuang.hu@kernel.org
parents ee316213 a846505a
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -30,9 +30,30 @@ config DRM_MEDIATEK_DP
	help
	  DRM/KMS Display Port driver for MediaTek SoCs.

config DRM_MEDIATEK_HDMI_COMMON
	tristate
	depends on DRM_MEDIATEK
	select DRM_DISPLAY_HDMI_HELPER
	select DRM_DISPLAY_HELPER
	select SND_SOC_HDMI_CODEC if SND_SOC
	help
	  MediaTek SoC HDMI common library

config DRM_MEDIATEK_HDMI
	tristate "DRM HDMI Support for Mediatek SoCs"
	depends on DRM_MEDIATEK
	select SND_SOC_HDMI_CODEC if SND_SOC
	select DRM_MEDIATEK_HDMI_COMMON
	help
	  DRM/KMS HDMI driver for Mediatek SoCs

config DRM_MEDIATEK_HDMI_V2
	tristate "DRM HDMI v2 IP support for MediaTek SoCs"
	depends on DRM_MEDIATEK
	select DRM_MEDIATEK_HDMI_COMMON
	help
	  Say yes here to enable support for the HDMIv2 IP and related
	  DDCv2 as found in the MediaTek MT8195, MT8188 SoCs and other
	  variants.
	  This driver can also be built as a module. If so, the HDMIv2
	  module will be called "mtk_hdmi_v2", and the DDCv2 module
	  will be called "mtk_hdmi_ddc_v2".
+3 −0
Original line number Diff line number Diff line
@@ -21,8 +21,11 @@ mediatek-drm-y := mtk_crtc.o \

obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o

obj-$(CONFIG_DRM_MEDIATEK_HDMI_COMMON) += mtk_hdmi_common.o
obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_cec.o
obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_hdmi.o
obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_hdmi_ddc.o
obj-$(CONFIG_DRM_MEDIATEK_HDMI_V2) += mtk_hdmi_v2.o
obj-$(CONFIG_DRM_MEDIATEK_HDMI_V2) += mtk_hdmi_ddc_v2.o

obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
+28 −5
Original line number Diff line number Diff line
@@ -621,15 +621,27 @@ int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev)
	return ret;
}

int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
static void mtk_ddp_comp_put_device(void *_dev)
{
	struct device *dev = _dev;

	put_device(dev);
}

static void mtk_ddp_comp_clk_put(void *_clk)
{
	struct clk *clk = _clk;

	clk_put(clk);
}

int mtk_ddp_comp_init(struct device *dev, struct device_node *node, struct mtk_ddp_comp *comp,
		      unsigned int comp_id)
{
	struct platform_device *comp_pdev;
	enum mtk_ddp_comp_type type;
	struct mtk_ddp_comp_dev *priv;
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
	int ret;
#endif

	if (comp_id >= DDP_COMPONENT_DRM_ID_MAX)
		return -EINVAL;
@@ -651,6 +663,10 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
	}
	comp->dev = &comp_pdev->dev;

	ret = devm_add_action_or_reset(dev, mtk_ddp_comp_put_device, comp->dev);
	if (ret)
		return ret;

	if (type == MTK_DISP_AAL ||
	    type == MTK_DISP_BLS ||
	    type == MTK_DISP_CCORR ||
@@ -666,15 +682,22 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
	    type == MTK_DSI)
		return 0;

	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->regs = of_iomap(node, 0);
	priv->regs = devm_of_iomap(dev, node, 0, NULL);
	if (IS_ERR(priv->regs))
		return PTR_ERR(priv->regs);

	priv->clk = of_clk_get(node, 0);
	if (IS_ERR(priv->clk))
		return PTR_ERR(priv->clk);

	ret = devm_add_action_or_reset(dev, mtk_ddp_comp_clk_put, priv->clk);
	if (ret)
		return ret;

#if IS_REACHABLE(CONFIG_MTK_CMDQ)
	ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0);
	if (ret)
+1 −1
Original line number Diff line number Diff line
@@ -350,7 +350,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);
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,
int mtk_ddp_comp_init(struct device *dev, 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);
void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
+1 −22
Original line number Diff line number Diff line
@@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev)
	writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN);
}

/* Converts a DRM S31.32 value to the HW S1.n format. */
static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n)
{
	u16 r;

	/* Sign bit. */
	r = in & BIT_ULL(63) ? BIT(n + 1) : 0;

	if ((in & GENMASK_ULL(62, 33)) > 0) {
		/* identity value 0x100000000 -> 0x400(mt8183), */
		/* identity value 0x100000000 -> 0x800(mt8192), */
		/* if bigger this, set it to max 0x7ff. */
		r |= GENMASK(n, 0);
	} else {
		/* take the n+1 most important bits. */
		r |= (in >> (32 - n)) & GENMASK(n, 0);
	}

	return r;
}

void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
@@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
	input = ctm->matrix;

	for (i = 0; i < ARRAY_SIZE(coeffs); i++)
		coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits);
		coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits);

	mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0);
Loading