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

drm/armada: move primary plane to separate file

Split out the primary plane support; this is now entirely separate from
the CRTC support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

+318 -283
+1 -1
drivers/gpu/drm/armada/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ 3 - armada_gem.o armada_overlay.o armada_trace.o 3 + armada_gem.o armada_overlay.o armada_plane.o armada_trace.o 4 4 armada-y += armada_510.o 5 5 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o 6 6
+2 -271
drivers/gpu/drm/armada/armada_crtc.c
··· 20 20 #include "armada_fb.h" 21 21 #include "armada_gem.h" 22 22 #include "armada_hw.h" 23 + #include "armada_plane.h" 23 24 #include "armada_trace.h" 24 25 25 26 enum csc_mode { ··· 29 28 CSC_YUV_CCIR709 = 2, 30 29 CSC_RGB_COMPUTER = 1, 31 30 CSC_RGB_STUDIO = 2, 32 - }; 33 - 34 - static const uint32_t armada_primary_formats[] = { 35 - DRM_FORMAT_UYVY, 36 - DRM_FORMAT_YUYV, 37 - DRM_FORMAT_VYUY, 38 - DRM_FORMAT_YVYU, 39 - DRM_FORMAT_ARGB8888, 40 - DRM_FORMAT_ABGR8888, 41 - DRM_FORMAT_XRGB8888, 42 - DRM_FORMAT_XBGR8888, 43 - DRM_FORMAT_RGB888, 44 - DRM_FORMAT_BGR888, 45 - DRM_FORMAT_ARGB1555, 46 - DRM_FORMAT_ABGR1555, 47 - DRM_FORMAT_RGB565, 48 - DRM_FORMAT_BGR565, 49 31 }; 50 32 51 33 /* ··· 142 158 dcrtc->dumb_ctrl = dumb_ctrl; 143 159 writel_relaxed(dumb_ctrl, dcrtc->base + LCD_SPU_DUMB_CTRL); 144 160 } 145 - } 146 - 147 - void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 148 - int x, int y) 149 - { 150 - const struct drm_format_info *format = fb->format; 151 - unsigned int num_planes = format->num_planes; 152 - u32 addr = drm_fb_obj(fb)->dev_addr; 153 - int i; 154 - 155 - if (num_planes > 3) 156 - num_planes = 3; 157 - 158 - addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] + 159 - x * format->cpp[0]; 160 - 161 - y /= format->vsub; 162 - x /= format->hsub; 163 - 164 - for (i = 1; i < num_planes; i++) 165 - addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + 166 - x * format->cpp[i]; 167 - for (; i < 3; i++) 168 - addrs[i] = 0; 169 - } 170 - 171 - static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, 172 - int x, int y, struct armada_regs *regs, bool interlaced) 173 - { 174 - unsigned pitch = fb->pitches[0]; 175 - u32 addrs[3], addr_odd, addr_even; 176 - unsigned i = 0; 177 - 178 - DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", 179 - pitch, x, y, fb->format->cpp[0] * 8); 180 - 181 - armada_drm_plane_calc_addrs(addrs, fb, x, y); 182 - 183 - addr_odd = addr_even = addrs[0]; 184 - 185 - if (interlaced) { 186 - addr_even += pitch; 187 - pitch *= 2; 188 - } 189 - 190 - /* write offset, base, and pitch */ 191 - armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0); 192 - armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1); 193 - armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH); 194 - 195 - return i; 196 161 } 197 162 198 163 static void armada_drm_plane_work_call(struct armada_crtc *dcrtc, ··· 1000 1067 .disable_vblank = armada_drm_crtc_disable_vblank, 1001 1068 }; 1002 1069 1003 - int armada_drm_plane_prepare_fb(struct drm_plane *plane, 1004 - struct drm_plane_state *state) 1005 - { 1006 - DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", 1007 - plane->base.id, plane->name, 1008 - state->fb ? state->fb->base.id : 0); 1009 - 1010 - /* 1011 - * Take a reference on the new framebuffer - we want to 1012 - * hold on to it while the hardware is displaying it. 1013 - */ 1014 - if (state->fb) 1015 - drm_framebuffer_get(state->fb); 1016 - return 0; 1017 - } 1018 - 1019 - void armada_drm_plane_cleanup_fb(struct drm_plane *plane, 1020 - struct drm_plane_state *old_state) 1021 - { 1022 - DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", 1023 - plane->base.id, plane->name, 1024 - old_state->fb ? old_state->fb->base.id : 0); 1025 - 1026 - if (old_state->fb) 1027 - drm_framebuffer_put(old_state->fb); 1028 - } 1029 - 1030 - int armada_drm_plane_atomic_check(struct drm_plane *plane, 1031 - struct drm_plane_state *state) 1032 - { 1033 - if (state->fb && !WARN_ON(!state->crtc)) { 1034 - struct drm_crtc *crtc = state->crtc; 1035 - struct drm_crtc_state *crtc_state; 1036 - 1037 - if (state->state) 1038 - crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); 1039 - else 1040 - crtc_state = crtc->state; 1041 - return drm_atomic_helper_check_plane_state(state, crtc_state, 1042 - 0, INT_MAX, 1043 - true, false); 1044 - } else { 1045 - state->visible = false; 1046 - } 1047 - return 0; 1048 - } 1049 - 1050 - static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, 1051 - struct drm_plane_state *old_state) 1052 - { 1053 - struct drm_plane_state *state = plane->state; 1054 - struct armada_crtc *dcrtc; 1055 - struct armada_regs *regs; 1056 - u32 cfg, cfg_mask, val; 1057 - unsigned int idx; 1058 - 1059 - DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); 1060 - 1061 - if (!state->fb || WARN_ON(!state->crtc)) 1062 - return; 1063 - 1064 - DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n", 1065 - plane->base.id, plane->name, 1066 - state->crtc->base.id, state->crtc->name, 1067 - state->fb->base.id, 1068 - old_state->visible, state->visible); 1069 - 1070 - dcrtc = drm_to_armada_crtc(state->crtc); 1071 - regs = dcrtc->regs + dcrtc->regs_idx; 1072 - 1073 - idx = 0; 1074 - if (!old_state->visible && state->visible) { 1075 - val = CFG_PDWN64x66; 1076 - if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) 1077 - val |= CFG_PDWN256x24; 1078 - armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1); 1079 - } 1080 - val = armada_rect_hw_fp(&state->src); 1081 - if (armada_rect_hw_fp(&old_state->src) != val) 1082 - armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN); 1083 - val = armada_rect_yx(&state->dst); 1084 - if (armada_rect_yx(&old_state->dst) != val) 1085 - armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN); 1086 - val = armada_rect_hw(&state->dst); 1087 - if (armada_rect_hw(&old_state->dst) != val) 1088 - armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN); 1089 - if (old_state->src.x1 != state->src.x1 || 1090 - old_state->src.y1 != state->src.y1 || 1091 - old_state->fb != state->fb) { 1092 - idx += armada_drm_crtc_calc_fb(state->fb, 1093 - state->src.x1 >> 16, 1094 - state->src.y1 >> 16, 1095 - regs + idx, 1096 - dcrtc->interlaced); 1097 - } 1098 - if (old_state->fb != state->fb) { 1099 - cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) | 1100 - CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod); 1101 - if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) 1102 - cfg |= CFG_PALETTE_ENA; 1103 - if (state->visible) 1104 - cfg |= CFG_GRA_ENA; 1105 - if (dcrtc->interlaced) 1106 - cfg |= CFG_GRA_FTOGGLE; 1107 - cfg_mask = CFG_GRAFORMAT | 1108 - CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | 1109 - CFG_SWAPYU | CFG_YUV2RGB) | 1110 - CFG_PALETTE_ENA | CFG_GRA_FTOGGLE | 1111 - CFG_GRA_ENA; 1112 - } else if (old_state->visible != state->visible) { 1113 - cfg = state->visible ? CFG_GRA_ENA : 0; 1114 - cfg_mask = CFG_GRA_ENA; 1115 - } else { 1116 - cfg = cfg_mask = 0; 1117 - } 1118 - if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) || 1119 - drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) { 1120 - cfg_mask |= CFG_GRA_HSMOOTH; 1121 - if (drm_rect_width(&state->src) >> 16 != 1122 - drm_rect_width(&state->dst)) 1123 - cfg |= CFG_GRA_HSMOOTH; 1124 - } 1125 - 1126 - if (cfg_mask) 1127 - armada_reg_queue_mod(regs, idx, cfg, cfg_mask, 1128 - LCD_SPU_DMA_CTRL0); 1129 - 1130 - dcrtc->regs_idx += idx; 1131 - } 1132 - 1133 - static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane, 1134 - struct drm_plane_state *old_state) 1135 - { 1136 - struct armada_crtc *dcrtc; 1137 - struct armada_regs *regs; 1138 - unsigned int idx = 0; 1139 - 1140 - DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); 1141 - 1142 - if (!old_state->crtc) 1143 - return; 1144 - 1145 - DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n", 1146 - plane->base.id, plane->name, 1147 - old_state->crtc->base.id, old_state->crtc->name, 1148 - old_state->fb->base.id); 1149 - 1150 - dcrtc = drm_to_armada_crtc(old_state->crtc); 1151 - regs = dcrtc->regs + dcrtc->regs_idx; 1152 - 1153 - /* Disable plane and power down most RAMs and FIFOs */ 1154 - armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0); 1155 - armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 | 1156 - CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66, 1157 - 0, LCD_SPU_SRAM_PARA1); 1158 - 1159 - dcrtc->regs_idx += idx; 1160 - } 1161 - 1162 - static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = { 1163 - .prepare_fb = armada_drm_plane_prepare_fb, 1164 - .cleanup_fb = armada_drm_plane_cleanup_fb, 1165 - .atomic_check = armada_drm_plane_atomic_check, 1166 - .atomic_update = armada_drm_primary_plane_atomic_update, 1167 - .atomic_disable = armada_drm_primary_plane_atomic_disable, 1168 - }; 1169 - 1170 - static const struct drm_plane_funcs armada_primary_plane_funcs = { 1171 - .update_plane = drm_plane_helper_update, 1172 - .disable_plane = drm_plane_helper_disable, 1173 - .destroy = drm_primary_helper_destroy, 1174 - .reset = drm_atomic_helper_plane_reset, 1175 - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 1176 - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 1177 - }; 1178 - 1179 - int armada_drm_plane_init(struct armada_plane *plane) 1180 - { 1181 - unsigned int i; 1182 - 1183 - for (i = 0; i < ARRAY_SIZE(plane->works); i++) 1184 - plane->works[i].plane = &plane->base; 1185 - 1186 - init_waitqueue_head(&plane->frame_wait); 1187 - 1188 - return 0; 1189 - } 1190 - 1191 1070 static const struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = { 1192 1071 { CSC_AUTO, "Auto" }, 1193 1072 { CSC_YUV_CCIR601, "CCIR601" }, ··· 1108 1363 goto err_crtc; 1109 1364 } 1110 1365 1111 - ret = armada_drm_plane_init(primary); 1112 - if (ret) { 1113 - kfree(primary); 1114 - goto err_crtc; 1115 - } 1116 - 1117 - drm_plane_helper_add(&primary->base, 1118 - &armada_primary_plane_helper_funcs); 1119 - 1120 - ret = drm_universal_plane_init(drm, &primary->base, 0, 1121 - &armada_primary_plane_funcs, 1122 - armada_primary_formats, 1123 - ARRAY_SIZE(armada_primary_formats), 1124 - NULL, 1125 - DRM_PLANE_TYPE_PRIMARY, NULL); 1366 + ret = armada_drm_primary_plane_init(drm, primary); 1126 1367 if (ret) { 1127 1368 kfree(primary); 1128 1369 goto err_crtc;
-10
drivers/gpu/drm/armada/armada_crtc.h
··· 54 54 }; 55 55 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base) 56 56 57 - int armada_drm_plane_init(struct armada_plane *plane); 58 57 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, 59 58 struct armada_plane_work *work); 60 59 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout); 61 60 void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc, 62 61 struct armada_plane *plane); 63 - void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 64 - int x, int y); 65 - 66 - int armada_drm_plane_prepare_fb(struct drm_plane *plane, 67 - struct drm_plane_state *state); 68 - void armada_drm_plane_cleanup_fb(struct drm_plane *plane, 69 - struct drm_plane_state *old_state); 70 - int armada_drm_plane_atomic_check(struct drm_plane *plane, 71 - struct drm_plane_state *state); 72 62 73 63 struct armada_crtc { 74 64 struct drm_crtc crtc;
+2 -1
drivers/gpu/drm/armada/armada_overlay.c
··· 10 10 #include <drm/drm_atomic.h> 11 11 #include <drm/drm_atomic_helper.h> 12 12 #include <drm/drm_plane_helper.h> 13 + #include <drm/armada_drm.h> 13 14 #include "armada_crtc.h" 14 15 #include "armada_drm.h" 15 16 #include "armada_fb.h" 16 17 #include "armada_gem.h" 17 18 #include "armada_hw.h" 18 - #include <drm/armada_drm.h> 19 19 #include "armada_ioctlP.h" 20 + #include "armada_plane.h" 20 21 #include "armada_trace.h" 21 22 22 23 struct armada_ovl_plane_properties {
+297
drivers/gpu/drm/armada/armada_plane.c
··· 1 + /* 2 + * Copyright (C) 2012 Russell King 3 + * Rewritten from the dovefb driver, and Armada510 manuals. 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + #include <drm/drmP.h> 10 + #include <drm/drm_atomic.h> 11 + #include <drm/drm_atomic_helper.h> 12 + #include <drm/drm_plane_helper.h> 13 + #include "armada_crtc.h" 14 + #include "armada_drm.h" 15 + #include "armada_fb.h" 16 + #include "armada_gem.h" 17 + #include "armada_hw.h" 18 + #include "armada_plane.h" 19 + #include "armada_trace.h" 20 + 21 + static const uint32_t armada_primary_formats[] = { 22 + DRM_FORMAT_UYVY, 23 + DRM_FORMAT_YUYV, 24 + DRM_FORMAT_VYUY, 25 + DRM_FORMAT_YVYU, 26 + DRM_FORMAT_ARGB8888, 27 + DRM_FORMAT_ABGR8888, 28 + DRM_FORMAT_XRGB8888, 29 + DRM_FORMAT_XBGR8888, 30 + DRM_FORMAT_RGB888, 31 + DRM_FORMAT_BGR888, 32 + DRM_FORMAT_ARGB1555, 33 + DRM_FORMAT_ABGR1555, 34 + DRM_FORMAT_RGB565, 35 + DRM_FORMAT_BGR565, 36 + }; 37 + 38 + void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 39 + int x, int y) 40 + { 41 + const struct drm_format_info *format = fb->format; 42 + unsigned int num_planes = format->num_planes; 43 + u32 addr = drm_fb_obj(fb)->dev_addr; 44 + int i; 45 + 46 + if (num_planes > 3) 47 + num_planes = 3; 48 + 49 + addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] + 50 + x * format->cpp[0]; 51 + 52 + y /= format->vsub; 53 + x /= format->hsub; 54 + 55 + for (i = 1; i < num_planes; i++) 56 + addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + 57 + x * format->cpp[i]; 58 + for (; i < 3; i++) 59 + addrs[i] = 0; 60 + } 61 + 62 + static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, 63 + int x, int y, struct armada_regs *regs, bool interlaced) 64 + { 65 + unsigned pitch = fb->pitches[0]; 66 + u32 addrs[3], addr_odd, addr_even; 67 + unsigned i = 0; 68 + 69 + DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", 70 + pitch, x, y, fb->format->cpp[0] * 8); 71 + 72 + armada_drm_plane_calc_addrs(addrs, fb, x, y); 73 + 74 + addr_odd = addr_even = addrs[0]; 75 + 76 + if (interlaced) { 77 + addr_even += pitch; 78 + pitch *= 2; 79 + } 80 + 81 + /* write offset, base, and pitch */ 82 + armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0); 83 + armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1); 84 + armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH); 85 + 86 + return i; 87 + } 88 + 89 + int armada_drm_plane_prepare_fb(struct drm_plane *plane, 90 + struct drm_plane_state *state) 91 + { 92 + DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", 93 + plane->base.id, plane->name, 94 + state->fb ? state->fb->base.id : 0); 95 + 96 + /* 97 + * Take a reference on the new framebuffer - we want to 98 + * hold on to it while the hardware is displaying it. 99 + */ 100 + if (state->fb) 101 + drm_framebuffer_get(state->fb); 102 + return 0; 103 + } 104 + 105 + void armada_drm_plane_cleanup_fb(struct drm_plane *plane, 106 + struct drm_plane_state *old_state) 107 + { 108 + DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n", 109 + plane->base.id, plane->name, 110 + old_state->fb ? old_state->fb->base.id : 0); 111 + 112 + if (old_state->fb) 113 + drm_framebuffer_put(old_state->fb); 114 + } 115 + 116 + int armada_drm_plane_atomic_check(struct drm_plane *plane, 117 + struct drm_plane_state *state) 118 + { 119 + if (state->fb && !WARN_ON(!state->crtc)) { 120 + struct drm_crtc *crtc = state->crtc; 121 + struct drm_crtc_state *crtc_state; 122 + 123 + if (state->state) 124 + crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); 125 + else 126 + crtc_state = crtc->state; 127 + return drm_atomic_helper_check_plane_state(state, crtc_state, 128 + 0, INT_MAX, 129 + true, false); 130 + } else { 131 + state->visible = false; 132 + } 133 + return 0; 134 + } 135 + 136 + static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane, 137 + struct drm_plane_state *old_state) 138 + { 139 + struct drm_plane_state *state = plane->state; 140 + struct armada_crtc *dcrtc; 141 + struct armada_regs *regs; 142 + u32 cfg, cfg_mask, val; 143 + unsigned int idx; 144 + 145 + DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); 146 + 147 + if (!state->fb || WARN_ON(!state->crtc)) 148 + return; 149 + 150 + DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n", 151 + plane->base.id, plane->name, 152 + state->crtc->base.id, state->crtc->name, 153 + state->fb->base.id, 154 + old_state->visible, state->visible); 155 + 156 + dcrtc = drm_to_armada_crtc(state->crtc); 157 + regs = dcrtc->regs + dcrtc->regs_idx; 158 + 159 + idx = 0; 160 + if (!old_state->visible && state->visible) { 161 + val = CFG_PDWN64x66; 162 + if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) 163 + val |= CFG_PDWN256x24; 164 + armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1); 165 + } 166 + val = armada_rect_hw_fp(&state->src); 167 + if (armada_rect_hw_fp(&old_state->src) != val) 168 + armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN); 169 + val = armada_rect_yx(&state->dst); 170 + if (armada_rect_yx(&old_state->dst) != val) 171 + armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN); 172 + val = armada_rect_hw(&state->dst); 173 + if (armada_rect_hw(&old_state->dst) != val) 174 + armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN); 175 + if (old_state->src.x1 != state->src.x1 || 176 + old_state->src.y1 != state->src.y1 || 177 + old_state->fb != state->fb) { 178 + idx += armada_drm_crtc_calc_fb(state->fb, 179 + state->src.x1 >> 16, 180 + state->src.y1 >> 16, 181 + regs + idx, 182 + dcrtc->interlaced); 183 + } 184 + if (old_state->fb != state->fb) { 185 + cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) | 186 + CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod); 187 + if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420) 188 + cfg |= CFG_PALETTE_ENA; 189 + if (state->visible) 190 + cfg |= CFG_GRA_ENA; 191 + if (dcrtc->interlaced) 192 + cfg |= CFG_GRA_FTOGGLE; 193 + cfg_mask = CFG_GRAFORMAT | 194 + CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | 195 + CFG_SWAPYU | CFG_YUV2RGB) | 196 + CFG_PALETTE_ENA | CFG_GRA_FTOGGLE | 197 + CFG_GRA_ENA; 198 + } else if (old_state->visible != state->visible) { 199 + cfg = state->visible ? CFG_GRA_ENA : 0; 200 + cfg_mask = CFG_GRA_ENA; 201 + } else { 202 + cfg = cfg_mask = 0; 203 + } 204 + if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) || 205 + drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) { 206 + cfg_mask |= CFG_GRA_HSMOOTH; 207 + if (drm_rect_width(&state->src) >> 16 != 208 + drm_rect_width(&state->dst)) 209 + cfg |= CFG_GRA_HSMOOTH; 210 + } 211 + 212 + if (cfg_mask) 213 + armada_reg_queue_mod(regs, idx, cfg, cfg_mask, 214 + LCD_SPU_DMA_CTRL0); 215 + 216 + dcrtc->regs_idx += idx; 217 + } 218 + 219 + static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane, 220 + struct drm_plane_state *old_state) 221 + { 222 + struct armada_crtc *dcrtc; 223 + struct armada_regs *regs; 224 + unsigned int idx = 0; 225 + 226 + DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name); 227 + 228 + if (!old_state->crtc) 229 + return; 230 + 231 + DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n", 232 + plane->base.id, plane->name, 233 + old_state->crtc->base.id, old_state->crtc->name, 234 + old_state->fb->base.id); 235 + 236 + dcrtc = drm_to_armada_crtc(old_state->crtc); 237 + regs = dcrtc->regs + dcrtc->regs_idx; 238 + 239 + /* Disable plane and power down most RAMs and FIFOs */ 240 + armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0); 241 + armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 | 242 + CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66, 243 + 0, LCD_SPU_SRAM_PARA1); 244 + 245 + dcrtc->regs_idx += idx; 246 + } 247 + 248 + static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = { 249 + .prepare_fb = armada_drm_plane_prepare_fb, 250 + .cleanup_fb = armada_drm_plane_cleanup_fb, 251 + .atomic_check = armada_drm_plane_atomic_check, 252 + .atomic_update = armada_drm_primary_plane_atomic_update, 253 + .atomic_disable = armada_drm_primary_plane_atomic_disable, 254 + }; 255 + 256 + static const struct drm_plane_funcs armada_primary_plane_funcs = { 257 + .update_plane = drm_plane_helper_update, 258 + .disable_plane = drm_plane_helper_disable, 259 + .destroy = drm_primary_helper_destroy, 260 + .reset = drm_atomic_helper_plane_reset, 261 + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 262 + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 263 + }; 264 + 265 + int armada_drm_plane_init(struct armada_plane *plane) 266 + { 267 + unsigned int i; 268 + 269 + for (i = 0; i < ARRAY_SIZE(plane->works); i++) 270 + plane->works[i].plane = &plane->base; 271 + 272 + init_waitqueue_head(&plane->frame_wait); 273 + 274 + return 0; 275 + } 276 + 277 + int armada_drm_primary_plane_init(struct drm_device *drm, 278 + struct armada_plane *primary) 279 + { 280 + int ret; 281 + 282 + ret = armada_drm_plane_init(primary); 283 + if (ret) 284 + return ret; 285 + 286 + drm_plane_helper_add(&primary->base, 287 + &armada_primary_plane_helper_funcs); 288 + 289 + ret = drm_universal_plane_init(drm, &primary->base, 0, 290 + &armada_primary_plane_funcs, 291 + armada_primary_formats, 292 + ARRAY_SIZE(armada_primary_formats), 293 + NULL, 294 + DRM_PLANE_TYPE_PRIMARY, NULL); 295 + 296 + return ret; 297 + }
+16
drivers/gpu/drm/armada/armada_plane.h
··· 1 + #ifndef ARMADA_PLANE_H 2 + #define ARMADA_PLANE_H 3 + 4 + void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 5 + int x, int y); 6 + int armada_drm_plane_prepare_fb(struct drm_plane *plane, 7 + struct drm_plane_state *state); 8 + void armada_drm_plane_cleanup_fb(struct drm_plane *plane, 9 + struct drm_plane_state *old_state); 10 + int armada_drm_plane_atomic_check(struct drm_plane *plane, 11 + struct drm_plane_state *state); 12 + int armada_drm_plane_init(struct armada_plane *plane); 13 + int armada_drm_primary_plane_init(struct drm_device *drm, 14 + struct armada_plane *primary); 15 + 16 + #endif