1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4 */ 5 #include "wndw.h" 6 #include "atom.h" 7 8 #include <nvif/pushc97b.h> 9 10 #include <nvhw/class/clca7e.h> 11 12 #include <nouveau_bo.h> 13 14 static int 15 wndwca7e_image_clr(struct nv50_wndw *wndw) 16 { 17 struct nvif_push *push = &wndw->wndw.push; 18 int ret; 19 20 ret = PUSH_WAIT(push, 4); 21 if (ret) 22 return ret; 23 24 PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL, 25 NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) | 26 NVDEF(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING)); 27 28 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0), 29 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, DISABLE)); 30 31 return 0; 32 } 33 34 static int 35 wndwca7e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 36 { 37 const u32 iso0_hi = upper_32_bits(asyw->image.offset[0]); 38 const u32 iso0_lo = lower_32_bits(asyw->image.offset[0]); 39 struct nvif_push *push = &wndw->wndw.push; 40 int ret, kind; 41 42 if (asyw->image.kind) 43 kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_BLOCKLINEAR; 44 else 45 kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_PITCH; 46 47 ret = PUSH_WAIT(push, 17); 48 if (ret) 49 return ret; 50 51 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ISO(0), iso0_hi); 52 53 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0), 54 NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ADDRESS_LO, iso0_lo >> 4) | 55 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, TARGET, PHYSICAL_NVM) | 56 NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, KIND, kind) | 57 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, ENABLE)); 58 59 PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL, 60 NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | 61 NVVAL(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | 62 NVDEF(NVCA7E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); 63 64 PUSH_MTHD(push, NVCA7E, SET_SIZE, 65 NVVAL(NVCA7E, SET_SIZE, WIDTH, asyw->image.w) | 66 NVVAL(NVCA7E, SET_SIZE, HEIGHT, asyw->image.h), 67 68 SET_STORAGE, 69 NVVAL(NVCA7E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), 70 71 SET_PARAMS, 72 NVVAL(NVCA7E, SET_PARAMS, FORMAT, asyw->image.format) | 73 NVDEF(NVCA7E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | 74 NVDEF(NVCA7E, SET_PARAMS, SWAP_UV, DISABLE) | 75 NVDEF(NVCA7E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST), 76 77 SET_PLANAR_STORAGE(0), 78 NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | 79 NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); 80 81 PUSH_MTHD(push, NVCA7E, SET_POINT_IN(0), 82 NVVAL(NVCA7E, SET_POINT_IN, X, asyw->state.src_x >> 16) | 83 NVVAL(NVCA7E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); 84 85 PUSH_MTHD(push, NVCA7E, SET_SIZE_IN, 86 NVVAL(NVCA7E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | 87 NVVAL(NVCA7E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); 88 89 PUSH_MTHD(push, NVCA7E, SET_SIZE_OUT, 90 NVVAL(NVCA7E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | 91 NVVAL(NVCA7E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); 92 93 return 0; 94 } 95 96 static int 97 wndwca7e_ilut_clr(struct nv50_wndw *wndw) 98 { 99 struct nvif_push *push = &wndw->wndw.push; 100 int ret; 101 102 ret = PUSH_WAIT(push, 2); 103 if (ret) 104 return ret; 105 106 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, 107 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, DISABLE)); 108 109 return 0; 110 } 111 112 static int 113 wndwca7e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 114 { 115 const u32 ilut_hi = upper_32_bits(asyw->xlut.i.offset); 116 const u32 ilut_lo = lower_32_bits(asyw->xlut.i.offset); 117 struct nvif_push *push = &wndw->wndw.push; 118 int ret; 119 120 ret = PUSH_WAIT(push, 5); 121 if (ret) 122 return ret; 123 124 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ILUT, ilut_hi, 125 126 SET_SURFACE_ADDRESS_LO_ILUT, 127 NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ADDRESS_LO, ilut_lo >> 4) | 128 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, TARGET, PHYSICAL_NVM) | 129 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, ENABLE)); 130 131 PUSH_MTHD(push, NVCA7E, SET_ILUT_CONTROL, 132 NVVAL(NVCA7E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) | 133 NVVAL(NVCA7E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) | 134 NVVAL(NVCA7E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode)); 135 136 return 0; 137 } 138 139 static int 140 wndwca7e_ntfy_clr(struct nv50_wndw *wndw) 141 { 142 struct nvif_push *push = &wndw->wndw.push; 143 int ret; 144 145 ret = PUSH_WAIT(push, 2); 146 if (ret) 147 return ret; 148 149 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, 150 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, DISABLE)); 151 152 return 0; 153 } 154 155 static int 156 wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 157 { 158 struct nv50_disp *disp = nv50_disp(wndw->plane.dev); 159 const u64 ntfy_addr = disp->sync->offset + asyw->ntfy.offset; 160 const u32 ntfy_hi = upper_32_bits(ntfy_addr); 161 const u32 ntfy_lo = lower_32_bits(ntfy_addr); 162 struct nvif_push *push = &wndw->wndw.push; 163 int ret; 164 165 ret = PUSH_WAIT(push, 5); 166 if (ret) 167 return ret; 168 169 PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_NOTIFIER, ntfy_hi, 170 171 SET_SURFACE_ADDRESS_LO_NOTIFIER, 172 NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ADDRESS_LO, ntfy_lo >> 4) | 173 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, TARGET, PHYSICAL_NVM) | 174 NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, ENABLE)); 175 176 PUSH_MTHD(push, NVCA7E, SET_NOTIFIER_CONTROL, 177 NVVAL(NVCA7E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken)); 178 179 return 0; 180 } 181 182 static const struct nv50_wndw_func 183 wndwca7e = { 184 .acquire = wndwc37e_acquire, 185 .release = wndwc37e_release, 186 .ntfy_set = wndwca7e_ntfy_set, 187 .ntfy_clr = wndwca7e_ntfy_clr, 188 .ntfy_reset = corec37d_ntfy_init, 189 .ntfy_wait_begun = base507c_ntfy_wait_begun, 190 .ilut = wndwc57e_ilut, 191 .ilut_identity = true, 192 .ilut_size = 1024, 193 .xlut_set = wndwca7e_ilut_set, 194 .xlut_clr = wndwca7e_ilut_clr, 195 .csc = base907c_csc, 196 .csc_set = wndwc57e_csc_set, 197 .csc_clr = wndwc57e_csc_clr, 198 .image_set = wndwca7e_image_set, 199 .image_clr = wndwca7e_image_clr, 200 .blend_set = wndwc37e_blend_set, 201 .update = wndwc37e_update, 202 }; 203 204 int 205 wndwca7e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, 206 s32 oclass, struct nv50_wndw **pwndw) 207 { 208 return wndwc37e_new_(&wndwca7e, drm, type, index, oclass, BIT(index >> 1), pwndw); 209 } 210