Lines Matching +full:layer +full:- +full:alpha +full:- +full:mode
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>
19 #include <linux/dma-mapping.h>
33 * --------
38 * +------------------------------------------------------------+
39 * +--------+ | +----------------+ +-----------+ |
40 * | DPDMA | --->| | --> | Video | Video +-------------+ |
41 * | 4x vid | | | | | Rendering | -+--> | | | +------+
42 * | 2x aud | | | Audio/Video | --> | Pipeline | | | DisplayPort |---> | PHY0 |
43 * +--------+ | | Buffer Manager | +-----------+ | | Source | | +------+
44 * | | and STC | +-----------+ | | Controller | | +------+
45 * Live Video --->| | --> | Audio | Audio | |---> | PHY1 |
46 * | | | | Mixer | --+-> | | | +------+
47 * Live Audio --->| | --> | | || +-------------+ |
48 * | +----------------+ +-----------+ || |
49 * +---------------------------------------||-------------------+
54 * Only non-live input from the DPDMA and output to the DisplayPort Source
68 * struct zynqmp_disp_format - Display subsystem format information
82 * struct zynqmp_disp_layer_dma - DMA channel for one data plane of a layer
94 * struct zynqmp_disp_layer_info - Static layer information
106 * struct zynqmp_disp_layer - Display layer
107 * @id: Layer ID
109 * @info: Static layer information
113 * @mode: Current operation mode
124 enum zynqmp_dpsub_layer_mode mode; member
128 * struct zynqmp_disp - Display controller
153 /* -----------------------------------------------------------------------------
187 /* List of video layer formats */
292 /* List of graphics layer formats */
359 return readl(disp->avbuf.base + reg); in zynqmp_disp_avbuf_read()
364 writel(val, disp->avbuf.base + reg); in zynqmp_disp_avbuf_write()
367 static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer) in zynqmp_disp_layer_is_video() argument
369 return layer->id == ZYNQMP_DPSUB_LAYER_VID; in zynqmp_disp_layer_is_video()
373 * zynqmp_disp_avbuf_set_format - Set the input format for a layer
375 * @layer: The layer
378 * Set the video buffer manager format for @layer to @fmt.
381 struct zynqmp_disp_layer *layer, in zynqmp_disp_avbuf_set_format() argument
388 val &= zynqmp_disp_layer_is_video(layer) in zynqmp_disp_avbuf_set_format()
391 val |= fmt->buf_fmt; in zynqmp_disp_avbuf_set_format()
395 unsigned int reg = zynqmp_disp_layer_is_video(layer) in zynqmp_disp_avbuf_set_format()
399 zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]); in zynqmp_disp_avbuf_set_format()
404 * zynqmp_disp_avbuf_set_clocks_sources - Set the clocks sources
432 * zynqmp_disp_avbuf_enable_channels - Enable buffer channels
460 * zynqmp_disp_avbuf_disable_channels - Disable buffer channels
475 * zynqmp_disp_avbuf_enable_audio - Enable audio
478 * Enable all audio buffers with a non-live (memory) source.
492 * zynqmp_disp_avbuf_disable_audio - Disable audio
509 * zynqmp_disp_avbuf_enable_video - Enable a video layer
511 * @layer: The layer
513 * Enable the video/graphics buffer for @layer.
516 struct zynqmp_disp_layer *layer) in zynqmp_disp_avbuf_enable_video() argument
521 if (zynqmp_disp_layer_is_video(layer)) { in zynqmp_disp_avbuf_enable_video()
523 if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE) in zynqmp_disp_avbuf_enable_video()
530 if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE) in zynqmp_disp_avbuf_enable_video()
539 * zynqmp_disp_avbuf_disable_video - Disable a video layer
541 * @layer: The layer
543 * Disable the video/graphics buffer for @layer.
546 struct zynqmp_disp_layer *layer) in zynqmp_disp_avbuf_disable_video() argument
551 if (zynqmp_disp_layer_is_video(layer)) { in zynqmp_disp_avbuf_disable_video()
562 * zynqmp_disp_avbuf_enable - Enable the video pipe
565 * De-assert the video pipe reset.
573 * zynqmp_disp_avbuf_disable - Disable the video pipe
584 /* -----------------------------------------------------------------------------
590 writel(val, disp->blend.base + reg); in zynqmp_disp_blend_write()
596 * Hardcode RGB <-> YUV conversion to full-range SDTV for now.
635 * zynqmp_disp_blend_set_output_format - Set the output format of the blender
678 * zynqmp_disp_blend_set_bg_color - Set the background color
697 * zynqmp_disp_blend_set_global_alpha - Configure global alpha blending
699 * @enable: True to enable global alpha blending
700 * @alpha: Global alpha value (ignored if @enabled is false)
703 bool enable, u32 alpha) in zynqmp_disp_blend_set_global_alpha() argument
706 ZYNQMP_DISP_V_BLEND_SET_GLOBAL_ALPHA_VALUE(alpha) | in zynqmp_disp_blend_set_global_alpha()
711 * zynqmp_disp_blend_layer_set_csc - Configure colorspace conversion for layer
713 * @layer: The layer
717 * Configure the input colorspace conversion matrix and offsets for the @layer.
722 struct zynqmp_disp_layer *layer, in zynqmp_disp_blend_layer_set_csc() argument
730 if (layer->disp_fmt->swap) { in zynqmp_disp_blend_layer_set_csc()
731 if (layer->drm_fmt->is_yuv) { in zynqmp_disp_blend_layer_set_csc()
742 if (zynqmp_disp_layer_is_video(layer)) in zynqmp_disp_blend_layer_set_csc()
753 if (zynqmp_disp_layer_is_video(layer)) in zynqmp_disp_blend_layer_set_csc()
763 * zynqmp_disp_blend_layer_enable - Enable a layer
765 * @layer: The layer
768 struct zynqmp_disp_layer *layer) in zynqmp_disp_blend_layer_enable() argument
774 val = (layer->drm_fmt->is_yuv ? in zynqmp_disp_blend_layer_enable()
776 (layer->drm_fmt->hsub > 1 ? in zynqmp_disp_blend_layer_enable()
780 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id), in zynqmp_disp_blend_layer_enable()
783 if (layer->drm_fmt->is_yuv) { in zynqmp_disp_blend_layer_enable()
791 zynqmp_disp_blend_layer_set_csc(disp, layer, coeffs, offsets); in zynqmp_disp_blend_layer_enable()
795 * zynqmp_disp_blend_layer_disable - Disable a layer
797 * @layer: The layer
800 struct zynqmp_disp_layer *layer) in zynqmp_disp_blend_layer_disable() argument
803 ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id), in zynqmp_disp_blend_layer_disable()
806 zynqmp_disp_blend_layer_set_csc(disp, layer, csc_zero_matrix, in zynqmp_disp_blend_layer_disable()
810 /* -----------------------------------------------------------------------------
816 writel(val, disp->audio.base + reg); in zynqmp_disp_audio_write()
820 * zynqmp_disp_audio_enable - Enable the audio mixer
823 * Enable the audio mixer by de-asserting the soft reset. The audio state is set to
828 /* Clear the audio soft reset register as it's an non-reset flop. */ in zynqmp_disp_audio_enable()
835 * zynqmp_disp_audio_disable - Disable the audio mixer
846 /* -----------------------------------------------------------------------------
847 * ZynqMP Display Layer & DRM Plane
851 * zynqmp_disp_layer_find_format - Find format information for a DRM format
852 * @layer: The layer
856 * format @drm_fmt for the @layer, and return a pointer to the format
862 zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer, in zynqmp_disp_layer_find_format() argument
867 for (i = 0; i < layer->info->num_formats; i++) { in zynqmp_disp_layer_find_format()
868 if (layer->info->formats[i].drm_fmt == drm_fmt) in zynqmp_disp_layer_find_format()
869 return &layer->info->formats[i]; in zynqmp_disp_layer_find_format()
876 * zynqmp_disp_layer_drm_formats - Return the DRM formats supported by the layer
877 * @layer: The layer
881 * supported by the layer. The number of formats in the array is returned
884 u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer, in zynqmp_disp_layer_drm_formats() argument
890 formats = kcalloc(layer->info->num_formats, sizeof(*formats), in zynqmp_disp_layer_drm_formats()
895 for (i = 0; i < layer->info->num_formats; ++i) in zynqmp_disp_layer_drm_formats()
896 formats[i] = layer->info->formats[i].drm_fmt; in zynqmp_disp_layer_drm_formats()
898 *num_formats = layer->info->num_formats; in zynqmp_disp_layer_drm_formats()
903 * zynqmp_disp_layer_enable - Enable a layer
904 * @layer: The layer
905 * @mode: Operating mode of layer
907 * Enable the @layer in the audio/video buffer manager and the blender. DMA
910 void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer, in zynqmp_disp_layer_enable() argument
911 enum zynqmp_dpsub_layer_mode mode) in zynqmp_disp_layer_enable() argument
913 layer->mode = mode; in zynqmp_disp_layer_enable()
914 zynqmp_disp_avbuf_enable_video(layer->disp, layer); in zynqmp_disp_layer_enable()
915 zynqmp_disp_blend_layer_enable(layer->disp, layer); in zynqmp_disp_layer_enable()
919 * zynqmp_disp_layer_disable - Disable the layer
920 * @layer: The layer
922 * Disable the layer by stopping its DMA channels and disabling it in the
925 void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer) in zynqmp_disp_layer_disable() argument
929 if (layer->disp->dpsub->dma_enabled) { in zynqmp_disp_layer_disable()
930 for (i = 0; i < layer->drm_fmt->num_planes; i++) in zynqmp_disp_layer_disable()
931 dmaengine_terminate_sync(layer->dmas[i].chan); in zynqmp_disp_layer_disable()
934 zynqmp_disp_avbuf_disable_video(layer->disp, layer); in zynqmp_disp_layer_disable()
935 zynqmp_disp_blend_layer_disable(layer->disp, layer); in zynqmp_disp_layer_disable()
939 * zynqmp_disp_layer_set_format - Set the layer format
940 * @layer: The layer
943 * Set the format for @layer to @info. The layer must be disabled.
945 void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer, in zynqmp_disp_layer_set_format() argument
950 layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format); in zynqmp_disp_layer_set_format()
951 layer->drm_fmt = info; in zynqmp_disp_layer_set_format()
953 zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt); in zynqmp_disp_layer_set_format()
955 if (!layer->disp->dpsub->dma_enabled) in zynqmp_disp_layer_set_format()
962 for (i = 0; i < info->num_planes; i++) { in zynqmp_disp_layer_set_format()
963 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_set_format()
973 dmaengine_slave_config(dma->chan, &config); in zynqmp_disp_layer_set_format()
978 * zynqmp_disp_layer_update - Update the layer framebuffer
979 * @layer: The layer
982 * Update the framebuffer for the layer by issuing a new DMA engine transaction
987 int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer, in zynqmp_disp_layer_update() argument
990 const struct drm_format_info *info = layer->drm_fmt; in zynqmp_disp_layer_update()
993 if (!layer->disp->dpsub->dma_enabled) in zynqmp_disp_layer_update()
996 for (i = 0; i < info->num_planes; i++) { in zynqmp_disp_layer_update()
997 unsigned int width = state->crtc_w / (i ? info->hsub : 1); in zynqmp_disp_layer_update()
998 unsigned int height = state->crtc_h / (i ? info->vsub : 1); in zynqmp_disp_layer_update()
999 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_update()
1003 dma_addr = drm_fb_dma_get_gem_addr(state->fb, state, i); in zynqmp_disp_layer_update()
1005 dma->xt.numf = height; in zynqmp_disp_layer_update()
1006 dma->sgl.size = width * info->cpp[i]; in zynqmp_disp_layer_update()
1007 dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size; in zynqmp_disp_layer_update()
1008 dma->xt.src_start = dma_addr; in zynqmp_disp_layer_update()
1009 dma->xt.frame_size = 1; in zynqmp_disp_layer_update()
1010 dma->xt.dir = DMA_MEM_TO_DEV; in zynqmp_disp_layer_update()
1011 dma->xt.src_sgl = true; in zynqmp_disp_layer_update()
1012 dma->xt.dst_sgl = false; in zynqmp_disp_layer_update()
1014 desc = dmaengine_prep_interleaved_dma(dma->chan, &dma->xt, in zynqmp_disp_layer_update()
1019 dev_err(layer->disp->dev, in zynqmp_disp_layer_update()
1021 return -ENOMEM; in zynqmp_disp_layer_update()
1025 dma_async_issue_pending(dma->chan); in zynqmp_disp_layer_update()
1032 * zynqmp_disp_layer_release_dma - Release DMA channels for a layer
1034 * @layer: The layer
1036 * Release the DMA channels associated with @layer.
1039 struct zynqmp_disp_layer *layer) in zynqmp_disp_layer_release_dma() argument
1043 if (!layer->info || !disp->dpsub->dma_enabled) in zynqmp_disp_layer_release_dma()
1046 for (i = 0; i < layer->info->num_channels; i++) { in zynqmp_disp_layer_release_dma()
1047 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_release_dma()
1049 if (!dma->chan) in zynqmp_disp_layer_release_dma()
1053 dmaengine_terminate_sync(dma->chan); in zynqmp_disp_layer_release_dma()
1054 dma_release_channel(dma->chan); in zynqmp_disp_layer_release_dma()
1059 * zynqmp_disp_destroy_layers - Destroy all layers
1066 for (i = 0; i < ARRAY_SIZE(disp->layers); i++) in zynqmp_disp_destroy_layers()
1067 zynqmp_disp_layer_release_dma(disp, &disp->layers[i]); in zynqmp_disp_destroy_layers()
1071 * zynqmp_disp_layer_request_dma - Request DMA channels for a layer
1073 * @layer: The layer
1075 * Request all DMA engine channels needed by @layer.
1080 struct zynqmp_disp_layer *layer) in zynqmp_disp_layer_request_dma() argument
1086 if (!disp->dpsub->dma_enabled) in zynqmp_disp_layer_request_dma()
1089 for (i = 0; i < layer->info->num_channels; i++) { in zynqmp_disp_layer_request_dma()
1090 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; in zynqmp_disp_layer_request_dma()
1094 "%s%u", dma_names[layer->id], i); in zynqmp_disp_layer_request_dma()
1095 dma->chan = dma_request_chan(disp->dev, dma_channel_name); in zynqmp_disp_layer_request_dma()
1096 if (IS_ERR(dma->chan)) { in zynqmp_disp_layer_request_dma()
1097 ret = dev_err_probe(disp->dev, PTR_ERR(dma->chan), in zynqmp_disp_layer_request_dma()
1099 dma->chan = NULL; in zynqmp_disp_layer_request_dma()
1108 * zynqmp_disp_create_layers - Create and initialize all layers
1131 for (i = 0; i < ARRAY_SIZE(disp->layers); i++) { in zynqmp_disp_create_layers()
1132 struct zynqmp_disp_layer *layer = &disp->layers[i]; in zynqmp_disp_create_layers() local
1134 layer->id = i; in zynqmp_disp_create_layers()
1135 layer->disp = disp; in zynqmp_disp_create_layers()
1136 layer->info = &layer_info[i]; in zynqmp_disp_create_layers()
1138 ret = zynqmp_disp_layer_request_dma(disp, layer); in zynqmp_disp_create_layers()
1142 disp->dpsub->layers[i] = layer; in zynqmp_disp_create_layers()
1152 /* -----------------------------------------------------------------------------
1157 * zynqmp_disp_enable - Enable the display controller
1167 zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps, in zynqmp_disp_enable()
1168 disp->dpsub->aud_clk_from_ps, in zynqmp_disp_enable()
1177 * zynqmp_disp_disable - Disable the display controller
1190 * zynqmp_disp_setup_clock - Configure the display controller pixel clock rate
1203 ret = clk_set_rate(disp->dpsub->vid_clk, mode_clock); in zynqmp_disp_setup_clock()
1205 dev_err(disp->dev, "failed to set the video clock\n"); in zynqmp_disp_setup_clock()
1209 rate = clk_get_rate(disp->dpsub->vid_clk); in zynqmp_disp_setup_clock()
1210 diff = rate - mode_clock; in zynqmp_disp_setup_clock()
1212 dev_info(disp->dev, in zynqmp_disp_setup_clock()
1216 dev_dbg(disp->dev, in zynqmp_disp_setup_clock()
1223 /* -----------------------------------------------------------------------------
1229 struct platform_device *pdev = to_platform_device(dpsub->dev); in zynqmp_disp_probe()
1235 return -ENOMEM; in zynqmp_disp_probe()
1237 disp->dev = &pdev->dev; in zynqmp_disp_probe()
1238 disp->dpsub = dpsub; in zynqmp_disp_probe()
1240 disp->blend.base = devm_platform_ioremap_resource_byname(pdev, "blend"); in zynqmp_disp_probe()
1241 if (IS_ERR(disp->blend.base)) { in zynqmp_disp_probe()
1242 ret = PTR_ERR(disp->blend.base); in zynqmp_disp_probe()
1246 disp->avbuf.base = devm_platform_ioremap_resource_byname(pdev, "av_buf"); in zynqmp_disp_probe()
1247 if (IS_ERR(disp->avbuf.base)) { in zynqmp_disp_probe()
1248 ret = PTR_ERR(disp->avbuf.base); in zynqmp_disp_probe()
1252 disp->audio.base = devm_platform_ioremap_resource_byname(pdev, "aud"); in zynqmp_disp_probe()
1253 if (IS_ERR(disp->audio.base)) { in zynqmp_disp_probe()
1254 ret = PTR_ERR(disp->audio.base); in zynqmp_disp_probe()
1262 if (disp->dpsub->dma_enabled) { in zynqmp_disp_probe()
1263 struct zynqmp_disp_layer *layer; in zynqmp_disp_probe() local
1265 layer = &disp->layers[ZYNQMP_DPSUB_LAYER_VID]; in zynqmp_disp_probe()
1266 dpsub->dma_align = 1 << layer->dmas[0].chan->device->copy_align; in zynqmp_disp_probe()
1269 dpsub->disp = disp; in zynqmp_disp_probe()
1280 struct zynqmp_disp *disp = dpsub->disp; in zynqmp_disp_remove()