X-Git-Url: http://git.monstr.eu/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fnouveau%2Fdispnv50%2Fheadc37d.c;h=4363fccdaf7328758aaf5ed332cef0d894f9a06e;hb=a5df76301caedcb60bc5db6909547391277e7950;hp=4a9a32b89f746f98a9970d26bf64906a27000fca;hpb=79ca035d2d941839f55f3b8b69f8e81c66946ed8;p=linux-2.6-microblaze.git diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c index 4a9a32b89f74..4363fccdaf73 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c @@ -23,30 +23,35 @@ #include "atom.h" #include "core.h" +#include + static void headc37d_or(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u8 depth; u32 *push; + if ((push = evo_wait(core, 2))) { /*XXX: This is a dirty hack until OR depth handling is * improved later for deep colour etc. */ switch (asyh->or.depth) { - case 6: asyh->or.depth = 5; break; - case 5: asyh->or.depth = 4; break; - case 2: asyh->or.depth = 1; break; - case 0: asyh->or.depth = 4; break; + case 6: depth = 5; break; + case 5: depth = 4; break; + case 2: depth = 1; break; + case 0: depth = 4; break; default: + depth = asyh->or.depth; WARN_ON(1); break; } evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000001 | - asyh->or.depth << 4 | + evo_data(push, depth << 4 | asyh->or.nvsync << 3 | - asyh->or.nhsync << 2); + asyh->or.nhsync << 2 | + asyh->or.crc_raster); evo_kick(push, core); } } @@ -132,20 +137,22 @@ headc37d_olut_clr(struct nv50_head *head) } } -static void +static int headc37d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x20a4 + (head->base.index * 0x400), 3); - evo_data(push, asyh->olut.output_mode << 8 | - asyh->olut.range << 4 | - asyh->olut.size); - evo_data(push, asyh->olut.offset >> 8); - evo_data(push, asyh->olut.handle); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_NVSQ(push, NVC37D, 0x20a4 + (i * 0x400), asyh->olut.output_mode << 8 | + asyh->olut.range << 4 | + asyh->olut.size, + 0x20a8 + (i * 0x400), asyh->olut.offset >> 8, + 0x20ac + (i * 0x400), asyh->olut.handle); + return 0; } static bool @@ -162,43 +169,53 @@ headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) return true; } -static void +static int headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 13))) { - evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x2008 + (head->base.index * 0x400), 2); - evo_data(push, m->interlace); - evo_data(push, m->clock * 1000); - evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); - evo_data(push, m->clock * 1000); - /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ - evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000124); - evo_kick(push, core); - } + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 13))) + return ret; + + PUSH_NVSQ(push, NVC37D, 0x2064 + (i * 0x400), m->v.active << 16 | m->h.active, + 0x2068 + (i * 0x400), m->v.synce << 16 | m->h.synce, + 0x206c + (i * 0x400), m->v.blanke << 16 | m->h.blanke, + 0x2070 + (i * 0x400), m->v.blanks << 16 | m->h.blanks, + 0x2074 + (i * 0x400), m->v.blank2e << 16 | m->v.blank2s); + PUSH_NVSQ(push, NVC37D, 0x2008 + (i * 0x400), m->interlace, + 0x200c + (i * 0x400), m->clock * 1000); + PUSH_NVSQ(push, NVC37D, 0x2028 + (i * 0x400), m->clock * 1000); + + /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ + PUSH_NVSQ(push, NVC37D, 0x2030 + (i * 0x400), 0x00000124); + return 0; } -void +int headc37d_view(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x204c + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x2058 + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_kick(push, core); - } + struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push; + const int i = head->base.index; + int ret; + + if ((ret = PUSH_WAIT(push, 4))) + return ret; + + PUSH_NVSQ(push, NVC37D, 0x204c + (i * 0x400), asyh->view.iH << 16 | asyh->view.iW); + PUSH_NVSQ(push, NVC37D, 0x2058 + (i * 0x400), asyh->view.oH << 16 | asyh->view.oW); + return 0; +} + +void +headc37d_static_wndw_map(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + int i, end; + + for (i = head->base.index * 2, end = i + 2; i < end; i++) + asyh->wndw.owned |= BIT(i); } const struct nv50_head_func @@ -216,4 +233,5 @@ headc37d = { .dither = headc37d_dither, .procamp = headc37d_procamp, .or = headc37d_or, + .static_wndw_map = headc37d_static_wndw_map, };