Linux-libre 4.10.7-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / msm / dsi / phy / dsi_phy_28nm_8960.c
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                 const unsigned long bit_rate, const unsigned long esc_rate)
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, bit_rate, esc_rate)) {
135                 dev_err(&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         },
195         .io_start = { 0x4700300, 0x5800300 },
196         .num_dsi_phy = 2,
197 };