Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 173 lines 5.2 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2025 Icenowy Zheng <uwu@icenowy.me> 4 */ 5 6#include <linux/regmap.h> 7 8#include <drm/drm_atomic.h> 9#include <drm/drm_atomic_helper.h> 10#include <drm/drm_crtc.h> 11#include <drm/drm_fourcc.h> 12#include <drm/drm_framebuffer.h> 13#include <drm/drm_gem_atomic_helper.h> 14#include <drm/drm_modeset_helper_vtables.h> 15#include <drm/drm_plane.h> 16#include <drm/drm_print.h> 17 18#include "vs_crtc.h" 19#include "vs_plane.h" 20#include "vs_dc.h" 21#include "vs_primary_plane_regs.h" 22 23static int vs_primary_plane_atomic_check(struct drm_plane *plane, 24 struct drm_atomic_state *state) 25{ 26 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 27 plane); 28 struct drm_crtc *crtc = new_plane_state->crtc; 29 struct drm_crtc_state *crtc_state; 30 31 if (!crtc) 32 return 0; 33 34 crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 35 if (WARN_ON(!crtc_state)) 36 return -EINVAL; 37 38 return drm_atomic_helper_check_plane_state(new_plane_state, 39 crtc_state, 40 DRM_PLANE_NO_SCALING, 41 DRM_PLANE_NO_SCALING, 42 false, true); 43} 44 45static void vs_primary_plane_commit(struct vs_dc *dc, unsigned int output) 46{ 47 regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output), 48 VSDC_FB_CONFIG_EX_COMMIT); 49} 50 51static void vs_primary_plane_atomic_enable(struct drm_plane *plane, 52 struct drm_atomic_state *atomic_state) 53{ 54 struct drm_plane_state *state = drm_atomic_get_new_plane_state(atomic_state, 55 plane); 56 struct drm_crtc *crtc = state->crtc; 57 struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc); 58 unsigned int output = vcrtc->id; 59 struct vs_dc *dc = vcrtc->dc; 60 61 regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output), 62 VSDC_FB_CONFIG_EX_FB_EN); 63 regmap_update_bits(dc->regs, VSDC_FB_CONFIG_EX(output), 64 VSDC_FB_CONFIG_EX_DISPLAY_ID_MASK, 65 VSDC_FB_CONFIG_EX_DISPLAY_ID(output)); 66 67 vs_primary_plane_commit(dc, output); 68} 69 70static void vs_primary_plane_atomic_disable(struct drm_plane *plane, 71 struct drm_atomic_state *atomic_state) 72{ 73 struct drm_plane_state *state = drm_atomic_get_old_plane_state(atomic_state, 74 plane); 75 struct drm_crtc *crtc = state->crtc; 76 struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc); 77 unsigned int output = vcrtc->id; 78 struct vs_dc *dc = vcrtc->dc; 79 80 regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output), 81 VSDC_FB_CONFIG_EX_FB_EN); 82 83 vs_primary_plane_commit(dc, output); 84} 85 86static void vs_primary_plane_atomic_update(struct drm_plane *plane, 87 struct drm_atomic_state *atomic_state) 88{ 89 struct drm_plane_state *state = drm_atomic_get_new_plane_state(atomic_state, 90 plane); 91 struct drm_framebuffer *fb = state->fb; 92 struct drm_crtc *crtc = state->crtc; 93 struct vs_dc *dc; 94 struct vs_crtc *vcrtc; 95 struct vs_format fmt; 96 unsigned int output; 97 dma_addr_t dma_addr; 98 99 if (!state->visible) { 100 vs_primary_plane_atomic_disable(plane, atomic_state); 101 return; 102 } 103 104 vcrtc = drm_crtc_to_vs_crtc(crtc); 105 output = vcrtc->id; 106 dc = vcrtc->dc; 107 108 drm_format_to_vs_format(state->fb->format->format, &fmt); 109 110 regmap_update_bits(dc->regs, VSDC_FB_CONFIG(output), 111 VSDC_FB_CONFIG_FMT_MASK, 112 VSDC_FB_CONFIG_FMT(fmt.color)); 113 regmap_update_bits(dc->regs, VSDC_FB_CONFIG(output), 114 VSDC_FB_CONFIG_SWIZZLE_MASK, 115 VSDC_FB_CONFIG_SWIZZLE(fmt.swizzle)); 116 regmap_assign_bits(dc->regs, VSDC_FB_CONFIG(output), 117 VSDC_FB_CONFIG_UV_SWIZZLE_EN, fmt.uv_swizzle); 118 119 dma_addr = vs_fb_get_dma_addr(fb, &state->src); 120 121 regmap_write(dc->regs, VSDC_FB_ADDRESS(output), 122 lower_32_bits(dma_addr)); 123 regmap_write(dc->regs, VSDC_FB_STRIDE(output), 124 fb->pitches[0]); 125 126 regmap_write(dc->regs, VSDC_FB_TOP_LEFT(output), 127 VSDC_MAKE_PLANE_POS(state->crtc_x, state->crtc_y)); 128 regmap_write(dc->regs, VSDC_FB_BOTTOM_RIGHT(output), 129 VSDC_MAKE_PLANE_POS(state->crtc_x + state->crtc_w, 130 state->crtc_y + state->crtc_h)); 131 regmap_write(dc->regs, VSDC_FB_SIZE(output), 132 VSDC_MAKE_PLANE_SIZE(state->crtc_w, state->crtc_h)); 133 134 regmap_write(dc->regs, VSDC_FB_BLEND_CONFIG(output), 135 VSDC_FB_BLEND_CONFIG_BLEND_DISABLE); 136 137 vs_primary_plane_commit(dc, output); 138} 139 140static const struct drm_plane_helper_funcs vs_primary_plane_helper_funcs = { 141 .atomic_check = vs_primary_plane_atomic_check, 142 .atomic_update = vs_primary_plane_atomic_update, 143 .atomic_enable = vs_primary_plane_atomic_enable, 144 .atomic_disable = vs_primary_plane_atomic_disable, 145}; 146 147static const struct drm_plane_funcs vs_primary_plane_funcs = { 148 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 149 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 150 .disable_plane = drm_atomic_helper_disable_plane, 151 .reset = drm_atomic_helper_plane_reset, 152 .update_plane = drm_atomic_helper_update_plane, 153}; 154 155struct drm_plane *vs_primary_plane_init(struct drm_device *drm_dev, struct vs_dc *dc) 156{ 157 struct drm_plane *plane; 158 159 plane = drmm_universal_plane_alloc(drm_dev, struct drm_plane, dev, 0, 160 &vs_primary_plane_funcs, 161 dc->identity.formats->array, 162 dc->identity.formats->num, 163 NULL, 164 DRM_PLANE_TYPE_PRIMARY, 165 NULL); 166 167 if (IS_ERR(plane)) 168 return plane; 169 170 drm_plane_helper_add(plane, &vs_primary_plane_helper_funcs); 171 172 return plane; 173}