1 /* $NetBSD: sunxi_mixer.c,v 1.16 2021/01/27 03:10:20 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.16 2021/01/27 03:10:20 thorpej Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/intr.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/conf.h> 39 #include <sys/sysctl.h> 40 41 #include <drm/drmP.h> 42 #include <drm/drm_crtc.h> 43 #include <drm/drm_crtc_helper.h> 44 #include <drm/drm_plane_helper.h> 45 46 #include <dev/fdt/fdtvar.h> 47 #include <dev/fdt/fdt_port.h> 48 49 #include <arm/sunxi/sunxi_drm.h> 50 51 #define MIXER_CURSOR_MAXWIDTH 256 52 #define MIXER_CURSOR_MAXHEIGHT 256 53 54 #define SUNXI_MIXER_FREQ 432000000 55 56 #define GLB_BASE 0x00000 57 #define BLD_BASE 0x01000 58 #define OVL_BASE(n) (0x02000 + (n) * 0x1000) 59 #define VSU_BASE 0x20000 60 #define CSC_BASE(n) ((n) == 0 ? 0xaa050 : 0xa0000) 61 62 /* GLB registers */ 63 #define GLB_CTL 0x000 64 #define GLB_CTL_EN __BIT(0) 65 #define GLB_STS 0x004 66 #define GLB_DBUFFER 0x008 67 #define GLB_DBUFFER_DOUBLE_BUFFER_RDY __BIT(0) 68 #define GLB_SIZE 0x00c 69 70 /* BLD registers */ 71 #define BLD_FILL_COLOR_CTL 0x000 72 #define BLD_FILL_COLOR_CTL_P3_EN __BIT(11) 73 #define BLD_FILL_COLOR_CTL_P2_EN __BIT(10) 74 #define BLD_FILL_COLOR_CTL_P1_EN __BIT(9) 75 #define BLD_FILL_COLOR_CTL_P0_EN __BIT(8) 76 #define BLD_FILL_COLOR_CTL_P3_FCEN __BIT(3) 77 #define BLD_FILL_COLOR_CTL_P2_FCEN __BIT(2) 78 #define BLD_FILL_COLOR_CTL_P1_FCEN __BIT(1) 79 #define BLD_FILL_COLOR_CTL_P0_FCEN __BIT(0) 80 #define BLD_FILL_COLOR(n) (0x004 + (n) * 0x10) 81 #define BLD_CH_ISIZE(n) (0x008 + (n) * 0x10) 82 #define BLD_CH_OFFSET(n) (0x00c + (n) * 0x10) 83 #define BLD_CH_RTCTL 0x080 84 #define BLD_CH_RTCTL_P3 __BITS(15,12) 85 #define BLD_CH_RTCTL_P2 __BITS(11,8) 86 #define BLD_CH_RTCTL_P1 __BITS(7,4) 87 #define BLD_CH_RTCTL_P0 __BITS(3,0) 88 #define BLD_SIZE 0x08c 89 #define BLD_CTL(n) (0x090 + (n) * 0x04) 90 91 /* OVL_V registers */ 92 #define OVL_V_ATTCTL(n) (0x000 + (n) * 0x30) 93 #define OVL_V_ATTCTL_VIDEO_UI_SEL __BIT(15) 94 #define OVL_V_ATTCTL_LAY_FBFMT __BITS(12,8) 95 #define OVL_V_ATTCTL_LAY_FBFMT_VYUY 0x00 96 #define OVL_V_ATTCTL_LAY_FBFMT_YVYU 0x01 97 #define OVL_V_ATTCTL_LAY_FBFMT_UYVY 0x02 98 #define OVL_V_ATTCTL_LAY_FBFMT_YUYV 0x03 99 #define OVL_V_ATTCTL_LAY_FBFMT_YUV422 0x06 100 #define OVL_V_ATTCTL_LAY_FBFMT_YUV420 0x0a 101 #define OVL_V_ATTCTL_LAY_FBFMT_YUV411 0x0e 102 #if BYTE_ORDER == BIG_ENDIAN 103 #define OVL_V_ATTCTL_LAY_FBFMT_ARGB_8888 0x03 104 #define OVL_V_ATTCTL_LAY_FBFMT_XRGB_8888 0x07 105 #else 106 #define OVL_V_ATTCTL_LAY_FBFMT_ARGB_8888 0x00 107 #define OVL_V_ATTCTL_LAY_FBFMT_XRGB_8888 0x04 108 #endif 109 #define OVL_V_ATTCTL_LAY0_EN __BIT(0) 110 #define OVL_V_MBSIZE(n) (0x004 + (n) * 0x30) 111 #define OVL_V_COOR(n) (0x008 + (n) * 0x30) 112 #define OVL_V_PITCH0(n) (0x00c + (n) * 0x30) 113 #define OVL_V_PITCH1(n) (0x010 + (n) * 0x30) 114 #define OVL_V_PITCH2(n) (0x014 + (n) * 0x30) 115 #define OVL_V_TOP_LADD0(n) (0x018 + (n) * 0x30) 116 #define OVL_V_TOP_LADD1(n) (0x01c + (n) * 0x30) 117 #define OVL_V_TOP_LADD2(n) (0x020 + (n) * 0x30) 118 #define OVL_V_FILL_COLOR(n) (0x0c0 + (n) * 0x4) 119 #define OVL_V_TOP_HADD0 0x0d0 120 #define OVL_V_TOP_HADD1 0x0d4 121 #define OVL_V_TOP_HADD2 0x0d8 122 #define OVL_V_TOP_HADD_LAYER0 __BITS(7,0) 123 #define OVL_V_SIZE 0x0e8 124 #define OVL_V_HDS_CTL0 0x0f0 125 #define OVL_V_HDS_CTL1 0x0f4 126 #define OVL_V_VDS_CTL0 0x0f8 127 #define OVL_V_VDS_CTL1 0x0fc 128 129 /* OVL_UI registers */ 130 #define OVL_UI_ATTR_CTL(n) (0x000 + (n) * 0x20) 131 #define OVL_UI_ATTR_CTL_LAY_FBFMT __BITS(12,8) 132 #if BYTE_ORDER == BIG_ENDIAN 133 #define OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888 0x03 134 #define OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888 0x07 135 #else 136 #define OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888 0x00 137 #define OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888 0x04 138 #endif 139 #define OVL_UI_ATTR_CTL_LAY_EN __BIT(0) 140 #define OVL_UI_MBSIZE(n) (0x004 + (n) * 0x20) 141 #define OVL_UI_COOR(n) (0x008 + (n) * 0x20) 142 #define OVL_UI_PITCH(n) (0x00c + (n) * 0x20) 143 #define OVL_UI_TOP_LADD(n) (0x010 + (n) * 0x20) 144 #define OVL_UI_FILL_COLOR(n) (0x018 + (n) * 0x20) 145 #define OVL_UI_TOP_HADD 0x080 146 #define OVL_UI_TOP_HADD_LAYER1 __BITS(15,8) 147 #define OVL_UI_TOP_HADD_LAYER0 __BITS(7,0) 148 #define OVL_UI_SIZE 0x088 149 150 /* VSU registers */ 151 #define VS_CTRL_REG 0x000 152 #define VS_CTRL_COEF_SWITCH_EN __BIT(4) 153 #define VS_CTRL_EN __BIT(0) 154 #define VS_STATUS_REG 0x008 155 #define VS_FIELD_CTRL_REG 0x00c 156 #define VS_OUT_SIZE_REG 0x040 157 #define VS_Y_SIZE_REG 0x080 158 #define VS_Y_HSTEP_REG 0x088 159 #define VS_Y_VSTEP_REG 0x08c 160 #define VS_Y_HPHASE_REG 0x090 161 #define VS_Y_VPHASE0_REG 0x098 162 #define VS_Y_VPHASE1_REG 0x09c 163 #define VS_C_SIZE_REG 0x0c0 164 #define VS_C_HSTEP_REG 0x0c8 165 #define VS_C_VSTEP_REG 0x0cc 166 #define VS_C_HPHASE_REG 0x0d0 167 #define VS_C_VPHASE0_REG 0x0d8 168 #define VS_C_VPHASE1_REG 0x0dc 169 #define VS_Y_HCOEF0_REG(n) (0x200 + (n) * 0x4) 170 #define VS_Y_HCOEF1_REG(n) (0x300 + (n) * 0x4) 171 #define VS_Y_VCOEF_REG(n) (0x400 + (n) * 0x4) 172 #define VS_C_HCOEF0_REG(n) (0x600 + (n) * 0x4) 173 #define VS_C_HCOEF1_REG(n) (0x700 + (n) * 0x4) 174 #define VS_C_VCOEF_REG(n) (0x800 + (n) * 0x4) 175 176 /* CSC registers */ 177 #define CSC_BYPASS_REG 0x000 178 #define CSC_BYPASS_DISABLE __BIT(0) 179 #define CSC_COEFF0_REG(n) (0x10 + 0x10 * (n)) 180 #define GLB_ALPHA_REG 0x040 181 182 enum { 183 MIXER_PORT_OUTPUT = 1, 184 }; 185 186 struct sunxi_mixer_compat_data { 187 uint8_t ovl_ui_count; 188 uint8_t mixer_index; 189 }; 190 191 struct sunxi_mixer_compat_data mixer0_data = { 192 .ovl_ui_count = 3, 193 .mixer_index = 0, 194 }; 195 196 struct sunxi_mixer_compat_data mixer1_data = { 197 .ovl_ui_count = 1, 198 .mixer_index = 1, 199 }; 200 201 static const struct device_compatible_entry compat_data[] = { 202 { .compat = "allwinner,sun8i-h3-de2-mixer-0", 203 .data = &mixer0_data }, 204 { .compat = "allwinner,sun50i-a64-de2-mixer-0", 205 .data = &mixer0_data }, 206 { .compat = "allwinner,sun50i-a64-de2-mixer-1", 207 .data = &mixer1_data }, 208 209 DEVICE_COMPAT_EOL 210 }; 211 212 struct sunxi_mixer_softc; 213 214 struct sunxi_mixer_crtc { 215 struct drm_crtc base; 216 struct sunxi_mixer_softc *sc; 217 }; 218 219 struct sunxi_mixer_plane { 220 struct drm_plane base; 221 struct sunxi_mixer_softc *sc; 222 }; 223 224 struct sunxi_mixer_softc { 225 device_t sc_dev; 226 bus_space_tag_t sc_bst; 227 bus_space_handle_t sc_bsh; 228 int sc_phandle; 229 230 u_int sc_ovl_ui_count; 231 232 struct sunxi_mixer_crtc sc_crtc; 233 struct sunxi_mixer_plane sc_overlay; 234 235 struct fdt_device_ports sc_ports; 236 }; 237 238 #define GLB_READ(sc, reg) \ 239 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, GLB_BASE + (reg)) 240 #define GLB_WRITE(sc, reg, val) \ 241 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, GLB_BASE + (reg), (val)) 242 243 #define BLD_READ(sc, reg) \ 244 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, BLD_BASE + (reg)) 245 #define BLD_WRITE(sc, reg, val) \ 246 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, BLD_BASE + (reg), (val)) 247 248 #define OVL_V_READ(sc, reg) \ 249 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE(0) + (reg)) 250 #define OVL_V_WRITE(sc, reg, val) \ 251 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE(0) + (reg), (val)) 252 253 #define OVL_UI_READ(sc, n, reg) \ 254 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE((n) + 1) + (reg)) 255 #define OVL_UI_WRITE(sc, n, reg, val) \ 256 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE((n) + 1) + (reg), (val)) 257 258 #define VSU_READ(sc, reg) \ 259 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg)) 260 #define VSU_WRITE(sc, reg, val) \ 261 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg), (val)) 262 263 #define CSC_READ(sc, n, reg) \ 264 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg)) 265 #define CSC_WRITE(sc, n, reg, val) \ 266 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg), (val)) 267 268 #define to_sunxi_mixer_crtc(x) container_of(x, struct sunxi_mixer_crtc, base) 269 #define to_sunxi_mixer_plane(x) container_of(x, struct sunxi_mixer_plane, base) 270 271 static int 272 sunxi_mixer_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, 273 int x, int y, int atomic) 274 { 275 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 276 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 277 struct sunxi_drm_framebuffer *sfb = atomic? 278 to_sunxi_drm_framebuffer(fb) : 279 to_sunxi_drm_framebuffer(crtc->primary->fb); 280 uint32_t val; 281 282 uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; 283 284 paddr += y * sfb->base.pitches[0]; 285 paddr += x * drm_format_plane_cpp(sfb->base.pixel_format, 0); 286 287 uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0; 288 uint32_t laddr = paddr & 0xffffffff; 289 290 /* Set UI overlay line size */ 291 OVL_UI_WRITE(sc, 0, OVL_UI_PITCH(0), sfb->base.pitches[0]); 292 293 /* Framebuffer start address */ 294 val = OVL_UI_READ(sc, 0, OVL_UI_TOP_HADD); 295 val &= ~OVL_UI_TOP_HADD_LAYER0; 296 val |= __SHIFTIN(haddr, OVL_UI_TOP_HADD_LAYER0); 297 OVL_UI_WRITE(sc, 0, OVL_UI_TOP_HADD, val); 298 OVL_UI_WRITE(sc, 0, OVL_UI_TOP_LADD(0), laddr); 299 300 return 0; 301 } 302 303 static void 304 sunxi_mixer_destroy(struct drm_crtc *crtc) 305 { 306 drm_crtc_cleanup(crtc); 307 } 308 309 static int 310 sunxi_mixer_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 311 struct drm_pending_vblank_event *event, uint32_t flags) 312 { 313 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 314 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 315 unsigned long irqflags; 316 317 drm_crtc_wait_one_vblank(crtc); 318 319 sunxi_mixer_mode_do_set_base(crtc, fb, 0, 0, true); 320 321 /* Commit settings */ 322 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 323 324 if (event) { 325 spin_lock_irqsave(&crtc->dev->event_lock, irqflags); 326 drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), event); 327 spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags); 328 } 329 330 return 0; 331 } 332 333 static int 334 sunxi_mixer_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, 335 uint32_t handle, uint32_t width, uint32_t height) 336 { 337 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 338 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 339 struct drm_gem_object *gem_obj = NULL; 340 struct drm_gem_cma_object *obj; 341 uint32_t val; 342 int error; 343 344 /* Only mixers with more than one UI layer can support hardware cursors */ 345 if (sc->sc_ovl_ui_count <= 1) 346 return -EINVAL; 347 348 if (handle == 0) { 349 val = BLD_READ(sc, BLD_FILL_COLOR_CTL); 350 val &= ~BLD_FILL_COLOR_CTL_P2_EN; 351 val |= BLD_FILL_COLOR_CTL_P2_FCEN; 352 BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val); 353 354 error = 0; 355 goto done; 356 } 357 358 /* Arbitrary limits, the hardware layer can do 8192x8192 */ 359 if (width > MIXER_CURSOR_MAXWIDTH || height > MIXER_CURSOR_MAXHEIGHT) { 360 DRM_ERROR("Cursor dimension %ux%u not supported\n", width, height); 361 error = -EINVAL; 362 goto done; 363 } 364 365 gem_obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); 366 if (gem_obj == NULL) { 367 DRM_ERROR("Cannot find cursor object %#x for crtc %d\n", 368 handle, drm_crtc_index(crtc)); 369 error = -ENOENT; 370 goto done; 371 } 372 obj = to_drm_gem_cma_obj(gem_obj); 373 374 if (obj->base.size < width * height * 4) { 375 DRM_ERROR("Cursor buffer is too small\n"); 376 error = -ENOMEM; 377 goto done; 378 } 379 380 uint64_t paddr = (uint64_t)obj->dmamap->dm_segs[0].ds_addr; 381 uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0; 382 uint32_t laddr = paddr & 0xffffffff; 383 384 /* Framebuffer start address */ 385 val = OVL_UI_READ(sc, 1, OVL_UI_TOP_HADD); 386 val &= ~OVL_UI_TOP_HADD_LAYER0; 387 val |= __SHIFTIN(haddr, OVL_UI_TOP_HADD_LAYER0); 388 OVL_UI_WRITE(sc, 1, OVL_UI_TOP_HADD, val); 389 OVL_UI_WRITE(sc, 1, OVL_UI_TOP_LADD(0), laddr); 390 391 const uint32_t size = ((height - 1) << 16) | (width - 1); 392 const uint32_t offset = (crtc->cursor_y << 16) | crtc->cursor_x; 393 const uint32_t crtc_size = ((crtc->primary->fb->height - 1) << 16) | 394 (crtc->primary->fb->width - 1); 395 396 /* Enable cursor in ARGB8888 mode */ 397 val = OVL_UI_ATTR_CTL_LAY_EN | 398 __SHIFTIN(OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888, OVL_UI_ATTR_CTL_LAY_FBFMT); 399 OVL_UI_WRITE(sc, 1, OVL_UI_ATTR_CTL(0), val); 400 /* Set UI overlay layer size */ 401 OVL_UI_WRITE(sc, 1, OVL_UI_MBSIZE(0), size); 402 /* Set UI overlay offset */ 403 OVL_UI_WRITE(sc, 1, OVL_UI_COOR(0), offset); 404 /* Set UI overlay line size */ 405 OVL_UI_WRITE(sc, 1, OVL_UI_PITCH(0), width * 4); 406 /* Set UI overlay window size */ 407 OVL_UI_WRITE(sc, 1, OVL_UI_SIZE, crtc_size); 408 409 /* Set blender 2 input size */ 410 BLD_WRITE(sc, BLD_CH_ISIZE(2), crtc_size); 411 /* Set blender 2 offset */ 412 BLD_WRITE(sc, BLD_CH_OFFSET(2), 0); 413 /* Route channel 2 to pipe 2 */ 414 val = BLD_READ(sc, BLD_CH_RTCTL); 415 val &= ~BLD_CH_RTCTL_P2; 416 val |= __SHIFTIN(2, BLD_CH_RTCTL_P2); 417 BLD_WRITE(sc, BLD_CH_RTCTL, val); 418 419 /* Enable pipe 2 */ 420 val = BLD_READ(sc, BLD_FILL_COLOR_CTL); 421 val |= BLD_FILL_COLOR_CTL_P2_EN; 422 val &= ~BLD_FILL_COLOR_CTL_P2_FCEN; 423 BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val); 424 425 error = 0; 426 427 done: 428 if (error == 0) { 429 /* Commit settings */ 430 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 431 } 432 433 if (gem_obj != NULL) 434 drm_gem_object_unreference_unlocked(gem_obj); 435 436 return error; 437 } 438 439 static int 440 sunxi_mixer_cursor_move(struct drm_crtc *crtc, int x, int y) 441 { 442 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 443 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 444 445 crtc->cursor_x = x & 0xffff; 446 crtc->cursor_y = y & 0xffff; 447 448 const uint32_t offset = (crtc->cursor_y << 16) | crtc->cursor_x; 449 450 OVL_UI_WRITE(sc, 1, OVL_UI_COOR(0), offset); 451 452 /* Commit settings */ 453 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 454 455 return 0; 456 } 457 458 static const struct drm_crtc_funcs sunxi_mixer0_crtc_funcs = { 459 .set_config = drm_crtc_helper_set_config, 460 .destroy = sunxi_mixer_destroy, 461 .page_flip = sunxi_mixer_page_flip, 462 .cursor_set = sunxi_mixer_cursor_set, 463 .cursor_move = sunxi_mixer_cursor_move, 464 }; 465 466 static const struct drm_crtc_funcs sunxi_mixer1_crtc_funcs = { 467 .set_config = drm_crtc_helper_set_config, 468 .destroy = sunxi_mixer_destroy, 469 .page_flip = sunxi_mixer_page_flip, 470 }; 471 472 static void 473 sunxi_mixer_dpms(struct drm_crtc *crtc, int mode) 474 { 475 } 476 477 static bool 478 sunxi_mixer_mode_fixup(struct drm_crtc *crtc, 479 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) 480 { 481 return true; 482 } 483 484 static int 485 sunxi_mixer_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 486 struct drm_display_mode *adjusted_mode, int x, int y, 487 struct drm_framebuffer *old_fb) 488 { 489 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 490 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 491 uint32_t val; 492 u_int fbfmt; 493 494 const uint32_t size = ((adjusted_mode->vdisplay - 1) << 16) | 495 (adjusted_mode->hdisplay - 1); 496 497 /* Set global size */ 498 GLB_WRITE(sc, GLB_SIZE, size); 499 500 /* Enable pipe 0 */ 501 val = BLD_READ(sc, BLD_FILL_COLOR_CTL); 502 val |= BLD_FILL_COLOR_CTL_P0_EN; 503 BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val); 504 505 /* Set blender 0 input size */ 506 BLD_WRITE(sc, BLD_CH_ISIZE(0), size); 507 /* Set blender 0 offset */ 508 BLD_WRITE(sc, BLD_CH_OFFSET(0), 0); 509 /* Route channel 1 to pipe 0 */ 510 val = BLD_READ(sc, BLD_CH_RTCTL); 511 val &= ~BLD_CH_RTCTL_P0; 512 val |= __SHIFTIN(1, BLD_CH_RTCTL_P0); 513 BLD_WRITE(sc, BLD_CH_RTCTL, val); 514 /* Set blender output size */ 515 BLD_WRITE(sc, BLD_SIZE, size); 516 517 /* Enable UI overlay */ 518 if (crtc->primary->fb->pixel_format == DRM_FORMAT_XRGB8888) 519 fbfmt = OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888; 520 else 521 fbfmt = OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888; 522 val = OVL_UI_ATTR_CTL_LAY_EN | __SHIFTIN(fbfmt, OVL_UI_ATTR_CTL_LAY_FBFMT); 523 OVL_UI_WRITE(sc, 0, OVL_UI_ATTR_CTL(0), val); 524 /* Set UI overlay layer size */ 525 OVL_UI_WRITE(sc, 0, OVL_UI_MBSIZE(0), size); 526 /* Set UI overlay offset */ 527 OVL_UI_WRITE(sc, 0, OVL_UI_COOR(0), 0); 528 /* Set UI overlay window size */ 529 OVL_UI_WRITE(sc, 0, OVL_UI_SIZE, size); 530 531 sunxi_mixer_mode_do_set_base(crtc, old_fb, x, y, 0); 532 533 return 0; 534 } 535 536 static int 537 sunxi_mixer_mode_set_base(struct drm_crtc *crtc, int x, int y, 538 struct drm_framebuffer *old_fb) 539 { 540 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 541 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 542 543 sunxi_mixer_mode_do_set_base(crtc, old_fb, x, y, 0); 544 545 /* Commit settings */ 546 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 547 548 return 0; 549 } 550 551 static int 552 sunxi_mixer_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, 553 int x, int y, enum mode_set_atomic state) 554 { 555 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 556 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 557 558 sunxi_mixer_mode_do_set_base(crtc, fb, x, y, 1); 559 560 /* Commit settings */ 561 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 562 563 return 0; 564 } 565 566 static void 567 sunxi_mixer_disable(struct drm_crtc *crtc) 568 { 569 } 570 571 static void 572 sunxi_mixer_prepare(struct drm_crtc *crtc) 573 { 574 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 575 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 576 577 /* RT enable */ 578 GLB_WRITE(sc, GLB_CTL, GLB_CTL_EN); 579 } 580 581 static void 582 sunxi_mixer_commit(struct drm_crtc *crtc) 583 { 584 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 585 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 586 587 /* Commit settings */ 588 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 589 } 590 591 static const struct drm_crtc_helper_funcs sunxi_mixer_crtc_helper_funcs = { 592 .dpms = sunxi_mixer_dpms, 593 .mode_fixup = sunxi_mixer_mode_fixup, 594 .mode_set = sunxi_mixer_mode_set, 595 .mode_set_base = sunxi_mixer_mode_set_base, 596 .mode_set_base_atomic = sunxi_mixer_mode_set_base_atomic, 597 .disable = sunxi_mixer_disable, 598 .prepare = sunxi_mixer_prepare, 599 .commit = sunxi_mixer_commit, 600 }; 601 602 static void 603 sunxi_mixer_overlay_destroy(struct drm_plane *plane) 604 { 605 } 606 607 static bool 608 sunxi_mixer_overlay_rgb(uint32_t drm_format) 609 { 610 switch (drm_format) { 611 case DRM_FORMAT_ARGB8888: 612 case DRM_FORMAT_XRGB8888: 613 return true; 614 default: 615 return false; 616 } 617 } 618 619 static u_int 620 sunxi_mixer_overlay_format(uint32_t drm_format) 621 { 622 switch (drm_format) { 623 case DRM_FORMAT_ARGB8888: return OVL_V_ATTCTL_LAY_FBFMT_ARGB_8888; 624 case DRM_FORMAT_XRGB8888: return OVL_V_ATTCTL_LAY_FBFMT_XRGB_8888; 625 case DRM_FORMAT_VYUY: return OVL_V_ATTCTL_LAY_FBFMT_VYUY; 626 case DRM_FORMAT_YVYU: return OVL_V_ATTCTL_LAY_FBFMT_YVYU; 627 case DRM_FORMAT_UYVY: return OVL_V_ATTCTL_LAY_FBFMT_UYVY; 628 case DRM_FORMAT_YUYV: return OVL_V_ATTCTL_LAY_FBFMT_YUYV; 629 case DRM_FORMAT_YUV422: return OVL_V_ATTCTL_LAY_FBFMT_YUV422; 630 case DRM_FORMAT_YUV420: return OVL_V_ATTCTL_LAY_FBFMT_YUV420; 631 case DRM_FORMAT_YUV411: return OVL_V_ATTCTL_LAY_FBFMT_YUV411; 632 default: return 0; /* shouldn't happen */ 633 } 634 } 635 636 static const uint32_t lan3coefftab32_left[512] = { 637 0x40000000, 0x40fe0000, 0x3ffd0100, 0x3efc0100, 638 0x3efb0100, 0x3dfa0200, 0x3cf90200, 0x3bf80200, 639 0x39f70200, 0x37f70200, 0x35f70200, 0x33f70200, 640 0x31f70200, 0x2ef70200, 0x2cf70200, 0x2af70200, 641 0x27f70200, 0x24f80100, 0x22f80100, 0x1ef90100, 642 0x1cf90100, 0x19fa0100, 0x17fa0100, 0x14fb0100, 643 0x11fc0000, 0x0ffc0000, 0x0cfd0000, 0x0afd0000, 644 0x08fe0000, 0x05ff0000, 0x03ff0000, 0x02000000, 645 646 0x40000000, 0x40fe0000, 0x3ffd0100, 0x3efc0100, 647 0x3efb0100, 0x3dfa0200, 0x3cf90200, 0x3bf80200, 648 0x39f70200, 0x37f70200, 0x35f70200, 0x33f70200, 649 0x31f70200, 0x2ef70200, 0x2cf70200, 0x2af70200, 650 0x27f70200, 0x24f80100, 0x22f80100, 0x1ef90100, 651 0x1cf90100, 0x19fa0100, 0x17fa0100, 0x14fb0100, 652 0x11fc0000, 0x0ffc0000, 0x0cfd0000, 0x0afd0000, 653 0x08fe0000, 0x05ff0000, 0x03ff0000, 0x02000000, 654 655 0x3806fc02, 0x3805fc02, 0x3803fd01, 0x3801fe01, 656 0x3700fe01, 0x35ffff01, 0x35fdff01, 0x34fc0001, 657 0x34fb0000, 0x33fa0000, 0x31fa0100, 0x2ff90100, 658 0x2df80200, 0x2bf80200, 0x2af70200, 0x28f70200, 659 0x27f70200, 0x24f70300, 0x22f70300, 0x1ff70300, 660 0x1ef70300, 0x1cf70300, 0x1af70300, 0x18f70300, 661 0x16f80300, 0x13f80300, 0x11f90300, 0x0ef90300, 662 0x0efa0200, 0x0cfa0200, 0x0afb0200, 0x08fb0200, 663 664 0x320bfa02, 0x3309fa02, 0x3208fb02, 0x3206fb02, 665 0x3205fb02, 0x3104fc02, 0x3102fc01, 0x3001fd01, 666 0x3000fd01, 0x2ffffd01, 0x2efefe01, 0x2dfdfe01, 667 0x2bfcff01, 0x29fcff01, 0x28fbff01, 0x27fa0001, 668 0x26fa0000, 0x24f90000, 0x22f90100, 0x20f90100, 669 0x1ff80100, 0x1ef80100, 0x1cf80100, 0x1af80200, 670 0x18f80200, 0x17f80200, 0x15f80200, 0x12f80200, 671 0x11f90200, 0x0ff90200, 0x0df90200, 0x0cfa0200, 672 673 0x2e0efa01, 0x2f0dfa01, 0x2f0bfa01, 0x2e0afa01, 674 0x2e09fa01, 0x2e07fb01, 0x2d06fb01, 0x2d05fb01, 675 0x2c04fb01, 0x2b03fc01, 0x2a02fc01, 0x2a01fc01, 676 0x2800fd01, 0x28fffd01, 0x26fefd01, 0x25fefe01, 677 0x24fdfe01, 0x23fcfe01, 0x21fcff01, 0x20fbff01, 678 0x1efbff01, 0x1efbff00, 0x1cfa0000, 0x1bfa0000, 679 0x19fa0000, 0x18fa0000, 0x17f90000, 0x15f90100, 680 0x14f90100, 0x12f90100, 0x11f90100, 0x0ff90100, 681 682 0x2b10fa00, 0x2b0ffa00, 0x2b0efa00, 0x2b0cfa00, 683 0x2b0bfa00, 0x2a0afb01, 0x2a09fb01, 0x2908fb01, 684 0x2807fb01, 0x2806fb01, 0x2805fb01, 0x2604fc01, 685 0x2503fc01, 0x2502fc01, 0x2401fc01, 0x2301fc01, 686 0x2100fd01, 0x21fffd01, 0x21fffd01, 0x20fefd01, 687 0x1dfefe01, 0x1cfdfe01, 0x1cfdfe00, 0x1bfcfe00, 688 0x19fcff00, 0x19fbff00, 0x17fbff00, 0x16fbff00, 689 0x15fbff00, 0x14fb0000, 0x13fa0000, 0x11fa0000, 690 691 0x2811fcff, 0x2810fcff, 0x280ffbff, 0x280efbff, 692 0x270dfb00, 0x270cfb00, 0x270bfb00, 0x260afb00, 693 0x2609fb00, 0x2508fb00, 0x2507fb00, 0x2407fb00, 694 0x2406fc00, 0x2305fc00, 0x2204fc00, 0x2203fc00, 695 0x2103fc00, 0x2002fc00, 0x1f01fd00, 0x1e01fd00, 696 0x1d00fd00, 0x1dfffd00, 0x1cfffd00, 0x1bfefd00, 697 0x1afefe00, 0x19fefe00, 0x18fdfe00, 0x17fdfe00, 698 0x16fdfe00, 0x15fcff00, 0x13fcff00, 0x12fcff00, 699 700 0x2512fdfe, 0x2511fdff, 0x2410fdff, 0x240ffdff, 701 0x240efcff, 0x240dfcff, 0x240dfcff, 0x240cfcff, 702 0x230bfcff, 0x230afc00, 0x2209fc00, 0x2108fc00, 703 0x2108fc00, 0x2007fc00, 0x2006fc00, 0x2005fc00, 704 0x1f05fc00, 0x1e04fc00, 0x1e03fc00, 0x1c03fd00, 705 0x1c02fd00, 0x1b02fd00, 0x1b01fd00, 0x1a00fd00, 706 0x1900fd00, 0x1800fd00, 0x17fffe00, 0x16fffe00, 707 0x16fefe00, 0x14fefe00, 0x13fefe00, 0x13fdfe00, 708 709 0x2212fffe, 0x2211fefe, 0x2211fefe, 0x2110fefe, 710 0x210ffeff, 0x220efdff, 0x210dfdff, 0x210dfdff, 711 0x210cfdff, 0x210bfdff, 0x200afdff, 0x200afdff, 712 0x1f09fdff, 0x1f08fdff, 0x1d08fd00, 0x1c07fd00, 713 0x1d06fd00, 0x1b06fd00, 0x1b05fd00, 0x1c04fd00, 714 0x1b04fd00, 0x1a03fd00, 0x1a03fd00, 0x1902fd00, 715 0x1802fd00, 0x1801fd00, 0x1701fd00, 0x1600fd00, 716 0x1400fe00, 0x1400fe00, 0x14fffe00, 0x13fffe00, 717 718 0x201200fe, 0x201100fe, 0x1f11fffe, 0x2010fffe, 719 0x1f0ffffe, 0x1e0ffffe, 0x1f0efeff, 0x1f0dfeff, 720 0x1f0dfeff, 0x1e0cfeff, 0x1e0bfeff, 0x1d0bfeff, 721 0x1d0afeff, 0x1d09fdff, 0x1d09fdff, 0x1c08fdff, 722 0x1c07fdff, 0x1b07fd00, 0x1b06fd00, 0x1a06fd00, 723 0x1a05fd00, 0x1805fd00, 0x1904fd00, 0x1804fd00, 724 0x1703fd00, 0x1703fd00, 0x1602fe00, 0x1502fe00, 725 0x1501fe00, 0x1401fe00, 0x1301fe00, 0x1300fe00, 726 727 0x1c1202fe, 0x1c1102fe, 0x1b1102fe, 0x1c1001fe, 728 0x1b1001fe, 0x1b0f01ff, 0x1b0e00ff, 0x1b0e00ff, 729 0x1b0d00ff, 0x1a0d00ff, 0x1a0c00ff, 0x1a0cffff, 730 0x1a0bffff, 0x1a0bffff, 0x1a0affff, 0x180affff, 731 0x1909ffff, 0x1809ffff, 0x1808ffff, 0x1808feff, 732 0x1807feff, 0x1707fe00, 0x1606fe00, 0x1506fe00, 733 0x1605fe00, 0x1505fe00, 0x1504fe00, 0x1304fe00, 734 0x1304fe00, 0x1303fe00, 0x1203fe00, 0x1203fe00, 735 736 0x181104ff, 0x191103ff, 0x191003ff, 0x181003ff, 737 0x180f03ff, 0x190f02ff, 0x190e02ff, 0x180e02ff, 738 0x180d02ff, 0x180d01ff, 0x180d01ff, 0x180c01ff, 739 0x180c01ff, 0x180b00ff, 0x170b00ff, 0x170a00ff, 740 0x170a00ff, 0x170900ff, 0x160900ff, 0x160900ff, 741 0x1608ffff, 0x1508ffff, 0x1507ff00, 0x1507ff00, 742 0x1407ff00, 0x1306ff00, 0x1306ff00, 0x1305ff00, 743 0x1205ff00, 0x1105ff00, 0x1204ff00, 0x1104ff00, 744 745 0x171005ff, 0x171005ff, 0x171004ff, 0x170f04ff, 746 0x160f04ff, 0x170f03ff, 0x170e03ff, 0x160e03ff, 747 0x160d03ff, 0x160d02ff, 0x160d02ff, 0x160c02ff, 748 0x160c02ff, 0x160c02ff, 0x160b01ff, 0x150b01ff, 749 0x150a01ff, 0x150a01ff, 0x150a01ff, 0x140901ff, 750 0x14090000, 0x14090000, 0x14080000, 0x13080000, 751 0x13070000, 0x12070000, 0x12070000, 0x12060000, 752 0x11060000, 0x11060000, 0x11050000, 0x1105ff00, 753 754 0x14100600, 0x15100500, 0x150f0500, 0x150f0500, 755 0x140f0500, 0x150e0400, 0x140e0400, 0x130e0400, 756 0x140d0400, 0x150d0300, 0x130d0300, 0x140c0300, 757 0x140c0300, 0x140c0200, 0x140b0200, 0x130b0200, 758 0x120b0200, 0x130a0200, 0x130a0200, 0x130a0100, 759 0x13090100, 0x12090100, 0x11090100, 0x12080100, 760 0x11080100, 0x10080100, 0x11070100, 0x11070000, 761 0x10070000, 0x11060000, 0x10060000, 0x10060000, 762 763 0x140f0600, 0x140f0600, 0x130f0600, 0x140f0500, 764 0x140e0500, 0x130e0500, 0x130e0500, 0x140d0400, 765 0x140d0400, 0x130d0400, 0x120d0400, 0x130c0400, 766 0x130c0300, 0x130c0300, 0x130b0300, 0x130b0300, 767 0x110b0300, 0x130a0200, 0x120a0200, 0x120a0200, 768 0x120a0200, 0x12090200, 0x10090200, 0x11090100, 769 0x11080100, 0x11080100, 0x10080100, 0x10080100, 770 0x10070100, 0x10070100, 0x0f070100, 0x10060100, 771 772 0x120f0701, 0x130f0601, 0x130e0601, 0x130e0601, 773 0x120e0601, 0x130e0501, 0x130e0500, 0x130d0500, 774 0x120d0500, 0x120d0500, 0x130c0400, 0x130c0400, 775 0x120c0400, 0x110c0400, 0x120b0400, 0x120b0300, 776 0x120b0300, 0x120b0300, 0x120a0300, 0x110a0300, 777 0x110a0200, 0x11090200, 0x11090200, 0x10090200, 778 0x10090200, 0x10080200, 0x10080200, 0x10080100, 779 0x0f080100, 0x10070100, 0x0f070100, 0x0f070100 780 }; 781 782 static const uint32_t lan3coefftab32_right[512] = { 783 0x00000000, 0x00000002, 0x0000ff04, 0x0000ff06, 784 0x0000fe08, 0x0000fd0a, 0x0000fd0c, 0x0000fc0f, 785 0x0000fc12, 0x0001fb14, 0x0001fa17, 0x0001fa19, 786 0x0001f91c, 0x0001f91f, 0x0001f822, 0x0001f824, 787 0x0002f727, 0x0002f72a, 0x0002f72c, 0x0002f72f, 788 0x0002f731, 0x0002f733, 0x0002f735, 0x0002f737, 789 0x0002f73a, 0x0002f83b, 0x0002f93c, 0x0002fa3d, 790 0x0001fb3e, 0x0001fc3f, 0x0001fd40, 0x0000fe40, 791 792 0x00000000, 0x00000002, 0x0000ff04, 0x0000ff06, 793 0x0000fe08, 0x0000fd0a, 0x0000fd0c, 0x0000fc0f, 794 0x0000fc12, 0x0001fb14, 0x0001fa17, 0x0001fa19, 795 0x0001f91c, 0x0001f91f, 0x0001f822, 0x0001f824, 796 0x0002f727, 0x0002f72a, 0x0002f72c, 0x0002f72f, 797 0x0002f731, 0x0002f733, 0x0002f735, 0x0002f737, 798 0x0002f73a, 0x0002f83b, 0x0002f93c, 0x0002fa3d, 799 0x0001fb3e, 0x0001fc3f, 0x0001fd40, 0x0000fe40, 800 801 0x0002fc06, 0x0002fb08, 0x0002fb0a, 0x0002fa0c, 802 0x0002fa0e, 0x0003f910, 0x0003f912, 0x0003f814, 803 0x0003f816, 0x0003f719, 0x0003f71a, 0x0003f71d, 804 0x0003f71f, 0x0003f721, 0x0003f723, 0x0003f725, 805 0x0002f727, 0x0002f729, 0x0002f72b, 0x0002f82d, 806 0x0002f82e, 0x0001f930, 0x0001fa31, 0x0000fa34, 807 0x0000fb34, 0x0100fc35, 0x01fffd36, 0x01ffff37, 808 0x01fe0037, 0x01fe0138, 0x01fd0338, 0x02fc0538, 809 810 0x0002fa0b, 0x0002fa0c, 0x0002f90e, 0x0002f910, 811 0x0002f911, 0x0002f813, 0x0002f816, 0x0002f817, 812 0x0002f818, 0x0002f81a, 0x0001f81c, 0x0001f81e, 813 0x0001f820, 0x0001f921, 0x0001f923, 0x0000f925, 814 0x0000fa26, 0x0100fa28, 0x01fffb29, 0x01fffc2a, 815 0x01fffc2c, 0x01fefd2d, 0x01fefe2e, 0x01fdff2f, 816 0x01fd0030, 0x01fd0130, 0x01fc0232, 0x02fc0432, 817 0x02fb0532, 0x02fb0633, 0x02fb0833, 0x02fa0933, 818 819 0x0001fa0e, 0x0001f90f, 0x0001f911, 0x0001f913, 820 0x0001f914, 0x0001f915, 0x0000f918, 0x0000fa18, 821 0x0000fa1a, 0x0000fa1b, 0x0000fa1d, 0x00fffb1e, 822 0x01fffb1f, 0x01fffb20, 0x01fffc22, 0x01fefc23, 823 0x01fefd24, 0x01fefe25, 0x01fdfe27, 0x01fdff28, 824 0x01fd0029, 0x01fc012a, 0x01fc022b, 0x01fc032b, 825 0x01fb042d, 0x01fb052d, 0x01fb062e, 0x01fb072e, 826 0x01fa092e, 0x01fa0a2f, 0x01fa0b2f, 0x01fa0d2f, 827 828 0x0000fa11, 0x0000fa12, 0x0000fa13, 0x0000fb14, 829 0x00fffb16, 0x00fffb16, 0x00fffb17, 0x00fffb19, 830 0x00fffc1a, 0x00fefc1c, 0x00fefd1c, 0x01fefd1d, 831 0x01fefe1e, 0x01fdfe20, 0x01fdff21, 0x01fdff22, 832 0x01fd0023, 0x01fc0124, 0x01fc0124, 0x01fc0225, 833 0x01fc0326, 0x01fc0427, 0x01fb0528, 0x01fb0629, 834 0x01fb0729, 0x01fb0829, 0x01fb092a, 0x01fb0a2a, 835 0x00fa0b2c, 0x00fa0c2b, 0x00fa0e2b, 0x00fa0f2c, 836 837 0x00fffc11, 0x00fffc12, 0x00fffc14, 0x00fffc15, 838 0x00fefd16, 0x00fefd17, 0x00fefd18, 0x00fefe19, 839 0x00fefe1a, 0x00fdfe1d, 0x00fdff1d, 0x00fdff1e, 840 0x00fd001d, 0x00fd011e, 0x00fd0120, 0x00fc0221, 841 0x00fc0321, 0x00fc0323, 0x00fc0423, 0x00fc0523, 842 0x00fc0624, 0x00fb0725, 0x00fb0726, 0x00fb0827, 843 0x00fb0926, 0x00fb0a26, 0x00fb0b27, 0x00fb0c27, 844 0x00fb0d27, 0xfffb0e28, 0xfffb0f29, 0xfffc1028, 845 846 0x00fefd13, 0x00fefd13, 0x00fefe14, 0x00fefe15, 847 0x00fefe17, 0x00feff17, 0x00feff17, 0x00fd0018, 848 0x00fd001a, 0x00fd001a, 0x00fd011b, 0x00fd021c, 849 0x00fd021c, 0x00fd031d, 0x00fc031f, 0x00fc041f, 850 0x00fc051f, 0x00fc0521, 0x00fc0621, 0x00fc0721, 851 0x00fc0821, 0x00fc0822, 0x00fc0922, 0x00fc0a23, 852 0xfffc0b24, 0xfffc0c24, 0xfffc0d24, 0xfffc0d25, 853 0xfffc0e25, 0xfffd0f25, 0xfffd1025, 0xfffd1125, 854 855 0x00feff12, 0x00feff14, 0x00feff14, 0x00fe0015, 856 0x00fe0015, 0x00fd0017, 0x00fd0118, 0x00fd0118, 857 0x00fd0218, 0x00fd0219, 0x00fd031a, 0x00fd031a, 858 0x00fd041b, 0x00fd041c, 0x00fd051c, 0x00fd061d, 859 0x00fd061d, 0x00fd071e, 0x00fd081e, 0xfffd081f, 860 0xfffd091f, 0xfffd0a20, 0xfffd0a20, 0xfffd0b21, 861 0xfffd0c21, 0xfffd0d21, 0xfffd0d22, 0xfffd0e23, 862 0xfffe0f22, 0xfefe1022, 0xfefe1122, 0xfefe1123, 863 864 0x00fe0012, 0x00fe0013, 0x00fe0114, 0x00fe0114, 865 0x00fe0116, 0x00fe0216, 0x00fe0216, 0x00fd0317, 866 0x00fd0317, 0x00fd0418, 0x00fd0419, 0x00fd0519, 867 0x00fd051a, 0x00fd061b, 0x00fd061b, 0x00fd071c, 868 0xfffd071e, 0xfffd081d, 0xfffd091d, 0xfffd091e, 869 0xfffe0a1d, 0xfffe0b1e, 0xfffe0b1e, 0xfffe0c1e, 870 0xfffe0d1f, 0xfffe0d1f, 0xfffe0e1f, 0xfeff0f1f, 871 0xfeff0f20, 0xfeff1020, 0xfeff1120, 0xfe001120, 872 873 0x00fe0212, 0x00fe0312, 0x00fe0313, 0x00fe0314, 874 0x00fe0414, 0x00fe0414, 0x00fe0416, 0x00fe0515, 875 0x00fe0516, 0x00fe0616, 0x00fe0617, 0x00fe0717, 876 0xfffe0719, 0xfffe0818, 0xffff0818, 0xffff0919, 877 0xffff0919, 0xffff0a19, 0xffff0a1a, 0xffff0b1a, 878 0xffff0b1b, 0xffff0c1a, 0xff000c1b, 0xff000d1b, 879 0xff000d1b, 0xff000e1b, 0xff000e1c, 0xff010f1c, 880 0xfe01101c, 0xfe01101d, 0xfe02111c, 0xfe02111c, 881 882 0x00ff0411, 0x00ff0411, 0x00ff0412, 0x00ff0512, 883 0x00ff0513, 0x00ff0513, 0x00ff0613, 0x00ff0614, 884 0x00ff0714, 0x00ff0715, 0x00ff0715, 0xffff0816, 885 0xffff0816, 0xff000916, 0xff000917, 0xff000918, 886 0xff000a17, 0xff000a18, 0xff000b18, 0xff000b18, 887 0xff010c18, 0xff010c19, 0xff010d18, 0xff010d18, 888 0xff020d18, 0xff020e19, 0xff020e19, 0xff020f19, 889 0xff030f19, 0xff031019, 0xff031019, 0xff031119, 890 891 0x00ff0511, 0x00ff0511, 0x00000511, 0x00000611, 892 0x00000612, 0x00000612, 0x00000712, 0x00000713, 893 0x00000714, 0x00000814, 0x00000814, 0x00000914, 894 0x00000914, 0xff010914, 0xff010a15, 0xff010a16, 895 0xff010a17, 0xff010b16, 0xff010b16, 0xff020c16, 896 0xff020c16, 0xff020c16, 0xff020d16, 0xff020d17, 897 0xff030d17, 0xff030e17, 0xff030e17, 0xff030f17, 898 0xff040f17, 0xff040f17, 0xff041017, 0xff051017, 899 900 0x00000610, 0x00000610, 0x00000611, 0x00000611, 901 0x00000711, 0x00000712, 0x00010712, 0x00010812, 902 0x00010812, 0x00010812, 0x00010913, 0x00010913, 903 0x00010913, 0x00010a13, 0x00020a13, 0x00020a14, 904 0x00020b14, 0x00020b14, 0x00020b14, 0x00020c14, 905 0x00030c14, 0x00030c15, 0x00030d15, 0x00030d15, 906 0x00040d15, 0x00040e15, 0x00040e15, 0x00040e16, 907 0x00050f15, 0x00050f15, 0x00050f16, 0x00051015, 908 909 0x00000611, 0x00010610, 0x00010710, 0x00010710, 910 0x00010711, 0x00010811, 0x00010811, 0x00010812, 911 0x00010812, 0x00010912, 0x00020912, 0x00020912, 912 0x00020a12, 0x00020a12, 0x00020a13, 0x00020a13, 913 0x00030b13, 0x00030b13, 0x00030b14, 0x00030c13, 914 0x00030c13, 0x00040c13, 0x00040d14, 0x00040d14, 915 0x00040d15, 0x00040d15, 0x00050e14, 0x00050e14, 916 0x00050e15, 0x00050f14, 0x00060f14, 0x00060f14, 917 918 0x0001070f, 0x0001070f, 0x00010710, 0x00010710, 919 0x00010810, 0x00010810, 0x00020810, 0x00020811, 920 0x00020911, 0x00020911, 0x00020912, 0x00020912, 921 0x00020a12, 0x00030a12, 0x00030a12, 0x00030b12, 922 0x00030b12, 0x00030b12, 0x00040b12, 0x00040c12, 923 0x00040c13, 0x00040c14, 0x00040c14, 0x00050d13, 924 0x00050d13, 0x00050d14, 0x00050e13, 0x01050e13, 925 0x01060e13, 0x01060e13, 0x01060e14, 0x01060f13 926 }; 927 928 static const uint32_t lan2coefftab32[512] = { 929 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb, 930 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc, 931 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 932 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100, 933 934 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb, 935 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc, 936 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 937 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100, 938 939 0xff053804, 0xff063803, 0xff083801, 0xff093701, 0xff0a3700, 0xff0c3500, 0xff0e34ff, 0xff1033fe, 940 0xff1232fd, 0xfe1431fd, 0xfe162ffd, 0xfe182dfd, 0xfd1b2cfc, 0xfd1d2afc, 0xfd1f28fc, 0xfd2126fc, 941 0xfd2323fd, 0xfc2621fd, 0xfc281ffd, 0xfc2a1dfd, 0xfc2c1bfd, 0xfd2d18fe, 0xfd2f16fe, 0xfd3114fe, 942 0xfd3212ff, 0xfe3310ff, 0xff340eff, 0x00350cff, 0x00360a00, 0x01360900, 0x02370700, 0x03370600, 943 944 0xff083207, 0xff093206, 0xff0a3205, 0xff0c3203, 0xff0d3103, 0xff0e3102, 0xfe113001, 0xfe132f00, 945 0xfe142e00, 0xfe162dff, 0xfe182bff, 0xfe192aff, 0xfe1b29fe, 0xfe1d27fe, 0xfe1f25fe, 0xfd2124fe, 946 0xfe2222fe, 0xfe2421fd, 0xfe251ffe, 0xfe271dfe, 0xfe291bfe, 0xff2a19fe, 0xff2b18fe, 0xff2d16fe, 947 0x002e14fe, 0x002f12ff, 0x013010ff, 0x02300fff, 0x03310dff, 0x04310cff, 0x05310a00, 0x06310900, 948 949 0xff0a2e09, 0xff0b2e08, 0xff0c2e07, 0xff0e2d06, 0xff0f2d05, 0xff102d04, 0xff122c03, 0xfe142c02, 950 0xfe152b02, 0xfe172a01, 0xfe182901, 0xfe1a2800, 0xfe1b2700, 0xfe1d2500, 0xff1e24ff, 0xfe2023ff, 951 0xff2121ff, 0xff2320fe, 0xff241eff, 0x00251dfe, 0x00261bff, 0x00281afe, 0x012818ff, 0x012a16ff, 952 0x022a15ff, 0x032b13ff, 0x032c12ff, 0x052c10ff, 0x052d0fff, 0x062d0d00, 0x072d0c00, 0x082d0b00, 953 954 0xff0c2a0b, 0xff0d2a0a, 0xff0e2a09, 0xff0f2a08, 0xff102a07, 0xff112a06, 0xff132905, 0xff142904, 955 0xff162803, 0xff172703, 0xff182702, 0xff1a2601, 0xff1b2501, 0xff1c2401, 0xff1e2300, 0xff1f2200, 956 0x00202000, 0x00211f00, 0x01221d00, 0x01231c00, 0x01251bff, 0x02251aff, 0x032618ff, 0x032717ff, 957 0x042815ff, 0x052814ff, 0x052913ff, 0x06291100, 0x072a10ff, 0x082a0e00, 0x092a0d00, 0x0a2a0c00, 958 959 0xff0d280c, 0xff0e280b, 0xff0f280a, 0xff102809, 0xff112808, 0xff122708, 0xff142706, 0xff152705, 960 0xff162605, 0xff172604, 0xff192503, 0xff1a2403, 0x001b2302, 0x001c2202, 0x001d2201, 0x001e2101, 961 0x011f1f01, 0x01211e00, 0x01221d00, 0x02221c00, 0x02231b00, 0x03241900, 0x04241800, 0x04251700, 962 0x052616ff, 0x06261400, 0x072713ff, 0x08271100, 0x08271100, 0x09271000, 0x0a280e00, 0x0b280d00, 963 964 0xff0e260d, 0xff0f260c, 0xff10260b, 0xff11260a, 0xff122609, 0xff132608, 0xff142508, 0xff152507, 965 0x00152506, 0x00172405, 0x00182305, 0x00192304, 0x001b2203, 0x001c2103, 0x011d2002, 0x011d2002, 966 0x011f1f01, 0x021f1e01, 0x02201d01, 0x03211c00, 0x03221b00, 0x04221a00, 0x04231801, 0x05241700, 967 0x06241600, 0x07241500, 0x08251300, 0x09251200, 0x09261100, 0x0a261000, 0x0b260f00, 0x0c260e00, 968 969 0xff0e250e, 0xff0f250d, 0xff10250c, 0xff11250b, 0x0011250a, 0x00132409, 0x00142408, 0x00152407, 970 0x00162307, 0x00172306, 0x00182206, 0x00192205, 0x011a2104, 0x011b2004, 0x011c2003, 0x021c1f03, 971 0x021e1e02, 0x031e1d02, 0x03201c01, 0x04201b01, 0x04211a01, 0x05221900, 0x05221801, 0x06231700, 972 0x07231600, 0x07241500, 0x08241400, 0x09241300, 0x0a241200, 0x0b241100, 0x0c241000, 0x0d240f00, 973 974 0x000e240e, 0x000f240d, 0x0010240c, 0x0011240b, 0x0013230a, 0x0013230a, 0x00142309, 0x00152308, 975 0x00162208, 0x00172207, 0x01182106, 0x01192105, 0x011a2005, 0x021b1f04, 0x021b1f04, 0x021d1e03, 976 0x031d1d03, 0x031e1d02, 0x041e1c02, 0x041f1b02, 0x05201a01, 0x05211901, 0x06211801, 0x07221700, 977 0x07221601, 0x08231500, 0x09231400, 0x0a231300, 0x0a231300, 0x0b231200, 0x0c231100, 0x0d231000, 978 979 0x000f220f, 0x0010220e, 0x0011220d, 0x0012220c, 0x0013220b, 0x0013220b, 0x0015210a, 0x0015210a, 980 0x01162108, 0x01172008, 0x01182007, 0x02191f06, 0x02191f06, 0x021a1e06, 0x031a1e05, 0x031c1d04, 981 0x041c1c04, 0x041d1c03, 0x051d1b03, 0x051e1a03, 0x061f1902, 0x061f1902, 0x07201801, 0x08201701, 982 0x08211601, 0x09211501, 0x0a211500, 0x0b211400, 0x0b221300, 0x0c221200, 0x0d221100, 0x0e221000, 983 984 0x0010210f, 0x0011210e, 0x0011210e, 0x0012210d, 0x0013210c, 0x0014200c, 0x0114200b, 0x0115200a, 985 0x01161f0a, 0x01171f09, 0x02171f08, 0x02181e08, 0x03181e07, 0x031a1d06, 0x031a1d06, 0x041b1c05, 986 0x041c1c04, 0x051c1b04, 0x051d1a04, 0x061d1a03, 0x071d1903, 0x071e1803, 0x081e1802, 0x081f1702, 987 0x091f1602, 0x0a201501, 0x0b1f1501, 0x0b201401, 0x0c211300, 0x0d211200, 0x0e201200, 0x0e211100, 988 989 0x00102010, 0x0011200f, 0x0012200e, 0x0013200d, 0x0013200d, 0x01141f0c, 0x01151f0b, 0x01151f0b, 990 0x01161f0a, 0x02171e09, 0x02171e09, 0x03181d08, 0x03191d07, 0x03191d07, 0x041a1c06, 0x041b1c05, 991 0x051b1b05, 0x051c1b04, 0x061c1a04, 0x071d1903, 0x071d1903, 0x081d1803, 0x081e1703, 0x091e1702, 992 0x0a1f1601, 0x0a1f1502, 0x0b1f1501, 0x0c1f1401, 0x0d201300, 0x0d201300, 0x0e201200, 0x0f201100, 993 994 0x00102010, 0x0011200f, 0x00121f0f, 0x00131f0e, 0x00141f0d, 0x01141f0c, 0x01141f0c, 0x01151e0c, 995 0x02161e0a, 0x02171e09, 0x03171d09, 0x03181d08, 0x03181d08, 0x04191c07, 0x041a1c06, 0x051a1b06, 996 0x051b1b05, 0x061b1a05, 0x061c1a04, 0x071c1904, 0x081c1903, 0x081d1803, 0x091d1703, 0x091e1702, 997 0x0a1e1602, 0x0b1e1502, 0x0c1e1501, 0x0c1f1401, 0x0d1f1400, 0x0e1f1300, 0x0e1f1201, 0x0f1f1200, 998 999 0x00111e11, 0x00121e10, 0x00131e0f, 0x00131e0f, 0x01131e0e, 0x01141d0e, 0x02151d0c, 0x02151d0c, 1000 0x02161d0b, 0x03161c0b, 0x03171c0a, 0x04171c09, 0x04181b09, 0x05181b08, 0x05191b07, 0x06191a07, 1001 0x061a1a06, 0x071a1906, 0x071b1905, 0x081b1805, 0x091b1804, 0x091c1704, 0x0a1c1703, 0x0a1c1604, 1002 0x0b1d1602, 0x0c1d1502, 0x0c1d1502, 0x0d1d1402, 0x0e1d1401, 0x0e1e1301, 0x0f1e1300, 0x101e1200, 1003 1004 0x00111e11, 0x00121e10, 0x00131d10, 0x01131d0f, 0x01141d0e, 0x01141d0e, 0x02151c0d, 0x02151c0d, 1005 0x03161c0b, 0x03161c0b, 0x04171b0a, 0x04171b0a, 0x05171b09, 0x05181a09, 0x06181a08, 0x06191a07, 1006 0x07191907, 0x071a1906, 0x081a1806, 0x081a1806, 0x091a1805, 0x0a1b1704, 0x0a1b1704, 0x0b1c1603, 1007 0x0b1c1603, 0x0c1c1503, 0x0d1c1502, 0x0d1d1402, 0x0e1d1401, 0x0f1d1301, 0x0f1d1301, 0x101e1200, 1008 }; 1009 1010 static void 1011 sunxi_mixer_vsu_init(struct sunxi_mixer_softc *sc, u_int src_w, u_int src_h, 1012 u_int crtc_w, u_int crtc_h, uint32_t pixel_format) 1013 { 1014 const u_int hstep = (src_w << 16) / crtc_w; 1015 const u_int vstep = (src_h << 16) / crtc_h; 1016 1017 const int hsub = drm_format_horz_chroma_subsampling(pixel_format); 1018 const int vsub = drm_format_vert_chroma_subsampling(pixel_format); 1019 1020 const u_int src_cw = src_w / hsub; 1021 const u_int src_ch = src_h / vsub; 1022 1023 VSU_WRITE(sc, VS_OUT_SIZE_REG, ((crtc_h - 1) << 16) | (crtc_w - 1)); 1024 VSU_WRITE(sc, VS_Y_SIZE_REG, ((src_h - 1) << 16) | (src_w - 1)); 1025 VSU_WRITE(sc, VS_Y_HSTEP_REG, hstep << 4); 1026 VSU_WRITE(sc, VS_Y_VSTEP_REG, vstep << 4); 1027 VSU_WRITE(sc, VS_Y_HPHASE_REG, 0); 1028 VSU_WRITE(sc, VS_Y_VPHASE0_REG, 0); 1029 VSU_WRITE(sc, VS_Y_VPHASE1_REG, 0); 1030 VSU_WRITE(sc, VS_C_SIZE_REG, ((src_ch - 1) << 16) | (src_cw - 1)); 1031 VSU_WRITE(sc, VS_C_HSTEP_REG, (hstep / hsub) << 4); 1032 VSU_WRITE(sc, VS_C_VSTEP_REG, (vstep / vsub) << 4); 1033 VSU_WRITE(sc, VS_C_HPHASE_REG, 0); 1034 VSU_WRITE(sc, VS_C_VPHASE0_REG, 0); 1035 VSU_WRITE(sc, VS_C_VPHASE1_REG, 0); 1036 1037 /* XXX */ 1038 const u_int coef_base = 0; 1039 1040 for (int i = 0; i < 32; i++) { 1041 VSU_WRITE(sc, VS_Y_HCOEF0_REG(i), lan3coefftab32_left[coef_base + i]); 1042 VSU_WRITE(sc, VS_Y_HCOEF1_REG(i), lan3coefftab32_right[coef_base + i]); 1043 VSU_WRITE(sc, VS_Y_VCOEF_REG(i), lan2coefftab32[coef_base + i]); 1044 VSU_WRITE(sc, VS_C_HCOEF0_REG(i), lan3coefftab32_left[coef_base + i]); 1045 VSU_WRITE(sc, VS_C_HCOEF1_REG(i), lan3coefftab32_right[coef_base + i]); 1046 VSU_WRITE(sc, VS_C_VCOEF_REG(i), lan2coefftab32[coef_base + i]); 1047 } 1048 1049 /* Commit settings and enable scaler */ 1050 VSU_WRITE(sc, VS_CTRL_REG, VS_CTRL_COEF_SWITCH_EN | VS_CTRL_EN); 1051 } 1052 1053 static const u32 yuv2rgb[] = { 1054 0x000004A8, 0x00000000, 0x00000662, 0xFFFC865A, 1055 0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021FF4, 1056 0x000004A8, 0x00000813, 0x00000000, 0xFFFBAE4A, 1057 }; 1058 1059 static void 1060 sunxi_mixer_csc_init(struct sunxi_mixer_softc *sc, uint32_t pixel_format) 1061 { 1062 const u_int crtc_index = drm_crtc_index(&sc->sc_crtc.base); 1063 1064 for (int i = 0; i < __arraycount(yuv2rgb); i++) 1065 CSC_WRITE(sc, crtc_index, CSC_COEFF0_REG(0) + i * 4, yuv2rgb[i]); 1066 1067 CSC_WRITE(sc, crtc_index, CSC_BYPASS_REG, CSC_BYPASS_DISABLE); 1068 } 1069 1070 static void 1071 sunxi_mixer_csc_disable(struct sunxi_mixer_softc *sc) 1072 { 1073 const u_int crtc_index = drm_crtc_index(&sc->sc_crtc.base); 1074 1075 CSC_WRITE(sc, crtc_index, CSC_BYPASS_REG, 0); 1076 } 1077 1078 static int 1079 sunxi_mixer_overlay_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 1080 struct drm_framebuffer *fb, int crtc_x, int crtc_y, u_int crtc_w, u_int crtc_h, 1081 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) 1082 { 1083 struct sunxi_mixer_plane *overlay = to_sunxi_mixer_plane(plane); 1084 struct sunxi_mixer_softc * const sc = overlay->sc; 1085 struct sunxi_drm_framebuffer *sfb = to_sunxi_drm_framebuffer(fb); 1086 uint32_t val; 1087 1088 const u_int fbfmt = sunxi_mixer_overlay_format(fb->pixel_format); 1089 const uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; 1090 1091 const uint32_t input_size = (((src_h >> 16) - 1) << 16) | ((src_w >> 16) - 1); 1092 const uint32_t input_pos = ((src_y >> 16) << 16) | (src_x >> 16); 1093 1094 OVL_V_WRITE(sc, OVL_V_MBSIZE(0), input_size); 1095 OVL_V_WRITE(sc, OVL_V_COOR(0), input_pos); 1096 1097 /* Note: DRM and hardware's ideas of pitch 1 and 2 are swapped */ 1098 1099 OVL_V_WRITE(sc, OVL_V_PITCH0(0), fb->pitches[0]); 1100 OVL_V_WRITE(sc, OVL_V_PITCH1(0), fb->pitches[2]); 1101 OVL_V_WRITE(sc, OVL_V_PITCH2(0), fb->pitches[1]); 1102 1103 const uint64_t paddr0 = paddr + fb->offsets[0] + 1104 (src_x >> 16) * drm_format_plane_cpp(fb->pixel_format, 0) + 1105 (src_y >> 16) * fb->pitches[0]; 1106 const uint64_t paddr1 = paddr + fb->offsets[2] + 1107 (src_x >> 16) * drm_format_plane_cpp(fb->pixel_format, 2) + 1108 (src_y >> 16) * fb->pitches[2]; 1109 const uint64_t paddr2 = paddr + fb->offsets[1] + 1110 (src_x >> 16) * drm_format_plane_cpp(fb->pixel_format, 1) + 1111 (src_y >> 16) * fb->pitches[1]; 1112 1113 OVL_V_WRITE(sc, OVL_V_TOP_HADD0, (paddr0 >> 32) & OVL_V_TOP_HADD_LAYER0); 1114 OVL_V_WRITE(sc, OVL_V_TOP_HADD1, (paddr1 >> 32) & OVL_V_TOP_HADD_LAYER0); 1115 OVL_V_WRITE(sc, OVL_V_TOP_HADD2, (paddr2 >> 32) & OVL_V_TOP_HADD_LAYER0); 1116 1117 OVL_V_WRITE(sc, OVL_V_TOP_LADD0(0), paddr0 & 0xffffffff); 1118 OVL_V_WRITE(sc, OVL_V_TOP_LADD1(0), paddr1 & 0xffffffff); 1119 OVL_V_WRITE(sc, OVL_V_TOP_LADD2(0), paddr2 & 0xffffffff); 1120 1121 OVL_V_WRITE(sc, OVL_V_SIZE, input_size); 1122 1123 val = OVL_V_ATTCTL_LAY0_EN; 1124 val |= __SHIFTIN(fbfmt, OVL_V_ATTCTL_LAY_FBFMT); 1125 if (sunxi_mixer_overlay_rgb(fb->pixel_format) == true) 1126 val |= OVL_V_ATTCTL_VIDEO_UI_SEL; 1127 OVL_V_WRITE(sc, OVL_V_ATTCTL(0), val); 1128 1129 /* Enable video scaler */ 1130 sunxi_mixer_vsu_init(sc, src_w >> 16, src_h >> 16, crtc_w, crtc_h, fb->pixel_format); 1131 1132 /* Enable colour space conversion for non-RGB formats */ 1133 if (sunxi_mixer_overlay_rgb(fb->pixel_format) == false) 1134 sunxi_mixer_csc_init(sc, fb->pixel_format); 1135 else 1136 sunxi_mixer_csc_disable(sc); 1137 1138 /* Set blender 1 input size */ 1139 BLD_WRITE(sc, BLD_CH_ISIZE(1), ((crtc_h - 1) << 16) | (crtc_w - 1)); 1140 /* Set blender 1 offset */ 1141 BLD_WRITE(sc, BLD_CH_OFFSET(1), (crtc_y << 16) | crtc_x); 1142 /* Route channel 0 to pipe 1 */ 1143 val = BLD_READ(sc, BLD_CH_RTCTL); 1144 val &= ~BLD_CH_RTCTL_P1; 1145 val |= __SHIFTIN(0, BLD_CH_RTCTL_P1); 1146 BLD_WRITE(sc, BLD_CH_RTCTL, val); 1147 1148 /* Enable pipe 1 */ 1149 val = BLD_READ(sc, BLD_FILL_COLOR_CTL); 1150 val |= BLD_FILL_COLOR_CTL_P1_EN; 1151 BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val); 1152 1153 /* Commit settings */ 1154 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 1155 1156 return 0; 1157 } 1158 1159 static int 1160 sunxi_mixer_overlay_disable_plane(struct drm_plane *plane) 1161 { 1162 struct sunxi_mixer_plane *overlay = to_sunxi_mixer_plane(plane); 1163 struct sunxi_mixer_softc * const sc = overlay->sc; 1164 uint32_t val; 1165 1166 sunxi_mixer_csc_disable(sc); 1167 1168 val = BLD_READ(sc, BLD_FILL_COLOR_CTL); 1169 val &= ~BLD_FILL_COLOR_CTL_P1_EN; 1170 BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val); 1171 1172 /* Commit settings */ 1173 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY); 1174 1175 return 0; 1176 } 1177 1178 static const struct drm_plane_funcs sunxi_mixer_overlay_funcs = { 1179 .update_plane = sunxi_mixer_overlay_update_plane, 1180 .disable_plane = sunxi_mixer_overlay_disable_plane, 1181 .destroy = sunxi_mixer_overlay_destroy, 1182 }; 1183 1184 static uint32_t sunxi_mixer_overlay_formats[] = { 1185 DRM_FORMAT_ARGB8888, 1186 DRM_FORMAT_XRGB8888, 1187 #if notyet 1188 DRM_FORMAT_VYUY, 1189 DRM_FORMAT_YVYU, 1190 DRM_FORMAT_UYVY, 1191 DRM_FORMAT_YUYV, 1192 #endif 1193 DRM_FORMAT_YUV422, 1194 DRM_FORMAT_YUV420, 1195 DRM_FORMAT_YUV411, 1196 }; 1197 1198 static int 1199 sunxi_mixer_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate) 1200 { 1201 struct sunxi_mixer_softc * const sc = device_private(dev); 1202 struct drm_device *ddev; 1203 bus_size_t reg; 1204 1205 if (!activate) 1206 return EINVAL; 1207 1208 ddev = sunxi_drm_endpoint_device(ep); 1209 if (ddev == NULL) { 1210 DRM_ERROR("couldn't find DRM device\n"); 1211 return ENXIO; 1212 } 1213 1214 sc->sc_crtc.sc = sc; 1215 sc->sc_overlay.sc = sc; 1216 1217 /* Initialize registers */ 1218 for (reg = 0; reg < 0xc000; reg += 4) 1219 bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, 0); 1220 BLD_WRITE(sc, BLD_CTL(0), 0x03010301); 1221 BLD_WRITE(sc, BLD_CTL(1), 0x03010301); 1222 BLD_WRITE(sc, BLD_CTL(2), 0x03010301); 1223 BLD_WRITE(sc, BLD_CTL(3), 0x03010301); 1224 1225 if (sc->sc_ovl_ui_count > 1) 1226 drm_crtc_init(ddev, &sc->sc_crtc.base, &sunxi_mixer0_crtc_funcs); 1227 else 1228 drm_crtc_init(ddev, &sc->sc_crtc.base, &sunxi_mixer1_crtc_funcs); 1229 drm_crtc_helper_add(&sc->sc_crtc.base, &sunxi_mixer_crtc_helper_funcs); 1230 1231 drm_universal_plane_init(ddev, &sc->sc_overlay.base, 1232 1 << drm_crtc_index(&sc->sc_crtc.base), &sunxi_mixer_overlay_funcs, 1233 sunxi_mixer_overlay_formats, __arraycount(sunxi_mixer_overlay_formats), 1234 DRM_PLANE_TYPE_OVERLAY); 1235 1236 return fdt_endpoint_activate(ep, activate); 1237 } 1238 1239 static void * 1240 sunxi_mixer_ep_get_data(device_t dev, struct fdt_endpoint *ep) 1241 { 1242 struct sunxi_mixer_softc * const sc = device_private(dev); 1243 1244 return &sc->sc_crtc; 1245 } 1246 1247 static int 1248 sunxi_mixer_match(device_t parent, cfdata_t cf, void *aux) 1249 { 1250 struct fdt_attach_args * const faa = aux; 1251 1252 return of_compatible_match(faa->faa_phandle, compat_data); 1253 } 1254 1255 static void 1256 sunxi_mixer_attach(device_t parent, device_t self, void *aux) 1257 { 1258 struct sunxi_mixer_softc * const sc = device_private(self); 1259 struct fdt_attach_args * const faa = aux; 1260 struct fdt_endpoint *out_ep; 1261 const int phandle = faa->faa_phandle; 1262 const struct sunxi_mixer_compat_data * const cd = 1263 of_compatible_lookup(phandle, compat_data)->data; 1264 struct clk *clk_bus, *clk_mod; 1265 struct fdtbus_reset *rst; 1266 bus_addr_t addr; 1267 bus_size_t size; 1268 1269 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 1270 aprint_error(": couldn't get registers\n"); 1271 return; 1272 } 1273 1274 rst = fdtbus_reset_get_index(phandle, 0); 1275 if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { 1276 aprint_error(": couldn't de-assert reset\n"); 1277 return; 1278 } 1279 1280 clk_bus = fdtbus_clock_get(phandle, "bus"); 1281 if (clk_bus == NULL || clk_enable(clk_bus) != 0) { 1282 aprint_error(": couldn't enable bus clock\n"); 1283 return; 1284 } 1285 1286 clk_mod = fdtbus_clock_get(phandle, "mod"); 1287 if (clk_mod == NULL || 1288 clk_set_rate(clk_mod, SUNXI_MIXER_FREQ) != 0 || 1289 clk_enable(clk_mod) != 0) { 1290 aprint_error(": couldn't enable mod clock\n"); 1291 return; 1292 } 1293 1294 sc->sc_dev = self; 1295 sc->sc_bst = faa->faa_bst; 1296 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 1297 aprint_error(": couldn't map registers\n"); 1298 return; 1299 } 1300 sc->sc_phandle = faa->faa_phandle; 1301 sc->sc_ovl_ui_count = cd->ovl_ui_count; 1302 1303 aprint_naive("\n"); 1304 aprint_normal(": Display Engine Mixer\n"); 1305 1306 sc->sc_ports.dp_ep_activate = sunxi_mixer_ep_activate; 1307 sc->sc_ports.dp_ep_get_data = sunxi_mixer_ep_get_data; 1308 fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_CRTC); 1309 1310 out_ep = fdt_endpoint_get_from_index(&sc->sc_ports, 1311 MIXER_PORT_OUTPUT, cd->mixer_index); 1312 if (out_ep == NULL) { 1313 /* Couldn't find new-style DE2 endpoint, try old style. */ 1314 out_ep = fdt_endpoint_get_from_index(&sc->sc_ports, 1315 MIXER_PORT_OUTPUT, 0); 1316 } 1317 1318 if (out_ep != NULL) 1319 sunxi_drm_register_endpoint(phandle, out_ep); 1320 } 1321 1322 CFATTACH_DECL_NEW(sunxi_mixer, sizeof(struct sunxi_mixer_softc), 1323 sunxi_mixer_match, sunxi_mixer_attach, NULL, NULL); 1324