Commit c586f30b authored by James Jones's avatar James Jones Committed by Ben Skeggs

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: default avatarJames Jones <jajones@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent fd44028f
...@@ -263,7 +263,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, ...@@ -263,7 +263,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
struct nv50_disp_base_channel_dma_v0 args = { struct nv50_disp_base_channel_dma_v0 args = {
.head = head, .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; struct nv50_wndw *wndw;
int ret; int ret;
...@@ -273,9 +274,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, ...@@ -273,9 +274,9 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
if (*pwndw = wndw, ret) if (*pwndw = wndw, ret)
return 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), &oclass, head, &args, sizeof(args),
disp->sync->bo.offset, &wndw->wndw); disp50->sync->bo.offset, &wndw->wndw);
if (ret) { if (ret) {
NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret);
return ret; return ret;
......
...@@ -2456,6 +2456,15 @@ nv50_display_create(struct drm_device *dev) ...@@ -2456,6 +2456,15 @@ nv50_display_create(struct drm_device *dev)
if (ret) if (ret)
goto out; 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 */ /* create crtc objects to represent the hw heads */
if (disp->disp->object.oclass >= GV100_DISP) if (disp->disp->object.oclass >= GV100_DISP)
crtcs = nvif_rd32(&device->object, 0x610060) & 0xff; crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
...@@ -2551,3 +2560,53 @@ nv50_display_create(struct drm_device *dev) ...@@ -2551,3 +2560,53 @@ nv50_display_create(struct drm_device *dev)
nv50_display_destroy(dev); nv50_display_destroy(dev);
return ret; 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 *); ...@@ -78,6 +78,10 @@ void nv50_dmac_destroy(struct nv50_dmac *);
u32 *evo_wait(struct nv50_dmac *, int nr); u32 *evo_wait(struct nv50_dmac *, int nr);
void evo_kick(u32 *, struct nv50_dmac *); 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 { \ #define evo_mthd(p, m, s) do { \
const u32 _m = (m), _s = (s); \ const u32 _m = (m), _s = (s); \
if (drm_debug_enabled(DRM_UT_KMS)) \ if (drm_debug_enabled(DRM_UT_KMS)) \
......
...@@ -609,6 +609,29 @@ nv50_wndw_destroy(struct drm_plane *plane) ...@@ -609,6 +609,29 @@ nv50_wndw_destroy(struct drm_plane *plane)
kfree(wndw); 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 const struct drm_plane_funcs
nv50_wndw = { nv50_wndw = {
.update_plane = drm_atomic_helper_update_plane, .update_plane = drm_atomic_helper_update_plane,
...@@ -617,6 +640,7 @@ nv50_wndw = { ...@@ -617,6 +640,7 @@ nv50_wndw = {
.reset = nv50_wndw_reset, .reset = nv50_wndw_reset,
.atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
.atomic_destroy_state = nv50_wndw_atomic_destroy_state, .atomic_destroy_state = nv50_wndw_atomic_destroy_state,
.format_mod_supported = nv50_plane_format_mod_supported,
}; };
static int static int
...@@ -664,7 +688,8 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, ...@@ -664,7 +688,8 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
for (nformat = 0; format[nformat]; nformat++); for (nformat = 0; format[nformat]; nformat++);
ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, 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); type, "%s-%d", name, index);
if (ret) { if (ret) {
kfree(*pwndw); kfree(*pwndw);
......
...@@ -173,6 +173,23 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size) ...@@ -173,6 +173,23 @@ wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
return true; 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 static const struct nv50_wndw_func
wndwc57e = { wndwc57e = {
.acquire = wndwc37e_acquire, .acquire = wndwc37e_acquire,
......
...@@ -32,6 +32,8 @@ struct nouveau_display { ...@@ -32,6 +32,8 @@ struct nouveau_display {
struct drm_property *color_vibrance_property; struct drm_property *color_vibrance_property;
struct drm_atomic_state *suspend; struct drm_atomic_state *suspend;
const u64 *format_modifiers;
}; };
static inline struct nouveau_display * static inline struct nouveau_display *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment