forked from mirrors/linux
		
	drm/nouveau/kms: Add format mod prop to base/ovly/nvdisp
Advertise support for the full list of format modifiers supported by each class of NVIDIA desktop GPU display hardware. Stash the array of modifiers in the nouveau_display struct for use when validating userspace framebuffer creation requests, which will be supportd in a subsequent change. Signed-off-by: James Jones <jajones@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
		
							parent
							
								
									fd44028ff1
								
							
						
					
					
						commit
						c586f30bf7
					
				
					 6 changed files with 112 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -263,7 +263,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
 | 
			
		|||
	struct nv50_disp_base_channel_dma_v0 args = {
 | 
			
		||||
		.head = head,
 | 
			
		||||
	};
 | 
			
		||||
	struct nv50_disp *disp = nv50_disp(drm->dev);
 | 
			
		||||
	struct nouveau_display *disp = nouveau_display(drm->dev);
 | 
			
		||||
	struct nv50_disp *disp50 = nv50_disp(drm->dev);
 | 
			
		||||
	struct nv50_wndw *wndw;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -273,9 +274,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
 | 
			
		|||
	if (*pwndw = wndw, ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
 | 
			
		||||
	ret = nv50_dmac_create(&drm->client.device, &disp->disp.object,
 | 
			
		||||
			       &oclass, head, &args, sizeof(args),
 | 
			
		||||
			       disp->sync->bo.offset, &wndw->wndw);
 | 
			
		||||
			       disp50->sync->bo.offset, &wndw->wndw);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret);
 | 
			
		||||
		return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2456,6 +2456,15 @@ nv50_display_create(struct drm_device *dev)
 | 
			
		|||
	if (ret)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	/* Assign the correct format modifiers */
 | 
			
		||||
	if (disp->disp->object.oclass >= TU102_DISP)
 | 
			
		||||
		nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
 | 
			
		||||
	else
 | 
			
		||||
	if (disp->disp->object.oclass >= GF110_DISP)
 | 
			
		||||
		nouveau_display(dev)->format_modifiers = disp90xx_modifiers;
 | 
			
		||||
	else
 | 
			
		||||
		nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
 | 
			
		||||
 | 
			
		||||
	/* create crtc objects to represent the hw heads */
 | 
			
		||||
	if (disp->disp->object.oclass >= GV100_DISP)
 | 
			
		||||
		crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
 | 
			
		||||
| 
						 | 
				
			
			@ -2551,3 +2560,53 @@ nv50_display_create(struct drm_device *dev)
 | 
			
		|||
		nv50_display_destroy(dev);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Format modifiers
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/****************************************************************
 | 
			
		||||
 *            Log2(block height) ----------------------------+  *
 | 
			
		||||
 *            Page Kind ----------------------------------+  |  *
 | 
			
		||||
 *            Gob Height/Page Kind Generation ------+     |  |  *
 | 
			
		||||
 *                          Sector layout -------+  |     |  |  *
 | 
			
		||||
 *                          Compression ------+  |  |     |  |  */
 | 
			
		||||
const u64 disp50xx_modifiers[] = { /*         |  |  |     |  |  */
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 0),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 1),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 2),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 3),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 4),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x7a, 5),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 0),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 1),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 2),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 3),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 4),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x78, 5),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 0),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 1),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 2),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 3),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 4),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 1, 0x70, 5),
 | 
			
		||||
	DRM_FORMAT_MOD_LINEAR,
 | 
			
		||||
	DRM_FORMAT_MOD_INVALID
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/****************************************************************
 | 
			
		||||
 *            Log2(block height) ----------------------------+  *
 | 
			
		||||
 *            Page Kind ----------------------------------+  |  *
 | 
			
		||||
 *            Gob Height/Page Kind Generation ------+     |  |  *
 | 
			
		||||
 *                          Sector layout -------+  |     |  |  *
 | 
			
		||||
 *                          Compression ------+  |  |     |  |  */
 | 
			
		||||
const u64 disp90xx_modifiers[] = { /*         |  |  |     |  |  */
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 0),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 1),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 2),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 3),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 4),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 0, 0xfe, 5),
 | 
			
		||||
	DRM_FORMAT_MOD_LINEAR,
 | 
			
		||||
	DRM_FORMAT_MOD_INVALID
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,6 +78,10 @@ void nv50_dmac_destroy(struct nv50_dmac *);
 | 
			
		|||
u32 *evo_wait(struct nv50_dmac *, int nr);
 | 
			
		||||
void evo_kick(u32 *, struct nv50_dmac *);
 | 
			
		||||
 | 
			
		||||
extern const u64 disp50xx_modifiers[];
 | 
			
		||||
extern const u64 disp90xx_modifiers[];
 | 
			
		||||
extern const u64 wndwc57e_modifiers[];
 | 
			
		||||
 | 
			
		||||
#define evo_mthd(p, m, s) do {						\
 | 
			
		||||
	const u32 _m = (m), _s = (s);					\
 | 
			
		||||
	if (drm_debug_enabled(DRM_UT_KMS))				\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -609,6 +609,29 @@ nv50_wndw_destroy(struct drm_plane *plane)
 | 
			
		|||
	kfree(wndw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function assumes the format has already been validated against the plane
 | 
			
		||||
 * and the modifier was validated against the device-wides modifier list at FB
 | 
			
		||||
 * creation time.
 | 
			
		||||
 */
 | 
			
		||||
static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
 | 
			
		||||
					    u32 format, u64 modifier)
 | 
			
		||||
{
 | 
			
		||||
	struct nouveau_drm *drm = nouveau_drm(plane->dev);
 | 
			
		||||
	uint8_t i;
 | 
			
		||||
 | 
			
		||||
	if (drm->client.device.info.chipset < 0xc0) {
 | 
			
		||||
		const struct drm_format_info *info = drm_format_info(format);
 | 
			
		||||
		const uint8_t kind = (modifier >> 12) & 0xff;
 | 
			
		||||
 | 
			
		||||
		if (!format) return false;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < info->num_planes; i++)
 | 
			
		||||
			if ((info->cpp[i] != 4) && kind != 0x70) return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const struct drm_plane_funcs
 | 
			
		||||
nv50_wndw = {
 | 
			
		||||
	.update_plane = drm_atomic_helper_update_plane,
 | 
			
		||||
| 
						 | 
				
			
			@ -617,6 +640,7 @@ nv50_wndw = {
 | 
			
		|||
	.reset = nv50_wndw_reset,
 | 
			
		||||
	.atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
 | 
			
		||||
	.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
 | 
			
		||||
	.format_mod_supported = nv50_plane_format_mod_supported,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
| 
						 | 
				
			
			@ -664,7 +688,8 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
 | 
			
		|||
	for (nformat = 0; format[nformat]; nformat++);
 | 
			
		||||
 | 
			
		||||
	ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw,
 | 
			
		||||
				       format, nformat, NULL,
 | 
			
		||||
				       format, nformat,
 | 
			
		||||
				       nouveau_display(dev)->format_modifiers,
 | 
			
		||||
				       type, "%s-%d", name, index);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		kfree(*pwndw);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,6 +173,23 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
 | 
			
		|||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/****************************************************************
 | 
			
		||||
 *            Log2(block height) ----------------------------+  *
 | 
			
		||||
 *            Page Kind ----------------------------------+  |  *
 | 
			
		||||
 *            Gob Height/Page Kind Generation ------+     |  |  *
 | 
			
		||||
 *                          Sector layout -------+  |     |  |  *
 | 
			
		||||
 *                          Compression ------+  |  |     |  |  */
 | 
			
		||||
const u64 wndwc57e_modifiers[] = { /*         |  |  |     |  |  */
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
 | 
			
		||||
	DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
 | 
			
		||||
	DRM_FORMAT_MOD_LINEAR,
 | 
			
		||||
	DRM_FORMAT_MOD_INVALID
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct nv50_wndw_func
 | 
			
		||||
wndwc57e = {
 | 
			
		||||
	.acquire = wndwc37e_acquire,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,8 @@ struct nouveau_display {
 | 
			
		|||
	struct drm_property *color_vibrance_property;
 | 
			
		||||
 | 
			
		||||
	struct drm_atomic_state *suspend;
 | 
			
		||||
 | 
			
		||||
	const u64 *format_modifiers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline struct nouveau_display *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue