Skip to content

Commit

Permalink
drm/nouveau/kms: Add format mod prop to base/ovly/nvdisp
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Jones authored and Ben Skeggs committed May 22, 2020
1 parent fd44028 commit c586f30
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 4 deletions.
7 changes: 4 additions & 3 deletions drivers/gpu/drm/nouveau/dispnv50/base507c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
59 changes: 59 additions & 0 deletions drivers/gpu/drm/nouveau/dispnv50/disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
};
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/dispnv50/disp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)) \
Expand Down
27 changes: 26 additions & 1 deletion drivers/gpu/drm/nouveau/dispnv50/wndw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down

0 comments on commit c586f30

Please sign in to comment.