soc/mediatek: dsi: Refactor MIPI TX configuration
[coreboot.git] / src / soc / mediatek / mt8173 / dsi.c
blob2e4a4bd58a85e59f031bce82088a3d8f896583f0
1 /*
2 * This file is part of the coreboot project.
4 * Copyright 2015 MediaTek Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <assert.h>
17 #include <device/mmio.h>
18 #include <console/console.h>
19 #include <delay.h>
20 #include <soc/dsi.h>
21 #include <timer.h>
23 void mtk_dsi_configure_mipi_tx(int data_rate, u32 lanes)
25 u32 txdiv0, txdiv1;
26 u64 pcw;
27 u32 reg;
28 int i;
30 reg = read32(&mipi_tx0->dsi_bg_con);
32 reg = (reg & (~RG_DSI_V02_SEL)) | (4 << 20);
33 reg = (reg & (~RG_DSI_V032_SEL)) | (4 << 17);
34 reg = (reg & (~RG_DSI_V04_SEL)) | (4 << 14);
35 reg = (reg & (~RG_DSI_V072_SEL)) | (4 << 11);
36 reg = (reg & (~RG_DSI_V10_SEL)) | (4 << 8);
37 reg = (reg & (~RG_DSI_V12_SEL)) | (4 << 5);
38 reg |= RG_DSI_BG_CKEN;
39 reg |= RG_DSI_BG_CORE_EN;
40 write32(&mipi_tx0->dsi_bg_con, reg);
41 udelay(30);
43 clrsetbits_le32(&mipi_tx0->dsi_top_con, RG_DSI_LNT_IMP_CAL_CODE,
44 8 << 4 | RG_DSI_LNT_HS_BIAS_EN);
46 setbits_le32(&mipi_tx0->dsi_con,
47 RG_DSI0_CKG_LDOOUT_EN | RG_DSI0_LDOCORE_EN);
49 clrsetbits_le32(&mipi_tx0->dsi_pll_pwr, RG_DSI_MPPLL_SDM_ISO_EN,
50 RG_DSI_MPPLL_SDM_PWR_ON);
52 clrbits_le32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN);
54 if (data_rate > 500) {
55 txdiv0 = 0;
56 txdiv1 = 0;
57 } else if (data_rate >= 250) {
58 txdiv0 = 1;
59 txdiv1 = 0;
60 } else if (data_rate >= 125) {
61 txdiv0 = 2;
62 txdiv1 = 0;
63 } else if (data_rate >= 62) {
64 txdiv0 = 2;
65 txdiv1 = 1;
66 } else {
67 /* MIN = 50 */
68 assert(data_rate >= MTK_DSI_DATA_RATE_MIN_MHZ);
69 txdiv0 = 2;
70 txdiv1 = 2;
73 clrsetbits_le32(&mipi_tx0->dsi_pll_con0,
74 RG_DSI0_MPPLL_TXDIV1 | RG_DSI0_MPPLL_TXDIV0 |
75 RG_DSI0_MPPLL_PREDIV, txdiv1 << 5 | txdiv0 << 3);
77 /**
78 * PLL PCW config
79 * PCW bit 24~30 = integer part of pcw
80 * PCW bit 0~23 = fractional part of pcw
81 * pcw = data_Rate*4*txdiv/(Ref_clk*2);
82 * Post DIV =4, so need data_Rate*4
83 * Ref_clk is 26MHz
85 pcw = (u64)(data_rate * (1 << txdiv0) * (1 << txdiv1)) << 24;
86 pcw /= 13;
87 write32(&mipi_tx0->dsi_pll_con2, pcw);
89 setbits_le32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_FRA_EN);
91 setbits_le32(&mipi_tx0->dsi_clock_lane, LDOOUT_EN);
93 for (i = 0; i < lanes; i++)
94 setbits_le32(&mipi_tx0->dsi_data_lane[i], LDOOUT_EN);
96 setbits_le32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN);
98 udelay(40);
100 clrbits_le32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_SSC_EN);
101 clrbits_le32(&mipi_tx0->dsi_top_con, RG_DSI_PAD_TIE_LOW_EN);
104 void mtk_dsi_reset(void)
106 setbits_le32(&dsi0->dsi_con_ctrl, 3);
107 clrbits_le32(&dsi0->dsi_con_ctrl, 1);
110 void mtk_dsi_pin_drv_ctrl(void)
112 struct stopwatch sw;
113 uint32_t pwr_ack;
115 setbits_le32(&lvds_tx1->vopll_ctl3, RG_DA_LVDSTX_PWR_ON);
117 stopwatch_init_usecs_expire(&sw, 1000);
119 do {
120 if (stopwatch_expired(&sw)) {
121 printk(BIOS_ERR, "enable lvdstx_power failed!!!\n");
122 return;
124 pwr_ack = read32(&lvds_tx1->vopll_ctl3) & RG_AD_LVDSTX_PWR_ACK;
125 } while (pwr_ack == 0);
127 clrbits_le32(&lvds_tx1->vopll_ctl3, RG_DA_LVDS_ISO_EN);