<pre>
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@baylibre.com>
> ---
> 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
>
>
</pre><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice ********************
The information contained in this e-mail message (including any
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be
conveyed only to the designated recipient(s). Any use, dissemination,
distribution, printing, retaining or copying of this e-mail (including its
attachments) by unintended recipient(s) is strictly prohibited and may
be unlawful. If you are not an intended recipient of this e-mail, or believe
that you have received this e-mail in error, please notify the sender
immediately (by replying to this e-mail), delete any and all copies of
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
</pre><!--}-->