Hi, Guillaume: On Mon, 2023-05-29 at 16:31 +0200, Guillaume Ranquet wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > Add the DPI1 hdmi path support in mtk dpi driver > > Signed-off-by: Guillaume Ranquet <granquet@xxxxxxxxxxxx> > --- > drivers/gpu/drm/mediatek/mtk_dpi.c | 121 > ++++++++++++++++++++++++++++++-- > drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 5 ++ > 2 files changed, 119 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index 948a53f1f4b3..b83a38e8bd60 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -9,12 +9,15 @@ > #include <linux/interrupt.h> > #include <linux/kernel.h> > #include <linux/media-bus-format.h> > +#include <linux/mfd/syscon.h> > #include <linux/of.h> > #include <linux/of_device.h> > #include <linux/of_graph.h> > #include <linux/pinctrl/consumer.h> > #include <linux/platform_device.h> > #include <linux/soc/mediatek/mtk-mmsys.h> > +#include <linux/regmap.h> > +#include <linux/reset.h> > #include <linux/types.h> > > #include <video/videomode.h> > @@ -67,11 +70,14 @@ struct mtk_dpi { > struct drm_bridge *next_bridge; > struct drm_connector *connector; > void __iomem *regs; > +struct reset_control *reset_ctl; > struct device *dev; > struct device *mmsys_dev; > struct clk *engine_clk; > +struct clk *dpi_ck_cg; > struct clk *pixel_clk; > struct clk *tvd_clk; > +struct clk *hdmi_cg; > int irq; > struct drm_display_mode mode; > const struct mtk_dpi_conf *conf; > @@ -138,6 +144,7 @@ struct mtk_dpi_yc_limit { > * @csc_enable_bit: Enable bit of CSC. > * @pixels_per_iter: Quantity of transferred pixels per iteration. > * @edge_cfg_in_mmsys: If the edge configuration for DPI's output > needs to be set in MMSYS. > + * @is_internal_hdmi: True if this DPI block is directly connected > to SoC internal HDMI block. > */ > struct mtk_dpi_conf { > unsigned int (*cal_factor)(int clock); > @@ -157,6 +164,7 @@ struct mtk_dpi_conf { > u32 csc_enable_bit; > u32 pixels_per_iter; > bool edge_cfg_in_mmsys; > +bool is_internal_hdmi; > }; > > static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, > u32 mask) > @@ -471,8 +479,14 @@ static void mtk_dpi_power_off(struct mtk_dpi > *dpi) > return; > > mtk_dpi_disable(dpi); > + > +reset_control_rearm(dpi->reset_ctl); > + > clk_disable_unprepare(dpi->pixel_clk); > clk_disable_unprepare(dpi->engine_clk); > +clk_disable_unprepare(dpi->dpi_ck_cg); > +clk_disable_unprepare(dpi->hdmi_cg); > +clk_disable_unprepare(dpi->tvd_clk); > } > > static int mtk_dpi_power_on(struct mtk_dpi *dpi) > @@ -488,15 +502,44 @@ static int mtk_dpi_power_on(struct mtk_dpi > *dpi) > goto err_refcount; > } > > +ret = clk_prepare_enable(dpi->tvd_clk); > +if (ret) { > +dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret); > +goto err_engine; > +} > + > +ret = clk_prepare_enable(dpi->hdmi_cg); > +if (ret) { > +dev_err(dpi->dev, "Failed to enable hdmi_cg clock: %d\n", ret); > +goto err_tvd; > +} > + > +ret = clk_prepare_enable(dpi->dpi_ck_cg); > +if (ret) { > +dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret); > +goto err_hdmi_cg; > +} > + > ret = clk_prepare_enable(dpi->pixel_clk); > if (ret) { > dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret); > goto err_pixel; > } > > +reset_control_reset(dpi->reset_ctl); > + > +if (dpi->pinctrl && dpi->pins_dpi) > +pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); > + > return 0; > > err_pixel: > +clk_disable_unprepare(dpi->dpi_ck_cg); > +err_hdmi_cg: > +clk_disable_unprepare(dpi->hdmi_cg); > +err_tvd: > +clk_disable_unprepare(dpi->tvd_clk); > +err_engine: > clk_disable_unprepare(dpi->engine_clk); > err_refcount: > dpi->refcount--; > @@ -541,7 +584,6 @@ static int mtk_dpi_set_display_mode(struct > mtk_dpi *dpi, > else > clk_set_rate(dpi->pixel_clk, vm.pixelclock); > > - > vm.pixelclock = clk_get_rate(dpi->pixel_clk); > > dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n", > @@ -608,7 +650,16 @@ static int mtk_dpi_set_display_mode(struct > mtk_dpi *dpi, > if (dpi->conf->support_direct_pin) { > mtk_dpi_config_yc_map(dpi, dpi->yc_map); > mtk_dpi_config_2n_h_fre(dpi); > -mtk_dpi_dual_edge(dpi); > +/* DPI could be connecting to external bridge > + * or internal HDMI encoder. */ > +if (dpi->conf->is_internal_hdmi) { > +mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, > + DPI_OUTPUT_1T1P_EN); > +mtk_dpi_mask(dpi, DPI_CON, DPI_INPUT_2P_EN, > + DPI_INPUT_2P_EN); > +} else { > +mtk_dpi_dual_edge(dpi); > +} > mtk_dpi_config_disable_edge(dpi); > } > if (dpi->conf->input_2pixel) { > @@ -723,7 +774,10 @@ static void mtk_dpi_bridge_disable(struct > drm_bridge *bridge) > { > struct mtk_dpi *dpi = bridge_to_dpi(bridge); > > -mtk_dpi_power_off(dpi); > +if (dpi->conf->is_internal_hdmi) > +mtk_dpi_power_off(dpi); > +else > +mtk_dpi_disable(dpi); > > if (dpi->pinctrl && dpi->pins_gpio) > pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); > @@ -772,14 +826,16 @@ void mtk_dpi_start(struct device *dev) > { > struct mtk_dpi *dpi = dev_get_drvdata(dev); > > -mtk_dpi_power_on(dpi); > +if (!dpi->conf->is_internal_hdmi) > +mtk_dpi_power_on(dpi); > } > > void mtk_dpi_stop(struct device *dev) > { > struct mtk_dpi *dpi = dev_get_drvdata(dev); > > -mtk_dpi_power_off(dpi); > +if (!dpi->conf->is_internal_hdmi) > +mtk_dpi_power_off(dpi); > } > > static int mtk_dpi_bind(struct device *dev, struct device *master, > void *data) > @@ -864,6 +920,11 @@ static unsigned int mt8183_calculate_factor(int > clock) > return 2; > } > > +static unsigned int mt8195_calculate_factor(int clock) > +{ > +return 1; > +} > + > static unsigned int mt8195_dpintf_calculate_factor(int clock) > { > if (clock < 70000) > @@ -989,6 +1050,24 @@ static const struct mtk_dpi_conf mt8192_conf = > { > .csc_enable_bit = CSC_ENABLE, > }; > > +static const struct mtk_dpi_conf mt8195_conf = { > +.cal_factor = mt8195_calculate_factor, > +.max_clock_khz = 594000, > +.reg_h_fre_con = 0xe0, > +.output_fmts = mt8183_output_fmts, > +.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), > +.pixels_per_iter = 1, > +.is_ck_de_pol = true, > +.swap_input_support = true, > +.dimension_mask = HPW_MASK, > +.hvsize_mask = HSIZE_MASK, > +.channel_swap_shift = CH_SWAP, > +.yuv422_en_bit = YUV422_EN, > +.csc_enable_bit = CSC_ENABLE, > +.is_internal_hdmi = true, mt8173 dpi is also connect to internal mt8173 hdmi. > +.support_direct_pin = true, > +}; > + > static const struct mtk_dpi_conf mt8195_dpintf_conf = { > .cal_factor = mt8195_dpintf_calculate_factor, > .max_clock_khz = 600000, > @@ -1046,6 +1125,12 @@ static int mtk_dpi_probe(struct > platform_device *pdev) > return ret; > } > > +dpi->reset_ctl = devm_reset_control_get_optional_exclusive(dev, > "dpi_on"); > +if (IS_ERR(dpi->reset_ctl)) { > +dev_err(dev, "Failed to get reset_ctl: %ld\n", PTR_ERR(dpi- > >reset_ctl)); > +return PTR_ERR(dpi->reset_ctl); > +} > + > dpi->engine_clk = devm_clk_get(dev, "engine"); > if (IS_ERR(dpi->engine_clk)) { > ret = PTR_ERR(dpi->engine_clk); > @@ -1055,7 +1140,26 @@ static int mtk_dpi_probe(struct > platform_device *pdev) > return ret; > } > > -dpi->pixel_clk = devm_clk_get(dev, "pixel"); > +dpi->hdmi_cg = devm_clk_get_optional(dev, "hdmi_cg"); This clock is not defined in binding document. > +if (IS_ERR(dpi->hdmi_cg)) { > +ret = PTR_ERR(dpi->hdmi_cg); > +if (ret != -EPROBE_DEFER) > +dev_err(dev, "Failed to get hdmi_cg clock: %d\n", ret); > + > +return ret; > +} > + > +dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg"); This clock is not defined in binding document. Regards, CK > +if (IS_ERR(dpi->dpi_ck_cg)) { > +ret = PTR_ERR(dpi->dpi_ck_cg); > +if (ret != -EPROBE_DEFER) > +dev_err(dev, "Failed to get dpi ck cg clock: %d\n", > +ret); > + > +return ret; > +} > + > +dpi->pixel_clk = devm_clk_get_optional(dev, "pixel"); > if (IS_ERR(dpi->pixel_clk)) { > ret = PTR_ERR(dpi->pixel_clk); > if (ret != -EPROBE_DEFER) > @@ -1064,7 +1168,7 @@ static int mtk_dpi_probe(struct platform_device > *pdev) > return ret; > } > > -dpi->tvd_clk = devm_clk_get(dev, "pll"); > +dpi->tvd_clk = devm_clk_get_optional(dev, "pll"); > if (IS_ERR(dpi->tvd_clk)) { > ret = PTR_ERR(dpi->tvd_clk); > if (ret != -EPROBE_DEFER) > @@ -1134,6 +1238,9 @@ static const struct of_device_id > mtk_dpi_of_ids[] = { > { .compatible = "mediatek,mt8195-dp-intf", > .data = &mt8195_dpintf_conf, > }, > +{ .compatible = "mediatek,mt8195-dpi", > + .data = &mt8195_conf, > +}, > { }, > }; > MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids); > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h > b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h > index 62bd4931b344..653ef4b93a97 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h > +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h > @@ -43,6 +43,11 @@ > #define DPINTF_YUV422_ENBIT(24) > #define DPINTF_CSC_ENABLEBIT(26) > #define DPINTF_INPUT_2P_ENBIT(29) > +#define DPI_OUTPUT_1T1P_ENBIT(24) > +#define DPI_INPUT_2P_ENBIT(25) > +#define DPI_EXT_VSYNC_ENBIT(26) > +#define DPI_RGB565_ENBIT(27) > +#define DPI_RGB880_ENBIT(28) > > #define DPI_OUTPUT_SETTING0x14 > #define CH_SWAP0 > > -- > 2.40.0 > >