Merge tag 'lsk-v4.4-16.06-android'
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_soc_rk3366.c
1 #ifdef CONFIG_ARM64
2 #include "camsys_soc_priv.h"
3 #include "camsys_soc_rk3366.h"
4
5 struct mipiphy_hsfreqrange_s {
6         unsigned int range_l;
7         unsigned int range_h;
8         unsigned char cfg_bit;
9 };
10
11 static struct mipiphy_hsfreqrange_s mipiphy_hsfreqrange[] = {
12         {80, 110, 0x00},
13         {110, 150, 0x01},
14         {150, 200, 0x02},
15         {200, 250, 0x03},
16         {250, 300, 0x04},
17         {300, 400, 0x05},
18         {400, 500, 0x06},
19         {500, 600, 0x07},
20         {600, 700, 0x08},
21         {700, 800, 0x09},
22         {800, 1000, 0x10},
23         {1000, 1200, 0x11},
24         {1200, 1400, 0x12},
25         {1400, 1600, 0x13},
26         {1600, 1800, 0x14}
27 };
28
29 #if 0
30 static int camsys_rk3368_mipiphy_wr_reg(
31 unsigned long phy_virt, unsigned char addr, unsigned char data)
32 {
33         /*TESTEN =1,TESTDIN=addr */
34         write_csihost_reg(CSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
35         /*TESTCLK=0 */
36         write_csihost_reg(CSIHOST_PHY_TEST_CTRL0, 0x00000000);
37         udelay(10);
38         /*TESTEN =0,TESTDIN=data */
39         write_csihost_reg(CSIHOST_PHY_TEST_CTRL1, (0x00000000 | data));
40         /*TESTCLK=1 */
41         write_csihost_reg(CSIHOST_PHY_TEST_CTRL0, 0x00000002);
42         udelay(10);
43
44         return 0;
45 }
46
47 static int camsys_rk3368_mipiphy_rd_reg(
48 unsigned long phy_virt, unsigned char addr)
49 {
50         return (read_csihost_reg(((CSIHOST_PHY_TEST_CTRL1) & 0xff00))>>8);
51 }
52
53 static int camsys_rk3368_csiphy_wr_reg(
54 unsigned long csiphy_virt, unsigned char addr, unsigned char data)
55 {
56         write_csiphy_reg(addr, data);
57         return 0;
58 }
59
60 static int camsys_rk3368_csiphy_rd_reg(
61 unsigned long csiphy_virt, unsigned char addr)
62 {
63         return read_csiphy_reg(addr);
64 }
65 #endif
66 static int camsys_rk3366_mipihpy_cfg(
67 camsys_mipiphy_soc_para_t *para)
68 {
69         unsigned char hsfreqrange = 0xff, i;
70         struct mipiphy_hsfreqrange_s *hsfreqrange_p;
71         unsigned long phy_virt, phy_index;
72         unsigned long base;
73         unsigned long csiphy_virt;
74
75         phy_index = para->phy->phy_index;
76         if (para->camsys_dev->mipiphy[phy_index].reg != NULL) {
77                 phy_virt  = para->camsys_dev->mipiphy[phy_index].reg->vir_base;
78         } else {
79                 phy_virt = 0x00;
80         }
81         if (para->camsys_dev->csiphy_reg != NULL) {
82                 csiphy_virt =
83                         (unsigned long)para->camsys_dev->csiphy_reg->vir_base;
84         } else {
85                 csiphy_virt = 0x00;
86         }
87         if ((para->phy->bit_rate == 0) ||
88                 (para->phy->data_en_bit == 0)) {
89                 if (para->phy->phy_index == 0) {
90                         base =
91                                 (unsigned long)
92                                 para->camsys_dev->devmems.registermem->vir_base;
93                         *((unsigned int *)
94                                 (base + (MRV_MIPI_BASE + MRV_MIPI_CTRL)))
95                                 &= ~(0x0f << 8);
96                         camsys_trace(1, "mipi phy 0 standby!");
97                 }
98
99                 return 0;
100         }
101
102         hsfreqrange_p = mipiphy_hsfreqrange;
103         for (i = 0;
104                 i <
105                         (sizeof(mipiphy_hsfreqrange)/
106                         sizeof(struct mipiphy_hsfreqrange_s));
107                 i++) {
108
109                 if ((para->phy->bit_rate > hsfreqrange_p->range_l) &&
110                         (para->phy->bit_rate <= hsfreqrange_p->range_h)) {
111                         hsfreqrange = hsfreqrange_p->cfg_bit;
112                         break;
113                 }
114                 hsfreqrange_p++;
115         }
116
117         if (hsfreqrange == 0xff) {
118                 camsys_err("mipi phy config bitrate %d Mbps isn't supported!",
119                         para->phy->bit_rate);
120                 hsfreqrange = 0x00;
121         }
122
123         if (para->phy->phy_index == 0) {
124                 /* isp select */
125                 /*write_grf_reg
126                         (GRF_SOC_CON6_OFFSET, ISP_MIPI_CSI_HOST_SEL_OFFSET_MASK
127                         | (1 << ISP_MIPI_CSI_HOST_SEL_OFFSET_BIT));
128                 */
129                 /* phy start */
130                 write_csiphy_reg
131                         ((MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET + 0x100),
132                         hsfreqrange |
133                         (read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
134                         + 0x100) & (~0xf)));
135
136                 if (para->phy->data_en_bit > 0x00) {
137                         write_csiphy_reg((MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
138                                 + 0x180), hsfreqrange |
139                         (read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
140                                 + 0x180) & (~0xf)));
141                 }
142                 if (para->phy->data_en_bit > 0x02) {
143                         write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
144                                 + 0x200, hsfreqrange |
145                         (read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
146                                 + 0x200) & (~0xf)));
147                 }
148                 if (para->phy->data_en_bit > 0x04) {
149                         write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
150                                 + 0x280, hsfreqrange |
151                         (read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
152                                 + 0x280) & (~0xf)));
153                         write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
154                                 + 0x300, hsfreqrange |
155                         (read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET
156                                 + 0x300) & (~0xf)));
157                 }
158
159                 /*set data lane num and enable clock lane */
160                 write_csiphy_reg(0x00, ((para->phy->data_en_bit << 2)
161                         | (0x1 << 6) | 0x1));
162
163                 base =
164                         (unsigned long)
165                         para->camsys_dev->devmems.registermem->vir_base;
166                 *((unsigned int *)(base + (MRV_MIPI_BASE + MRV_MIPI_CTRL)))
167                                 &= ~(0x0f << 8);
168         } else {
169                 camsys_err("mipi phy index %d is invalidate!",
170                         para->phy->phy_index);
171                 goto fail;
172         }
173
174         camsys_trace(1, "mipi phy(%d) turn on(lane: 0x%x  bit_rate: %dMbps)",
175         para->phy->phy_index, para->phy->data_en_bit, para->phy->bit_rate);
176
177         return 0;
178
179 fail:
180         return -1;
181 }
182
183 #define MRV_AFM_BASE            0x0000
184 #define VI_IRCL                 0x0014
185 int camsys_rk3366_cfg(
186 camsys_dev_t *camsys_dev, camsys_soc_cfg_t cfg_cmd, void *cfg_para)
187 {
188         unsigned int *para_int;
189
190         switch (cfg_cmd) {
191         case Clk_DriverStrength_Cfg: {
192                 para_int = (unsigned int *)cfg_para;
193                 __raw_writel((((*para_int) & 0x03) << 3) | (0x03 << 3),
194                 (void *)(camsys_dev->rk_grf_base + 0x204));
195                 /* set 0xffffffff to max all */
196                 break;
197         }
198
199         case Cif_IoDomain_Cfg: {
200                 para_int = (unsigned int *)cfg_para;
201                 if (*para_int < 28000000) {
202                         /* 1.8v IO */
203                         __raw_writel(((1 << 1) | (1 << (1 + 16))),
204                         (void *)(camsys_dev->rk_grf_base + 0x0900));
205                 } else {
206                         /* 3.3v IO */
207                         __raw_writel(((0 << 1) | (1 << (1 + 16))),
208                         (void *)(camsys_dev->rk_grf_base + 0x0900));
209                 }
210                 break;
211         }
212
213         case Mipi_Phy_Cfg: {
214                 camsys_rk3366_mipihpy_cfg
215                         ((camsys_mipiphy_soc_para_t *)cfg_para);
216                 break;
217         }
218
219         case Isp_SoftRst: /* ddl@rock-chips.com: v0.d.0 */ {
220                 unsigned long reset;
221                 reset = (unsigned long)cfg_para;
222                 if (reset == 1)
223                         __raw_writel(0x80, (void *)(camsys_dev->rk_isp_base +
224                                 MRV_AFM_BASE + VI_IRCL));
225                 else
226                         __raw_writel(0x00, (void *)(camsys_dev->rk_isp_base +
227                                 MRV_AFM_BASE + VI_IRCL));
228                         camsys_trace(1, "Isp self soft rst: %ld", reset);
229                 break;
230         }
231
232         default: {
233                 camsys_warn("cfg_cmd: 0x%x isn't support", cfg_cmd);
234                 break;
235         }
236
237         }
238
239         return 0;
240 }
241 #endif /* CONFIG_ARM64 */