Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66c9e573 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'mediatek-drm-next-4.20' of...

Merge branch 'mediatek-drm-next-4.20' of https://github.com/ckhu-mediatek/linux.git-tags

 into drm-next

This include hdmi output support for mt2701 and mt7623.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1538616148.28906.1.camel@mtksdaap41
parents 7e6191d4 84dacb9c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

mediatek-drm-y := mtk_disp_color.o \
		  mtk_disp_ovl.o \
		  mtk_disp_rdma.o \
@@ -18,6 +19,8 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
mediatek-drm-hdmi-objs := mtk_cec.o \
			  mtk_hdmi.o \
			  mtk_hdmi_ddc.o \
			  mtk_mt8173_hdmi_phy.o
                          mtk_mt2701_hdmi_phy.o \
			  mtk_mt8173_hdmi_phy.o \
			  mtk_hdmi_phy.o

obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+79 −52
Original line number Diff line number Diff line
@@ -14,10 +14,12 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_of.h>
#include <linux/kernel.h>
#include <linux/component.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/interrupt.h>
#include <linux/types.h>
@@ -72,12 +74,12 @@ struct mtk_dpi {
	struct clk *tvd_clk;
	int irq;
	struct drm_display_mode mode;
	const struct mtk_dpi_conf *conf;
	enum mtk_dpi_out_color_format color_format;
	enum mtk_dpi_out_yc_map yc_map;
	enum mtk_dpi_out_bit_num bit_num;
	enum mtk_dpi_out_channel_swap channel_swap;
	bool power_sta;
	u8 power_ctl;
	int refcount;
};

static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e)
@@ -90,11 +92,6 @@ enum mtk_dpi_polarity {
	MTK_DPI_POLARITY_FALLING,
};

enum mtk_dpi_power_ctl {
	DPI_POWER_START = BIT(0),
	DPI_POWER_ENABLE = BIT(1),
};

struct mtk_dpi_polarities {
	enum mtk_dpi_polarity de_pol;
	enum mtk_dpi_polarity ck_pol;
@@ -116,6 +113,12 @@ struct mtk_dpi_yc_limit {
	u16 c_bottom;
};

struct mtk_dpi_conf {
	unsigned int (*cal_factor)(int clock);
	u32 reg_h_fre_con;
	bool edge_sel_en;
};

static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
{
	u32 tmp = readl(dpi->regs + offset) & ~mask;
@@ -341,7 +344,13 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)

static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
{
	mtk_dpi_mask(dpi, DPI_H_FRE_CON, H_FRE_2N, H_FRE_2N);
	mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
}

static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
{
	if (dpi->conf->edge_sel_en)
		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
}

static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
@@ -367,40 +376,30 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
	}
}

static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl)
static void mtk_dpi_power_off(struct mtk_dpi *dpi)
{
	dpi->power_ctl &= ~pctl;

	if ((dpi->power_ctl & DPI_POWER_START) ||
	    (dpi->power_ctl & DPI_POWER_ENABLE))
	if (WARN_ON(dpi->refcount == 0))
		return;

	if (!dpi->power_sta)
	if (--dpi->refcount != 0)
		return;

	mtk_dpi_disable(dpi);
	clk_disable_unprepare(dpi->pixel_clk);
	clk_disable_unprepare(dpi->engine_clk);
	dpi->power_sta = false;
}

static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl)
static int mtk_dpi_power_on(struct mtk_dpi *dpi)
{
	int ret;

	dpi->power_ctl |= pctl;

	if (!(dpi->power_ctl & DPI_POWER_START) &&
	    !(dpi->power_ctl & DPI_POWER_ENABLE))
		return 0;

	if (dpi->power_sta)
	if (++dpi->refcount != 1)
		return 0;

	ret = clk_prepare_enable(dpi->engine_clk);
	if (ret) {
		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
		goto err_eng;
		goto err_refcount;
	}

	ret = clk_prepare_enable(dpi->pixel_clk);
@@ -410,13 +409,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl)
	}

	mtk_dpi_enable(dpi);
	dpi->power_sta = true;
	return 0;

err_pixel:
	clk_disable_unprepare(dpi->engine_clk);
err_eng:
	dpi->power_ctl &= ~pctl;
err_refcount:
	dpi->refcount--;
	return ret;
}

@@ -435,15 +433,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
	unsigned int factor;

	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */

	if (mode->clock <= 27000)
		factor = 3 << 4;
	else if (mode->clock <= 84000)
		factor = 3 << 3;
	else if (mode->clock <= 167000)
		factor = 3 << 2;
	else
		factor = 3 << 1;
	factor = dpi->conf->cal_factor(mode->clock);
	drm_display_mode_to_videomode(mode, &vm);
	pll_rate = vm.pixelclock * factor;

@@ -518,6 +508,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
	mtk_dpi_config_color_format(dpi, dpi->color_format);
	mtk_dpi_config_2n_h_fre(dpi);
	mtk_dpi_config_disable_edge(dpi);
	mtk_dpi_sw_reset(dpi, false);

	return 0;
@@ -552,14 +543,14 @@ static void mtk_dpi_encoder_disable(struct drm_encoder *encoder)
{
	struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);

	mtk_dpi_power_off(dpi, DPI_POWER_ENABLE);
	mtk_dpi_power_off(dpi);
}

static void mtk_dpi_encoder_enable(struct drm_encoder *encoder)
{
	struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);

	mtk_dpi_power_on(dpi, DPI_POWER_ENABLE);
	mtk_dpi_power_on(dpi);
	mtk_dpi_set_display_mode(dpi, &dpi->mode);
}

@@ -582,14 +573,14 @@ static void mtk_dpi_start(struct mtk_ddp_comp *comp)
{
	struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);

	mtk_dpi_power_on(dpi, DPI_POWER_START);
	mtk_dpi_power_on(dpi);
}

static void mtk_dpi_stop(struct mtk_ddp_comp *comp)
{
	struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);

	mtk_dpi_power_off(dpi, DPI_POWER_START);
	mtk_dpi_power_off(dpi);
}

static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = {
@@ -656,12 +647,46 @@ static const struct component_ops mtk_dpi_component_ops = {
	.unbind = mtk_dpi_unbind,
};

static unsigned int mt8173_calculate_factor(int clock)
{
	if (clock <= 27000)
		return 3 << 4;
	else if (clock <= 84000)
		return 3 << 3;
	else if (clock <= 167000)
		return 3 << 2;
	else
		return 3 << 1;
}

static unsigned int mt2701_calculate_factor(int clock)
{
	if (clock <= 64000)
		return 16;
	else if (clock <= 128000)
		return 8;
	else if (clock <= 256000)
		return 4;
	else
		return 2;
}

static const struct mtk_dpi_conf mt8173_conf = {
	.cal_factor = mt8173_calculate_factor,
	.reg_h_fre_con = 0xe0,
};

static const struct mtk_dpi_conf mt2701_conf = {
	.cal_factor = mt2701_calculate_factor,
	.reg_h_fre_con = 0xb0,
	.edge_sel_en = true,
};

static int mtk_dpi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mtk_dpi *dpi;
	struct resource *mem;
	struct device_node *bridge_node;
	int comp_id;
	int ret;

@@ -670,6 +695,7 @@ static int mtk_dpi_probe(struct platform_device *pdev)
		return -ENOMEM;

	dpi->dev = dev;
	dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dpi->regs = devm_ioremap_resource(dev, mem);
@@ -706,16 +732,12 @@ static int mtk_dpi_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	bridge_node = of_graph_get_remote_node(dev->of_node, 0, 0);
	if (!bridge_node)
		return -ENODEV;

	dev_info(dev, "Found bridge node: %pOF\n", bridge_node);
	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
					  NULL, &dpi->bridge);
	if (ret)
		return ret;

	dpi->bridge = of_drm_find_bridge(bridge_node);
	of_node_put(bridge_node);
	if (!dpi->bridge)
		return -EPROBE_DEFER;
	dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node);

	comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
	if (comp_id < 0) {
@@ -749,8 +771,13 @@ static int mtk_dpi_remove(struct platform_device *pdev)
}

static const struct of_device_id mtk_dpi_of_ids[] = {
	{ .compatible = "mediatek,mt8173-dpi", },
	{}
	{ .compatible = "mediatek,mt2701-dpi",
	  .data = &mt2701_conf,
	},
	{ .compatible = "mediatek,mt8173-dpi",
	  .data = &mt8173_conf,
	},
	{ },
};

struct platform_driver mtk_dpi_driver = {
+1 −1
Original line number Diff line number Diff line
@@ -223,6 +223,6 @@
#define ESAV_CODE2			(0xFFF << 0)
#define ESAV_CODE3_MSB			BIT(16)

#define DPI_H_FRE_CON		0xE0
#define EDGE_SEL_EN			BIT(5)
#define H_FRE_2N			BIT(25)
#endif /* __MTK_DPI_REGS_H */
+13 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN	0x030
#define DISP_REG_CONFIG_OUT_SEL			0x04c
#define DISP_REG_CONFIG_DSI_SEL			0x050
#define DISP_REG_CONFIG_DPI_SEL			0x064

#define DISP_REG_MUTEX_EN(n)	(0x20 + 0x20 * (n))
#define DISP_REG_MUTEX(n)	(0x24 + 0x20 * (n))
@@ -136,7 +137,10 @@

#define OVL_MOUT_EN_RDMA		0x1
#define BLS_TO_DSI_RDMA1_TO_DPI1	0x8
#define BLS_TO_DPI_RDMA1_TO_DSI		0x2
#define DSI_SEL_IN_BLS			0x0
#define DPI_SEL_IN_BLS			0x0
#define DSI_SEL_IN_RDMA			0x1

struct mtk_disp_mutex {
	int id;
@@ -339,9 +343,17 @@ static void mtk_ddp_sout_sel(void __iomem *config_regs,
			     enum mtk_ddp_comp_id cur,
			     enum mtk_ddp_comp_id next)
{
	if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
	if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
		writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
			       config_regs + DISP_REG_CONFIG_OUT_SEL);
	} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
		writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
			       config_regs + DISP_REG_CONFIG_OUT_SEL);
		writel_relaxed(DSI_SEL_IN_RDMA,
			       config_regs + DISP_REG_CONFIG_DSI_SEL);
		writel_relaxed(DPI_SEL_IN_BLS,
			       config_regs + DISP_REG_CONFIG_DPI_SEL);
	}
}

void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
+1 −1
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
	comp->irq = of_irq_get(node, 0);
	comp->clk = of_clk_get(node, 0);
	if (IS_ERR(comp->clk))
		comp->clk = NULL;
		return PTR_ERR(comp->clk);

	/* Only DMA capable components need the LARB property */
	comp->larb_dev = NULL;
Loading