2 *************************************************************************
3 * Rockchip driver for CIF ISP 1.0
4 * (Based on Intel driver for sofiaxxx)
6 * Copyright (C) 2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *************************************************************************
17 #include <linux/init.h>
18 #include <linux/delay.h>
19 #include <linux/regmap.h>
20 #include <linux/mfd/syscon.h>
21 #include <linux/clk.h>
22 #include <linux/reset.h>
25 #include <linux/kernel.h>
26 #include <linux/platform_device.h>
27 #include <linux/platform_data/rk_isp10_platform.h>
29 #define VI_IRCL 0x0014
30 #define MRV_MIPI_BASE 0x1C00
31 #define MRV_MIPI_CTRL 0x00
35 #define GRF_IO_VSEL_OFFSET (0x0900)
36 #define DVP_V18SEL ((1 << 1) | (1 << 17))
37 #define DVP_V33SEL ((0 << 1) | (1 << 17))
41 #define GRF_GPIO2B_E_OFFSET (0x0204)
42 #define CIF_CLKOUT_STRENGTH(a) \
43 ((((a) & 0x03) << 3) | (0x03 << 19))
44 #define GRF_SOC_STATUS1 (0x0e2a4)
46 #define GRF_SOC_CON9_OFFSET (0x6224)
47 #define DPHY_RX0_TURNREQUEST_MASK (0xF << 16)
48 #define DPHY_RX0_TURNREQUEST_BIT (0)
50 #define GRF_SOC_CON21_OFFSET (0x6254)
51 #define DPHY_RX0_FORCERXMODE_MASK (0xF << 20)
52 #define DPHY_RX0_FORCERXMODE_BIT (4)
53 #define DPHY_RX0_FORCETXSTOPMODE_MASK (0xF << 24)
54 #define DPHY_RX0_FORCETXSTOPMODE_BIT (8)
55 #define DPHY_RX0_TURNDISABLE_MASK (0xF << 28)
56 #define DPHY_RX0_TURNDISABLE_BIT (12)
57 #define DPHY_RX0_ENABLE_MASK (0xF << 16)
58 #define DPHY_RX0_ENABLE_BIT (0)
60 #define GRF_SOC_CON23_OFFSET (0x625c)
61 #define DPHY_TX1RX1_TURNDISABLE_MASK (0xF << 28)
62 #define DPHY_TX1RX1_TURNDISABLE_BIT (12)
63 #define DPHY_TX1RX1_FORCERXMODE_MASK (0xF << 20)
64 #define DPHY_TX1RX1_FORCERXMODE_BIT (4)
65 #define DPHY_TX1RX1_FORCETXSTOPMODE_MASK (0xF << 24)
66 #define DPHY_TX1RX1_FORCETXSTOPMODE_BIT (8)
67 #define DPHY_TX1RX1_ENABLE_MASK (0xF << 16)
68 #define DPHY_TX1RX1_ENABLE_BIT (0)
70 #define GRF_SOC_CON24_OFFSET (0x6260)
71 #define DPHY_TX1RX1_MASTERSLAVEZ_MASK (0x1 << 23)
72 #define DPHY_TX1RX1_MASTERSLAVEZ_BIT (7)
73 #define DPHY_TX1RX1_BASEDIR_MASK (0x1 << 21)
74 #define DPHY_TX1RX1_BASEDIR_BIT (5)
75 #define DPHY_RX1_MASK (0x1 << 20)
76 #define DPHY_RX1_SEL_BIT (4)
78 #define GRF_SOC_CON25_OFFSET (0x6264)
79 #define DPHY_RX0_TESTCLK_MASK (0x1 << 25)
80 #define DPHY_RX0_TESTCLK_BIT (9)
81 #define DPHY_RX0_TESTCLR_MASK (0x1 << 26)
82 #define DPHY_RX0_TESTCLR_BIT (10)
83 #define DPHY_RX0_TESTDIN_MASK (0xFF << 16)
84 #define DPHY_RX0_TESTDIN_BIT (0)
85 #define DPHY_RX0_TESTEN_MASK (0x1 << 24)
86 #define DPHY_RX0_TESTEN_BIT (8)
88 #define DPHY_TX1RX1_TURNREQUEST_MASK (0xF << 16)
89 #define DPHY_TX1RX1_TURNREQUEST_BIT (0)
91 #define DSIHOST_PHY_SHUTDOWNZ (0x00a0)
92 #define DSIHOST_DPHY_RSTZ (0x00a0)
93 #define DSIHOST_PHY_TEST_CTRL0 (0x00b4)
94 #define DSIHOST_PHY_TEST_CTRL1 (0x00b8)
96 #define write_cifisp_reg(addr, val) \
97 __raw_writel(val, (addr) + rk3399->isp_base)
98 #define read_cifisp_reg(addr) \
99 __raw_readl((addr) + rk3399->isp_base)
101 #define write_grf_reg(addr, val) \
102 regmap_write(rk3399->regmap_grf, addr, val)
103 #define read_grf_reg(addr, val) \
104 regmap_read(rk3399->regmap_grf, addr, val)
106 #define write_dsihost_reg(addr, val) \
107 __raw_writel(val, (addr) + rk3399->dsihost_base)
108 #define read_dsihost_reg(addr) \
109 __raw_readl((addr) + rk3399->dsihost_base)
111 struct cif_isp10_clk_rst_rk3399 {
112 struct clk *hclk_isp0_noc;
113 struct clk *hclk_isp0_wrapper;
114 struct clk *hclk_isp1_noc;
115 struct clk *hclk_isp1_wrapper;
116 struct clk *aclk_isp0_noc;
117 struct clk *aclk_isp0_wrapper;
118 struct clk *aclk_isp1_noc;
119 struct clk *aclk_isp1_wrapper;
120 struct clk *clk_isp0;
121 struct clk *clk_isp1;
122 struct clk *pclkin_isp1;
123 struct clk *pclk_dphy_ref;
124 struct clk *pclk_dphytxrx;
125 struct clk *pclk_dphyrx;
126 struct clk *cif_clk_out;
127 struct clk *cif_clk_pll;
128 struct clk *cif_clk_mipi_dsi;
129 struct clk *cif_clk_mipi_dphy_cfg;
132 struct cif_isp10_rk3399 {
133 struct regmap *regmap_grf;
134 void __iomem *dsihost_base;
135 void __iomem *isp_base;
136 struct cif_isp10_clk_rst_rk3399 clk_rst;
137 struct cif_isp10_device *cif_isp10;
140 struct mipi_dphy_hsfreqrange {
141 unsigned int range_l;
142 unsigned int range_h;
143 unsigned char cfg_bit;
146 static struct mipi_dphy_hsfreqrange mipi_dphy_hsfreq_range[] = {
187 static struct cif_isp10_rk3399 *rk3399;
188 static int mipi_dphy0_wr_reg(unsigned char addr, unsigned char data)
192 * TESTEN =1,TESTDIN=addr
195 write_grf_reg(GRF_SOC_CON25_OFFSET,
196 DPHY_RX0_TESTCLK_MASK | (1 << DPHY_RX0_TESTCLK_BIT));
197 write_grf_reg(GRF_SOC_CON25_OFFSET,
198 ((addr << DPHY_RX0_TESTDIN_BIT) | DPHY_RX0_TESTDIN_MASK
199 | (1 << DPHY_RX0_TESTEN_BIT) | DPHY_RX0_TESTEN_MASK));
200 write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK);
204 * TESTEN =0,TESTDIN=data
208 write_grf_reg(GRF_SOC_CON25_OFFSET,
209 ((data << DPHY_RX0_TESTDIN_BIT) |
210 DPHY_RX0_TESTDIN_MASK | DPHY_RX0_TESTEN_MASK));
211 write_grf_reg(GRF_SOC_CON25_OFFSET,
212 DPHY_RX0_TESTCLK_MASK | (1 << DPHY_RX0_TESTCLK_BIT));
217 static int mipi_dphy0_rd_reg(unsigned char addr)
221 write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK |
222 (1 << DPHY_RX0_TESTCLK_BIT));
223 /*TESTEN =1,TESTDIN=addr*/
224 write_grf_reg(GRF_SOC_CON25_OFFSET,
225 ((addr << DPHY_RX0_TESTDIN_BIT) |
226 DPHY_RX0_TESTDIN_MASK |
227 (1 << DPHY_RX0_TESTEN_BIT) |
228 DPHY_RX0_TESTEN_MASK));
230 write_grf_reg(GRF_SOC_CON25_OFFSET, DPHY_RX0_TESTCLK_MASK);
231 read_grf_reg(GRF_SOC_STATUS1, &val);
235 static int mipi_dphy1_wr_reg(unsigned char addr, unsigned char data)
238 * TESTEN =1,TESTDIN=addr
240 * TESTEN =0,TESTDIN=data
243 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
244 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000000);
245 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00000000 | data));
246 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
251 static int mipi_dphy1_rd_reg(unsigned char addr)
253 /* TESTEN =1,TESTDIN=addr */
254 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
256 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000000);
257 return (read_dsihost_reg(DSIHOST_PHY_TEST_CTRL1) >> 8);
260 static int mipi_dphy_cfg(struct pltfrm_cam_mipi_config *para)
262 unsigned char hsfreqrange = 0xff, i;
263 struct mipi_dphy_hsfreqrange *hsfreqrange_p;
264 unsigned char datalane_en, input_sel;
266 hsfreqrange_p = mipi_dphy_hsfreq_range;
268 i < (sizeof(mipi_dphy_hsfreq_range) /
269 sizeof(struct mipi_dphy_hsfreqrange));
271 if ((para->bit_rate > hsfreqrange_p->range_l) &&
272 (para->bit_rate <= hsfreqrange_p->range_h)) {
273 hsfreqrange = hsfreqrange_p->cfg_bit;
279 if (hsfreqrange == 0xff)
284 input_sel = para->dphy_index;
286 for (i = 0; i < para->nb_lanes; i++)
287 datalane_en |= (1 << i);
289 if (input_sel == 0) {
290 write_grf_reg(GRF_SOC_CON21_OFFSET,
291 DPHY_RX0_FORCERXMODE_MASK |
292 (0x0 << DPHY_RX0_FORCERXMODE_BIT) |
293 DPHY_RX0_FORCETXSTOPMODE_MASK |
294 (0x0 << DPHY_RX0_FORCETXSTOPMODE_BIT));
297 write_grf_reg(GRF_SOC_CON21_OFFSET,
298 DPHY_RX0_ENABLE_MASK |
299 (datalane_en << DPHY_RX0_ENABLE_BIT));
301 /* set lan turndisab as 1 */
302 write_grf_reg(GRF_SOC_CON21_OFFSET,
303 DPHY_RX0_TURNDISABLE_MASK |
304 (0xf << DPHY_RX0_TURNDISABLE_BIT));
305 write_grf_reg(GRF_SOC_CON21_OFFSET, (0x0 << 4) | (0xf << 20));
307 /* set lan turnrequest as 0 */
308 write_grf_reg(GRF_SOC_CON9_OFFSET,
309 DPHY_RX0_TURNREQUEST_MASK |
310 (0x0 << DPHY_RX0_TURNREQUEST_BIT));
319 write_grf_reg(GRF_SOC_CON25_OFFSET,
320 DPHY_RX0_TESTCLK_MASK |
321 (0x1 << DPHY_RX0_TESTCLK_BIT)); /* TESTCLK=1 */
322 write_grf_reg(GRF_SOC_CON25_OFFSET,
323 DPHY_RX0_TESTCLR_MASK |
324 (0x1 << DPHY_RX0_TESTCLR_BIT)); /* TESTCLR=1 */
325 usleep_range(100, 150);
327 write_grf_reg(GRF_SOC_CON25_OFFSET,
328 DPHY_RX0_TESTCLR_MASK);
329 usleep_range(100, 150);
334 /* HS hsfreqrange & lane 0 settle bypass */
335 mipi_dphy0_wr_reg(0x44, hsfreqrange);
336 mipi_dphy0_wr_reg(0x54, 0);
337 mipi_dphy0_wr_reg(0x84, 0);
338 mipi_dphy0_wr_reg(0x94, 0);
339 mipi_dphy0_wr_reg(0x75, 0x04);
340 mipi_dphy0_rd_reg(0x75);
342 /* Normal operation */
347 mipi_dphy0_wr_reg(0x0, -1);
348 write_grf_reg(GRF_SOC_CON25_OFFSET,
349 DPHY_RX0_TESTCLK_MASK | (1 << DPHY_RX0_TESTCLK_BIT));
350 write_grf_reg(GRF_SOC_CON25_OFFSET,
351 (DPHY_RX0_TESTEN_MASK));
353 write_cifisp_reg((MRV_MIPI_BASE + MRV_MIPI_CTRL),
354 read_cifisp_reg(MRV_MIPI_BASE + MRV_MIPI_CTRL)
357 } else if (input_sel == 1) {
358 write_grf_reg(GRF_SOC_CON23_OFFSET,
359 DPHY_RX0_FORCERXMODE_MASK |
360 (0x0 << DPHY_RX0_FORCERXMODE_BIT) |
361 DPHY_RX0_FORCETXSTOPMODE_MASK |
362 (0x0 << DPHY_RX0_FORCETXSTOPMODE_BIT));
363 write_grf_reg(GRF_SOC_CON24_OFFSET,
364 DPHY_TX1RX1_MASTERSLAVEZ_MASK |
365 (0x0 << DPHY_TX1RX1_MASTERSLAVEZ_BIT) |
366 DPHY_TX1RX1_BASEDIR_MASK |
367 (0x1 << DPHY_TX1RX1_BASEDIR_BIT) |
368 DPHY_RX1_MASK | 0x0 << DPHY_RX1_SEL_BIT);
371 write_grf_reg(GRF_SOC_CON23_OFFSET,
372 DPHY_TX1RX1_ENABLE_MASK |
373 (datalane_en << DPHY_TX1RX1_ENABLE_BIT));
375 /* set lan turndisab as 1 */
376 write_grf_reg(GRF_SOC_CON23_OFFSET,
377 DPHY_TX1RX1_TURNDISABLE_MASK |
378 (0xf << DPHY_TX1RX1_TURNDISABLE_BIT));
379 write_grf_reg(GRF_SOC_CON23_OFFSET, (0x0 << 4) | (0xf << 20));
381 /* set lan turnrequest as 0 */
382 write_grf_reg(GRF_SOC_CON24_OFFSET,
383 DPHY_TX1RX1_TURNREQUEST_MASK |
384 (0x0 << DPHY_TX1RX1_TURNREQUEST_BIT));
391 * TESTCLR=1 TESTCLK=1
392 * TESTCLR=0 TESTCLK=1
394 write_dsihost_reg(DSIHOST_PHY_SHUTDOWNZ, 0x00000000);
395 write_dsihost_reg(DSIHOST_DPHY_RSTZ, 0x00000000);
396 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
397 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, 0x00000003);
398 usleep_range(100, 150);
399 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
400 usleep_range(100, 150);
403 mipi_dphy1_wr_reg(0x34, 0x00);
404 mipi_dphy1_wr_reg(0x44, hsfreqrange);
405 mipi_dphy1_wr_reg(0x54, 0);
406 mipi_dphy1_wr_reg(0x84, 0);
407 mipi_dphy1_wr_reg(0x94, 0);
408 mipi_dphy1_wr_reg(0x75, 0x04);
410 mipi_dphy1_rd_reg(0x0);
417 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL0, 0x00000002);
418 write_dsihost_reg(DSIHOST_PHY_TEST_CTRL1, 0x00000000);
419 write_dsihost_reg(DSIHOST_PHY_SHUTDOWNZ, 0x00000001);
420 write_dsihost_reg(DSIHOST_DPHY_RSTZ, 0x00000001);
430 static int soc_clk_enable(void)
432 struct cif_isp10_clk_rst_rk3399 *clk_rst = &rk3399->clk_rst;
434 clk_prepare_enable(clk_rst->hclk_isp0_noc);
435 clk_prepare_enable(clk_rst->hclk_isp0_wrapper);
436 clk_prepare_enable(clk_rst->aclk_isp0_noc);
437 clk_prepare_enable(clk_rst->aclk_isp0_wrapper);
438 clk_prepare_enable(clk_rst->clk_isp0);
439 clk_prepare_enable(clk_rst->cif_clk_out);
440 clk_prepare_enable(clk_rst->pclk_dphyrx);
441 clk_prepare_enable(clk_rst->pclk_dphy_ref);
446 static int soc_clk_disable(void)
448 struct cif_isp10_clk_rst_rk3399 *clk_rst = &rk3399->clk_rst;
450 clk_disable_unprepare(clk_rst->hclk_isp0_noc);
451 clk_disable_unprepare(clk_rst->hclk_isp0_wrapper);
452 clk_disable_unprepare(clk_rst->aclk_isp0_noc);
453 clk_disable_unprepare(clk_rst->aclk_isp0_wrapper);
454 clk_disable_unprepare(clk_rst->clk_isp0);
455 clk_disable_unprepare(clk_rst->pclk_dphyrx);
456 clk_disable_unprepare(clk_rst->pclk_dphy_ref);
457 if (!IS_ERR_OR_NULL(clk_rst->cif_clk_pll)) {
458 clk_set_parent(clk_rst->cif_clk_out,
459 clk_rst->cif_clk_pll);
461 clk_disable_unprepare(clk_rst->cif_clk_out);
466 static int soc_init(struct pltfrm_soc_init_para *init)
468 struct cif_isp10_clk_rst_rk3399 *clk_rst;
469 struct platform_device *pdev = init->pdev;
470 struct device_node *np = pdev->dev.of_node, *node;
471 struct resource *res;
474 rk3399 = (struct cif_isp10_rk3399 *)devm_kzalloc(
476 sizeof(struct cif_isp10_rk3399),
479 dev_err(&pdev->dev, "Can't allocate cif_isp10_rk3399\n");
484 node = of_parse_phandle(np, "rockchip,grf", 0);
486 rk3399->regmap_grf = syscon_node_to_regmap(node);
487 if (IS_ERR(rk3399->regmap_grf)) {
488 dev_err(&pdev->dev, "Can't allocate cif_isp10_rk3399\n");
494 res = platform_get_resource_byname(pdev,
495 IORESOURCE_MEM, "dsihost-register");
498 "platform_get_resource_byname dsihost-register failed\n");
502 rk3399->dsihost_base = devm_ioremap_resource(&pdev->dev, res);
503 if (IS_ERR_OR_NULL(rk3399->dsihost_base)) {
504 dev_err(&pdev->dev, "devm_ioremap_resource failed\n");
505 if (IS_ERR(rk3399->dsihost_base))
506 err = PTR_ERR(rk3399->dsihost_base);
512 clk_rst = &rk3399->clk_rst;
514 clk_rst->hclk_isp0_noc =
515 devm_clk_get(&pdev->dev, "hclk_isp0_noc");
516 clk_rst->hclk_isp0_wrapper =
517 devm_clk_get(&pdev->dev, "hclk_isp0_wrapper");
518 clk_rst->aclk_isp0_noc =
519 devm_clk_get(&pdev->dev, "aclk_isp0_noc");
520 clk_rst->aclk_isp0_wrapper =
521 devm_clk_get(&pdev->dev, "aclk_isp0_wrapper");
523 devm_clk_get(&pdev->dev, "clk_isp0");
524 clk_rst->cif_clk_out =
525 devm_clk_get(&pdev->dev, "clk_cif_out");
526 clk_rst->cif_clk_pll =
527 devm_clk_get(&pdev->dev, "cif_clk_pll");
528 clk_rst->pclk_dphyrx =
529 devm_clk_get(&pdev->dev, "pclk_dphyrx");
530 clk_rst->pclk_dphy_ref =
531 devm_clk_get(&pdev->dev, "pclk_dphy_ref");
533 if (IS_ERR_OR_NULL(clk_rst->hclk_isp0_noc) ||
534 IS_ERR_OR_NULL(clk_rst->hclk_isp0_wrapper) ||
535 IS_ERR_OR_NULL(clk_rst->aclk_isp0_noc) ||
536 IS_ERR_OR_NULL(clk_rst->aclk_isp0_wrapper) ||
537 IS_ERR_OR_NULL(clk_rst->clk_isp0) ||
538 IS_ERR_OR_NULL(clk_rst->cif_clk_out) ||
539 IS_ERR_OR_NULL(clk_rst->pclk_dphy_ref) ||
540 IS_ERR_OR_NULL(clk_rst->pclk_dphyrx)) {
541 dev_err(&pdev->dev, "Get rk3399 cif isp10 clock resouce failed !\n");
546 clk_set_rate(clk_rst->clk_isp0, 420000000);
548 rk3399->isp_base = init->isp_base;
552 if (!IS_ERR_OR_NULL(clk_rst->hclk_isp0_noc))
553 devm_clk_put(&pdev->dev, clk_rst->hclk_isp0_noc);
555 if (!IS_ERR_OR_NULL(clk_rst->hclk_isp0_wrapper))
556 devm_clk_put(&pdev->dev, clk_rst->hclk_isp0_wrapper);
558 if (!IS_ERR_OR_NULL(clk_rst->aclk_isp0_noc))
559 devm_clk_put(&pdev->dev, clk_rst->aclk_isp0_noc);
561 if (!IS_ERR_OR_NULL(clk_rst->aclk_isp0_wrapper))
562 devm_clk_put(&pdev->dev, clk_rst->aclk_isp0_wrapper);
564 if (!IS_ERR_OR_NULL(clk_rst->clk_isp0))
565 devm_clk_put(&pdev->dev, clk_rst->clk_isp0);
567 if (!IS_ERR_OR_NULL(clk_rst->cif_clk_out))
568 devm_clk_put(&pdev->dev, clk_rst->cif_clk_out);
570 if (!IS_ERR_OR_NULL(clk_rst->cif_clk_pll))
571 devm_clk_put(&pdev->dev, clk_rst->cif_clk_pll);
573 if (!IS_ERR_OR_NULL(clk_rst->pclk_dphyrx))
574 devm_clk_put(&pdev->dev, clk_rst->pclk_dphyrx);
576 if (!IS_ERR_OR_NULL(clk_rst->pclk_dphy_ref))
577 devm_clk_put(&pdev->dev, clk_rst->pclk_dphy_ref);
586 int pltfrm_rk3399_cfg(
587 struct pltfrm_soc_cfg_para *cfg)
590 case PLTFRM_MCLK_CFG: {
591 struct pltfrm_soc_mclk_para *mclk_para;
593 mclk_para = (struct pltfrm_soc_mclk_para *)cfg->cfg_para;
594 if (mclk_para->io_voltage == PLTFRM_IO_1V8)
595 write_grf_reg(GRF_IO_VSEL_OFFSET, DVP_V18SEL);
597 write_grf_reg(GRF_IO_VSEL_OFFSET, DVP_V33SEL);
599 write_grf_reg(GRF_GPIO2B_E_OFFSET,
600 CIF_CLKOUT_STRENGTH(mclk_para->drv_strength));
603 case PLTFRM_MIPI_DPHY_CFG:
604 mipi_dphy_cfg((struct pltfrm_cam_mipi_config *)cfg->cfg_para);
616 write_cifisp_reg(VI_IRCL, 0x80);
617 usleep_range(10, 15);
618 write_cifisp_reg(VI_IRCL, 0x00);
621 case PLTFRM_SOC_INIT:
622 soc_init((struct pltfrm_soc_init_para *)cfg->cfg_para);