Lines Matching +full:zynqmp +full:- +full:dma +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
3 * ZynqMP DisplayPort Subsystem Driver
5 * Copyright (C) 2017 - 2020 Xilinx, Inc.
8 * - Hyun Woo Kwon <[email protected]>
9 * - Laurent Pinchart <[email protected]>
13 #include <linux/dma-mapping.h>
31 /* -----------------------------------------------------------------------------
39 if (!dpsub->drm) in zynqmp_dpsub_suspend()
42 return drm_mode_config_helper_suspend(&dpsub->drm->dev); in zynqmp_dpsub_suspend()
49 if (!dpsub->drm) in zynqmp_dpsub_resume()
52 return drm_mode_config_helper_resume(&dpsub->drm->dev); in zynqmp_dpsub_resume()
59 /* -----------------------------------------------------------------------------
67 dpsub->apb_clk = devm_clk_get(dpsub->dev, "dp_apb_clk"); in zynqmp_dpsub_init_clocks()
68 if (IS_ERR(dpsub->apb_clk)) in zynqmp_dpsub_init_clocks()
69 return PTR_ERR(dpsub->apb_clk); in zynqmp_dpsub_init_clocks()
71 ret = clk_prepare_enable(dpsub->apb_clk); in zynqmp_dpsub_init_clocks()
73 dev_err(dpsub->dev, "failed to enable the APB clock\n"); in zynqmp_dpsub_init_clocks()
81 dpsub->vid_clk = devm_clk_get(dpsub->dev, "dp_live_video_in_clk"); in zynqmp_dpsub_init_clocks()
82 if (!IS_ERR(dpsub->vid_clk)) in zynqmp_dpsub_init_clocks()
83 dpsub->vid_clk_from_ps = false; in zynqmp_dpsub_init_clocks()
84 else if (PTR_ERR(dpsub->vid_clk) == -EPROBE_DEFER) in zynqmp_dpsub_init_clocks()
85 return PTR_ERR(dpsub->vid_clk); in zynqmp_dpsub_init_clocks()
87 if (IS_ERR_OR_NULL(dpsub->vid_clk)) { in zynqmp_dpsub_init_clocks()
88 dpsub->vid_clk = devm_clk_get(dpsub->dev, "dp_vtc_pixel_clk_in"); in zynqmp_dpsub_init_clocks()
89 if (IS_ERR(dpsub->vid_clk)) { in zynqmp_dpsub_init_clocks()
90 dev_err(dpsub->dev, "failed to init any video clock\n"); in zynqmp_dpsub_init_clocks()
91 return PTR_ERR(dpsub->vid_clk); in zynqmp_dpsub_init_clocks()
93 dpsub->vid_clk_from_ps = true; in zynqmp_dpsub_init_clocks()
101 dpsub->aud_clk = devm_clk_get(dpsub->dev, "dp_live_audio_aclk"); in zynqmp_dpsub_init_clocks()
102 if (!IS_ERR(dpsub->aud_clk)) { in zynqmp_dpsub_init_clocks()
103 dpsub->aud_clk_from_ps = false; in zynqmp_dpsub_init_clocks()
107 dpsub->aud_clk = devm_clk_get(dpsub->dev, "dp_aud_clk"); in zynqmp_dpsub_init_clocks()
108 if (!IS_ERR(dpsub->aud_clk)) { in zynqmp_dpsub_init_clocks()
109 dpsub->aud_clk_from_ps = true; in zynqmp_dpsub_init_clocks()
113 dev_info(dpsub->dev, "audio disabled due to missing clock\n"); in zynqmp_dpsub_init_clocks()
127 np = of_get_child_by_name(dpsub->dev->of_node, "ports"); in zynqmp_dpsub_parse_dt()
130 dev_warn(dpsub->dev, "missing ports, update DT bindings\n"); in zynqmp_dpsub_parse_dt()
131 dpsub->connected_ports = BIT(ZYNQMP_DPSUB_PORT_OUT_DP); in zynqmp_dpsub_parse_dt()
132 dpsub->dma_enabled = true; in zynqmp_dpsub_parse_dt()
140 np = of_graph_get_remote_node(dpsub->dev->of_node, i, -1); in zynqmp_dpsub_parse_dt()
142 dpsub->connected_ports |= BIT(i); in zynqmp_dpsub_parse_dt()
148 if ((dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO)) && in zynqmp_dpsub_parse_dt()
149 (dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX))) { in zynqmp_dpsub_parse_dt()
150 dev_err(dpsub->dev, "only one live video input is supported\n"); in zynqmp_dpsub_parse_dt()
151 return -EINVAL; in zynqmp_dpsub_parse_dt()
154 if ((dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO)) || in zynqmp_dpsub_parse_dt()
155 (dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX))) { in zynqmp_dpsub_parse_dt()
156 if (dpsub->vid_clk_from_ps) { in zynqmp_dpsub_parse_dt()
157 dev_err(dpsub->dev, in zynqmp_dpsub_parse_dt()
159 return -EINVAL; in zynqmp_dpsub_parse_dt()
162 dpsub->dma_enabled = true; in zynqmp_dpsub_parse_dt()
165 if (dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_AUDIO)) in zynqmp_dpsub_parse_dt()
166 dev_warn(dpsub->dev, "live audio unsupported, ignoring\n"); in zynqmp_dpsub_parse_dt()
168 if ((dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_OUT_VIDEO)) || in zynqmp_dpsub_parse_dt()
169 (dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_OUT_AUDIO))) in zynqmp_dpsub_parse_dt()
170 dev_warn(dpsub->dev, "output to PL unsupported, ignoring\n"); in zynqmp_dpsub_parse_dt()
172 if (!(dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_OUT_DP))) { in zynqmp_dpsub_parse_dt()
173 dev_err(dpsub->dev, "DP output port not connected\n"); in zynqmp_dpsub_parse_dt()
174 return -EINVAL; in zynqmp_dpsub_parse_dt()
182 kfree(dpsub->disp); in zynqmp_dpsub_release()
183 kfree(dpsub->dp); in zynqmp_dpsub_release()
195 return -ENOMEM; in zynqmp_dpsub_probe()
197 dpsub->dev = &pdev->dev; in zynqmp_dpsub_probe()
200 ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT)); in zynqmp_dpsub_probe()
204 dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); in zynqmp_dpsub_probe()
207 of_reserved_mem_device_init(&pdev->dev); in zynqmp_dpsub_probe()
217 pm_runtime_enable(&pdev->dev); in zynqmp_dpsub_probe()
231 drm_bridge_add(dpsub->bridge); in zynqmp_dpsub_probe()
233 if (dpsub->dma_enabled) { in zynqmp_dpsub_probe()
243 dev_info(&pdev->dev, "ZynqMP DisplayPort Subsystem driver probed"); in zynqmp_dpsub_probe()
248 if (dpsub->drm) in zynqmp_dpsub_probe()
251 drm_bridge_remove(dpsub->bridge); in zynqmp_dpsub_probe()
256 pm_runtime_disable(&pdev->dev); in zynqmp_dpsub_probe()
257 clk_disable_unprepare(dpsub->apb_clk); in zynqmp_dpsub_probe()
259 of_reserved_mem_device_release(&pdev->dev); in zynqmp_dpsub_probe()
260 if (!dpsub->drm) in zynqmp_dpsub_probe()
271 if (dpsub->drm) in zynqmp_dpsub_remove()
274 drm_bridge_remove(dpsub->bridge); in zynqmp_dpsub_remove()
278 pm_runtime_disable(&pdev->dev); in zynqmp_dpsub_remove()
279 clk_disable_unprepare(dpsub->apb_clk); in zynqmp_dpsub_remove()
280 of_reserved_mem_device_release(&pdev->dev); in zynqmp_dpsub_remove()
282 if (!dpsub->drm) in zynqmp_dpsub_remove()
290 if (!dpsub->drm) in zynqmp_dpsub_shutdown()
293 drm_atomic_helper_shutdown(&dpsub->drm->dev); in zynqmp_dpsub_shutdown()
297 { .compatible = "xlnx,zynqmp-dpsub-1.7", },
307 .name = "zynqmp-dpsub",
316 MODULE_DESCRIPTION("ZynqMP DP Subsystem Driver");