Lines Matching +full:audio +full:- +full:video

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017 - 2020 Xilinx, Inc.
8 * - Hyun Woo Kwon <hyun.kwon@xilinx.com>
9 * - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
27 #include <linux/dma-mapping.h>
43 * --------
45 * The display controller part of ZynqMP DP subsystem, made of the Audio/Video
46 * Buffer Manager, the Video Rendering Pipeline (blender) and the Audio Mixer.
48 * +------------------------------------------------------------+
49 * +--------+ | +----------------+ +-----------+ |
50 * | DPDMA | --->| | --> | Video | Video +-------------+ |
51 * | 4x vid | | | | | Rendering | -+--> | | | +------+
52 * | 2x aud | | | Audio/Video | --> | Pipeline | | | DisplayPort |---> | PHY0 |
53 * +--------+ | | Buffer Manager | +-----------+ | | Source | | +------+
54 * | | and STC | +-----------+ | | Controller | | +------+
55 * Live Video --->| | --> | Audio | Audio | |---> | PHY1 |
56 * | | | | Mixer | --+-> | | | +------+
57 * Live Audio --->| | --> | | || +-------------+ |
58 * | +----------------+ +-----------+ || |
59 * +---------------------------------------||-------------------+
61 * Blended Video and
62 * Mixed Audio to PL
64 * Only non-live input from the DPDMA and output to the DisplayPort Source
68 * The display controller code creates planes for the DPDMA video and graphics
69 * layers, and a CRTC for the Video Rendering Pipeline.
79 * struct zynqmp_disp_format - Display subsystem format information
95 * enum zynqmp_disp_id - Layer identifier
96 * @ZYNQMP_DISP_LAYER_VID: Video layer
105 * enum zynqmp_disp_layer_mode - Layer mode
106 * @ZYNQMP_DISP_LAYER_NONLIVE: non-live (memory) mode
115 * struct zynqmp_disp_layer_dma - DMA channel for one data plane of a layer
127 * struct zynqmp_disp_layer_info - Static layer information
139 * struct zynqmp_disp_layer - Display layer (DRM plane)
163 * struct zynqmp_disp_blend - Blender
171 * struct zynqmp_disp_avbuf - Audio/video buffer manager
179 * struct zynqmp_disp_audio - Audio mixer
181 * @clk: Audio clock
182 * @clk_from_ps: True of the audio clock comes from PS, false from PL
191 * struct zynqmp_disp - Display controller
196 * @blend: Blender (video rendering pipeline)
197 * @avbuf: Audio/video buffer manager
198 * @audio: Audio mixer
202 * @pclk_from_ps: True of the video clock comes from PS, false from PL
213 struct zynqmp_disp_audio audio; member
223 /* -----------------------------------------------------------------------------
224 * Audio/Video Buffer Manager
257 /* List of video layer formats */
429 return readl(avbuf->base + reg); in zynqmp_disp_avbuf_read()
435 writel(val, avbuf->base + reg); in zynqmp_disp_avbuf_write()
439 * zynqmp_disp_avbuf_set_format - Set the input format for a layer
440 * @avbuf: Audio/video buffer manager
444 * Set the video buffer manager format for @layer to @fmt.
457 val |= fmt->buf_fmt; in zynqmp_disp_avbuf_set_format()
465 zynqmp_disp_avbuf_write(avbuf, reg, fmt->sf[i]); in zynqmp_disp_avbuf_set_format()
470 * zynqmp_disp_avbuf_set_clocks_sources - Set the clocks sources
471 * @avbuf: Audio/video buffer manager
472 * @video_from_ps: True if the video clock originates from the PS
473 * @audio_from_ps: True if the audio clock originates from the PS
474 * @timings_internal: True if video timings are generated internally
476 * Set the source for the video and audio clocks, as well as for the video
498 * zynqmp_disp_avbuf_enable_channels - Enable buffer channels
499 * @avbuf: Audio/video buffer manager
501 * Enable all (video and audio) buffer channels.
526 * zynqmp_disp_avbuf_disable_channels - Disable buffer channels
527 * @avbuf: Audio/video buffer manager
529 * Disable all (video and audio) buffer channels.
541 * zynqmp_disp_avbuf_enable_audio - Enable audio
542 * @avbuf: Audio/video buffer manager
544 * Enable all audio buffers with a non-live (memory) source.
558 * zynqmp_disp_avbuf_disable_audio - Disable audio
559 * @avbuf: Audio/video buffer manager
561 * Disable all audio buffers.
575 * zynqmp_disp_avbuf_enable_video - Enable a video layer
576 * @avbuf: Audio/video buffer manager
580 * Enable the video/graphics buffer for @layer.
607 * zynqmp_disp_avbuf_disable_video - Disable a video layer
608 * @avbuf: Audio/video buffer manager
611 * Disable the video/graphics buffer for @layer.
630 * zynqmp_disp_avbuf_enable - Enable the video pipe
631 * @avbuf: Audio/video buffer manager
633 * De-assert the video pipe reset.
641 * zynqmp_disp_avbuf_disable - Disable the video pipe
642 * @avbuf: Audio/video buffer manager
644 * Assert the video pipe reset.
652 /* -----------------------------------------------------------------------------
653 * Blender (Video Pipeline)
659 writel(val, blend->base + reg); in zynqmp_disp_blend_write()
665 * Hardcode RGB <-> YUV conversion to full-range SDTV for now.
704 * zynqmp_disp_blend_set_output_format - Set the output format of the blender
747 * zynqmp_disp_blend_set_bg_color - Set the background color
766 * zynqmp_disp_blend_set_global_alpha - Configure global alpha blending
780 * zynqmp_disp_blend_layer_set_csc - Configure colorspace conversion for layer
799 if (layer->disp_fmt->swap) { in zynqmp_disp_blend_layer_set_csc()
800 if (layer->drm_fmt->is_yuv) { in zynqmp_disp_blend_layer_set_csc()
811 if (layer->id == ZYNQMP_DISP_LAYER_VID) in zynqmp_disp_blend_layer_set_csc()
822 if (layer->id == ZYNQMP_DISP_LAYER_VID) in zynqmp_disp_blend_layer_set_csc()
832 * zynqmp_disp_blend_layer_enable - Enable a layer
843 val = (layer->drm_fmt->is_yuv ? in zynqmp_disp_blend_layer_enable()
845 (layer->drm_fmt->hsub > 1 ? in zynqmp_disp_blend_layer_enable()
849 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id), in zynqmp_disp_blend_layer_enable()
852 if (layer->drm_fmt->is_yuv) { in zynqmp_disp_blend_layer_enable()
864 * zynqmp_disp_blend_layer_disable - Disable a layer
872 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id), in zynqmp_disp_blend_layer_disable()
879 /* -----------------------------------------------------------------------------
880 * Audio Mixer
883 static void zynqmp_disp_audio_write(struct zynqmp_disp_audio *audio, in zynqmp_disp_audio_write() argument
886 writel(val, audio->base + reg); in zynqmp_disp_audio_write()
890 * zynqmp_disp_audio_enable - Enable the audio mixer
891 * @audio: Audio mixer
893 * Enable the audio mixer by de-asserting the soft reset. The audio state is set to
896 static void zynqmp_disp_audio_enable(struct zynqmp_disp_audio *audio) in zynqmp_disp_audio_enable() argument
898 /* Clear the audio soft reset register as it's an non-reset flop. */ in zynqmp_disp_audio_enable()
899 zynqmp_disp_audio_write(audio, ZYNQMP_DISP_AUD_SOFT_RESET, 0); in zynqmp_disp_audio_enable()
900 zynqmp_disp_audio_write(audio, ZYNQMP_DISP_AUD_MIXER_VOLUME, in zynqmp_disp_audio_enable()
905 * zynqmp_disp_audio_disable - Disable the audio mixer
906 * @audio: Audio mixer
908 * Disable the audio mixer by asserting its soft reset.
910 static void zynqmp_disp_audio_disable(struct zynqmp_disp_audio *audio) in zynqmp_disp_audio_disable() argument
912 zynqmp_disp_audio_write(audio, ZYNQMP_DISP_AUD_SOFT_RESET, in zynqmp_disp_audio_disable()
917 struct zynqmp_disp_audio *audio) in zynqmp_disp_audio_init() argument
919 /* Try the live PL audio clock. */ in zynqmp_disp_audio_init()
920 audio->clk = devm_clk_get(dev, "dp_live_audio_aclk"); in zynqmp_disp_audio_init()
921 if (!IS_ERR(audio->clk)) { in zynqmp_disp_audio_init()
922 audio->clk_from_ps = false; in zynqmp_disp_audio_init()
926 /* If the live PL audio clock is not valid, fall back to PS clock. */ in zynqmp_disp_audio_init()
927 audio->clk = devm_clk_get(dev, "dp_aud_clk"); in zynqmp_disp_audio_init()
928 if (!IS_ERR(audio->clk)) { in zynqmp_disp_audio_init()
929 audio->clk_from_ps = true; in zynqmp_disp_audio_init()
933 dev_err(dev, "audio disabled due to missing clock\n"); in zynqmp_disp_audio_init()
936 /* -----------------------------------------------------------------------------
941 * zynqmp_disp_handle_vblank - Handle the vblank event
949 struct drm_crtc *crtc = &disp->crtc; in zynqmp_disp_handle_vblank()
955 * zynqmp_disp_audio_enabled - If the audio is enabled
958 * Return if the audio is enabled depending on the audio clock.
960 * Return: true if audio is enabled, or false.
964 return !!disp->audio.clk; in zynqmp_disp_audio_enabled()
968 * zynqmp_disp_get_audio_clk_rate - Get the current audio clock rate
971 * Return: the current audio clock rate.
977 return clk_get_rate(disp->audio.clk); in zynqmp_disp_get_audio_clk_rate()
981 * zynqmp_disp_get_crtc_mask - Return the CRTC bit mask
988 return drm_crtc_mask(&disp->crtc); in zynqmp_disp_get_crtc_mask()
991 /* -----------------------------------------------------------------------------
996 * zynqmp_disp_layer_find_format - Find format information for a DRM format
1012 for (i = 0; i < layer->info->num_formats; i++) { in zynqmp_disp_layer_find_format()
1013 if (layer->info->formats[i].drm_fmt == drm_fmt) in zynqmp_disp_layer_find_format()
1014 return &layer->info->formats[i]; in zynqmp_disp_layer_find_format()
1021 * zynqmp_disp_layer_enable - Enable a layer
1024 * Enable the @layer in the audio/video buffer manager and the blender. DMA
1029 zynqmp_disp_avbuf_enable_video(&layer->disp->avbuf, layer->id, in zynqmp_disp_layer_enable()
1031 zynqmp_disp_blend_layer_enable(&layer->disp->blend, layer); in zynqmp_disp_layer_enable()
1033 layer->mode = ZYNQMP_DISP_LAYER_NONLIVE; in zynqmp_disp_layer_enable()
1037 * zynqmp_disp_layer_disable - Disable the layer
1041 * audio/video buffer manager and the blender.
1047 for (i = 0; i < layer->drm_fmt->num_planes; i++) in zynqmp_disp_layer_disable()
1048 dmaengine_terminate_sync(layer->dmas[i].chan); in zynqmp_disp_layer_disable()
1050 zynqmp_disp_avbuf_disable_video(&layer->disp->avbuf, layer->id); in zynqmp_disp_layer_disable()
1051 zynqmp_disp_blend_layer_disable(&layer->disp->blend, layer); in zynqmp_disp_layer_disable()
1055 * zynqmp_disp_layer_set_format - Set the layer format
1059 * Set the format for @layer based on @state->fb->format. The layer must be
1065 const struct drm_format_info *info = state->fb->format; in zynqmp_disp_layer_set_format()
1068 layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format); in zynqmp_disp_layer_set_format()
1069 layer->drm_fmt = info; in zynqmp_disp_layer_set_format()
1071 zynqmp_disp_avbuf_set_format(&layer->disp->avbuf, layer->id, in zynqmp_disp_layer_set_format()
1072 layer->disp_fmt); in zynqmp_disp_layer_set_format()
1076 * video group. in zynqmp_disp_layer_set_format()
1078 for (i = 0; i < info->num_planes; i++) { in zynqmp_disp_layer_set_format()
1079 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_set_format()
1085 dmaengine_slave_config(dma->chan, &config); in zynqmp_disp_layer_set_format()
1090 * zynqmp_disp_layer_update - Update the layer framebuffer
1102 const struct drm_format_info *info = layer->drm_fmt; in zynqmp_disp_layer_update()
1105 for (i = 0; i < layer->drm_fmt->num_planes; i++) { in zynqmp_disp_layer_update()
1106 unsigned int width = state->crtc_w / (i ? info->hsub : 1); in zynqmp_disp_layer_update()
1107 unsigned int height = state->crtc_h / (i ? info->vsub : 1); in zynqmp_disp_layer_update()
1108 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_update()
1112 paddr = drm_fb_cma_get_gem_addr(state->fb, state, i); in zynqmp_disp_layer_update()
1114 dma->xt.numf = height; in zynqmp_disp_layer_update()
1115 dma->sgl.size = width * info->cpp[i]; in zynqmp_disp_layer_update()
1116 dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size; in zynqmp_disp_layer_update()
1117 dma->xt.src_start = paddr; in zynqmp_disp_layer_update()
1118 dma->xt.frame_size = 1; in zynqmp_disp_layer_update()
1119 dma->xt.dir = DMA_MEM_TO_DEV; in zynqmp_disp_layer_update()
1120 dma->xt.src_sgl = true; in zynqmp_disp_layer_update()
1121 dma->xt.dst_sgl = false; in zynqmp_disp_layer_update()
1123 desc = dmaengine_prep_interleaved_dma(dma->chan, &dma->xt, in zynqmp_disp_layer_update()
1128 dev_err(layer->disp->dev, in zynqmp_disp_layer_update()
1130 return -ENOMEM; in zynqmp_disp_layer_update()
1134 dma_async_issue_pending(dma->chan); in zynqmp_disp_layer_update()
1151 if (!state->crtc) in zynqmp_disp_plane_atomic_check()
1154 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); in zynqmp_disp_plane_atomic_check()
1170 if (!old_state->fb) in zynqmp_disp_plane_atomic_disable()
1183 if (!old_state->fb || in zynqmp_disp_plane_atomic_update()
1184 old_state->fb->format->format != plane->state->fb->format->format) in zynqmp_disp_plane_atomic_update()
1193 if (old_state->fb) in zynqmp_disp_plane_atomic_update()
1196 zynqmp_disp_layer_set_format(layer, plane->state); in zynqmp_disp_plane_atomic_update()
1199 zynqmp_disp_layer_update(layer, plane->state); in zynqmp_disp_plane_atomic_update()
1201 /* Enable or re-enable the plane is the format has changed. */ in zynqmp_disp_plane_atomic_update()
1227 struct zynqmp_disp_layer *layer = &disp->layers[i]; in zynqmp_disp_create_planes()
1231 drm_formats = drmm_kcalloc(disp->drm, sizeof(*drm_formats), in zynqmp_disp_create_planes()
1232 layer->info->num_formats, in zynqmp_disp_create_planes()
1235 return -ENOMEM; in zynqmp_disp_create_planes()
1237 for (j = 0; j < layer->info->num_formats; ++j) in zynqmp_disp_create_planes()
1238 drm_formats[j] = layer->info->formats[j].drm_fmt; in zynqmp_disp_create_planes()
1240 /* Graphics layer is primary, and video layer is overlay. */ in zynqmp_disp_create_planes()
1243 ret = drm_universal_plane_init(disp->drm, &layer->plane, 0, in zynqmp_disp_create_planes()
1246 layer->info->num_formats, in zynqmp_disp_create_planes()
1251 drm_plane_helper_add(&layer->plane, in zynqmp_disp_create_planes()
1259 * zynqmp_disp_layer_release_dma - Release DMA channels for a layer
1270 if (!layer->info) in zynqmp_disp_layer_release_dma()
1273 for (i = 0; i < layer->info->num_channels; i++) { in zynqmp_disp_layer_release_dma()
1274 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_release_dma()
1276 if (!dma->chan) in zynqmp_disp_layer_release_dma()
1280 dmaengine_terminate_sync(dma->chan); in zynqmp_disp_layer_release_dma()
1281 dma_release_channel(dma->chan); in zynqmp_disp_layer_release_dma()
1286 * zynqmp_disp_destroy_layers - Destroy all layers
1294 zynqmp_disp_layer_release_dma(disp, &disp->layers[i]); in zynqmp_disp_destroy_layers()
1298 * zynqmp_disp_layer_request_dma - Request DMA channels for a layer
1313 for (i = 0; i < layer->info->num_channels; i++) { in zynqmp_disp_layer_request_dma()
1314 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_request_dma()
1318 "%s%u", dma_names[layer->id], i); in zynqmp_disp_layer_request_dma()
1319 dma->chan = of_dma_request_slave_channel(disp->dev->of_node, in zynqmp_disp_layer_request_dma()
1321 if (IS_ERR(dma->chan)) { in zynqmp_disp_layer_request_dma()
1322 dev_err(disp->dev, "failed to request dma channel\n"); in zynqmp_disp_layer_request_dma()
1323 ret = PTR_ERR(dma->chan); in zynqmp_disp_layer_request_dma()
1324 dma->chan = NULL; in zynqmp_disp_layer_request_dma()
1333 * zynqmp_disp_create_layers - Create and initialize all layers
1357 struct zynqmp_disp_layer *layer = &disp->layers[i]; in zynqmp_disp_create_layers()
1359 layer->id = i; in zynqmp_disp_create_layers()
1360 layer->disp = disp; in zynqmp_disp_create_layers()
1361 layer->info = &layer_info[i]; in zynqmp_disp_create_layers()
1375 /* -----------------------------------------------------------------------------
1380 * zynqmp_disp_enable - Enable the display controller
1385 zynqmp_disp_avbuf_enable(&disp->avbuf); in zynqmp_disp_enable()
1387 zynqmp_disp_avbuf_set_clocks_sources(&disp->avbuf, disp->pclk_from_ps, in zynqmp_disp_enable()
1388 disp->audio.clk_from_ps, true); in zynqmp_disp_enable()
1389 zynqmp_disp_avbuf_enable_channels(&disp->avbuf); in zynqmp_disp_enable()
1390 zynqmp_disp_avbuf_enable_audio(&disp->avbuf); in zynqmp_disp_enable()
1392 zynqmp_disp_audio_enable(&disp->audio); in zynqmp_disp_enable()
1396 * zynqmp_disp_disable - Disable the display controller
1401 struct drm_crtc *crtc = &disp->crtc; in zynqmp_disp_disable()
1403 zynqmp_disp_audio_disable(&disp->audio); in zynqmp_disp_disable()
1405 zynqmp_disp_avbuf_disable_audio(&disp->avbuf); in zynqmp_disp_disable()
1406 zynqmp_disp_avbuf_disable_channels(&disp->avbuf); in zynqmp_disp_disable()
1407 zynqmp_disp_avbuf_disable(&disp->avbuf); in zynqmp_disp_disable()
1410 if (crtc->state->event) { in zynqmp_disp_disable()
1411 complete_all(crtc->state->event->base.completion); in zynqmp_disp_disable()
1412 crtc->state->event = NULL; in zynqmp_disp_disable()
1425 unsigned long mode_clock = adjusted_mode->clock * 1000; in zynqmp_disp_crtc_setup_clock()
1430 ret = clk_set_rate(disp->pclk, mode_clock); in zynqmp_disp_crtc_setup_clock()
1432 dev_err(disp->dev, "failed to set a pixel clock\n"); in zynqmp_disp_crtc_setup_clock()
1436 rate = clk_get_rate(disp->pclk); in zynqmp_disp_crtc_setup_clock()
1437 diff = rate - mode_clock; in zynqmp_disp_crtc_setup_clock()
1439 dev_info(disp->dev, in zynqmp_disp_crtc_setup_clock()
1443 dev_dbg(disp->dev, in zynqmp_disp_crtc_setup_clock()
1455 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; in zynqmp_disp_crtc_atomic_enable()
1460 pm_runtime_get_sync(disp->dev); in zynqmp_disp_crtc_atomic_enable()
1461 ret = clk_prepare_enable(disp->pclk); in zynqmp_disp_crtc_atomic_enable()
1463 dev_err(disp->dev, "failed to enable a pixel clock\n"); in zynqmp_disp_crtc_atomic_enable()
1464 pm_runtime_put_sync(disp->dev); in zynqmp_disp_crtc_atomic_enable()
1468 zynqmp_disp_blend_set_output_format(&disp->blend, in zynqmp_disp_crtc_atomic_enable()
1470 zynqmp_disp_blend_set_bg_color(&disp->blend, 0, 0, 0); in zynqmp_disp_crtc_atomic_enable()
1471 zynqmp_disp_blend_set_global_alpha(&disp->blend, false, 0); in zynqmp_disp_crtc_atomic_enable()
1476 vrefresh = (adjusted_mode->clock * 1000) / in zynqmp_disp_crtc_atomic_enable()
1477 (adjusted_mode->vtotal * adjusted_mode->htotal); in zynqmp_disp_crtc_atomic_enable()
1493 old_plane_state = drm_atomic_get_old_plane_state(old_crtc_state->state, in zynqmp_disp_crtc_atomic_disable()
1494 crtc->primary); in zynqmp_disp_crtc_atomic_disable()
1496 zynqmp_disp_plane_atomic_disable(crtc->primary, old_plane_state); in zynqmp_disp_crtc_atomic_disable()
1500 drm_crtc_vblank_off(&disp->crtc); in zynqmp_disp_crtc_atomic_disable()
1502 clk_disable_unprepare(disp->pclk); in zynqmp_disp_crtc_atomic_disable()
1503 pm_runtime_put_sync(disp->dev); in zynqmp_disp_crtc_atomic_disable()
1509 return drm_atomic_add_affected_planes(state->state, crtc); in zynqmp_disp_crtc_atomic_check()
1523 if (crtc->state->event) { in zynqmp_disp_crtc_atomic_flush()
1527 event = crtc->state->event; in zynqmp_disp_crtc_atomic_flush()
1528 crtc->state->event = NULL; in zynqmp_disp_crtc_atomic_flush()
1530 event->pipe = drm_crtc_index(crtc); in zynqmp_disp_crtc_atomic_flush()
1534 spin_lock_irq(&crtc->dev->event_lock); in zynqmp_disp_crtc_atomic_flush()
1536 spin_unlock_irq(&crtc->dev->event_lock); in zynqmp_disp_crtc_atomic_flush()
1552 zynqmp_dp_enable_vblank(disp->dpsub->dp); in zynqmp_disp_crtc_enable_vblank()
1561 zynqmp_dp_disable_vblank(disp->dpsub->dp); in zynqmp_disp_crtc_disable_vblank()
1577 struct drm_plane *plane = &disp->layers[ZYNQMP_DISP_LAYER_GFX].plane; in zynqmp_disp_create_crtc()
1580 ret = drm_crtc_init_with_planes(disp->drm, &disp->crtc, plane, in zynqmp_disp_create_crtc()
1585 drm_crtc_helper_add(&disp->crtc, &zynqmp_disp_crtc_helper_funcs); in zynqmp_disp_create_crtc()
1588 drm_crtc_vblank_off(&disp->crtc); in zynqmp_disp_create_crtc()
1595 u32 possible_crtcs = drm_crtc_mask(&disp->crtc); in zynqmp_disp_map_crtc_to_plane()
1599 disp->layers[i].plane.possible_crtcs = possible_crtcs; in zynqmp_disp_map_crtc_to_plane()
1602 /* -----------------------------------------------------------------------------
1608 struct zynqmp_disp *disp = dpsub->disp; in zynqmp_disp_drm_init()
1626 struct platform_device *pdev = to_platform_device(dpsub->dev); in zynqmp_disp_probe()
1634 return -ENOMEM; in zynqmp_disp_probe()
1636 disp->dev = &pdev->dev; in zynqmp_disp_probe()
1637 disp->dpsub = dpsub; in zynqmp_disp_probe()
1638 disp->drm = drm; in zynqmp_disp_probe()
1640 dpsub->disp = disp; in zynqmp_disp_probe()
1643 disp->blend.base = devm_ioremap_resource(disp->dev, res); in zynqmp_disp_probe()
1644 if (IS_ERR(disp->blend.base)) in zynqmp_disp_probe()
1645 return PTR_ERR(disp->blend.base); in zynqmp_disp_probe()
1648 disp->avbuf.base = devm_ioremap_resource(disp->dev, res); in zynqmp_disp_probe()
1649 if (IS_ERR(disp->avbuf.base)) in zynqmp_disp_probe()
1650 return PTR_ERR(disp->avbuf.base); in zynqmp_disp_probe()
1653 disp->audio.base = devm_ioremap_resource(disp->dev, res); in zynqmp_disp_probe()
1654 if (IS_ERR(disp->audio.base)) in zynqmp_disp_probe()
1655 return PTR_ERR(disp->audio.base); in zynqmp_disp_probe()
1657 /* Try the live PL video clock */ in zynqmp_disp_probe()
1658 disp->pclk = devm_clk_get(disp->dev, "dp_live_video_in_clk"); in zynqmp_disp_probe()
1659 if (!IS_ERR(disp->pclk)) in zynqmp_disp_probe()
1660 disp->pclk_from_ps = false; in zynqmp_disp_probe()
1661 else if (PTR_ERR(disp->pclk) == -EPROBE_DEFER) in zynqmp_disp_probe()
1662 return PTR_ERR(disp->pclk); in zynqmp_disp_probe()
1664 /* If the live PL video clock is not valid, fall back to PS clock */ in zynqmp_disp_probe()
1665 if (IS_ERR_OR_NULL(disp->pclk)) { in zynqmp_disp_probe()
1666 disp->pclk = devm_clk_get(disp->dev, "dp_vtc_pixel_clk_in"); in zynqmp_disp_probe()
1667 if (IS_ERR(disp->pclk)) { in zynqmp_disp_probe()
1668 dev_err(disp->dev, "failed to init any video clock\n"); in zynqmp_disp_probe()
1669 return PTR_ERR(disp->pclk); in zynqmp_disp_probe()
1671 disp->pclk_from_ps = true; in zynqmp_disp_probe()
1674 zynqmp_disp_audio_init(disp->dev, &disp->audio); in zynqmp_disp_probe()
1680 layer = &disp->layers[ZYNQMP_DISP_LAYER_VID]; in zynqmp_disp_probe()
1681 dpsub->dma_align = 1 << layer->dmas[0].chan->device->copy_align; in zynqmp_disp_probe()
1688 struct zynqmp_disp *disp = dpsub->disp; in zynqmp_disp_remove()