Lines Matching +full:display +full:- +full:bridge

1 // SPDX-License-Identifier: GPL-2.0
5 * (C) ST-Ericsson SA 2013
9 * DOC: ST-Ericsson MCDE Driver
11 * The MCDE (short for multi-channel display engine) is a graphics
15 * ST-Ericsson U8500 where is was used for mass-market deployments
18 * It can do 1080p30 on SDTV CCIR656, DPI-2, DBI-2 or DSI for
22 * The hardware has four display pipes, and the layout is a little
25 * Memory -> Overlay -> Channel -> FIFO -> 8 formatters -> DSI/DPI
26 * External 0..5 0..3 A,B, 6 x DSI bridge
36 * DPI port, it is possible to configure up to 4 display pipelines
41 * helpers. We then provide a bridge to the DSI port, and on the DSI port
42 * bridge we connect hang a panel bridge or other bridge. This may be subject
47 * - Enabled damaged rectangles using drm_plane_enable_fb_damage_clips()
49 * command-only display.
50 * - Enable mixing of more planes, possibly at the cost of moving away
52 * - Enable output to bridges such as the AV8100 HDMI encoder from
53 * the DSI bridge.
58 #include <linux/dma-buf.h>
117 val = readl(mcde->regs + MCDE_MISERR); in mcde_irq()
122 dev_info(mcde->dev, "some error IRQ\n"); in mcde_irq()
123 writel(val, mcde->regs + MCDE_RISERR); in mcde_irq()
135 * If no other bridge was found, check if we have a DPI panel or in mcde_modeset_init()
136 * any other bridge connected directly to the MCDE DPI output. in mcde_modeset_init()
137 * If a DSI bridge is found, DSI will take precedence. in mcde_modeset_init()
139 * TODO: more elaborate bridge selection if we have more than one in mcde_modeset_init()
142 if (!mcde->bridge) { in mcde_modeset_init()
144 struct drm_bridge *bridge; in mcde_modeset_init() local
146 ret = drm_of_find_panel_or_bridge(drm->dev->of_node, in mcde_modeset_init()
147 0, 0, &panel, &bridge); in mcde_modeset_init()
149 dev_err(drm->dev, in mcde_modeset_init()
150 "Could not locate any output bridge or panel\n"); in mcde_modeset_init()
154 bridge = drm_panel_bridge_add_typed(panel, in mcde_modeset_init()
156 if (IS_ERR(bridge)) { in mcde_modeset_init()
157 dev_err(drm->dev, in mcde_modeset_init()
158 "Could not connect panel bridge\n"); in mcde_modeset_init()
159 return PTR_ERR(bridge); in mcde_modeset_init()
162 mcde->dpi_output = true; in mcde_modeset_init()
163 mcde->bridge = bridge; in mcde_modeset_init()
164 mcde->flow_mode = MCDE_DPI_FORMATTER_FLOW; in mcde_modeset_init()
167 mode_config = &drm->mode_config; in mcde_modeset_init()
168 mode_config->funcs = &mcde_mode_config_funcs; in mcde_modeset_init()
169 mode_config->helper_private = &mcde_mode_config_helpers; in mcde_modeset_init()
171 mode_config->min_width = 1; in mcde_modeset_init()
172 mode_config->max_width = 1920; in mcde_modeset_init()
173 mode_config->min_height = 1; in mcde_modeset_init()
174 mode_config->max_height = 1080; in mcde_modeset_init()
178 dev_err(drm->dev, "failed to init vblank\n"); in mcde_modeset_init()
184 dev_err(drm->dev, "failed to init display\n"); in mcde_modeset_init()
188 /* Attach the bridge. */ in mcde_modeset_init()
189 ret = drm_simple_display_pipe_attach_bridge(&mcde->pipe, in mcde_modeset_init()
190 mcde->bridge); in mcde_modeset_init()
192 dev_err(drm->dev, "failed to attach display output bridge\n"); in mcde_modeset_init()
227 ret = component_bind_all(drm->dev, drm); in mcde_drm_bind()
246 component_unbind_all(drm->dev, drm); in mcde_drm_bind()
256 component_unbind_all(drm->dev, drm); in mcde_drm_unbind()
270 struct device *dev = &pdev->dev; in mcde_probe()
282 drm = &mcde->drm; in mcde_probe()
283 mcde->dev = dev; in mcde_probe()
287 mcde->epod = devm_regulator_get(dev, "epod"); in mcde_probe()
288 if (IS_ERR(mcde->epod)) { in mcde_probe()
289 ret = PTR_ERR(mcde->epod); in mcde_probe()
293 ret = regulator_enable(mcde->epod); in mcde_probe()
298 mcde->vana = devm_regulator_get(dev, "vana"); in mcde_probe()
299 if (IS_ERR(mcde->vana)) { in mcde_probe()
300 ret = PTR_ERR(mcde->vana); in mcde_probe()
304 ret = regulator_enable(mcde->vana); in mcde_probe()
311 * the v-esram34 regulator, but we don't use that yet in mcde_probe()
315 mcde->mcde_clk = devm_clk_get(dev, "mcde"); in mcde_probe()
316 if (IS_ERR(mcde->mcde_clk)) { in mcde_probe()
318 ret = PTR_ERR(mcde->mcde_clk); in mcde_probe()
321 ret = clk_prepare_enable(mcde->mcde_clk); in mcde_probe()
326 dev_info(dev, "MCDE clk rate %lu Hz\n", clk_get_rate(mcde->mcde_clk)); in mcde_probe()
328 mcde->lcd_clk = devm_clk_get(dev, "lcd"); in mcde_probe()
329 if (IS_ERR(mcde->lcd_clk)) { in mcde_probe()
331 ret = PTR_ERR(mcde->lcd_clk); in mcde_probe()
334 mcde->hdmi_clk = devm_clk_get(dev, "hdmi"); in mcde_probe()
335 if (IS_ERR(mcde->hdmi_clk)) { in mcde_probe()
337 ret = PTR_ERR(mcde->hdmi_clk); in mcde_probe()
341 mcde->regs = devm_platform_ioremap_resource(pdev, 0); in mcde_probe()
342 if (IS_ERR(mcde->regs)) { in mcde_probe()
344 ret = -EINVAL; in mcde_probe()
366 pid = readl(mcde->regs + MCDE_PID); in mcde_probe()
378 ret = -ENODEV; in mcde_probe()
384 writel(0, mcde->regs + MCDE_IMSCERR); in mcde_probe()
385 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); in mcde_probe()
392 struct device_driver *drv = &mcde_component_drivers[i]->driver; in mcde_probe()
404 ret = -ENODEV; in mcde_probe()
416 * later when we enable the display as a result of in mcde_probe()
419 ret = regulator_disable(mcde->epod); in mcde_probe()
427 ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops, in mcde_probe()
435 clk_disable_unprepare(mcde->mcde_clk); in mcde_probe()
436 regulator_disable(mcde->vana); in mcde_probe()
443 clk_disable_unprepare(mcde->mcde_clk); in mcde_probe()
445 regulator_disable(mcde->vana); in mcde_probe()
447 regulator_disable(mcde->epod); in mcde_probe()
457 component_master_del(&pdev->dev, &mcde_drm_comp_ops); in mcde_remove()
458 clk_disable_unprepare(mcde->mcde_clk); in mcde_remove()
459 regulator_disable(mcde->vana); in mcde_remove()
460 regulator_disable(mcde->epod); in mcde_remove()
467 if (drm->registered) in mcde_shutdown()
498 return -ENODEV; in mcde_drm_register()
518 MODULE_ALIAS("platform:mcde-drm");