diff options
author | Dave Airlie <airlied@redhat.com> | 2018-12-13 10:21:31 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-12-13 10:25:25 +1000 |
commit | 02c4fb0210dc2773e0d7f0a5a1b866986f8edc40 (patch) | |
tree | f5cc8547e48623ac26b814836d7629c37dbafe52 /drivers/gpu/drm/nouveau/dispnv50/lut.c | |
parent | Merge tag 'drm/tegra/for-4.21-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next (diff) | |
parent | drm/nouveau/ce/tu106: initial support (diff) | |
download | linux-dev-02c4fb0210dc2773e0d7f0a5a1b866986f8edc40.tar.xz linux-dev-02c4fb0210dc2773e0d7f0a5a1b866986f8edc40.zip |
Merge branch 'linux-4.21' of git://github.com/skeggsb/linux into drm-next
Mostly just initial support for Turing TU104/TU106 chipsets. Support
for TU102 is missing as I don't yet have HW, but it should be trivial
to add in later in the merge window (in theory).
It's a bit of a rough first pass that'll get improved in future
releases as a finish figuring out some of the other HW changes, but
it's good enough as it stands for modesetting and suspend/resume etc.
Acceleration bring-up is incomplete due to NVIDIA not yet having
provided FW images for me to use, though command submission and copy
engines are functional already.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7KmfcQqZcx+wh_1UKjTovp4PH_5UVMfeyxUu-M9WLZfw@mail.gmail.com
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50/lut.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv50/lut.c | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/lut.c b/drivers/gpu/drm/nouveau/dispnv50/lut.c index a6b96ae2a22f..994def4fd51a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/lut.c +++ b/drivers/gpu/drm/nouveau/dispnv50/lut.c @@ -29,45 +29,29 @@ #include <nvif/class.h> u32 -nv50_lut_load(struct nv50_lut *lut, bool legacy, int buffer, - struct drm_property_blob *blob) +nv50_lut_load(struct nv50_lut *lut, int buffer, struct drm_property_blob *blob, + void (*load)(struct drm_color_lut *, int, void __iomem *)) { - struct drm_color_lut *in = (struct drm_color_lut *)blob->data; + struct drm_color_lut *in = blob ? blob->data : NULL; void __iomem *mem = lut->mem[buffer].object.map.ptr; - const int size = blob->length / sizeof(*in); - int bits, shift, i; - u16 zero, r, g, b; - u32 addr = lut->mem[buffer].addr; - - /* This can't happen.. But it shuts the compiler up. */ - if (WARN_ON(size != 256)) - return 0; + const u32 addr = lut->mem[buffer].addr; + int i; - if (legacy) { - bits = 11; - shift = 3; - zero = 0x0000; + if (!in) { + in = kvmalloc_array(1024, sizeof(*in), GFP_KERNEL); + if (!WARN_ON(!in)) { + for (i = 0; i < 1024; i++) { + in[i].red = + in[i].green = + in[i].blue = (i << 16) >> 10; + } + load(in, 1024, mem); + kvfree(in); + } } else { - bits = 14; - shift = 0; - zero = 0x6000; - } - - for (i = 0; i < size; i++) { - r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift; - g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift; - b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift; - writew(r, mem + (i * 0x08) + 0); - writew(g, mem + (i * 0x08) + 2); - writew(b, mem + (i * 0x08) + 4); + load(in, blob->length / sizeof(*in), mem); } - /* INTERPOLATE modes require a "next" entry to interpolate with, - * so we replicate the last entry to deal with this for now. - */ - writew(r, mem + (i * 0x08) + 0); - writew(g, mem + (i * 0x08) + 2); - writew(b, mem + (i * 0x08) + 4); return addr; } |