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 
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 
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 
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 
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 
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 
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 
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