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