lkml.org 
[lkml]   [2022]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH v3 12/12] drm/mediatek: dpi: Add mt8195 hdmi to DPI driver
    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 | 143 ++++++++++++++++++++++++++++++--
    drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 5 ++
    2 files changed, 141 insertions(+), 7 deletions(-)

    diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
    index 508a6d994e83..8052b47042b8 100644
    --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
    +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
    @@ -14,7 +14,10 @@
    #include <linux/of_graph.h>
    #include <linux/pinctrl/consumer.h>
    #include <linux/platform_device.h>
    +#include <linux/reset.h>
    #include <linux/types.h>
    +#include <linux/regmap.h>
    +#include <linux/mfd/syscon.h>

    #include <video/videomode.h>

    @@ -65,10 +68,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 clk *engine_clk;
    + struct clk *dpi_ck_cg;
    struct clk *pixel_clk;
    + struct clk *dpi_sel_clk;
    struct clk *tvd_clk;
    + struct clk *hdmi_cg;
    int irq;
    struct drm_display_mode mode;
    const struct mtk_dpi_conf *conf;
    @@ -134,6 +141,7 @@ struct mtk_dpi_yc_limit {
    * @yuv422_en_bit: Enable bit of yuv422.
    * @csc_enable_bit: Enable bit of CSC.
    * @pixels_per_iter: Quantity of transferred pixels per iteration.
    + * @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);
    @@ -152,6 +160,7 @@ struct mtk_dpi_conf {
    u32 yuv422_en_bit;
    u32 csc_enable_bit;
    u32 pixels_per_iter;
    + bool is_internal_hdmi;
    };

    static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
    @@ -465,8 +474,15 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
    pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);

    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_sel_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)
    @@ -482,12 +498,44 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
    goto err_refcount;
    }

    + ret = clk_prepare_enable(dpi->dpi_sel_clk);
    + if (ret) {
    + dev_err(dpi->dev, "failed to enable dpi_sel clock: %d\n", ret);
    + 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_tvd;
    + }
    +
    + ret = clk_prepare_enable(dpi->engine_clk);
    + if (ret) {
    + dev_err(dpi->dev, "Failed to enable engine clock: %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_hdmi_cg;
    + }
    +
    + 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_ck_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);

    @@ -495,6 +543,15 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)

    err_pixel:
    clk_disable_unprepare(dpi->engine_clk);
    + clk_disable_unprepare(dpi->dpi_ck_cg);
    +err_ck_cg:
    + clk_disable_unprepare(dpi->hdmi_cg);
    +err_hdmi_cg:
    + clk_disable_unprepare(dpi->engine_clk);
    +err_engine:
    + clk_disable_unprepare(dpi->tvd_clk);
    +err_tvd:
    + clk_disable_unprepare(dpi->dpi_sel_clk);
    err_refcount:
    dpi->refcount--;
    return ret;
    @@ -538,7 +595,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",
    @@ -605,7 +661,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) {
    @@ -720,7 +785,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);
    }

    static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
    @@ -763,14 +831,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)
    @@ -853,6 +923,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)
    @@ -946,6 +1021,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,
    + .support_direct_pin = true,
    +};
    +
    static const struct mtk_dpi_conf mt8195_dpintf_conf = {
    .cal_factor = mt8195_dpintf_calculate_factor,
    .max_clock_khz = 600000,
    @@ -1003,6 +1096,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);
    @@ -1012,7 +1111,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");
    + 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");
    + 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)
    @@ -1021,7 +1139,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)
    @@ -1030,6 +1148,14 @@ static int mtk_dpi_probe(struct platform_device *pdev)
    return ret;
    }

    + dpi->dpi_sel_clk = devm_clk_get_optional(dev, "dpi_sel");
    + if (IS_ERR(dpi->dpi_sel_clk)) {
    + ret = PTR_ERR(dpi->dpi_sel_clk);
    + dev_err_probe(dev, ret, "Failed to get dpi_Sel_clk clock: %d\n", ret);
    +
    + return ret;
    + }
    +
    dpi->irq = platform_get_irq(pdev, 0);
    if (dpi->irq <= 0)
    return -EINVAL;
    @@ -1085,6 +1211,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_EN BIT(24)
    #define DPINTF_CSC_ENABLE BIT(26)
    #define DPINTF_INPUT_2P_EN BIT(29)
    +#define DPI_OUTPUT_1T1P_EN BIT(24)
    +#define DPI_INPUT_2P_EN BIT(25)
    +#define DPI_EXT_VSYNC_EN BIT(26)
    +#define DPI_RGB565_EN BIT(27)
    +#define DPI_RGB880_EN BIT(28)

    #define DPI_OUTPUT_SETTING 0x14
    #define CH_SWAP 0
    --
    b4 0.11.0-dev

    \
     
     \ /
      Last update: 2022-11-04 15:15    [W:4.149 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site