Lines Matching +full:csi +full:- +full:2
1 // SPDX-License-Identifier: GPL-2.0+
30 #include "rockchip-mipi-csi-tx.h"
45 #define PHY_ENABLECLK BIT(2)
74 #define INPUT_DIVIDER(val) (((val) - 1) & 0x7f)
77 #define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f)
78 #define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0x1f)
84 #define BIAS_BLOCK_ON BIT(2)
91 #define SETRD_MAX (0x7 << 2)
177 grf_field_write(struct rockchip_mipi_csi *csi, enum grf_reg_fields index, in grf_field_write() argument
180 const u32 field = csi->pdata->csi0_grf_reg_fields[index]; in grf_field_write()
184 if (!field || !csi->grf) in grf_field_write()
191 regmap_write(csi->grf, reg, (val << lsb) | (GENMASK(msb, lsb) << 16)); in grf_field_write()
194 static inline void csi_writel(struct rockchip_mipi_csi *csi, u32 offset, u32 v) in csi_writel() argument
196 writel(v, csi->regs + offset); in csi_writel()
197 csi->regsbak[offset >> 2] = v; in csi_writel()
200 static inline u32 csi_readl(struct rockchip_mipi_csi *csi, u32 offset) in csi_readl() argument
202 return readl(csi->regs + offset); in csi_readl()
205 static inline void csi_mask_write(struct rockchip_mipi_csi *csi, u32 offset, in csi_mask_write() argument
209 u32 cached_val = csi->regsbak[offset >> 2]; in csi_mask_write()
214 csi_writel(csi, offset, v); in csi_mask_write()
216 writel(v, csi->regs + offset); in csi_mask_write()
227 return -EINVAL; in phy_max_mbps_to_testdin()
246 static void rockchip_mipi_csi_phy_write(struct rockchip_mipi_csi *csi, in rockchip_mipi_csi_phy_write() argument
254 writel(0x01000100, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
256 csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
257 writel(0x02000200, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
258 writel(0x01000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
259 writel(0x02000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
260 writel(0x01000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
262 csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
263 writel(0x01000100, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_write()
267 rockchip_mipi_csi_phy_read(struct rockchip_mipi_csi *csi, u8 test_code) in rockchip_mipi_csi_phy_read() argument
272 csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_read()
273 writel(0x01000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_read()
275 val = readl(csi->test_code_regs + FPGA_DSI_PHY_TST_READ) & 0xff; in rockchip_mipi_csi_phy_read()
276 writel(0x03000100, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_mipi_csi_phy_read()
281 static void rockchip_bidir4l_board_phy_reset(struct rockchip_mipi_csi *csi) in rockchip_bidir4l_board_phy_reset() argument
283 writel(0x04000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
284 writel(0x08000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
285 writel(0x01000100, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
286 writel(0x80008000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
287 writel(0x80000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
288 writel(0x40004000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_reset()
291 static void rockchip_bidir4l_board_phy_enable(struct rockchip_mipi_csi *csi) in rockchip_bidir4l_board_phy_enable() argument
293 writel(0x01000100, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_enable()
294 writel(0x02000000, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_enable()
295 writel(0x08000800, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_enable()
296 writel(0x04000400, csi->test_code_regs + FPGA_DSI_PHY_TST_CTRL0); in rockchip_bidir4l_board_phy_enable()
299 static void rockchip_mipi_csi_irq_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_irq_init() argument
301 /* enable csi err irq */ in rockchip_mipi_csi_irq_init()
302 writel(m_ERR_INTR_EN | m_ERR_INTR_MASK, csi->regs + CSITX_ERR_INTR_EN); in rockchip_mipi_csi_irq_init()
304 /* disable csi frame end tx irq */ in rockchip_mipi_csi_irq_init()
305 writel(m_FRM_END_TX | v_FRM_END_TX(0), csi->regs + CSITX_INTR_EN); in rockchip_mipi_csi_irq_init()
308 static void rockchip_mipi_csi_irq_disable(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_irq_disable() argument
310 /* disable csi err irq */ in rockchip_mipi_csi_irq_disable()
311 writel(m_ERR_INTR_MASK, csi->regs + CSITX_ERR_INTR_EN); in rockchip_mipi_csi_irq_disable()
313 /* disable csi tx irq */ in rockchip_mipi_csi_irq_disable()
314 writel(m_INTR_MASK, csi->regs + CSITX_INTR_EN); in rockchip_mipi_csi_irq_disable()
317 static int rockchip_mipi_dphy_power_on(struct rockchip_mipi_csi *csi) in rockchip_mipi_dphy_power_on() argument
319 if (csi->dphy.phy) in rockchip_mipi_dphy_power_on()
320 phy_power_on(csi->dphy.phy); in rockchip_mipi_dphy_power_on()
327 static void rockchip_mipi_dphy_power_off(struct rockchip_mipi_csi *csi) in rockchip_mipi_dphy_power_off() argument
329 if (csi->dphy.phy) in rockchip_mipi_dphy_power_off()
330 phy_power_off(csi->dphy.phy); in rockchip_mipi_dphy_power_off()
333 static void rockchip_mipi_csi_tx_en(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_tx_en() argument
337 /* enable csi tx, dphy and config lane num */ in rockchip_mipi_csi_tx_en()
339 val = v_CSITX_EN(1) | v_DPHY_EN(1) | v_LANE_NUM(csi->lanes - 1); in rockchip_mipi_csi_tx_en()
340 csi_mask_write(csi, CSITX_ENABLE, mask, val, true); in rockchip_mipi_csi_tx_en()
343 static void rockchip_mipi_csi_host_power_on(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_host_power_on() argument
347 rockchip_mipi_csi_tx_en(csi); in rockchip_mipi_csi_host_power_on()
348 rockchip_mipi_csi_irq_init(csi); in rockchip_mipi_csi_host_power_on()
352 csi_mask_write(csi, CSITX_CONFIG_DONE, mask, val, false); in rockchip_mipi_csi_host_power_on()
355 static void rockchip_mipi_csi_host_power_off(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_host_power_off() argument
359 rockchip_mipi_csi_irq_disable(csi); in rockchip_mipi_csi_host_power_off()
361 /* disable csi tx, dphy and config lane num */ in rockchip_mipi_csi_host_power_off()
364 csi_mask_write(csi, CSITX_ENABLE, mask, val, true); in rockchip_mipi_csi_host_power_off()
365 csi_mask_write(csi, CSITX_CONFIG_DONE, m_CONFIG_DONE, in rockchip_mipi_csi_host_power_off()
369 static void rockchip_mipi_csi_phy_pll_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_phy_pll_init() argument
371 rockchip_mipi_csi_phy_write(csi, 0x17, in rockchip_mipi_csi_phy_pll_init()
372 INPUT_DIVIDER(csi->dphy.input_div)); in rockchip_mipi_csi_phy_pll_init()
373 rockchip_mipi_csi_phy_write(csi, 0x18, in rockchip_mipi_csi_phy_pll_init()
374 LOOP_DIV_LOW_SEL(csi->dphy.feedback_div) | in rockchip_mipi_csi_phy_pll_init()
376 rockchip_mipi_csi_phy_write(csi, 0x19, in rockchip_mipi_csi_phy_pll_init()
378 rockchip_mipi_csi_phy_write(csi, 0x18, in rockchip_mipi_csi_phy_pll_init()
379 LOOP_DIV_HIGH_SEL(csi->dphy.feedback_div) | in rockchip_mipi_csi_phy_pll_init()
381 rockchip_mipi_csi_phy_write(csi, 0x19, in rockchip_mipi_csi_phy_pll_init()
386 rockchip_mipi_csi_phy_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_phy_init() argument
390 vco = (csi->lane_mbps < 200) ? 0 : (csi->lane_mbps + 100) / 200; in rockchip_mipi_csi_phy_init()
392 testdin = phy_max_mbps_to_testdin(csi->lane_mbps); in rockchip_mipi_csi_phy_init()
394 dev_err(csi->dev, in rockchip_mipi_csi_phy_init()
396 csi->lane_mbps); in rockchip_mipi_csi_phy_init()
400 rockchip_mipi_csi_phy_write(csi, 0xb0, 0x01); in rockchip_mipi_csi_phy_init()
401 rockchip_mipi_csi_phy_write(csi, 0xac, csi->lanes - 1); in rockchip_mipi_csi_phy_init()
402 rockchip_mipi_csi_phy_write(csi, 0xb1, 0x00); in rockchip_mipi_csi_phy_init()
403 rockchip_mipi_csi_phy_write(csi, 0xb2, 0x00); in rockchip_mipi_csi_phy_init()
404 rockchip_mipi_csi_phy_write(csi, 0xb3, 0x00); in rockchip_mipi_csi_phy_init()
405 rockchip_mipi_csi_phy_write(csi, 0x10, BYPASS_VCO_RANGE | in rockchip_mipi_csi_phy_init()
410 rockchip_mipi_csi_phy_write(csi, 0x11, CP_CURRENT_3MA); in rockchip_mipi_csi_phy_init()
411 rockchip_mipi_csi_phy_write(csi, 0x12, CP_PROGRAM_EN | LPF_PROGRAM_EN | in rockchip_mipi_csi_phy_init()
414 rockchip_mipi_csi_phy_write(csi, 0x44, HSFREQRANGE_SEL(testdin)); in rockchip_mipi_csi_phy_init()
416 rockchip_mipi_csi_phy_pll_init(csi); in rockchip_mipi_csi_phy_init()
418 rockchip_mipi_csi_phy_write(csi, 0x20, POWER_CONTROL | in rockchip_mipi_csi_phy_init()
422 rockchip_mipi_csi_phy_write(csi, 0x21, TER_RESISTOR_LOW | TER_CAL_DONE | in rockchip_mipi_csi_phy_init()
424 rockchip_mipi_csi_phy_write(csi, 0x21, TER_RESISTOR_HIGH | in rockchip_mipi_csi_phy_init()
428 rockchip_mipi_csi_phy_write(csi, 0x22, LOW_PROGRAM_EN | in rockchip_mipi_csi_phy_init()
430 rockchip_mipi_csi_phy_write(csi, 0x22, HIGH_PROGRAM_EN | in rockchip_mipi_csi_phy_init()
433 rockchip_mipi_csi_phy_write(csi, 0x70, TLP_PROGRAM_EN | 0xf); in rockchip_mipi_csi_phy_init()
434 rockchip_mipi_csi_phy_write(csi, 0x71, THS_PRE_PROGRAM_EN | 0x2d); in rockchip_mipi_csi_phy_init()
435 rockchip_mipi_csi_phy_write(csi, 0x72, THS_ZERO_PROGRAM_EN | 0xa); in rockchip_mipi_csi_phy_init()
441 * mipi_csi_pixel_format_to_bpp - obtain the number of bits per pixel for any
442 * given pixel format defined by the MIPI CSI
444 * @fmt: MIPI CSI pixel format
456 pr_info("mipi csi unsupported format: %d\n", fmt); in mipi_csi_pixel_format_to_bpp()
460 return -EINVAL; in mipi_csi_pixel_format_to_bpp()
464 rockchip_mipi_csi_calc_bandwidth(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_calc_bandwidth() argument
470 struct device_node *np = csi->dev->of_node; in rockchip_mipi_csi_calc_bandwidth()
475 if (!of_property_read_u32(np, "rockchip,lane-rate", &value)) in rockchip_mipi_csi_calc_bandwidth()
478 max_mbps = csi->pdata->max_bit_rate_per_lane / USEC_PER_SEC; in rockchip_mipi_csi_calc_bandwidth()
480 bpp = mipi_csi_pixel_format_to_bpp(csi->format); in rockchip_mipi_csi_calc_bandwidth()
482 dev_err(csi->dev, "failed to get bpp for pixel format %d\n", in rockchip_mipi_csi_calc_bandwidth()
483 csi->format); in rockchip_mipi_csi_calc_bandwidth()
487 lanes = csi->lanes; in rockchip_mipi_csi_calc_bandwidth()
489 mpclk = DIV_ROUND_UP(csi->mode.clock, MSEC_PER_SEC); in rockchip_mipi_csi_calc_bandwidth()
498 dev_err(csi->dev, "DPHY clock freq is out of range\n"); in rockchip_mipi_csi_calc_bandwidth()
504 static int rockchip_mipi_csi_get_lane_bps(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_get_lane_bps() argument
511 target_mbps = rockchip_mipi_csi_calc_bandwidth(csi); in rockchip_mipi_csi_get_lane_bps()
515 pllref = DIV_ROUND_UP(clk_get_rate(csi->dphy.ref_clk), USEC_PER_SEC); in rockchip_mipi_csi_get_lane_bps()
530 csi->lane_mbps = pllref / n * m; in rockchip_mipi_csi_get_lane_bps()
531 csi->dphy.input_div = n; in rockchip_mipi_csi_get_lane_bps()
532 csi->dphy.feedback_div = m; in rockchip_mipi_csi_get_lane_bps()
537 static void rockchip_mipi_csi_set_hs_clk(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_set_hs_clk() argument
543 target_mbps = rockchip_mipi_csi_calc_bandwidth(csi); in rockchip_mipi_csi_set_hs_clk()
546 rate = clk_round_rate(csi->dphy.hs_clk, bw); in rockchip_mipi_csi_set_hs_clk()
547 ret = clk_set_rate(csi->dphy.hs_clk, rate); in rockchip_mipi_csi_set_hs_clk()
549 dev_err(csi->dev, "failed to set hs clock rate: %lu\n", in rockchip_mipi_csi_set_hs_clk()
552 csi->lane_mbps = rate / USEC_PER_SEC; in rockchip_mipi_csi_set_hs_clk()
558 struct rockchip_mipi_csi *csi = host_to_csi(host); in rockchip_mipi_csi_host_attach() local
560 if (device->lanes == 0 || device->lanes > 8) { in rockchip_mipi_csi_host_attach()
561 dev_err(csi->dev, "the number of data lanes(%u) is too many\n", in rockchip_mipi_csi_host_attach()
562 device->lanes); in rockchip_mipi_csi_host_attach()
563 return -EINVAL; in rockchip_mipi_csi_host_attach()
565 csi->client = device->dev.of_node; in rockchip_mipi_csi_host_attach()
566 csi->lanes = device->lanes; in rockchip_mipi_csi_host_attach()
567 csi->channel = device->channel; in rockchip_mipi_csi_host_attach()
568 csi->format = device->format; in rockchip_mipi_csi_host_attach()
569 csi->mode_flags = device->mode_flags; in rockchip_mipi_csi_host_attach()
577 struct rockchip_mipi_csi *csi = host_to_csi(host); in rockchip_mipi_csi_host_detach() local
579 if (csi->panel) in rockchip_mipi_csi_host_detach()
580 drm_panel_detach(csi->panel); in rockchip_mipi_csi_host_detach()
582 csi->panel = NULL; in rockchip_mipi_csi_host_detach()
591 static void rockchip_mipi_csi_path_config(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_path_config() argument
597 switch (csi->format) { in rockchip_mipi_csi_path_config()
599 vop_wc = csi->mode.hdisplay; in rockchip_mipi_csi_path_config()
603 vop_wc = csi->mode.hdisplay * 5 / 4; in rockchip_mipi_csi_path_config()
607 vop_wc = csi->mode.hdisplay; in rockchip_mipi_csi_path_config()
612 if (csi->path_mode == VOP_PATH) { in rockchip_mipi_csi_path_config()
616 csi_mask_write(csi, CSITX_SYS_CTRL1, mask, val, true); in rockchip_mipi_csi_path_config()
628 csi_mask_write(csi, CSITX_VOP_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_path_config()
633 csi_mask_write(csi, CSITX_BYPASS_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_path_config()
638 csi_mask_write(csi, CSITX_SYS_CTRL1, mask, val, true); in rockchip_mipi_csi_path_config()
647 csi_mask_write(csi, CSITX_VOP_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_path_config()
652 csi_mask_write(csi, CSITX_BYPASS_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_path_config()
657 csi_mask_write(csi, CSITX_ENABLE, mask, val, true); in rockchip_mipi_csi_path_config()
661 static void rockchip_mipi_csi_video_mode_config(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_video_mode_config() argument
665 if (csi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { in rockchip_mipi_csi_video_mode_config()
673 csi_mask_write(csi, CSITX_SYS_CTRL3, mask, val, true); in rockchip_mipi_csi_video_mode_config()
676 static void rockchip_mipi_dphy_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_dphy_init() argument
681 grf_field_write(csi, DPHY_SEL, 0); in rockchip_mipi_dphy_init()
684 grf_field_write(csi, MASTERSLAVEZ, 1); in rockchip_mipi_dphy_init()
687 grf_field_write(csi, BASEDIR, 0); in rockchip_mipi_dphy_init()
690 grf_field_write(csi, TURNREQUEST, 0); in rockchip_mipi_dphy_init()
691 grf_field_write(csi, TURNDISABLE, 0); in rockchip_mipi_dphy_init()
692 grf_field_write(csi, FORCETXSTOPMODE, 0); in rockchip_mipi_dphy_init()
693 grf_field_write(csi, FORCERXMODE, 0); in rockchip_mipi_dphy_init()
696 grf_field_write(csi, ENABLE_N, map[csi->lanes - 1]); in rockchip_mipi_dphy_init()
699 grf_field_write(csi, ENABLECLK, 1); in rockchip_mipi_dphy_init()
700 if (!csi->dphy.phy) { in rockchip_mipi_dphy_init()
702 rockchip_bidir4l_board_phy_reset(csi); in rockchip_mipi_dphy_init()
706 rockchip_mipi_csi_phy_write(csi, 0xb0, 0x01); in rockchip_mipi_dphy_init()
707 rockchip_mipi_csi_phy_write(csi, 0xac, csi->lanes - 1); in rockchip_mipi_dphy_init()
709 rockchip_mipi_csi_phy_write(csi, 0x44, 0x0a);/* fpga:324Mbps */ in rockchip_mipi_dphy_init()
710 rockchip_mipi_csi_phy_write(csi, 0x19, 0x30); in rockchip_mipi_dphy_init()
711 rockchip_mipi_csi_phy_write(csi, 0x17, 0x00); in rockchip_mipi_dphy_init()
712 rockchip_mipi_csi_phy_write(csi, 0x18, 0xb); in rockchip_mipi_dphy_init()
713 rockchip_mipi_csi_phy_write(csi, 0x18, 0x80); in rockchip_mipi_dphy_init()
715 rockchip_mipi_csi_phy_write(csi, 0x10, 0x80); in rockchip_mipi_dphy_init()
716 rockchip_mipi_csi_phy_write(csi, 0x11, 0x09); in rockchip_mipi_dphy_init()
717 rockchip_mipi_csi_phy_write(csi, 0x12, 0xc2); in rockchip_mipi_dphy_init()
719 rockchip_mipi_csi_phy_init(csi); in rockchip_mipi_dphy_init()
722 rockchip_bidir4l_board_phy_enable(csi); in rockchip_mipi_dphy_init()
727 static void rockchip_mipi_csi_fmt_config(struct rockchip_mipi_csi *csi, in rockchip_mipi_csi_fmt_config() argument
733 val = v_PIXEL_FORMAT(csi->format); in rockchip_mipi_csi_fmt_config()
734 csi_mask_write(csi, CSITX_VOP_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_fmt_config()
737 val = v_CAM_FORMAT(csi->format); in rockchip_mipi_csi_fmt_config()
738 csi_mask_write(csi, CSITX_BYPASS_PATH_CTRL, mask, val, true); in rockchip_mipi_csi_fmt_config()
746 struct rockchip_mipi_csi *csi = encoder_to_csi(encoder); in rockchip_mipi_csi_encoder_mode_set() local
748 drm_mode_copy(&csi->mode, adjusted_mode); in rockchip_mipi_csi_encoder_mode_set()
751 static void rockchip_mipi_csi_post_disable(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_post_disable() argument
753 rockchip_mipi_csi_host_power_off(csi); in rockchip_mipi_csi_post_disable()
754 rockchip_mipi_dphy_power_off(csi); in rockchip_mipi_csi_post_disable()
756 pm_runtime_put(csi->dev); in rockchip_mipi_csi_post_disable()
757 clk_disable_unprepare(csi->pclk); in rockchip_mipi_csi_post_disable()
758 clk_disable_unprepare(csi->dphy.hs_clk); in rockchip_mipi_csi_post_disable()
759 clk_disable_unprepare(csi->dphy.ref_clk); in rockchip_mipi_csi_post_disable()
764 struct rockchip_mipi_csi *csi = encoder_to_csi(encoder); in rockchip_mipi_csi_encoder_disable() local
766 if (csi->panel) in rockchip_mipi_csi_encoder_disable()
767 drm_panel_disable(csi->panel); in rockchip_mipi_csi_encoder_disable()
769 if (csi->panel) in rockchip_mipi_csi_encoder_disable()
770 drm_panel_unprepare(csi->panel); in rockchip_mipi_csi_encoder_disable()
772 rockchip_mipi_csi_post_disable(csi); in rockchip_mipi_csi_encoder_disable()
783 static void rockchip_mipi_csi_pre_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_pre_init() argument
785 if (csi->dphy.phy) in rockchip_mipi_csi_pre_init()
786 rockchip_mipi_csi_set_hs_clk(csi); in rockchip_mipi_csi_pre_init()
788 rockchip_mipi_csi_get_lane_bps(csi); in rockchip_mipi_csi_pre_init()
790 dev_info(csi->dev, "final CSI-Link bandwidth: %u x %d Mbps\n", in rockchip_mipi_csi_pre_init()
791 csi->lane_mbps, csi->lanes); in rockchip_mipi_csi_pre_init()
794 static void rockchip_mipi_csihost_enable_phy(struct rockchip_mipi_csi *csi) in rockchip_mipi_csihost_enable_phy() argument
800 val = v_CSITX_ENABLE_PHY(map[csi->lanes - 1]); in rockchip_mipi_csihost_enable_phy()
801 csi_mask_write(csi, CSITX_DPHY_CTRL, mask, val, true); in rockchip_mipi_csihost_enable_phy()
804 static void rockchip_mipi_csi_host_init(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_host_init() argument
806 rockchip_mipi_csi_fmt_config(csi, &csi->mode); in rockchip_mipi_csi_host_init()
807 rockchip_mipi_csi_video_mode_config(csi); in rockchip_mipi_csi_host_init()
808 rockchip_mipi_csi_path_config(csi); in rockchip_mipi_csi_host_init()
809 rockchip_mipi_csihost_enable_phy(csi); in rockchip_mipi_csi_host_init()
814 static int rockchip_mipi_csi_calibration(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_calibration() argument
820 grf_field_write(csi, TXSKEWCALHS, 0x1f); in rockchip_mipi_csi_calibration()
822 grf_field_write(csi, TXSKEWCALHS, 0x0); in rockchip_mipi_csi_calibration()
824 ret = readl_poll_timeout(csi->regs + CSITX_STATUS1, in rockchip_mipi_csi_calibration()
828 dev_err(csi->dev, "PHY is not locked\n"); in rockchip_mipi_csi_calibration()
833 ret = readl_poll_timeout(csi->regs + CSITX_STATUS1, in rockchip_mipi_csi_calibration()
837 dev_err(csi->dev, "lane module is not in stop state\n"); in rockchip_mipi_csi_calibration()
845 static int rockchip_mipi_csi_pre_enable(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_pre_enable() argument
849 rockchip_mipi_csi_pre_init(csi); in rockchip_mipi_csi_pre_enable()
850 clk_prepare_enable(csi->dphy.ref_clk); in rockchip_mipi_csi_pre_enable()
851 clk_prepare_enable(csi->dphy.hs_clk); in rockchip_mipi_csi_pre_enable()
852 clk_prepare_enable(csi->pclk); in rockchip_mipi_csi_pre_enable()
853 pm_runtime_get_sync(csi->dev); in rockchip_mipi_csi_pre_enable()
855 /* MIPI CSI TX software reset request. */ in rockchip_mipi_csi_pre_enable()
856 for (i = 0; i < csi->pdata->rsts_num; i++) { in rockchip_mipi_csi_pre_enable()
857 if (csi->tx_rsts[i]) in rockchip_mipi_csi_pre_enable()
858 reset_control_assert(csi->tx_rsts[i]); in rockchip_mipi_csi_pre_enable()
861 for (i = 0; i < csi->pdata->rsts_num; i++) { in rockchip_mipi_csi_pre_enable()
862 if (csi->tx_rsts[i]) in rockchip_mipi_csi_pre_enable()
863 reset_control_deassert(csi->tx_rsts[i]); in rockchip_mipi_csi_pre_enable()
866 if (!csi->regsbak) { in rockchip_mipi_csi_pre_enable()
867 csi->regsbak = in rockchip_mipi_csi_pre_enable()
868 devm_kzalloc(csi->dev, csi->regs_len, GFP_KERNEL); in rockchip_mipi_csi_pre_enable()
870 if (!csi->regsbak) in rockchip_mipi_csi_pre_enable()
871 return -ENOMEM; in rockchip_mipi_csi_pre_enable()
873 memcpy(csi->regsbak, csi->regs, csi->regs_len); in rockchip_mipi_csi_pre_enable()
876 rockchip_mipi_csi_host_init(csi); in rockchip_mipi_csi_pre_enable()
877 rockchip_mipi_dphy_init(csi); in rockchip_mipi_csi_pre_enable()
878 rockchip_mipi_dphy_power_on(csi); in rockchip_mipi_csi_pre_enable()
879 rockchip_mipi_csi_calibration(csi); in rockchip_mipi_csi_pre_enable()
880 rockchip_mipi_csi_host_power_on(csi); in rockchip_mipi_csi_pre_enable()
887 struct rockchip_mipi_csi *csi = encoder_to_csi(encoder); in rockchip_mipi_csi_encoder_enable() local
889 rockchip_mipi_csi_pre_enable(csi); in rockchip_mipi_csi_encoder_enable()
891 if (csi->panel) in rockchip_mipi_csi_encoder_enable()
892 drm_panel_prepare(csi->panel); in rockchip_mipi_csi_encoder_enable()
894 if (csi->panel) in rockchip_mipi_csi_encoder_enable()
895 drm_panel_enable(csi->panel); in rockchip_mipi_csi_encoder_enable()
904 struct rockchip_mipi_csi *csi = encoder_to_csi(encoder); in rockchip_mipi_csi_encoder_atomic_check() local
905 struct drm_connector *connector = conn_state->connector; in rockchip_mipi_csi_encoder_atomic_check()
906 struct drm_display_info *info = &connector->display_info; in rockchip_mipi_csi_encoder_atomic_check()
908 switch (csi->format) { in rockchip_mipi_csi_encoder_atomic_check()
910 s->output_mode = ROCKCHIP_OUT_MODE_P888; in rockchip_mipi_csi_encoder_atomic_check()
913 s->output_mode = ROCKCHIP_OUT_MODE_P666; in rockchip_mipi_csi_encoder_atomic_check()
917 s->output_mode = ROCKCHIP_OUT_MODE_P888; in rockchip_mipi_csi_encoder_atomic_check()
921 s->output_type = DRM_MODE_CONNECTOR_DSI; in rockchip_mipi_csi_encoder_atomic_check()
922 if (info->num_bus_formats) in rockchip_mipi_csi_encoder_atomic_check()
923 s->bus_format = info->bus_formats[0]; in rockchip_mipi_csi_encoder_atomic_check()
925 s->bus_format = MEDIA_BUS_FMT_RGB888_1X24; in rockchip_mipi_csi_encoder_atomic_check()
926 s->tv_state = &conn_state->tv; in rockchip_mipi_csi_encoder_atomic_check()
927 s->eotf = TRADITIONAL_GAMMA_SDR; in rockchip_mipi_csi_encoder_atomic_check()
928 s->color_space = V4L2_COLORSPACE_DEFAULT; in rockchip_mipi_csi_encoder_atomic_check()
949 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_csi_connector_get_modes() local
951 return drm_panel_get_modes(csi->panel); in rockchip_mipi_csi_connector_get_modes()
957 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_csi_connector_best_encoder() local
959 return &csi->encoder; in rockchip_mipi_csi_connector_best_encoder()
965 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_loader_protect() local
967 if (csi->panel) in rockchip_mipi_loader_protect()
968 drm_panel_loader_protect(csi->panel, on); in rockchip_mipi_loader_protect()
970 pm_runtime_get_sync(csi->dev); in rockchip_mipi_loader_protect()
971 if (!csi->regsbak) { in rockchip_mipi_loader_protect()
972 csi->regsbak = devm_kzalloc(csi->dev, csi->regs_len, in rockchip_mipi_loader_protect()
974 if (!csi->regsbak) in rockchip_mipi_loader_protect()
975 return -ENOMEM; in rockchip_mipi_loader_protect()
976 memcpy(csi->regsbak, csi->regs, csi->regs_len); in rockchip_mipi_loader_protect()
979 pm_runtime_put(csi->dev); in rockchip_mipi_loader_protect()
988 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_csi_connector_atomic_flush() local
991 rockchip_mipi_csi_path_config(csi); in rockchip_mipi_csi_connector_atomic_flush()
994 csi_mask_write(csi, CSITX_CONFIG_DONE, mask, val, false); in rockchip_mipi_csi_connector_atomic_flush()
1024 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_csi_connector_set_property() local
1026 if (property == csi->csi_tx_path_property) { in rockchip_mipi_csi_connector_set_property()
1028 * csi->path_mode = val; in rockchip_mipi_csi_connector_set_property()
1034 DRM_ERROR("failed to set mipi csi tx cproperty\n"); in rockchip_mipi_csi_connector_set_property()
1035 return -EINVAL; in rockchip_mipi_csi_connector_set_property()
1044 struct rockchip_mipi_csi *csi = con_to_csi(connector); in rockchip_mipi_csi_connector_get_property() local
1046 if (property == csi->csi_tx_path_property) { in rockchip_mipi_csi_connector_get_property()
1047 *val = csi->path_mode; in rockchip_mipi_csi_connector_get_property()
1051 DRM_ERROR("failed to get mipi csi tx cproperty\n"); in rockchip_mipi_csi_connector_get_property()
1052 return -EINVAL; in rockchip_mipi_csi_connector_get_property()
1068 static int rockchip_mipi_csi_property_create(struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_property_create() argument
1072 prop = drm_property_create_range(csi->connector.dev, 0, in rockchip_mipi_csi_property_create()
1073 "CSI-TX-PATH", in rockchip_mipi_csi_property_create()
1076 csi->csi_tx_path_property = prop; in rockchip_mipi_csi_property_create()
1077 drm_object_attach_property(&csi->connector.base, prop, 0); in rockchip_mipi_csi_property_create()
1084 struct rockchip_mipi_csi *csi) in rockchip_mipi_csi_register() argument
1086 struct drm_encoder *encoder = &csi->encoder; in rockchip_mipi_csi_register()
1087 struct drm_connector *connector = &csi->connector; in rockchip_mipi_csi_register()
1088 struct device *dev = csi->dev; in rockchip_mipi_csi_register()
1091 encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, in rockchip_mipi_csi_register()
1092 dev->of_node); in rockchip_mipi_csi_register()
1099 if (encoder->possible_crtcs == 0) in rockchip_mipi_csi_register()
1100 return -EPROBE_DEFER; in rockchip_mipi_csi_register()
1102 drm_encoder_helper_add(&csi->encoder, in rockchip_mipi_csi_register()
1104 ret = drm_encoder_init(drm, &csi->encoder, in rockchip_mipi_csi_register()
1112 csi->connector.port = dev->of_node; in rockchip_mipi_csi_register()
1113 ret = drm_connector_init(drm, &csi->connector, in rockchip_mipi_csi_register()
1126 ret = drm_panel_attach(csi->panel, &csi->connector); in rockchip_mipi_csi_register()
1144 struct rockchip_mipi_csi *csi = dev_get_drvdata(dev); in rockchip_mipi_csi_bind() local
1147 csi->panel = of_drm_find_panel(csi->client); in rockchip_mipi_csi_bind()
1148 if (!csi->panel) { in rockchip_mipi_csi_bind()
1150 return -EPROBE_DEFER; in rockchip_mipi_csi_bind()
1153 ret = rockchip_mipi_csi_register(drm, csi); in rockchip_mipi_csi_bind()
1159 rockchip_mipi_csi_property_create(csi); in rockchip_mipi_csi_bind()
1178 struct rockchip_mipi_csi *csi = data; in rockchip_mipi_csi_irq_handler() local
1182 int_status = csi_readl(csi, CSITX_INTR_STATUS); in rockchip_mipi_csi_irq_handler()
1183 err_int_status = csi_readl(csi, CSITX_ERR_INTR_STATUS); in rockchip_mipi_csi_irq_handler()
1187 DRM_DEV_ERROR_RATELIMITED(csi->dev, "%s\n", in rockchip_mipi_csi_irq_handler()
1192 DRM_DEV_ERROR_RATELIMITED(csi->dev, "%s\n", in rockchip_mipi_csi_irq_handler()
1194 writel(int_status | m_INTR_MASK, csi->regs + CSITX_INTR_CLR); in rockchip_mipi_csi_irq_handler()
1196 csi->regs + CSITX_ERR_INTR_CLR); in rockchip_mipi_csi_irq_handler()
1201 static int rockchip_mipi_dphy_attach(struct rockchip_mipi_csi *csi) in rockchip_mipi_dphy_attach() argument
1203 struct device *dev = csi->dev; in rockchip_mipi_dphy_attach()
1206 csi->dphy.phy = devm_phy_optional_get(dev, "mipi_dphy"); in rockchip_mipi_dphy_attach()
1207 if (IS_ERR(csi->dphy.phy)) { in rockchip_mipi_dphy_attach()
1208 ret = PTR_ERR(csi->dphy.phy); in rockchip_mipi_dphy_attach()
1213 if (csi->dphy.phy) { in rockchip_mipi_dphy_attach()
1214 dev_dbg(dev, "Use Non-SNPS PHY\n"); in rockchip_mipi_dphy_attach()
1216 csi->dphy.hs_clk = devm_clk_get(dev, "hs_clk"); in rockchip_mipi_dphy_attach()
1217 if (IS_ERR(csi->dphy.hs_clk)) { in rockchip_mipi_dphy_attach()
1218 dev_err(dev, "failed to get PHY high-speed clock\n"); in rockchip_mipi_dphy_attach()
1219 return PTR_ERR(csi->dphy.hs_clk); in rockchip_mipi_dphy_attach()
1223 csi->dphy.ref_clk = devm_clk_get(dev, "ref"); in rockchip_mipi_dphy_attach()
1224 if (IS_ERR(csi->dphy.ref_clk)) { in rockchip_mipi_dphy_attach()
1226 return PTR_ERR(csi->dphy.ref_clk); in rockchip_mipi_dphy_attach()
1233 static int dw_mipi_csi_parse_dt(struct rockchip_mipi_csi *csi) in dw_mipi_csi_parse_dt() argument
1235 struct device *dev = csi->dev; in dw_mipi_csi_parse_dt()
1236 struct device_node *np = dev->of_node; in dw_mipi_csi_parse_dt()
1239 endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); in dw_mipi_csi_parse_dt()
1246 return -ENODEV; in dw_mipi_csi_parse_dt()
1251 csi->client = remote; in dw_mipi_csi_parse_dt()
1258 struct device *dev = &pdev->dev; in rockchip_mipi_csi_probe()
1259 struct rockchip_mipi_csi *csi; in rockchip_mipi_csi_probe() local
1260 struct device_node *np = dev->of_node; in rockchip_mipi_csi_probe()
1264 csi = devm_kzalloc(dev, sizeof(*csi), GFP_KERNEL); in rockchip_mipi_csi_probe()
1265 if (!csi) in rockchip_mipi_csi_probe()
1266 return -ENOMEM; in rockchip_mipi_csi_probe()
1268 csi->dev = dev; in rockchip_mipi_csi_probe()
1269 csi->pdata = of_device_get_match_data(dev); in rockchip_mipi_csi_probe()
1270 platform_set_drvdata(pdev, csi); in rockchip_mipi_csi_probe()
1272 ret = dw_mipi_csi_parse_dt(csi); in rockchip_mipi_csi_probe()
1279 csi->regs = devm_ioremap_resource(dev, res); in rockchip_mipi_csi_probe()
1280 if (IS_ERR(csi->regs)) in rockchip_mipi_csi_probe()
1281 return PTR_ERR(csi->regs); in rockchip_mipi_csi_probe()
1282 csi->regs_len = resource_size(res); in rockchip_mipi_csi_probe()
1283 csi->regsbak = NULL; in rockchip_mipi_csi_probe()
1288 csi->test_code_regs = devm_ioremap_resource(dev, res); in rockchip_mipi_csi_probe()
1289 if (IS_ERR(csi->test_code_regs)) in rockchip_mipi_csi_probe()
1293 csi->irq = platform_get_irq(pdev, 0); in rockchip_mipi_csi_probe()
1294 if (csi->irq < 0) { in rockchip_mipi_csi_probe()
1295 dev_err(dev, "Failed to ger csi tx irq\n"); in rockchip_mipi_csi_probe()
1296 return -EINVAL; in rockchip_mipi_csi_probe()
1299 csi->pclk = devm_clk_get(dev, "pclk"); in rockchip_mipi_csi_probe()
1300 if (IS_ERR(csi->pclk)) { in rockchip_mipi_csi_probe()
1301 ret = PTR_ERR(csi->pclk); in rockchip_mipi_csi_probe()
1306 csi->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); in rockchip_mipi_csi_probe()
1307 if (IS_ERR(csi->grf)) { in rockchip_mipi_csi_probe()
1309 csi->grf = NULL; in rockchip_mipi_csi_probe()
1312 for (i = 0; i < csi->pdata->rsts_num; i++) { in rockchip_mipi_csi_probe()
1314 devm_reset_control_get(dev, csi->pdata->rsts[i]); in rockchip_mipi_csi_probe()
1316 dev_err(dev, "failed to get %s\n", csi->pdata->rsts[i]); in rockchip_mipi_csi_probe()
1319 csi->tx_rsts[i] = rst; in rockchip_mipi_csi_probe()
1322 ret = rockchip_mipi_dphy_attach(csi); in rockchip_mipi_csi_probe()
1326 ret = devm_request_irq(dev, csi->irq, rockchip_mipi_csi_irq_handler, in rockchip_mipi_csi_probe()
1327 IRQF_SHARED, dev_name(dev), csi); in rockchip_mipi_csi_probe()
1333 csi->dsi_host.ops = &rockchip_mipi_csi_host_ops; in rockchip_mipi_csi_probe()
1334 csi->dsi_host.dev = dev; in rockchip_mipi_csi_probe()
1336 ret = mipi_dsi_host_register(&csi->dsi_host); in rockchip_mipi_csi_probe()
1342 mipi_dsi_host_unregister(&csi->dsi_host); in rockchip_mipi_csi_probe()
1344 if (!of_property_read_u32(np, "csi-tx-bypass-mode", &val)) in rockchip_mipi_csi_probe()
1345 csi->path_mode = val; in rockchip_mipi_csi_probe()
1352 struct rockchip_mipi_csi *csi = dev_get_drvdata(&pdev->dev); in rockchip_mipi_csi_remove() local
1354 if (csi) in rockchip_mipi_csi_remove()
1355 mipi_dsi_host_unregister(&csi->dsi_host); in rockchip_mipi_csi_remove()
1356 component_del(&pdev->dev, &rockchip_mipi_csi_ops); in rockchip_mipi_csi_remove()
1385 { .compatible = "rockchip,rk1808-mipi-csi", .data = &rk1808_socdata, },
1400 MODULE_DESCRIPTION("ROCKCHIP MIPI CSI TX controller driver");
1401 MODULE_AUTHOR("Sandy huang <hjc@rock-chips.com>");