0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "core.h"
0023 #include "head.h"
0024
0025 #include <nvif/class.h>
0026 #include <nvif/pushc37b.h>
0027 #include <nvif/timer.h>
0028
0029 #include <nvhw/class/clc37d.h>
0030
0031 #include <nouveau_bo.h>
0032
0033 int
0034 corec37d_wndw_owner(struct nv50_core *core)
0035 {
0036 struct nvif_push *push = core->chan.push;
0037 const u32 windows = 8;
0038 int ret, i;
0039
0040 if ((ret = PUSH_WAIT(push, windows * 2)))
0041 return ret;
0042
0043 for (i = 0; i < windows; i++) {
0044 PUSH_MTHD(push, NVC37D, WINDOW_SET_CONTROL(i),
0045 NVDEF(NVC37D, WINDOW_SET_CONTROL, OWNER, HEAD(i >> 1)));
0046 }
0047
0048 return 0;
0049 }
0050
0051 int
0052 corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
0053 {
0054 struct nvif_push *push = core->chan.push;
0055 int ret;
0056
0057 if ((ret = PUSH_WAIT(push, (ntfy ? 2 * 2 : 0) + 5)))
0058 return ret;
0059
0060 if (ntfy) {
0061 PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL,
0062 NVDEF(NVC37D, SET_NOTIFIER_CONTROL, MODE, WRITE) |
0063 NVVAL(NVC37D, SET_NOTIFIER_CONTROL, OFFSET, NV50_DISP_CORE_NTFY >> 4) |
0064 NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE));
0065 }
0066
0067 PUSH_MTHD(push, NVC37D, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS],
0068 SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]);
0069 PUSH_MTHD(push, NVC37D, UPDATE, 0x00000001 |
0070 NVDEF(NVC37D, UPDATE, SPECIAL_HANDLING, NONE) |
0071 NVDEF(NVC37D, UPDATE, INHIBIT_INTERRUPTS, FALSE));
0072
0073 if (ntfy) {
0074 PUSH_MTHD(push, NVC37D, SET_NOTIFIER_CONTROL,
0075 NVDEF(NVC37D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE));
0076 }
0077
0078 return PUSH_KICK(push);
0079 }
0080
0081 int
0082 corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
0083 struct nvif_device *device)
0084 {
0085 s64 time = nvif_msec(device, 2000ULL,
0086 if (NVBO_TD32(bo, offset, NV_DISP_NOTIFIER, _0, STATUS, ==, FINISHED))
0087 break;
0088 usleep_range(1, 2);
0089 );
0090 return time < 0 ? time : 0;
0091 }
0092
0093 void
0094 corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset)
0095 {
0096 NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _0,
0097 NVDEF(NV_DISP_NOTIFIER, _0, STATUS, NOT_BEGUN));
0098 NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _1, 0);
0099 NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _2, 0);
0100 NVBO_WR32(bo, offset, NV_DISP_NOTIFIER, _3, 0);
0101 }
0102
0103 int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp)
0104 {
0105 int ret;
0106
0107 ret = nvif_object_ctor(&disp->disp->object, "dispCaps", 0,
0108 GV100_DISP_CAPS, NULL, 0, &disp->caps);
0109 if (ret) {
0110 NV_ERROR(drm,
0111 "Failed to init notifier caps region: %d\n",
0112 ret);
0113 return ret;
0114 }
0115
0116 ret = nvif_object_map(&disp->caps, NULL, 0);
0117 if (ret) {
0118 NV_ERROR(drm,
0119 "Failed to map notifier caps region: %d\n",
0120 ret);
0121 return ret;
0122 }
0123
0124 return 0;
0125 }
0126
0127 static int
0128 corec37d_init(struct nv50_core *core)
0129 {
0130 struct nvif_push *push = core->chan.push;
0131 const u32 windows = 8;
0132 int ret, i;
0133
0134 if ((ret = PUSH_WAIT(push, 2 + windows * 5)))
0135 return ret;
0136
0137 PUSH_MTHD(push, NVC37D, SET_CONTEXT_DMA_NOTIFIER, core->chan.sync.handle);
0138
0139 for (i = 0; i < windows; i++) {
0140 PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i),
0141 NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) |
0142 NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) |
0143 NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) |
0144 NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE) |
0145 NVDEF(NVC37D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, YUV_PACKED422, TRUE),
0146
0147 WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000);
0148
0149 PUSH_MTHD(push, NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i),
0150 NVVAL(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) |
0151 NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_LUT, USAGE_1025) |
0152 NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) |
0153 NVDEF(NVC37D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE));
0154 }
0155
0156 core->assign_windows = true;
0157 return PUSH_KICK(push);
0158 }
0159
0160 static const struct nv50_core_func
0161 corec37d = {
0162 .init = corec37d_init,
0163 .ntfy_init = corec37d_ntfy_init,
0164 .caps_init = corec37d_caps_init,
0165 .ntfy_wait_done = corec37d_ntfy_wait_done,
0166 .update = corec37d_update,
0167 .wndw.owner = corec37d_wndw_owner,
0168 .head = &headc37d,
0169 .sor = &sorc37d,
0170 #if IS_ENABLED(CONFIG_DEBUG_FS)
0171 .crc = &crcc37d,
0172 #endif
0173 };
0174
0175 int
0176 corec37d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
0177 {
0178 return core507d_new_(&corec37d, drm, oclass, pcore);
0179 }