aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c259
1 files changed, 158 insertions, 101 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 09528e2e69aa..b6eac92c67f8 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
126#define CLK_HS_POST (0xff << 8) 126#define CLK_HS_POST (0xff << 8)
127#define CLK_HS_EXIT (0xff << 16) 127#define CLK_HS_EXIT (0xff << 16)
128 128
129#define DSI_VM_CMD_CON 0x130
130#define VM_CMD_EN BIT(0)
131#define TS_VFP_EN BIT(5)
132
129#define DSI_CMDQ0 0x180 133#define DSI_CMDQ0 0x180
130#define CONFIG (0xff << 0) 134#define CONFIG (0xff << 0)
131#define SHORT_PACKET 0 135#define SHORT_PACKET 0
@@ -239,85 +243,6 @@ static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
239 mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0); 243 mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
240} 244}
241 245
242static int mtk_dsi_poweron(struct mtk_dsi *dsi)
243{
244 struct device *dev = dsi->dev;
245 int ret;
246 u64 pixel_clock, total_bits;
247 u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
248
249 if (++dsi->refcount != 1)
250 return 0;
251
252 switch (dsi->format) {
253 case MIPI_DSI_FMT_RGB565:
254 bit_per_pixel = 16;
255 break;
256 case MIPI_DSI_FMT_RGB666_PACKED:
257 bit_per_pixel = 18;
258 break;
259 case MIPI_DSI_FMT_RGB666:
260 case MIPI_DSI_FMT_RGB888:
261 default:
262 bit_per_pixel = 24;
263 break;
264 }
265
266 /**
267 * vm.pixelclock is in kHz, pixel_clock unit is Hz, so multiply by 1000
268 * htotal_time = htotal * byte_per_pixel / num_lanes
269 * overhead_time = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
270 * mipi_ratio = (htotal_time + overhead_time) / htotal_time
271 * data_rate = pixel_clock * bit_per_pixel * mipi_ratio / num_lanes;
272 */
273 pixel_clock = dsi->vm.pixelclock * 1000;
274 htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
275 dsi->vm.hsync_len;
276 htotal_bits = htotal * bit_per_pixel;
277
278 overhead_cycles = T_LPX + T_HS_PREP + T_HS_ZERO + T_HS_TRAIL +
279 T_HS_EXIT;
280 overhead_bits = overhead_cycles * dsi->lanes * 8;
281 total_bits = htotal_bits + overhead_bits;
282
283 dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits,
284 htotal * dsi->lanes);
285
286 ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
287 if (ret < 0) {
288 dev_err(dev, "Failed to set data rate: %d\n", ret);
289 goto err_refcount;
290 }
291
292 phy_power_on(dsi->phy);
293
294 ret = clk_prepare_enable(dsi->engine_clk);
295 if (ret < 0) {
296 dev_err(dev, "Failed to enable engine clock: %d\n", ret);
297 goto err_phy_power_off;
298 }
299
300 ret = clk_prepare_enable(dsi->digital_clk);
301 if (ret < 0) {
302 dev_err(dev, "Failed to enable digital clock: %d\n", ret);
303 goto err_disable_engine_clk;
304 }
305
306 mtk_dsi_enable(dsi);
307 mtk_dsi_reset_engine(dsi);
308 mtk_dsi_phy_timconfig(dsi);
309
310 return 0;
311
312err_disable_engine_clk:
313 clk_disable_unprepare(dsi->engine_clk);
314err_phy_power_off:
315 phy_power_off(dsi->phy);
316err_refcount:
317 dsi->refcount--;
318 return ret;
319}
320
321static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi) 246static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
322{ 247{
323 mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0); 248 mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
@@ -365,16 +290,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
365 u32 vid_mode = CMD_MODE; 290 u32 vid_mode = CMD_MODE;
366 291
367 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { 292 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
368 vid_mode = SYNC_PULSE_MODE; 293 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
369
370 if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
371 !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
372 vid_mode = BURST_MODE; 294 vid_mode = BURST_MODE;
295 else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
296 vid_mode = SYNC_PULSE_MODE;
297 else
298 vid_mode = SYNC_EVENT_MODE;
373 } 299 }
374 300
375 writel(vid_mode, dsi->regs + DSI_MODE_CTRL); 301 writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
376} 302}
377 303
304static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
305{
306 mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
307 mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
308}
309
378static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi) 310static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
379{ 311{
380 struct videomode *vm = &dsi->vm; 312 struct videomode *vm = &dsi->vm;
@@ -512,6 +444,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
512 writel(1, dsi->regs + DSI_START); 444 writel(1, dsi->regs + DSI_START);
513} 445}
514 446
447static void mtk_dsi_stop(struct mtk_dsi *dsi)
448{
449 writel(0, dsi->regs + DSI_START);
450}
451
452static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
453{
454 writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
455}
456
515static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi) 457static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
516{ 458{
517 u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG; 459 u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -570,6 +512,116 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
570 return IRQ_HANDLED; 512 return IRQ_HANDLED;
571} 513}
572 514
515static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
516{
517 mtk_dsi_irq_data_clear(dsi, irq_flag);
518 mtk_dsi_set_cmd_mode(dsi);
519
520 if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
521 DRM_ERROR("failed to switch cmd mode\n");
522 return -ETIME;
523 } else {
524 return 0;
525 }
526}
527
528static int mtk_dsi_poweron(struct mtk_dsi *dsi)
529{
530 struct device *dev = dsi->dev;
531 int ret;
532 u64 pixel_clock, total_bits;
533 u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
534
535 if (++dsi->refcount != 1)
536 return 0;
537
538 switch (dsi->format) {
539 case MIPI_DSI_FMT_RGB565:
540 bit_per_pixel = 16;
541 break;
542 case MIPI_DSI_FMT_RGB666_PACKED:
543 bit_per_pixel = 18;
544 break;
545 case MIPI_DSI_FMT_RGB666:
546 case MIPI_DSI_FMT_RGB888:
547 default:
548 bit_per_pixel = 24;
549 break;
550 }
551
552 /**
553 * vm.pixelclock is in kHz, pixel_clock unit is Hz, so multiply by 1000
554 * htotal_time = htotal * byte_per_pixel / num_lanes
555 * overhead_time = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
556 * mipi_ratio = (htotal_time + overhead_time) / htotal_time
557 * data_rate = pixel_clock * bit_per_pixel * mipi_ratio / num_lanes;
558 */
559 pixel_clock = dsi->vm.pixelclock * 1000;
560 htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
561 dsi->vm.hsync_len;
562 htotal_bits = htotal * bit_per_pixel;
563
564 overhead_cycles = T_LPX + T_HS_PREP + T_HS_ZERO + T_HS_TRAIL +
565 T_HS_EXIT;
566 overhead_bits = overhead_cycles * dsi->lanes * 8;
567 total_bits = htotal_bits + overhead_bits;
568
569 dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits,
570 htotal * dsi->lanes);
571
572 ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
573 if (ret < 0) {
574 dev_err(dev, "Failed to set data rate: %d\n", ret);
575 goto err_refcount;
576 }
577
578 phy_power_on(dsi->phy);
579
580 ret = clk_prepare_enable(dsi->engine_clk);
581 if (ret < 0) {
582 dev_err(dev, "Failed to enable engine clock: %d\n", ret);
583 goto err_phy_power_off;
584 }
585
586 ret = clk_prepare_enable(dsi->digital_clk);
587 if (ret < 0) {
588 dev_err(dev, "Failed to enable digital clock: %d\n", ret);
589 goto err_disable_engine_clk;
590 }
591
592 mtk_dsi_enable(dsi);
593 mtk_dsi_reset_engine(dsi);
594 mtk_dsi_phy_timconfig(dsi);
595
596 mtk_dsi_rxtx_control(dsi);
597 mtk_dsi_ps_control_vact(dsi);
598 mtk_dsi_set_vm_cmd(dsi);
599 mtk_dsi_config_vdo_timing(dsi);
600 mtk_dsi_set_interrupt_enable(dsi);
601
602 mtk_dsi_clk_ulp_mode_leave(dsi);
603 mtk_dsi_lane0_ulp_mode_leave(dsi);
604 mtk_dsi_clk_hs_mode(dsi, 0);
605
606 if (dsi->panel) {
607 if (drm_panel_prepare(dsi->panel)) {
608 DRM_ERROR("failed to prepare the panel\n");
609 goto err_disable_digital_clk;
610 }
611 }
612
613 return 0;
614err_disable_digital_clk:
615 clk_disable_unprepare(dsi->digital_clk);
616err_disable_engine_clk:
617 clk_disable_unprepare(dsi->engine_clk);
618err_phy_power_off:
619 phy_power_off(dsi->phy);
620err_refcount:
621 dsi->refcount--;
622 return ret;
623}
624
573static void mtk_dsi_poweroff(struct mtk_dsi *dsi) 625static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
574{ 626{
575 if (WARN_ON(dsi->refcount == 0)) 627 if (WARN_ON(dsi->refcount == 0))
@@ -578,6 +630,16 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
578 if (--dsi->refcount != 0) 630 if (--dsi->refcount != 0)
579 return; 631 return;
580 632
633 if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
634 if (dsi->panel) {
635 if (drm_panel_unprepare(dsi->panel)) {
636 DRM_ERROR("failed to unprepare the panel\n");
637 return;
638 }
639 }
640 }
641
642 mtk_dsi_reset_engine(dsi);
581 mtk_dsi_lane0_ulp_mode_enter(dsi); 643 mtk_dsi_lane0_ulp_mode_enter(dsi);
582 mtk_dsi_clk_ulp_mode_enter(dsi); 644 mtk_dsi_clk_ulp_mode_enter(dsi);
583 645
@@ -596,36 +658,30 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
596 if (dsi->enabled) 658 if (dsi->enabled)
597 return; 659 return;
598 660
599 if (dsi->panel) {
600 if (drm_panel_prepare(dsi->panel)) {
601 DRM_ERROR("failed to setup the panel\n");
602 return;
603 }
604 }
605
606 ret = mtk_dsi_poweron(dsi); 661 ret = mtk_dsi_poweron(dsi);
607 if (ret < 0) { 662 if (ret < 0) {
608 DRM_ERROR("failed to power on dsi\n"); 663 DRM_ERROR("failed to power on dsi\n");
609 return; 664 return;
610 } 665 }
611 666
612 mtk_dsi_rxtx_control(dsi);
613
614 mtk_dsi_clk_ulp_mode_leave(dsi);
615 mtk_dsi_lane0_ulp_mode_leave(dsi);
616 mtk_dsi_clk_hs_mode(dsi, 0);
617 mtk_dsi_set_mode(dsi);
618
619 mtk_dsi_ps_control_vact(dsi);
620 mtk_dsi_config_vdo_timing(dsi);
621 mtk_dsi_set_interrupt_enable(dsi);
622
623 mtk_dsi_set_mode(dsi); 667 mtk_dsi_set_mode(dsi);
624 mtk_dsi_clk_hs_mode(dsi, 1); 668 mtk_dsi_clk_hs_mode(dsi, 1);
625 669
626 mtk_dsi_start(dsi); 670 mtk_dsi_start(dsi);
627 671
672 if (dsi->panel) {
673 if (drm_panel_enable(dsi->panel)) {
674 DRM_ERROR("failed to enable the panel\n");
675 goto err_dsi_power_off;
676 }
677 }
678
628 dsi->enabled = true; 679 dsi->enabled = true;
680
681 return;
682err_dsi_power_off:
683 mtk_dsi_stop(dsi);
684 mtk_dsi_poweroff(dsi);
629} 685}
630 686
631static void mtk_output_dsi_disable(struct mtk_dsi *dsi) 687static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
@@ -640,6 +696,7 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
640 } 696 }
641 } 697 }
642 698
699 mtk_dsi_stop(dsi);
643 mtk_dsi_poweroff(dsi); 700 mtk_dsi_poweroff(dsi);
644 701
645 dsi->enabled = false; 702 dsi->enabled = false;