Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45c4e0aa authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50-nvc0: precalculate some fb state when creating them



Just a cleanup, to avoid duplicating parts of nv50_crtc.c's code in
the page flipping routines.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 292deb7a
Loading
Loading
Loading
Loading
+47 −5
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "nouveau_hw.h"
#include "nouveau_crtc.h"
#include "nouveau_dma.h"
#include "nv50_display.h"

static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
};

int
nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
			 struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo)
nouveau_framebuffer_init(struct drm_device *dev,
			 struct nouveau_framebuffer *nv_fb,
			 struct drm_mode_fb_cmd *mode_cmd,
			 struct nouveau_bo *nvbo)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_framebuffer *fb = &nv_fb->base;
	int ret;

	ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs);
	ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
	if (ret) {
		return ret;
	}

	drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd);
	nouveau_fb->nvbo = nvbo;
	drm_helper_mode_fill_fb_struct(fb, mode_cmd);
	nv_fb->nvbo = nvbo;

	if (dev_priv->card_type >= NV_50) {
		u32 tile_flags = nouveau_bo_tile_layout(nvbo);
		if (tile_flags == 0x7a00 ||
		    tile_flags == 0xfe00)
			nv_fb->r_dma = NvEvoFB32;
		else
		if (tile_flags == 0x7000)
			nv_fb->r_dma = NvEvoFB16;
		else
			nv_fb->r_dma = NvEvoVRAM_LP;

		switch (fb->depth) {
		case  8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break;
		case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break;
		case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break;
		case 24:
		case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
		case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
		default:
			 NV_ERROR(dev, "unknown depth %d\n", fb->depth);
			 return -EINVAL;
		}

		if (dev_priv->chipset == 0x50)
			nv_fb->r_format |= (tile_flags << 8);

		if (!tile_flags)
			nv_fb->r_pitch = 0x00100000 | fb->pitch;
		else {
			u32 mode = nvbo->tile_mode;
			if (dev_priv->card_type >= NV_C0)
				mode >>= 4;
			nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
		}
	}

	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@
struct nouveau_framebuffer {
	struct drm_framebuffer base;
	struct nouveau_bo *nvbo;
	u32 r_dma;
	u32 r_format;
	u32 r_pitch;
};

static inline struct nouveau_framebuffer *
+11 −50
Original line number Diff line number Diff line
@@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
	struct nouveau_channel *evo = nv50_display(dev)->master;
	struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
	int ret, format;
	int ret;

	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);

@@ -548,28 +548,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
		}
	}

	switch (drm_fb->depth) {
	case  8:
		format = NV50_EVO_CRTC_FB_DEPTH_8;
		break;
	case 15:
		format = NV50_EVO_CRTC_FB_DEPTH_15;
		break;
	case 16:
		format = NV50_EVO_CRTC_FB_DEPTH_16;
		break;
	case 24:
	case 32:
		format = NV50_EVO_CRTC_FB_DEPTH_24;
		break;
	case 30:
		format = NV50_EVO_CRTC_FB_DEPTH_30;
		break;
	default:
		 NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
		 return -EINVAL;
	}

	nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
	nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
	nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
			return ret;

		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
		if (nv_crtc->fb.tile_flags == 0x7a00 ||
		    nv_crtc->fb.tile_flags == 0xfe00)
			OUT_RING(evo, NvEvoFB32);
		else
		if (nv_crtc->fb.tile_flags == 0x7000)
			OUT_RING(evo, NvEvoFB16);
		else
			OUT_RING(evo, NvEvoVRAM_LP);
		OUT_RING  (evo, fb->r_dma);
	}

	ret = RING_SPACE(evo, 12);
@@ -597,18 +568,8 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
	OUT_RING  (evo, nv_crtc->fb.offset >> 8);
	OUT_RING  (evo, 0);
	OUT_RING  (evo, (drm_fb->height << 16) | drm_fb->width);
	if (!nv_crtc->fb.tile_flags) {
		OUT_RING(evo, drm_fb->pitch | (1 << 20));
	} else {
		u32 tile_mode = fb->nvbo->tile_mode;
		if (dev_priv->card_type >= NV_C0)
			tile_mode >>= 4;
		OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
	}
	if (dev_priv->chipset == 0x50)
		OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
	else
		OUT_RING(evo, format);
	OUT_RING  (evo, fb->r_pitch);
	OUT_RING  (evo, fb->r_format);

	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
	OUT_RING  (evo, fb->base.depth == 8 ?