1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4 */ 5 #include "core.h" 6 #include "head.h" 7 8 #include <nvif/class.h> 9 #include <nvif/pushc97b.h> 10 11 #include <nvhw/class/clca7d.h> 12 13 #include <nouveau_bo.h> 14 15 static int 16 coreca7d_update(struct nv50_core *core, u32 *interlock, bool ntfy) 17 { 18 const u64 ntfy_addr = core->disp->sync->offset + NV50_DISP_CORE_NTFY; 19 const u32 ntfy_hi = upper_32_bits(ntfy_addr); 20 const u32 ntfy_lo = lower_32_bits(ntfy_addr); 21 struct nvif_push *push = &core->chan.push; 22 int ret; 23 24 ret = PUSH_WAIT(push, 5 + (ntfy ? 5 + 2 : 0)); 25 if (ret) 26 return ret; 27 28 if (ntfy) { 29 PUSH_MTHD(push, NVCA7D, SET_SURFACE_ADDRESS_HI_NOTIFIER, ntfy_hi, 30 31 SET_SURFACE_ADDRESS_LO_NOTIFIER, 32 NVVAL(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, ADDRESS_LO, ntfy_lo >> 4) | 33 NVDEF(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, TARGET, PHYSICAL_NVM) | 34 NVDEF(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, ENABLE)); 35 36 PUSH_MTHD(push, NVCA7D, SET_NOTIFIER_CONTROL, 37 NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, MODE, WRITE) | 38 NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); 39 } 40 41 PUSH_MTHD(push, NVCA7D, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS], 42 SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]); 43 44 PUSH_MTHD(push, NVCA7D, UPDATE, 45 NVDEF(NVCA7D, UPDATE, RELEASE_ELV, TRUE) | 46 NVDEF(NVCA7D, UPDATE, SPECIAL_HANDLING, NONE) | 47 NVDEF(NVCA7D, UPDATE, INHIBIT_INTERRUPTS, FALSE)); 48 49 if (ntfy) { 50 PUSH_MTHD(push, NVCA7D, SET_NOTIFIER_CONTROL, 51 NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE)); 52 } 53 54 return PUSH_KICK(push); 55 } 56 57 static int 58 coreca7d_init(struct nv50_core *core) 59 { 60 struct nvif_push *push = &core->chan.push; 61 const u32 windows = 8, heads = 4; 62 int ret, i; 63 64 ret = PUSH_WAIT(push, windows * 6 + heads * 6); 65 if (ret) 66 return ret; 67 68 for (i = 0; i < windows; i++) { 69 PUSH_MTHD(push, NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i), 70 NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) | 71 NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) | 72 NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) | 73 NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE), 74 75 WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000); 76 77 PUSH_MTHD(push, NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i), 78 NVVAL(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) | 79 NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, ILUT_ALLOWED, TRUE) | 80 NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) | 81 NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE), 82 83 WINDOW_SET_PHYSICAL(i), BIT(i)); 84 } 85 86 for (i = 0; i < heads; i++) { 87 PUSH_MTHD(push, NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS(i), 88 NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, CURSOR, USAGE_W256_H256) | 89 NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, OLUT_ALLOWED, TRUE) | 90 NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, OUTPUT_SCALER_TAPS, TAPS_2) | 91 NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, UPSCALING_ALLOWED, TRUE)); 92 93 PUSH_MTHD(push, NVCA7D, HEAD_SET_TILE_MASK(i), BIT(i)); 94 95 PUSH_MTHD(push, NVCA7D, TILE_SET_TILE_SIZE(i), 0); 96 } 97 98 core->assign_windows = true; 99 return PUSH_KICK(push); 100 } 101 102 static const struct nv50_core_func 103 coreca7d = { 104 .init = coreca7d_init, 105 .ntfy_init = corec37d_ntfy_init, 106 .caps_init = corec37d_caps_init, 107 .caps_class = GB202_DISP_CAPS, 108 .ntfy_wait_done = corec37d_ntfy_wait_done, 109 .update = coreca7d_update, 110 .wndw.owner = corec37d_wndw_owner, 111 .head = &headca7d, 112 .sor = &sorc37d, 113 #if IS_ENABLED(CONFIG_DEBUG_FS) 114 .crc = &crcca7d, 115 #endif 116 }; 117 118 int 119 coreca7d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) 120 { 121 return core507d_new_(&coreca7d, drm, oclass, pcore); 122 } 123