1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/delay.h>
7
8 #include "dsi_phy.h"
9 #include "dsi.xml.h"
10
dsi_28nm_dphy_set_timing(struct msm_dsi_phy * phy,struct msm_dsi_dphy_timing * timing)11 static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
12 struct msm_dsi_dphy_timing *timing)
13 {
14 void __iomem *base = phy->base;
15
16 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0,
17 DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
18 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1,
19 DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
20 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2,
21 DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
22 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3, 0x0);
23 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4,
24 DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
25 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5,
26 DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
27 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6,
28 DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
29 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7,
30 DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
31 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8,
32 DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
33 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9,
34 DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
35 DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
36 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10,
37 DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
38 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11,
39 DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
40 }
41
dsi_28nm_phy_regulator_init(struct msm_dsi_phy * phy)42 static void dsi_28nm_phy_regulator_init(struct msm_dsi_phy *phy)
43 {
44 void __iomem *base = phy->reg_base;
45
46 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
47 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 1);
48 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 1);
49 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0);
50 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4,
51 0x100);
52 }
53
dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy * phy)54 static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy)
55 {
56 void __iomem *base = phy->reg_base;
57
58 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
59 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 0xa);
60 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 0x4);
61 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0x0);
62 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4, 0x20);
63 }
64
dsi_28nm_phy_calibration(struct msm_dsi_phy * phy)65 static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy)
66 {
67 void __iomem *base = phy->reg_base;
68 u32 status;
69 int i = 5000;
70
71 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG,
72 0x3);
73
74 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2, 0x0);
75 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1, 0x5a);
76 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3, 0x10);
77 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4, 0x1);
78 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0, 0x1);
79
80 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x1);
81 usleep_range(5000, 6000);
82 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x0);
83
84 do {
85 status = dsi_phy_read(base +
86 REG_DSI_28nm_8960_PHY_MISC_CAL_STATUS);
87
88 if (!(status & DSI_28nm_8960_PHY_MISC_CAL_STATUS_CAL_BUSY))
89 break;
90
91 udelay(1);
92 } while (--i > 0);
93 }
94
dsi_28nm_phy_lane_config(struct msm_dsi_phy * phy)95 static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy)
96 {
97 void __iomem *base = phy->base;
98 int i;
99
100 for (i = 0; i < 4; i++) {
101 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i), 0x80);
102 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i), 0x45);
103 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i), 0x00);
104 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i),
105 0x00);
106 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i),
107 0x01);
108 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i),
109 0x66);
110 }
111
112 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0, 0x40);
113 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1, 0x67);
114 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2, 0x0);
115 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH, 0x0);
116 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0, 0x1);
117 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1, 0x88);
118 }
119
dsi_28nm_phy_enable(struct msm_dsi_phy * phy,int src_pll_id,struct msm_dsi_phy_clk_request * clk_req)120 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
121 struct msm_dsi_phy_clk_request *clk_req)
122 {
123 struct msm_dsi_dphy_timing *timing = &phy->timing;
124 void __iomem *base = phy->base;
125
126 DBG("");
127
128 if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
129 DRM_DEV_ERROR(&phy->pdev->dev,
130 "%s: D-PHY timing calculation failed\n", __func__);
131 return -EINVAL;
132 }
133
134 dsi_28nm_phy_regulator_init(phy);
135
136 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LDO_CTRL, 0x04);
137
138 /* strength control */
139 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_0, 0xff);
140 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_1, 0x00);
141 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_2, 0x06);
142
143 /* phy ctrl */
144 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x5f);
145 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_1, 0x00);
146 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_2, 0x00);
147 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_3, 0x10);
148
149 dsi_28nm_phy_regulator_ctrl(phy);
150
151 dsi_28nm_phy_calibration(phy);
152
153 dsi_28nm_phy_lane_config(phy);
154
155 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0f);
156 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1, 0x03);
157 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0, 0x03);
158 dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0);
159
160 dsi_28nm_dphy_set_timing(phy, timing);
161
162 return 0;
163 }
164
dsi_28nm_phy_disable(struct msm_dsi_phy * phy)165 static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
166 {
167 dsi_phy_write(phy->base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x0);
168
169 /*
170 * Wait for the registers writes to complete in order to
171 * ensure that the phy is completely disabled
172 */
173 wmb();
174 }
175
176 const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = {
177 .type = MSM_DSI_PHY_28NM_8960,
178 .src_pll_truthtable = { {true, true}, {false, true} },
179 .reg_cfg = {
180 .num = 1,
181 .regs = {
182 {"vddio", 100000, 100}, /* 1.8 V */
183 },
184 },
185 .ops = {
186 .enable = dsi_28nm_phy_enable,
187 .disable = dsi_28nm_phy_disable,
188 .init = msm_dsi_phy_init_common,
189 },
190 .io_start = { 0x4700300, 0x5800300 },
191 .num_dsi_phy = 2,
192 };
193