Angel Pons | e67ab18 | 2020-04-04 18:51:11 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 2 | |
Hung-Te Lin | 302dddf | 2019-08-08 06:28:43 +0800 | [diff] [blame] | 3 | #include <assert.h> |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 4 | #include <device/mmio.h> |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 5 | #include <console/console.h> |
| 6 | #include <delay.h> |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 7 | #include <soc/dsi.h> |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 8 | #include <timer.h> |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 9 | |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 10 | void mtk_dsi_configure_mipi_tx(u32 data_rate, u32 lanes) |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 11 | { |
| 12 | u32 txdiv0, txdiv1; |
| 13 | u64 pcw; |
| 14 | u32 reg; |
Hung-Te Lin | 302dddf | 2019-08-08 06:28:43 +0800 | [diff] [blame] | 15 | int i; |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 16 | |
| 17 | reg = read32(&mipi_tx0->dsi_bg_con); |
| 18 | |
| 19 | reg = (reg & (~RG_DSI_V02_SEL)) | (4 << 20); |
| 20 | reg = (reg & (~RG_DSI_V032_SEL)) | (4 << 17); |
| 21 | reg = (reg & (~RG_DSI_V04_SEL)) | (4 << 14); |
| 22 | reg = (reg & (~RG_DSI_V072_SEL)) | (4 << 11); |
| 23 | reg = (reg & (~RG_DSI_V10_SEL)) | (4 << 8); |
| 24 | reg = (reg & (~RG_DSI_V12_SEL)) | (4 << 5); |
| 25 | reg |= RG_DSI_BG_CKEN; |
| 26 | reg |= RG_DSI_BG_CORE_EN; |
Hung-Te Lin | 1c6e5a6 | 2019-08-05 14:38:30 +0800 | [diff] [blame] | 27 | write32(&mipi_tx0->dsi_bg_con, reg); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 28 | udelay(30); |
| 29 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 30 | clrsetbits32(&mipi_tx0->dsi_top_con, RG_DSI_LNT_IMP_CAL_CODE, |
| 31 | 8 << 4 | RG_DSI_LNT_HS_BIAS_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 32 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 33 | setbits32(&mipi_tx0->dsi_con, |
| 34 | RG_DSI0_CKG_LDOOUT_EN | RG_DSI0_LDOCORE_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 35 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 36 | clrsetbits32(&mipi_tx0->dsi_pll_pwr, RG_DSI_MPPLL_SDM_ISO_EN, |
| 37 | RG_DSI_MPPLL_SDM_PWR_ON); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 38 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 39 | clrbits32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 40 | |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 41 | if (data_rate > 500 * MHz) { |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 42 | txdiv0 = 0; |
| 43 | txdiv1 = 0; |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 44 | } else if (data_rate >= 250 * MHz) { |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 45 | txdiv0 = 1; |
| 46 | txdiv1 = 0; |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 47 | } else if (data_rate >= 125 * MHz) { |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 48 | txdiv0 = 2; |
| 49 | txdiv1 = 0; |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 50 | } else if (data_rate >= 62 * MHz) { |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 51 | txdiv0 = 2; |
| 52 | txdiv1 = 1; |
Hung-Te Lin | 302dddf | 2019-08-08 06:28:43 +0800 | [diff] [blame] | 53 | } else { |
| 54 | /* MIN = 50 */ |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 55 | assert(data_rate >= MTK_DSI_DATA_RATE_MIN_MHZ * MHz); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 56 | txdiv0 = 2; |
| 57 | txdiv1 = 2; |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 58 | } |
| 59 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 60 | clrsetbits32(&mipi_tx0->dsi_pll_con0, |
| 61 | RG_DSI0_MPPLL_TXDIV1 | RG_DSI0_MPPLL_TXDIV0 | |
| 62 | RG_DSI0_MPPLL_PREDIV, txdiv1 << 5 | txdiv0 << 3); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 63 | |
| 64 | /** |
| 65 | * PLL PCW config |
| 66 | * PCW bit 24~30 = integer part of pcw |
| 67 | * PCW bit 0~23 = fractional part of pcw |
| 68 | * pcw = data_Rate*4*txdiv/(Ref_clk*2); |
| 69 | * Post DIV =4, so need data_Rate*4 |
| 70 | * Ref_clk is 26MHz |
| 71 | */ |
| 72 | pcw = (u64)(data_rate * (1 << txdiv0) * (1 << txdiv1)) << 24; |
Yu-Ping Wu | 443fbd7 | 2020-02-11 18:33:57 +0800 | [diff] [blame] | 73 | pcw /= 13 * MHz; |
Hung-Te Lin | 1c6e5a6 | 2019-08-05 14:38:30 +0800 | [diff] [blame] | 74 | write32(&mipi_tx0->dsi_pll_con2, pcw); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 75 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 76 | setbits32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_FRA_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 77 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 78 | setbits32(&mipi_tx0->dsi_clock_lane, LDOOUT_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 79 | |
| 80 | for (i = 0; i < lanes; i++) |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 81 | setbits32(&mipi_tx0->dsi_data_lane[i], LDOOUT_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 82 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 83 | setbits32(&mipi_tx0->dsi_pll_con0, RG_DSI0_MPPLL_PLL_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 84 | |
| 85 | udelay(40); |
| 86 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 87 | clrbits32(&mipi_tx0->dsi_pll_con1, RG_DSI0_MPPLL_SDM_SSC_EN); |
| 88 | clrbits32(&mipi_tx0->dsi_top_con, RG_DSI_PAD_TIE_LOW_EN); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 89 | } |
| 90 | |
Hung-Te Lin | c59fbf2 | 2019-08-07 08:00:58 +0800 | [diff] [blame] | 91 | void mtk_dsi_reset(void) |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 92 | { |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 93 | setbits32(&dsi0->dsi_con_ctrl, 3); |
| 94 | clrbits32(&dsi0->dsi_con_ctrl, 1); |
Jitao Shi | 4a04a7b | 2016-01-08 16:02:13 +0800 | [diff] [blame] | 95 | } |
| 96 | |
Hung-Te Lin | ff0945e | 2019-08-07 09:59:16 +0800 | [diff] [blame] | 97 | void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing) |
| 98 | { |
| 99 | int lpx = 5; |
| 100 | timing->lpx = lpx; |
| 101 | timing->da_hs_prepare = 6; |
| 102 | timing->da_hs_zero = 10; |
| 103 | timing->da_hs_trail = 8; |
| 104 | |
| 105 | timing->ta_go = 4 * lpx; |
| 106 | timing->ta_sure = 3 * lpx / 2; |
| 107 | timing->ta_get = 5 * lpx; |
| 108 | timing->da_hs_exit = 7; |
| 109 | |
| 110 | timing->da_hs_sync = 0; |
| 111 | timing->clk_hs_exit = 2 * lpx; |
Hung-Te Lin | 3b217d5 | 2019-08-07 10:15:48 +0800 | [diff] [blame] | 112 | |
| 113 | timing->d_phy = 12; |
Hung-Te Lin | ff0945e | 2019-08-07 09:59:16 +0800 | [diff] [blame] | 114 | } |
| 115 | |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 116 | void mtk_dsi_pin_drv_ctrl(void) |
| 117 | { |
| 118 | struct stopwatch sw; |
Jitao Shi | b927fe1 | 2017-02-07 08:51:01 +0800 | [diff] [blame] | 119 | uint32_t pwr_ack; |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 120 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 121 | setbits32(&lvds_tx1->vopll_ctl3, RG_DA_LVDSTX_PWR_ON); |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 122 | |
| 123 | stopwatch_init_usecs_expire(&sw, 1000); |
| 124 | |
| 125 | do { |
| 126 | if (stopwatch_expired(&sw)) { |
| 127 | printk(BIOS_ERR, "enable lvdstx_power failed!!!\n"); |
| 128 | return; |
| 129 | } |
Jitao Shi | b927fe1 | 2017-02-07 08:51:01 +0800 | [diff] [blame] | 130 | pwr_ack = read32(&lvds_tx1->vopll_ctl3) & RG_AD_LVDSTX_PWR_ACK; |
Jitao Shi | b927fe1 | 2017-02-07 08:51:01 +0800 | [diff] [blame] | 131 | } while (pwr_ack == 0); |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 132 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 133 | clrbits32(&lvds_tx1->vopll_ctl3, RG_DA_LVDS_ISO_EN); |
Jitao Shi | 700b039 | 2016-07-15 14:23:53 +0800 | [diff] [blame] | 134 | } |