Message ID | 20190416054217.75387-4-jitao.shi@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | support mipitx on mt8183 | expand |
Hi, Jitao: On Tue, 2019-04-16 at 13:42 +0800, Jitao Shi wrote: > This patch add mt8183 mipi_tx driver. > And also support other chips that use the same binding and driver. > > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> > --- > drivers/gpu/drm/mediatek/Makefile | 1 + > drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 + > drivers/gpu/drm/mediatek/mtk_mipi_tx.h | 1 + > drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 154 ++++++++++++++++++ > 4 files changed, 158 insertions(+) > create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c > [snip] > + > +static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) > +{ > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > + unsigned int txdiv, txdiv0; > + u64 pcw; > + int ret; > + > + dev_dbg(mipi_tx->dev, "prepare: %u bps\n", mipi_tx->data_rate); > + > + if (mipi_tx->data_rate >= 2000000000) { > + txdiv = 1; > + txdiv0 = 0; > + } else if (mipi_tx->data_rate >= 1000000000) { > + txdiv = 2; > + txdiv0 = 1; > + } else if (mipi_tx->data_rate >= 500000000) { > + txdiv = 4; > + txdiv0 = 2; > + } else if (mipi_tx->data_rate > 250000000) { > + txdiv = 8; > + txdiv0 = 3; > + } else if (mipi_tx->data_rate >= 125000000) { > + txdiv = 16; > + txdiv0 = 4; > + } else { > + return -EINVAL; > + } > + > + ret = clk_prepare_enable(mipi_tx->ref_clk); > + if (ret < 0) { > + dev_err(mipi_tx->dev, > + "can't prepare and enable mipi_tx ref_clk %d\n", ret); > + return ret; > + } You enable the parent clock when prepare this clock here, this behavior looks strange. I think the flow should be: 1. Parent clock prepare 2. This clock prepare 3. Parent clock enable 4. This clock enable Maybe you should implement 'enable callback' so that parent clock would be already enabled. One question is, mipi_tx_pll is used by dsi driver, but I does not see dsi prepare_enable() mipi_tx_pll, how does this work? Regards, CK > + > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); > + > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > + usleep_range(30, 100); > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > + pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); > + writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); > + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, > + txdiv0 << 8); > + usleep_range(1000, 2000); > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > + > + return 0; > +} > + > +static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) > +{ > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > + > + dev_dbg(mipi_tx->dev, "unprepare\n"); > + > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > + > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > + clk_disable_unprepare(mipi_tx->ref_clk); > +} > +
On Mon, 2019-05-06 at 17:17 +0800, CK Hu wrote: > Hi, Jitao: > > On Tue, 2019-04-16 at 13:42 +0800, Jitao Shi wrote: > > This patch add mt8183 mipi_tx driver. > > And also support other chips that use the same binding and driver. > > > > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> > > --- > > drivers/gpu/drm/mediatek/Makefile | 1 + > > drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 + > > drivers/gpu/drm/mediatek/mtk_mipi_tx.h | 1 + > > drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 154 ++++++++++++++++++ > > 4 files changed, 158 insertions(+) > > create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c > > > > [snip] > > > + > > +static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) > > +{ > > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > > + unsigned int txdiv, txdiv0; > > + u64 pcw; > > + int ret; > > + > > + dev_dbg(mipi_tx->dev, "prepare: %u bps\n", mipi_tx->data_rate); > > + > > + if (mipi_tx->data_rate >= 2000000000) { > > + txdiv = 1; > > + txdiv0 = 0; > > + } else if (mipi_tx->data_rate >= 1000000000) { > > + txdiv = 2; > > + txdiv0 = 1; > > + } else if (mipi_tx->data_rate >= 500000000) { > > + txdiv = 4; > > + txdiv0 = 2; > > + } else if (mipi_tx->data_rate > 250000000) { > > + txdiv = 8; > > + txdiv0 = 3; > > + } else if (mipi_tx->data_rate >= 125000000) { > > + txdiv = 16; > > + txdiv0 = 4; > > + } else { > > + return -EINVAL; > > + } > > + > > + ret = clk_prepare_enable(mipi_tx->ref_clk); > > + if (ret < 0) { > > + dev_err(mipi_tx->dev, > > + "can't prepare and enable mipi_tx ref_clk %d\n", ret); > > + return ret; > > + } > > You enable the parent clock when prepare this clock here, this behavior > looks strange. I think the flow should be: > > 1. Parent clock prepare > 2. This clock prepare > 3. Parent clock enable > 4. This clock enable > > Maybe you should implement 'enable callback' so that parent clock would > be already enabled. > > One question is, mipi_tx_pll is used by dsi driver, but I does not see > dsi prepare_enable() mipi_tx_pll, how does this work? > > Regards, > CK > The mipi_tx can be accessed after clk_prepare_enable(mipi_tx->ref_clk); So place the clk_prepare_enable(mipi_tx->ref_clk) before accessing mipitx. mipi_tx_pll is enable by mtk_mipi_tx_power_on() in mtk_mip_tx.c. clk_prepare_enable(mipi_tx->pll) will enable mipi_tx_pll. Beset Regards Jitao > > + > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); > > + > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > > + usleep_range(30, 100); > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > > + pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); > > + writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); > > + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, > > + txdiv0 << 8); > > + usleep_range(1000, 2000); > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > > + > > + return 0; > > +} > > + > > +static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) > > +{ > > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > > + > > + dev_dbg(mipi_tx->dev, "unprepare\n"); > > + > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > > + > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > > + clk_disable_unprepare(mipi_tx->ref_clk); > > +} > > + > >
On Sat, 2019-05-18 at 15:51 +0800, Jitao Shi wrote: > On Mon, 2019-05-06 at 17:17 +0800, CK Hu wrote: > > Hi, Jitao: > > > > On Tue, 2019-04-16 at 13:42 +0800, Jitao Shi wrote: > > > This patch add mt8183 mipi_tx driver. > > > And also support other chips that use the same binding and driver. > > > > > > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> > > > --- > > > drivers/gpu/drm/mediatek/Makefile | 1 + > > > drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 + > > > drivers/gpu/drm/mediatek/mtk_mipi_tx.h | 1 + > > > drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 154 ++++++++++++++++++ > > > 4 files changed, 158 insertions(+) > > > create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c > > > > > > > [snip] > > > > > + > > > +static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) > > > +{ > > > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > > > + unsigned int txdiv, txdiv0; > > > + u64 pcw; > > > + int ret; > > > + > > > + dev_dbg(mipi_tx->dev, "prepare: %u bps\n", mipi_tx->data_rate); > > > + > > > + if (mipi_tx->data_rate >= 2000000000) { > > > + txdiv = 1; > > > + txdiv0 = 0; > > > + } else if (mipi_tx->data_rate >= 1000000000) { > > > + txdiv = 2; > > > + txdiv0 = 1; > > > + } else if (mipi_tx->data_rate >= 500000000) { > > > + txdiv = 4; > > > + txdiv0 = 2; > > > + } else if (mipi_tx->data_rate > 250000000) { > > > + txdiv = 8; > > > + txdiv0 = 3; > > > + } else if (mipi_tx->data_rate >= 125000000) { > > > + txdiv = 16; > > > + txdiv0 = 4; > > > + } else { > > > + return -EINVAL; > > > + } > > > + > > > + ret = clk_prepare_enable(mipi_tx->ref_clk); > > > + if (ret < 0) { > > > + dev_err(mipi_tx->dev, > > > + "can't prepare and enable mipi_tx ref_clk %d\n", ret); > > > + return ret; > > > + } > > > > You enable the parent clock when prepare this clock here, this behavior > > looks strange. I think the flow should be: > > > > 1. Parent clock prepare > > 2. This clock prepare > > 3. Parent clock enable > > 4. This clock enable > > > > Maybe you should implement 'enable callback' so that parent clock would > > be already enabled. > > > > One question is, mipi_tx_pll is used by dsi driver, but I does not see > > dsi prepare_enable() mipi_tx_pll, how does this work? > > > > Regards, > > CK > > > > The mipi_tx can be accessed after clk_prepare_enable(mipi_tx->ref_clk); > > So place the clk_prepare_enable(mipi_tx->ref_clk) before accessing > mipitx. > > mipi_tx_pll is enable by mtk_mipi_tx_power_on() in mtk_mip_tx.c. > clk_prepare_enable(mipi_tx->pll) will enable mipi_tx_pll. OK, so it start from dsi driver. The callstack is: phy_power_on(dsi->phy); -> mtk_mipi_tx_power_on() --> clk_prepare_enable(mipi_tx->pll); ---> mtk_mipi_tx_pll_prepare(); In clk_prepare_enable(), it separately call clk_prepare() and clk_enable(). When clk_prepare(), it prepare the parent clock then prepare this clock. When clk_enable(), it enable the parent clock then enable this clock. So this would result in the sequence: 1. Prepare mipi_tx->ref_clk 2. Prepare mipi_tx->pll 3. Enable mipi_tx->ref_clk 4. Enable mipi_tx->pll You say 'So place the clk_prepare_enable(mipi_tx->ref_clk) before accessing mipitx.', so the step 1 and step 3 is equal to clk_prepare_enable(mipi_tx->ref_clk), so I require you to access mipitx in step 4, not in step 2. Regards, CK > > Beset Regards > Jitao > > > > + > > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); > > > + > > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > > > + usleep_range(30, 100); > > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > > > + pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); > > > + writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); > > > + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, > > > + txdiv0 << 8); > > > + usleep_range(1000, 2000); > > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > > > + > > > + return 0; > > > +} > > > + > > > +static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) > > > +{ > > > + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); > > > + > > > + dev_dbg(mipi_tx->dev, "unprepare\n"); > > > + > > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); > > > + > > > + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); > > > + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); > > > + clk_disable_unprepare(mipi_tx->ref_clk); > > > +} > > > + > > > > > >
diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index 2c8de1f5a5ee..8067a4be8311 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -13,6 +13,7 @@ mediatek-drm-y := mtk_disp_color.o \ mtk_dsi.o \ mtk_mipi_tx.o \ mtk_mt8173_mipi_tx.o \ + mtk_mt8183_mipi_tx.o \ mtk_dpi.o obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c index d832798598a6..6acef158ac2a 100644 --- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c +++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c @@ -188,6 +188,8 @@ static const struct of_device_id mtk_mipi_tx_match[] = { .data = &mt2701_mipitx_data }, { .compatible = "mediatek,mt8173-mipi-tx", .data = &mt8173_mipitx_data }, + { .compatible = "mediatek,mt8183-mipi-tx", + .data = &mt8183_mipitx_data }, { }, }; diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.h b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h index 2d7f05b0d6a7..af83023e81cf 100644 --- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.h +++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.h @@ -47,5 +47,6 @@ unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw, extern const struct mtk_mipitx_data mt2701_mipitx_data; extern const struct mtk_mipitx_data mt8173_mipitx_data; +extern const struct mtk_mipitx_data mt8183_mipitx_data; #endif diff --git a/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c new file mode 100644 index 000000000000..a1399568b8d5 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: jitao.shi <jitao.shi@mediatek.com> + */ + +#include "mtk_mipi_tx.h" + +#define MIPITX_LANE_CON 0x000c +#define RG_DSI_CPHY_T1DRV_EN BIT(0) +#define RG_DSI_ANA_CK_SEL BIT(1) +#define RG_DSI_PHY_CK_SEL BIT(2) +#define RG_DSI_CPHY_EN BIT(3) +#define RG_DSI_PHYCK_INV_EN BIT(4) +#define RG_DSI_PWR04_EN BIT(5) +#define RG_DSI_BG_LPF_EN BIT(6) +#define RG_DSI_BG_CORE_EN BIT(7) +#define RG_DSI_PAD_TIEL_SEL BIT(8) + +#define MIPITX_PLL_PWR 0x0028 +#define MIPITX_PLL_CON0 0x002c +#define MIPITX_PLL_CON1 0x0030 +#define MIPITX_PLL_CON2 0x0034 +#define MIPITX_PLL_CON3 0x0038 +#define MIPITX_PLL_CON4 0x003c +#define RG_DSI_PLL_IBIAS (3 << 10) + +#define MIPITX_D2_SW_CTL_EN 0x0144 +#define MIPITX_D0_SW_CTL_EN 0x0244 +#define MIPITX_CK_CKMODE_EN 0x0328 +#define DSI_CK_CKMODE_EN BIT(0) +#define MIPITX_CK_SW_CTL_EN 0x0344 +#define MIPITX_D1_SW_CTL_EN 0x0444 +#define MIPITX_D3_SW_CTL_EN 0x0544 +#define DSI_SW_CTL_EN BIT(0) +#define AD_DSI_PLL_SDM_PWR_ON BIT(0) +#define AD_DSI_PLL_SDM_ISO_EN BIT(1) + +#define RG_DSI_PLL_EN BIT(4) +#define RG_DSI_PLL_POSDIV (0x7 << 8) + +static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) +{ + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); + unsigned int txdiv, txdiv0; + u64 pcw; + int ret; + + dev_dbg(mipi_tx->dev, "prepare: %u bps\n", mipi_tx->data_rate); + + if (mipi_tx->data_rate >= 2000000000) { + txdiv = 1; + txdiv0 = 0; + } else if (mipi_tx->data_rate >= 1000000000) { + txdiv = 2; + txdiv0 = 1; + } else if (mipi_tx->data_rate >= 500000000) { + txdiv = 4; + txdiv0 = 2; + } else if (mipi_tx->data_rate > 250000000) { + txdiv = 8; + txdiv0 = 3; + } else if (mipi_tx->data_rate >= 125000000) { + txdiv = 16; + txdiv0 = 4; + } else { + return -EINVAL; + } + + ret = clk_prepare_enable(mipi_tx->ref_clk); + if (ret < 0) { + dev_err(mipi_tx->dev, + "can't prepare and enable mipi_tx ref_clk %d\n", ret); + return ret; + } + + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); + + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); + usleep_range(30, 100); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); + pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); + writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, + txdiv0 << 8); + usleep_range(1000, 2000); + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); + + return 0; +} + +static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) +{ + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); + + dev_dbg(mipi_tx->dev, "unprepare\n"); + + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); + + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); + clk_disable_unprepare(mipi_tx->ref_clk); +} + +static const struct clk_ops mtk_mipi_tx_pll_ops = { + .prepare = mtk_mipi_tx_pll_prepare, + .unprepare = mtk_mipi_tx_pll_unprepare, + .round_rate = mtk_mipi_tx_pll_round_rate, + .set_rate = mtk_mipi_tx_pll_set_rate, + .recalc_rate = mtk_mipi_tx_pll_recalc_rate, +}; + +static void mtk_mipi_tx_power_on_signal(struct phy *phy) +{ + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); + + /* BG_LPF_EN / BG_CORE_EN */ + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, + mipi_tx->regs + MIPITX_LANE_CON); + usleep_range(30, 100); + writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, + mipi_tx->regs + MIPITX_LANE_CON); + + /* Switch OFF each Lane */ + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); + + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN); +} + +static void mtk_mipi_tx_power_off_signal(struct phy *phy) +{ + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); + + /* Switch ON each Lane */ + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); + + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, + mipi_tx->regs + MIPITX_LANE_CON); + writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON); +} + +const struct mtk_mipitx_data mt8183_mipitx_data = { + .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, + .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, + .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, +};
This patch add mt8183 mipi_tx driver. And also support other chips that use the same binding and driver. Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> --- drivers/gpu/drm/mediatek/Makefile | 1 + drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 + drivers/gpu/drm/mediatek/mtk_mipi_tx.h | 1 + drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c | 154 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c