Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/phy/mediatek/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 8 kB image not shown  

Quelle  phy-mtk-mipi-dsi-mt8173.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2019 MediaTek Inc.
 * Author: jitao.shi <jitao.shi@mediatek.com>
 */


#include "phy-mtk-io.h"
#include "phy-mtk-mipi-dsi.h"

#define MIPITX_DSI_CON  0x00
#define RG_DSI_LDOCORE_EN  BIT(0)
#define RG_DSI_CKG_LDOOUT_EN  BIT(1)
#define RG_DSI_BCLK_SEL   GENMASK(3, 2)
#define RG_DSI_LD_IDX_SEL  GENMASK(6, 4)
#define RG_DSI_PHYCLK_SEL  GENMASK(9, 8)
#define RG_DSI_DSICLK_FREQ_SEL  BIT(10)
#define RG_DSI_LPTX_CLMP_EN  BIT(11)

#define MIPITX_DSI_CLOCK_LANE 0x04
#define MIPITX_DSI_DATA_LANE0 0x08
#define MIPITX_DSI_DATA_LANE1 0x0c
#define MIPITX_DSI_DATA_LANE2 0x10
#define MIPITX_DSI_DATA_LANE3 0x14
#define RG_DSI_LNTx_LDOOUT_EN  BIT(0)
#define RG_DSI_LNTx_CKLANE_EN  BIT(1)
#define RG_DSI_LNTx_LPTX_IPLUS1  BIT(2)
#define RG_DSI_LNTx_LPTX_IPLUS2  BIT(3)
#define RG_DSI_LNTx_LPTX_IMINUS  BIT(4)
#define RG_DSI_LNTx_LPCD_IPLUS  BIT(5)
#define RG_DSI_LNTx_LPCD_IMINUS  BIT(6)
#define RG_DSI_LNTx_RT_CODE  GENMASK(11, 8)

#define MIPITX_DSI_TOP_CON 0x40
#define RG_DSI_LNT_INTR_EN  BIT(0)
#define RG_DSI_LNT_HS_BIAS_EN  BIT(1)
#define RG_DSI_LNT_IMP_CAL_EN  BIT(2)
#define RG_DSI_LNT_TESTMODE_EN  BIT(3)
#define RG_DSI_LNT_IMP_CAL_CODE  GENMASK(7, 4)
#define RG_DSI_LNT_AIO_SEL  GENMASK(10, 8)
#define RG_DSI_PAD_TIE_LOW_EN  BIT(11)
#define RG_DSI_DEBUG_INPUT_EN  BIT(12)
#define RG_DSI_PRESERVE   GENMASK(15, 13)

#define MIPITX_DSI_BG_CON 0x44
#define RG_DSI_BG_CORE_EN  BIT(0)
#define RG_DSI_BG_CKEN   BIT(1)
#define RG_DSI_BG_DIV   GENMASK(3, 2)
#define RG_DSI_BG_FAST_CHARGE  BIT(4)

#define RG_DSI_V12_SEL   GENMASK(7, 5)
#define RG_DSI_V10_SEL   GENMASK(10, 8)
#define RG_DSI_V072_SEL   GENMASK(13, 11)
#define RG_DSI_V04_SEL   GENMASK(16, 14)
#define RG_DSI_V032_SEL   GENMASK(19, 17)
#define RG_DSI_V02_SEL   GENMASK(22, 20)
#define RG_DSI_VOUT_MSK   \
  (RG_DSI_V12_SEL | RG_DSI_V10_SEL | RG_DSI_V072_SEL | \
   RG_DSI_V04_SEL | RG_DSI_V032_SEL | RG_DSI_V02_SEL)
#define RG_DSI_BG_R1_TRIM  GENMASK(27, 24)
#define RG_DSI_BG_R2_TRIM  GENMASK(31, 28)

#define MIPITX_DSI_PLL_CON0 0x50
#define RG_DSI_MPPLL_PLL_EN  BIT(0)
#define RG_DSI_MPPLL_PREDIV  GENMASK(2, 1)
#define RG_DSI_MPPLL_TXDIV0  GENMASK(4, 3)
#define RG_DSI_MPPLL_TXDIV1  GENMASK(6, 5)
#define RG_DSI_MPPLL_POSDIV  GENMASK(9, 7)
#define RG_DSI_MPPLL_DIV_MSK  \
  (RG_DSI_MPPLL_PREDIV | RG_DSI_MPPLL_TXDIV0 | \
   RG_DSI_MPPLL_TXDIV1 | RG_DSI_MPPLL_POSDIV)
#define RG_DSI_MPPLL_MONVC_EN  BIT(10)
#define RG_DSI_MPPLL_MONREF_EN  BIT(11)
#define RG_DSI_MPPLL_VOD_EN  BIT(12)

#define MIPITX_DSI_PLL_CON1 0x54
#define RG_DSI_MPPLL_SDM_FRA_EN  BIT(0)
#define RG_DSI_MPPLL_SDM_SSC_PH_INIT BIT(1)
#define RG_DSI_MPPLL_SDM_SSC_EN  BIT(2)
#define RG_DSI_MPPLL_SDM_SSC_PRD GENMASK(31, 16)

#define MIPITX_DSI_PLL_CON2 0x58

#define MIPITX_DSI_PLL_TOP 0x64
#define RG_DSI_MPPLL_PRESERVE  GENMASK(15, 8)

#define MIPITX_DSI_PLL_PWR 0x68
#define RG_DSI_MPPLL_SDM_PWR_ON  BIT(0)
#define RG_DSI_MPPLL_SDM_ISO_EN  BIT(1)
#define RG_DSI_MPPLL_SDM_PWR_ACK BIT(8)

#define MIPITX_DSI_SW_CTRL 0x80
#define SW_CTRL_EN   BIT(0)

#define MIPITX_DSI_SW_CTRL_CON0 0x84
#define SW_LNTC_LPTX_PRE_OE  BIT(0)
#define SW_LNTC_LPTX_OE   BIT(1)
#define SW_LNTC_LPTX_P   BIT(2)
#define SW_LNTC_LPTX_N   BIT(3)
#define SW_LNTC_HSTX_PRE_OE  BIT(4)
#define SW_LNTC_HSTX_OE   BIT(5)
#define SW_LNTC_HSTX_ZEROCLK  BIT(6)
#define SW_LNT0_LPTX_PRE_OE  BIT(7)
#define SW_LNT0_LPTX_OE   BIT(8)
#define SW_LNT0_LPTX_P   BIT(9)
#define SW_LNT0_LPTX_N   BIT(10)
#define SW_LNT0_HSTX_PRE_OE  BIT(11)
#define SW_LNT0_HSTX_OE   BIT(12)
#define SW_LNT0_LPRX_EN   BIT(13)
#define SW_LNT1_LPTX_PRE_OE  BIT(14)
#define SW_LNT1_LPTX_OE   BIT(15)
#define SW_LNT1_LPTX_P   BIT(16)
#define SW_LNT1_LPTX_N   BIT(17)
#define SW_LNT1_HSTX_PRE_OE  BIT(18)
#define SW_LNT1_HSTX_OE   BIT(19)
#define SW_LNT2_LPTX_PRE_OE  BIT(20)
#define SW_LNT2_LPTX_OE   BIT(21)
#define SW_LNT2_LPTX_P   BIT(22)
#define SW_LNT2_LPTX_N   BIT(23)
#define SW_LNT2_HSTX_PRE_OE  BIT(24)
#define SW_LNT2_HSTX_OE   BIT(25)

static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
{
 struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
 void __iomem *base = mipi_tx->regs;
 u8 txdiv, txdiv0, txdiv1;
 u64 pcw;

 dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);

 if (mipi_tx->data_rate >= 500000000) {
  txdiv = 1;
  txdiv0 = 0;
  txdiv1 = 0;
 } else if (mipi_tx->data_rate >= 250000000) {
  txdiv = 2;
  txdiv0 = 1;
  txdiv1 = 0;
 } else if (mipi_tx->data_rate >= 125000000) {
  txdiv = 4;
  txdiv0 = 2;
  txdiv1 = 0;
 } else if (mipi_tx->data_rate > 62000000) {
  txdiv = 8;
  txdiv0 = 2;
  txdiv1 = 1;
 } else if (mipi_tx->data_rate >= 50000000) {
  txdiv = 16;
  txdiv0 = 2;
  txdiv1 = 2;
 } else {
  return -EINVAL;
 }

 mtk_phy_update_bits(base + MIPITX_DSI_BG_CON,
       RG_DSI_VOUT_MSK | RG_DSI_BG_CKEN |
       RG_DSI_BG_CORE_EN,
       FIELD_PREP(RG_DSI_V02_SEL, 4) |
       FIELD_PREP(RG_DSI_V032_SEL, 4) |
       FIELD_PREP(RG_DSI_V04_SEL, 4) |
       FIELD_PREP(RG_DSI_V072_SEL, 4) |
       FIELD_PREP(RG_DSI_V10_SEL, 4) |
       FIELD_PREP(RG_DSI_V12_SEL, 4) |
       RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);

 usleep_range(30, 100);

 mtk_phy_update_bits(base + MIPITX_DSI_TOP_CON,
       RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN,
       FIELD_PREP(RG_DSI_LNT_IMP_CAL_CODE, 8) |
       RG_DSI_LNT_HS_BIAS_EN);

 mtk_phy_set_bits(base + MIPITX_DSI_CON,
    RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);

 mtk_phy_update_bits(base + MIPITX_DSI_PLL_PWR,
       RG_DSI_MPPLL_SDM_PWR_ON | RG_DSI_MPPLL_SDM_ISO_EN,
       RG_DSI_MPPLL_SDM_PWR_ON);

 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);

 mtk_phy_update_bits(base + MIPITX_DSI_PLL_CON0,
       RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 |
       RG_DSI_MPPLL_PREDIV,
       FIELD_PREP(RG_DSI_MPPLL_TXDIV0, txdiv0) |
       FIELD_PREP(RG_DSI_MPPLL_TXDIV1, txdiv1));

 /*
 * PLL PCW config
 * PCW bit 24~30 = integer part of pcw
 * PCW bit 0~23 = fractional part of pcw
 * pcw = data_Rate*4*txdiv/(Ref_clk*2);
 * Post DIV =4, so need data_Rate*4
 * Ref_clk is 26MHz
 */

 pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24, 26000000);
 writel(pcw, base + MIPITX_DSI_PLL_CON2);

 mtk_phy_set_bits(base + MIPITX_DSI_PLL_CON1, RG_DSI_MPPLL_SDM_FRA_EN);

 mtk_phy_set_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);

 usleep_range(20, 100);

 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON1, RG_DSI_MPPLL_SDM_SSC_EN);

 mtk_phy_update_field(base + MIPITX_DSI_PLL_TOP,
        RG_DSI_MPPLL_PRESERVE,
        mipi_tx->driver_data->mppll_preserve);

 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);
 void __iomem *base = mipi_tx->regs;

 dev_dbg(mipi_tx->dev, "unprepare\n");

 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);

 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_TOP, RG_DSI_MPPLL_PRESERVE);

 mtk_phy_update_bits(base + MIPITX_DSI_PLL_PWR,
       RG_DSI_MPPLL_SDM_ISO_EN | RG_DSI_MPPLL_SDM_PWR_ON,
       RG_DSI_MPPLL_SDM_ISO_EN);

 mtk_phy_clear_bits(base + MIPITX_DSI_TOP_CON, RG_DSI_LNT_HS_BIAS_EN);

 mtk_phy_clear_bits(base + MIPITX_DSI_CON,
      RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);

 mtk_phy_clear_bits(base + MIPITX_DSI_BG_CON,
      RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);

 mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK);
}

static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
           unsigned long *prate)
{
 return clamp_val(rate, 50000000, 1250000000);
}

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);
 u32 reg;

 for (reg = MIPITX_DSI_CLOCK_LANE;
      reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
  mtk_phy_set_bits(mipi_tx->regs + reg, RG_DSI_LNTx_LDOOUT_EN);

 mtk_phy_clear_bits(mipi_tx->regs + MIPITX_DSI_TOP_CON,
      RG_DSI_PAD_TIE_LOW_EN);
}

static void mtk_mipi_tx_power_off_signal(struct phy *phy)
{
 struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
 u32 reg;

 mtk_phy_set_bits(mipi_tx->regs + MIPITX_DSI_TOP_CON,
    RG_DSI_PAD_TIE_LOW_EN);

 for (reg = MIPITX_DSI_CLOCK_LANE;
      reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
  mtk_phy_clear_bits(mipi_tx->regs + reg, RG_DSI_LNTx_LDOOUT_EN);
}

const struct mtk_mipitx_data mt2701_mipitx_data = {
 .mppll_preserve = 3,
 .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,
};

const struct mtk_mipitx_data mt8173_mipitx_data = {
 .mppll_preserve = 0,
 .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,
};

Messung V0.5
C=96 H=96 G=95

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.