• Home
  • Raw
  • Download

Lines Matching full:mcde

4  * Parts of this file were based on the MCDE driver by Marcus Lorentzon
66 void mcde_display_irq(struct mcde *mcde) in mcde_display_irq() argument
72 mispp = readl(mcde->regs + MCDE_MISPP); in mcde_display_irq()
73 misovl = readl(mcde->regs + MCDE_MISOVL); in mcde_display_irq()
74 mischnl = readl(mcde->regs + MCDE_MISCHNL); in mcde_display_irq()
78 * are just latched onto the MCDE IRQ line, so we need to traverse in mcde_display_irq()
84 if (mcde_dsi_irq(mcde->mdsi)) { in mcde_display_irq()
93 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { in mcde_display_irq()
94 spin_lock(&mcde->flow_lock); in mcde_display_irq()
95 if (--mcde->flow_active == 0) { in mcde_display_irq()
96 dev_dbg(mcde->dev, "TE0 IRQ\n"); in mcde_display_irq()
98 val = readl(mcde->regs + MCDE_CRA0); in mcde_display_irq()
100 writel(val, mcde->regs + MCDE_CRA0); in mcde_display_irq()
102 spin_unlock(&mcde->flow_lock); in mcde_display_irq()
108 dev_dbg(mcde->dev, "chnl A vblank IRQ\n"); in mcde_display_irq()
112 dev_dbg(mcde->dev, "chnl B vblank IRQ\n"); in mcde_display_irq()
116 dev_dbg(mcde->dev, "chnl C0 vblank IRQ\n"); in mcde_display_irq()
118 dev_dbg(mcde->dev, "chnl C1 vblank IRQ\n"); in mcde_display_irq()
120 dev_dbg(mcde->dev, "chnl C0 TE IRQ\n"); in mcde_display_irq()
122 dev_dbg(mcde->dev, "chnl C1 TE IRQ\n"); in mcde_display_irq()
123 writel(mispp, mcde->regs + MCDE_RISPP); in mcde_display_irq()
126 drm_crtc_handle_vblank(&mcde->pipe.crtc); in mcde_display_irq()
129 dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl); in mcde_display_irq()
130 writel(misovl, mcde->regs + MCDE_RISOVL); in mcde_display_irq()
133 dev_info(mcde->dev, "some stray channel error IRQ %08x\n", in mcde_display_irq()
135 writel(mischnl, mcde->regs + MCDE_RISCHNL); in mcde_display_irq()
138 void mcde_display_disable_irqs(struct mcde *mcde) in mcde_display_disable_irqs() argument
141 writel(0, mcde->regs + MCDE_IMSCPP); in mcde_display_disable_irqs()
142 writel(0, mcde->regs + MCDE_IMSCOVL); in mcde_display_disable_irqs()
143 writel(0, mcde->regs + MCDE_IMSCCHNL); in mcde_display_disable_irqs()
146 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); in mcde_display_disable_irqs()
147 writel(0xFFFFFFFF, mcde->regs + MCDE_RISOVL); in mcde_display_disable_irqs()
148 writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL); in mcde_display_disable_irqs()
188 static int mcde_configure_extsrc(struct mcde *mcde, enum mcde_extsrc src, in mcde_configure_extsrc() argument
247 * MCDE has inverse semantics from DRM on RBG/BGR which is why in mcde_configure_extsrc()
319 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", in mcde_configure_extsrc()
323 writel(val, mcde->regs + conf); in mcde_configure_extsrc()
328 writel(val, mcde->regs + cr); in mcde_configure_extsrc()
333 static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, in mcde_configure_overlay() argument
403 writel(val, mcde->regs + conf1); in mcde_configure_overlay()
427 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", in mcde_configure_overlay()
455 dev_dbg(mcde->dev, "pixel fetcher watermark level %d pixels\n", in mcde_configure_overlay()
458 writel(val, mcde->regs + conf2); in mcde_configure_overlay()
461 writel(mcde->stride, mcde->regs + ljinc); in mcde_configure_overlay()
463 writel(0, mcde->regs + crop); in mcde_configure_overlay()
475 writel(val, mcde->regs + cr); in mcde_configure_overlay()
482 writel(val, mcde->regs + comp); in mcde_configure_overlay()
485 static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch, in mcde_configure_channel() argument
528 switch (mcde->flow_mode) { in mcde_configure_channel()
565 dev_err(mcde->dev, "unknown flow mode %d\n", in mcde_configure_channel()
566 mcde->flow_mode); in mcde_configure_channel()
570 writel(val, mcde->regs + sync); in mcde_configure_channel()
575 writel(val, mcde->regs + conf); in mcde_configure_channel()
583 writel(val, mcde->regs + stat); in mcde_configure_channel()
584 writel(0, mcde->regs + bgcol); in mcde_configure_channel()
590 mcde->regs + mux); in mcde_configure_channel()
594 mcde->regs + mux); in mcde_configure_channel()
599 static void mcde_configure_fifo(struct mcde *mcde, enum mcde_fifo fifo, in mcde_configure_fifo() argument
627 writel(val, mcde->regs + ctrl); in mcde_configure_fifo()
632 writel(val, mcde->regs + cr0); in mcde_configure_fifo()
636 /* Use the MCDE clock for this FIFO */ in mcde_configure_fifo()
640 writel(val, mcde->regs + cr1); in mcde_configure_fifo()
643 static void mcde_configure_dsi_formatter(struct mcde *mcde, in mcde_configure_dsi_formatter() argument
691 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) in mcde_configure_dsi_formatter()
693 switch (mcde->mdsi->format) { in mcde_configure_dsi_formatter()
711 dev_err(mcde->dev, "unknown DSI format\n"); in mcde_configure_dsi_formatter()
714 writel(val, mcde->regs + conf0); in mcde_configure_dsi_formatter()
716 writel(formatter_frame, mcde->regs + frame); in mcde_configure_dsi_formatter()
717 writel(pkt_size, mcde->regs + pkt); in mcde_configure_dsi_formatter()
718 writel(0, mcde->regs + sync); in mcde_configure_dsi_formatter()
724 writel(val, mcde->regs + cmdw); in mcde_configure_dsi_formatter()
730 writel(0, mcde->regs + delay0); in mcde_configure_dsi_formatter()
731 writel(0, mcde->regs + delay1); in mcde_configure_dsi_formatter()
734 static void mcde_enable_fifo(struct mcde *mcde, enum mcde_fifo fifo) in mcde_enable_fifo() argument
747 dev_err(mcde->dev, "cannot enable FIFO %c\n", in mcde_enable_fifo()
752 spin_lock(&mcde->flow_lock); in mcde_enable_fifo()
753 val = readl(mcde->regs + cr); in mcde_enable_fifo()
755 writel(val, mcde->regs + cr); in mcde_enable_fifo()
756 mcde->flow_active++; in mcde_enable_fifo()
757 spin_unlock(&mcde->flow_lock); in mcde_enable_fifo()
760 static void mcde_disable_fifo(struct mcde *mcde, enum mcde_fifo fifo, in mcde_disable_fifo() argument
775 dev_err(mcde->dev, "cannot disable FIFO %c\n", in mcde_disable_fifo()
780 spin_lock(&mcde->flow_lock); in mcde_disable_fifo()
781 val = readl(mcde->regs + cr); in mcde_disable_fifo()
783 writel(val, mcde->regs + cr); in mcde_disable_fifo()
784 mcde->flow_active = 0; in mcde_disable_fifo()
785 spin_unlock(&mcde->flow_lock); in mcde_disable_fifo()
791 while (readl(mcde->regs + cr) & MCDE_CRX0_FLOEN) { in mcde_disable_fifo()
794 dev_err(mcde->dev, in mcde_disable_fifo()
805 static void mcde_drain_pipe(struct mcde *mcde, enum mcde_fifo fifo, in mcde_drain_pipe() argument
836 val = readl(mcde->regs + ctrl); in mcde_drain_pipe()
838 dev_err(mcde->dev, "Channel A FIFO not empty (handover)\n"); in mcde_drain_pipe()
840 mcde_enable_fifo(mcde, fifo); in mcde_drain_pipe()
842 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, mcde->regs + synsw); in mcde_drain_pipe()
844 mcde_disable_fifo(mcde, fifo, true); in mcde_drain_pipe()
870 struct mcde *mcde = to_mcde(drm); in mcde_display_enable() local
885 /* This powers up the entire MCDE block and the DSI hardware */ in mcde_display_enable()
886 ret = regulator_enable(mcde->epod); in mcde_display_enable()
892 dev_info(drm->dev, "enable MCDE, %d x %d format %s\n", in mcde_display_enable()
895 if (!mcde->mdsi) { in mcde_display_enable()
914 writel(val, mcde->regs + MCDE_CONF0); in mcde_display_enable()
917 mcde_display_disable_irqs(mcde); in mcde_display_enable()
918 writel(0, mcde->regs + MCDE_IMSCERR); in mcde_display_enable()
919 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); in mcde_display_enable()
922 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? in mcde_display_enable()
924 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format)); in mcde_display_enable()
926 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8; in mcde_display_enable()
943 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { in mcde_display_enable()
958 if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)) in mcde_display_enable()
965 mcde->stride = mode->hdisplay * cpp; in mcde_display_enable()
967 mcde->stride); in mcde_display_enable()
973 mcde_drain_pipe(mcde, MCDE_FIFO_A, MCDE_CHANNEL_0); in mcde_display_enable()
982 mcde_configure_extsrc(mcde, MCDE_EXTSRC_0, format); in mcde_display_enable()
989 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0, in mcde_display_enable()
996 mcde_configure_channel(mcde, MCDE_CHANNEL_0, MCDE_FIFO_A, mode); in mcde_display_enable()
999 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0, in mcde_display_enable()
1004 * to the MCDE DSI formatter. in mcde_display_enable()
1010 mcde_dsi_enable(mcde->bridge); in mcde_display_enable()
1013 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0, in mcde_display_enable()
1016 switch (mcde->flow_mode) { in mcde_display_enable()
1025 writel(val, mcde->regs + MCDE_VSCRC0); in mcde_display_enable()
1027 val = readl(mcde->regs + MCDE_CRC); in mcde_display_enable()
1029 writel(val, mcde->regs + MCDE_CRC); in mcde_display_enable()
1046 if (mcde->flow_mode != MCDE_COMMAND_ONESHOT_FLOW) { in mcde_display_enable()
1047 mcde_enable_fifo(mcde, MCDE_FIFO_A); in mcde_display_enable()
1048 dev_dbg(mcde->dev, "started MCDE video FIFO flow\n"); in mcde_display_enable()
1051 /* Enable MCDE with automatic clock gating */ in mcde_display_enable()
1052 val = readl(mcde->regs + MCDE_CR); in mcde_display_enable()
1054 writel(val, mcde->regs + MCDE_CR); in mcde_display_enable()
1056 dev_info(drm->dev, "MCDE display is enabled\n"); in mcde_display_enable()
1063 struct mcde *mcde = to_mcde(drm); in mcde_display_disable() local
1070 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); in mcde_display_disable()
1073 mcde_dsi_disable(mcde->bridge); in mcde_display_disable()
1084 ret = regulator_disable(mcde->epod); in mcde_display_disable()
1090 dev_info(drm->dev, "MCDE display is disabled\n"); in mcde_display_disable()
1093 static void mcde_start_flow(struct mcde *mcde) in mcde_start_flow() argument
1096 if (mcde->flow_mode == MCDE_COMMAND_BTA_TE_FLOW) in mcde_start_flow()
1097 mcde_dsi_te_request(mcde->mdsi); in mcde_start_flow()
1100 mcde_enable_fifo(mcde, MCDE_FIFO_A); in mcde_start_flow()
1109 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { in mcde_start_flow()
1112 mcde->regs + MCDE_CHNL0SYNCHSW); in mcde_start_flow()
1121 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); in mcde_start_flow()
1124 dev_dbg(mcde->dev, "started MCDE FIFO flow\n"); in mcde_start_flow()
1127 static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address) in mcde_set_extsrc() argument
1130 writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0); in mcde_set_extsrc()
1135 writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1); in mcde_set_extsrc()
1143 struct mcde *mcde = to_mcde(drm); in mcde_display_update() local
1162 * until we get an update. If MCDE output isn't yet enabled, in mcde_display_update()
1166 dev_dbg(mcde->dev, "arm vblank event\n"); in mcde_display_update()
1169 dev_dbg(mcde->dev, "insert fake vblank event\n"); in mcde_display_update()
1182 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); in mcde_display_update()
1183 dev_info_once(mcde->dev, "first update of display contents\n"); in mcde_display_update()
1188 if (mcde->flow_active == 0) in mcde_display_update()
1189 mcde_start_flow(mcde); in mcde_display_update()
1192 * If an update is receieved before the MCDE is enabled in mcde_display_update()
1196 dev_info(mcde->dev, "ignored a display update\n"); in mcde_display_update()
1204 struct mcde *mcde = to_mcde(drm); in mcde_display_enable_vblank() local
1214 writel(val, mcde->regs + MCDE_IMSCPP); in mcde_display_enable_vblank()
1223 struct mcde *mcde = to_mcde(drm); in mcde_display_disable_vblank() local
1226 writel(0, mcde->regs + MCDE_IMSCPP); in mcde_display_disable_vblank()
1228 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); in mcde_display_disable_vblank()
1243 struct mcde *mcde = to_mcde(drm); in mcde_display_init() local
1264 ret = drm_simple_display_pipe_init(drm, &mcde->pipe, in mcde_display_init()
1268 mcde->connector); in mcde_display_init()