Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_soc_rk3399.c
1 #ifdef CONFIG_ARM64
2 #include "camsys_soc_priv.h"
3 #include "camsys_soc_rk3399.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, 90, 0x00},
13         {90, 100, 0x10},
14         {100, 110, 0x20},
15         {110, 130, 0x01},
16         {130, 140, 0x11},
17         {140, 150, 0x21},
18         {150, 170, 0x02},
19         {170, 180, 0x12},
20         {180, 200, 0x22},
21         {200, 220, 0x03},
22         {220, 240, 0x13},
23         {240, 250, 0x23},
24         {250, 270, 0x04},
25         {270, 300, 0x14},
26         {300, 330, 0x05},
27         {330, 360, 0x15},
28         {360, 400, 0x25},
29         {400, 450, 0x06},
30         {450, 500, 0x16},
31         {500, 550, 0x07},
32         {550, 600, 0x17},
33         {600, 650, 0x08},
34         {650, 700, 0x18},
35         {700, 750, 0x09},
36         {750, 800, 0x19},
37         {800, 850, 0x29},
38         {850, 900, 0x39},
39         {900, 950, 0x0a},
40         {950, 1000, 0x1a},
41         {1000, 1050, 0x2a},
42         {1100, 1150, 0x3a},
43         {1150, 1200, 0x0b},
44         {1200, 1250, 0x1b},
45         {1250, 1300, 0x2b},
46         {1300, 1350, 0x0c},
47         {1350, 1400, 0x1c},
48         {1400, 1450, 0x2c},
49         {1450, 1500, 0x3c}
50 };
51
52 static char camsys_rk3399_mipiphy0_rd_reg(camsys_mipiphy_soc_para_t *para, unsigned char addr)
53 {
54         /*TESTCLK=1*/
55         write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK |
56                                 (1 << DPHY_RX0_TESTCLK_BIT));
57         /*TESTEN =1,TESTDIN=addr*/
58         write_grf_reg(GRF_SOC_CON25_OFFSET,
59                                 ((addr << DPHY_RX0_TESTDIN_BIT) |
60                                 DPHY_RX0_TESTDIN_MASK |
61                                 (1 << DPHY_RX0_TESTEN_BIT) |
62                                 DPHY_RX0_TESTEN_MASK));
63         /*TESTCLK=0*/
64         write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK);
65
66     return read_grf_reg(GRF_SOC_STATUS1)&0xff;
67 }
68
69 static int camsys_rk3399_mipiphy0_wr_reg
70 (camsys_mipiphy_soc_para_t *para, unsigned char addr, unsigned char data)
71 {
72         /*TESTCLK=1*/
73         write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK |
74                                 (1 << DPHY_RX0_TESTCLK_BIT));
75         /*TESTEN =1,TESTDIN=addr*/
76         write_grf_reg(GRF_SOC_CON25_OFFSET,
77                                 ((addr << DPHY_RX0_TESTDIN_BIT) |
78                                 DPHY_RX0_TESTDIN_MASK |
79                                 (1 << DPHY_RX0_TESTEN_BIT) |
80                                 DPHY_RX0_TESTEN_MASK));
81         /*TESTCLK=0*/
82         write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK);
83
84         if (data != 0xff) { /*write data ?*/
85                 /*TESTEN =0,TESTDIN=data*/
86                 write_grf_reg(GRF_SOC_CON25_OFFSET,
87                                         ((data << DPHY_RX0_TESTDIN_BIT) |
88                                         DPHY_RX0_TESTDIN_MASK |
89                                         DPHY_RX0_TESTEN_MASK));
90
91                 /*TESTCLK=1*/
92                 write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK |
93                                         (1 << DPHY_RX0_TESTCLK_BIT));
94         }
95         return 0;
96 }
97
98 static char camsys_rk3399_mipiphy1_wr_reg
99 (unsigned long dsiphy_virt, unsigned char addr, unsigned char data)
100 {
101         /*TESTEN =1,TESTDIN=addr*/
102         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
103         /*TESTCLK=0*/
104         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000000);
105         /*TESTEN =0,TESTDIN=data*/
106         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00000000 | data));
107         /*TESTCLK=1 */
108         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
109
110         return 0;
111 }
112
113 static int camsys_rk3399_mipiphy1_rd_reg(unsigned long dsiphy_virt, unsigned char addr)
114 {
115         /*TESTEN =1,TESTDIN=addr*/
116         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
117         /*TESTCLK=0*/
118         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000000);
119     return (read_dsihost_reg(DSIHOST_PHY_TEST_CTRL1)>>8);
120 }
121
122 static int camsys_rk3399_mipihpy_cfg
123 (camsys_mipiphy_soc_para_t *para)
124 {
125         unsigned char hsfreqrange = 0xff, i;
126         struct mipiphy_hsfreqrange_s *hsfreqrange_p;
127         unsigned long phy_virt, phy_index;
128         unsigned long base;
129         unsigned long csiphy_virt;
130         unsigned long dsiphy_virt;
131         unsigned long vir_base = 0;
132         unsigned char settle_bypass = 0;
133         unsigned char settle_en = 0;
134         unsigned char manu_hsfreqrange = 0x04;
135
136         phy_index = para->phy->phy_index;
137         if (para->camsys_dev->mipiphy[phy_index].reg != NULL) {
138                 phy_virt  = para->camsys_dev->mipiphy[phy_index].reg->vir_base;
139         } else {
140                 phy_virt = 0x00;
141         }
142         if (para->camsys_dev->csiphy_reg != NULL) {
143                 csiphy_virt =
144                         (unsigned long)para->camsys_dev->csiphy_reg->vir_base;
145         } else {
146                 csiphy_virt = 0x00;
147         }
148         if (para->camsys_dev->dsiphy_reg != NULL) {
149                 dsiphy_virt =
150                         (unsigned long)para->camsys_dev->dsiphy_reg->vir_base;
151         } else {
152                 dsiphy_virt = 0x00;
153         }
154
155         if ((para->phy->bit_rate == 0) ||
156                 (para->phy->data_en_bit == 0)) {
157                 if (para->phy->phy_index == 0) {
158                         base =
159                         (para->camsys_dev->devmems.registermem->vir_base);
160                         *((unsigned int *)
161                                 (base + (MRV_MIPI_BASE + MRV_MIPI_CTRL)))
162                                 &= ~(0x0f << 8);
163                 camsys_trace(1, "mipi phy 0 standby!");
164                 }
165
166                 return 0;
167         }
168
169         hsfreqrange_p = mipiphy_hsfreqrange;
170         for (i = 0;
171                 i < (sizeof(mipiphy_hsfreqrange)/
172                         sizeof(struct mipiphy_hsfreqrange_s));
173                 i++) {
174                 if ((para->phy->bit_rate > hsfreqrange_p->range_l) &&
175                         (para->phy->bit_rate <= hsfreqrange_p->range_h)) {
176                         hsfreqrange = hsfreqrange_p->cfg_bit;
177                         break;
178                 }
179                 hsfreqrange_p++;
180         }
181
182         if (hsfreqrange == 0xff) {
183                 camsys_err("mipi phy config bitrate %d Mbps isn't supported!",
184                         para->phy->bit_rate);
185                 hsfreqrange = 0x00;
186         }
187         hsfreqrange <<= 1;
188         if (para->phy->phy_index == 0) {
189                 if (strstr(para->camsys_dev->miscdev.name, "camsys_marvin1")) {
190                         camsys_err("miscdev.name = %s,mipi phy index %d is invalidate\n",
191                                 para->camsys_dev->miscdev.name,
192                                 para->phy->phy_index);
193                         goto fail;
194                 }
195
196                 write_grf_reg(GRF_SOC_CON21_OFFSET,
197                                         DPHY_RX0_FORCERXMODE_MASK |
198                                         (0x0 << DPHY_RX0_FORCERXMODE_BIT) |
199                                         DPHY_RX0_FORCETXSTOPMODE_MASK |
200                                         (0x0 << DPHY_RX0_FORCETXSTOPMODE_BIT));
201
202                 /*  set lane num*/
203                 write_grf_reg(GRF_SOC_CON21_OFFSET,
204                         DPHY_RX0_ENABLE_MASK |
205                         (para->phy->data_en_bit << DPHY_RX0_ENABLE_BIT));
206
207                 /*  set lan turndisab as 1*/
208                 write_grf_reg(GRF_SOC_CON21_OFFSET,
209                         DPHY_RX0_TURNDISABLE_MASK |
210                         (0xf << DPHY_RX0_TURNDISABLE_BIT));
211                 write_grf_reg(GRF_SOC_CON21_OFFSET, (0x0<<4) | (0xf<<20));
212
213                 /*  set lan turnrequest as 0 */
214                 write_grf_reg(GRF_SOC_CON9_OFFSET,
215                         DPHY_RX0_TURNREQUEST_MASK |
216                         (0x0 << DPHY_RX0_TURNREQUEST_BIT));
217
218                 /*phy start*/
219                 {
220                         write_grf_reg(GRF_SOC_CON25_OFFSET,
221                                 DPHY_RX0_TESTCLK_MASK |
222                                 (0x1 << DPHY_RX0_TESTCLK_BIT)); /*TESTCLK=1 */
223                         write_grf_reg(GRF_SOC_CON25_OFFSET,
224                                 DPHY_RX0_TESTCLR_MASK |
225                                 (0x1 << DPHY_RX0_TESTCLR_BIT));   /*TESTCLR=1*/
226                         udelay(100);
227                         /*TESTCLR=0  zyc*/
228                         write_grf_reg(GRF_SOC_CON25_OFFSET,
229                                 DPHY_RX0_TESTCLR_MASK);
230                         udelay(100);
231                         /*set clock lane*/
232                         camsys_rk3399_mipiphy0_wr_reg
233                                 (para, 0x34, settle_bypass);
234                         /*HS hsfreqrange & lane 0  settle bypass*/
235                         camsys_rk3399_mipiphy0_wr_reg
236                                 (para, 0x44, hsfreqrange | settle_bypass);
237                         camsys_rk3399_mipiphy0_wr_reg
238                                 (para, 0x54, settle_bypass);
239                         camsys_rk3399_mipiphy0_wr_reg
240                                 (para, 0x84, settle_bypass);
241                         camsys_rk3399_mipiphy0_wr_reg
242                                 (para, 0x94, settle_bypass);
243                         camsys_rk3399_mipiphy0_wr_reg
244                                 (para, 0x75, (settle_en << 7) | manu_hsfreqrange);
245                         camsys_rk3399_mipiphy0_rd_reg(para, 0x75);
246                         /*Normal operation*/
247                         camsys_rk3399_mipiphy0_wr_reg(para, 0x0, -1);
248                         write_grf_reg(GRF_SOC_CON25_OFFSET,
249                                 DPHY_RX0_TESTCLK_MASK |
250                                 (1 << DPHY_RX0_TESTCLK_BIT));    /*TESTCLK=1*/
251                         /*TESTEN =0 */
252                         write_grf_reg(GRF_SOC_CON25_OFFSET,
253                                 (DPHY_RX0_TESTEN_MASK));
254                 }
255
256                 base = (para->camsys_dev->devmems.registermem->vir_base);
257                 *((unsigned int *)(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL))) |=
258                         (0x0f<<8);
259
260     } else if (para->phy->phy_index == 1) {
261
262                 if (!strstr(para->camsys_dev->miscdev.name, "camsys_marvin1")) {
263                         camsys_err
264                                 ("miscdev.name = %s,mipi phy index %d is invalidate\n",
265                                 para->camsys_dev->miscdev.name,
266                                 para->phy->phy_index);
267                         goto fail;
268                 }
269
270                 write_grf_reg(GRF_SOC_CON23_OFFSET,
271                         DPHY_RX0_FORCERXMODE_MASK |
272                         (0x0 << DPHY_RX0_FORCERXMODE_BIT) |
273                         DPHY_RX0_FORCETXSTOPMODE_MASK |
274                         (0x0 << DPHY_RX0_FORCETXSTOPMODE_BIT));
275                 write_grf_reg(GRF_SOC_CON24_OFFSET,
276                         DPHY_TX1RX1_MASTERSLAVEZ_MASK |
277                         (0x0 << DPHY_TX1RX1_MASTERSLAVEZ_BIT) |
278                         DPHY_TX1RX1_BASEDIR_MASK |
279                         (0x1 << DPHY_TX1RX1_BASEDIR_BIT) |
280                         DPHY_RX1_MASK | 0x0 << DPHY_RX1_SEL_BIT);
281
282                 /*      set lane num*/
283                 write_grf_reg(GRF_SOC_CON23_OFFSET,
284                         DPHY_TX1RX1_ENABLE_MASK |
285                         (para->phy->data_en_bit << DPHY_TX1RX1_ENABLE_BIT));
286
287                 /*      set lan turndisab as 1*/
288                 write_grf_reg(GRF_SOC_CON23_OFFSET,
289                         DPHY_TX1RX1_TURNDISABLE_MASK |
290                         (0xf << DPHY_TX1RX1_TURNDISABLE_BIT));
291                 write_grf_reg(GRF_SOC_CON23_OFFSET, (0x0<<4)|(0xf<<20));
292
293                 /*      set lan turnrequest as 0*/
294                 write_grf_reg(GRF_SOC_CON24_OFFSET,
295                         DPHY_TX1RX1_TURNREQUEST_MASK |
296                         (0x0 << DPHY_TX1RX1_TURNREQUEST_BIT));
297                 /*phy1 start*/
298                 {
299                         char res_val = 0;
300                         res_val = read_dsihost_reg(DSIHOST_PHY_SHUTDOWNZ);
301                         res_val &= 0xfffffffe;
302                         /*SHUTDOWNZ=0*/
303                         write_dsihost_reg(DSIHOST_PHY_SHUTDOWNZ, res_val);
304                         vir_base = (unsigned long)ioremap(0xff910000, 0x10000);
305                         /*__raw_writel(0x60000, (void*)(0x1c00+vir_base));*/
306                         res_val = 0;
307                         res_val = read_dsihost_reg(DSIHOST_DPHY_RSTZ);
308                         res_val &= 0xfffffffd;
309                         /*RSTZ=0*/
310                         write_dsihost_reg(DSIHOST_DPHY_RSTZ, res_val);
311                         /*TESTCLK=1*/
312                         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
313                         /*TESTCLR=1 TESTCLK=1 */
314                         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000003);
315                         udelay(100);
316                         /*TESTCLR=0 TESTCLK=1*/
317                         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
318                         udelay(100);
319                         /*set clock lane*/
320                         camsys_rk3399_mipiphy1_wr_reg
321                                 (dsiphy_virt, 0x34, settle_bypass);
322                         /*HS hsfreqrange & lane 0  settle bypass*/
323                         camsys_rk3399_mipiphy1_wr_reg
324                                 (dsiphy_virt, 0x44, hsfreqrange | settle_bypass);
325                         camsys_rk3399_mipiphy1_wr_reg
326                                 (dsiphy_virt, 0x54, settle_bypass);
327                         camsys_rk3399_mipiphy1_wr_reg
328                                 (dsiphy_virt, 0x84, settle_bypass);
329                         camsys_rk3399_mipiphy1_wr_reg
330                                 (dsiphy_virt, 0x94, settle_bypass);
331                         camsys_rk3399_mipiphy1_wr_reg
332                                 (dsiphy_virt, 0x75, (settle_en << 7) | manu_hsfreqrange);
333                         camsys_rk3399_mipiphy1_rd_reg(dsiphy_virt, 0x75);
334                         /*TESTCLK=1*/
335                         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
336                         /*TESTEN =0*/
337                         write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, 0x00000000);
338                         /*SHUTDOWNZ=1*//*RSTZ=1*/
339                         /*__raw_writel(0x60f00, (void*)(0x1c00+vir_base));*/
340                         write_dsihost_reg(DSIHOST_DPHY_RSTZ, 0x00000002);
341                 }
342
343         } else {
344                 camsys_err("mipi phy index %d is invalidate!",
345                         para->phy->phy_index);
346                 goto fail;
347         }
348
349         camsys_trace(1, "mipi phy(%d) turn on(lane: 0x%x  bit_rate: %dMbps)",
350                 para->phy->phy_index, para->phy->data_en_bit,
351                 para->phy->bit_rate);
352
353         return 0;
354
355 fail:
356         return -1;
357 }
358
359 #define MRV_AFM_BASE            0x0000
360 #define VI_IRCL                 0x0014
361 int camsys_rk3399_cfg
362 (camsys_dev_t *camsys_dev, camsys_soc_cfg_t cfg_cmd, void *cfg_para)
363 {
364         unsigned int *para_int;
365
366         switch (cfg_cmd) {
367         case Clk_DriverStrength_Cfg: {
368                 para_int = (unsigned int *)cfg_para;
369                 __raw_writel((((*para_int) & 0x03) << 3) | (0x03 << 3),
370                 (void *)(camsys_dev->rk_grf_base + 0x204));
371                 /* set 0xffffffff to max all */
372                 break;
373         }
374
375         case Cif_IoDomain_Cfg: {
376                 para_int = (unsigned int *)cfg_para;
377                 if (*para_int < 28000000) {
378                         /* 1.8v IO */
379                         __raw_writel(((1 << 1) | (1 << (1 + 16))),
380                         (void *)(camsys_dev->rk_grf_base + 0x0900));
381                 } else {
382                         /* 3.3v IO */
383                         __raw_writel(((0 << 1) | (1 << (1 + 16))),
384                         (void *)(camsys_dev->rk_grf_base + 0x0900));
385                 }
386                 break;
387         }
388
389         case Mipi_Phy_Cfg: {
390                 camsys_rk3399_mipihpy_cfg
391                         ((camsys_mipiphy_soc_para_t *)cfg_para);
392                 break;
393         }
394
395         case Isp_SoftRst: /* ddl@rock-chips.com: v0.d.0 */ {
396                 unsigned long reset;
397                 reset = (unsigned long)cfg_para;
398
399                 if (reset == 1)
400                         __raw_writel(0x80, (void *)(camsys_dev->rk_isp_base +
401                         MRV_AFM_BASE + VI_IRCL));
402                 else
403                         __raw_writel(0x00, (void *)(camsys_dev->rk_isp_base +
404                         MRV_AFM_BASE + VI_IRCL));
405                 break;
406         }
407
408         default: {
409                 camsys_warn("cfg_cmd: 0x%x isn't support", cfg_cmd);
410                 break;
411         }
412
413         }
414
415         return 0;
416 }
417 #endif /* CONFIG_ARM64 */