Lines Matching +full:sharkl3 +full:- +full:dpu

1 // SPDX-License-Identifier: GPL-2.0
142 return (readl(ctx->base + offset) & mask) >> shift; in dsi_reg_rd()
151 ret = readl(ctx->base + offset); in dsi_reg_wr()
154 writel(ret, ctx->base + offset); in dsi_reg_wr()
161 u32 ret = readl(ctx->base + offset); in dsi_reg_up()
163 writel((ret & ~mask) | (val & mask), ctx->base + offset); in dsi_reg_up()
169 struct dsi_context *ctx = &dsi->ctx; in regmap_tst_io_write()
172 return -EINVAL; in regmap_tst_io_write()
174 drm_dbg(dsi->drm, "reg = 0x%02x, val = 0x%02x\n", reg, val); in regmap_tst_io_write()
191 struct dsi_context *ctx = &dsi->ctx; in regmap_tst_io_read()
195 return -EINVAL; in regmap_tst_io_read()
211 drm_dbg(dsi->drm, "reg = 0x%02x, val = 0x%02x\n", reg, *val); in regmap_tst_io_read()
236 drm_err(dsi->drm, "dphy pll can not be locked\n"); in dphy_wait_pll_locked()
237 return -ETIMEDOUT; in dphy_wait_pll_locked()
250 return -ETIMEDOUT; in dsi_wait_tx_payload_fifo_empty()
263 return -ETIMEDOUT; in dsi_wait_tx_cmd_fifo_empty()
276 return -ETIMEDOUT; in dsi_wait_rd_resp_completed()
395 u32 byte_clk = dsi->slave->hs_rate / 8; in sprd_dsi_init()
400 writel(0, ctx->base + SOFT_RESET); in sprd_dsi_init()
401 writel(0xffffffff, ctx->base + MASK_PROTOCOL_INT); in sprd_dsi_init()
402 writel(0xffffffff, ctx->base + MASK_INTERNAL_INT); in sprd_dsi_init()
403 writel(1, ctx->base + DSI_MODE_CFG); in sprd_dsi_init()
408 writel(1, ctx->base + TA_EN); in sprd_dsi_init()
412 div = DIV_ROUND_UP(byte_clk, dsi->slave->lp_rate); in sprd_dsi_init()
413 writel(div, ctx->base + TX_ESC_CLK_CONFIG); in sprd_dsi_init()
415 max_rd_time = ns_to_cycle(ctx->max_rd_time, byte_clk); in sprd_dsi_init()
416 writel(max_rd_time, ctx->base + MAX_READ_TIME); in sprd_dsi_init()
418 data_hs2lp = ns_to_cycle(ctx->data_hs2lp, byte_clk); in sprd_dsi_init()
419 data_lp2hs = ns_to_cycle(ctx->data_lp2hs, byte_clk); in sprd_dsi_init()
420 clk_hs2lp = ns_to_cycle(ctx->clk_hs2lp, byte_clk); in sprd_dsi_init()
421 clk_lp2hs = ns_to_cycle(ctx->clk_lp2hs, byte_clk); in sprd_dsi_init()
431 writel(1, ctx->base + SOFT_RESET); in sprd_dsi_init()
439 writel(0xffffffff, ctx->base + MASK_PROTOCOL_INT); in sprd_dsi_fini()
440 writel(0xffffffff, ctx->base + MASK_INTERNAL_INT); in sprd_dsi_fini()
441 writel(0, ctx->base + SOFT_RESET); in sprd_dsi_fini()
453 struct videomode *vm = &ctx->vm; in sprd_dsi_dpi_video()
454 u32 byte_clk = dsi->slave->hs_rate / 8; in sprd_dsi_dpi_video()
472 coding = fmt_to_coding(dsi->slave->format); in sprd_dsi_dpi_video()
473 video_size = round_video_size(coding, vm->hactive); in sprd_dsi_dpi_video()
476 ratio_x1000 = byte_clk * 1000 / (vm->pixelclock / 1000); in sprd_dsi_dpi_video()
477 hline = vm->hactive + vm->hsync_len + vm->hfront_porch + in sprd_dsi_dpi_video()
478 vm->hback_porch; in sprd_dsi_dpi_video()
480 writel(0, ctx->base + SOFT_RESET); in sprd_dsi_dpi_video()
481 dsi_reg_wr(ctx, VID_MODE_CFG, FRAME_BTA_ACK_EN, 15, ctx->frame_ack_en); in sprd_dsi_dpi_video()
483 dsi_reg_wr(ctx, VID_MODE_CFG, VID_MODE_TYPE, 0, ctx->burst_mode); in sprd_dsi_dpi_video()
487 writel(byte_cycle, ctx->base + VIDEO_LINE_TIME); in sprd_dsi_dpi_video()
488 byte_cycle = vm->hsync_len * ratio_x1000 / 1000; in sprd_dsi_dpi_video()
490 byte_cycle = vm->hback_porch * ratio_x1000 / 1000; in sprd_dsi_dpi_video()
492 writel(vm->vactive, ctx->base + VIDEO_VACTIVE_LINES); in sprd_dsi_dpi_video()
493 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VFP_LINES, 0, vm->vfront_porch); in sprd_dsi_dpi_video()
494 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VBP_LINES, 10, vm->vback_porch); in sprd_dsi_dpi_video()
495 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VSA_LINES, 20, vm->vsync_len); in sprd_dsi_dpi_video()
500 hs_to = (hline * vm->vactive) + (2 * bpp_x100) / 100; in sprd_dsi_dpi_video()
501 for (div = 0x80; (div < hs_to) && (div > 2); div--) { in sprd_dsi_dpi_video()
503 writel(div, ctx->base + TIMEOUT_CNT_CLK_CONFIG); in sprd_dsi_dpi_video()
504 writel(hs_to / div, ctx->base + LRX_H_TO_CONFIG); in sprd_dsi_dpi_video()
505 writel(hs_to / div, ctx->base + HTX_TO_CONFIG); in sprd_dsi_dpi_video()
510 if (ctx->burst_mode == VIDEO_BURST_WITH_SYNC_PULSES) { in sprd_dsi_dpi_video()
512 writel(0, ctx->base + VIDEO_NULLPKT_SIZE); in sprd_dsi_dpi_video()
518 /* bytes to be sent - first as one chunk */ in sprd_dsi_dpi_video()
519 bytes_per_chunk = vm->hactive * bpp_x100 / 100 + pkt_header; in sprd_dsi_dpi_video()
522 total_bytes = (vm->hactive + vm->hfront_porch) * in sprd_dsi_dpi_video()
523 ratio_x1000 / dsi->slave->lanes / 1000; in sprd_dsi_dpi_video()
527 drm_err(dsi->drm, "current resolution can not be set\n"); in sprd_dsi_dpi_video()
528 return -EINVAL; in sprd_dsi_dpi_video()
531 chunk_overhead = total_bytes - bytes_per_chunk; in sprd_dsi_dpi_video()
533 /* overhead higher than 1 -> enable multi packets */ in sprd_dsi_dpi_video()
537 video_size < vm->hactive; in sprd_dsi_dpi_video()
539 if (vm->hactive * 1000 / video_size % 1000) in sprd_dsi_dpi_video()
542 chunks = vm->hactive / video_size; in sprd_dsi_dpi_video()
546 bytes_left = total_bytes - in sprd_dsi_dpi_video()
552 /* prevent overflow (unsigned - unsigned) */ in sprd_dsi_dpi_video()
554 null_pkt_size = (bytes_left - in sprd_dsi_dpi_video()
566 for (video_size = vm->hactive; in sprd_dsi_dpi_video()
573 writel(null_pkt_size, ctx->base + VIDEO_NULLPKT_SIZE); in sprd_dsi_dpi_video()
577 writel(ctx->int0_mask, ctx->base + MASK_PROTOCOL_INT); in sprd_dsi_dpi_video()
578 writel(ctx->int1_mask, ctx->base + MASK_INTERNAL_INT); in sprd_dsi_dpi_video()
579 writel(1, ctx->base + SOFT_RESET); in sprd_dsi_dpi_video()
589 u32 hactive = ctx->vm.hactive; in sprd_dsi_edpi_video()
594 coding = fmt_to_coding(dsi->slave->format); in sprd_dsi_edpi_video()
598 writel(0, ctx->base + SOFT_RESET); in sprd_dsi_edpi_video()
600 dsi_reg_wr(ctx, CMD_MODE_CFG, TEAR_FX_EN, 0, ctx->te_ack_en); in sprd_dsi_edpi_video()
603 writel(hactive, ctx->base + DCS_WM_PKT_SIZE); in sprd_dsi_edpi_video()
605 writel(max_fifo_len, ctx->base + DCS_WM_PKT_SIZE); in sprd_dsi_edpi_video()
607 writel(ctx->int0_mask, ctx->base + MASK_PROTOCOL_INT); in sprd_dsi_edpi_video()
608 writel(ctx->int1_mask, ctx->base + MASK_INTERNAL_INT); in sprd_dsi_edpi_video()
609 writel(1, ctx->base + SOFT_RESET); in sprd_dsi_edpi_video()
631 return -EINVAL; in sprd_dsi_wr_pkt()
636 drm_err(dsi->drm, "tx payload fifo is not empty\n"); in sprd_dsi_wr_pkt()
646 writel(payload, ctx->base + GEN_PLD_DATA); in sprd_dsi_wr_pkt()
658 drm_err(dsi->drm, "tx cmd fifo is not empty\n"); in sprd_dsi_wr_pkt()
663 ctx->base + GEN_HDR); in sprd_dsi_wr_pkt()
687 return -EINVAL; in sprd_dsi_rd_pkt()
692 return -EIO; in sprd_dsi_rd_pkt()
695 ctx->base + GEN_HDR); in sprd_dsi_rd_pkt()
700 drm_err(dsi->drm, "wait read response time out\n"); in sprd_dsi_rd_pkt()
707 drm_err(dsi->drm, "rx payload fifo empty\n"); in sprd_dsi_rd_pkt()
708 return -EIO; in sprd_dsi_rd_pkt()
712 temp = readl(ctx->base + GEN_PLD_DATA); in sprd_dsi_rd_pkt()
734 writel(1, ctx->base + DSI_MODE_CFG); in sprd_dsi_set_work_mode()
736 writel(0, ctx->base + DSI_MODE_CFG); in sprd_dsi_set_work_mode()
741 writel(0, ctx->base + SOFT_RESET); in sprd_dsi_state_reset()
743 writel(1, ctx->base + SOFT_RESET); in sprd_dsi_state_reset()
764 writel(0x1C, ctx->base + PHY_MIN_STOP_TIME); in sprd_dphy_init()
766 writel(dsi->slave->lanes - 1, ctx->base + PHY_LANE_NUM_CONFIG); in sprd_dphy_init()
770 drm_err(dsi->drm, "dphy initial failed\n"); in sprd_dphy_init()
790 drm_display_mode_to_videomode(adj_mode, &dsi->ctx.vm); in sprd_dsi_encoder_mode_set()
796 struct sprd_dpu *dpu = to_sprd_crtc(encoder->crtc); in sprd_dsi_encoder_enable() local
797 struct dsi_context *ctx = &dsi->ctx; in sprd_dsi_encoder_enable()
799 if (ctx->enabled) { in sprd_dsi_encoder_enable()
800 drm_warn(dsi->drm, "dsi is initialized\n"); in sprd_dsi_encoder_enable()
805 if (ctx->work_mode == DSI_MODE_VIDEO) in sprd_dsi_encoder_enable()
812 sprd_dsi_set_work_mode(ctx, ctx->work_mode); in sprd_dsi_encoder_enable()
815 if (dsi->slave->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { in sprd_dsi_encoder_enable()
825 sprd_dpu_run(dpu); in sprd_dsi_encoder_enable()
827 ctx->enabled = true; in sprd_dsi_encoder_enable()
833 struct sprd_dpu *dpu = to_sprd_crtc(encoder->crtc); in sprd_dsi_encoder_disable() local
834 struct dsi_context *ctx = &dsi->ctx; in sprd_dsi_encoder_disable()
836 if (!ctx->enabled) { in sprd_dsi_encoder_disable()
837 drm_warn(dsi->drm, "dsi isn't initialized\n"); in sprd_dsi_encoder_disable()
841 sprd_dpu_stop(dpu); in sprd_dsi_encoder_disable()
845 ctx->enabled = false; in sprd_dsi_encoder_disable()
861 struct drm_encoder *encoder = &dsi->encoder; in sprd_dsi_encoder_init()
865 crtc_mask = drm_of_find_possible_crtcs(dsi->drm, dev->of_node); in sprd_dsi_encoder_init()
867 drm_err(dsi->drm, "failed to find crtc mask\n"); in sprd_dsi_encoder_init()
868 return -EINVAL; in sprd_dsi_encoder_init()
871 drm_dbg(dsi->drm, "find possible crtcs: 0x%08x\n", crtc_mask); in sprd_dsi_encoder_init()
873 encoder->possible_crtcs = crtc_mask; in sprd_dsi_encoder_init()
874 ret = drm_encoder_init(dsi->drm, encoder, &sprd_encoder_funcs, in sprd_dsi_encoder_init()
877 drm_err(dsi->drm, "failed to init dsi encoder\n"); in sprd_dsi_encoder_init()
891 dsi->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); in sprd_dsi_bridge_init()
892 if (IS_ERR(dsi->panel_bridge)) in sprd_dsi_bridge_init()
893 return PTR_ERR(dsi->panel_bridge); in sprd_dsi_bridge_init()
895 ret = drm_bridge_attach(&dsi->encoder, dsi->panel_bridge, NULL, 0); in sprd_dsi_bridge_init()
906 struct dsi_context *ctx = &dsi->ctx; in sprd_dsi_context_init()
912 return -EINVAL; in sprd_dsi_context_init()
915 ctx->base = devm_ioremap(dev, res->start, resource_size(res)); in sprd_dsi_context_init()
916 if (!ctx->base) { in sprd_dsi_context_init()
917 drm_err(dsi->drm, "failed to map dsi host registers\n"); in sprd_dsi_context_init()
918 return -ENXIO; in sprd_dsi_context_init()
921 ctx->regmap = devm_regmap_init(dev, &regmap_tst_io, dsi, &byte_config); in sprd_dsi_context_init()
922 if (IS_ERR(ctx->regmap)) { in sprd_dsi_context_init()
923 drm_err(dsi->drm, "dphy regmap init failed\n"); in sprd_dsi_context_init()
924 return PTR_ERR(ctx->regmap); in sprd_dsi_context_init()
927 ctx->data_hs2lp = 120; in sprd_dsi_context_init()
928 ctx->data_lp2hs = 500; in sprd_dsi_context_init()
929 ctx->clk_hs2lp = 4; in sprd_dsi_context_init()
930 ctx->clk_lp2hs = 15; in sprd_dsi_context_init()
931 ctx->max_rd_time = 6000; in sprd_dsi_context_init()
932 ctx->int0_mask = 0xffffffff; in sprd_dsi_context_init()
933 ctx->int1_mask = 0xffffffff; in sprd_dsi_context_init()
934 ctx->enabled = true; in sprd_dsi_context_init()
945 dsi->drm = drm; in sprd_dsi_bind()
967 drm_of_panel_bridge_remove(dev->of_node, 1, 0); in sprd_dsi_unbind()
969 drm_encoder_cleanup(&dsi->encoder); in sprd_dsi_unbind()
981 struct dsi_context *ctx = &dsi->ctx; in sprd_dsi_host_attach()
983 dsi->slave = slave; in sprd_dsi_host_attach()
985 if (slave->mode_flags & MIPI_DSI_MODE_VIDEO) in sprd_dsi_host_attach()
986 ctx->work_mode = DSI_MODE_VIDEO; in sprd_dsi_host_attach()
988 ctx->work_mode = DSI_MODE_CMD; in sprd_dsi_host_attach()
990 if (slave->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) in sprd_dsi_host_attach()
991 ctx->burst_mode = VIDEO_BURST_WITH_SYNC_PULSES; in sprd_dsi_host_attach()
992 else if (slave->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) in sprd_dsi_host_attach()
993 ctx->burst_mode = VIDEO_NON_BURST_WITH_SYNC_PULSES; in sprd_dsi_host_attach()
995 ctx->burst_mode = VIDEO_NON_BURST_WITH_SYNC_EVENTS; in sprd_dsi_host_attach()
997 return component_add(host->dev, &dsi_component_ops); in sprd_dsi_host_attach()
1003 component_del(host->dev, &dsi_component_ops); in sprd_dsi_host_detach()
1012 const u8 *tx_buf = msg->tx_buf; in sprd_dsi_host_transfer()
1014 if (msg->rx_buf && msg->rx_len) { in sprd_dsi_host_transfer()
1015 u8 lsb = (msg->tx_len > 0) ? tx_buf[0] : 0; in sprd_dsi_host_transfer()
1016 u8 msb = (msg->tx_len > 1) ? tx_buf[1] : 0; in sprd_dsi_host_transfer()
1018 return sprd_dsi_rd_pkt(&dsi->ctx, msg->channel, msg->type, in sprd_dsi_host_transfer()
1019 msb, lsb, msg->rx_buf, msg->rx_len); in sprd_dsi_host_transfer()
1022 if (msg->tx_buf && msg->tx_len) in sprd_dsi_host_transfer()
1023 return sprd_dsi_wr_pkt(&dsi->ctx, msg->channel, msg->type, in sprd_dsi_host_transfer()
1024 tx_buf, msg->tx_len); in sprd_dsi_host_transfer()
1036 { .compatible = "sprd,sharkl3-dsi-host" },
1042 struct device *dev = &pdev->dev; in sprd_dsi_probe()
1047 return -ENOMEM; in sprd_dsi_probe()
1051 dsi->host.ops = &sprd_dsi_host_ops; in sprd_dsi_probe()
1052 dsi->host.dev = dev; in sprd_dsi_probe()
1054 return mipi_dsi_host_register(&dsi->host); in sprd_dsi_probe()
1059 struct sprd_dsi *dsi = dev_get_drvdata(&pdev->dev); in sprd_dsi_remove()
1061 mipi_dsi_host_unregister(&dsi->host); in sprd_dsi_remove()
1070 .name = "sprd-dsi-drv",