drm/nouveau/kms/nv50-: initial overlay support
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
88b600d421
Коммит
2ce7f38629
|
@ -40,3 +40,4 @@ nouveau-y += dispnv50/ovly.o
|
||||||
nouveau-y += dispnv50/ovly507e.o
|
nouveau-y += dispnv50/ovly507e.o
|
||||||
nouveau-y += dispnv50/ovly827e.o
|
nouveau-y += dispnv50/ovly827e.o
|
||||||
nouveau-y += dispnv50/ovly907e.o
|
nouveau-y += dispnv50/ovly907e.o
|
||||||
|
nouveau-y += dispnv50/ovly917e.o
|
||||||
|
|
|
@ -173,6 +173,7 @@ struct nv50_wndw_atom {
|
||||||
u8 mode:2;
|
u8 mode:2;
|
||||||
u8 interval:4;
|
u8 interval:4;
|
||||||
|
|
||||||
|
u8 colorspace:2;
|
||||||
u8 format;
|
u8 format;
|
||||||
u8 kind:7;
|
u8 kind:7;
|
||||||
u8 layout:1;
|
u8 layout:1;
|
||||||
|
@ -186,6 +187,15 @@ struct nv50_wndw_atom {
|
||||||
u64 offset[6];
|
u64 offset[6];
|
||||||
} image;
|
} image;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u16 sx;
|
||||||
|
u16 sy;
|
||||||
|
u16 sw;
|
||||||
|
u16 sh;
|
||||||
|
u16 dw;
|
||||||
|
u16 dh;
|
||||||
|
} scale;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u16 x;
|
u16 x;
|
||||||
u16 y;
|
u16 y;
|
||||||
|
@ -197,6 +207,7 @@ struct nv50_wndw_atom {
|
||||||
bool sema:1;
|
bool sema:1;
|
||||||
bool xlut:1;
|
bool xlut:1;
|
||||||
bool image:1;
|
bool image:1;
|
||||||
|
bool scale:1;
|
||||||
bool point:1;
|
bool point:1;
|
||||||
};
|
};
|
||||||
u8 mask;
|
u8 mask;
|
||||||
|
|
|
@ -13,10 +13,8 @@ void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||||
struct nv50_head_atom *);
|
struct nv50_head_atom *);
|
||||||
void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
void base507c_sema_clr(struct nv50_wndw *);
|
void base507c_sema_clr(struct nv50_wndw *);
|
||||||
void base507c_ntfy_reset(struct nouveau_bo *, u32);
|
|
||||||
void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
void base507c_ntfy_clr(struct nv50_wndw *);
|
void base507c_ntfy_clr(struct nv50_wndw *);
|
||||||
int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
|
|
||||||
void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
void base507c_xlut_clr(struct nv50_wndw *);
|
void base507c_xlut_clr(struct nv50_wndw *);
|
||||||
void base507c_image_clr(struct nv50_wndw *);
|
void base507c_image_clr(struct nv50_wndw *);
|
||||||
|
|
|
@ -6,7 +6,6 @@ int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *,
|
int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *,
|
||||||
int head, s32 oclass, u32 interlock_data,
|
int head, s32 oclass, u32 interlock_data,
|
||||||
struct nv50_wndw **);
|
struct nv50_wndw **);
|
||||||
extern const struct nv50_wimm_func curs507a;
|
|
||||||
|
|
||||||
int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ struct nv50_disp {
|
||||||
#define NV50_DISP_BASE_SEM0(c) NV50_DISP_WNDW_SEM0(0 + (c))
|
#define NV50_DISP_BASE_SEM0(c) NV50_DISP_WNDW_SEM0(0 + (c))
|
||||||
#define NV50_DISP_BASE_SEM1(c) NV50_DISP_WNDW_SEM1(0 + (c))
|
#define NV50_DISP_BASE_SEM1(c) NV50_DISP_WNDW_SEM1(0 + (c))
|
||||||
#define NV50_DISP_BASE_NTFY(c) NV50_DISP_WNDW_NTFY(0 + (c))
|
#define NV50_DISP_BASE_NTFY(c) NV50_DISP_WNDW_NTFY(0 + (c))
|
||||||
|
#define NV50_DISP_OVLY_SEM0(c) NV50_DISP_WNDW_SEM0(4 + (c))
|
||||||
|
#define NV50_DISP_OVLY_SEM1(c) NV50_DISP_WNDW_SEM1(4 + (c))
|
||||||
|
#define NV50_DISP_OVLY_NTFY(c) NV50_DISP_WNDW_NTFY(4 + (c))
|
||||||
struct nouveau_bo *sync;
|
struct nouveau_bo *sync;
|
||||||
|
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
|
|
|
@ -58,7 +58,6 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
|
|
||||||
if (asyh->ovly.cpp) {
|
if (asyh->ovly.cpp) {
|
||||||
switch (asyh->ovly.cpp) {
|
switch (asyh->ovly.cpp) {
|
||||||
case 8: bounds |= 0x00000500; break;
|
|
||||||
case 4: bounds |= 0x00000300; break;
|
case 4: bounds |= 0x00000300; break;
|
||||||
case 2: bounds |= 0x00000100; break;
|
case 2: bounds |= 0x00000100; break;
|
||||||
default:
|
default:
|
||||||
|
@ -66,6 +65,8 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bounds |= 0x00000001;
|
bounds |= 0x00000001;
|
||||||
|
} else {
|
||||||
|
bounds |= 0x00000100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
|
|
|
@ -82,6 +82,8 @@ head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bounds |= 0x00000001;
|
bounds |= 0x00000001;
|
||||||
|
} else {
|
||||||
|
bounds |= 0x00000100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((push = evo_wait(core, 2))) {
|
if ((push = evo_wait(core, 2))) {
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
|
|
||||||
#include <nvif/cl507b.h>
|
#include <nvif/cl507b.h>
|
||||||
|
|
||||||
static const struct nv50_wimm_func
|
|
||||||
oimm507b = {
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
|
oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
|
||||||
s32 oclass, struct nv50_wndw *wndw)
|
s32 oclass, struct nv50_wndw *wndw)
|
||||||
|
@ -52,5 +48,5 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
|
||||||
int
|
int
|
||||||
oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw)
|
oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw)
|
||||||
{
|
{
|
||||||
return oimm507b_init_(&oimm507b, drm, oclass, wndw);
|
return oimm507b_init_(&curs507a, drm, oclass, wndw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
|
||||||
int version;
|
int version;
|
||||||
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
} ovlys[] = {
|
} ovlys[] = {
|
||||||
{ GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new },
|
{ GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly917e_new },
|
||||||
{ GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new },
|
{ GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new },
|
||||||
{ GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
|
{ GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
|
||||||
{ GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
|
{ GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new },
|
||||||
|
|
|
@ -6,11 +6,25 @@ int ovly507e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
int ovly507e_new_(const struct nv50_wndw_func *, const u32 *format,
|
int ovly507e_new_(const struct nv50_wndw_func *, const u32 *format,
|
||||||
struct nouveau_drm *, int head, s32 oclass,
|
struct nouveau_drm *, int head, s32 oclass,
|
||||||
u32 interlock_data, struct nv50_wndw **);
|
u32 interlock_data, struct nv50_wndw **);
|
||||||
|
int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||||
|
struct nv50_head_atom *);
|
||||||
|
void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||||
|
struct nv50_head_atom *);
|
||||||
|
void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
|
void ovly507e_ntfy_clr(struct nv50_wndw *);
|
||||||
|
void ovly507e_image_clr(struct nv50_wndw *);
|
||||||
|
void ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
|
void ovly507e_update(struct nv50_wndw *, u32 *);
|
||||||
|
|
||||||
extern const u32 ovly827e_format[];
|
extern const u32 ovly827e_format[];
|
||||||
|
void ovly827e_ntfy_reset(struct nouveau_bo *, u32);
|
||||||
|
int ovly827e_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
|
||||||
|
|
||||||
|
extern const struct nv50_wndw_func ovly907e;
|
||||||
|
|
||||||
int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
|
int ovly917e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
|
||||||
|
|
||||||
int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **);
|
int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,17 +20,149 @@
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "ovly.h"
|
#include "ovly.h"
|
||||||
|
#include "atom.h"
|
||||||
|
|
||||||
|
#include <drm/drm_atomic_helper.h>
|
||||||
|
#include <drm/drm_plane_helper.h>
|
||||||
|
|
||||||
#include <nvif/cl507e.h>
|
#include <nvif/cl507e.h>
|
||||||
|
#include <nvif/event.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_update(struct nv50_wndw *wndw, u32 *interlock)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||||
|
evo_mthd(push, 0x0080, 1);
|
||||||
|
evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||||
|
evo_mthd(push, 0x00e0, 3);
|
||||||
|
evo_data(push, asyw->scale.sy << 16 | asyw->scale.sx);
|
||||||
|
evo_data(push, asyw->scale.sh << 16 | asyw->scale.sw);
|
||||||
|
evo_data(push, asyw->scale.dw);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_image_clr(struct nv50_wndw *wndw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 4))) {
|
||||||
|
evo_mthd(push, 0x0084, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_mthd(push, 0x00c0, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 12))) {
|
||||||
|
evo_mthd(push, 0x0084, 1);
|
||||||
|
evo_data(push, asyw->image.interval << 4);
|
||||||
|
evo_mthd(push, 0x00c0, 1);
|
||||||
|
evo_data(push, asyw->image.handle[0]);
|
||||||
|
evo_mthd(push, 0x0100, 1);
|
||||||
|
evo_data(push, 0x00000002);
|
||||||
|
evo_mthd(push, 0x0800, 1);
|
||||||
|
evo_data(push, asyw->image.offset[0] >> 8);
|
||||||
|
evo_mthd(push, 0x0808, 3);
|
||||||
|
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||||
|
evo_data(push, asyw->image.layout << 20 |
|
||||||
|
(asyw->image.pitch[0] >> 8) << 8 |
|
||||||
|
asyw->image.blocks[0] << 8 |
|
||||||
|
asyw->image.blockh);
|
||||||
|
evo_data(push, asyw->image.kind << 16 |
|
||||||
|
asyw->image.format << 8 |
|
||||||
|
asyw->image.colorspace);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_ntfy_clr(struct nv50_wndw *wndw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||||
|
evo_mthd(push, 0x00a4, 1);
|
||||||
|
evo_data(push, 0x00000000);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 3))) {
|
||||||
|
evo_mthd(push, 0x00a0, 2);
|
||||||
|
evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset);
|
||||||
|
evo_data(push, asyw->ntfy.handle);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||||
|
struct nv50_head_atom *asyh)
|
||||||
|
{
|
||||||
|
asyh->ovly.cpp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||||
|
struct nv50_head_atom *asyh)
|
||||||
|
{
|
||||||
|
const struct drm_framebuffer *fb = asyw->state.fb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
|
||||||
|
DRM_PLANE_HELPER_NO_SCALING,
|
||||||
|
DRM_PLANE_HELPER_NO_SCALING,
|
||||||
|
true, true);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
asyh->ovly.cpp = fb->format->cpp[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#include "nouveau_bo.h"
|
#include "nouveau_bo.h"
|
||||||
|
|
||||||
static const struct nv50_wndw_func
|
static const struct nv50_wndw_func
|
||||||
ovly507e = {
|
ovly507e = {
|
||||||
|
.acquire = ovly507e_acquire,
|
||||||
|
.release = ovly507e_release,
|
||||||
|
.ntfy_set = ovly507e_ntfy_set,
|
||||||
|
.ntfy_clr = ovly507e_ntfy_clr,
|
||||||
|
.ntfy_reset = base507c_ntfy_reset,
|
||||||
|
.ntfy_wait_begun = base507c_ntfy_wait_begun,
|
||||||
|
.image_set = ovly507e_image_set,
|
||||||
|
.image_clr = ovly507e_image_clr,
|
||||||
|
.scale_set = ovly507e_scale_set,
|
||||||
|
.update = ovly507e_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32
|
static const u32
|
||||||
ovly507e_format[] = {
|
ovly507e_format[] = {
|
||||||
|
DRM_FORMAT_YUYV,
|
||||||
|
DRM_FORMAT_UYVY,
|
||||||
|
DRM_FORMAT_XRGB8888,
|
||||||
|
DRM_FORMAT_ARGB8888,
|
||||||
|
DRM_FORMAT_XRGB1555,
|
||||||
|
DRM_FORMAT_ARGB1555,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +193,18 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, false,
|
||||||
|
NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT,
|
||||||
|
&(struct nvif_notify_uevent_req) {},
|
||||||
|
sizeof(struct nvif_notify_uevent_req),
|
||||||
|
sizeof(struct nvif_notify_uevent_rep),
|
||||||
|
&wndw->notify);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
|
||||||
|
wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
|
||||||
|
wndw->data = 0x00000000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,17 +20,81 @@
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "ovly.h"
|
#include "ovly.h"
|
||||||
|
#include "atom.h"
|
||||||
|
|
||||||
#include <nouveau_bo.h>
|
#include <nouveau_bo.h>
|
||||||
|
|
||||||
#include <nvif/cl507e.h>
|
static void
|
||||||
|
ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 12))) {
|
||||||
|
evo_mthd(push, 0x0084, 1);
|
||||||
|
evo_data(push, asyw->image.interval << 4);
|
||||||
|
evo_mthd(push, 0x00c0, 1);
|
||||||
|
evo_data(push, asyw->image.handle[0]);
|
||||||
|
evo_mthd(push, 0x0100, 1);
|
||||||
|
evo_data(push, 0x00000002);
|
||||||
|
evo_mthd(push, 0x0800, 1);
|
||||||
|
evo_data(push, asyw->image.offset[0] >> 8);
|
||||||
|
evo_mthd(push, 0x0808, 3);
|
||||||
|
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||||
|
evo_data(push, asyw->image.layout << 20 |
|
||||||
|
(asyw->image.pitch[0] >> 8) << 8 |
|
||||||
|
asyw->image.blocks[0] << 8 |
|
||||||
|
asyw->image.blockh);
|
||||||
|
evo_data(push, asyw->image.format << 8 |
|
||||||
|
asyw->image.colorspace);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
|
||||||
|
struct nvif_device *device)
|
||||||
|
{
|
||||||
|
s64 time = nvif_msec(device, 2000ULL,
|
||||||
|
u32 data = nouveau_bo_rd32(bo, offset / 4 + 3);
|
||||||
|
if ((data & 0xffff0000) == 0xffff0000)
|
||||||
|
break;
|
||||||
|
usleep_range(1, 2);
|
||||||
|
);
|
||||||
|
return time < 0 ? time : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset)
|
||||||
|
{
|
||||||
|
nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000);
|
||||||
|
nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000);
|
||||||
|
nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000);
|
||||||
|
nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct nv50_wndw_func
|
static const struct nv50_wndw_func
|
||||||
ovly827e = {
|
ovly827e = {
|
||||||
|
.acquire = ovly507e_acquire,
|
||||||
|
.release = ovly507e_release,
|
||||||
|
.ntfy_set = ovly507e_ntfy_set,
|
||||||
|
.ntfy_clr = ovly507e_ntfy_clr,
|
||||||
|
.ntfy_reset = ovly827e_ntfy_reset,
|
||||||
|
.ntfy_wait_begun = ovly827e_ntfy_wait_begun,
|
||||||
|
.image_set = ovly827e_image_set,
|
||||||
|
.image_clr = ovly507e_image_clr,
|
||||||
|
.scale_set = ovly507e_scale_set,
|
||||||
|
.update = ovly507e_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
const u32
|
const u32
|
||||||
ovly827e_format[] = {
|
ovly827e_format[] = {
|
||||||
|
DRM_FORMAT_YUYV,
|
||||||
|
DRM_FORMAT_UYVY,
|
||||||
|
DRM_FORMAT_XRGB8888,
|
||||||
|
DRM_FORMAT_ARGB8888,
|
||||||
|
DRM_FORMAT_XRGB1555,
|
||||||
|
DRM_FORMAT_ARGB1555,
|
||||||
|
DRM_FORMAT_XBGR2101010,
|
||||||
|
DRM_FORMAT_ABGR2101010,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,45 @@
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "ovly.h"
|
#include "ovly.h"
|
||||||
|
#include "atom.h"
|
||||||
|
|
||||||
static const struct nv50_wndw_func
|
static void
|
||||||
|
ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
u32 *push;
|
||||||
|
if ((push = evo_wait(&wndw->wndw, 12))) {
|
||||||
|
evo_mthd(push, 0x0084, 1);
|
||||||
|
evo_data(push, asyw->image.interval << 4);
|
||||||
|
evo_mthd(push, 0x00c0, 1);
|
||||||
|
evo_data(push, asyw->image.handle[0]);
|
||||||
|
evo_mthd(push, 0x0100, 1);
|
||||||
|
evo_data(push, 0x00000002);
|
||||||
|
evo_mthd(push, 0x0400, 1);
|
||||||
|
evo_data(push, asyw->image.offset[0] >> 8);
|
||||||
|
evo_mthd(push, 0x0408, 3);
|
||||||
|
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||||
|
evo_data(push, asyw->image.layout << 24 |
|
||||||
|
(asyw->image.pitch[0] >> 8) << 8 |
|
||||||
|
asyw->image.blocks[0] << 8 |
|
||||||
|
asyw->image.blockh);
|
||||||
|
evo_data(push, asyw->image.format << 8 |
|
||||||
|
asyw->image.colorspace);
|
||||||
|
evo_kick(push, &wndw->wndw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nv50_wndw_func
|
||||||
ovly907e = {
|
ovly907e = {
|
||||||
|
.acquire = ovly507e_acquire,
|
||||||
|
.release = ovly507e_release,
|
||||||
|
.ntfy_set = ovly507e_ntfy_set,
|
||||||
|
.ntfy_clr = ovly507e_ntfy_clr,
|
||||||
|
.ntfy_reset = ovly827e_ntfy_reset,
|
||||||
|
.ntfy_wait_begun = ovly827e_ntfy_wait_begun,
|
||||||
|
.image_set = ovly907e_image_set,
|
||||||
|
.image_clr = ovly507e_image_clr,
|
||||||
|
.scale_set = ovly507e_scale_set,
|
||||||
|
.update = ovly507e_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "ovly.h"
|
||||||
|
|
||||||
|
static const u32
|
||||||
|
ovly917e_format[] = {
|
||||||
|
DRM_FORMAT_YUYV,
|
||||||
|
DRM_FORMAT_UYVY,
|
||||||
|
DRM_FORMAT_XRGB8888,
|
||||||
|
DRM_FORMAT_ARGB8888,
|
||||||
|
DRM_FORMAT_XRGB1555,
|
||||||
|
DRM_FORMAT_ARGB1555,
|
||||||
|
DRM_FORMAT_XBGR2101010,
|
||||||
|
DRM_FORMAT_ABGR2101010,
|
||||||
|
DRM_FORMAT_XRGB2101010,
|
||||||
|
DRM_FORMAT_ARGB2101010,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ovly917e_new(struct nouveau_drm *drm, int head, s32 oclass,
|
||||||
|
struct nv50_wndw **pwndw)
|
||||||
|
{
|
||||||
|
return ovly507e_new_(&ovly907e, ovly917e_format, drm, head, oclass,
|
||||||
|
0x00000004 << (head * 4), pwndw);
|
||||||
|
}
|
|
@ -146,6 +146,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
|
||||||
wndw->func->xlut_set(wndw, asyw);
|
wndw->func->xlut_set(wndw, asyw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
|
||||||
if (asyw->set.point) {
|
if (asyw->set.point) {
|
||||||
wndw->immd->point(wndw, asyw);
|
wndw->immd->point(wndw, asyw);
|
||||||
wndw->immd->update(wndw, interlock);
|
wndw->immd->update(wndw, interlock);
|
||||||
|
@ -180,6 +181,20 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw,
|
||||||
asyw->sema.handle = 0;
|
asyw->sema.handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw)
|
||||||
|
{
|
||||||
|
switch (asyw->state.fb->format->format) {
|
||||||
|
case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break;
|
||||||
|
case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
asyw->image.colorspace = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
|
nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
|
||||||
{
|
{
|
||||||
|
@ -197,9 +212,9 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
|
||||||
case DRM_FORMAT_XRGB2101010:
|
case DRM_FORMAT_XRGB2101010:
|
||||||
case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break;
|
case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break;
|
||||||
default:
|
default:
|
||||||
WARN_ON(1);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
asyw->image.colorspace = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,8 +236,11 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
|
||||||
asyw->image.kind = fb->nvbo->kind;
|
asyw->image.kind = fb->nvbo->kind;
|
||||||
|
|
||||||
ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
|
ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
|
||||||
if (ret)
|
if (ret) {
|
||||||
return ret;
|
ret = nv50_wndw_atomic_check_acquire_yuv(asyw);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (asyw->image.kind) {
|
if (asyw->image.kind) {
|
||||||
asyw->image.layout = 0;
|
asyw->image.layout = 0;
|
||||||
|
@ -247,6 +265,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
|
||||||
asyw->set.image = wndw->func->image_set != NULL;
|
asyw->set.image = wndw->func->image_set != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wndw->func->scale_set) {
|
||||||
|
asyw->scale.sx = asyw->state.src_x >> 16;
|
||||||
|
asyw->scale.sy = asyw->state.src_y >> 16;
|
||||||
|
asyw->scale.sw = asyw->state.src_w >> 16;
|
||||||
|
asyw->scale.sh = asyw->state.src_h >> 16;
|
||||||
|
asyw->scale.dw = asyw->state.crtc_w;
|
||||||
|
asyw->scale.dh = asyw->state.crtc_h;
|
||||||
|
if (memcmp(&armw->scale, &asyw->scale, sizeof(asyw->scale)))
|
||||||
|
asyw->set.scale = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (wndw->immd) {
|
if (wndw->immd) {
|
||||||
asyw->point.x = asyw->state.crtc_x;
|
asyw->point.x = asyw->state.crtc_x;
|
||||||
asyw->point.y = asyw->state.crtc_y;
|
asyw->point.y = asyw->state.crtc_y;
|
||||||
|
|
|
@ -70,15 +70,21 @@ struct nv50_wndw_func {
|
||||||
void (*xlut_clr)(struct nv50_wndw *);
|
void (*xlut_clr)(struct nv50_wndw *);
|
||||||
void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
void (*image_clr)(struct nv50_wndw *);
|
void (*image_clr)(struct nv50_wndw *);
|
||||||
|
void (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
|
|
||||||
void (*update)(struct nv50_wndw *, u32 *interlock);
|
void (*update)(struct nv50_wndw *, u32 *interlock);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct drm_plane_funcs nv50_wndw;
|
extern const struct drm_plane_funcs nv50_wndw;
|
||||||
|
|
||||||
|
void base507c_ntfy_reset(struct nouveau_bo *, u32);
|
||||||
|
int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
|
||||||
|
|
||||||
struct nv50_wimm_func {
|
struct nv50_wimm_func {
|
||||||
void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||||
|
|
||||||
void (*update)(struct nv50_wndw *, u32 *interlock);
|
void (*update)(struct nv50_wndw *, u32 *interlock);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct nv50_wimm_func curs507a;
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче