FILE
disp.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c
1/* SPDX-License-Identifier: MIT 2 * 3 * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. 4 */ 5#include <rm/rm.h> 6 7#include <engine/disp.h> 8#include <engine/disp/outp.h> 9 10#include "nvhw/drf.h" 11 12#include "nvrm/disp.h" 13 14static int 15r570_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset, 16 struct nvkm_gsp_object *dmac) 17{ 18 NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; 19 20 args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass, 21 sizeof(*args), dmac); 22 if (IS_ERR(args)) 23 return PTR_ERR(args); 24 25 args->channelInstance = inst; 26 args->offset = put_offset; 27 args->subDeviceId = BIT(0); 28 29 return nvkm_gsp_rm_alloc_wr(dmac, args); 30} 31 32static int 33r570_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory) 34{ 35 struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; 36 NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl; 37 38 ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, 39 NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER, 40 sizeof(*ctrl)); 41 if (IS_ERR(ctrl)) 42 return PTR_ERR(ctrl); 43 44 if (memory) { 45 switch (nvkm_memory_target(memory)) { 46 case NVKM_MEM_TARGET_NCOH: 47 ctrl->addressSpace = ADDR_SYSMEM; 48 ctrl->cacheSnoop = 0; 49 ctrl->pbTargetAperture = PHYS_PCI; 50 break; 51 case NVKM_MEM_TARGET_HOST: 52 ctrl->addressSpace = ADDR_SYSMEM; 53 ctrl->cacheSnoop = 1; 54 ctrl->pbTargetAperture = PHYS_PCI_COHERENT; 55 break; 56 case NVKM_MEM_TARGET_VRAM: 57 ctrl->addressSpace = ADDR_FBMEM; 58 ctrl->pbTargetAperture = PHYS_NVM; 59 break; 60 default: 61 WARN_ON(1); 62 return -EINVAL; 63 } 64 65 ctrl->physicalAddr = nvkm_memory_addr(memory); 66 ctrl->limit = nvkm_memory_size(memory) - 1; 67 } 68 69 ctrl->hclass = oclass; 70 ctrl->channelInstance = inst; 71 ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0; 72 ctrl->subDeviceId = BIT(0); 73 74 return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); 75} 76 77static int 78r570_dp_set_indexed_link_rates(struct nvkm_outp *outp) 79{ 80 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl; 81 struct nvkm_disp *disp = outp->disp; 82 83 if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl))) 84 return -EINVAL; 85 86 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, 87 NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES, sizeof(*ctrl)); 88 if (IS_ERR(ctrl)) 89 return PTR_ERR(ctrl); 90 91 ctrl->displayId = BIT(outp->index); 92 for (int i = 0; i < outp->dp.rates; i++) 93 ctrl->linkRateTbl[outp->dp.rate[i].dpcd] = outp->dp.rate[i].rate * 10 / 200; 94 95 return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); 96} 97 98static int 99r570_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm) 100{ 101 NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; 102 int ret; 103 104 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, 105 NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); 106 if (IS_ERR(ctrl)) 107 return PTR_ERR(ctrl); 108 109 ctrl->sorIndex = ~0; 110 111 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); 112 if (ret) { 113 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 114 return ret; 115 } 116 117 switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { 118 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: 119 *plink_bw = 0x06; 120 break; 121 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: 122 *plink_bw = 0x0a; 123 break; 124 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: 125 *plink_bw = 0x14; 126 break; 127 case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: 128 *plink_bw = 0x1e; 129 break; 130 default: 131 *plink_bw = 0x00; 132 break; 133 } 134 135 *pmst = ctrl->bIsMultistreamSupported; 136 *pwm = ctrl->bHasIncreasedWatermarkLimits; 137 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 138 return 0; 139} 140 141static int 142r570_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval) 143{ 144 u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS : 145 NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS; 146 NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; 147 int ret; 148 149 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl)); 150 if (IS_ERR(ctrl)) 151 return PTR_ERR(ctrl); 152 153 ctrl->displayId = BIT(display_id); 154 ctrl->brightness = *pval; 155 ctrl->brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100; 156 157 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); 158 if (ret) 159 return ret; 160 161 *pval = ctrl->brightness; 162 163 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 164 return 0; 165} 166 167static int 168r570_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid) 169{ 170 NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl; 171 int ret; 172 173 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, 174 NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE, sizeof(*ctrl)); 175 if (IS_ERR(ctrl)) 176 return PTR_ERR(ctrl); 177 178 ctrl->subDeviceInstance = 0; 179 ctrl->head = head; 180 181 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); 182 if (ret) { 183 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 184 return ret; 185 } 186 187 *displayid = ctrl->displayId; 188 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 189 return 0; 190} 191static int 192r570_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id) 193{ 194 NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl; 195 int ret; 196 197 ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, 198 NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE, sizeof(*ctrl)); 199 if (IS_ERR(ctrl)) 200 return PTR_ERR(ctrl); 201 202 ctrl->subDeviceInstance = 0; 203 ctrl->displayMask = BIT(display_id); 204 205 ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); 206 if (ret == 0 && (ctrl->displayMask & BIT(display_id))) 207 ret = 1; 208 209 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 210 return ret; 211} 212 213static int 214r570_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask) 215{ 216 NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; 217 218 ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, 219 NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); 220 if (IS_ERR(ctrl)) 221 return PTR_ERR(ctrl); 222 223 *pmask = ctrl->displayMask; 224 225 nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); 226 return 0; 227} 228 229static int 230r570_disp_get_static_info(struct nvkm_disp *disp) 231{ 232 NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; 233 struct nvkm_gsp *gsp = disp->engine.subdev.device->gsp; 234 235 ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, 236 NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, 237 sizeof(*ctrl)); 238 if (IS_ERR(ctrl)) 239 return PTR_ERR(ctrl); 240 241 disp->wndw.mask = ctrl->windowPresentMask; 242 disp->wndw.nr = fls(disp->wndw.mask); 243 244 nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); 245 return 0; 246} 247 248const struct nvkm_rm_api_disp 249r570_disp = { 250 .get_static_info = r570_disp_get_static_info, 251 .get_supported = r570_disp_get_supported, 252 .get_connect_state = r570_disp_get_connect_state, 253 .get_active = r570_disp_get_active, 254 .bl_ctrl = r570_bl_ctrl, 255 .dp = { 256 .get_caps = r570_dp_get_caps, 257 .set_indexed_link_rates = r570_dp_set_indexed_link_rates, 258 }, 259 .chan = { 260 .set_pushbuf = r570_disp_chan_set_pushbuf, 261 .dmac_alloc = r570_dmac_alloc, 262 }, 263};
~/
Read-only file preview.