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

Commit ab0af559 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50/kms: move framebuffer wrangling out of common code



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 7820e5ee
Loading
Loading
Loading
Loading
+12 −47
Original line number Diff line number Diff line
@@ -200,6 +200,10 @@ static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
{
	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
	struct nouveau_display *disp = nouveau_display(drm_fb->dev);

	if (disp->fb_dtor)
		disp->fb_dtor(drm_fb);

	if (fb->nvbo)
		drm_gem_object_unreference_unlocked(&fb->nvbo->gem);
@@ -229,63 +233,24 @@ nouveau_framebuffer_init(struct drm_device *dev,
			 struct drm_mode_fb_cmd2 *mode_cmd,
			 struct nouveau_bo *nvbo)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_display *disp = nouveau_display(dev);
	struct drm_framebuffer *fb = &nv_fb->base;
	int ret;

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

	if (nv_device(drm->device)->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 = 0x1e00; break;
		case 15: nv_fb->r_format = 0xe900; break;
		case 16: nv_fb->r_format = 0xe800; break;
		case 24:
		case 32: nv_fb->r_format = 0xcf00; break;
		case 30: nv_fb->r_format = 0xd100; break;
		default:
			 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
			 return -EINVAL;
		}

		if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
			NV_ERROR(drm, "framebuffer requires contiguous bo\n");
			return -EINVAL;
		}

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

		if (!tile_flags) {
			if (nv_device(drm->device)->card_type < NV_D0)
				nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
			else
				nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
		} else {
			u32 mode = nvbo->tile_mode;
			if (nv_device(drm->device)->card_type >= NV_C0)
				mode >>= 4;
			nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
		}
	}

	ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
	if (ret) {
	if (ret)
		return ret;

	if (disp->fb_ctor) {
		ret = disp->fb_ctor(fb);
		if (ret)
			disp->fb_dtor(fb);
	}

	return 0;
	return ret;
}

static struct drm_framebuffer *
+4 −0
Original line number Diff line number Diff line
@@ -36,9 +36,13 @@ struct nouveau_display {
	int  (*init)(struct drm_device *);
	void (*fini)(struct drm_device *);

	int  (*fb_ctor)(struct drm_framebuffer *);
	void (*fb_dtor)(struct drm_framebuffer *);

	struct nouveau_object *core;
	struct nouveau_eventh **vblank;


	struct drm_property *dithering_mode;
	struct drm_property *dithering_depth;
	struct drm_property *underscan_property;
+65 −0
Original line number Diff line number Diff line
@@ -2168,9 +2168,72 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
	return 0;
}

/******************************************************************************
 * Framebuffer
 *****************************************************************************/

static void
nv50_fb_dtor(struct drm_framebuffer *fb)
{
}

static int
nv50_fb_ctor(struct drm_framebuffer *fb)
{
	struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
	struct nouveau_drm *drm = nouveau_drm(fb->dev);
	struct nouveau_bo *nvbo = nv_fb->nvbo;
	u32 tile_flags;

	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;

	if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
		NV_ERROR(drm, "framebuffer requires contiguous bo\n");
		return -EINVAL;
	}

	switch (fb->depth) {
	case  8: nv_fb->r_format = 0x1e00; break;
	case 15: nv_fb->r_format = 0xe900; break;
	case 16: nv_fb->r_format = 0xe800; break;
	case 24:
	case 32: nv_fb->r_format = 0xcf00; break;
	case 30: nv_fb->r_format = 0xd100; break;
	default:
		 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
		 return -EINVAL;
	}

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

	if (!tile_flags) {
		if (nv_device(drm->device)->card_type < NV_D0)
			nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
		else
			nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
	} else {
		u32 mode = nvbo->tile_mode;
		if (nv_device(drm->device)->card_type >= NV_C0)
			mode >>= 4;
		nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
	}

	return 0;
}

/******************************************************************************
 * Init
 *****************************************************************************/

void
nv50_display_fini(struct drm_device *dev)
{
@@ -2233,6 +2296,8 @@ nv50_display_create(struct drm_device *dev)
	nouveau_display(dev)->dtor = nv50_display_destroy;
	nouveau_display(dev)->init = nv50_display_init;
	nouveau_display(dev)->fini = nv50_display_fini;
	nouveau_display(dev)->fb_ctor = nv50_fb_ctor;
	nouveau_display(dev)->fb_dtor = nv50_fb_dtor;
	disp->core = nouveau_display(dev)->core;

	/* small shared memory area we use for notifiers and semaphores */