Tue Feb 5 21:01:38 2019 UTC ()
Implement page flip API


(jmcneill)
diff -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_mixer.c

cvs diff -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_mixer.c (expand / switch to unified diff)

--- src/sys/arch/arm/sunxi/sunxi_mixer.c 2019/02/05 00:21:35 1.4
+++ src/sys/arch/arm/sunxi/sunxi_mixer.c 2019/02/05 21:01:38 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sunxi_mixer.c,v 1.4 2019/02/05 00:21:35 jmcneill Exp $ */ 1/* $NetBSD: sunxi_mixer.c,v 1.5 2019/02/05 21:01:38 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.4 2019/02/05 00:21:35 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.5 2019/02/05 21:01:38 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/intr.h> 35#include <sys/intr.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/conf.h> 38#include <sys/conf.h>
39 39
40#include <drm/drmP.h> 40#include <drm/drmP.h>
41#include <drm/drm_crtc.h> 41#include <drm/drm_crtc.h>
42#include <drm/drm_crtc_helper.h> 42#include <drm/drm_crtc_helper.h>
43#include <drm/drm_plane_helper.h> 43#include <drm/drm_plane_helper.h>
@@ -212,72 +212,97 @@ struct sunxi_mixer_softc { @@ -212,72 +212,97 @@ struct sunxi_mixer_softc {
212#define VSU_READ(sc, reg) \ 212#define VSU_READ(sc, reg) \
213 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg)) 213 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg))
214#define VSU_WRITE(sc, reg, val) \ 214#define VSU_WRITE(sc, reg, val) \
215 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg), (val)) 215 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg), (val))
216 216
217#define CSC_READ(sc, n, reg) \ 217#define CSC_READ(sc, n, reg) \
218 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg)) 218 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg))
219#define CSC_WRITE(sc, n, reg, val) \ 219#define CSC_WRITE(sc, n, reg, val) \
220 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg), (val)) 220 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg), (val))
221 221
222#define to_sunxi_mixer_crtc(x) container_of(x, struct sunxi_mixer_crtc, base) 222#define to_sunxi_mixer_crtc(x) container_of(x, struct sunxi_mixer_crtc, base)
223#define to_sunxi_mixer_overlay(x) container_of(x, struct sunxi_mixer_overlay, base) 223#define to_sunxi_mixer_overlay(x) container_of(x, struct sunxi_mixer_overlay, base)
224 224
 225static int
 226sunxi_mixer_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 227 int x, int y, int atomic)
 228{
 229 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
 230 struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
 231 struct sunxi_drm_framebuffer *sfb = atomic?
 232 to_sunxi_drm_framebuffer(fb) :
 233 to_sunxi_drm_framebuffer(crtc->primary->fb);
 234
 235 uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
 236
 237 uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0;
 238 uint32_t laddr = paddr & 0xffffffff;
 239
 240 /* Framebuffer start address */
 241 OVL_UI_WRITE(sc, OVL_UI_TOP_HADD, haddr);
 242 OVL_UI_WRITE(sc, OVL_UI_TOP_LADD(0), laddr);
 243
 244 return 0;
 245}
 246
225static void 247static void
226sunxi_mixer_destroy(struct drm_crtc *crtc) 248sunxi_mixer_destroy(struct drm_crtc *crtc)
227{ 249{
228 drm_crtc_cleanup(crtc); 250 drm_crtc_cleanup(crtc);
229} 251}
230 252
 253static int
 254sunxi_mixer_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 255 struct drm_pending_vblank_event *event, uint32_t flags)
 256{
 257 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
 258 struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
 259 unsigned long irqflags;
 260
 261 drm_crtc_wait_one_vblank(crtc);
 262
 263 sunxi_mixer_mode_do_set_base(crtc, fb, 0, 0, true);
 264
 265 /* Commit settings */
 266 GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY);
 267
 268 if (event) {
 269 spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
 270 drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), event);
 271 spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
 272 }
 273
 274 return 0;
 275}
 276
231static const struct drm_crtc_funcs sunxi_mixer_crtc_funcs = { 277static const struct drm_crtc_funcs sunxi_mixer_crtc_funcs = {
232 .set_config = drm_crtc_helper_set_config, 278 .set_config = drm_crtc_helper_set_config,
 279 .page_flip = sunxi_mixer_page_flip,
233 .destroy = sunxi_mixer_destroy, 280 .destroy = sunxi_mixer_destroy,
234}; 281};
235 282
236static void 283static void
237sunxi_mixer_dpms(struct drm_crtc *crtc, int mode) 284sunxi_mixer_dpms(struct drm_crtc *crtc, int mode)
238{ 285{
239} 286}
240 287
241static bool 288static bool
242sunxi_mixer_mode_fixup(struct drm_crtc *crtc, 289sunxi_mixer_mode_fixup(struct drm_crtc *crtc,
243 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) 290 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
244{ 291{
245 return true; 292 return true;
246} 293}
247 294
248static int 295static int
249sunxi_mixer_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, 
250 int x, int y, int atomic) 
251{ 
252 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 
253 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 
254 struct sunxi_drm_framebuffer *sfb = atomic? 
255 to_sunxi_drm_framebuffer(fb) : 
256 to_sunxi_drm_framebuffer(crtc->primary->fb); 
257 
258 uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; 
259 
260 uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0; 
261 uint32_t laddr = paddr & 0xffffffff; 
262 
263 /* Framebuffer start address */ 
264 OVL_UI_WRITE(sc, OVL_UI_TOP_HADD, haddr); 
265 OVL_UI_WRITE(sc, OVL_UI_TOP_LADD(0), laddr); 
266 
267 return 0; 
268} 
269 
270static int 
271sunxi_mixer_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 296sunxi_mixer_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
272 struct drm_display_mode *adjusted_mode, int x, int y, 297 struct drm_display_mode *adjusted_mode, int x, int y,
273 struct drm_framebuffer *old_fb) 298 struct drm_framebuffer *old_fb)
274{ 299{
275 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc); 300 struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
276 struct sunxi_mixer_softc * const sc = mixer_crtc->sc; 301 struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
277 uint32_t val; 302 uint32_t val;
278 303
279 const uint32_t size = ((adjusted_mode->vdisplay - 1) << 16) | 304 const uint32_t size = ((adjusted_mode->vdisplay - 1) << 16) |
280 (adjusted_mode->hdisplay - 1); 305 (adjusted_mode->hdisplay - 1);
281 const uint32_t offset = (y << 16) | x; 306 const uint32_t offset = (y << 16) | x;
282 307
283 /* Set global size */ 308 /* Set global size */