Lines Matching +full:mcde +full:- +full:dsi
1 // SPDX-License-Identifier: GPL-2.0
4 * Parts of this file were based on the MCDE driver by Marcus Lorentzon
5 * (C) ST-Ericsson SA 2013
9 #include <linux/dma-buf.h>
11 #include <linux/media-bus-format.h>
73 void mcde_display_irq(struct mcde *mcde) in mcde_display_irq() argument
79 mispp = readl(mcde->regs + MCDE_MISPP); in mcde_display_irq()
80 misovl = readl(mcde->regs + MCDE_MISOVL); in mcde_display_irq()
81 mischnl = readl(mcde->regs + MCDE_MISCHNL); in mcde_display_irq()
84 * Handle IRQs from the DSI link. All IRQs from the DSI links in mcde_display_irq()
85 * are just latched onto the MCDE IRQ line, so we need to traverse in mcde_display_irq()
86 * any active DSI masters and check if an IRQ is originating from in mcde_display_irq()
89 * TODO: Currently only one DSI link is supported. in mcde_display_irq()
91 if (!mcde->dpi_output && mcde_dsi_irq(mcde->mdsi)) { in mcde_display_irq()
100 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { in mcde_display_irq()
101 spin_lock(&mcde->flow_lock); in mcde_display_irq()
102 if (--mcde->flow_active == 0) { in mcde_display_irq()
103 dev_dbg(mcde->dev, "TE0 IRQ\n"); in mcde_display_irq()
105 val = readl(mcde->regs + MCDE_CRA0); in mcde_display_irq()
107 writel(val, mcde->regs + MCDE_CRA0); in mcde_display_irq()
109 spin_unlock(&mcde->flow_lock); in mcde_display_irq()
115 dev_dbg(mcde->dev, "chnl A vblank IRQ\n"); in mcde_display_irq()
119 dev_dbg(mcde->dev, "chnl B vblank IRQ\n"); in mcde_display_irq()
123 dev_dbg(mcde->dev, "chnl C0 vblank IRQ\n"); in mcde_display_irq()
125 dev_dbg(mcde->dev, "chnl C1 vblank IRQ\n"); in mcde_display_irq()
127 dev_dbg(mcde->dev, "chnl C0 TE IRQ\n"); in mcde_display_irq()
129 dev_dbg(mcde->dev, "chnl C1 TE IRQ\n"); in mcde_display_irq()
130 writel(mispp, mcde->regs + MCDE_RISPP); in mcde_display_irq()
133 drm_crtc_handle_vblank(&mcde->pipe.crtc); in mcde_display_irq()
136 dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl); in mcde_display_irq()
137 writel(misovl, mcde->regs + MCDE_RISOVL); in mcde_display_irq()
140 dev_info(mcde->dev, "some stray channel error IRQ %08x\n", in mcde_display_irq()
142 writel(mischnl, mcde->regs + MCDE_RISCHNL); in mcde_display_irq()
145 void mcde_display_disable_irqs(struct mcde *mcde) in mcde_display_disable_irqs() argument
148 writel(0, mcde->regs + MCDE_IMSCPP); in mcde_display_disable_irqs()
149 writel(0, mcde->regs + MCDE_IMSCOVL); in mcde_display_disable_irqs()
150 writel(0, mcde->regs + MCDE_IMSCCHNL); in mcde_display_disable_irqs()
153 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); in mcde_display_disable_irqs()
154 writel(0xFFFFFFFF, mcde->regs + MCDE_RISOVL); in mcde_display_disable_irqs()
155 writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL); in mcde_display_disable_irqs()
162 const struct drm_display_mode *mode = &cstate->mode; in mcde_display_check()
163 struct drm_framebuffer *old_fb = pipe->plane.state->fb; in mcde_display_check()
164 struct drm_framebuffer *fb = pstate->fb; in mcde_display_check()
171 DRM_DEBUG_KMS("FB not 32-bit aligned\n"); in mcde_display_check()
172 return -EINVAL; in mcde_display_check()
179 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) { in mcde_display_check()
181 return -EINVAL; in mcde_display_check()
185 * We can't change the FB format in a flicker-free in mcde_display_check()
188 if (old_fb && old_fb->format != fb->format) in mcde_display_check()
189 cstate->mode_changed = true; in mcde_display_check()
195 static int mcde_configure_extsrc(struct mcde *mcde, enum mcde_extsrc src, in mcde_configure_extsrc() argument
323 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", in mcde_configure_extsrc()
325 return -EINVAL; in mcde_configure_extsrc()
327 writel(val, mcde->regs + conf); in mcde_configure_extsrc()
332 writel(val, mcde->regs + cr); in mcde_configure_extsrc()
337 static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, in mcde_configure_overlay() argument
403 val = mode->hdisplay << MCDE_OVLXCONF_PPL_SHIFT; in mcde_configure_overlay()
404 val |= mode->vdisplay << MCDE_OVLXCONF_LPF_SHIFT; in mcde_configure_overlay()
407 writel(val, mcde->regs + conf1); in mcde_configure_overlay()
431 dev_err(mcde->dev, "Unknown pixel format 0x%08x\n", in mcde_configure_overlay()
459 dev_dbg(mcde->dev, "pixel fetcher watermark level %d pixels\n", in mcde_configure_overlay()
462 writel(val, mcde->regs + conf2); in mcde_configure_overlay()
465 writel(mcde->stride, mcde->regs + ljinc); in mcde_configure_overlay()
467 writel(0, mcde->regs + crop); in mcde_configure_overlay()
479 writel(val, mcde->regs + cr); in mcde_configure_overlay()
486 writel(val, mcde->regs + comp); in mcde_configure_overlay()
489 static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch, in mcde_configure_channel() argument
532 switch (mcde->flow_mode) { in mcde_configure_channel()
570 dev_err(mcde->dev, "unknown flow mode %d\n", in mcde_configure_channel()
571 mcde->flow_mode); in mcde_configure_channel()
575 writel(val, mcde->regs + sync); in mcde_configure_channel()
578 val = (mode->hdisplay - 1) << MCDE_CHNLXCONF_PPL_SHIFT; in mcde_configure_channel()
579 val |= (mode->vdisplay - 1) << MCDE_CHNLXCONF_LPF_SHIFT; in mcde_configure_channel()
580 writel(val, mcde->regs + conf); in mcde_configure_channel()
588 writel(val, mcde->regs + stat); in mcde_configure_channel()
589 writel(0, mcde->regs + bgcol); in mcde_configure_channel()
595 mcde->regs + mux); in mcde_configure_channel()
599 mcde->regs + mux); in mcde_configure_channel()
607 if (mcde->dpi_output) { in mcde_configure_channel()
610 stripwidth = 0xF000 / (mode->vdisplay * 4); in mcde_configure_channel()
611 dev_info(mcde->dev, "stripwidth: %d\n", stripwidth); in mcde_configure_channel()
614 (mode->hdisplay - 1 - stripwidth) << MCDE_SYNCHCONF_HWREQVCNT_SHIFT | in mcde_configure_channel()
616 (mode->hdisplay - 1 - stripwidth) << MCDE_SYNCHCONF_SWINTVCNT_SHIFT; in mcde_configure_channel()
620 writel(val, mcde->regs + MCDE_SYNCHCONFA); in mcde_configure_channel()
623 writel(val, mcde->regs + MCDE_SYNCHCONFB); in mcde_configure_channel()
629 static void mcde_configure_fifo(struct mcde *mcde, enum mcde_fifo fifo, in mcde_configure_fifo() argument
656 * by the DSI formatters depending on if they are in VID or CMD in mcde_configure_fifo()
694 writel(val, mcde->regs + ctrl); in mcde_configure_fifo()
699 writel(val, mcde->regs + cr0); in mcde_configure_fifo()
701 spin_lock(&mcde->fifo_crx1_lock); in mcde_configure_fifo()
702 val = readl(mcde->regs + cr1); in mcde_configure_fifo()
704 * Set-up from mcde_fmtr_dsi.c, fmtr_dsi_enable_video() in mcde_configure_fifo()
707 if (mcde->dpi_output) { in mcde_configure_fifo()
708 struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge); in mcde_configure_fifo()
712 if (!connector->display_info.num_bus_formats) { in mcde_configure_fifo()
713 dev_info(mcde->dev, "panel does not specify bus format, assume RGB888\n"); in mcde_configure_fifo()
716 bus_format = connector->display_info.bus_formats[0]; in mcde_configure_fifo()
733 dev_err(mcde->dev, "unknown bus format, assume RGB888\n"); in mcde_configure_fifo()
739 /* Use the MCDE clock for DSI */ in mcde_configure_fifo()
743 writel(val, mcde->regs + cr1); in mcde_configure_fifo()
744 spin_unlock(&mcde->fifo_crx1_lock); in mcde_configure_fifo()
747 static void mcde_configure_dsi_formatter(struct mcde *mcde, in mcde_configure_dsi_formatter() argument
789 dev_err(mcde->dev, "tried to configure a non-DSI formatter as DSI\n"); in mcde_configure_dsi_formatter()
798 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) in mcde_configure_dsi_formatter()
800 switch (mcde->mdsi->format) { in mcde_configure_dsi_formatter()
810 dev_err(mcde->dev, in mcde_configure_dsi_formatter()
820 dev_err(mcde->dev, "unknown DSI format\n"); in mcde_configure_dsi_formatter()
823 writel(val, mcde->regs + conf0); in mcde_configure_dsi_formatter()
825 writel(formatter_frame, mcde->regs + frame); in mcde_configure_dsi_formatter()
826 writel(pkt_size, mcde->regs + pkt); in mcde_configure_dsi_formatter()
827 writel(0, mcde->regs + sync); in mcde_configure_dsi_formatter()
833 writel(val, mcde->regs + cmdw); in mcde_configure_dsi_formatter()
839 writel(0, mcde->regs + delay0); in mcde_configure_dsi_formatter()
840 writel(0, mcde->regs + delay1); in mcde_configure_dsi_formatter()
843 static void mcde_enable_fifo(struct mcde *mcde, enum mcde_fifo fifo) in mcde_enable_fifo() argument
856 dev_err(mcde->dev, "cannot enable FIFO %c\n", in mcde_enable_fifo()
861 spin_lock(&mcde->flow_lock); in mcde_enable_fifo()
862 val = readl(mcde->regs + cr); in mcde_enable_fifo()
864 writel(val, mcde->regs + cr); in mcde_enable_fifo()
865 mcde->flow_active++; in mcde_enable_fifo()
866 spin_unlock(&mcde->flow_lock); in mcde_enable_fifo()
869 static void mcde_disable_fifo(struct mcde *mcde, enum mcde_fifo fifo, in mcde_disable_fifo() argument
884 dev_err(mcde->dev, "cannot disable FIFO %c\n", in mcde_disable_fifo()
889 spin_lock(&mcde->flow_lock); in mcde_disable_fifo()
890 val = readl(mcde->regs + cr); in mcde_disable_fifo()
892 writel(val, mcde->regs + cr); in mcde_disable_fifo()
893 mcde->flow_active = 0; in mcde_disable_fifo()
894 spin_unlock(&mcde->flow_lock); in mcde_disable_fifo()
900 while (readl(mcde->regs + cr) & MCDE_CRX0_FLOEN) { in mcde_disable_fifo()
902 if (!--timeout) { in mcde_disable_fifo()
903 dev_err(mcde->dev, in mcde_disable_fifo()
914 static void mcde_drain_pipe(struct mcde *mcde, enum mcde_fifo fifo, in mcde_drain_pipe() argument
945 val = readl(mcde->regs + ctrl); in mcde_drain_pipe()
947 dev_err(mcde->dev, "Channel A FIFO not empty (handover)\n"); in mcde_drain_pipe()
949 mcde_enable_fifo(mcde, fifo); in mcde_drain_pipe()
950 /* Trigger a software sync out on respective channel (0-3) */ in mcde_drain_pipe()
951 writel(MCDE_CHNLXSYNCHSW_SW_TRIG, mcde->regs + synsw); in mcde_drain_pipe()
953 mcde_disable_fifo(mcde, fifo, true); in mcde_drain_pipe()
960 * DSI command mode line packets should be split into an even number of in mcde_dsi_get_pkt_div()
972 static void mcde_setup_dpi(struct mcde *mcde, const struct drm_display_mode *mode, in mcde_setup_dpi() argument
975 struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge); in mcde_setup_dpi()
981 hsw = mode->hsync_end - mode->hsync_start; in mcde_setup_dpi()
982 hfp = mode->hsync_start - mode->hdisplay; in mcde_setup_dpi()
983 hbp = mode->htotal - mode->hsync_end; in mcde_setup_dpi()
984 vsw = mode->vsync_end - mode->vsync_start; in mcde_setup_dpi()
985 vfp = mode->vsync_start - mode->vdisplay; in mcde_setup_dpi()
986 vbp = mode->vtotal - mode->vsync_end; in mcde_setup_dpi()
988 dev_info(mcde->dev, "output on DPI LCD from channel A\n"); in mcde_setup_dpi()
990 dev_info(mcde->dev, "HSW: %d, HFP: %d, HBP: %d, VSW: %d, VFP: %d, VBP: %d\n", in mcde_setup_dpi()
994 * The pixel fetcher is 128 64-bit words deep = 1024 bytes. in mcde_setup_dpi()
1026 writel(val, mcde->regs + MCDE_CONF0); in mcde_setup_dpi()
1029 writel(0, mcde->regs + MCDE_TVCRA); in mcde_setup_dpi()
1034 writel(val, mcde->regs + MCDE_TVBL1A); in mcde_setup_dpi()
1036 writel(val, mcde->regs + MCDE_TVBL2A); in mcde_setup_dpi()
1042 writel(val, mcde->regs + MCDE_TVDVOA); in mcde_setup_dpi()
1045 writel((hbp - 1), mcde->regs + MCDE_TVTIM1A); in mcde_setup_dpi()
1048 val = ((hsw - 1) << MCDE_TVLBALW_LBW_SHIFT); in mcde_setup_dpi()
1049 val |= ((hfp - 1) << MCDE_TVLBALW_ALW_SHIFT); in mcde_setup_dpi()
1050 writel(val, mcde->regs + MCDE_TVLBALWA); in mcde_setup_dpi()
1053 writel(0, mcde->regs + MCDE_TVISLA); in mcde_setup_dpi()
1054 writel(0, mcde->regs + MCDE_TVBLUA); in mcde_setup_dpi()
1058 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in mcde_setup_dpi()
1060 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in mcde_setup_dpi()
1062 if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) in mcde_setup_dpi()
1064 if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) in mcde_setup_dpi()
1066 writel(val, mcde->regs + MCDE_LCDTIM1A); in mcde_setup_dpi()
1069 static void mcde_setup_dsi(struct mcde *mcde, const struct drm_display_mode *mode, in mcde_setup_dsi() argument
1073 u32 formatter_ppl = mode->hdisplay; /* pixels per line */ in mcde_setup_dsi()
1074 u32 formatter_lpf = mode->vdisplay; /* lines per frame */ in mcde_setup_dsi()
1082 dev_info(mcde->dev, "output in %s mode, format %dbpp\n", in mcde_setup_dsi()
1083 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? in mcde_setup_dsi()
1085 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format)); in mcde_setup_dsi()
1087 mipi_dsi_pixel_format_to_bpp(mcde->mdsi->format) / 8; in mcde_setup_dsi()
1088 dev_info(mcde->dev, "Overlay CPP: %d bytes, DSI formatter CPP %d bytes\n", in mcde_setup_dsi()
1097 * this at all (we are using DSI) these are just in mcde_setup_dsi()
1105 writel(val, mcde->regs + MCDE_CONF0); in mcde_setup_dsi()
1118 fifo_wtrmrk = mode->hdisplay; in mcde_setup_dsi()
1119 if (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) { in mcde_setup_dsi()
1125 pkt_div = mcde_dsi_get_pkt_div(mode->hdisplay, 640); in mcde_setup_dsi()
1127 dev_dbg(mcde->dev, "FIFO watermark after flooring: %d bytes\n", in mcde_setup_dsi()
1129 dev_dbg(mcde->dev, "Packet divisor: %d bytes\n", pkt_div); in mcde_setup_dsi()
1134 if (!(mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)) in mcde_setup_dsi()
1137 dev_dbg(mcde->dev, "DSI packet size: %d * %d bytes per line\n", in mcde_setup_dsi()
1139 dev_dbg(mcde->dev, "Overlay frame size: %u bytes\n", in mcde_setup_dsi()
1140 mode->hdisplay * mode->vdisplay * cpp); in mcde_setup_dsi()
1143 dev_dbg(mcde->dev, "Formatter frame size: %u bytes\n", formatter_frame); in mcde_setup_dsi()
1154 struct drm_crtc *crtc = &pipe->crtc; in mcde_display_enable()
1155 struct drm_plane *plane = &pipe->plane; in mcde_display_enable()
1156 struct drm_device *drm = crtc->dev; in mcde_display_enable()
1157 struct mcde *mcde = to_mcde(drm); in mcde_display_enable() local
1158 const struct drm_display_mode *mode = &cstate->mode; in mcde_display_enable()
1159 struct drm_framebuffer *fb = plane->state->fb; in mcde_display_enable()
1160 u32 format = fb->format->format; in mcde_display_enable()
1163 int cpp = fb->format->cpp[0]; in mcde_display_enable()
1168 /* This powers up the entire MCDE block and the DSI hardware */ in mcde_display_enable()
1169 ret = regulator_enable(mcde->epod); in mcde_display_enable()
1171 dev_err(drm->dev, "can't re-enable EPOD regulator\n"); in mcde_display_enable()
1175 dev_info(drm->dev, "enable MCDE, %d x %d format %p4cc\n", in mcde_display_enable()
1176 mode->hdisplay, mode->vdisplay, &format); in mcde_display_enable()
1180 mcde_display_disable_irqs(mcde); in mcde_display_enable()
1181 writel(0, mcde->regs + MCDE_IMSCERR); in mcde_display_enable()
1182 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); in mcde_display_enable()
1184 if (mcde->dpi_output) in mcde_display_enable()
1185 mcde_setup_dpi(mcde, mode, &fifo_wtrmrk); in mcde_display_enable()
1187 mcde_setup_dsi(mcde, mode, cpp, &fifo_wtrmrk, in mcde_display_enable()
1190 mcde->stride = mode->hdisplay * cpp; in mcde_display_enable()
1191 dev_dbg(drm->dev, "Overlay line stride: %u bytes\n", in mcde_display_enable()
1192 mcde->stride); in mcde_display_enable()
1195 mcde_drain_pipe(mcde, MCDE_FIFO_A, MCDE_CHANNEL_0); in mcde_display_enable()
1199 * EXTSRC 0 -> OVERLAY 0 -> CHANNEL 0 -> FIFO A -> DSI FORMATTER 0 in mcde_display_enable()
1204 mcde_configure_extsrc(mcde, MCDE_EXTSRC_0, format); in mcde_display_enable()
1211 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0, in mcde_display_enable()
1215 * Configure pixel-per-line and line-per-frame for channel 0 and then in mcde_display_enable()
1218 mcde_configure_channel(mcde, MCDE_CHANNEL_0, MCDE_FIFO_A, mode); in mcde_display_enable()
1220 if (mcde->dpi_output) { in mcde_display_enable()
1224 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DPI_FORMATTER_0, in mcde_display_enable()
1228 lcd_freq = clk_round_rate(mcde->fifoa_clk, mode->clock * 1000); in mcde_display_enable()
1229 ret = clk_set_rate(mcde->fifoa_clk, lcd_freq); in mcde_display_enable()
1231 dev_err(mcde->dev, "failed to set LCD clock rate %lu Hz\n", in mcde_display_enable()
1233 ret = clk_prepare_enable(mcde->fifoa_clk); in mcde_display_enable()
1235 dev_err(mcde->dev, "failed to enable FIFO A DPI clock\n"); in mcde_display_enable()
1238 dev_info(mcde->dev, "LCD FIFO A clk rate %lu Hz\n", in mcde_display_enable()
1239 clk_get_rate(mcde->fifoa_clk)); in mcde_display_enable()
1241 /* Configure FIFO A to use DSI formatter 0 */ in mcde_display_enable()
1242 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0, in mcde_display_enable()
1246 * This brings up the DSI bridge which is tightly connected in mcde_display_enable()
1247 * to the MCDE DSI formatter. in mcde_display_enable()
1249 mcde_dsi_enable(mcde->bridge); in mcde_display_enable()
1251 /* Configure the DSI formatter 0 for the DSI panel output */ in mcde_display_enable()
1252 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0, in mcde_display_enable()
1256 switch (mcde->flow_mode) { in mcde_display_enable()
1261 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in mcde_display_enable()
1265 writel(val, mcde->regs + MCDE_VSCRC0); in mcde_display_enable()
1267 val = readl(mcde->regs + MCDE_CRC); in mcde_display_enable()
1269 writel(val, mcde->regs + MCDE_CRC); in mcde_display_enable()
1286 if (mcde->flow_mode != MCDE_COMMAND_ONESHOT_FLOW) { in mcde_display_enable()
1287 mcde_enable_fifo(mcde, MCDE_FIFO_A); in mcde_display_enable()
1288 dev_dbg(mcde->dev, "started MCDE video FIFO flow\n"); in mcde_display_enable()
1291 /* Enable MCDE with automatic clock gating */ in mcde_display_enable()
1292 val = readl(mcde->regs + MCDE_CR); in mcde_display_enable()
1294 writel(val, mcde->regs + MCDE_CR); in mcde_display_enable()
1296 dev_info(drm->dev, "MCDE display is enabled\n"); in mcde_display_enable()
1301 struct drm_crtc *crtc = &pipe->crtc; in mcde_display_disable()
1302 struct drm_device *drm = crtc->dev; in mcde_display_disable()
1303 struct mcde *mcde = to_mcde(drm); in mcde_display_disable() local
1310 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); in mcde_display_disable()
1312 if (mcde->dpi_output) { in mcde_display_disable()
1313 clk_disable_unprepare(mcde->fifoa_clk); in mcde_display_disable()
1315 /* This disables the DSI bridge */ in mcde_display_disable()
1316 mcde_dsi_disable(mcde->bridge); in mcde_display_disable()
1319 event = crtc->state->event; in mcde_display_disable()
1321 crtc->state->event = NULL; in mcde_display_disable()
1323 spin_lock_irq(&crtc->dev->event_lock); in mcde_display_disable()
1325 spin_unlock_irq(&crtc->dev->event_lock); in mcde_display_disable()
1328 ret = regulator_disable(mcde->epod); in mcde_display_disable()
1330 dev_err(drm->dev, "can't disable EPOD regulator\n"); in mcde_display_disable()
1334 dev_info(drm->dev, "MCDE display is disabled\n"); in mcde_display_disable()
1337 static void mcde_start_flow(struct mcde *mcde) in mcde_start_flow() argument
1340 if (mcde->flow_mode == MCDE_COMMAND_BTA_TE_FLOW) in mcde_start_flow()
1341 mcde_dsi_te_request(mcde->mdsi); in mcde_start_flow()
1344 mcde_enable_fifo(mcde, MCDE_FIFO_A); in mcde_start_flow()
1353 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) { in mcde_start_flow()
1356 mcde->regs + MCDE_CHNL0SYNCHSW); in mcde_start_flow()
1365 mcde_disable_fifo(mcde, MCDE_FIFO_A, true); in mcde_start_flow()
1368 dev_dbg(mcde->dev, "started MCDE FIFO flow\n"); in mcde_start_flow()
1371 static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address) in mcde_set_extsrc() argument
1374 writel(buffer_address, mcde->regs + MCDE_EXTSRCXA0); in mcde_set_extsrc()
1379 writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1); in mcde_set_extsrc()
1385 struct drm_crtc *crtc = &pipe->crtc; in mcde_display_update()
1386 struct drm_device *drm = crtc->dev; in mcde_display_update()
1387 struct mcde *mcde = to_mcde(drm); in mcde_display_update() local
1388 struct drm_pending_vblank_event *event = crtc->state->event; in mcde_display_update()
1389 struct drm_plane *plane = &pipe->plane; in mcde_display_update()
1390 struct drm_plane_state *pstate = plane->state; in mcde_display_update()
1391 struct drm_framebuffer *fb = pstate->fb; in mcde_display_update()
1399 crtc->state->event = NULL; in mcde_display_update()
1401 spin_lock_irq(&crtc->dev->event_lock); in mcde_display_update()
1406 * until we get an update. If MCDE output isn't yet enabled, in mcde_display_update()
1409 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) { in mcde_display_update()
1410 dev_dbg(mcde->dev, "arm vblank event\n"); in mcde_display_update()
1413 dev_dbg(mcde->dev, "insert fake vblank event\n"); in mcde_display_update()
1417 spin_unlock_irq(&crtc->dev->event_lock); in mcde_display_update()
1426 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); in mcde_display_update()
1427 dev_info_once(mcde->dev, "first update of display contents\n"); in mcde_display_update()
1432 if (mcde->flow_active == 0) in mcde_display_update()
1433 mcde_start_flow(mcde); in mcde_display_update()
1436 * If an update is receieved before the MCDE is enabled in mcde_display_update()
1440 dev_info(mcde->dev, "ignored a display update\n"); in mcde_display_update()
1446 struct drm_crtc *crtc = &pipe->crtc; in mcde_display_enable_vblank()
1447 struct drm_device *drm = crtc->dev; in mcde_display_enable_vblank()
1448 struct mcde *mcde = to_mcde(drm); in mcde_display_enable_vblank() local
1458 writel(val, mcde->regs + MCDE_IMSCPP); in mcde_display_enable_vblank()
1465 struct drm_crtc *crtc = &pipe->crtc; in mcde_display_disable_vblank()
1466 struct drm_device *drm = crtc->dev; in mcde_display_disable_vblank()
1467 struct mcde *mcde = to_mcde(drm); in mcde_display_disable_vblank() local
1470 writel(0, mcde->regs + MCDE_IMSCPP); in mcde_display_disable_vblank()
1472 writel(0xFFFFFFFF, mcde->regs + MCDE_RISPP); in mcde_display_disable_vblank()
1486 struct mcde *mcde = to_mcde(drm); in mcde_display_init() local
1507 ret = mcde_init_clock_divider(mcde); in mcde_display_init()
1511 ret = drm_simple_display_pipe_init(drm, &mcde->pipe, in mcde_display_init()
1515 mcde->connector); in mcde_display_init()