Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'amd-drm-next-7.1-2026-03-12' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-7.1-2026-03-12:

amdgpu:
- SMU13 fix
- SMU14 fix
- Fixes for bring up hw testing
- Kerneldoc fix
- GC12 idle power fix for compute workloads
- DCCG fixes
- UserQ fixes
- Move test for fbdev object to a generic helper
- GC 12.1 updates
- Use struct drm_edid in non-DC code
- Include IP discovery data in devcoredump
- SMU 13.x updates
- Misc cleanups
- DML 2.1 fixes
- Enable NV12/P010 support on primary planes
- Enable color encoding and color range on overlay planes
- DC underflow fixes
- HWSS fast path fixes
- Replay fixes
- DCN 4.2 updates
- Support newer IP discovery tables
- LSDMA 7.1 support
- IH 7.1 fixes
- SoC v1 updates
- GC12.1 updates
- PSP 15 updates
- XGMI fixes
- GPUVM locking fix

amdkfd:
- Fix missing BO unreserve in an error path

radeon:
- Move test for fbdev object to a generic helper

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260312184425.3875669-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>

+3822 -2526
+1 -1
drivers/gpu/drm/amd/amdgpu/Makefile
··· 86 86 nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o soc24.o \ 87 87 sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \ 88 88 nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o nbif_v6_3_1.o \ 89 - cyan_skillfish_reg_init.o soc_v1_0.o 89 + cyan_skillfish_reg_init.o soc_v1_0.o lsdma_v7_1.o 90 90 91 91 # add DF block 92 92 amdgpu-y += \
+23 -31
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
··· 246 246 return NULL; 247 247 } 248 248 249 - static struct edid * 249 + static const struct drm_edid * 250 250 amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev) 251 251 { 252 - return drm_edid_duplicate(drm_edid_raw(adev->mode_info.bios_hardcoded_edid)); 252 + return drm_edid_dup(adev->mode_info.bios_hardcoded_edid); 253 253 } 254 254 255 255 static void amdgpu_connector_get_edid(struct drm_connector *connector) ··· 268 268 if ((amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) != 269 269 ENCODER_OBJECT_ID_NONE) && 270 270 amdgpu_connector->ddc_bus->has_aux) { 271 - amdgpu_connector->edid = drm_get_edid(connector, 272 - &amdgpu_connector->ddc_bus->aux.ddc); 271 + amdgpu_connector->edid = drm_edid_read_ddc(connector, 272 + &amdgpu_connector->ddc_bus->aux.ddc); 273 273 } else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || 274 274 (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { 275 275 struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv; ··· 277 277 if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || 278 278 dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && 279 279 amdgpu_connector->ddc_bus->has_aux) 280 - amdgpu_connector->edid = drm_get_edid(connector, 281 - &amdgpu_connector->ddc_bus->aux.ddc); 280 + amdgpu_connector->edid = drm_edid_read_ddc(connector, 281 + &amdgpu_connector->ddc_bus->aux.ddc); 282 282 else if (amdgpu_connector->ddc_bus) 283 - amdgpu_connector->edid = drm_get_edid(connector, 284 - &amdgpu_connector->ddc_bus->adapter); 283 + amdgpu_connector->edid = drm_edid_read_ddc(connector, 284 + &amdgpu_connector->ddc_bus->adapter); 285 285 } else if (amdgpu_connector->ddc_bus) { 286 - amdgpu_connector->edid = drm_get_edid(connector, 287 - &amdgpu_connector->ddc_bus->adapter); 286 + amdgpu_connector->edid = drm_edid_read_ddc(connector, 287 + &amdgpu_connector->ddc_bus->adapter); 288 288 } 289 289 290 290 if (!amdgpu_connector->edid) { ··· 292 292 if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || 293 293 (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) { 294 294 amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev); 295 - drm_connector_update_edid_property(connector, amdgpu_connector->edid); 295 + drm_edid_connector_update(connector, amdgpu_connector->edid); 296 296 } 297 297 } 298 - } 299 - 300 - static void amdgpu_connector_free_edid(struct drm_connector *connector) 301 - { 302 - struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); 303 - 304 - kfree(amdgpu_connector->edid); 305 - amdgpu_connector->edid = NULL; 306 298 } 307 299 308 300 static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) ··· 303 311 int ret; 304 312 305 313 if (amdgpu_connector->edid) { 306 - drm_connector_update_edid_property(connector, amdgpu_connector->edid); 307 - ret = drm_add_edid_modes(connector, amdgpu_connector->edid); 314 + drm_edid_connector_update(connector, amdgpu_connector->edid); 315 + ret = drm_edid_connector_add_modes(connector); 308 316 return ret; 309 317 } 310 - drm_connector_update_edid_property(connector, NULL); 318 + drm_edid_connector_update(connector, NULL); 311 319 return 0; 312 320 } 313 321 ··· 746 754 { 747 755 struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); 748 756 749 - amdgpu_connector_free_edid(connector); 757 + drm_edid_free(amdgpu_connector->edid); 750 758 kfree(amdgpu_connector->con_priv); 751 759 drm_connector_unregister(connector); 752 760 drm_connector_cleanup(connector); ··· 865 873 dret = amdgpu_display_ddc_probe(amdgpu_connector, false); 866 874 if (dret) { 867 875 amdgpu_connector->detected_by_load = false; 868 - amdgpu_connector_free_edid(connector); 876 + drm_edid_free(amdgpu_connector->edid); 869 877 amdgpu_connector_get_edid(connector); 870 878 871 879 if (!amdgpu_connector->edid) { ··· 875 883 ret = connector_status_connected; 876 884 } else { 877 885 amdgpu_connector->use_digital = 878 - !!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL); 886 + drm_edid_is_digital(amdgpu_connector->edid); 879 887 880 888 /* some oems have boards with separate digital and analog connectors 881 889 * with a shared ddc line (often vga + hdmi) 882 890 */ 883 891 if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) { 884 - amdgpu_connector_free_edid(connector); 892 + drm_edid_free(amdgpu_connector->edid); 885 893 ret = connector_status_disconnected; 886 894 } else { 887 895 ret = connector_status_connected; ··· 976 984 /* hpd is our only option in this case */ 977 985 if (!amdgpu_display_hpd_sense(adev, 978 986 amdgpu_connector->hpd.hpd)) { 979 - amdgpu_connector_free_edid(connector); 987 + drm_edid_free(amdgpu_connector->edid); 980 988 *status = connector_status_disconnected; 981 989 } 982 990 } ··· 1045 1053 } 1046 1054 if (dret) { 1047 1055 amdgpu_connector->detected_by_load = false; 1048 - amdgpu_connector_free_edid(connector); 1056 + drm_edid_free(amdgpu_connector->edid); 1049 1057 amdgpu_connector_get_edid(connector); 1050 1058 1051 1059 if (!amdgpu_connector->edid) { ··· 1055 1063 broken_edid = true; /* defer use_digital to later */ 1056 1064 } else { 1057 1065 amdgpu_connector->use_digital = 1058 - !!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL); 1066 + drm_edid_is_digital(amdgpu_connector->edid); 1059 1067 1060 1068 /* some oems have boards with separate digital and analog connectors 1061 1069 * with a shared ddc line (often vga + hdmi) 1062 1070 */ 1063 1071 if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) { 1064 - amdgpu_connector_free_edid(connector); 1072 + drm_edid_free(amdgpu_connector->edid); 1065 1073 ret = connector_status_disconnected; 1066 1074 } else { 1067 1075 ret = connector_status_connected; ··· 1409 1417 goto out; 1410 1418 } 1411 1419 1412 - amdgpu_connector_free_edid(connector); 1420 + drm_edid_free(amdgpu_connector->edid); 1413 1421 1414 1422 if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || 1415 1423 (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
+53
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
··· 39 39 40 40 #include "amdgpu_reset.h" 41 41 #include "amdgpu_psp_ta.h" 42 + #include "amdgpu_userq.h" 42 43 43 44 #if defined(CONFIG_DEBUG_FS) 44 45 ··· 2157 2156 .release = single_release, 2158 2157 }; 2159 2158 2159 + static int amdgpu_mqd_info_read(struct seq_file *m, void *unused) 2160 + { 2161 + struct amdgpu_usermode_queue *queue = m->private; 2162 + struct amdgpu_bo *bo; 2163 + int r; 2164 + 2165 + if (!queue || !queue->mqd.obj) 2166 + return -EINVAL; 2167 + 2168 + bo = amdgpu_bo_ref(queue->mqd.obj); 2169 + r = amdgpu_bo_reserve(bo, true); 2170 + if (r) { 2171 + amdgpu_bo_unref(&bo); 2172 + return -EINVAL; 2173 + } 2174 + 2175 + seq_printf(m, "queue_type: %d\n", queue->queue_type); 2176 + seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj)); 2177 + 2178 + amdgpu_bo_unreserve(bo); 2179 + amdgpu_bo_unref(&bo); 2180 + 2181 + return 0; 2182 + } 2183 + 2184 + static int amdgpu_mqd_info_open(struct inode *inode, struct file *file) 2185 + { 2186 + return single_open(file, amdgpu_mqd_info_read, inode->i_private); 2187 + } 2188 + 2189 + static const struct file_operations amdgpu_mqd_info_fops = { 2190 + .owner = THIS_MODULE, 2191 + .open = amdgpu_mqd_info_open, 2192 + .read = seq_read, 2193 + .llseek = seq_lseek, 2194 + .release = single_release, 2195 + }; 2196 + 2197 + void amdgpu_debugfs_userq_init(struct drm_file *file, struct amdgpu_usermode_queue *queue, int qid) 2198 + { 2199 + char queue_name[32]; 2200 + 2201 + scnprintf(queue_name, sizeof(queue_name), "queue_%d", qid); 2202 + queue->debugfs_queue = debugfs_create_dir(queue_name, file->debugfs_client); 2203 + debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops); 2204 + } 2205 + 2160 2206 void amdgpu_debugfs_vm_init(struct drm_file *file) 2161 2207 { 2162 2208 debugfs_create_file("vm_pagetable_info", 0444, file->debugfs_client, file, ··· 2220 2172 return 0; 2221 2173 } 2222 2174 void amdgpu_debugfs_vm_init(struct drm_file *file) 2175 + { 2176 + } 2177 + void amdgpu_debugfs_userq_init(struct drm_file *file, 2178 + struct amdgpu_usermode_queue *queue, 2179 + int qid) 2223 2180 { 2224 2181 } 2225 2182 #endif
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h
··· 25 25 /* 26 26 * Debugfs 27 27 */ 28 + struct amdgpu_usermode_queue; 28 29 29 30 int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); 30 31 int amdgpu_debugfs_init(struct amdgpu_device *adev); ··· 35 34 void amdgpu_debugfs_gem_init(struct amdgpu_device *adev); 36 35 void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev); 37 36 void amdgpu_debugfs_vm_init(struct drm_file *file); 37 + void amdgpu_debugfs_userq_init(struct drm_file *file, 38 + struct amdgpu_usermode_queue *queue, 39 + int qid); 38 40
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
··· 261 261 } 262 262 } 263 263 264 + amdgpu_discovery_dump(coredump->adev, &p); 265 + 264 266 /* IP firmware information */ 265 267 drm_printf(&p, "\nIP Firmwares\n"); 266 268 amdgpu_devcoredump_fw_info(coredump->adev, &p);
+13 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 1995 1995 break; 1996 1996 default: 1997 1997 r = amdgpu_discovery_set_ip_blocks(adev); 1998 - if (r) 1998 + if (r) { 1999 + adev->num_ip_blocks = 0; 1999 2000 return r; 2001 + } 2000 2002 break; 2001 2003 } 2002 2004 ··· 2552 2550 i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; 2553 2551 if (!adev->ip_blocks[i].status.late_initialized) 2554 2552 continue; 2553 + if (!adev->ip_blocks[i].version) 2554 + continue; 2555 2555 /* skip CG for GFX, SDMA on S0ix */ 2556 2556 if (adev->in_s0ix && 2557 2557 (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || ··· 2592 2588 for (j = 0; j < adev->num_ip_blocks; j++) { 2593 2589 i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; 2594 2590 if (!adev->ip_blocks[i].status.late_initialized) 2591 + continue; 2592 + if (!adev->ip_blocks[i].version) 2595 2593 continue; 2596 2594 /* skip PG for GFX, SDMA on S0ix */ 2597 2595 if (adev->in_s0ix && ··· 2802 2796 int i, r; 2803 2797 2804 2798 for (i = 0; i < adev->num_ip_blocks; i++) { 2799 + if (!adev->ip_blocks[i].version) 2800 + continue; 2805 2801 if (!adev->ip_blocks[i].version->funcs->early_fini) 2806 2802 continue; 2807 2803 ··· 2881 2873 if (!adev->ip_blocks[i].status.sw) 2882 2874 continue; 2883 2875 2876 + if (!adev->ip_blocks[i].version) 2877 + continue; 2884 2878 if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { 2885 2879 amdgpu_ucode_free_bo(adev); 2886 2880 amdgpu_free_static_csa(&adev->virt.csa_obj); ··· 2908 2898 2909 2899 for (i = adev->num_ip_blocks - 1; i >= 0; i--) { 2910 2900 if (!adev->ip_blocks[i].status.late_initialized) 2901 + continue; 2902 + if (!adev->ip_blocks[i].version) 2911 2903 continue; 2912 2904 if (adev->ip_blocks[i].version->funcs->late_fini) 2913 2905 adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]);
+305 -224
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 87 87 #include "sdma_v7_1.h" 88 88 #include "lsdma_v6_0.h" 89 89 #include "lsdma_v7_0.h" 90 + #include "lsdma_v7_1.h" 90 91 #include "vcn_v2_0.h" 91 92 #include "jpeg_v2_0.h" 92 93 #include "vcn_v3_0.h" ··· 133 132 MODULE_FIRMWARE("amdgpu/arcturus_ip_discovery.bin"); 134 133 MODULE_FIRMWARE("amdgpu/aldebaran_ip_discovery.bin"); 135 134 135 + /* Note: These registers are consistent across all the SOCs */ 136 136 #define mmIP_DISCOVERY_VERSION 0x16A00 137 137 #define mmRCC_CONFIG_MEMSIZE 0xde3 138 138 #define mmMP0_SMN_C2PMSG_33 0x16061 139 139 #define mmMM_INDEX 0x0 140 140 #define mmMM_INDEX_HI 0x6 141 141 #define mmMM_DATA 0x1 142 + 143 + #define mmDRIVER_SCRATCH_0 0x94 144 + #define mmDRIVER_SCRATCH_1 0x95 145 + #define mmDRIVER_SCRATCH_2 0x96 142 146 143 147 static const char *hw_id_names[HW_ID_MAX] = { 144 148 [MP1_HWID] = "MP1", ··· 259 253 [ATU_HWIP] = ATU_HWID, 260 254 }; 261 255 262 - static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev, uint8_t *binary) 256 + static int amdgpu_discovery_get_tmr_info(struct amdgpu_device *adev, 257 + bool *is_tmr_in_sysmem) 263 258 { 264 - u64 tmr_offset, tmr_size, pos; 265 - void *discv_regn; 266 - int ret; 267 - 268 - ret = amdgpu_acpi_get_tmr_info(adev, &tmr_offset, &tmr_size); 269 - if (ret) 270 - return ret; 271 - 272 - pos = tmr_offset + tmr_size - DISCOVERY_TMR_OFFSET; 273 - 274 - /* This region is read-only and reserved from system use */ 275 - discv_regn = memremap(pos, adev->discovery.size, MEMREMAP_WC); 276 - if (discv_regn) { 277 - memcpy(binary, discv_regn, adev->discovery.size); 278 - memunmap(discv_regn); 279 - return 0; 280 - } 281 - 282 - return -ENOENT; 283 - } 284 - 285 - #define IP_DISCOVERY_V2 2 286 - #define IP_DISCOVERY_V4 4 287 - 288 - static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev, 289 - uint8_t *binary) 290 - { 291 - bool sz_valid = true; 292 - uint64_t vram_size; 293 - int i, ret = 0; 294 - u32 msg; 259 + u64 vram_size, tmr_offset, tmr_size; 260 + u32 msg, tmr_offset_lo, tmr_offset_hi; 261 + int i, ret; 295 262 296 263 if (!amdgpu_sriov_vf(adev)) { 297 264 /* It can take up to two second for IFWI init to complete on some dGPUs, ··· 284 305 } 285 306 286 307 vram_size = RREG32(mmRCC_CONFIG_MEMSIZE); 287 - if (!vram_size || vram_size == U32_MAX) 288 - sz_valid = false; 308 + if (vram_size == U32_MAX) 309 + return -ENXIO; 310 + else if (!vram_size) 311 + *is_tmr_in_sysmem = true; 289 312 else 290 - vram_size <<= 20; 313 + *is_tmr_in_sysmem = false; 291 314 292 - /* 293 - * If in VRAM, discovery TMR is marked for reservation. If it is in system mem, 294 - * then it is not required to be reserved. 295 - */ 296 - if (sz_valid) { 297 - if (amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled) { 298 - /* For SRIOV VFs with dynamic critical region enabled, 299 - * we will get the IPD binary via below call. 300 - * If dynamic critical is disabled, fall through to normal seq. 301 - */ 302 - if (amdgpu_virt_get_dynamic_data_info(adev, 303 - AMD_SRIOV_MSG_IPD_TABLE_ID, binary, 304 - &adev->discovery.size)) { 305 - dev_err(adev->dev, 306 - "failed to read discovery info from dynamic critical region."); 307 - ret = -EINVAL; 308 - goto exit; 309 - } 315 + /* init the default tmr size and offset */ 316 + adev->discovery.size = DISCOVERY_TMR_SIZE; 317 + if (vram_size) 318 + adev->discovery.offset = (vram_size << 20) - DISCOVERY_TMR_OFFSET; 319 + 320 + if (amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled) { 321 + adev->discovery.offset = 322 + adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].offset; 323 + adev->discovery.size = 324 + adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb << 10; 325 + if (!adev->discovery.offset || !adev->discovery.size) 326 + return -EINVAL; 327 + } else { 328 + tmr_size = RREG32(mmDRIVER_SCRATCH_2); 329 + if (tmr_size) { 330 + /* It's preferred to transition to PSP mailbox reg interface 331 + * for both bare-metal and passthrough if available */ 332 + adev->discovery.size = (u32)tmr_size; 333 + tmr_offset_lo = RREG32(mmDRIVER_SCRATCH_0); 334 + tmr_offset_hi = RREG32(mmDRIVER_SCRATCH_1); 335 + adev->discovery.offset = ((u64)le32_to_cpu(tmr_offset_hi) << 32 | 336 + le32_to_cpu(tmr_offset_lo)); 337 + } else if (!vram_size) { 338 + /* fall back to apci approach to query tmr offset if vram_size is 0 */ 339 + ret = amdgpu_acpi_get_tmr_info(adev, &tmr_offset, &tmr_size); 340 + if (ret) 341 + return ret; 342 + adev->discovery.size = (u32)tmr_size; 343 + adev->discovery.offset = tmr_offset + tmr_size - DISCOVERY_TMR_OFFSET; 344 + } 345 + } 346 + 347 + adev->discovery.bin = kzalloc(adev->discovery.size, GFP_KERNEL); 348 + if (!adev->discovery.bin) 349 + return -ENOMEM; 350 + adev->discovery.debugfs_blob.data = adev->discovery.bin; 351 + adev->discovery.debugfs_blob.size = adev->discovery.size; 352 + 353 + return 0; 354 + } 355 + 356 + static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev, uint8_t *binary) 357 + { 358 + void *discv_regn; 359 + 360 + /* This region is read-only and reserved from system use */ 361 + discv_regn = memremap(adev->discovery.offset, adev->discovery.size, MEMREMAP_WC); 362 + if (discv_regn) { 363 + memcpy(binary, discv_regn, adev->discovery.size); 364 + memunmap(discv_regn); 365 + return 0; 366 + } 367 + 368 + return -ENOENT; 369 + } 370 + 371 + #define IP_DISCOVERY_V2 2 372 + #define IP_DISCOVERY_V4 4 373 + 374 + static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev, 375 + uint8_t *binary, 376 + bool is_tmr_in_sysmem) 377 + { 378 + int ret = 0; 379 + 380 + if (!is_tmr_in_sysmem) { 381 + if (amdgpu_sriov_vf(adev) && 382 + amdgpu_sriov_xgmi_connected_to_cpu(adev)) { 383 + ret = amdgpu_discovery_read_binary_from_sysmem(adev, binary); 310 384 } else { 311 - uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET; 312 - 313 - amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, 314 - adev->discovery.size, false); 385 + amdgpu_device_vram_access(adev, adev->discovery.offset, 386 + (uint32_t *)binary, 387 + adev->discovery.size, false); 315 388 adev->discovery.reserve_tmr = true; 316 389 } 317 390 } else { 318 391 ret = amdgpu_discovery_read_binary_from_sysmem(adev, binary); 319 392 } 320 393 321 - if (ret) 322 - dev_err(adev->dev, 323 - "failed to read discovery info from memory, vram size read: %llx", 324 - vram_size); 325 - exit: 326 394 return ret; 327 395 } 328 396 329 397 static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, 330 - uint8_t *binary, 331 - const char *fw_name) 398 + uint8_t *binary, 399 + const char *fw_name) 332 400 { 333 401 const struct firmware *fw; 334 402 int r; ··· 457 431 } 458 432 459 433 static int amdgpu_discovery_verify_npsinfo(struct amdgpu_device *adev, 460 - struct binary_header *bhdr) 434 + struct table_info *info) 461 435 { 462 436 uint8_t *discovery_bin = adev->discovery.bin; 463 - struct table_info *info; 464 437 uint16_t checksum; 465 438 uint16_t offset; 466 439 467 - info = &bhdr->table_list[NPS_INFO]; 468 440 offset = le16_to_cpu(info->offset); 469 441 checksum = le16_to_cpu(info->checksum); 470 442 ··· 515 491 } 516 492 } 517 493 494 + static int amdgpu_discovery_get_table_info(struct amdgpu_device *adev, 495 + struct table_info **info, 496 + uint16_t table_id) 497 + { 498 + struct binary_header *bhdr = 499 + (struct binary_header *)adev->discovery.bin; 500 + struct binary_header_v2 *bhdrv2; 501 + 502 + switch (bhdr->version_major) { 503 + case 2: 504 + bhdrv2 = (struct binary_header_v2 *)adev->discovery.bin; 505 + *info = &bhdrv2->table_list[table_id]; 506 + break; 507 + case 1: 508 + *info = &bhdr->table_list[table_id]; 509 + break; 510 + default: 511 + dev_err(adev->dev, "Invalid ip discovery table version\n"); 512 + return -EINVAL; 513 + } 514 + 515 + return 0; 516 + } 517 + 518 + static int amdgpu_discovery_table_check(struct amdgpu_device *adev, 519 + uint8_t *discovery_bin, 520 + uint16_t table_id) 521 + { 522 + int r, act_val, exp_val, table_size; 523 + uint16_t offset, checksum; 524 + struct table_info *info; 525 + bool check_table = true; 526 + char *table_name; 527 + 528 + r = amdgpu_discovery_get_table_info(adev, &info, table_id); 529 + if (r) 530 + return r; 531 + offset = le16_to_cpu(info->offset); 532 + checksum = le16_to_cpu(info->checksum); 533 + 534 + switch (table_id) { 535 + case IP_DISCOVERY: 536 + struct ip_discovery_header *ihdr = 537 + (struct ip_discovery_header *)(discovery_bin + offset); 538 + act_val = le32_to_cpu(ihdr->signature); 539 + exp_val = DISCOVERY_TABLE_SIGNATURE; 540 + table_size = le16_to_cpu(ihdr->size); 541 + table_name = "data table"; 542 + break; 543 + case GC: 544 + struct gpu_info_header *ghdr = 545 + (struct gpu_info_header *)(discovery_bin + offset); 546 + act_val = le32_to_cpu(ghdr->table_id); 547 + exp_val = GC_TABLE_ID; 548 + table_size = le16_to_cpu(ghdr->size); 549 + table_name = "gc table"; 550 + break; 551 + case HARVEST_INFO: 552 + struct harvest_info_header *hhdr = 553 + (struct harvest_info_header *)(discovery_bin + offset); 554 + act_val = le32_to_cpu(hhdr->signature); 555 + exp_val = HARVEST_TABLE_SIGNATURE; 556 + table_size = sizeof(struct harvest_table); 557 + table_name = "harvest table"; 558 + break; 559 + case VCN_INFO: 560 + struct vcn_info_header *vhdr = 561 + (struct vcn_info_header *)(discovery_bin + offset); 562 + act_val = le32_to_cpu(vhdr->table_id); 563 + exp_val = VCN_INFO_TABLE_ID; 564 + table_size = le32_to_cpu(vhdr->size_bytes); 565 + table_name = "vcn table"; 566 + break; 567 + case MALL_INFO: 568 + struct mall_info_header *mhdr = 569 + (struct mall_info_header *)(discovery_bin + offset); 570 + act_val = le32_to_cpu(mhdr->table_id); 571 + exp_val = MALL_INFO_TABLE_ID; 572 + table_size = le32_to_cpu(mhdr->size_bytes); 573 + table_name = "mall table"; 574 + check_table = false; 575 + break; 576 + default: 577 + dev_err(adev->dev, "invalid ip discovery table id %d specified\n", table_id); 578 + check_table = false; 579 + break; 580 + } 581 + 582 + if (check_table && offset) { 583 + if (act_val != exp_val) { 584 + dev_err(adev->dev, "invalid ip discovery %s signature\n", table_name); 585 + return -EINVAL; 586 + } 587 + 588 + if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset, 589 + table_size, checksum)) { 590 + dev_err(adev->dev, "invalid ip discovery %s checksum\n", table_name); 591 + return -EINVAL; 592 + } 593 + } 594 + 595 + return 0; 596 + } 597 + 518 598 static int amdgpu_discovery_init(struct amdgpu_device *adev) 519 599 { 520 - struct table_info *info; 521 600 struct binary_header *bhdr; 522 601 uint8_t *discovery_bin; 523 602 const char *fw_name; 524 603 uint16_t offset; 525 604 uint16_t size; 526 605 uint16_t checksum; 606 + uint16_t table_id; 607 + bool is_tmr_in_sysmem; 527 608 int r; 528 609 529 - adev->discovery.bin = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL); 530 - if (!adev->discovery.bin) 531 - return -ENOMEM; 532 - adev->discovery.size = DISCOVERY_TMR_SIZE; 533 - adev->discovery.debugfs_blob.data = adev->discovery.bin; 534 - adev->discovery.debugfs_blob.size = adev->discovery.size; 610 + r = amdgpu_discovery_get_tmr_info(adev, &is_tmr_in_sysmem); 611 + if (r) 612 + return r; 535 613 536 614 discovery_bin = adev->discovery.bin; 537 615 /* Read from file if it is the preferred option */ ··· 646 520 goto out; 647 521 } else { 648 522 drm_dbg(&adev->ddev, "use ip discovery information from memory"); 649 - r = amdgpu_discovery_read_binary_from_mem(adev, discovery_bin); 523 + r = amdgpu_discovery_read_binary_from_mem(adev, discovery_bin, 524 + is_tmr_in_sysmem); 650 525 if (r) 651 526 goto out; 652 527 } ··· 674 547 goto out; 675 548 } 676 549 677 - info = &bhdr->table_list[IP_DISCOVERY]; 678 - offset = le16_to_cpu(info->offset); 679 - checksum = le16_to_cpu(info->checksum); 680 - 681 - if (offset) { 682 - struct ip_discovery_header *ihdr = 683 - (struct ip_discovery_header *)(discovery_bin + offset); 684 - if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) { 685 - dev_err(adev->dev, "invalid ip discovery data table signature\n"); 686 - r = -EINVAL; 550 + for (table_id = 0; table_id <= MALL_INFO; table_id++) { 551 + r = amdgpu_discovery_table_check(adev, discovery_bin, table_id); 552 + if (r) 687 553 goto out; 688 - } 689 - 690 - if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset, 691 - le16_to_cpu(ihdr->size), 692 - checksum)) { 693 - dev_err(adev->dev, "invalid ip discovery data table checksum\n"); 694 - r = -EINVAL; 695 - goto out; 696 - } 697 - } 698 - 699 - info = &bhdr->table_list[GC]; 700 - offset = le16_to_cpu(info->offset); 701 - checksum = le16_to_cpu(info->checksum); 702 - 703 - if (offset) { 704 - struct gpu_info_header *ghdr = 705 - (struct gpu_info_header *)(discovery_bin + offset); 706 - 707 - if (le32_to_cpu(ghdr->table_id) != GC_TABLE_ID) { 708 - dev_err(adev->dev, "invalid ip discovery gc table id\n"); 709 - r = -EINVAL; 710 - goto out; 711 - } 712 - 713 - if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset, 714 - le32_to_cpu(ghdr->size), 715 - checksum)) { 716 - dev_err(adev->dev, "invalid gc data table checksum\n"); 717 - r = -EINVAL; 718 - goto out; 719 - } 720 - } 721 - 722 - info = &bhdr->table_list[HARVEST_INFO]; 723 - offset = le16_to_cpu(info->offset); 724 - checksum = le16_to_cpu(info->checksum); 725 - 726 - if (offset) { 727 - struct harvest_info_header *hhdr = 728 - (struct harvest_info_header *)(discovery_bin + offset); 729 - 730 - if (le32_to_cpu(hhdr->signature) != HARVEST_TABLE_SIGNATURE) { 731 - dev_err(adev->dev, "invalid ip discovery harvest table signature\n"); 732 - r = -EINVAL; 733 - goto out; 734 - } 735 - 736 - if (!amdgpu_discovery_verify_checksum(adev, 737 - discovery_bin + offset, 738 - sizeof(struct harvest_table), checksum)) { 739 - dev_err(adev->dev, "invalid harvest data table checksum\n"); 740 - r = -EINVAL; 741 - goto out; 742 - } 743 - } 744 - 745 - info = &bhdr->table_list[VCN_INFO]; 746 - offset = le16_to_cpu(info->offset); 747 - checksum = le16_to_cpu(info->checksum); 748 - 749 - if (offset) { 750 - struct vcn_info_header *vhdr = 751 - (struct vcn_info_header *)(discovery_bin + offset); 752 - 753 - if (le32_to_cpu(vhdr->table_id) != VCN_INFO_TABLE_ID) { 754 - dev_err(adev->dev, "invalid ip discovery vcn table id\n"); 755 - r = -EINVAL; 756 - goto out; 757 - } 758 - 759 - if (!amdgpu_discovery_verify_checksum(adev, 760 - discovery_bin + offset, 761 - le32_to_cpu(vhdr->size_bytes), checksum)) { 762 - dev_err(adev->dev, "invalid vcn data table checksum\n"); 763 - r = -EINVAL; 764 - goto out; 765 - } 766 - } 767 - 768 - info = &bhdr->table_list[MALL_INFO]; 769 - offset = le16_to_cpu(info->offset); 770 - checksum = le16_to_cpu(info->checksum); 771 - 772 - if (0 && offset) { 773 - struct mall_info_header *mhdr = 774 - (struct mall_info_header *)(discovery_bin + offset); 775 - 776 - if (le32_to_cpu(mhdr->table_id) != MALL_INFO_TABLE_ID) { 777 - dev_err(adev->dev, "invalid ip discovery mall table id\n"); 778 - r = -EINVAL; 779 - goto out; 780 - } 781 - 782 - if (!amdgpu_discovery_verify_checksum(adev, 783 - discovery_bin + offset, 784 - le32_to_cpu(mhdr->size_bytes), checksum)) { 785 - dev_err(adev->dev, "invalid mall data table checksum\n"); 786 - r = -EINVAL; 787 - goto out; 788 - } 789 554 } 790 555 791 556 return 0; ··· 789 770 uint32_t *umc_harvest_count) 790 771 { 791 772 uint8_t *discovery_bin = adev->discovery.bin; 792 - struct binary_header *bhdr; 773 + struct table_info *info; 793 774 struct harvest_table *harvest_info; 794 775 u16 offset; 795 776 int i; 796 - uint32_t umc_harvest_config = 0; 777 + u64 umc_harvest_config = 0; 797 778 798 - bhdr = (struct binary_header *)discovery_bin; 799 - offset = le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset); 779 + if (amdgpu_discovery_get_table_info(adev, &info, HARVEST_INFO)) 780 + return; 781 + offset = le16_to_cpu(info->offset); 800 782 801 783 if (!offset) { 802 784 dev_err(adev->dev, "invalid harvest table offset\n"); ··· 850 830 } 851 831 } 852 832 853 - adev->umc.active_mask = ((1 << adev->umc.node_inst_num) - 1) & 833 + adev->umc.active_mask = ((1ULL << adev->umc.node_inst_num) - 1ULL) & 854 834 ~umc_harvest_config; 855 835 } 856 836 ··· 1215 1195 ip_hw_instance->num_instance); 1216 1196 ip_hw_instance->num_base_addresses = ip->num_base_address; 1217 1197 1218 - for (kk = 0; kk < ip_hw_instance->num_base_addresses; kk++) { 1219 - if (reg_base_64) 1220 - ip_hw_instance->base_addr[kk] = 1221 - lower_32_bits(le64_to_cpu(ip->base_address_64[kk])) & 0x3FFFFFFF; 1222 - else 1223 - ip_hw_instance->base_addr[kk] = ip->base_address[kk]; 1224 - } 1198 + for (kk = 0; kk < ip_hw_instance->num_base_addresses; kk++) 1199 + ip_hw_instance->base_addr[kk] = ip->base_address[kk]; 1225 1200 1226 1201 kobject_init(&ip_hw_instance->kobj, &ip_hw_instance_ktype); 1227 1202 ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset; ··· 1239 1224 { 1240 1225 struct ip_discovery_top *ip_top = adev->discovery.ip_top; 1241 1226 uint8_t *discovery_bin = adev->discovery.bin; 1242 - struct binary_header *bhdr; 1227 + struct table_info *info; 1243 1228 struct ip_discovery_header *ihdr; 1244 1229 struct die_header *dhdr; 1245 1230 struct kset *die_kset = &ip_top->die_kset; ··· 1247 1232 size_t ip_offset; 1248 1233 int ii, res; 1249 1234 1250 - bhdr = (struct binary_header *)discovery_bin; 1235 + res = amdgpu_discovery_get_table_info(adev, &info, IP_DISCOVERY); 1236 + if (res) 1237 + return res; 1251 1238 ihdr = (struct ip_discovery_header 1252 1239 *)(discovery_bin + 1253 - le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset)); 1240 + le16_to_cpu(info->offset)); 1254 1241 num_dies = le16_to_cpu(ihdr->num_dies); 1255 1242 1256 1243 DRM_DEBUG("number of dies: %d\n", num_dies); ··· 1396 1379 kobject_put(&ip_top->kobj); 1397 1380 } 1398 1381 1382 + /* devcoredump support */ 1383 + void amdgpu_discovery_dump(struct amdgpu_device *adev, struct drm_printer *p) 1384 + { 1385 + struct ip_discovery_top *ip_top = adev->discovery.ip_top; 1386 + struct ip_die_entry *ip_die_entry; 1387 + struct list_head *el_die, *el_hw_id, *el_hw_inst; 1388 + struct ip_hw_id *hw_id; 1389 + struct kset *die_kset; 1390 + struct ip_hw_instance *ip_inst; 1391 + int i = 0, j; 1392 + 1393 + die_kset = &ip_top->die_kset; 1394 + 1395 + drm_printf(p, "\nHW IP Discovery\n"); 1396 + spin_lock(&die_kset->list_lock); 1397 + list_for_each(el_die, &die_kset->list) { 1398 + drm_printf(p, "die %d\n", i++); 1399 + ip_die_entry = to_ip_die_entry(list_to_kobj(el_die)); 1400 + 1401 + list_for_each(el_hw_id, &ip_die_entry->ip_kset.list) { 1402 + hw_id = to_ip_hw_id(list_to_kobj(el_hw_id)); 1403 + drm_printf(p, "hw_id %d %s\n", hw_id->hw_id, hw_id_names[hw_id->hw_id]); 1404 + 1405 + list_for_each(el_hw_inst, &hw_id->hw_id_kset.list) { 1406 + ip_inst = to_ip_hw_instance(list_to_kobj(el_hw_inst)); 1407 + drm_printf(p, "\tinstance %d\n", ip_inst->num_instance); 1408 + drm_printf(p, "\tmajor %d\n", ip_inst->major); 1409 + drm_printf(p, "\tminor %d\n", ip_inst->minor); 1410 + drm_printf(p, "\trevision %d\n", ip_inst->revision); 1411 + drm_printf(p, "\tharvest 0x%01X\n", ip_inst->harvest); 1412 + drm_printf(p, "\tnum_base_addresses %d\n", 1413 + ip_inst->num_base_addresses); 1414 + for (j = 0; j < ip_inst->num_base_addresses; j++) 1415 + drm_printf(p, "\tbase_addr[%d] 0x%08X\n", 1416 + j, ip_inst->base_addr[j]); 1417 + } 1418 + } 1419 + } 1420 + spin_unlock(&die_kset->list_lock); 1421 + } 1422 + 1423 + 1399 1424 /* ================================================== */ 1400 1425 1401 1426 static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) 1402 1427 { 1403 1428 uint8_t num_base_address, subrev, variant; 1404 - struct binary_header *bhdr; 1429 + struct table_info *info; 1405 1430 struct ip_discovery_header *ihdr; 1406 1431 struct die_header *dhdr; 1407 1432 uint8_t *discovery_bin; ··· 1468 1409 adev->sdma.sdma_mask = 0; 1469 1410 adev->vcn.inst_mask = 0; 1470 1411 adev->jpeg.inst_mask = 0; 1471 - bhdr = (struct binary_header *)discovery_bin; 1412 + r = amdgpu_discovery_get_table_info(adev, &info, IP_DISCOVERY); 1413 + if (r) 1414 + return r; 1472 1415 ihdr = (struct ip_discovery_header 1473 1416 *)(discovery_bin + 1474 - le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset)); 1417 + le16_to_cpu(info->offset)); 1475 1418 num_dies = le16_to_cpu(ihdr->num_dies); 1476 1419 1477 1420 DRM_DEBUG("number of dies: %d\n", num_dies); ··· 1646 1585 { 1647 1586 uint8_t *discovery_bin = adev->discovery.bin; 1648 1587 struct ip_discovery_header *ihdr; 1649 - struct binary_header *bhdr; 1588 + struct table_info *info; 1650 1589 int vcn_harvest_count = 0; 1651 1590 int umc_harvest_count = 0; 1652 - uint16_t offset, ihdr_ver; 1591 + uint16_t ihdr_ver; 1653 1592 1654 - bhdr = (struct binary_header *)discovery_bin; 1655 - offset = le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset); 1656 - ihdr = (struct ip_discovery_header *)(discovery_bin + offset); 1593 + if (amdgpu_discovery_get_table_info(adev, &info, IP_DISCOVERY)) 1594 + return; 1595 + ihdr = (struct ip_discovery_header *)(discovery_bin + 1596 + le16_to_cpu(info->offset)); 1657 1597 ihdr_ver = le16_to_cpu(ihdr->version); 1658 1598 /* 1659 1599 * Harvest table does not fit Navi1x and legacy GPUs, ··· 1702 1640 static int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev) 1703 1641 { 1704 1642 uint8_t *discovery_bin = adev->discovery.bin; 1705 - struct binary_header *bhdr; 1643 + struct table_info *info; 1706 1644 union gc_info *gc_info; 1707 1645 u16 offset; 1708 1646 ··· 1711 1649 return -EINVAL; 1712 1650 } 1713 1651 1714 - bhdr = (struct binary_header *)discovery_bin; 1715 - offset = le16_to_cpu(bhdr->table_list[GC].offset); 1652 + if (amdgpu_discovery_get_table_info(adev, &info, GC)) 1653 + return -EINVAL; 1654 + offset = le16_to_cpu(info->offset); 1716 1655 1717 1656 if (!offset) 1718 1657 return 0; ··· 1812 1749 static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev) 1813 1750 { 1814 1751 uint8_t *discovery_bin = adev->discovery.bin; 1815 - struct binary_header *bhdr; 1752 + struct table_info *info; 1816 1753 union mall_info *mall_info; 1817 1754 u32 u, mall_size_per_umc, m_s_present, half_use; 1818 1755 u64 mall_size; ··· 1823 1760 return -EINVAL; 1824 1761 } 1825 1762 1826 - bhdr = (struct binary_header *)discovery_bin; 1827 - offset = le16_to_cpu(bhdr->table_list[MALL_INFO].offset); 1763 + if (amdgpu_discovery_get_table_info(adev, &info, MALL_INFO)) 1764 + return -EINVAL; 1765 + offset = le16_to_cpu(info->offset); 1828 1766 1829 1767 if (!offset) 1830 1768 return 0; ··· 1870 1806 static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev) 1871 1807 { 1872 1808 uint8_t *discovery_bin = adev->discovery.bin; 1873 - struct binary_header *bhdr; 1809 + struct table_info *info; 1874 1810 union vcn_info *vcn_info; 1875 1811 u16 offset; 1876 1812 int v; ··· 1890 1826 return -EINVAL; 1891 1827 } 1892 1828 1893 - bhdr = (struct binary_header *)discovery_bin; 1894 - offset = le16_to_cpu(bhdr->table_list[VCN_INFO].offset); 1829 + if (amdgpu_discovery_get_table_info(adev, &info, VCN_INFO)) 1830 + return -EINVAL; 1831 + offset = le16_to_cpu(info->offset); 1895 1832 1896 1833 if (!offset) 1897 1834 return 0; ··· 1929 1864 uint64_t vram_size, pos, offset; 1930 1865 struct nps_info_header *nhdr; 1931 1866 struct binary_header bhdr; 1867 + struct binary_header_v2 bhdrv2; 1932 1868 uint16_t checksum; 1933 1869 1934 1870 vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; 1935 1871 pos = vram_size - DISCOVERY_TMR_OFFSET; 1936 1872 amdgpu_device_vram_access(adev, pos, &bhdr, sizeof(bhdr), false); 1937 1873 1938 - offset = le16_to_cpu(bhdr.table_list[NPS_INFO].offset); 1939 - checksum = le16_to_cpu(bhdr.table_list[NPS_INFO].checksum); 1874 + switch (bhdr.version_major) { 1875 + case 2: 1876 + amdgpu_device_vram_access(adev, pos, &bhdrv2, sizeof(bhdrv2), false); 1877 + offset = le16_to_cpu(bhdrv2.table_list[NPS_INFO].offset); 1878 + checksum = le16_to_cpu(bhdrv2.table_list[NPS_INFO].checksum); 1879 + break; 1880 + case 1: 1881 + offset = le16_to_cpu(bhdr.table_list[NPS_INFO].offset); 1882 + checksum = le16_to_cpu(bhdr.table_list[NPS_INFO].checksum); 1883 + break; 1884 + default: 1885 + return -EINVAL; 1886 + } 1940 1887 1941 1888 amdgpu_device_vram_access(adev, (pos + offset), nps_data, 1942 1889 sizeof(*nps_data), false); ··· 1971 1894 { 1972 1895 uint8_t *discovery_bin = adev->discovery.bin; 1973 1896 struct amdgpu_gmc_memrange *mem_ranges; 1974 - struct binary_header *bhdr; 1897 + struct table_info *info; 1975 1898 union nps_info *nps_info; 1976 1899 union nps_info nps_data; 1977 1900 u16 offset; ··· 1992 1915 return -EINVAL; 1993 1916 } 1994 1917 1995 - bhdr = (struct binary_header *)discovery_bin; 1996 - offset = le16_to_cpu(bhdr->table_list[NPS_INFO].offset); 1918 + if (amdgpu_discovery_get_table_info(adev, &info, NPS_INFO)) 1919 + return -EINVAL; 1920 + offset = le16_to_cpu(info->offset); 1997 1921 1998 1922 if (!offset) 1999 1923 return -ENOENT; 2000 1924 2001 1925 /* If verification fails, return as if NPS table doesn't exist */ 2002 - if (amdgpu_discovery_verify_npsinfo(adev, bhdr)) 1926 + if (amdgpu_discovery_verify_npsinfo(adev, info)) 2003 1927 return -ENOENT; 2004 1928 2005 1929 nps_info = (union nps_info *)(discovery_bin + offset); ··· 3303 3225 case IP_VERSION(7, 0, 0): 3304 3226 case IP_VERSION(7, 0, 1): 3305 3227 adev->lsdma.funcs = &lsdma_v7_0_funcs; 3228 + break; 3229 + case IP_VERSION(7, 1, 0): 3230 + adev->lsdma.funcs = &lsdma_v7_1_funcs; 3306 3231 break; 3307 3232 default: 3308 3233 break;
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
··· 30 30 #define DISCOVERY_TMR_OFFSET (64 << 10) 31 31 32 32 struct ip_discovery_top; 33 + struct drm_printer; 33 34 34 35 struct amdgpu_discovery_info { 35 36 struct debugfs_blob_wrapper debugfs_blob; 36 37 struct ip_discovery_top *ip_top; 38 + uint64_t offset; 37 39 uint32_t size; 38 40 uint8_t *bin; 39 41 bool reserve_tmr; ··· 48 46 uint32_t *nps_type, 49 47 struct amdgpu_gmc_memrange **ranges, 50 48 int *range_cnt, bool refresh); 49 + 50 + void amdgpu_discovery_dump(struct amdgpu_device *adev, struct drm_printer *p); 51 51 52 52 #endif /* __AMDGPU_DISCOVERY__ */
+3 -18
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
··· 1738 1738 stime, etime, mode); 1739 1739 } 1740 1740 1741 - static bool 1742 - amdgpu_display_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj) 1743 - { 1744 - struct drm_device *dev = adev_to_drm(adev); 1745 - struct drm_fb_helper *fb_helper = dev->fb_helper; 1746 - 1747 - if (!fb_helper || !fb_helper->buffer) 1748 - return false; 1749 - 1750 - if (gem_to_amdgpu_bo(fb_helper->buffer->gem) != robj) 1751 - return false; 1752 - 1753 - return true; 1754 - } 1755 - 1756 1741 int amdgpu_display_suspend_helper(struct amdgpu_device *adev) 1757 1742 { 1758 1743 struct drm_device *dev = adev_to_drm(adev); ··· 1760 1775 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1761 1776 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1762 1777 struct drm_framebuffer *fb = crtc->primary->fb; 1763 - struct amdgpu_bo *robj; 1764 1778 1765 1779 if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { 1766 1780 struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); ··· 1774 1790 if (!fb || !fb->obj[0]) 1775 1791 continue; 1776 1792 1777 - robj = gem_to_amdgpu_bo(fb->obj[0]); 1778 - if (!amdgpu_display_robj_is_fb(adev, robj)) { 1793 + if (!drm_fb_helper_gem_is_fb(dev->fb_helper, fb->obj[0])) { 1794 + struct amdgpu_bo *robj = gem_to_amdgpu_bo(fb->obj[0]); 1795 + 1779 1796 r = amdgpu_bo_reserve(robj, true); 1780 1797 if (r == 0) { 1781 1798 amdgpu_bo_unpin(robj);
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
··· 94 94 #define AMDGPU_GMC9_FAULT_SOURCE_DATA_WRITE 0x20 95 95 #define AMDGPU_GMC9_FAULT_SOURCE_DATA_EXE 0x10 96 96 97 + #define AMDGPU_GMC121_FAULT_SOURCE_DATA_READ 0x400000 98 + #define AMDGPU_GMC121_FAULT_SOURCE_DATA_WRITE 0x200000 99 + #define AMDGPU_GMC121_FAULT_SOURCE_DATA_EXE 0x100000 100 + 97 101 /* 98 102 * GMC page fault information 99 103 */
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 83 83 { 84 84 struct amdgpu_device *adev = drm_to_adev(dev); 85 85 86 - if (adev == NULL) 86 + if (adev == NULL || !adev->num_ip_blocks) 87 87 return; 88 88 89 89 amdgpu_unregister_gpu_instance(adev);
+3 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
··· 159 159 160 160 int hung_queue_db_array_size; 161 161 int hung_queue_hqd_info_offset; 162 - struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_PIPES]; 163 - uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_PIPES]; 164 - void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_PIPES]; 162 + struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_INST_PIPES]; 163 + uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_INST_PIPES]; 164 + void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_INST_PIPES]; 165 165 166 166 /* cooperative dispatch */ 167 167 bool enable_coop_mode;
+9 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
··· 368 368 369 369 struct drm_property *plane_ctm_property; 370 370 /** 371 - * @shaper_lut_property: Plane property to set pre-blending shaper LUT 372 - * that converts color content before 3D LUT. If 373 - * plane_shaper_tf_property != Identity TF, AMD color module will 371 + * @plane_shaper_lut_property: Plane property to set pre-blending 372 + * shaper LUT that converts color content before 3D LUT. 373 + * If plane_shaper_tf_property != Identity TF, AMD color module will 374 374 * combine the user LUT values with pre-defined TF into the LUT 375 375 * parameters to be programmed. 376 376 */ 377 377 struct drm_property *plane_shaper_lut_property; 378 378 /** 379 - * @shaper_lut_size_property: Plane property for the size of 379 + * @plane_shaper_lut_size_property: Plane property for the size of 380 380 * pre-blending shaper LUT as supported by the driver (read-only). 381 381 */ 382 382 struct drm_property *plane_shaper_lut_size_property; ··· 400 400 */ 401 401 struct drm_property *plane_lut3d_property; 402 402 /** 403 - * @plane_degamma_lut_size_property: Plane property to define the max 404 - * size of 3D LUT as supported by the driver (read-only). The max size 405 - * is the max size of one dimension and, therefore, the max number of 406 - * entries for 3D LUT array is the 3D LUT size cubed; 403 + * @plane_lut3d_size_property: Plane property to define the max size 404 + * of 3D LUT as supported by the driver (read-only). The max size is 405 + * the max size of one dimension and, therefore, the max number of 406 + * entries for 3D LUT array is the 3D LUT size cubed. 407 407 */ 408 408 struct drm_property *plane_lut3d_size_property; 409 409 /** ··· 624 624 bool use_digital; 625 625 /* we need to mind the EDID between detect 626 626 and get modes due to analog/digital/tvencoder */ 627 - struct edid *edid; 627 + const struct drm_edid *edid; 628 628 void *con_priv; 629 629 bool dac_load_detect; 630 630 bool detected_by_load; /* if the connection status was determined by load */
+7
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 3096 3096 */ 3097 3097 continue; 3098 3098 3099 + /* IMU ucode is part of IFWI and MP0 15.0.8 would load it */ 3100 + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == 3101 + IP_VERSION(15, 0, 8) && 3102 + (ucode->ucode_id == AMDGPU_UCODE_ID_IMU_I || 3103 + ucode->ucode_id == AMDGPU_UCODE_ID_IMU_D)) 3104 + continue; 3105 + 3099 3106 psp_print_fw_hdr(psp, ucode); 3100 3107 3101 3108 ret = psp_execute_ip_fw_load(psp, ucode);
+8 -8
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
··· 291 291 break; 292 292 case 5: 293 293 /* rlc_hdr v2_5 */ 294 - DRM_INFO("rlc_iram_ucode_size_bytes: %u\n", 294 + DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n", 295 295 le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_size_bytes)); 296 - DRM_INFO("rlc_iram_ucode_offset_bytes: %u\n", 296 + DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n", 297 297 le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_offset_bytes)); 298 - DRM_INFO("rlc_dram_ucode_size_bytes: %u\n", 298 + DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n", 299 299 le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_size_bytes)); 300 - DRM_INFO("rlc_dram_ucode_offset_bytes: %u\n", 300 + DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n", 301 301 le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_offset_bytes)); 302 302 /* rlc_hdr v2_5 */ 303 - DRM_INFO("rlc_1_iram_ucode_size_bytes: %u\n", 303 + DRM_DEBUG("rlc_1_iram_ucode_size_bytes: %u\n", 304 304 le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_size_bytes)); 305 - DRM_INFO("rlc_1_iram_ucode_offset_bytes: %u\n", 305 + DRM_DEBUG("rlc_1_iram_ucode_offset_bytes: %u\n", 306 306 le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_offset_bytes)); 307 - DRM_INFO("rlc_1_dram_ucode_size_bytes: %u\n", 307 + DRM_DEBUG("rlc_1_dram_ucode_size_bytes: %u\n", 308 308 le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_size_bytes)); 309 - DRM_INFO("rlc_1_dram_ucode_offset_bytes: %u\n", 309 + DRM_DEBUG("rlc_1_dram_ucode_offset_bytes: %u\n", 310 310 le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_offset_bytes)); 311 311 break; 312 312 default:
+43 -92
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 709 709 return -EACCES; 710 710 } 711 711 712 - #if defined(CONFIG_DEBUG_FS) 713 - static int amdgpu_mqd_info_read(struct seq_file *m, void *unused) 714 - { 715 - struct amdgpu_usermode_queue *queue = m->private; 716 - struct amdgpu_bo *bo; 717 - int r; 718 - 719 - if (!queue || !queue->mqd.obj) 720 - return -EINVAL; 721 - 722 - bo = amdgpu_bo_ref(queue->mqd.obj); 723 - r = amdgpu_bo_reserve(bo, true); 724 - if (r) { 725 - amdgpu_bo_unref(&bo); 726 - return -EINVAL; 727 - } 728 - 729 - seq_printf(m, "queue_type: %d\n", queue->queue_type); 730 - seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj)); 731 - 732 - amdgpu_bo_unreserve(bo); 733 - amdgpu_bo_unref(&bo); 734 - 735 - return 0; 736 - } 737 - 738 - static int amdgpu_mqd_info_open(struct inode *inode, struct file *file) 739 - { 740 - return single_open(file, amdgpu_mqd_info_read, inode->i_private); 741 - } 742 - 743 - static const struct file_operations amdgpu_mqd_info_fops = { 744 - .owner = THIS_MODULE, 745 - .open = amdgpu_mqd_info_open, 746 - .read = seq_read, 747 - .llseek = seq_lseek, 748 - .release = single_release, 749 - }; 750 - #endif 751 - 752 712 static int 753 713 amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) 754 714 { ··· 718 758 const struct amdgpu_userq_funcs *uq_funcs; 719 759 struct amdgpu_usermode_queue *queue; 720 760 struct amdgpu_db_info db_info; 721 - char *queue_name; 722 761 bool skip_map_queue; 723 762 u32 qid; 724 763 uint64_t index; ··· 778 819 amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || 779 820 amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { 780 821 r = -EINVAL; 781 - kfree(queue); 782 - goto unlock; 822 + goto free_queue; 783 823 } 784 824 785 825 /* Convert relative doorbell offset into absolute doorbell index */ 786 826 index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp); 787 827 if (index == (uint64_t)-EINVAL) { 788 828 drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n"); 789 - kfree(queue); 790 829 r = -EINVAL; 791 - goto unlock; 830 + goto free_queue; 792 831 } 793 832 794 833 queue->doorbell_index = index; ··· 794 837 r = amdgpu_userq_fence_driver_alloc(adev, queue); 795 838 if (r) { 796 839 drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n"); 797 - goto unlock; 840 + goto free_queue; 798 841 } 799 842 800 843 r = uq_funcs->mqd_create(queue, &args->in); 801 844 if (r) { 802 845 drm_file_err(uq_mgr->file, "Failed to create Queue\n"); 803 - amdgpu_userq_fence_driver_free(queue); 804 - kfree(queue); 805 - goto unlock; 846 + goto clean_fence_driver; 806 847 } 807 - 808 - /* drop this refcount during queue destroy */ 809 - kref_init(&queue->refcount); 810 - 811 - /* Wait for mode-1 reset to complete */ 812 - down_read(&adev->reset_domain->sem); 813 - r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL)); 814 - if (r) { 815 - kfree(queue); 816 - up_read(&adev->reset_domain->sem); 817 - goto unlock; 818 - } 819 - 820 - r = xa_alloc(&uq_mgr->userq_xa, &qid, queue, 821 - XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL); 822 - if (r) { 823 - drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n"); 824 - amdgpu_userq_fence_driver_free(queue); 825 - uq_funcs->mqd_destroy(queue); 826 - kfree(queue); 827 - r = -ENOMEM; 828 - up_read(&adev->reset_domain->sem); 829 - goto unlock; 830 - } 831 - up_read(&adev->reset_domain->sem); 832 848 833 849 /* don't map the queue if scheduling is halted */ 834 850 if (adev->userq_halt_for_enforce_isolation && ··· 814 884 r = amdgpu_userq_map_helper(queue); 815 885 if (r) { 816 886 drm_file_err(uq_mgr->file, "Failed to map Queue\n"); 817 - xa_erase(&uq_mgr->userq_xa, qid); 818 - amdgpu_userq_fence_driver_free(queue); 819 - uq_funcs->mqd_destroy(queue); 820 - kfree(queue); 821 - goto unlock; 887 + down_read(&adev->reset_domain->sem); 888 + goto clean_mqd; 822 889 } 823 890 } 824 891 825 - queue_name = kasprintf(GFP_KERNEL, "queue-%d", qid); 826 - if (!queue_name) { 892 + /* drop this refcount during queue destroy */ 893 + kref_init(&queue->refcount); 894 + 895 + /* Wait for mode-1 reset to complete */ 896 + down_read(&adev->reset_domain->sem); 897 + 898 + r = xa_alloc(&uq_mgr->userq_xa, &qid, queue, 899 + XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL); 900 + if (r) { 901 + if (!skip_map_queue) 902 + amdgpu_userq_unmap_helper(queue); 903 + 827 904 r = -ENOMEM; 828 - goto unlock; 905 + goto clean_mqd; 829 906 } 830 907 831 - #if defined(CONFIG_DEBUG_FS) 832 - /* Queue dentry per client to hold MQD information */ 833 - queue->debugfs_queue = debugfs_create_dir(queue_name, filp->debugfs_client); 834 - debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops); 835 - #endif 908 + r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL)); 909 + if (r) { 910 + xa_erase(&uq_mgr->userq_xa, qid); 911 + if (!skip_map_queue) 912 + amdgpu_userq_unmap_helper(queue); 913 + 914 + goto clean_mqd; 915 + } 916 + up_read(&adev->reset_domain->sem); 917 + 918 + amdgpu_debugfs_userq_init(filp, queue, qid); 836 919 amdgpu_userq_init_hang_detect_work(queue); 837 - kfree(queue_name); 838 920 839 921 args->out.queue_id = qid; 840 922 atomic_inc(&uq_mgr->userq_count[queue->queue_type]); 923 + mutex_unlock(&uq_mgr->userq_mutex); 924 + return 0; 841 925 926 + clean_mqd: 927 + uq_funcs->mqd_destroy(queue); 928 + up_read(&adev->reset_domain->sem); 929 + clean_fence_driver: 930 + amdgpu_userq_fence_driver_free(queue); 931 + free_queue: 932 + kfree(queue); 842 933 unlock: 843 934 mutex_unlock(&uq_mgr->userq_mutex); 844 935 ··· 1040 1089 struct amdgpu_bo *bo; 1041 1090 int ret; 1042 1091 1043 - spin_lock(&vm->status_lock); 1092 + spin_lock(&vm->invalidated_lock); 1044 1093 while (!list_empty(&vm->invalidated)) { 1045 1094 bo_va = list_first_entry(&vm->invalidated, 1046 1095 struct amdgpu_bo_va, 1047 1096 base.vm_status); 1048 - spin_unlock(&vm->status_lock); 1097 + spin_unlock(&vm->invalidated_lock); 1049 1098 1050 1099 bo = bo_va->base.bo; 1051 1100 ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 2); ··· 1062 1111 if (ret) 1063 1112 return ret; 1064 1113 1065 - spin_lock(&vm->status_lock); 1114 + spin_lock(&vm->invalidated_lock); 1066 1115 } 1067 - spin_unlock(&vm->status_lock); 1116 + spin_unlock(&vm->invalidated_lock); 1068 1117 1069 1118 return 0; 1070 1119 }
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
··· 162 162 AMDGIM_FEATURE_RAS_TELEMETRY = (1 << 10), 163 163 AMDGIM_FEATURE_RAS_CPER = (1 << 11), 164 164 AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK = (1 << 12), 165 + AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU = (1 << 13), 165 166 }; 166 167 167 168 enum AMDGIM_REG_ACCESS_FLAG { ··· 412 411 413 412 #define amdgpu_sriov_xgmi_ta_ext_peer_link_en(adev) \ 414 413 ((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK) 414 + 415 + #define amdgpu_sriov_xgmi_connected_to_cpu(adev) \ 416 + ((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU) 415 417 416 418 static inline bool is_virtual_machine(void) 417 419 {
+55 -91
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 153 153 154 154 vm_bo->moved = true; 155 155 amdgpu_vm_assert_locked(vm); 156 - spin_lock(&vm_bo->vm->status_lock); 157 156 if (bo->tbo.type == ttm_bo_type_kernel) 158 157 list_move(&vm_bo->vm_status, &vm->evicted); 159 158 else 160 159 list_move_tail(&vm_bo->vm_status, &vm->evicted); 161 - spin_unlock(&vm_bo->vm->status_lock); 162 160 } 163 161 /** 164 162 * amdgpu_vm_bo_moved - vm_bo is moved ··· 169 171 static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo) 170 172 { 171 173 amdgpu_vm_assert_locked(vm_bo->vm); 172 - spin_lock(&vm_bo->vm->status_lock); 173 174 list_move(&vm_bo->vm_status, &vm_bo->vm->moved); 174 - spin_unlock(&vm_bo->vm->status_lock); 175 175 } 176 176 177 177 /** ··· 183 187 static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo) 184 188 { 185 189 amdgpu_vm_assert_locked(vm_bo->vm); 186 - spin_lock(&vm_bo->vm->status_lock); 187 190 list_move(&vm_bo->vm_status, &vm_bo->vm->idle); 188 - spin_unlock(&vm_bo->vm->status_lock); 189 191 vm_bo->moved = false; 190 192 } 191 193 ··· 197 203 */ 198 204 static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo) 199 205 { 200 - spin_lock(&vm_bo->vm->status_lock); 206 + spin_lock(&vm_bo->vm->invalidated_lock); 201 207 list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated); 202 - spin_unlock(&vm_bo->vm->status_lock); 208 + spin_unlock(&vm_bo->vm->invalidated_lock); 203 209 } 204 210 205 211 /** ··· 212 218 */ 213 219 static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo) 214 220 { 221 + amdgpu_vm_assert_locked(vm_bo->vm); 215 222 vm_bo->moved = true; 216 - spin_lock(&vm_bo->vm->status_lock); 217 223 list_move(&vm_bo->vm_status, &vm_bo->vm->evicted_user); 218 - spin_unlock(&vm_bo->vm->status_lock); 219 224 } 220 225 221 226 /** ··· 228 235 static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo) 229 236 { 230 237 amdgpu_vm_assert_locked(vm_bo->vm); 231 - if (vm_bo->bo->parent) { 232 - spin_lock(&vm_bo->vm->status_lock); 238 + if (vm_bo->bo->parent) 233 239 list_move(&vm_bo->vm_status, &vm_bo->vm->relocated); 234 - spin_unlock(&vm_bo->vm->status_lock); 235 - } else { 240 + else 236 241 amdgpu_vm_bo_idle(vm_bo); 237 - } 238 242 } 239 243 240 244 /** ··· 245 255 static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) 246 256 { 247 257 amdgpu_vm_assert_locked(vm_bo->vm); 248 - spin_lock(&vm_bo->vm->status_lock); 249 258 list_move(&vm_bo->vm_status, &vm_bo->vm->done); 250 - spin_unlock(&vm_bo->vm->status_lock); 251 259 } 252 260 253 261 /** ··· 259 271 { 260 272 struct amdgpu_vm_bo_base *vm_bo, *tmp; 261 273 262 - amdgpu_vm_assert_locked(vm); 263 - 264 - spin_lock(&vm->status_lock); 274 + spin_lock(&vm->invalidated_lock); 265 275 list_splice_init(&vm->done, &vm->invalidated); 266 276 list_for_each_entry(vm_bo, &vm->invalidated, vm_status) 267 277 vm_bo->moved = true; 278 + spin_unlock(&vm->invalidated_lock); 268 279 280 + amdgpu_vm_assert_locked(vm); 269 281 list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) { 270 282 struct amdgpu_bo *bo = vm_bo->bo; 271 283 ··· 275 287 else if (bo->parent) 276 288 list_move(&vm_bo->vm_status, &vm_bo->vm->relocated); 277 289 } 278 - spin_unlock(&vm->status_lock); 279 290 } 280 291 281 292 /** 282 293 * amdgpu_vm_update_shared - helper to update shared memory stat 283 294 * @base: base structure for tracking BO usage in a VM 284 295 * 285 - * Takes the vm status_lock and updates the shared memory stat. If the basic 296 + * Takes the vm stats_lock and updates the shared memory stat. If the basic 286 297 * stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called 287 298 * as well. 288 299 */ ··· 294 307 bool shared; 295 308 296 309 dma_resv_assert_held(bo->tbo.base.resv); 297 - spin_lock(&vm->status_lock); 310 + spin_lock(&vm->stats_lock); 298 311 shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); 299 312 if (base->shared != shared) { 300 313 base->shared = shared; ··· 306 319 vm->stats[bo_memtype].drm.private += size; 307 320 } 308 321 } 309 - spin_unlock(&vm->status_lock); 322 + spin_unlock(&vm->stats_lock); 310 323 } 311 324 312 325 /** ··· 331 344 * be bo->tbo.resource 332 345 * @sign: if we should add (+1) or subtract (-1) from the stat 333 346 * 334 - * Caller need to have the vm status_lock held. Useful for when multiple update 347 + * Caller need to have the vm stats_lock held. Useful for when multiple update 335 348 * need to happen at the same time. 336 349 */ 337 350 static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base, 338 - struct ttm_resource *res, int sign) 351 + struct ttm_resource *res, int sign) 339 352 { 340 353 struct amdgpu_vm *vm = base->vm; 341 354 struct amdgpu_bo *bo = base->bo; ··· 359 372 */ 360 373 if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) 361 374 vm->stats[res_memtype].drm.purgeable += size; 362 - if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(res_memtype))) 375 + if (!(bo->preferred_domains & 376 + amdgpu_mem_type_to_domain(res_memtype))) 363 377 vm->stats[bo_memtype].evicted += size; 364 378 } 365 379 } ··· 379 391 { 380 392 struct amdgpu_vm *vm = base->vm; 381 393 382 - spin_lock(&vm->status_lock); 394 + spin_lock(&vm->stats_lock); 383 395 amdgpu_vm_update_stats_locked(base, res, sign); 384 - spin_unlock(&vm->status_lock); 396 + spin_unlock(&vm->stats_lock); 385 397 } 386 398 387 399 /** ··· 407 419 base->next = bo->vm_bo; 408 420 bo->vm_bo = base; 409 421 410 - spin_lock(&vm->status_lock); 422 + spin_lock(&vm->stats_lock); 411 423 base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base); 412 424 amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1); 413 - spin_unlock(&vm->status_lock); 425 + spin_unlock(&vm->stats_lock); 414 426 415 427 if (!amdgpu_vm_is_bo_always_valid(vm, bo)) 416 428 return; ··· 469 481 int ret; 470 482 471 483 /* We can only trust prev->next while holding the lock */ 472 - spin_lock(&vm->status_lock); 484 + spin_lock(&vm->invalidated_lock); 473 485 while (!list_is_head(prev->next, &vm->done)) { 474 486 bo_va = list_entry(prev->next, typeof(*bo_va), base.vm_status); 475 487 476 488 bo = bo_va->base.bo; 477 489 if (bo) { 478 490 amdgpu_bo_ref(bo); 479 - spin_unlock(&vm->status_lock); 491 + spin_unlock(&vm->invalidated_lock); 480 492 481 493 ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 1); 482 494 amdgpu_bo_unref(&bo); 483 495 if (unlikely(ret)) 484 496 return ret; 485 497 486 - spin_lock(&vm->status_lock); 498 + spin_lock(&vm->invalidated_lock); 487 499 } 488 500 prev = prev->next; 489 501 } 490 - spin_unlock(&vm->status_lock); 502 + spin_unlock(&vm->invalidated_lock); 491 503 492 504 return 0; 493 505 } ··· 583 595 void *param) 584 596 { 585 597 uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm); 586 - struct amdgpu_vm_bo_base *bo_base; 598 + struct amdgpu_vm_bo_base *bo_base, *tmp; 587 599 struct amdgpu_bo *bo; 588 600 int r; 589 601 ··· 596 608 return r; 597 609 } 598 610 599 - spin_lock(&vm->status_lock); 600 - while (!list_empty(&vm->evicted)) { 601 - bo_base = list_first_entry(&vm->evicted, 602 - struct amdgpu_vm_bo_base, 603 - vm_status); 604 - spin_unlock(&vm->status_lock); 605 - 611 + list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { 606 612 bo = bo_base->bo; 607 613 608 614 r = validate(param, bo); ··· 609 627 vm->update_funcs->map_table(to_amdgpu_bo_vm(bo)); 610 628 amdgpu_vm_bo_relocated(bo_base); 611 629 } 612 - spin_lock(&vm->status_lock); 613 630 } 614 - while (ticket && !list_empty(&vm->evicted_user)) { 615 - bo_base = list_first_entry(&vm->evicted_user, 616 - struct amdgpu_vm_bo_base, 617 - vm_status); 618 - spin_unlock(&vm->status_lock); 619 631 620 - bo = bo_base->bo; 621 - dma_resv_assert_held(bo->tbo.base.resv); 632 + if (ticket) { 633 + list_for_each_entry_safe(bo_base, tmp, &vm->evicted_user, 634 + vm_status) { 635 + bo = bo_base->bo; 636 + dma_resv_assert_held(bo->tbo.base.resv); 622 637 623 - r = validate(param, bo); 624 - if (r) 625 - return r; 638 + r = validate(param, bo); 639 + if (r) 640 + return r; 626 641 627 - amdgpu_vm_bo_invalidated(bo_base); 628 - 629 - spin_lock(&vm->status_lock); 642 + amdgpu_vm_bo_invalidated(bo_base); 643 + } 630 644 } 631 - spin_unlock(&vm->status_lock); 632 645 633 646 amdgpu_vm_eviction_lock(vm); 634 647 vm->evicting = false; ··· 652 675 ret = !vm->evicting; 653 676 amdgpu_vm_eviction_unlock(vm); 654 677 655 - spin_lock(&vm->status_lock); 656 678 ret &= list_empty(&vm->evicted); 657 - spin_unlock(&vm->status_lock); 658 679 659 680 spin_lock(&vm->immediate.lock); 660 681 ret &= !vm->immediate.stopped; ··· 946 971 struct amdgpu_vm *vm, bool immediate) 947 972 { 948 973 struct amdgpu_vm_update_params params; 949 - struct amdgpu_vm_bo_base *entry; 974 + struct amdgpu_vm_bo_base *entry, *tmp; 950 975 bool flush_tlb_needed = false; 951 - LIST_HEAD(relocated); 952 976 int r, idx; 953 977 954 978 amdgpu_vm_assert_locked(vm); 955 979 956 - spin_lock(&vm->status_lock); 957 - list_splice_init(&vm->relocated, &relocated); 958 - spin_unlock(&vm->status_lock); 959 - 960 - if (list_empty(&relocated)) 980 + if (list_empty(&vm->relocated)) 961 981 return 0; 962 982 963 983 if (!drm_dev_enter(adev_to_drm(adev), &idx)) ··· 968 998 if (r) 969 999 goto error; 970 1000 971 - list_for_each_entry(entry, &relocated, vm_status) { 1001 + list_for_each_entry(entry, &vm->relocated, vm_status) { 972 1002 /* vm_flush_needed after updating moved PDEs */ 973 1003 flush_tlb_needed |= entry->moved; 974 1004 ··· 984 1014 if (flush_tlb_needed) 985 1015 atomic64_inc(&vm->tlb_seq); 986 1016 987 - while (!list_empty(&relocated)) { 988 - entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base, 989 - vm_status); 1017 + list_for_each_entry_safe(entry, tmp, &vm->relocated, vm_status) { 990 1018 amdgpu_vm_bo_idle(entry); 991 1019 } 992 1020 ··· 1211 1243 void amdgpu_vm_get_memory(struct amdgpu_vm *vm, 1212 1244 struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]) 1213 1245 { 1214 - spin_lock(&vm->status_lock); 1246 + spin_lock(&vm->stats_lock); 1215 1247 memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM); 1216 - spin_unlock(&vm->status_lock); 1248 + spin_unlock(&vm->stats_lock); 1217 1249 } 1218 1250 1219 1251 /** ··· 1580 1612 struct amdgpu_vm *vm, 1581 1613 struct ww_acquire_ctx *ticket) 1582 1614 { 1583 - struct amdgpu_bo_va *bo_va; 1615 + struct amdgpu_bo_va *bo_va, *tmp; 1584 1616 struct dma_resv *resv; 1585 1617 bool clear, unlock; 1586 1618 int r; 1587 1619 1588 - spin_lock(&vm->status_lock); 1589 - while (!list_empty(&vm->moved)) { 1590 - bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va, 1591 - base.vm_status); 1592 - spin_unlock(&vm->status_lock); 1593 - 1620 + list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) { 1594 1621 /* Per VM BOs never need to bo cleared in the page tables */ 1595 1622 r = amdgpu_vm_bo_update(adev, bo_va, false); 1596 1623 if (r) 1597 1624 return r; 1598 - spin_lock(&vm->status_lock); 1599 1625 } 1600 1626 1627 + spin_lock(&vm->invalidated_lock); 1601 1628 while (!list_empty(&vm->invalidated)) { 1602 1629 bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va, 1603 1630 base.vm_status); 1604 1631 resv = bo_va->base.bo->tbo.base.resv; 1605 - spin_unlock(&vm->status_lock); 1632 + spin_unlock(&vm->invalidated_lock); 1606 1633 1607 1634 /* Try to reserve the BO to avoid clearing its ptes */ 1608 1635 if (!adev->debug_vm && dma_resv_trylock(resv)) { ··· 1629 1666 bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM)) 1630 1667 amdgpu_vm_bo_evicted_user(&bo_va->base); 1631 1668 1632 - spin_lock(&vm->status_lock); 1669 + spin_lock(&vm->invalidated_lock); 1633 1670 } 1634 - spin_unlock(&vm->status_lock); 1671 + spin_unlock(&vm->invalidated_lock); 1635 1672 1636 1673 return 0; 1637 1674 } ··· 2174 2211 } 2175 2212 } 2176 2213 2177 - spin_lock(&vm->status_lock); 2214 + spin_lock(&vm->invalidated_lock); 2178 2215 list_del(&bo_va->base.vm_status); 2179 - spin_unlock(&vm->status_lock); 2216 + spin_unlock(&vm->invalidated_lock); 2180 2217 2181 2218 list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { 2182 2219 list_del(&mapping->list); ··· 2284 2321 for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) { 2285 2322 struct amdgpu_vm *vm = bo_base->vm; 2286 2323 2287 - spin_lock(&vm->status_lock); 2324 + spin_lock(&vm->stats_lock); 2288 2325 amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1); 2289 2326 amdgpu_vm_update_stats_locked(bo_base, new_mem, +1); 2290 - spin_unlock(&vm->status_lock); 2327 + spin_unlock(&vm->stats_lock); 2291 2328 } 2292 2329 2293 2330 amdgpu_vm_bo_invalidate(bo, evicted); ··· 2556 2593 INIT_LIST_HEAD(&vm->relocated); 2557 2594 INIT_LIST_HEAD(&vm->moved); 2558 2595 INIT_LIST_HEAD(&vm->idle); 2596 + spin_lock_init(&vm->invalidated_lock); 2559 2597 INIT_LIST_HEAD(&vm->invalidated); 2560 - spin_lock_init(&vm->status_lock); 2561 2598 INIT_LIST_HEAD(&vm->freed); 2562 2599 INIT_LIST_HEAD(&vm->done); 2563 2600 INIT_KFIFO(vm->faults); 2601 + spin_lock_init(&vm->stats_lock); 2564 2602 2565 2603 r = amdgpu_vm_init_entities(adev, vm); 2566 2604 if (r) ··· 3029 3065 3030 3066 amdgpu_vm_assert_locked(vm); 3031 3067 3032 - spin_lock(&vm->status_lock); 3033 3068 seq_puts(m, "\tIdle BOs:\n"); 3034 3069 list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { 3035 3070 if (!bo_va->base.bo) ··· 3066 3103 id = 0; 3067 3104 3068 3105 seq_puts(m, "\tInvalidated BOs:\n"); 3106 + spin_lock(&vm->invalidated_lock); 3069 3107 list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { 3070 3108 if (!bo_va->base.bo) 3071 3109 continue; 3072 3110 total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m); 3073 3111 } 3112 + spin_unlock(&vm->invalidated_lock); 3074 3113 total_invalidated_objs = id; 3075 3114 id = 0; 3076 3115 ··· 3082 3117 continue; 3083 3118 total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m); 3084 3119 } 3085 - spin_unlock(&vm->status_lock); 3086 3120 total_done_objs = id; 3087 3121 3088 3122 seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,
+9 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 205 205 /* protected by bo being reserved */ 206 206 struct amdgpu_vm_bo_base *next; 207 207 208 - /* protected by vm status_lock */ 208 + /* protected by vm reservation and invalidated_lock */ 209 209 struct list_head vm_status; 210 210 211 211 /* if the bo is counted as shared in mem stats 212 - * protected by vm status_lock */ 212 + * protected by vm BO being reserved */ 213 213 bool shared; 214 214 215 215 /* protected by the BO being reserved */ ··· 345 345 bool evicting; 346 346 unsigned int saved_flags; 347 347 348 - /* Lock to protect vm_bo add/del/move on all lists of vm */ 349 - spinlock_t status_lock; 350 - 351 - /* Memory statistics for this vm, protected by status_lock */ 348 + /* Memory statistics for this vm, protected by stats_lock */ 349 + spinlock_t stats_lock; 352 350 struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM]; 353 351 354 352 /* ··· 354 356 * PDs, PTs or per VM BOs. The state transits are: 355 357 * 356 358 * evicted -> relocated (PDs, PTs) or moved (per VM BOs) -> idle 359 + * 360 + * Lists are protected by the root PD dma_resv lock. 357 361 */ 358 362 359 363 /* Per-VM and PT BOs who needs a validation */ ··· 376 376 * state transits are: 377 377 * 378 378 * evicted_user or invalidated -> done 379 + * 380 + * Lists are protected by the invalidated_lock. 379 381 */ 382 + spinlock_t invalidated_lock; 380 383 381 384 /* BOs for user mode queues that need a validation */ 382 385 struct list_head evicted_user;
-4
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
··· 544 544 entry->bo->vm_bo = NULL; 545 545 ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); 546 546 547 - spin_lock(&entry->vm->status_lock); 548 547 list_del(&entry->vm_status); 549 - spin_unlock(&entry->vm->status_lock); 550 548 amdgpu_bo_unref(&entry->bo); 551 549 } 552 550 ··· 588 590 struct amdgpu_vm_pt_cursor seek; 589 591 struct amdgpu_vm_bo_base *entry; 590 592 591 - spin_lock(&params->vm->status_lock); 592 593 for_each_amdgpu_vm_pt_dfs_safe(params->adev, params->vm, cursor, seek, entry) { 593 594 if (entry && entry->bo) 594 595 list_move(&entry->vm_status, &params->tlb_flush_waitlist); ··· 595 598 596 599 /* enter start node now */ 597 600 list_move(&cursor->entry->vm_status, &params->tlb_flush_waitlist); 598 - spin_unlock(&params->vm->status_lock); 599 601 } 600 602 601 603 /**
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
··· 161 161 uint32_t ras_telemetry : 1; 162 162 uint32_t ras_cper : 1; 163 163 uint32_t xgmi_ta_ext_peer_link : 1; 164 - uint32_t reserved : 19; 164 + uint32_t xgmi_connected_to_cpu : 1; 165 + uint32_t reserved : 18; 165 166 } flags; 166 167 uint32_t all; 167 168 };
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
··· 1298 1298 return; 1299 1299 } 1300 1300 1301 - sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb); 1301 + sad_count = drm_edid_to_speaker_allocation(drm_edid_raw(amdgpu_connector->edid), &sadb); 1302 1302 if (sad_count < 0) { 1303 1303 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); 1304 1304 sad_count = 0; ··· 1368 1368 return; 1369 1369 } 1370 1370 1371 - sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads); 1371 + sad_count = drm_edid_to_sad(drm_edid_raw(amdgpu_connector->edid), &sads); 1372 1372 if (sad_count < 0) 1373 1373 DRM_ERROR("Couldn't read SADs: %d\n", sad_count); 1374 1374 if (sad_count <= 0)
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
··· 1265 1265 return; 1266 1266 } 1267 1267 1268 - sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb); 1268 + sad_count = drm_edid_to_speaker_allocation(drm_edid_raw(amdgpu_connector->edid), &sadb); 1269 1269 if (sad_count < 0) { 1270 1270 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); 1271 1271 sad_count = 0; ··· 1346 1346 return; 1347 1347 } 1348 1348 1349 - sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads); 1349 + sad_count = drm_edid_to_sad(drm_edid_raw(amdgpu_connector->edid), &sads); 1350 1350 if (sad_count < 0) 1351 1351 DRM_ERROR("Couldn't read SADs: %d\n", sad_count); 1352 1352 if (sad_count <= 0)
+2 -2
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
··· 1271 1271 return; 1272 1272 } 1273 1273 1274 - sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb); 1274 + sad_count = drm_edid_to_speaker_allocation(drm_edid_raw(amdgpu_connector->edid), &sadb); 1275 1275 if (sad_count < 0) { 1276 1276 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); 1277 1277 sad_count = 0; ··· 1339 1339 return; 1340 1340 } 1341 1341 1342 - sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads); 1342 + sad_count = drm_edid_to_sad(drm_edid_raw(amdgpu_connector->edid), &sads); 1343 1343 if (sad_count < 0) 1344 1344 DRM_ERROR("Couldn't read SADs: %d\n", sad_count); 1345 1345 if (sad_count <= 0)
+74 -33
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
··· 1155 1155 break; 1156 1156 } 1157 1157 1158 - /* recalculate compute rings to use based on hardware configuration */ 1159 - num_compute_rings = (adev->gfx.mec.num_pipe_per_mec * 1160 - adev->gfx.mec.num_queue_per_pipe) / 2; 1161 - adev->gfx.num_compute_rings = min(adev->gfx.num_compute_rings, 1162 - num_compute_rings); 1158 + if (adev->gfx.num_compute_rings) { 1159 + /* recalculate compute rings to use based on hardware configuration */ 1160 + num_compute_rings = (adev->gfx.mec.num_pipe_per_mec * 1161 + adev->gfx.mec.num_queue_per_pipe) / 2; 1162 + adev->gfx.num_compute_rings = min(adev->gfx.num_compute_rings, 1163 + num_compute_rings); 1164 + } 1163 1165 1164 1166 num_xcc = NUM_XCC(adev->gfx.xcc_mask); 1165 1167 ··· 2796 2794 gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id); 2797 2795 } 2798 2796 2797 + static int gfx_v12_1_set_userq_eop_interrupts(struct amdgpu_device *adev, 2798 + bool enable) 2799 + { 2800 + unsigned int irq_type; 2801 + int m, p, r; 2802 + 2803 + if (adev->gfx.disable_kq) { 2804 + for (m = 0; m < adev->gfx.mec.num_mec; ++m) { 2805 + for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) { 2806 + irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP 2807 + + (m * adev->gfx.mec.num_pipe_per_mec) 2808 + + p; 2809 + if (enable) 2810 + r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, 2811 + irq_type); 2812 + else 2813 + r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, 2814 + irq_type); 2815 + if (r) 2816 + return r; 2817 + } 2818 + } 2819 + } 2820 + 2821 + return 0; 2822 + } 2823 + 2799 2824 static int gfx_v12_1_hw_fini(struct amdgpu_ip_block *ip_block) 2800 2825 { 2801 2826 struct amdgpu_device *adev = ip_block->adev; ··· 2830 2801 2831 2802 amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); 2832 2803 amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); 2804 + gfx_v12_1_set_userq_eop_interrupts(adev, false); 2833 2805 2834 2806 num_xcc = NUM_XCC(adev->gfx.xcc_mask); 2835 2807 for (i = 0; i < num_xcc; i++) { ··· 2898 2868 { 2899 2869 struct amdgpu_device *adev = ip_block->adev; 2900 2870 2871 + 2872 + switch (amdgpu_user_queue) { 2873 + case -1: 2874 + default: 2875 + adev->gfx.disable_kq = true; 2876 + adev->gfx.disable_uq = true; 2877 + break; 2878 + case 0: 2879 + adev->gfx.disable_kq = false; 2880 + adev->gfx.disable_uq = true; 2881 + break; 2882 + } 2883 + 2901 2884 adev->gfx.funcs = &gfx_v12_1_gfx_funcs; 2902 2885 2903 - adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), 2904 - AMDGPU_MAX_COMPUTE_RINGS); 2886 + if (adev->gfx.disable_kq) 2887 + adev->gfx.num_compute_rings = 0; 2888 + else 2889 + adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev), 2890 + AMDGPU_MAX_COMPUTE_RINGS); 2905 2891 2906 2892 gfx_v12_1_set_kiq_pm4_funcs(adev); 2907 2893 gfx_v12_1_set_ring_funcs(adev); ··· 2941 2895 return r; 2942 2896 2943 2897 r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0); 2898 + if (r) 2899 + return r; 2900 + 2901 + r = gfx_v12_1_set_userq_eop_interrupts(adev, true); 2944 2902 if (r) 2945 2903 return r; 2946 2904 ··· 3680 3630 return -EINVAL; 3681 3631 3682 3632 switch (me_id) { 3683 - case 0: 3684 - if (pipe_id == 0) 3685 - amdgpu_fence_process(&adev->gfx.gfx_ring[0]); 3686 - else 3687 - amdgpu_fence_process(&adev->gfx.gfx_ring[1]); 3688 - break; 3689 3633 case 1: 3690 3634 case 2: 3691 3635 for (i = 0; i < adev->gfx.num_compute_rings; i++) { ··· 3695 3651 (ring->queue == queue_id)) 3696 3652 amdgpu_fence_process(ring); 3697 3653 } 3654 + break; 3655 + default: 3656 + dev_dbg(adev->dev, "Unexpected me %d in eop_irq\n", me_id); 3698 3657 break; 3699 3658 } 3700 3659 } ··· 3766 3719 if (xcc_id == -EINVAL) 3767 3720 return; 3768 3721 3769 - switch (me_id) { 3770 - case 0: 3771 - for (i = 0; i < adev->gfx.num_gfx_rings; i++) { 3772 - ring = &adev->gfx.gfx_ring[i]; 3773 - /* we only enabled 1 gfx queue per pipe for now */ 3774 - if (ring->me == me_id && ring->pipe == pipe_id) 3775 - drm_sched_fault(&ring->sched); 3776 - } 3777 - break; 3778 - case 1: 3779 - case 2: 3780 - for (i = 0; i < adev->gfx.num_compute_rings; i++) { 3781 - ring = &adev->gfx.compute_ring 3722 + if (!adev->gfx.disable_kq) { 3723 + switch (me_id) { 3724 + case 1: 3725 + case 2: 3726 + for (i = 0; i < adev->gfx.num_compute_rings; i++) { 3727 + ring = &adev->gfx.compute_ring 3782 3728 [i + 3783 3729 xcc_id * adev->gfx.num_compute_rings]; 3784 - if (ring->me == me_id && ring->pipe == pipe_id && 3785 - ring->queue == queue_id) 3786 - drm_sched_fault(&ring->sched); 3730 + if (ring->me == me_id && ring->pipe == pipe_id && 3731 + ring->queue == queue_id) 3732 + drm_sched_fault(&ring->sched); 3733 + } 3734 + break; 3735 + default: 3736 + dev_dbg(adev->dev, "Unexpected me %d in priv_fault\n", me_id); 3737 + break; 3787 3738 } 3788 - break; 3789 - default: 3790 - BUG(); 3791 - break; 3792 3739 } 3793 3740 } 3794 3741
+1 -1
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 2355 2355 for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) { 2356 2356 ring = &adev->gfx.sw_gfx_ring[i]; 2357 2357 ring->ring_obj = NULL; 2358 - sprintf(ring->name, amdgpu_sw_ring_name(i)); 2358 + strscpy(ring->name, amdgpu_sw_ring_name(i), sizeof(ring->name)); 2359 2359 ring->use_doorbell = true; 2360 2360 ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1; 2361 2361 ring->is_sw_ring = true;
+1 -1
drivers/gpu/drm/amd/amdgpu/gmc_v12_1.c
··· 121 121 122 122 if (entry->src_id == UTCL2_1_0__SRCID__RETRY) { 123 123 retry_fault = true; 124 - write_fault = !!(entry->src_data[1] & 0x200000); 124 + write_fault = !!(entry->src_data[1] & AMDGPU_GMC121_FAULT_SOURCE_DATA_WRITE); 125 125 } 126 126 127 127 if (entry->client_id == SOC_V1_0_IH_CLIENTID_VMC) {
+29 -7
drivers/gpu/drm/amd/amdgpu/ih_v7_0.c
··· 289 289 return val; 290 290 } 291 291 292 + #define regIH_RING1_CLIENT_CFG_INDEX_V7_1 0x122 293 + #define regIH_RING1_CLIENT_CFG_INDEX_V7_1_BASE_IDX 0 294 + #define regIH_RING1_CLIENT_CFG_DATA_V7_1 0x123 295 + #define regIH_RING1_CLIENT_CFG_DATA_V7_1_BASE_IDX 0 296 + #define regIH_CHICKEN_V7_1 0x129 297 + #define regIH_CHICKEN_V7_1_BASE_IDX 0 298 + 292 299 /** 293 300 * ih_v7_0_irq_init - init and enable the interrupt ring 294 301 * ··· 314 307 u32 tmp; 315 308 int ret; 316 309 int i; 310 + u32 reg_addr; 317 311 318 312 /* disable irqs */ 319 313 ret = ih_v7_0_toggle_interrupts(adev, false); ··· 326 318 if (unlikely((adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) || 327 319 (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO))) { 328 320 if (ih[0]->use_bus_addr) { 329 - ih_chicken = RREG32_SOC15(OSSSYS, 0, regIH_CHICKEN); 321 + if (amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(7, 1, 0)) 322 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_CHICKEN_V7_1); 323 + else 324 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_CHICKEN); 325 + ih_chicken = RREG32(reg_addr); 326 + /* The reg fields definitions are identical in ih v7_0 and ih v7_1 */ 330 327 ih_chicken = REG_SET_FIELD(ih_chicken, 331 328 IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1); 332 - WREG32_SOC15(OSSSYS, 0, regIH_CHICKEN, ih_chicken); 329 + WREG32(reg_addr, ih_chicken); 333 330 } 334 331 } 335 332 ··· 371 358 372 359 /* Redirect the interrupts to IH RB1 for dGPU */ 373 360 if (adev->irq.ih1.ring_size) { 374 - tmp = RREG32_SOC15(OSSSYS, 0, regIH_RING1_CLIENT_CFG_INDEX); 361 + if (amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(7, 1, 0)) 362 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_RING1_CLIENT_CFG_INDEX_V7_1); 363 + else 364 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_RING1_CLIENT_CFG_INDEX); 365 + tmp = RREG32(reg_addr); 366 + /* The reg fields definitions are identical in ih v7_0 and ih v7_1 */ 375 367 tmp = REG_SET_FIELD(tmp, IH_RING1_CLIENT_CFG_INDEX, INDEX, 0); 376 - WREG32_SOC15(OSSSYS, 0, regIH_RING1_CLIENT_CFG_INDEX, tmp); 368 + WREG32(reg_addr, tmp); 377 369 378 - tmp = RREG32_SOC15(OSSSYS, 0, regIH_RING1_CLIENT_CFG_DATA); 370 + if (amdgpu_ip_version(adev, OSSSYS_HWIP, 0) == IP_VERSION(7, 1, 0)) 371 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_RING1_CLIENT_CFG_DATA_V7_1); 372 + else 373 + reg_addr = SOC15_REG_OFFSET(OSSSYS, 0, regIH_RING1_CLIENT_CFG_DATA); 374 + tmp = RREG32(reg_addr); 375 + /* The reg fields definitions are identical in ih v7_0 and ih v7_1 */ 379 376 tmp = REG_SET_FIELD(tmp, IH_RING1_CLIENT_CFG_DATA, CLIENT_ID, 0xa); 380 377 tmp = REG_SET_FIELD(tmp, IH_RING1_CLIENT_CFG_DATA, SOURCE_ID, 0x0); 381 378 tmp = REG_SET_FIELD(tmp, IH_RING1_CLIENT_CFG_DATA, 382 379 SOURCE_ID_MATCH_ENABLE, 0x1); 383 - 384 - WREG32_SOC15(OSSSYS, 0, regIH_RING1_CLIENT_CFG_DATA, tmp); 380 + WREG32(reg_addr, tmp); 385 381 } 386 382 387 383 pci_set_master(adev->pdev);
+99
drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.c
··· 1 + /* 2 + * Copyright 2026 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + */ 23 + 24 + #include <linux/delay.h> 25 + #include "amdgpu.h" 26 + #include "lsdma_v7_1.h" 27 + #include "amdgpu_lsdma.h" 28 + 29 + #include "lsdma/lsdma_7_1_0_offset.h" 30 + #include "lsdma/lsdma_7_1_0_sh_mask.h" 31 + 32 + static int lsdma_v7_1_wait_pio_status(struct amdgpu_device *adev) 33 + { 34 + return amdgpu_lsdma_wait_for(adev, SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS), 35 + LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK, 36 + LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK); 37 + } 38 + 39 + static int lsdma_v7_1_copy_mem(struct amdgpu_device *adev, 40 + uint64_t src_addr, 41 + uint64_t dst_addr, 42 + uint64_t size) 43 + { 44 + int ret; 45 + uint32_t tmp; 46 + 47 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_SRC_ADDR_LO, lower_32_bits(src_addr)); 48 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_SRC_ADDR_HI, upper_32_bits(src_addr)); 49 + 50 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_LO, lower_32_bits(dst_addr)); 51 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_HI, upper_32_bits(dst_addr)); 52 + 53 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONTROL, 0x0); 54 + 55 + tmp = RREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND); 56 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, COUNT, size); 57 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, RAW_WAIT, 0); 58 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, CONSTANT_FILL, 0); 59 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND, tmp); 60 + 61 + ret = lsdma_v7_1_wait_pio_status(adev); 62 + if (ret) 63 + dev_err(adev->dev, "LSDMA PIO failed to copy memory!\n"); 64 + 65 + return ret; 66 + } 67 + 68 + static int lsdma_v7_1_fill_mem(struct amdgpu_device *adev, 69 + uint64_t dst_addr, 70 + uint32_t data, 71 + uint64_t size) 72 + { 73 + int ret; 74 + uint32_t tmp; 75 + 76 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONSTFILL_DATA, data); 77 + 78 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_LO, lower_32_bits(dst_addr)); 79 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_HI, upper_32_bits(dst_addr)); 80 + 81 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONTROL, 0x0); 82 + 83 + tmp = RREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND); 84 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, COUNT, size); 85 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, RAW_WAIT, 0); 86 + tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, CONSTANT_FILL, 1); 87 + WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND, tmp); 88 + 89 + ret = lsdma_v7_1_wait_pio_status(adev); 90 + if (ret) 91 + dev_err(adev->dev, "LSDMA PIO failed to fill memory!\n"); 92 + 93 + return ret; 94 + } 95 + 96 + const struct amdgpu_lsdma_funcs lsdma_v7_1_funcs = { 97 + .copy_mem = lsdma_v7_1_copy_mem, 98 + .fill_mem = lsdma_v7_1_fill_mem, 99 + };
+31
drivers/gpu/drm/amd/amdgpu/lsdma_v7_1.h
··· 1 + /* 2 + * Copyright 2026 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + */ 23 + 24 + #ifndef __LSDMA_V7_1_H__ 25 + #define __LSDMA_V7_1_H__ 26 + 27 + #include "soc15_common.h" 28 + 29 + extern const struct amdgpu_lsdma_funcs lsdma_v7_1_funcs; 30 + 31 + #endif /* __LSDMA_V7_1_H__ */
+4 -1
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
··· 731 731 int i; 732 732 struct amdgpu_device *adev = mes->adev; 733 733 union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; 734 + uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ? 735 + (mes->sched_version & AMDGPU_MES_VERSION_MASK) : 736 + (mes->kiq_version & AMDGPU_MES_VERSION_MASK); 734 737 735 738 memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); 736 739 ··· 788 785 * handling support, other queue will not use the oversubscribe timer. 789 786 * handling mode - 0: disabled; 1: basic version; 2: basic+ version 790 787 */ 791 - mes_set_hw_res_pkt.oversubscription_timer = 50; 788 + mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50; 792 789 mes_set_hw_res_pkt.unmapped_doorbell_handling = 1; 793 790 794 791 if (amdgpu_mes_log_enable) {
+3 -1
drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
··· 1611 1611 amdgpu_bo_free_kernel(&adev->mes.eop_gpu_obj[inst], 1612 1612 &adev->mes.eop_gpu_addr[inst], 1613 1613 NULL); 1614 - amdgpu_ucode_release(&adev->mes.fw[inst]); 1615 1614 1616 1615 if (adev->enable_uni_mes || pipe == AMDGPU_MES_SCHED_PIPE) { 1617 1616 amdgpu_bo_free_kernel(&adev->mes.ring[inst].mqd_obj, ··· 1620 1621 } 1621 1622 } 1622 1623 } 1624 + 1625 + for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) 1626 + amdgpu_ucode_release(&adev->mes.fw[pipe]); 1623 1627 1624 1628 for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) { 1625 1629 if (!adev->enable_uni_mes) {
+1 -1
drivers/gpu/drm/amd/amdgpu/soc24.c
··· 478 478 if (adev->nbio.funcs->remap_hdp_registers) 479 479 adev->nbio.funcs->remap_hdp_registers(adev); 480 480 481 - if (adev->df.funcs->hw_init) 481 + if (adev->df.funcs && adev->df.funcs->hw_init) 482 482 adev->df.funcs->hw_init(adev); 483 483 484 484 /* enable the doorbell aperture */
+34 -18
drivers/gpu/drm/amd/amdgpu/soc_v1_0.c
··· 57 57 adev->doorbell_index.userqueue_end = AMDGPU_SOC_V1_0_DOORBELL_USERQUEUE_END; 58 58 adev->doorbell_index.xcc_doorbell_range = AMDGPU_SOC_V1_0_DOORBELL_XCC_RANGE; 59 59 60 - adev->doorbell_index.sdma_doorbell_range = 20; 60 + adev->doorbell_index.sdma_doorbell_range = 14; 61 61 for (i = 0; i < adev->sdma.num_instances; i++) 62 62 adev->doorbell_index.sdma_engine[i] = 63 63 AMDGPU_SOC_V1_0_DOORBELL_sDMA_ENGINE_START + ··· 214 214 215 215 static bool soc_v1_0_need_reset_on_init(struct amdgpu_device *adev) 216 216 { 217 - u32 sol_reg; 218 - 219 - if (adev->flags & AMD_IS_APU) 220 - return false; 221 - 222 - /* Check sOS sign of life register to confirm sys driver and sOS 223 - * are already been loaded. 224 - */ 225 - sol_reg = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_81); 226 - if (sol_reg) 227 - return true; 228 217 229 218 return false; 230 219 } 231 220 221 + static enum amd_reset_method 222 + soc_v1_0_asic_reset_method(struct amdgpu_device *adev) 223 + { 224 + if ((adev->gmc.xgmi.supported && adev->gmc.xgmi.connected_to_cpu) || 225 + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 8))) { 226 + if (amdgpu_reset_method != -1) 227 + dev_warn_once(adev->dev, "Reset override isn't supported, using Mode2 instead.\n"); 228 + 229 + return AMD_RESET_METHOD_MODE2; 230 + } 231 + 232 + return amdgpu_reset_method; 233 + } 234 + 232 235 static int soc_v1_0_asic_reset(struct amdgpu_device *adev) 233 236 { 237 + switch (soc_v1_0_asic_reset_method(adev)) { 238 + case AMD_RESET_METHOD_MODE2: 239 + dev_info(adev->dev, "MODE2 reset\n"); 240 + return amdgpu_dpm_mode2_reset(adev); 241 + default: 242 + dev_info(adev->dev, "Invalid reset method Not supported\n"); 243 + return -EOPNOTSUPP; 244 + } 245 + 234 246 return 0; 235 247 } 236 248 ··· 256 244 .need_reset_on_init = &soc_v1_0_need_reset_on_init, 257 245 .encode_ext_smn_addressing = &soc_v1_0_encode_ext_smn_addressing, 258 246 .reset = soc_v1_0_asic_reset, 247 + .reset_method = &soc_v1_0_asic_reset_method, 259 248 }; 260 249 261 250 static int soc_v1_0_common_early_init(struct amdgpu_ip_block *ip_block) ··· 281 268 282 269 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { 283 270 case IP_VERSION(12, 1, 0): 284 - adev->cg_flags = 0; 271 + adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG | 272 + AMD_CG_SUPPORT_GFX_CGLS; 285 273 adev->pg_flags = 0; 286 274 adev->external_rev_id = adev->rev_id + 0x50; 287 275 break; ··· 823 809 { 824 810 int ret, i; 825 811 int xcc_inst_per_aid = 4; 826 - uint16_t xcc_mask; 812 + uint16_t xcc_mask, sdma_mask = 0; 827 813 828 814 xcc_mask = adev->gfx.xcc_mask; 829 815 adev->aid_mask = 0; ··· 833 819 } 834 820 835 821 adev->sdma.num_inst_per_xcc = 2; 836 - adev->sdma.num_instances = 837 - NUM_XCC(adev->gfx.xcc_mask) * adev->sdma.num_inst_per_xcc; 838 - adev->sdma.sdma_mask = 839 - GENMASK(adev->sdma.num_instances - 1, 0); 822 + for_each_inst(i, adev->gfx.xcc_mask) 823 + sdma_mask |= 824 + GENMASK(adev->sdma.num_inst_per_xcc - 1, 0) << 825 + (i * adev->sdma.num_inst_per_xcc); 826 + adev->sdma.sdma_mask = sdma_mask; 827 + adev->sdma.num_instances = NUM_XCC(adev->sdma.sdma_mask); 840 828 841 829 ret = soc_v1_0_xcp_mgr_init(adev); 842 830 if (ret)
+5 -2
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
··· 2720 2720 ctl_stack, ctl_stack_used_size, save_area_used_size); 2721 2721 } 2722 2722 2723 - static void get_queue_checkpoint_info(struct device_queue_manager *dqm, 2723 + static int get_queue_checkpoint_info(struct device_queue_manager *dqm, 2724 2724 const struct queue *q, 2725 2725 u32 *mqd_size, 2726 2726 u32 *ctl_stack_size) ··· 2728 2728 struct mqd_manager *mqd_mgr; 2729 2729 enum KFD_MQD_TYPE mqd_type = 2730 2730 get_mqd_type_from_queue_type(q->properties.type); 2731 + int ret = 0; 2731 2732 2732 2733 dqm_lock(dqm); 2733 2734 mqd_mgr = dqm->mqd_mgrs[mqd_type]; ··· 2736 2735 *ctl_stack_size = 0; 2737 2736 2738 2737 if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE && mqd_mgr->get_checkpoint_info) 2739 - mqd_mgr->get_checkpoint_info(mqd_mgr, q->mqd, ctl_stack_size); 2738 + ret = mqd_mgr->get_checkpoint_info(mqd_mgr, q->mqd, ctl_stack_size); 2740 2739 2741 2740 dqm_unlock(dqm); 2741 + 2742 + return ret; 2742 2743 } 2743 2744 2744 2745 static int checkpoint_mqd(struct device_queue_manager *dqm,
+1 -1
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
··· 192 192 193 193 int (*reset_queues)(struct device_queue_manager *dqm, 194 194 uint16_t pasid); 195 - void (*get_queue_checkpoint_info)(struct device_queue_manager *dqm, 195 + int (*get_queue_checkpoint_info)(struct device_queue_manager *dqm, 196 196 const struct queue *q, u32 *mqd_size, 197 197 u32 *ctl_stack_size); 198 198
+2 -1
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
··· 102 102 u32 *ctl_stack_used_size, 103 103 u32 *save_area_used_size); 104 104 105 - void (*get_checkpoint_info)(struct mqd_manager *mm, void *mqd, uint32_t *ctl_stack_size); 105 + int (*get_checkpoint_info)(struct mqd_manager *mm, void *mqd, 106 + uint32_t *ctl_stack_size); 106 107 107 108 void (*checkpoint_mqd)(struct mqd_manager *mm, 108 109 void *mqd,
+5 -2
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
··· 385 385 return 0; 386 386 } 387 387 388 - static void get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size) 388 + static int get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size) 389 389 { 390 390 struct v9_mqd *m = get_mqd(mqd); 391 391 392 - *ctl_stack_size = m->cp_hqd_cntl_stack_size * NUM_XCC(mm->dev->xcc_mask); 392 + if (check_mul_overflow(m->cp_hqd_cntl_stack_size, NUM_XCC(mm->dev->xcc_mask), ctl_stack_size)) 393 + return -EINVAL; 394 + 395 + return 0; 393 396 } 394 397 395 398 static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+2 -1
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
··· 274 274 return 0; 275 275 } 276 276 277 - static void get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size) 277 + static int get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size) 278 278 { 279 279 /* Control stack is stored in user mode */ 280 280 *ctl_stack_size = 0; 281 + return 0; 281 282 } 282 283 283 284 static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+2 -2
drivers/gpu/drm/amd/amdkfd/kfd_process.c
··· 585 585 ret = kobject_init_and_add(pdd->kobj_stats, 586 586 &procfs_stats_type, 587 587 p->kobj, 588 - stats_dir_filename); 588 + "%s", stats_dir_filename); 589 589 590 590 if (ret) { 591 591 pr_warn("Creating KFD proc/stats_%s folder failed", ··· 632 632 return; 633 633 634 634 ret = kobject_init_and_add(kobj_counters, &sysfs_counters_type, 635 - p->kobj, counters_dir_filename); 635 + p->kobj, "%s", counters_dir_filename); 636 636 if (ret) { 637 637 pr_warn("Creating KFD proc/%s folder failed", 638 638 counters_dir_filename);
+8 -1
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
··· 593 593 p->queue_size)) { 594 594 pr_debug("ring buf 0x%llx size 0x%llx not mapped on GPU\n", 595 595 p->queue_address, p->queue_size); 596 + amdgpu_bo_unreserve(vm->root.bo); 596 597 return -EFAULT; 597 598 } 598 599 ··· 1070 1069 uint32_t *ctl_stack_size) 1071 1070 { 1072 1071 struct process_queue_node *pqn; 1072 + int ret; 1073 1073 1074 1074 pqn = get_queue_by_qid(pqm, qid); 1075 1075 if (!pqn) { ··· 1083 1081 return -EOPNOTSUPP; 1084 1082 } 1085 1083 1086 - pqn->q->device->dqm->ops.get_queue_checkpoint_info(pqn->q->device->dqm, 1084 + ret = pqn->q->device->dqm->ops.get_queue_checkpoint_info(pqn->q->device->dqm, 1087 1085 pqn->q, mqd_size, 1088 1086 ctl_stack_size); 1087 + if (ret) { 1088 + pr_debug("amdkfd: Overflow while computing stack size for queue %d\n", qid); 1089 + return ret; 1090 + } 1091 + 1089 1092 return 0; 1090 1093 } 1091 1094
+2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 2473 2473 DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_7_SCRATCH_MEM 2474 2474 DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_IB_MEM 2475 2475 DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_SHARED_STATE 2476 + DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_LSDMA_BUFFER 2477 + DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_CURSOR_OFFLOAD 2476 2478 }; 2477 2479 int r; 2478 2480
+5 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
··· 62 62 DRM_FORMAT_XBGR8888, 63 63 DRM_FORMAT_ABGR8888, 64 64 DRM_FORMAT_RGB565, 65 + DRM_FORMAT_NV21, 66 + DRM_FORMAT_NV12, 67 + DRM_FORMAT_P010 65 68 }; 66 69 67 70 static const uint32_t overlay_formats[] = { ··· 1911 1908 drm_plane_create_zpos_immutable_property(plane, 255); 1912 1909 } 1913 1910 1914 - if (plane->type == DRM_PLANE_TYPE_PRIMARY && 1911 + if ((plane->type == DRM_PLANE_TYPE_PRIMARY || 1912 + plane->type == DRM_PLANE_TYPE_OVERLAY) && 1915 1913 plane_cap && 1916 1914 (plane_cap->pixel_format_support.nv12 || 1917 1915 plane_cap->pixel_format_support.p010)) {
+1 -10
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
··· 794 794 795 795 static enum bp_result bios_parser_dac_load_detection( 796 796 struct dc_bios *dcb, 797 - enum engine_id engine_id, 798 - struct graphics_object_id ext_enc_id) 797 + enum engine_id engine_id) 799 798 { 800 799 struct bios_parser *bp = BP_FROM_DCB(dcb); 801 800 struct dc_context *ctx = dcb->ctx; 802 801 struct bp_load_detection_parameters bp_params = {0}; 803 - struct bp_external_encoder_control ext_cntl = {0}; 804 802 enum bp_result bp_result = BP_RESULT_UNSUPPORTED; 805 803 uint32_t bios_0_scratch; 806 804 uint32_t device_id_mask = 0; ··· 824 826 825 827 bp_params.engine_id = engine_id; 826 828 bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params); 827 - } else if (ext_enc_id.id) { 828 - if (!bp->cmd_tbl.external_encoder_control) 829 - return BP_RESULT_UNSUPPORTED; 830 - 831 - ext_cntl.action = EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT; 832 - ext_cntl.encoder_id = ext_enc_id; 833 - bp_result = bp->cmd_tbl.external_encoder_control(bp, &ext_cntl); 834 829 } 835 830 836 831 if (bp_result != BP_RESULT_OK)
+16
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
··· 48 48 #include "dcn32/dcn32_clk_mgr.h" 49 49 #include "dcn35/dcn35_clk_mgr.h" 50 50 #include "dcn401/dcn401_clk_mgr.h" 51 + #include "dcn42/dcn42_clk_mgr.h" 51 52 52 53 int clk_mgr_helper_get_active_display_cnt( 53 54 struct dc *dc, ··· 363 362 return &clk_mgr->base; 364 363 } 365 364 break; 365 + case AMDGPU_FAMILY_GC_11_5_4: { 366 + struct clk_mgr_dcn42 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); 367 + 368 + if (clk_mgr == NULL) { 369 + BREAK_TO_DEBUGGER(); 370 + return NULL; 371 + } 372 + 373 + dcn42_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 374 + return &clk_mgr->base.base; 375 + } 376 + break; 366 377 #endif /* CONFIG_DRM_AMD_DC_FP */ 367 378 default: 368 379 ASSERT(0); /* Unknown Asic */ ··· 431 418 break; 432 419 case AMDGPU_FAMILY_GC_12_0_0: 433 420 dcn401_clk_mgr_destroy(clk_mgr); 421 + break; 422 + case AMDGPU_FAMILY_GC_11_5_4: 423 + dcn42_clk_mgr_destroy(clk_mgr); 434 424 break; 435 425 436 426 default:
+1
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
··· 547 547 /* in case we don't get a value from the register, use default */ 548 548 if (clk_mgr->base.dentist_vco_freq_khz == 0) 549 549 clk_mgr->base.dentist_vco_freq_khz = 3650000; 550 + 550 551 /* Convert dprefclk units from MHz to KHz */ 551 552 /* Value already divided by 10, some resolution lost */ 552 553
+156 -143
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
··· 31 31 #include "link_service.h" 32 32 #include "logger_types.h" 33 33 34 + #include "clk/clk_15_0_0_offset.h" 35 + #include "clk/clk_15_0_0_sh_mask.h" 36 + #include "dcn/dcn_4_2_0_offset.h" 37 + #include "dcn/dcn_4_2_0_sh_mask.h" 38 + 34 39 35 40 #undef DC_LOGGER 36 41 #define DC_LOGGER \ 37 - clk_mgr->base.base.ctx->logger 42 + dc_logger 43 + #define DC_LOGGER_INIT(logger) \ 44 + struct dal_logger *dc_logger = logger 38 45 39 - 40 - #define DCN_BASE__INST0_SEG1 0x000000C0 41 - 42 - #define regCLK8_CLK2_BYPASS_CNTL 0x4c2a 43 - #define regCLK8_CLK2_BYPASS_CNTL_BASE_IDX 0 44 - #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0 45 - #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT 0x10 46 - #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L 47 - #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L 48 - 49 - #define regDENTIST_DISPCLK_CNTL 0x0064 50 - #define regDENTIST_DISPCLK_CNTL_BASE_IDX 1 51 - 52 - // DENTIST_DISPCLK_CNTL 53 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_WDIVIDER__SHIFT 0x0 54 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_RDIVIDER__SHIFT 0x8 55 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_CHG_DONE__SHIFT 0x13 56 - #define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_CHG_DONE__SHIFT 0x14 57 - #define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_WDIVIDER__SHIFT 0x18 58 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_WDIVIDER_MASK 0x0000007FL 59 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_RDIVIDER_MASK 0x00007F00L 60 - #define DENTIST_DISPCLK_CNTL__DENTIST_DISPCLK_CHG_DONE_MASK 0x00080000L 61 - #define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_CHG_DONE_MASK 0x00100000L 62 - #define DENTIST_DISPCLK_CNTL__DENTIST_DPPCLK_WDIVIDER_MASK 0x7F000000L 63 - #define mmDENTIST_DISPCLK_CNTL 0x0124 64 - #define mmCLK8_CLK_TICK_CNT_CONFIG_REG 0x1B851 65 - #define mmCLK8_CLK0_CURRENT_CNT 0x1B853 66 - #define mmCLK8_CLK1_CURRENT_CNT 0x1B854 67 - #define mmCLK8_CLK2_CURRENT_CNT 0x1B855 68 - #define mmCLK8_CLK3_CURRENT_CNT 0x1B856 69 - #define mmCLK8_CLK4_CURRENT_CNT 0x1B857 70 - 71 - 72 - #define mmCLK8_CLK0_BYPASS_CNTL 0x1B81A 73 - #define mmCLK8_CLK1_BYPASS_CNTL 0x1B822 74 - #define mmCLK8_CLK2_BYPASS_CNTL 0x1B82A 75 - #define mmCLK8_CLK3_BYPASS_CNTL 0x1B832 76 - #define mmCLK8_CLK4_BYPASS_CNTL 0x1B83A 77 - 78 - 79 - #define mmCLK8_CLK0_DS_CNTL 0x1B814 80 - #define mmCLK8_CLK1_DS_CNTL 0x1B81C 81 - #define mmCLK8_CLK2_DS_CNTL 0x1B824 82 - #define mmCLK8_CLK3_DS_CNTL 0x1B82C 83 - #define mmCLK8_CLK4_DS_CNTL 0x1B834 84 - 85 - 86 - 46 + #define DCN42_CLKIP_REFCLK 48000 87 47 88 48 #undef FN 89 49 #define FN(reg_name, field_name) \ ··· 52 92 #define REG(reg) \ 53 93 (clk_mgr->regs->reg) 54 94 95 + // for DCN register access 96 + #define DCN_BASE__INST0_SEG0 0x00000012 97 + #define DCN_BASE__INST0_SEG1 0x000000C0 98 + 55 99 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg 56 100 57 101 #define BASE(seg) BASE_INNER(seg) 58 102 59 - #define SR(reg_name)\ 60 - .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \ 61 - reg ## reg_name 103 + #define SR(reg_name) \ 104 + .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name 62 105 63 - #define CLK_SR_DCN42(reg_name)\ 64 - .reg_name = mm ## reg_name 106 + // for CLKIP register access 107 + #define CLK_BASE__INST0_SEG0 0x00016C00 108 + 109 + #define CLK_BASE_INNER(seg) \ 110 + CLK_BASE__INST0_SEG ## seg 111 + 112 + #define CLK_SR_DCN42(reg_name) \ 113 + .reg_name = CLK_BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name 65 114 66 115 static const struct clk_mgr_registers clk_mgr_regs_dcn42 = { 67 116 CLK_REG_LIST_DCN42() ··· 84 115 CLK_COMMON_MASK_SH_LIST_DCN42(_MASK) 85 116 }; 86 117 87 - 88 - 89 118 #define TO_CLK_MGR_DCN42(clk_mgr_int)\ 90 119 container_of(clk_mgr_int, struct clk_mgr_dcn42, base) 91 120 92 - int dcn42_get_active_display_cnt_wa( 93 - struct dc *dc, 94 - struct dc_state *context, 95 - int *all_active_disps) 121 + bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context) 96 122 { 97 - int i, display_count = 0; 98 - bool tmds_present = false; 123 + int i, active_count = 0; 99 124 100 125 for (i = 0; i < context->stream_count; i++) { 101 126 const struct dc_stream_state *stream = context->streams[i]; 102 127 103 - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || 104 - stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || 105 - stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) 106 - tmds_present = true; 128 + /* Checking stream / link detection ensuring that PHY is active*/ 129 + if (dc_is_hdmi_signal(stream->signal) || 130 + dc_is_dvi_signal(stream->signal) || 131 + (dc_is_dp_signal(stream->signal) && !stream->dpms_off)) 132 + active_count++; 107 133 } 108 134 109 135 for (i = 0; i < dc->link_count; i++) { ··· 107 143 /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ 108 144 if (link->link_enc && link->link_enc->funcs->is_dig_enabled && 109 145 link->link_enc->funcs->is_dig_enabled(link->link_enc)) 110 - display_count++; 146 + active_count++; 111 147 } 112 - if (all_active_disps != NULL) 113 - *all_active_disps = display_count; 114 - /* WA for hang on HDMI after display off back on*/ 115 - if (display_count == 0 && tmds_present) 116 - display_count = 1; 117 148 118 - return display_count; 149 + return active_count > 0; 150 + } 151 + 152 + static uint32_t dcn42_get_clock_freq_from_clkip(struct clk_mgr *clk_mgr_base, enum clock_type clock) 153 + { 154 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 155 + uint64_t clock_freq_mhz = 0; 156 + uint32_t timer_threshold = 0; 157 + 158 + // always safer to read the timer threshold instead of using cached value 159 + REG_GET(CLK8_CLK_TICK_CNT_CONFIG_REG, TIMER_THRESHOLD, &timer_threshold); 160 + 161 + if (timer_threshold == 0) { 162 + BREAK_TO_DEBUGGER(); 163 + return 0; 164 + } 165 + 166 + switch (clock) { 167 + case clock_type_dispclk: 168 + clock_freq_mhz = REG_READ(CLK8_CLK0_CURRENT_CNT); 169 + break; 170 + case clock_type_dppclk: 171 + clock_freq_mhz = REG_READ(CLK8_CLK1_CURRENT_CNT); 172 + break; 173 + case clock_type_dprefclk: 174 + clock_freq_mhz = REG_READ(CLK8_CLK2_CURRENT_CNT); 175 + break; 176 + case clock_type_dcfclk: 177 + clock_freq_mhz = REG_READ(CLK8_CLK3_CURRENT_CNT); 178 + break; 179 + case clock_type_dtbclk: 180 + clock_freq_mhz = REG_READ(CLK8_CLK4_CURRENT_CNT); 181 + break; 182 + default: 183 + break; 184 + } 185 + 186 + clock_freq_mhz *= DCN42_CLKIP_REFCLK; 187 + clock_freq_mhz = div_u64(clock_freq_mhz, timer_threshold); 188 + 189 + // there are no DCN clocks over 0xFFFFFFFF MHz 190 + ASSERT(clock_freq_mhz <= 0xFFFFFFFF); 191 + 192 + return (uint32_t)clock_freq_mhz; 119 193 } 120 194 121 195 void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, ··· 215 213 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 216 214 struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; 217 215 struct dc *dc = clk_mgr_base->ctx->dc; 218 - int display_count = 0; 219 216 bool update_dppclk = false; 220 217 bool update_dispclk = false; 221 218 bool dpp_clock_lowered = false; 222 - int all_active_disps = 0; 219 + bool has_active_display; 223 220 224 221 if (dc->work_arounds.skip_clock_update) 225 222 return; 226 223 227 - display_count = dcn42_get_active_display_cnt_wa(dc, context, &all_active_disps); 224 + has_active_display = dcn42_has_active_display(dc, context); 228 225 229 - /*dml21 issue*/ 230 - ASSERT(new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz > 590000); //remove this section if assert is hit 231 226 if (new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz < 590000) 232 227 new_clocks->ref_dtbclk_khz = 600000; 233 - 234 228 /* 235 229 * if it is safe to lower, but we are already in the lower state, we don't have to do anything 236 230 * also if safe to lower is false, we just go in the higher state ··· 246 248 /* check that we're not already in lower */ 247 249 if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { 248 250 /* if we can go lower, go lower */ 249 - if (display_count == 0) 251 + if (has_active_display == false) 250 252 clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; 251 253 } 252 254 } else { ··· 260 262 261 263 dcn42_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz); 262 264 dcn42_smu_set_dtbclk(clk_mgr, true); 263 - if (clk_mgr_base->boot_snapshot.timer_threhold) 264 - actual_dtbclk = REG_READ(CLK8_CLK4_CURRENT_CNT) / (clk_mgr_base->boot_snapshot.timer_threhold / 48000); 265 - 265 + actual_dtbclk = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dtbclk); 266 266 267 267 if (actual_dtbclk > 590000) { 268 268 clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz; ··· 304 308 } 305 309 306 310 if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) && 307 - (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) { 311 + (new_clocks->dispclk_khz > 0 || (safe_to_lower && has_active_display == false))) { 308 312 int requested_dispclk_khz = new_clocks->dispclk_khz; 309 313 310 314 dcn35_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true); ··· 382 386 static void dcn42_dump_clk_registers_internal(struct dcn42_clk_internal *internal, struct clk_mgr *clk_mgr_base) 383 387 { 384 388 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 385 - uint32_t ratio = 1; 386 389 387 - internal->CLK8_CLK_TICK_CNT__TIMER_THRESHOLD = REG_READ(CLK8_CLK_TICK_CNT_CONFIG_REG) & 0xFFFFFF; 390 + REG_GET(CLK8_CLK_TICK_CNT_CONFIG_REG, TIMER_THRESHOLD, &internal->CLK8_CLK_TICK_CNT__TIMER_THRESHOLD); 388 391 389 - ratio = internal->CLK8_CLK_TICK_CNT__TIMER_THRESHOLD / 48000; 390 - ASSERT(ratio != 0); 391 - 392 - if (ratio) { 393 - // read dcf deep sleep divider 394 - internal->CLK8_CLK0_DS_CNTL = REG_READ(CLK8_CLK0_DS_CNTL); 395 - internal->CLK8_CLK3_DS_CNTL = REG_READ(CLK8_CLK3_DS_CNTL); 396 - // read dispclk 397 - internal->CLK8_CLK0_CURRENT_CNT = REG_READ(CLK8_CLK0_CURRENT_CNT) / ratio; 398 - internal->CLK8_CLK0_BYPASS_CNTL = REG_READ(CLK8_CLK0_BYPASS_CNTL); 399 - // read dppclk 400 - internal->CLK8_CLK1_CURRENT_CNT = REG_READ(CLK8_CLK1_CURRENT_CNT) / ratio; 401 - internal->CLK8_CLK1_BYPASS_CNTL = REG_READ(CLK8_CLK1_BYPASS_CNTL); 402 - // read dprefclk 403 - internal->CLK8_CLK2_CURRENT_CNT = REG_READ(CLK8_CLK2_CURRENT_CNT) / ratio; 404 - internal->CLK8_CLK2_BYPASS_CNTL = REG_READ(CLK8_CLK2_BYPASS_CNTL); 405 - // read dcfclk 406 - internal->CLK8_CLK3_CURRENT_CNT = REG_READ(CLK8_CLK3_CURRENT_CNT) / ratio; 407 - internal->CLK8_CLK3_BYPASS_CNTL = REG_READ(CLK8_CLK3_BYPASS_CNTL); 408 - // read dtbclk 409 - internal->CLK8_CLK4_CURRENT_CNT = REG_READ(CLK8_CLK4_CURRENT_CNT) / ratio; 410 - internal->CLK8_CLK4_BYPASS_CNTL = REG_READ(CLK8_CLK4_BYPASS_CNTL); 411 - } 412 - 392 + // read dcf deep sleep divider 393 + internal->CLK8_CLK0_DS_CNTL = REG_READ(CLK8_CLK0_DS_CNTL); 394 + internal->CLK8_CLK3_DS_CNTL = REG_READ(CLK8_CLK3_DS_CNTL); 395 + // read dispclk 396 + internal->CLK8_CLK0_CURRENT_CNT = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dispclk); 397 + internal->CLK8_CLK0_BYPASS_CNTL = REG_READ(CLK8_CLK0_BYPASS_CNTL); 398 + // read dppclk 399 + internal->CLK8_CLK1_CURRENT_CNT = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dppclk); 400 + internal->CLK8_CLK1_BYPASS_CNTL = REG_READ(CLK8_CLK1_BYPASS_CNTL); 401 + // read dprefclk 402 + internal->CLK8_CLK2_CURRENT_CNT = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dprefclk); 403 + internal->CLK8_CLK2_BYPASS_CNTL = REG_READ(CLK8_CLK2_BYPASS_CNTL); 404 + // read dcfclk 405 + internal->CLK8_CLK3_CURRENT_CNT = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dcfclk); 406 + internal->CLK8_CLK3_BYPASS_CNTL = REG_READ(CLK8_CLK3_BYPASS_CNTL); 407 + // read dtbclk 408 + internal->CLK8_CLK4_CURRENT_CNT = dcn42_get_clock_freq_from_clkip(clk_mgr_base, clock_type_dtbclk); 409 + internal->CLK8_CLK4_BYPASS_CNTL = REG_READ(CLK8_CLK4_BYPASS_CNTL); 413 410 } 414 411 415 412 static void dcn42_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass, ··· 411 422 struct dcn42_clk_internal internal = {0}; 412 423 char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"}; 413 424 425 + DC_LOGGER_INIT(clk_mgr->base.base.ctx->logger); 426 + (void)dc_logger; 427 + 414 428 dcn42_dump_clk_registers_internal(&internal, &clk_mgr->base.base); 415 - regs_and_bypass->timer_threhold = internal.CLK8_CLK_TICK_CNT__TIMER_THRESHOLD; 429 + regs_and_bypass->timer_threshold = internal.CLK8_CLK_TICK_CNT__TIMER_THRESHOLD; 416 430 regs_and_bypass->dcfclk = internal.CLK8_CLK3_CURRENT_CNT / 10; 417 431 regs_and_bypass->dcf_deep_sleep_divider = internal.CLK8_CLK3_DS_CNTL / 10; 418 432 regs_and_bypass->dcf_deep_sleep_allow = internal.CLK8_CLK3_DS_CNTL & 0x10; /*bit 4: CLK0_ALLOW_DS*/ ··· 424 432 regs_and_bypass->dppclk = internal.CLK8_CLK1_CURRENT_CNT / 10; 425 433 regs_and_bypass->dtbclk = internal.CLK8_CLK4_CURRENT_CNT / 10; 426 434 427 - regs_and_bypass->dppclk_bypass = internal.CLK8_CLK1_BYPASS_CNTL & 0x0007; 428 - if (regs_and_bypass->dppclk_bypass > 4) 429 - regs_and_bypass->dppclk_bypass = 0; 430 - regs_and_bypass->dcfclk_bypass = internal.CLK8_CLK3_BYPASS_CNTL & 0x0007; 431 - if (regs_and_bypass->dcfclk_bypass > 4) 432 - regs_and_bypass->dcfclk_bypass = 0; 433 - regs_and_bypass->dispclk_bypass = internal.CLK8_CLK0_BYPASS_CNTL & 0x0007; 434 - if (regs_and_bypass->dispclk_bypass > 4) 435 - regs_and_bypass->dispclk_bypass = 0; 436 - regs_and_bypass->dprefclk_bypass = internal.CLK8_CLK2_BYPASS_CNTL & 0x0007; 437 - if (regs_and_bypass->dprefclk_bypass > 4) 438 - regs_and_bypass->dprefclk_bypass = 0; 435 + regs_and_bypass->dispclk_bypass = get_reg_field_value(internal.CLK8_CLK0_BYPASS_CNTL, CLK8_CLK0_BYPASS_CNTL, CLK0_BYPASS_SEL); 436 + regs_and_bypass->dppclk_bypass = get_reg_field_value(internal.CLK8_CLK1_BYPASS_CNTL, CLK8_CLK1_BYPASS_CNTL, CLK1_BYPASS_SEL); 437 + regs_and_bypass->dprefclk_bypass = get_reg_field_value(internal.CLK8_CLK2_BYPASS_CNTL, CLK8_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL); 438 + regs_and_bypass->dcfclk_bypass = get_reg_field_value(internal.CLK8_CLK3_BYPASS_CNTL, CLK8_CLK3_BYPASS_CNTL, CLK3_BYPASS_SEL); 439 439 440 440 if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) { 441 441 DC_LOG_SMU("clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n"); ··· 451 467 452 468 // REGISTER VALUES 453 469 DC_LOG_SMU("reg_name,value,clk_type\n"); 454 - 455 470 DC_LOG_SMU("CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n", 456 471 internal.CLK8_CLK3_CURRENT_CNT); 457 472 ··· 571 588 struct clk_mgr_dcn42 *clk_mgr = TO_CLK_MGR_DCN42(clk_mgr_int); 572 589 struct dcn42_smu_dpm_clks smu_dpm_clks = { 0 }; 573 590 591 + DC_LOGGER_INIT(clk_mgr_base->ctx->logger); 592 + (void)dc_logger; 593 + 574 594 init_clk_states(clk_mgr_base); 575 595 576 596 // to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk ··· 583 597 else 584 598 clk_mgr_base->dp_dto_source_clock_in_khz = clk_mgr_base->dprefclk_khz; 585 599 600 + DC_LOG_SMU("dp_dto_source_clock %d, dprefclk %d\n", clk_mgr_base->dp_dto_source_clock_in_khz, clk_mgr_base->dprefclk_khz); 586 601 dcn42_dump_clk_registers(&clk_mgr_base->boot_snapshot, clk_mgr); 587 602 588 603 clk_mgr_base->clks.ref_dtbclk_khz = clk_mgr_base->boot_snapshot.dtbclk * 10; 589 604 if (clk_mgr_base->boot_snapshot.dtbclk > 59000) { 590 605 /*dtbclk enabled based on*/ 591 606 clk_mgr_base->clks.dtbclk_en = true; 607 + } 608 + 609 + if (clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels != 0) { 610 + /*skip to get clock table and notify pmfw watermark range again*/ 611 + DC_LOG_SMU("skip to get dpm_clks from pmfw from resume and acr\n"); 612 + return; 592 613 } 593 614 594 615 smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn42 *)dm_helpers_allocate_gpu_mem( ··· 704 711 /* DTBCLK*/ 705 712 clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz = clk_mgr_base->clks.ref_dtbclk_khz / 1000; 706 713 clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels = 1; 707 - 708 714 /* Refresh bounding box */ 709 715 clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box( 710 - clk_mgr_base->ctx->dc, clk_mgr_base->bw_params); 716 + clk_mgr_base->ctx->dc, clk_mgr_base->bw_params); 711 717 } 712 718 } 713 719 if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) ··· 818 826 } 819 827 } 820 828 821 - /* Exposed for dcn42b reuse */ 822 829 void dcn42_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn42_watermarks *table) 823 830 { 824 831 int i, num_valid_sets; ··· 876 885 877 886 void dcn42_notify_wm_ranges(struct clk_mgr *clk_mgr_base) 878 887 { 888 + int i = 0; 889 + struct dcn42_watermarks *table = NULL; 879 890 struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 880 891 struct clk_mgr_dcn42 *clk_mgr_dcn42 = TO_CLK_MGR_DCN42(clk_mgr); 881 - struct dcn42_watermarks *table = clk_mgr_dcn42->smu_wm_set.wm_set; 882 892 883 893 if (!clk_mgr->smu_ver) 884 894 return; 895 + /*send once already skip*/ 896 + if (clk_mgr_base->bw_params->wm_table.entries[WM_A].valid == true) 897 + return; 898 + clk_mgr_dcn42->smu_wm_set.wm_set = (struct dcn42_watermarks *)dm_helpers_allocate_gpu_mem( 899 + clk_mgr->base.ctx, 900 + DC_MEM_ALLOC_TYPE_GART, 901 + sizeof(struct dcn42_watermarks), 902 + &clk_mgr_dcn42->smu_wm_set.mc_address.quad_part); 903 + 904 + ASSERT(clk_mgr_dcn42->smu_wm_set.wm_set); 905 + 906 + table = clk_mgr_dcn42->smu_wm_set.wm_set; 885 907 886 908 if (!table || clk_mgr_dcn42->smu_wm_set.mc_address.quad_part == 0) 887 909 return; 888 910 889 911 memset(table, 0, sizeof(*table)); 912 + /*same as previous asic, set wm valid before building watermark ranges*/ 913 + for (i = 0; i < WM_SET_COUNT; i++) { 914 + clk_mgr_base->bw_params->wm_table.entries[i].wm_inst = i; 890 915 916 + if (i >= clk_mgr_base->bw_params->clk_table.num_entries) { 917 + clk_mgr_base->bw_params->wm_table.entries[i].valid = false; 918 + continue; 919 + } 920 + clk_mgr_base->bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG; 921 + clk_mgr_base->bw_params->wm_table.entries[i].valid = true; 922 + } 923 + /* build watermark_range will check this valid range*/ 891 924 dcn42_build_watermark_ranges(clk_mgr_base->bw_params, table); 892 925 893 926 dcn42_smu_set_dram_addr_high(clk_mgr, ··· 919 904 dcn42_smu_set_dram_addr_low(clk_mgr, 920 905 clk_mgr_dcn42->smu_wm_set.mc_address.low_part); 921 906 dcn42_smu_transfer_wm_table_dram_2_smu(clk_mgr); 907 + 908 + if (clk_mgr_dcn42->smu_wm_set.wm_set && clk_mgr_dcn42->smu_wm_set.mc_address.quad_part != 0) 909 + dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_GART, 910 + clk_mgr_dcn42->smu_wm_set.wm_set); 911 + 922 912 } 923 913 924 914 void dcn42_set_low_power_state(struct clk_mgr *clk_mgr_base) 925 915 { 926 - int display_count; 927 916 struct dc *dc = clk_mgr_base->ctx->dc; 928 917 struct dc_state *context = dc->current_state; 929 918 930 919 if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { 931 - display_count = dcn42_get_active_display_cnt_wa(dc, context, NULL); 932 920 /* if we can go lower, go lower */ 933 - if (display_count == 0) 921 + if (dcn42_has_active_display(dc, context) == false) 934 922 clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; 935 923 } 936 924 ··· 1114 1096 clk_mgr->base.dprefclk_ss_divider = 1000; 1115 1097 clk_mgr->base.ss_on_dprefclk = false; 1116 1098 clk_mgr->base.dfs_ref_freq_khz = 48000; /*sync with pmfw*/ 1117 - 1118 - clk_mgr->smu_wm_set.wm_set = (struct dcn42_watermarks *)dm_helpers_allocate_gpu_mem( 1119 - clk_mgr->base.base.ctx, 1120 - DC_MEM_ALLOC_TYPE_GART, 1121 - sizeof(struct dcn42_watermarks), 1122 - &clk_mgr->smu_wm_set.mc_address.quad_part); 1123 - 1124 - ASSERT(clk_mgr->smu_wm_set.wm_set); 1099 + clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; 1125 1100 1126 1101 /* Changed from DCN3.2_clock_frequency doc to match 1127 1102 * dcn32_dump_clk_registers from 4 * dentist_vco_freq_khz / ··· 1123 1112 clk_mgr->base.base.dprefclk_khz = 600000; 1124 1113 1125 1114 clk_mgr->base.smu_present = false; 1115 + clk_mgr->base.smu_ver = dcn42_smu_get_pmfw_version(&clk_mgr->base); 1116 + if (clk_mgr->base.smu_ver && clk_mgr->base.smu_ver != -1) 1117 + clk_mgr->base.smu_present = true; 1126 1118 1127 1119 if (ctx->dc_bios->integrated_info) { 1128 1120 clk_mgr->base.base.dentist_vco_freq_khz = ctx->dc_bios->integrated_info->dentist_vco_freq; ··· 1136 1122 dcn42_bw_params.wm_table = ddr5_wm_table; 1137 1123 dcn42_bw_params.vram_type = ctx->dc_bios->integrated_info->memory_type; 1138 1124 dcn42_bw_params.dram_channel_width_bytes = ctx->dc_bios->integrated_info->memory_type == 0x22 ? 8 : 4; 1139 - dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 4; 1125 + dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 1; 1126 + clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base); 1127 + clk_mgr->base.base.clks.ref_dtbclk_khz = dcn42_smu_get_dtbclk(&clk_mgr->base); 1140 1128 } 1141 1129 /* in case we don't get a value from the BIOS, use default */ 1142 1130 if (clk_mgr->base.base.dentist_vco_freq_khz == 0) ··· 1147 1131 /* Saved clocks configured at boot for debug purposes */ 1148 1132 dcn42_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr); 1149 1133 1150 - if (clk_mgr->base.smu_present) 1151 - clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base); 1152 - clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; 1153 1134 dce_clock_read_ss_info(&clk_mgr->base); 1154 1135 /*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/ 1155 1136
+1 -1
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.h
··· 59 59 60 60 void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int); 61 61 62 - /* Exposed for dcn42b reuse */ 63 62 void dcn42_init_single_clock(unsigned int *entry_0, 64 63 uint32_t *smu_entry_0, 65 64 uint8_t num_levels); ··· 75 76 void dcn42_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, bool safe_to_lower); 76 77 void dcn42_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr, struct dc_state *context, int ref_dtbclk_khz); 77 78 bool dcn42_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base); 79 + bool dcn42_has_active_display(struct dc *dc, const struct dc_state *context); 78 80 #endif //__DCN42_CLK_MGR_H__
+61 -73
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2895 2895 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2896 2896 } 2897 2897 2898 - if (u->blend_tf || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) { 2898 + if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) { 2899 2899 update_flags->bits.gamma_change = 1; 2900 2900 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2901 2901 } 2902 2902 2903 - if (u->lut3d_func || u->func_shaper) { 2903 + if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) { 2904 2904 update_flags->bits.lut_3d = 1; 2905 2905 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2906 + } 2907 + 2908 + if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable && 2909 + u->cm->flags.bits.lut3d_enable && u->surface->cm.flags.bits.lut3d_enable) { 2910 + /* Toggling 3DLUT loading between DMA and Host is illegal */ 2911 + BREAK_TO_DEBUGGER(); 2912 + } 2913 + 2914 + if (u->cm && u->cm->flags.bits.lut3d_enable && !u->cm->flags.bits.lut3d_dma_enable) { 2915 + /* Host loading 3DLUT requires full update but only stream lock */ 2916 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_STREAM); 2906 2917 } 2907 2918 2908 2919 if (u->hdr_mult.value) ··· 2930 2919 elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2931 2920 } 2932 2921 2933 - if (u->cm2_params) { 2934 - if (u->cm2_params->component_settings.shaper_3dlut_setting != u->surface->mcm_shaper_3dlut_setting 2935 - || u->cm2_params->component_settings.lut1d_enable != u->surface->mcm_lut1d_enable 2936 - || u->cm2_params->cm2_luts.lut3d_data.lut3d_src != u->surface->mcm_luts.lut3d_data.lut3d_src) { 2937 - update_flags->bits.mcm_transfer_function_enable_change = 1; 2938 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2939 - } 2922 + if (u->cm_hist_control) { 2923 + update_flags->bits.cm_hist_change = 1; 2924 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2940 2925 } 2941 - 2942 - if (update_flags->bits.lut_3d && 2943 - u->surface->mcm_luts.lut3d_data.lut3d_src != DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) { 2944 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2945 - } 2946 - 2947 2926 if (check_config->enable_legacy_fast_update && 2948 2927 (update_flags->bits.gamma_change || 2949 2928 update_flags->bits.gamut_remap_change || 2950 2929 update_flags->bits.input_csc_change || 2930 + update_flags->bits.cm_hist_change || 2951 2931 update_flags->bits.coeff_reduction_change)) { 2952 2932 elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2953 2933 } ··· 3170 3168 surface->gamma_correction.type = 3171 3169 srf_update->gamma->type; 3172 3170 } 3171 + if (srf_update->cm_hist_control) { 3172 + memcpy(&surface->cm_hist_control, 3173 + srf_update->cm_hist_control, 3174 + sizeof(surface->cm_hist_control)); 3175 + } 3173 3176 3174 3177 if (srf_update->in_transfer_func) { 3175 3178 surface->in_transfer_func.sdr_ref_white_level = ··· 3188 3181 sizeof(struct dc_transfer_func_distributed_points)); 3189 3182 } 3190 3183 3191 - if (srf_update->cm2_params) { 3192 - surface->mcm_shaper_3dlut_setting = srf_update->cm2_params->component_settings.shaper_3dlut_setting; 3193 - surface->mcm_lut1d_enable = srf_update->cm2_params->component_settings.lut1d_enable; 3194 - surface->mcm_luts = srf_update->cm2_params->cm2_luts; 3184 + /* Shaper, 3DLUT, 1DLUT */ 3185 + if (srf_update->cm) { 3186 + memcpy(&surface->cm, srf_update->cm, 3187 + sizeof(surface->cm)); 3195 3188 } 3196 - 3197 - if (srf_update->func_shaper) { 3198 - memcpy(&surface->in_shaper_func, srf_update->func_shaper, 3199 - sizeof(surface->in_shaper_func)); 3200 - 3201 - if (surface->mcm_shaper_3dlut_setting >= DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER) 3202 - surface->mcm_luts.shaper = &surface->in_shaper_func; 3203 - } 3204 - 3205 - if (srf_update->lut3d_func) 3206 - memcpy(&surface->lut3d_func, srf_update->lut3d_func, 3207 - sizeof(surface->lut3d_func)); 3208 3189 3209 3190 if (srf_update->hdr_mult.value) 3210 3191 surface->hdr_mult = ··· 3201 3206 if (srf_update->sdr_white_level_nits) 3202 3207 surface->sdr_white_level_nits = 3203 3208 srf_update->sdr_white_level_nits; 3204 - 3205 - if (srf_update->blend_tf) { 3206 - memcpy(&surface->blend_tf, srf_update->blend_tf, 3207 - sizeof(surface->blend_tf)); 3208 - 3209 - if (surface->mcm_lut1d_enable) 3210 - surface->mcm_luts.lut1d_func = &surface->blend_tf; 3211 - } 3212 - 3213 - if (srf_update->cm2_params || srf_update->blend_tf) 3214 - surface->lut_bank_a = !surface->lut_bank_a; 3215 3209 3216 3210 if (srf_update->input_csc_color_matrix) 3217 3211 surface->input_csc_color_matrix = ··· 4485 4501 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 4486 4502 continue; 4487 4503 4488 - if (srf_updates[i].cm2_params && 4489 - srf_updates[i].cm2_params->cm2_luts.lut3d_data.lut3d_src == 4490 - DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM && 4491 - srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting == 4492 - DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT && 4504 + if (srf_updates[i].cm && 4505 + srf_updates[i].cm->flags.bits.lut3d_enable && 4506 + srf_updates[i].cm->flags.bits.lut3d_dma_enable && 4493 4507 dc->hwss.trigger_3dlut_dma_load) 4494 4508 dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx); 4495 4509 ··· 5055 5073 fast_update[i].input_csc_color_matrix = srf_updates[i].input_csc_color_matrix; 5056 5074 fast_update[i].coeff_reduction_factor = srf_updates[i].coeff_reduction_factor; 5057 5075 fast_update[i].cursor_csc_color_matrix = srf_updates[i].cursor_csc_color_matrix; 5076 + fast_update[i].cm_hist_control = srf_updates[i].cm_hist_control; 5058 5077 } 5059 5078 } 5060 5079 ··· 5073 5090 fast_update[i].gamut_remap_matrix || 5074 5091 fast_update[i].input_csc_color_matrix || 5075 5092 fast_update[i].cursor_csc_color_matrix || 5093 + fast_update[i].cm_hist_control || 5076 5094 fast_update[i].coeff_reduction_factor) 5077 5095 return true; 5078 5096 } ··· 5094 5110 fast_update[i].gamma || 5095 5111 fast_update[i].gamut_remap_matrix || 5096 5112 fast_update[i].coeff_reduction_factor || 5113 + fast_update[i].cm_hist_control || 5097 5114 fast_update[i].cursor_csc_color_matrix) 5098 5115 return true; 5099 5116 } ··· 5136 5151 const struct dc_stream_update *stream_update, 5137 5152 const struct dc_stream_state *stream) 5138 5153 { 5154 + const union dc_plane_cm_flags blend_only_flags = { 5155 + .bits = { 5156 + .blend_enable = 1, 5157 + } 5158 + }; 5159 + 5139 5160 if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream)) 5140 5161 return true; 5141 5162 ··· 5154 5163 (srf_updates[i].sdr_white_level_nits && 5155 5164 srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) || 5156 5165 srf_updates[i].in_transfer_func || 5157 - srf_updates[i].func_shaper || 5158 - srf_updates[i].lut3d_func || 5159 5166 srf_updates[i].surface->force_full_update || 5160 5167 (srf_updates[i].flip_addr && 5161 5168 srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) || 5162 - (srf_updates[i].cm2_params && 5163 - (srf_updates[i].cm2_params->component_settings.shaper_3dlut_setting != srf_updates[i].surface->mcm_shaper_3dlut_setting || 5164 - srf_updates[i].cm2_params->component_settings.lut1d_enable != srf_updates[i].surface->mcm_lut1d_enable)))) 5169 + (srf_updates[i].cm && 5170 + ((srf_updates[i].cm->flags.all != blend_only_flags.all && srf_updates[i].cm->flags.all != 0) || 5171 + (srf_updates[i].surface->cm.flags.all != blend_only_flags.all && srf_updates[i].surface->cm.flags.all != 0))))) 5165 5172 return true; 5166 5173 } 5167 5174 ··· 5934 5945 5935 5946 case AMDGPU_FAMILY_GC_11_0_1: 5936 5947 case AMDGPU_FAMILY_GC_11_5_0: 5948 + case AMDGPU_FAMILY_GC_11_5_4: 5937 5949 if (!dc->debug.dpia_debug.bits.disable_dpia) 5938 5950 return true; 5939 5951 break; ··· 6887 6897 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 6888 6898 6889 6899 /* MPCC blending tree and mode control - capture actual blend configuration */ 6890 - state->mpc.mpcc_mode[i] = (plane_state->blend_tf.type != TF_TYPE_BYPASS) ? 1 : 0; 6900 + state->mpc.mpcc_mode[i] = (plane_state->cm.blend_func.type != TF_TYPE_BYPASS) ? 1 : 0; 6891 6901 state->mpc.mpcc_alpha_blend_mode[i] = plane_state->per_pixel_alpha ? 1 : 0; 6892 6902 state->mpc.mpcc_alpha_multiplied_mode[i] = plane_state->pre_multiplied_alpha ? 1 : 0; 6893 6903 state->mpc.mpcc_blnd_active_overlap_only[i] = 0; /* Default - no overlap restriction */ ··· 7285 7295 ASSERT(scratch->flow == UPDATE_V3_FLOW_INVALID); 7286 7296 dc_exit_ips_for_hw_access(scratch->dc); 7287 7297 7298 + /* HWSS path determination needs to be done prior to updating the surface and stream states. */ 7299 + struct dc_fast_update fast_update[MAX_SURFACES] = { 0 }; 7300 + 7301 + populate_fast_updates(fast_update, 7302 + scratch->surface_updates, 7303 + scratch->surface_count, 7304 + scratch->stream_update); 7305 + 7306 + const bool is_hwss_fast_path_only = 7307 + fast_update_only(scratch->dc, 7308 + fast_update, 7309 + scratch->surface_updates, 7310 + scratch->surface_count, 7311 + scratch->stream_update, 7312 + scratch->stream) && 7313 + !scratch->dc->check_config.enable_legacy_fast_update; 7314 + 7288 7315 if (!update_planes_and_stream_state( 7289 7316 scratch->dc, 7290 7317 scratch->surface_updates, ··· 7317 7310 if (scratch->new_context == scratch->dc->current_state) { 7318 7311 ASSERT(scratch->update_type < UPDATE_TYPE_FULL); 7319 7312 7320 - // TODO: Do we need this to be alive in execute? 7321 - struct dc_fast_update fast_update[MAX_SURFACES] = { 0 }; 7322 - 7323 - populate_fast_updates( 7324 - fast_update, 7325 - scratch->surface_updates, 7326 - scratch->surface_count, 7327 - scratch->stream_update 7328 - ); 7329 - const bool fast = fast_update_only( 7330 - scratch->dc, 7331 - fast_update, 7332 - scratch->surface_updates, 7333 - scratch->surface_count, 7334 - scratch->stream_update, 7335 - scratch->stream 7336 - ) 7337 - // TODO: Can this be used to skip `populate_fast_updates`? 7338 - && !scratch->dc->check_config.enable_legacy_fast_update; 7339 - scratch->flow = fast 7313 + scratch->flow = is_hwss_fast_path_only 7340 7314 ? UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FAST 7341 7315 : UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FULL; 7342 7316 return true;
-1
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 2431 2431 2432 2432 int slice_idx, dpp_idx, plane_idx, slice_count, dpp_count; 2433 2433 bool is_primary; 2434 - DC_LOGGER_INIT(dc->ctx->logger); 2435 2434 2436 2435 slice_count = resource_get_opp_heads_for_otg_master(otg_master, 2437 2436 &state->res_ctx, opp_heads);
+32 -9
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
··· 33 33 #include "dc_dmub_srv.h" 34 34 #include "dc_state_priv.h" 35 35 #include "dc_stream_priv.h" 36 + #include "dce/dmub_hw_lock_mgr.h" 36 37 37 38 #define DC_LOGGER dc->ctx->logger 38 39 #ifndef MIN ··· 172 171 goto fail; 173 172 174 173 stream = kzalloc_obj(struct dc_stream_state, GFP_ATOMIC); 174 + 175 175 if (stream == NULL) 176 176 goto fail; 177 177 178 178 stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_ATOMIC); 179 + 179 180 if (stream->update_scratch == NULL) 180 181 goto fail; 181 182 ··· 248 245 const struct dc_stream_state *stream) 249 246 { 250 247 struct dc *dc = stream->ctx->dc; 251 - 252 248 return dc_state_get_stream_status(dc->current_state, stream); 253 249 } 254 250 ··· 259 257 struct resource_context *res_ctx; 260 258 struct pipe_ctx *pipe_to_program = NULL; 261 259 bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc); 260 + bool unlock_dmub = false; 262 261 263 262 if (!stream) 264 263 return; ··· 278 275 if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) { 279 276 dc->hwss.begin_cursor_offload_update(dc, pipe_ctx); 280 277 } else { 278 + if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream && 279 + should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) { 280 + dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true); 281 + unlock_dmub = true; 282 + } 283 + 281 284 dc->hwss.cursor_lock(dc, pipe_to_program, true); 282 285 if (pipe_to_program->next_odm_pipe) 283 286 dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true); ··· 306 297 dc->hwss.cursor_lock(dc, pipe_to_program, false); 307 298 if (pipe_to_program->next_odm_pipe) 308 299 dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false); 300 + 301 + if (unlock_dmub) 302 + dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false); 309 303 } 310 304 } 311 305 } ··· 416 404 struct resource_context *res_ctx; 417 405 struct pipe_ctx *pipe_to_program = NULL; 418 406 bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc); 407 + bool unlock_dmub = false; 419 408 420 409 if (!stream) 421 410 return; ··· 436 423 if (!pipe_to_program) { 437 424 pipe_to_program = pipe_ctx; 438 425 439 - if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) 426 + if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) { 440 427 dc->hwss.begin_cursor_offload_update(dc, pipe_ctx); 441 - else 428 + } else { 429 + if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream && 430 + should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) { 431 + dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true); 432 + unlock_dmub = true; 433 + } 442 434 dc->hwss.cursor_lock(dc, pipe_to_program, true); 435 + } 443 436 } 444 437 445 438 dc->hwss.set_cursor_position(pipe_ctx); ··· 457 438 } 458 439 459 440 if (pipe_to_program) { 460 - if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update) 441 + if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update) { 461 442 dc->hwss.commit_cursor_offload_update(dc, pipe_to_program); 462 - else 443 + } else { 463 444 dc->hwss.cursor_lock(dc, pipe_to_program, false); 445 + 446 + if (unlock_dmub) 447 + dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false); 448 + } 464 449 } 465 450 } 466 451 ··· 546 523 struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 547 524 548 525 /* trigger event on first pipe with current stream */ 549 - if (stream == pipe_ctx->stream) { 550 - pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); 526 + if (stream == pipe_ctx->stream && 527 + pipe_ctx->stream_res.tg->funcs->program_manual_trigger) { 528 + pipe_ctx->stream_res.tg->funcs->program_manual_trigger( 529 + pipe_ctx->stream_res.tg); 551 530 break; 552 531 } 553 532 } ··· 1009 984 if (rmcm_3dlut) { 1010 985 rmcm_3dlut->isInUse = false; 1011 986 rmcm_3dlut->stream = NULL; 1012 - rmcm_3dlut->protection_bits = 0; 1013 987 } 1014 988 } 1015 989 ··· 1020 996 for (int i = 0; i < num_rmcm; i++) { 1021 997 dc->res_pool->rmcm_3dlut[i].isInUse = false; 1022 998 dc->res_pool->rmcm_3dlut[i].stream = NULL; 1023 - dc->res_pool->rmcm_3dlut[i].protection_bits = 0; 1024 999 } 1025 1000 } 1026 1001
+9
drivers/gpu/drm/amd/display/dc/core/dc_surface.c
··· 139 139 140 140 if (pipe_ctx->plane_state && flags.bits.address) 141 141 pipe_ctx->plane_state->status.is_flip_pending = false; 142 + if (pipe_ctx->plane_state && flags.bits.histogram) 143 + memset(&pipe_ctx->plane_state->status.cm_hist, 0, 144 + sizeof(pipe_ctx->plane_state->status.cm_hist)); 142 145 143 146 break; 144 147 } ··· 157 154 158 155 if (flags.bits.address) 159 156 dc->hwss.update_pending_status(pipe_ctx); 157 + if (flags.bits.histogram) { 158 + struct dpp *dpp = pipe_ctx->plane_res.dpp; 159 + 160 + if (dpp && dpp->funcs->dpp_cm_hist_read) 161 + dpp->funcs->dpp_cm_hist_read(dpp, &pipe_ctx->plane_state->status.cm_hist); 162 + } 160 163 } 161 164 162 165 return plane_status;
+50 -11
drivers/gpu/drm/amd/display/dc/dc.h
··· 63 63 struct dcn_optc_reg_state; 64 64 struct dcn_dccg_reg_state; 65 65 66 - #define DC_VER "3.2.372" 66 + #define DC_VER "3.2.373" 67 67 68 68 /** 69 69 * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC ··· 1404 1404 struct dc_rmcm_3dlut { 1405 1405 bool isInUse; 1406 1406 const struct dc_stream_state *stream; 1407 - uint8_t protection_bits; 1408 1407 }; 1409 1408 1410 1409 struct dc_3dlut { 1411 1410 struct kref refcount; 1412 1411 struct tetrahedral_params lut_3d; 1413 - struct fixed31_32 hdr_multiplier; 1414 1412 union dc_3dlut_state state; 1415 1413 }; 1414 + 1415 + /* 3DLUT DMA (Fast Load) params */ 1416 + struct dc_3dlut_dma { 1417 + struct dc_plane_address addr; 1418 + enum dc_cm_lut_swizzle swizzle; 1419 + enum dc_cm_lut_pixel_format format; 1420 + uint16_t bias; /* FP1.5.10 */ 1421 + uint16_t scale; /* FP1.5.10 */ 1422 + enum dc_cm_lut_size size; 1423 + }; 1424 + 1425 + /* color manager */ 1426 + union dc_plane_cm_flags { 1427 + unsigned int all; 1428 + struct { 1429 + unsigned int shaper_enable : 1; 1430 + unsigned int lut3d_enable : 1; 1431 + unsigned int blend_enable : 1; 1432 + /* whether legacy (lut3d_func) or DMA is valid */ 1433 + unsigned int lut3d_dma_enable : 1; 1434 + /* RMCM lut to be used instead of MCM */ 1435 + unsigned int rmcm_enable : 1; 1436 + unsigned int reserved: 27; 1437 + } bits; 1438 + }; 1439 + 1440 + struct dc_plane_cm { 1441 + struct kref refcount; 1442 + struct dc_transfer_func shaper_func; 1443 + union { 1444 + struct dc_3dlut lut3d_func; 1445 + struct dc_3dlut_dma lut3d_dma; 1446 + }; 1447 + struct dc_transfer_func blend_func; 1448 + union dc_plane_cm_flags flags; 1449 + }; 1450 + 1416 1451 /* 1417 1452 * This structure is filled in by dc_surface_get_status and contains 1418 1453 * the last requested address and the currently active address so the called ··· 1525 1490 struct fixed31_32 hdr_mult; 1526 1491 struct colorspace_transform gamut_remap_matrix; 1527 1492 1528 - // TODO: No longer used, remove 1529 - struct dc_hdr_static_metadata hdr_static_ctx; 1530 - 1531 1493 enum dc_color_space color_space; 1532 1494 1495 + bool lut_bank_a; 1496 + struct dc_hdr_static_metadata hdr_static_ctx; 1533 1497 struct dc_3dlut lut3d_func; 1534 1498 struct dc_transfer_func in_shaper_func; 1535 1499 struct dc_transfer_func blend_tf; 1500 + enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting; 1501 + bool mcm_lut1d_enable; 1502 + struct dc_cm2_func_luts mcm_luts; 1503 + enum mpcc_movable_cm_location mcm_location; 1504 + struct dc_plane_cm cm; 1536 1505 1537 1506 struct dc_transfer_func *gamcor_tf; 1538 1507 enum surface_pixel_format format; ··· 1573 1534 1574 1535 bool is_statically_allocated; 1575 1536 enum chroma_cositing cositing; 1576 - enum dc_cm2_shaper_3dlut_setting mcm_shaper_3dlut_setting; 1577 - bool mcm_lut1d_enable; 1578 - struct dc_cm2_func_luts mcm_luts; 1579 - bool lut_bank_a; 1580 - enum mpcc_movable_cm_location mcm_location; 1581 1537 struct dc_csc_transform cursor_csc_color_matrix; 1582 1538 bool adaptive_sharpness_en; 1583 1539 int adaptive_sharpness_policy; ··· 1918 1884 * change cm2_params.cm2_luts: Fast update 1919 1885 */ 1920 1886 const struct dc_cm2_parameters *cm2_params; 1887 + const struct dc_plane_cm *cm; 1921 1888 const struct dc_csc_transform *cursor_csc_color_matrix; 1922 1889 unsigned int sdr_white_level_nits; 1923 1890 struct dc_bias_and_scale bias_and_scale; ··· 1962 1927 struct dc_3dlut *dc_create_3dlut_func(void); 1963 1928 void dc_3dlut_func_release(struct dc_3dlut *lut); 1964 1929 void dc_3dlut_func_retain(struct dc_3dlut *lut); 1930 + 1931 + struct dc_plane_cm *dc_plane_cm_create(void); 1932 + void dc_plane_cm_release(struct dc_plane_cm *cm); 1933 + void dc_plane_cm_retain(struct dc_plane_cm *cm); 1965 1934 1966 1935 void dc_post_update_surfaces_to_stream( 1967 1936 struct dc *dc);
+1 -2
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
··· 102 102 struct bp_external_encoder_control *cntl); 103 103 enum bp_result (*dac_load_detection)( 104 104 struct dc_bios *bios, 105 - enum engine_id engine_id, 106 - struct graphics_object_id ext_enc_id); 105 + enum engine_id engine_id); 107 106 enum bp_result (*transmitter_control)( 108 107 struct dc_bios *bios, 109 108 struct bp_transmitter_control *cntl);
+1 -1
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
··· 1374 1374 unsigned char DESYNC_ERROR_STATUS : 1; 1375 1375 unsigned char SINK_DEVICE_REPLAY_STATUS : 3; 1376 1376 unsigned char SINK_FRAME_LOCKED : 2; 1377 - unsigned char RESERVED : 1; 1377 + unsigned char FRAME_SKIPPING_ERROR_STATUS : 1; 1378 1378 } bits; 1379 1379 unsigned char raw; 1380 1380 };
+1
drivers/gpu/drm/amd/display/dc/dc_plane.h
··· 31 31 union dc_plane_status_update_flags { 32 32 struct { 33 33 uint32_t address : 1; 34 + uint32_t histogram : 1; 34 35 } bits; 35 36 uint32_t raw; 36 37 };
+1
drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
··· 89 89 spl_in->callbacks = dcn32_spl_callbacks; 90 90 break; 91 91 case DCN_VERSION_4_01: 92 + case DCN_VERSION_4_2: 92 93 spl_in->callbacks = dcn401_spl_callbacks; 93 94 break; 94 95 default:
+2 -2
drivers/gpu/drm/amd/display/dc/dc_trace.h
··· 23 23 24 24 #include "amdgpu_dm_trace.h" 25 25 26 - #define TRACE_DC_PIPE_STATE(pipe_ctx, index, max_pipes) \ 27 - for (index = 0; index < max_pipes; ++index) { \ 26 + #define TRACE_DC_PIPE_STATE(pipe_ctx, max_pipes) \ 27 + for (int index = 0; index < max_pipes; ++index) { \ 28 28 struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[index]; \ 29 29 if (pipe_ctx->plane_state) \ 30 30 trace_amdgpu_dm_dc_pipe_state(pipe_ctx->pipe_idx, pipe_ctx->plane_state, \
+26
drivers/gpu/drm/amd/display/dc/dc_types.h
··· 1194 1194 union replay_optimization replay_optimization; 1195 1195 /* Replay sub feature Frame Skipping is supported */ 1196 1196 bool frame_skip_supported; 1197 + /* Replay Received Frame Skipping Error HPD. */ 1198 + bool received_frame_skipping_error_hpd; 1197 1199 }; 1198 1200 1199 1201 /* Replay feature flags*/ ··· 1481 1479 const struct dc_link *link; 1482 1480 const struct dc_tunnel_settings *tunnel_settings; 1483 1481 uint32_t required_bw; 1482 + }; 1483 + 1484 + enum dc_cm_lut_swizzle { 1485 + CM_LUT_3D_SWIZZLE_LINEAR_RGB, 1486 + CM_LUT_3D_SWIZZLE_LINEAR_BGR, 1487 + CM_LUT_1D_PACKED_LINEAR 1488 + }; 1489 + 1490 + enum dc_cm_lut_pixel_format { 1491 + CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB, 1492 + CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB, 1493 + CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB, 1494 + CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB, 1495 + CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10, 1496 + CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10 1497 + }; 1498 + 1499 + enum dc_cm_lut_size { 1500 + CM_LUT_SIZE_NONE, 1501 + CM_LUT_SIZE_999, 1502 + CM_LUT_SIZE_171717, 1503 + CM_LUT_SIZE_333333, 1504 + CM_LUT_SIZE_454545, 1505 + CM_LUT_SIZE_656565, 1484 1506 }; 1485 1507 1486 1508 #endif /* DC_TYPES_H_ */
+7 -2
drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
··· 38 38 DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\ 39 39 DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\ 40 40 SR(DISPCLK_FREQ_CHANGE_CNTL),\ 41 - SR(DC_MEM_GLOBAL_PWR_REQ_CNTL) 41 + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ 42 + SR(MICROSECOND_TIME_BASE_DIV),\ 43 + SR(MILLISECOND_TIME_BASE_DIV),\ 44 + SR(DCCG_GATE_DISABLE_CNTL),\ 45 + SR(DCCG_GATE_DISABLE_CNTL2) 42 46 43 47 #define DCCG_REG_LIST_DCN2() \ 44 48 DCCG_COMMON_REG_LIST_DCN_BASE(),\ ··· 374 370 type OTG1_DROP_PIXEL;\ 375 371 type OTG2_DROP_PIXEL;\ 376 372 type OTG3_ADD_PIXEL;\ 377 - type OTG3_DROP_PIXEL; 373 + type OTG3_DROP_PIXEL;\ 374 + type RESYNC_FIFO_LEVEL_ADJUST_EN; 378 375 379 376 struct dccg_shift { 380 377 DCCG_REG_FIELD_LIST(uint8_t)
+20 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c
··· 96 96 dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; 97 97 } 98 98 99 + /* 100 + * On DCN21 S0i3 resume, BIOS programs MICROSECOND_TIME_BASE_DIV to 101 + * 0x00120464 as a marker that golden init has already been done. 102 + * dcn21_s0i3_golden_init_wa() reads this marker later in bios_golden_init() 103 + * to decide whether to skip golden init. 104 + * 105 + * dccg2_init() unconditionally overwrites MICROSECOND_TIME_BASE_DIV to 106 + * 0x00120264, destroying the marker before it can be read. 107 + * 108 + * Guard the call: if the S0i3 marker is present, skip dccg2_init() so the 109 + * WA can function correctly. bios_golden_init() will handle init in that case. 110 + */ 111 + static void dccg21_init(struct dccg *dccg) 112 + { 113 + if (dccg2_is_s0i3_golden_init_wa_done(dccg)) 114 + return; 115 + 116 + dccg2_init(dccg); 117 + } 99 118 100 119 static const struct dccg_funcs dccg21_funcs = { 101 120 .update_dpp_dto = dccg21_update_dpp_dto, ··· 122 103 .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, 123 104 .otg_add_pixel = dccg2_otg_add_pixel, 124 105 .otg_drop_pixel = dccg2_otg_drop_pixel, 125 - .dccg_init = dccg2_init, 106 + .dccg_init = dccg21_init, 126 107 .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ 127 108 .allow_clock_gating = dccg2_allow_clock_gating, 128 109 .enable_memory_low_power = dccg2_enable_memory_low_power,
+7 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h
··· 34 34 DCCG_SRII(DTO_PARAM, DPPCLK, 1),\ 35 35 DCCG_SRII(DTO_PARAM, DPPCLK, 2),\ 36 36 DCCG_SRII(DTO_PARAM, DPPCLK, 3),\ 37 - SR(REFCLK_CNTL) 37 + SR(REFCLK_CNTL),\ 38 + SR(DISPCLK_FREQ_CHANGE_CNTL),\ 39 + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ 40 + SR(MICROSECOND_TIME_BASE_DIV),\ 41 + SR(MILLISECOND_TIME_BASE_DIV),\ 42 + SR(DCCG_GATE_DISABLE_CNTL),\ 43 + SR(DCCG_GATE_DISABLE_CNTL2) 38 44 39 45 #define DCCG_MASK_SH_LIST_DCN301(mask_sh) \ 40 46 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\
+4 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h
··· 64 64 SR(DSCCLK1_DTO_PARAM),\ 65 65 SR(DSCCLK2_DTO_PARAM),\ 66 66 SR(DSCCLK_DTO_CTRL),\ 67 + SR(DCCG_GATE_DISABLE_CNTL),\ 67 68 SR(DCCG_GATE_DISABLE_CNTL2),\ 68 69 SR(DCCG_GATE_DISABLE_CNTL3),\ 69 - SR(HDMISTREAMCLK0_DTO_PARAM) 70 + SR(HDMISTREAMCLK0_DTO_PARAM),\ 71 + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ 72 + SR(MICROSECOND_TIME_BASE_DIV) 70 73 71 74 72 75 #define DCCG_MASK_SH_LIST_DCN31(mask_sh) \
+4 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h
··· 70 70 SR(DSCCLK2_DTO_PARAM),\ 71 71 SR(DSCCLK3_DTO_PARAM),\ 72 72 SR(DSCCLK_DTO_CTRL),\ 73 + SR(DCCG_GATE_DISABLE_CNTL),\ 73 74 SR(DCCG_GATE_DISABLE_CNTL2),\ 74 75 SR(DCCG_GATE_DISABLE_CNTL3),\ 75 76 SR(HDMISTREAMCLK0_DTO_PARAM),\ 76 77 SR(OTG_PIXEL_RATE_DIV),\ 77 - SR(DTBCLK_P_CNTL) 78 + SR(DTBCLK_P_CNTL),\ 79 + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ 80 + SR(MICROSECOND_TIME_BASE_DIV) 78 81 79 82 #define DCCG_MASK_SH_LIST_DCN314_COMMON(mask_sh) \ 80 83 DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\
+20
drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
··· 827 827 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 828 828 REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1); 829 829 break; 830 + case 4: 831 + if (dccg_dcn->dccg_mask->SYMCLKE_FE_ROOT_GATE_DISABLE) { 832 + REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE, 833 + SYMCLKE_FE_EN, 1, 834 + SYMCLKE_FE_SRC_SEL, link_enc_inst); 835 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 1); 836 + } 837 + break; 838 + default: 839 + return; 830 840 } 831 841 } 832 842 ··· 865 855 SYMCLKD_FE_EN, 0, 866 856 SYMCLKD_FE_SRC_SEL, 0); 867 857 break; 858 + case 4: 859 + if (dccg_dcn->dccg_mask->SYMCLKE_FE_ROOT_GATE_DISABLE) { 860 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 0); 861 + REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE, 862 + SYMCLKE_FE_EN, 0, 863 + SYMCLKE_FE_SRC_SEL, 0); 864 + } 865 + break; 866 + default: 867 + return; 868 868 } 869 869 } 870 870
+57 -2
drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c
··· 180 180 } 181 181 } 182 182 183 + void dccg42_set_pixel_rate_div( 184 + struct dccg *dccg, 185 + uint32_t otg_inst, 186 + enum pixel_rate_div tmds_div, 187 + enum pixel_rate_div unused) 188 + { 189 + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 190 + uint32_t cur_tmds_div = PIXEL_RATE_DIV_NA; 191 + uint32_t dp_dto_int; 192 + uint32_t reg_val; 193 + 194 + // only 2 and 4 are valid on dcn401 195 + if (tmds_div != PIXEL_RATE_DIV_BY_2 && tmds_div != PIXEL_RATE_DIV_BY_4) { 196 + return; 197 + } 198 + 199 + dccg401_get_pixel_rate_div(dccg, otg_inst, &cur_tmds_div, &dp_dto_int); 200 + if (tmds_div == cur_tmds_div) 201 + return; 202 + 203 + // encode enum to register value 204 + reg_val = tmds_div == PIXEL_RATE_DIV_BY_4 ? 1 : 0; 205 + 206 + switch (otg_inst) { 207 + case 0: 208 + REG_UPDATE(OTG_PIXEL_RATE_DIV, 209 + OTG0_TMDS_PIXEL_RATE_DIV, reg_val); 210 + break; 211 + case 1: 212 + REG_UPDATE(OTG_PIXEL_RATE_DIV, 213 + OTG1_TMDS_PIXEL_RATE_DIV, reg_val); 214 + break; 215 + case 2: 216 + REG_UPDATE(OTG_PIXEL_RATE_DIV, 217 + OTG2_TMDS_PIXEL_RATE_DIV, reg_val); 218 + break; 219 + case 3: 220 + REG_UPDATE(OTG_PIXEL_RATE_DIV, 221 + OTG3_TMDS_PIXEL_RATE_DIV, reg_val); 222 + break; 223 + default: 224 + BREAK_TO_DEBUGGER(); 225 + return; 226 + } 227 + } 228 + 229 + void dccg42_trigger_dio_fifo_resync(struct dccg *dccg) 230 + { 231 + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 232 + 233 + REG_UPDATE(DISPCLK_FREQ_CHANGE_CNTL, RESYNC_FIFO_LEVEL_ADJUST_EN, 1); 234 + REG_UPDATE(DISPCLK_FREQ_CHANGE_CNTL, RESYNC_FIFO_LEVEL_ADJUST_EN, 0); 235 + REG_WAIT(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_FREQ_RAMP_DONE, 1, 50, 2000); 236 + } 237 + 183 238 static void dccg42_init(struct dccg *dccg) 184 239 { 185 240 int otg_inst; ··· 295 240 .otg_drop_pixel = dccg42_otg_drop_pixel, 296 241 .disable_dsc = dccg35_disable_dscclk, 297 242 .enable_dsc = dccg35_enable_dscclk, 298 - .set_pixel_rate_div = dccg401_set_pixel_rate_div, 243 + .set_pixel_rate_div = dccg42_set_pixel_rate_div, 299 244 .get_pixel_rate_div = dccg401_get_pixel_rate_div, 300 - .trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync, 245 + .trigger_dio_fifo_resync = dccg42_trigger_dio_fifo_resync, 301 246 .set_dp_dto = dccg401_set_dp_dto, 302 247 .enable_symclk_se = dccg35_enable_symclk_se, 303 248 .disable_symclk_se = dccg35_disable_symclk_se,
+10 -1
drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.h
··· 238 238 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_SRC_SEL, mask_sh),\ 239 239 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_CLOCK_ENABLE, mask_sh),\ 240 240 DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_EN, mask_sh),\ 241 - DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, mask_sh) 241 + DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, mask_sh),\ 242 + DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, RESYNC_FIFO_LEVEL_ADJUST_EN, mask_sh) 242 243 243 244 244 245 void dccg42_otg_add_pixel(struct dccg *dccg, ··· 254 253 int phy_inst, 255 254 enum physymclk_clock_source clk_src, 256 255 bool force_enable); 256 + 257 + void dccg42_set_pixel_rate_div( 258 + struct dccg *dccg, 259 + uint32_t otg_inst, 260 + enum pixel_rate_div tmds_div, 261 + enum pixel_rate_div unused); 262 + 263 + void dccg42_trigger_dio_fifo_resync(struct dccg *dccg); 257 264 258 265 struct dccg *dccg42_create( 259 266 struct dc_context *ctx,
+16
drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
··· 28 28 #include "dc_types.h" 29 29 #include "core_types.h" 30 30 31 + static bool dmub_hw_lock_has_inbox0_lock(const struct dc *dc) 32 + { 33 + return dc->ctx && dc->ctx->dmub_srv && 34 + dc->hwss.dmub_hw_control_lock && 35 + dc->hwss.dmub_hw_control_lock_fast && 36 + dc->ctx->dmub_srv->dmub->meta_info.feature_bits.bits.inbox0_lock_support; 37 + } 38 + 31 39 void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv, 32 40 bool lock, 33 41 union dmub_hw_lock_flags *hw_locks, ··· 113 105 if (dc->ctx->dce_version >= DCN_VERSION_4_01) 114 106 return false; 115 107 108 + if (dmub_hw_lock_has_inbox0_lock(dc)) 109 + return false; 110 + 116 111 return dmub_hw_lock_mgr_does_link_require_lock(dc, link); 112 + } 113 + 114 + bool should_use_dmub_inbox0_lock_for_link(const struct dc *dc, const struct dc_link *link) 115 + { 116 + return dmub_hw_lock_has_inbox0_lock(dc) && dmub_hw_lock_mgr_does_link_require_lock(dc, link); 117 117 }
+31
drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.h
··· 46 46 * Return: true if the inbox1 lock should be used, false otherwise 47 47 */ 48 48 bool should_use_dmub_inbox1_lock(const struct dc *dc, const struct dc_link *link); 49 + 50 + /** 51 + * dmub_hw_lock_mgr_does_link_require_lock() - Returns true if the link has a feature that needs the HW lock. 52 + * 53 + * @dc: Pointer to DC object 54 + * @link: The link to check 55 + * 56 + * Return: true if the link has a feature that needs the HW lock, false otherwise 57 + */ 49 58 bool dmub_hw_lock_mgr_does_link_require_lock(const struct dc *dc, const struct dc_link *link); 59 + 60 + /** 61 + * dmub_hw_lock_mgr_does_context_require_lock() - Returns true if the context has any stream that needs the HW lock. 62 + * 63 + * @dc: Pointer to DC object 64 + * @context: The context to check 65 + * 66 + * Return: true if the context has any stream that needs the HW lock, false otherwise 67 + */ 50 68 bool dmub_hw_lock_mgr_does_context_require_lock(const struct dc *dc, const struct dc_state *context); 69 + 70 + /** 71 + * should_use_dmub_inbox0_lock_for_link() - Checks if the inbox0 interlock with DMU should be used. 72 + * 73 + * Is not functionally equivalent to inbox1 as DMUB will not own programming of the relevant locking 74 + * registers. 75 + * 76 + * @dc: pointer to DC object 77 + * @link: optional pointer to the link object to check for enabled link features 78 + * 79 + * Return: true if the inbox0 lock should be used, false otherwise 80 + */ 81 + bool should_use_dmub_inbox0_lock_for_link(const struct dc *dc, const struct dc_link *link); 51 82 52 83 #endif /*_DMUB_HW_LOCK_MGR_H_ */
+3
drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
··· 90 90 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := $(dml2_ccflags) 91 91 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.o := $(dml2_ccflags) 92 92 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := $(dml2_ccflags) 93 + CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.o := $(dml2_ccflags) 93 94 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.o := $(dml2_ccflags) 94 95 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := $(dml2_ccflags) 95 96 CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o := $(dml2_ccflags) ··· 108 107 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.o := $(dml2_rcflags) 109 108 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.o := $(dml2_rcflags) 110 109 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn4.o := $(dml2_rcflags) 110 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.o := $(dml2_rcflags) 111 111 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.o := $(dml2_rcflags) 112 112 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn3.o := $(dml2_rcflags) 113 113 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.o := $(dml2_rcflags) ··· 126 124 DML21 += src/dml2_dpmm/dml2_dpmm_dcn4.o 127 125 DML21 += src/dml2_dpmm/dml2_dpmm_factory.o 128 126 DML21 += src/dml2_mcg/dml2_mcg_dcn4.o 127 + DML21 += src/dml2_mcg/dml2_mcg_dcn42.o 129 128 DML21 += src/dml2_mcg/dml2_mcg_factory.o 130 129 DML21 += src/dml2_pmo/dml2_pmo_dcn3.o 131 130 DML21 += src/dml2_pmo/dml2_pmo_factory.o
+2 -2
drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c
··· 4089 4089 dml_uint_t MaximumSwathHeightC[__DML_NUM_PLANES__]; 4090 4090 dml_uint_t RoundedUpMaxSwathSizeBytesY[__DML_NUM_PLANES__]; 4091 4091 dml_uint_t RoundedUpMaxSwathSizeBytesC[__DML_NUM_PLANES__]; 4092 - dml_uint_t RoundedUpSwathSizeBytesY[__DML_NUM_PLANES__]; 4093 - dml_uint_t RoundedUpSwathSizeBytesC[__DML_NUM_PLANES__]; 4092 + dml_uint_t RoundedUpSwathSizeBytesY[__DML_NUM_PLANES__] = { 0 }; 4093 + dml_uint_t RoundedUpSwathSizeBytesC[__DML_NUM_PLANES__] = { 0 }; 4094 4094 dml_uint_t SwathWidthSingleDPP[__DML_NUM_PLANES__]; 4095 4095 dml_uint_t SwathWidthSingleDPPChroma[__DML_NUM_PLANES__]; 4096 4096
+46 -10
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
··· 45 45 case DCN_VERSION_4_01: 46 46 project_id = dml2_project_dcn4x_stage2_auto_drr_svp; 47 47 break; 48 + case DCN_VERSION_4_2: 49 + project_id = dml2_project_dcn42; 50 + break; 48 51 default: 49 52 project_id = dml2_project_invalid; 50 53 DC_ERR("unsupported dcn version for DML21!"); ··· 601 598 602 599 plane->composition.viewport.stationary = false; 603 600 604 - if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) { 601 + if (plane_state->cm.flags.bits.lut3d_dma_enable) { 605 602 plane->tdlut.setup_for_tdlut = true; 606 603 607 - switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) { 608 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB: 609 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR: 604 + switch (plane_state->cm.lut3d_dma.swizzle) { 605 + case CM_LUT_3D_SWIZZLE_LINEAR_RGB: 606 + case CM_LUT_3D_SWIZZLE_LINEAR_BGR: 610 607 plane->tdlut.tdlut_addressing_mode = dml2_tdlut_sw_linear; 611 608 break; 612 - case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR: 609 + case CM_LUT_1D_PACKED_LINEAR: 610 + default: 613 611 plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear; 614 612 break; 615 613 } 616 614 617 - switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) { 618 - case DC_CM2_GPU_MEM_SIZE_171717: 619 - plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube; 615 + switch (plane_state->cm.lut3d_dma.size) { 616 + case CM_LUT_SIZE_333333: 617 + plane->tdlut.tdlut_width_mode = dml2_tdlut_width_33_cube; 620 618 break; 621 - case DC_CM2_GPU_MEM_SIZE_TRANSFORMED: 619 + case CM_LUT_SIZE_171717: 622 620 default: 623 - //plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined 621 + plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube; 624 622 break; 625 623 } 626 624 } 625 + 627 626 plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable; 628 627 629 628 plane->dynamic_meta_data.enable = false; ··· 829 824 context->bw_ctx.bw.dcn.clk.subvp_prefetch_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz; 830 825 context->bw_ctx.bw.dcn.clk.stutter_efficiency.base_efficiency = in_ctx->v21.mode_programming.programming->stutter.base_percent_efficiency; 831 826 context->bw_ctx.bw.dcn.clk.stutter_efficiency.low_power_efficiency = in_ctx->v21.mode_programming.programming->stutter.low_power_percent_efficiency; 827 + context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_efficiency = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_efficiency; 828 + context->bw_ctx.bw.dcn.clk.stutter_efficiency.z8_stutter_period = in_ctx->v21.mode_programming.programming->informative.power_management.z8.stutter_period; 829 + context->bw_ctx.bw.dcn.clk.zstate_support = in_ctx->v21.mode_programming.programming->z8_stutter.supported_in_blank; /*ignore meets_eco since it is not used*/ 832 830 } 833 831 834 832 static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index wm_index) ··· 937 929 pipe_ctx->p_state_type = P_STATE_UNKNOWN; 938 930 break; 939 931 } 932 + } 933 + 934 + void dml21_init_min_clocks_for_dc_state(struct dml2_context *in_ctx, struct dc_state *context) 935 + { 936 + unsigned int lowest_dpm_state_index = 0; 937 + struct dc_clocks *min_clocks = &context->bw_ctx.bw.dcn.clk; 938 + 939 + min_clocks->dispclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dispclk.clk_values_khz[lowest_dpm_state_index]; 940 + min_clocks->dppclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dppclk.clk_values_khz[lowest_dpm_state_index]; 941 + min_clocks->dcfclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.dcfclk.clk_values_khz[lowest_dpm_state_index]; 942 + min_clocks->dramclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.uclk.clk_values_khz[lowest_dpm_state_index]; 943 + min_clocks->fclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.fclk.clk_values_khz[lowest_dpm_state_index]; 944 + min_clocks->idle_dramclk_khz = 0; 945 + min_clocks->idle_fclk_khz = 0; 946 + min_clocks->dcfclk_deep_sleep_khz = 0; 947 + min_clocks->fclk_p_state_change_support = true; 948 + min_clocks->p_state_change_support = true; 949 + min_clocks->dtbclk_en = false; 950 + min_clocks->ref_dtbclk_khz = 0; 951 + min_clocks->socclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.socclk.clk_values_khz[lowest_dpm_state_index]; 952 + min_clocks->subvp_prefetch_dramclk_khz = 0; 953 + min_clocks->subvp_prefetch_fclk_khz = 0; 954 + min_clocks->phyclk_khz = in_ctx->v21.dml_init.soc_bb.clk_table.phyclk.clk_values_khz[lowest_dpm_state_index]; 955 + min_clocks->stutter_efficiency.base_efficiency = 1; 956 + min_clocks->stutter_efficiency.low_power_efficiency = 1; 957 + min_clocks->stutter_efficiency.z8_stutter_efficiency = 1; 958 + min_clocks->stutter_efficiency.z8_stutter_period = 100000; 959 + min_clocks->zstate_support = DCN_ZSTATE_SUPPORT_ALLOW; 940 960 } 941 961
+1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.h
··· 25 25 void dml21_get_pipe_mcache_config(struct dc_state *context, struct pipe_ctx *pipe_ctx, struct dml2_per_plane_programming *pln_prog, struct dml2_pipe_configuration_descriptor *mcache_pipe_config); 26 26 void dml21_set_dc_p_state_type(struct pipe_ctx *pipe_ctx, struct dml2_per_stream_programming *stream_programming, bool sub_vp_enabled); 27 27 unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id, const struct dc_plane_state *plane, const struct dc_state *context); 28 + void dml21_init_min_clocks_for_dc_state(struct dml2_context *in_ctx, struct dc_state *context); 28 29 #endif
+1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
··· 374 374 dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state); 375 375 } 376 376 377 + 377 378 static unsigned int dml21_build_fams2_stream_programming_v2(const struct dc *dc, 378 379 struct dc_state *context, 379 380 struct dml2_context *dml_ctx)
+11 -4
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c
··· 9 9 #include "dml21_utils.h" 10 10 #include "dml21_translation_helper.h" 11 11 #include "dml2_dc_resource_mgmt.h" 12 + #include "dc_fpu.h" 13 + 14 + #if !defined(DC_RUN_WITH_PREEMPTION_ENABLED) 15 + #define DC_RUN_WITH_PREEMPTION_ENABLED(code) code 16 + #endif // !DC_RUN_WITH_PREEMPTION_ENABLED 12 17 13 18 #define INVALID -1 14 19 15 20 static bool dml21_allocate_memory(struct dml2_context **dml_ctx) 16 21 { 17 - *dml_ctx = vzalloc(sizeof(struct dml2_context)); 22 + DC_RUN_WITH_PREEMPTION_ENABLED(*dml_ctx = vzalloc(sizeof(struct dml2_context))); 18 23 if (!(*dml_ctx)) 19 24 return false; 20 25 21 - (*dml_ctx)->v21.dml_init.dml2_instance = vzalloc(sizeof(struct dml2_instance)); 26 + DC_RUN_WITH_PREEMPTION_ENABLED((*dml_ctx)->v21.dml_init.dml2_instance = vzalloc(sizeof(struct dml2_instance))); 22 27 if (!((*dml_ctx)->v21.dml_init.dml2_instance)) 23 28 return false; 24 29 ··· 33 28 (*dml_ctx)->v21.mode_support.display_config = &(*dml_ctx)->v21.display_config; 34 29 (*dml_ctx)->v21.mode_programming.display_config = (*dml_ctx)->v21.mode_support.display_config; 35 30 36 - (*dml_ctx)->v21.mode_programming.programming = vzalloc(sizeof(struct dml2_display_cfg_programming)); 31 + DC_RUN_WITH_PREEMPTION_ENABLED((*dml_ctx)->v21.mode_programming.programming = vzalloc(sizeof(struct dml2_display_cfg_programming))); 37 32 if (!((*dml_ctx)->v21.mode_programming.programming)) 38 33 return false; 39 34 ··· 75 70 bool dml21_create(const struct dc *in_dc, struct dml2_context **dml_ctx, const struct dml2_configuration_options *config) 76 71 { 77 72 /* Allocate memory for initializing DML21 instance */ 78 - if (!dml21_allocate_memory(dml_ctx)) 73 + if (!dml21_allocate_memory(dml_ctx)) { 79 74 return false; 75 + } 80 76 81 77 dml21_init(in_dc, *dml_ctx, config); 82 78 ··· 221 215 return true; 222 216 223 217 if (context->stream_count == 0) { 218 + dml21_init_min_clocks_for_dc_state(dml_ctx, context); 224 219 dml21_build_fams2_programming(in_dc, context, dml_ctx); 225 220 return true; 226 221 }
+263
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + // 3 + // Copyright 2024 Advanced Micro Devices, Inc. 4 + 5 + #ifndef __DML_DML_DCN42_SOC_BB__ 6 + #define __DML_DML_DCN42_SOC_BB__ 7 + 8 + #include "dml_top_soc_parameter_types.h" 9 + 10 + static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params = { 11 + .derate_table = { 12 + .system_active_urgent = { 13 + .dram_derate_percent_pixel = 65, 14 + .dram_derate_percent_vm = 30, 15 + .dram_derate_percent_pixel_and_vm = 60, 16 + .fclk_derate_percent = 80, 17 + .dcfclk_derate_percent = 80, 18 + }, 19 + .system_active_average = { 20 + .dram_derate_percent_pixel = 30, 21 + .dram_derate_percent_vm = 30, 22 + .dram_derate_percent_pixel_and_vm = 30, 23 + .fclk_derate_percent = 60, 24 + .dcfclk_derate_percent = 60, 25 + }, 26 + .dcn_mall_prefetch_urgent = { 27 + .dram_derate_percent_pixel = 65, 28 + .dram_derate_percent_vm = 30, 29 + .dram_derate_percent_pixel_and_vm = 60, 30 + .fclk_derate_percent = 80, 31 + .dcfclk_derate_percent = 80, 32 + }, 33 + .dcn_mall_prefetch_average = { 34 + .dram_derate_percent_pixel = 30, 35 + .dram_derate_percent_vm = 30, 36 + .dram_derate_percent_pixel_and_vm = 30, 37 + .fclk_derate_percent = 60, 38 + .dcfclk_derate_percent = 60, 39 + }, 40 + .system_idle_average = { 41 + .dram_derate_percent_pixel = 30, 42 + .dram_derate_percent_vm = 30, 43 + .dram_derate_percent_pixel_and_vm = 30, 44 + .fclk_derate_percent = 60, 45 + .dcfclk_derate_percent = 60, 46 + }, 47 + }, 48 + .writeback = { 49 + .base_latency_us = 12, 50 + .scaling_factor_us = 0, 51 + .scaling_factor_mhz = 0, 52 + }, 53 + .qos_params = { 54 + .dcn32x = { 55 + .loaded_round_trip_latency_fclk_cycles = 106, 56 + .urgent_latency_us = { 57 + .base_latency_us = 4, 58 + .base_latency_pixel_vm_us = 4, 59 + .base_latency_vm_us = 4, 60 + .scaling_factor_fclk_us = 0, 61 + .scaling_factor_mhz = 0, 62 + }, 63 + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 64 + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 65 + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 66 + }, 67 + }, 68 + .qos_type = dml2_qos_param_type_dcn3, 69 + }; 70 + 71 + static const struct dml2_soc_bb dml2_socbb_dcn42 = { 72 + .clk_table = { 73 + .wck_ratio = { 74 + .clk_values_khz = {2}, 75 + }, 76 + .uclk = { 77 + .clk_values_khz = {400000}, 78 + .num_clk_values = 1, 79 + }, 80 + .fclk = { 81 + .clk_values_khz = {400000}, 82 + .num_clk_values = 1, 83 + }, 84 + .dcfclk = { 85 + .clk_values_khz = {200000}, 86 + .num_clk_values = 1, 87 + }, 88 + .dispclk = { 89 + .clk_values_khz = {1500000}, 90 + .num_clk_values = 1, 91 + }, 92 + .dppclk = { 93 + .clk_values_khz = {1500000}, 94 + .num_clk_values = 1, 95 + }, 96 + .dtbclk = { 97 + .clk_values_khz = {600000}, 98 + .num_clk_values = 1, 99 + }, 100 + .phyclk = { 101 + .clk_values_khz = {810000}, 102 + .num_clk_values = 1, 103 + }, 104 + .socclk = { 105 + .clk_values_khz = {600000}, 106 + .num_clk_values = 1, 107 + }, 108 + .dscclk = { 109 + .clk_values_khz = {500000}, 110 + .num_clk_values = 1, 111 + }, 112 + .phyclk_d18 = { 113 + .clk_values_khz = {667000}, 114 + .num_clk_values = 1, 115 + }, 116 + .phyclk_d32 = { 117 + .clk_values_khz = {625000}, 118 + .num_clk_values = 1, 119 + }, 120 + .dram_config = { 121 + .channel_width_bytes = 4, 122 + .channel_count = 4, 123 + .alt_clock_bw_conversion = true, 124 + }, 125 + }, 126 + 127 + .qos_parameters = { 128 + .derate_table = { 129 + .system_active_urgent = { 130 + .dram_derate_percent_pixel = 65, 131 + .dram_derate_percent_vm = 30, 132 + .dram_derate_percent_pixel_and_vm = 60, 133 + .fclk_derate_percent = 80, 134 + .dcfclk_derate_percent = 80, 135 + }, 136 + .system_active_average = { 137 + .dram_derate_percent_pixel = 30, 138 + .dram_derate_percent_vm = 30, 139 + .dram_derate_percent_pixel_and_vm = 30, 140 + .fclk_derate_percent = 60, 141 + .dcfclk_derate_percent = 60, 142 + }, 143 + .dcn_mall_prefetch_urgent = { 144 + .dram_derate_percent_pixel = 65, 145 + .dram_derate_percent_vm = 30, 146 + .dram_derate_percent_pixel_and_vm = 60, 147 + .fclk_derate_percent = 80, 148 + .dcfclk_derate_percent = 80, 149 + }, 150 + .dcn_mall_prefetch_average = { 151 + .dram_derate_percent_pixel = 30, 152 + .dram_derate_percent_vm = 30, 153 + .dram_derate_percent_pixel_and_vm = 30, 154 + .fclk_derate_percent = 60, 155 + .dcfclk_derate_percent = 60, 156 + }, 157 + .system_idle_average = { 158 + .dram_derate_percent_pixel = 30, 159 + .dram_derate_percent_vm = 30, 160 + .dram_derate_percent_pixel_and_vm = 30, 161 + .fclk_derate_percent = 60, 162 + .dcfclk_derate_percent = 60, 163 + }, 164 + }, 165 + .writeback = { 166 + .base_latency_us = 12, 167 + .scaling_factor_us = 0, 168 + .scaling_factor_mhz = 0, 169 + }, 170 + .qos_params = { 171 + .dcn32x = { 172 + .loaded_round_trip_latency_fclk_cycles = 106, 173 + .urgent_latency_us = { 174 + .base_latency_us = 4, 175 + .base_latency_pixel_vm_us = 4, 176 + .base_latency_vm_us = 4, 177 + .scaling_factor_fclk_us = 0, 178 + .scaling_factor_mhz = 0, 179 + }, 180 + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 181 + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 182 + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 183 + }, 184 + }, 185 + .qos_type = dml2_qos_param_type_dcn3, 186 + }, 187 + 188 + .power_management_parameters = { 189 + .dram_clk_change_blackout_us = 29, 190 + .fclk_change_blackout_us = 0, 191 + .g7_ppt_blackout_us = 0, 192 + .stutter_enter_plus_exit_latency_us = 11, 193 + .stutter_exit_latency_us = 9, 194 + .z8_stutter_enter_plus_exit_latency_us = 300, 195 + .z8_stutter_exit_latency_us = 200, 196 + }, 197 + 198 + .vmin_limit = { 199 + .dispclk_khz = 632 * 1000, 200 + }, 201 + 202 + .dprefclk_mhz = 600, 203 + .xtalclk_mhz = 24, 204 + .pcie_refclk_mhz = 100, 205 + .dchub_refclk_mhz = 50, 206 + .mall_allocated_for_dcn_mbytes = 64, 207 + .max_outstanding_reqs = 256, 208 + .fabric_datapath_to_dcn_data_return_bytes = 32, 209 + .return_bus_width_bytes = 64, 210 + .hostvm_min_page_size_kbytes = 4, 211 + .gpuvm_min_page_size_kbytes = 256, 212 + .gpuvm_max_page_table_levels = 1, 213 + .hostvm_max_non_cached_page_table_levels = 2, 214 + .phy_downspread_percent = 0.38, 215 + .dcn_downspread_percent = 0.38, 216 + .dispclk_dppclk_vco_speed_mhz = 3000, 217 + .do_urgent_latency_adjustment = 0, 218 + .mem_word_bytes = 32, 219 + .num_dcc_mcaches = 8, 220 + .mcache_size_bytes = 2048, 221 + .mcache_line_size_bytes = 32, 222 + .max_fclk_for_uclk_dpm_khz = 2200 * 1000, 223 + }; 224 + 225 + static const struct dml2_ip_capabilities dml2_dcn42_max_ip_caps = { 226 + .pipe_count = 4, 227 + .otg_count = 4, 228 + .num_dsc = 4, 229 + .max_num_dp2p0_streams = 4, 230 + .max_num_hdmi_frl_outputs = 1, 231 + .max_num_dp2p0_outputs = 4, 232 + .rob_buffer_size_kbytes = 64, 233 + .config_return_buffer_size_in_kbytes = 1792, 234 + .config_return_buffer_segment_size_in_kbytes = 64, 235 + .meta_fifo_size_in_kentries = 32, 236 + .compressed_buffer_segment_size_in_kbytes = 64, 237 + .cursor_buffer_size = 24, 238 + .max_flip_time_us = 110, 239 + .max_flip_time_lines = 50, 240 + .hostvm_mode = 0, 241 + .subvp_drr_scheduling_margin_us = 100, 242 + .subvp_prefetch_end_to_mall_start_us = 15, 243 + .subvp_fw_processing_delay = 15, 244 + .max_vactive_det_fill_delay_us = 400, 245 + 246 + .fams2 = { 247 + .max_allow_delay_us = 100 * 1000, 248 + .scheduling_delay_us = 550, 249 + .vertical_interrupt_ack_delay_us = 40, 250 + .allow_programming_delay_us = 18, 251 + .min_allow_width_us = 20, 252 + .subvp_df_throttle_delay_us = 100, 253 + .subvp_programming_delay_us = 200, 254 + .subvp_prefetch_to_mall_delay_us = 18, 255 + .drr_programming_delay_us = 35, 256 + 257 + .lock_timeout_us = 5000, 258 + .recovery_timeout_us = 5000, 259 + .flip_programming_delay_us = 300, 260 + }, 261 + }; 262 + 263 + #endif
+13
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
··· 27 27 dml2_gfx11_sw_256kb_d_x, 28 28 dml2_gfx11_sw_256kb_r_x, 29 29 30 + dml2_sw_linear_256b, // GFX10 SW_LINEAR only accepts 256 byte aligned pitch 31 + dml2_gfx10_sw_64kb_r_x, 32 + dml2_gfx102_sw_64kb_s, 33 + dml2_gfx102_sw_64kb_s_t, 34 + dml2_gfx102_sw_64kb_s_x, 35 + dml2_gfx102_sw_64kb_r_x, 36 + 37 + dml2_linear_64elements, // GFX7 LINEAR_ALIGNED accepts pitch alignment of the maximum of 64 elements or 256 bytes 38 + dml2_gfx7_1d_thin, 39 + dml2_gfx7_2d_thin_gen_zero, 40 + dml2_gfx7_2d_thin_gen_one, 41 + dml2_gfx7_2d_thin_arlene, 42 + dml2_gfx7_2d_thin_anubis 30 43 }; 31 44 32 45 enum dml2_source_format_class {
+3
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
··· 19 19 dml2_project_dcn4x_stage1, 20 20 dml2_project_dcn4x_stage2, 21 21 dml2_project_dcn4x_stage2_auto_drr_svp, 22 + dml2_project_dcn40, 23 + dml2_project_dcn42, 22 24 }; 23 25 24 26 enum dml2_pstate_change_support { ··· 80 78 enum dml2_project_id project_id; 81 79 struct dml2_pmo_options pmo_options; 82 80 }; 81 + 83 82 84 83 struct dml2_initialize_instance_in_out { 85 84 struct dml2_instance *dml2_instance;
+111
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
··· 78 78 .subvp_swath_height_margin_lines = 16, 79 79 }; 80 80 81 + struct dml2_core_ip_params core_dcn42_ip_caps_base = { 82 + .vblank_nom_default_us = 668, 83 + .remote_iommu_outstanding_translations = 256, 84 + .rob_buffer_size_kbytes = 64, 85 + .config_return_buffer_size_in_kbytes = 1792, 86 + .config_return_buffer_segment_size_in_kbytes = 64, 87 + .compressed_buffer_segment_size_in_kbytes = 64, 88 + .dpte_buffer_size_in_pte_reqs_luma = 68, 89 + .dpte_buffer_size_in_pte_reqs_chroma = 36, 90 + .pixel_chunk_size_kbytes = 8, 91 + .alpha_pixel_chunk_size_kbytes = 4, 92 + .min_pixel_chunk_size_bytes = 1024, 93 + .writeback_chunk_size_kbytes = 8, 94 + .line_buffer_size_bits = 1171920, 95 + .max_line_buffer_lines = 32, 96 + .writeback_interface_buffer_size_kbytes = 90, 97 + 98 + //Number of pipes after DCN Pipe harvesting 99 + .max_num_dpp = 4, 100 + .max_num_otg = 4, 101 + .max_num_opp = 4, 102 + .max_num_wb = 1, 103 + .max_dchub_pscl_bw_pix_per_clk = 4, 104 + .max_pscl_lb_bw_pix_per_clk = 2, 105 + .max_lb_vscl_bw_pix_per_clk = 4, 106 + .max_vscl_hscl_bw_pix_per_clk = 4, 107 + .max_hscl_ratio = 6, 108 + .max_vscl_ratio = 6, 109 + .max_hscl_taps = 8, 110 + .max_vscl_taps = 8, 111 + .dispclk_ramp_margin_percent = 1, 112 + .dppclk_delay_subtotal = 47, 113 + .dppclk_delay_scl = 50, 114 + .dppclk_delay_scl_lb_only = 16, 115 + .dppclk_delay_cnvc_formatter = 28, 116 + .dppclk_delay_cnvc_cursor = 6, 117 + .cursor_buffer_size = 42, 118 + .cursor_chunk_size = 2, 119 + .dispclk_delay_subtotal = 125, 120 + .max_inter_dcn_tile_repeaters = 8, 121 + .writeback_max_hscl_ratio = 1, 122 + .writeback_max_vscl_ratio = 1, 123 + .writeback_min_hscl_ratio = 1, 124 + .writeback_min_vscl_ratio = 1, 125 + .writeback_max_hscl_taps = 1, 126 + .writeback_max_vscl_taps = 1, 127 + .writeback_line_buffer_buffer_size = 0, 128 + .num_dsc = 4, 129 + .maximum_dsc_bits_per_component = 12, 130 + .maximum_pixels_per_line_per_dsc_unit = 5760, 131 + .dsc422_native_support = true, 132 + .dcc_supported = true, 133 + .ptoi_supported = false, 134 + 135 + .cursor_64bpp_support = true, 136 + .dynamic_metadata_vm_enabled = false, 137 + 138 + .max_num_hdmi_frl_outputs = 0, 139 + .max_num_dp2p0_outputs = 2, 140 + .max_num_dp2p0_streams = 4, 141 + .imall_supported = 1, 142 + .max_flip_time_us = 110, 143 + .max_flip_time_lines = 50, 144 + .words_per_channel = 16, 145 + 146 + .subvp_fw_processing_delay_us = 15, 147 + .subvp_pstate_allow_width_us = 20, 148 + .subvp_swath_height_margin_lines = 16, 149 + 150 + .dcn_mrq_present = 1, 151 + .zero_size_buffer_entries = 512, 152 + .compbuf_reserved_space_zs = 64, 153 + .dcc_meta_buffer_size_bytes = 6272, 154 + .meta_chunk_size_kbytes = 2, 155 + .min_meta_chunk_size_bytes = 256, 156 + 157 + .dchub_arb_to_ret_delay = 102, 158 + .hostvm_mode = 1, 159 + }; 160 + 81 161 static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities *ip_caps, const struct dml2_core_ip_params *ip_params) 82 162 { 83 163 ip_caps->pipe_count = ip_params->max_num_dpp; ··· 223 143 core->clean_me_up.mode_lib.ip.subvp_swath_height_margin_lines = core_dcn4_ip_caps_base.subvp_swath_height_margin_lines; 224 144 } else { 225 145 memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn4_ip_caps_base, sizeof(struct dml2_core_ip_params)); 146 + patch_ip_params_with_ip_caps(&core->clean_me_up.mode_lib.ip, in_out->ip_caps); 147 + core->clean_me_up.mode_lib.ip.imall_supported = false; 148 + } 149 + 150 + memcpy(&core->clean_me_up.mode_lib.soc, in_out->soc_bb, sizeof(struct dml2_soc_bb)); 151 + memcpy(&core->clean_me_up.mode_lib.ip_caps, in_out->ip_caps, sizeof(struct dml2_ip_capabilities)); 152 + 153 + return true; 154 + } 155 + 156 + bool core_dcn42_initialize(struct dml2_core_initialize_in_out *in_out) 157 + { 158 + struct dml2_core_instance *core = in_out->instance; 159 + 160 + if (!in_out->minimum_clock_table) 161 + return false; 162 + else 163 + core->minimum_clock_table = in_out->minimum_clock_table; 164 + 165 + if (in_out->explicit_ip_bb && in_out->explicit_ip_bb_size > 0) { 166 + memcpy(&core->clean_me_up.mode_lib.ip, in_out->explicit_ip_bb, in_out->explicit_ip_bb_size); 167 + 168 + // FIXME_STAGE2: 169 + // DV still uses stage1 ip_param_st for each variant, need to patch the ip_caps with ip_param info 170 + // Should move DV to use ip_caps but need move more overrides to ip_caps 171 + patch_ip_caps_with_explicit_ip_params(in_out->ip_caps, in_out->explicit_ip_bb); 172 + core->clean_me_up.mode_lib.ip.subvp_pstate_allow_width_us = core_dcn4_ip_caps_base.subvp_pstate_allow_width_us; 173 + core->clean_me_up.mode_lib.ip.subvp_fw_processing_delay_us = core_dcn4_ip_caps_base.subvp_pstate_allow_width_us; 174 + core->clean_me_up.mode_lib.ip.subvp_swath_height_margin_lines = core_dcn4_ip_caps_base.subvp_swath_height_margin_lines; 175 + } else { 176 + memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn42_ip_caps_base, sizeof(struct dml2_core_ip_params)); 226 177 patch_ip_params_with_ip_caps(&core->clean_me_up.mode_lib.ip, in_out->ip_caps); 227 178 core->clean_me_up.mode_lib.ip.imall_supported = false; 228 179 }
+1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.h
··· 5 5 #ifndef __DML2_CORE_DCN4_H__ 6 6 #define __DML2_CORE_DCN4_H__ 7 7 bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out); 8 + bool core_dcn42_initialize(struct dml2_core_initialize_in_out *in_out); 8 9 bool core_dcn4_mode_support(struct dml2_core_mode_support_in_out *in_out); 9 10 bool core_dcn4_mode_programming(struct dml2_core_mode_programming_in_out *in_out); 10 11 bool core_dcn4_populate_informative(struct dml2_core_populate_informative_in_out *in_out);
+9
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_factory.c
··· 21 21 case dml2_project_dcn4x_stage1: 22 22 result = false; 23 23 break; 24 + case dml2_project_dcn40: 24 25 case dml2_project_dcn4x_stage2: 25 26 case dml2_project_dcn4x_stage2_auto_drr_svp: 26 27 out->initialize = &core_dcn4_initialize; 28 + out->mode_support = &core_dcn4_mode_support; 29 + out->mode_programming = &core_dcn4_mode_programming; 30 + out->populate_informative = &core_dcn4_populate_informative; 31 + out->calculate_mcache_allocation = &core_dcn4_calculate_mcache_allocation; 32 + result = true; 33 + break; 34 + case dml2_project_dcn42: 35 + out->initialize = &core_dcn42_initialize; 27 36 out->mode_support = &core_dcn4_mode_support; 28 37 out->mode_programming = &core_dcn4_mode_programming; 29 38 out->populate_informative = &core_dcn4_populate_informative;
+61 -2
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c
··· 428 428 429 429 unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel) 430 430 { 431 + if (dml2_core_utils_get_gfx_version(sw_mode) == 10 || dml2_core_utils_get_gfx_version(sw_mode) == 7) { 432 + return dml2_core_utils_get_tile_block_size_bytes_backcompat(sw_mode, byte_per_pixel); 433 + } 431 434 432 435 if (sw_mode == dml2_sw_linear) 433 436 return 256; ··· 462 459 }; 463 460 } 464 461 462 + unsigned int dml2_core_utils_get_tile_block_size_bytes_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel) 463 + { 464 + if (sw_mode == dml2_sw_linear_256b) 465 + return 256; 466 + else if (sw_mode == dml2_gfx10_sw_64kb_r_x) 467 + return 65536; 468 + else if (sw_mode == dml2_gfx102_sw_64kb_s) 469 + return 65536; 470 + else if (sw_mode == dml2_gfx102_sw_64kb_s_t) 471 + return 65536; 472 + else if (sw_mode == dml2_gfx102_sw_64kb_s_x) 473 + return 65536; 474 + else if (sw_mode == dml2_gfx102_sw_64kb_r_x) 475 + return 65536; 476 + else if (sw_mode == dml2_linear_64elements) 477 + return 256; 478 + else if (sw_mode == dml2_gfx7_1d_thin) 479 + return 256; 480 + else if (sw_mode == dml2_gfx7_2d_thin_gen_zero) 481 + return (128 * 64 * byte_per_pixel); 482 + else if (sw_mode == dml2_gfx7_2d_thin_gen_one) 483 + return (128 * 128 * byte_per_pixel); 484 + else if (sw_mode == dml2_gfx7_2d_thin_arlene) 485 + return (64 * 32 * byte_per_pixel); 486 + else if (sw_mode == dml2_gfx7_2d_thin_anubis) 487 + return (128 * 128 * byte_per_pixel); 488 + else { 489 + DML_ASSERT(0); 490 + return 256; 491 + }; 492 + } 493 + 465 494 bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel) 466 495 { 467 - return (byte_per_pixel != 2); 496 + if (dml2_core_utils_get_gfx_version(sw_mode) == 10 || dml2_core_utils_get_gfx_version(sw_mode) == 7) { 497 + return dml2_core_utils_get_segment_horizontal_contiguous_backcompat(sw_mode, byte_per_pixel); 498 + } else { 499 + return (byte_per_pixel != 2); 500 + } 501 + } 502 + 503 + bool dml2_core_utils_get_segment_horizontal_contiguous_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel) 504 + { 505 + return !((byte_per_pixel == 4) && 506 + ((sw_mode == dml2_gfx10_sw_64kb_r_x) || (sw_mode == dml2_gfx102_sw_64kb_s) || (sw_mode == dml2_gfx102_sw_64kb_s_t) || (sw_mode == dml2_gfx102_sw_64kb_s_x))); 468 507 } 469 508 470 509 bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode) 471 510 { 472 - return sw_mode == dml2_sw_linear; 511 + return (sw_mode == dml2_sw_linear || sw_mode == dml2_sw_linear_256b || sw_mode == dml2_linear_64elements); 473 512 }; 474 513 475 514 ··· 544 499 sw_mode == dml2_gfx11_sw_256kb_d_x || 545 500 sw_mode == dml2_gfx11_sw_256kb_r_x) 546 501 version = 11; 502 + else if (sw_mode == dml2_sw_linear_256b || 503 + sw_mode == dml2_gfx10_sw_64kb_r_x || 504 + sw_mode == dml2_gfx102_sw_64kb_s || 505 + sw_mode == dml2_gfx102_sw_64kb_s_t || 506 + sw_mode == dml2_gfx102_sw_64kb_s_x || 507 + sw_mode == dml2_gfx102_sw_64kb_r_x) 508 + version = 10; 509 + else if (sw_mode == dml2_linear_64elements || 510 + sw_mode == dml2_gfx7_1d_thin || 511 + sw_mode == dml2_gfx7_2d_thin_gen_zero || 512 + sw_mode == dml2_gfx7_2d_thin_gen_one || 513 + sw_mode == dml2_gfx7_2d_thin_arlene || 514 + sw_mode == dml2_gfx7_2d_thin_anubis) 515 + version = 7; 547 516 else { 548 517 DML_LOG_VERBOSE("ERROR: Invalid sw_mode setting! val=%u\n", sw_mode); 549 518 DML_ASSERT(0);
+2
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h
··· 22 22 bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg); 23 23 unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel); 24 24 bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel); 25 + unsigned int dml2_core_utils_get_tile_block_size_bytes_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel); 26 + bool dml2_core_utils_get_segment_horizontal_contiguous_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel); 25 27 bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan); 26 28 bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode); 27 29 int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode);
+33
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
··· 802 802 803 803 return true; 804 804 } 805 + bool dpmm_dcn42_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_out) 806 + { 807 + const struct dml2_display_cfg *display_cfg = &in_out->display_cfg->display_config; 808 + const struct dml2_core_internal_display_mode_lib *mode_lib = &in_out->core->clean_me_up.mode_lib; 809 + struct dml2_dchub_global_register_set *dchubbub_regs = &in_out->programming->global_regs; 810 + 811 + double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz; 812 + 813 + /* set A */ 814 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz); 815 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 816 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz); 817 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_enter_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 818 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].sr_exit_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterExitWatermark * refclk_freq_in_mhz); 819 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz); 820 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz); 821 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); 822 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].usr = (int unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz); 823 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].refcyc_per_trip_to_mem = (unsigned int)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); 824 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].refcyc_per_meta_trip_to_mem = (unsigned int)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); 825 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_flip = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip * 1000); 826 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_nom = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidth * 1000); 827 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A].frac_urg_bw_mall = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthMALL * 1000); 828 + 829 + /* set B */ 830 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_B] = dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]; 831 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_C] = dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]; 832 + dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_D] = dchubbub_regs->wm_regs[DML2_DCHUB_WATERMARK_SET_A]; 833 + 834 + dchubbub_regs->num_watermark_sets = 4; 835 + 836 + return true; 837 + }
+1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.h
··· 10 10 bool dpmm_dcn3_map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out); 11 11 bool dpmm_dcn4_map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out); 12 12 bool dpmm_dcn4_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_out); 13 + bool dpmm_dcn42_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_out); 13 14 14 15 #endif
+6
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
··· 31 31 out->map_watermarks = &dummy_map_watermarks; 32 32 result = true; 33 33 break; 34 + case dml2_project_dcn40: 34 35 case dml2_project_dcn4x_stage2: 35 36 out->map_mode_to_soc_dpm = &dpmm_dcn3_map_mode_to_soc_dpm; 36 37 out->map_watermarks = &dummy_map_watermarks; ··· 40 39 case dml2_project_dcn4x_stage2_auto_drr_svp: 41 40 out->map_mode_to_soc_dpm = &dpmm_dcn4_map_mode_to_soc_dpm; 42 41 out->map_watermarks = &dpmm_dcn4_map_watermarks; 42 + result = true; 43 + break; 44 + case dml2_project_dcn42: 45 + out->map_mode_to_soc_dpm = &dpmm_dcn4_map_mode_to_soc_dpm; 46 + out->map_watermarks = &dpmm_dcn42_map_watermarks; 43 47 result = true; 44 48 break; 45 49 case dml2_project_invalid:
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn4.h
+76
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.c
··· 1 + // SPDX-License-Identifier: MIT 2 + // 3 + // Copyright 2026 Advanced Micro Devices, Inc. 4 + 5 + #include "dml2_mcg_dcn42.h" 6 + #include "dml_top_soc_parameter_types.h" 7 + 8 + static unsigned long long uclk_to_dram_bw_kbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config, unsigned long wck_ratio) 9 + { 10 + unsigned long long bw_kbps = 0; 11 + 12 + bw_kbps = (unsigned long long) uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * wck_ratio * 2; 13 + return bw_kbps; 14 + } 15 + 16 + static bool build_min_clk_table_coarse_grained(const struct dml2_soc_bb *soc_bb, struct dml2_mcg_min_clock_table *min_table) 17 + { 18 + int i; 19 + 20 + for (i = 0; i < soc_bb->clk_table.fclk.num_clk_values; i++) { 21 + if (i < soc_bb->clk_table.uclk.num_clk_values) { 22 + min_table->dram_bw_table.entries[i].pre_derate_dram_bw_kbps = 23 + uclk_to_dram_bw_kbps(soc_bb->clk_table.uclk.clk_values_khz[i], &soc_bb->clk_table.dram_config, soc_bb->clk_table.wck_ratio.clk_values_khz[i]); 24 + min_table->dram_bw_table.entries[i].min_uclk_khz = soc_bb->clk_table.uclk.clk_values_khz[i]; 25 + } else { 26 + min_table->dram_bw_table.entries[i].pre_derate_dram_bw_kbps = min_table->dram_bw_table.entries[soc_bb->clk_table.uclk.num_clk_values - 1].pre_derate_dram_bw_kbps; 27 + min_table->dram_bw_table.entries[i].min_uclk_khz = soc_bb->clk_table.uclk.clk_values_khz[soc_bb->clk_table.uclk.num_clk_values - 1]; 28 + } 29 + 30 + min_table->dram_bw_table.entries[i].min_dcfclk_khz = soc_bb->clk_table.dcfclk.clk_values_khz[i]; 31 + min_table->dram_bw_table.entries[i].min_fclk_khz = soc_bb->clk_table.fclk.clk_values_khz[i]; 32 + } 33 + min_table->dram_bw_table.num_entries = soc_bb->clk_table.fclk.num_clk_values; 34 + 35 + return true; 36 + } 37 + 38 + static bool build_min_clock_table(const struct dml2_soc_bb *soc_bb, struct dml2_mcg_min_clock_table *min_table) 39 + { 40 + bool result; 41 + 42 + if (!soc_bb || !min_table) 43 + return false; 44 + 45 + 46 + if (soc_bb->clk_table.uclk.num_clk_values > DML_MCG_MAX_CLK_TABLE_SIZE) 47 + return false; 48 + 49 + min_table->fixed_clocks_khz.amclk = 0; 50 + min_table->fixed_clocks_khz.dprefclk = soc_bb->dprefclk_mhz * 1000; 51 + min_table->fixed_clocks_khz.pcierefclk = soc_bb->pcie_refclk_mhz * 1000; 52 + min_table->fixed_clocks_khz.dchubrefclk = soc_bb->dchub_refclk_mhz * 1000; 53 + min_table->fixed_clocks_khz.xtalclk = soc_bb->xtalclk_mhz * 1000; 54 + 55 + min_table->max_clocks_khz.dispclk = soc_bb->clk_table.dispclk.clk_values_khz[soc_bb->clk_table.dispclk.num_clk_values - 1]; 56 + min_table->max_clocks_khz.dppclk = soc_bb->clk_table.dppclk.clk_values_khz[soc_bb->clk_table.dppclk.num_clk_values - 1]; 57 + min_table->max_clocks_khz.dscclk = soc_bb->clk_table.dscclk.clk_values_khz[soc_bb->clk_table.dscclk.num_clk_values - 1]; 58 + min_table->max_clocks_khz.dtbclk = soc_bb->clk_table.dtbclk.clk_values_khz[soc_bb->clk_table.dtbclk.num_clk_values - 1]; 59 + min_table->max_clocks_khz.phyclk = soc_bb->clk_table.phyclk.clk_values_khz[soc_bb->clk_table.phyclk.num_clk_values - 1]; 60 + 61 + min_table->max_ss_clocks_khz.dispclk = (unsigned int)((double)min_table->max_clocks_khz.dispclk / (1.0 + soc_bb->dcn_downspread_percent / 100.0)); 62 + min_table->max_ss_clocks_khz.dppclk = (unsigned int)((double)min_table->max_clocks_khz.dppclk / (1.0 + soc_bb->dcn_downspread_percent / 100.0)); 63 + min_table->max_ss_clocks_khz.dtbclk = (unsigned int)((double)min_table->max_clocks_khz.dtbclk / (1.0 + soc_bb->dcn_downspread_percent / 100.0)); 64 + 65 + min_table->max_clocks_khz.dcfclk = soc_bb->clk_table.dcfclk.clk_values_khz[soc_bb->clk_table.dcfclk.num_clk_values - 1]; 66 + min_table->max_clocks_khz.fclk = soc_bb->clk_table.fclk.clk_values_khz[soc_bb->clk_table.fclk.num_clk_values - 1]; 67 + 68 + result = build_min_clk_table_coarse_grained(soc_bb, min_table); 69 + 70 + return result; 71 + } 72 + 73 + bool mcg_dcn42_build_min_clock_table(struct dml2_mcg_build_min_clock_table_params_in_out *in_out) 74 + { 75 + return build_min_clock_table(in_out->soc_bb, in_out->min_clk_table); 76 + }
+12
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_dcn42.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + // 3 + // Copyright 2026 Advanced Micro Devices, Inc. 4 + 5 + #ifndef __DML2_MCG_DCN42_H__ 6 + #define __DML2_MCG_DCN42_H__ 7 + 8 + #include "dml2_internal_shared_types.h" 9 + 10 + bool mcg_dcn42_build_min_clock_table(struct dml2_mcg_build_min_clock_table_params_in_out *in_out); 11 + 12 + #endif
+6
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
··· 4 4 5 5 #include "dml2_mcg_factory.h" 6 6 #include "dml2_mcg_dcn4.h" 7 + #include "dml2_mcg_dcn42.h" 7 8 #include "dml2_external_lib_deps.h" 8 9 9 10 static bool dummy_build_min_clock_table(struct dml2_mcg_build_min_clock_table_params_in_out *in_out) ··· 26 25 out->build_min_clock_table = &dummy_build_min_clock_table; 27 26 result = true; 28 27 break; 28 + case dml2_project_dcn40: 29 29 case dml2_project_dcn4x_stage2: 30 30 case dml2_project_dcn4x_stage2_auto_drr_svp: 31 31 out->build_min_clock_table = &mcg_dcn4_build_min_clock_table; 32 + result = true; 33 + break; 34 + case dml2_project_dcn42: 35 + out->build_min_clock_table = &mcg_dcn42_build_min_clock_table; 32 36 result = true; 33 37 break; 34 38 case dml2_project_invalid:
+6
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
··· 23 23 .allow_state_increase = true, 24 24 }, 25 25 26 + 26 27 // Then VBlank 27 28 { 28 29 .per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na }, ··· 53 52 .per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_na, dml2_pstate_method_na }, 54 53 .allow_state_increase = true, 55 54 }, 55 + 56 56 57 57 // Then VActive + VBlank 58 58 { ··· 115 113 .allow_state_increase = true, 116 114 }, 117 115 116 + 118 117 // VActive + 1 VBlank 119 118 { 120 119 .per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vblank, dml2_pstate_method_na }, ··· 151 148 .per_stream_pstate_method = { dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive, dml2_pstate_method_vactive }, 152 149 .allow_state_increase = true, 153 150 }, 151 + 154 152 155 153 // VActive + 1 VBlank 156 154 { ··· 1655 1651 if (svp_count > 0 && (pmo->options->disable_svp || !all_timings_support_svp(pmo, display_cfg, svp_stream_mask))) 1656 1652 return false; 1657 1653 1654 + 1658 1655 return is_config_schedulable(pmo, display_cfg, pstate_strategy); 1659 1656 } 1660 1657 ··· 1984 1979 display_config->stage3.pstate_switch_modes[plane_index] = dml2_pstate_method_na; 1985 1980 } 1986 1981 } 1982 + 1987 1983 1988 1984 static void setup_planes_for_drr_by_mask(struct display_configuation_with_meta *display_config, 1989 1985 struct dml2_pmo_instance *pmo,
+3 -1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c
··· 3 3 // Copyright 2024 Advanced Micro Devices, Inc. 4 4 5 5 #include "dml2_pmo_factory.h" 6 - #include "dml2_pmo_dcn4_fams2.h" 7 6 #include "dml2_pmo_dcn3.h" 7 + #include "dml2_pmo_dcn4_fams2.h" 8 8 #include "dml2_external_lib_deps.h" 9 9 10 10 static bool dummy_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in_out) ··· 37 37 out->optimize_dcc_mcache = pmo_dcn4_fams2_optimize_dcc_mcache; 38 38 result = true; 39 39 break; 40 + case dml2_project_dcn40: 40 41 case dml2_project_dcn4x_stage2: 41 42 out->initialize = pmo_dcn3_initialize; 42 43 ··· 57 56 58 57 result = true; 59 58 break; 59 + case dml2_project_dcn42: 60 60 case dml2_project_dcn4x_stage2_auto_drr_svp: 61 61 out->initialize = pmo_dcn4_fams2_initialize; 62 62
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.h
+2
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_interfaces.c
··· 17 17 case dml2_project_dcn4x_stage1: 18 18 case dml2_project_dcn4x_stage2: 19 19 case dml2_project_dcn4x_stage2_auto_drr_svp: 20 + case dml2_project_dcn40: 21 + case dml2_project_dcn42: 20 22 return dml2_top_soc15_initialize_instance(in_out); 21 23 case dml2_project_invalid: 22 24 default:
-1
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_legacy.c
··· 3 3 // Copyright 2024 Advanced Micro Devices, Inc. 4 4 5 5 #include "dml2_top_legacy.h" 6 - #include "dml2_top_soc15.h" 7 6 #include "dml2_core_factory.h" 8 7 #include "dml2_pmo_factory.h" 9 8 #include "display_mode_core_structs.h"
+3
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
··· 410 410 } legacy; 411 411 }; 412 412 413 + 413 414 struct dml2_core_mode_programming_in_out { 414 415 /* 415 416 * Inputs ··· 501 500 bool (*mode_programming)(struct dml2_core_mode_programming_in_out *in_out); 502 501 bool (*populate_informative)(struct dml2_core_populate_informative_in_out *in_out); 503 502 bool (*calculate_mcache_allocation)(struct dml2_calculate_mcache_allocation_in_out *in_out); 503 + 504 504 505 505 struct { 506 506 struct dml2_core_internal_display_mode_lib mode_lib; ··· 754 752 bool (*init_for_stutter)(struct dml2_pmo_init_for_stutter_in_out *in_out); 755 753 bool (*test_for_stutter)(struct dml2_pmo_test_for_stutter_in_out *in_out); 756 754 bool (*optimize_for_stutter)(struct dml2_pmo_optimize_for_stutter_in_out *in_out); 755 + 757 756 758 757 struct dml2_pmo_init_data init_data; 759 758 struct dml2_pmo_scratch scratch;
+38 -3
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_mall_phantom.c
··· 357 357 */ 358 358 static bool subvp_subvp_schedulable(struct dml2_context *ctx, struct dc_state *context) 359 359 { 360 - struct pipe_ctx *subvp_pipes[2]; 360 + struct pipe_ctx *subvp_pipes[2] = { NULL, NULL }; 361 361 struct dc_stream_state *phantom = NULL; 362 362 uint32_t microschedule_lines = 0; 363 363 uint32_t index = 0; ··· 368 368 for (i = 0; i < ctx->config.dcn_pipe_count; i++) { 369 369 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 370 370 uint32_t time_us = 0; 371 + 372 + if (pipe == NULL || pipe->stream == NULL) 373 + continue; 371 374 372 375 /* Loop to calculate the maximum microschedule time between the two SubVP pipes, 373 376 * and also to store the two main SubVP pipe pointers in subvp_pipes[2]. ··· 389 386 if (time_us > max_microschedule_us) 390 387 max_microschedule_us = time_us; 391 388 392 - subvp_pipes[index] = pipe; 393 - index++; 389 + if (index < 2) 390 + subvp_pipes[index++] = pipe; 394 391 395 392 // Maximum 2 SubVP pipes 396 393 if (index == 2) 397 394 break; 398 395 } 399 396 } 397 + 398 + /* Minimal guard to avoid C6001 before subvp_pipes[0]/[1] dereference */ 399 + if (index < 2 || !subvp_pipes[0] || !subvp_pipes[1]) 400 + return false; 401 + 400 402 vactive1_us = ((subvp_pipes[0]->stream->timing.v_addressable * subvp_pipes[0]->stream->timing.h_total) / 401 403 (double)(subvp_pipes[0]->stream->timing.pix_clk_100hz * 100)) * 1000000; 402 404 vactive2_us = ((subvp_pipes[1]->stream->timing.v_addressable * subvp_pipes[1]->stream->timing.h_total) / ··· 467 459 break; 468 460 } 469 461 462 + if (pipe == NULL || pipe->stream == NULL) { 463 + // Defensive: should never happen, try to catch in debug 464 + ASSERT(0); 465 + return false; 466 + } 470 467 phantom_stream = ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, pipe->stream); 471 468 main_timing = &pipe->stream->timing; 472 469 phantom_timing = &phantom_stream->timing; ··· 562 549 if (!subvp_pipe && pipe_mall_type == SUBVP_MAIN) 563 550 subvp_pipe = pipe; 564 551 } 552 + 553 + if (subvp_pipe == NULL) { 554 + // Defensive: should never happen, catch in debug 555 + ASSERT(0); 556 + return false; 557 + } 558 + 565 559 // Use ignore_msa_timing_param flag to identify as DRR 566 560 if (found && context->res_ctx.pipe_ctx[vblank_index].stream->ignore_msa_timing_param) { 567 561 // SUBVP + DRR case ··· 773 753 return; 774 754 } 775 755 756 + /* Minimal NULL guard for C6011 */ 757 + if (!phantom_plane) { 758 + ASSERT(0); 759 + continue; 760 + } 761 + 776 762 memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address)); 777 763 memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality, 778 764 sizeof(phantom_plane->scaling_quality)); ··· 906 880 if (ctx->config.svp_pstate.force_disable_subvp) 907 881 return false; 908 882 883 + if (!state) { 884 + ASSERT(0); 885 + return false; 886 + } 887 + 909 888 if (!all_pipes_have_stream_and_plane(ctx, state)) 910 889 return false; 911 890 ··· 929 898 } 930 899 931 900 if (enough_pipes_for_subvp(ctx, state) && assign_subvp_pipe(ctx, state, &dc_pipe_idx)) { 901 + if (state->res_ctx.pipe_ctx[dc_pipe_idx].stream == NULL) { 902 + ASSERT(0); 903 + return false; 904 + } 932 905 dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(ctx, state->res_ctx.pipe_ctx[dc_pipe_idx].stream->stream_id); 933 906 svp_height = mode_support_info->SubViewportLinesNeededInMALL[dml_pipe_idx]; 934 907 vstartup = dml_get_vstartup_calculated(&ctx->v20.dml_core_ctx, dml_pipe_idx);
+2 -1
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c
··· 84 84 bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) 85 85 { 86 86 // TODO : Temporarily add DCN_VERSION_3_2 for N-1 validation. Remove DCN_VERSION_3_2 after N-1 validation phase is complete. 87 - if ((in_dc->debug.using_dml21) && (in_dc->ctx->dce_version >= DCN_VERSION_4_01)) 87 + if ((in_dc->debug.using_dml21) && (in_dc->ctx->dce_version >= DCN_VERSION_4_01)) { 88 88 return dml21_create(in_dc, dml2, config); 89 + } 89 90 90 91 // Allocate Mode Lib Ctx 91 92 *dml2 = dml2_allocate_memory();
+6 -2
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
··· 172 172 scl_data->taps.h_taps_c = in_taps->h_taps_c; 173 173 174 174 if (!dpp->ctx->dc->debug.always_scale) { 175 - if (IDENTITY_RATIO(scl_data->ratios.horz)) 175 + if (IDENTITY_RATIO(scl_data->ratios.horz)) { 176 176 scl_data->taps.h_taps = 1; 177 - if (IDENTITY_RATIO(scl_data->ratios.vert)) 177 + scl_data->taps.h_taps_c = 1; 178 + } 179 + if (IDENTITY_RATIO(scl_data->ratios.vert)) { 178 180 scl_data->taps.v_taps = 1; 181 + scl_data->taps.v_taps_c = 1; 182 + } 179 183 if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 180 184 scl_data->taps.h_taps_c = 1; 181 185 if (IDENTITY_RATIO(scl_data->ratios.vert_c))
+6 -2
drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c
··· 524 524 scl_data->taps.v_taps_c = max_taps_c; 525 525 526 526 if (!dpp->ctx->dc->debug.always_scale) { 527 - if (IDENTITY_RATIO(scl_data->ratios.horz)) 527 + if (IDENTITY_RATIO(scl_data->ratios.horz)) { 528 528 scl_data->taps.h_taps = 1; 529 - if (IDENTITY_RATIO(scl_data->ratios.vert)) 529 + scl_data->taps.h_taps_c = 1; 530 + } 531 + if (IDENTITY_RATIO(scl_data->ratios.vert)) { 530 532 scl_data->taps.v_taps = 1; 533 + scl_data->taps.v_taps_c = 1; 534 + } 531 535 if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 532 536 scl_data->taps.h_taps_c = 1; 533 537 if (IDENTITY_RATIO(scl_data->ratios.vert_c))
+2
drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp_cm.c
··· 132 132 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 133 133 if (power_on) { 134 134 REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); 135 + if (dpp_base->ctx->dc->caps.ips_v2_support) 136 + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_DIS, 1); 135 137 REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); 136 138 } else { 137 139 dpp_base->ctx->dc->optimized_required = true;
+22 -1
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
··· 155 155 if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) { 156 156 if (power_on) { 157 157 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0); 158 - REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5); 158 + if (dpp->base.ctx->dc->caps.ips_v2_support) { 159 + /*hw default changes to LS*/ 160 + REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_DIS, 1); 161 + REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 100); 162 + } else 163 + REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5); 159 164 } else { 160 165 if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) { 161 166 dpp->base.ctx->dc->optimized_required = true; ··· 961 956 *bs_coeffs_updated = false; 962 957 963 958 PERF_TRACE(); 959 + /*power on isharp_delta_mem first*/ 960 + if (dpp_base->ctx->dc->caps.ips_v2_support) { 961 + /*HW default is LS, need to wake up*/ 962 + REG_UPDATE_2(ISHARP_DELTA_LUT_MEM_PWR_CTRL, 963 + ISHARP_DELTA_LUT_MEM_PWR_FORCE, 0, 964 + ISHARP_DELTA_LUT_MEM_PWR_DIS, 1); 965 + REG_WAIT(ISHARP_DELTA_LUT_MEM_PWR_CTRL, 966 + ISHARP_DELTA_LUT_MEM_PWR_STATE, 0, 1, 100); 967 + } 964 968 /* ISHARP_MODE */ 965 969 REG_SET_6(ISHARP_MODE, 0, 966 970 ISHARP_EN, scl_data->dscl_prog_data.isharp_en, ··· 1047 1033 } 1048 1034 } 1049 1035 1036 + /*power on isharp_delta_mem first*/ 1037 + if (dpp_base->ctx->dc->caps.ips_v2_support) { 1038 + /*HW default is LS, need to wake up*/ 1039 + REG_UPDATE_SEQ_2(ISHARP_DELTA_LUT_MEM_PWR_CTRL, 1040 + ISHARP_DELTA_LUT_MEM_PWR_FORCE, 0, 1041 + ISHARP_DELTA_LUT_MEM_PWR_DIS, 0); 1042 + } 1050 1043 PERF_TRACE(); 1051 1044 } // dpp401_dscl_program_isharp 1052 1045 /**
+5
drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_stream_encoder.c
··· 640 640 REG_UPDATE(DP_STREAM_ENC_AUDIO_CONTROL, 641 641 DP_STREAM_ENC_INPUT_MUX_AUDIO_STREAM_SOURCE_SEL, az_inst); 642 642 643 + if (enc3->hpo_se_mask->DP_STREAM_ENC_APG_CLOCK_EN) { 644 + /*enable apg clk*/ 645 + REG_UPDATE(DP_STREAM_ENC_AUDIO_CONTROL, 646 + DP_STREAM_ENC_APG_CLOCK_EN, 1); 647 + } 643 648 ASSERT(enc->apg); 644 649 enc->apg->funcs->se_audio_setup(enc->apg, az_inst, info); 645 650 }
-4
drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
··· 1151 1151 { 1152 1152 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); 1153 1153 1154 - unsigned int cur_compbuf_size_seg = 0; 1155 - 1156 1154 if (safe_to_increase || compbuf_size_seg <= hubbub2->compbuf_size_segments) { 1157 1155 if (compbuf_size_seg > hubbub2->compbuf_size_segments) { 1158 1156 REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1, 100); ··· 1163 1165 + hubbub2->det3_size + compbuf_size_seg <= hubbub2->crb_size_segs); 1164 1166 REG_UPDATE(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, compbuf_size_seg); 1165 1167 hubbub2->compbuf_size_segments = compbuf_size_seg; 1166 - 1167 - ASSERT(REG_GET(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, &cur_compbuf_size_seg) && !cur_compbuf_size_seg); 1168 1168 } 1169 1169 } 1170 1170
+134 -67
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
··· 41 41 hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name 42 42 43 43 void hubp401_program_3dlut_fl_addr(struct hubp *hubp, 44 - const struct dc_plane_address address) 44 + const struct dc_plane_address *address) 45 45 { 46 46 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 47 47 48 - REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address.lut3d.addr.high_part); 49 - REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part); 48 + REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address->lut3d.addr.high_part); 49 + REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address->lut3d.addr.low_part); 50 50 } 51 51 52 52 void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group) ··· 72 72 return ret; 73 73 } 74 74 75 - void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode) 75 + static void hubp401_get_3dlut_fl_xbar_map( 76 + const enum dc_cm_lut_pixel_format format, 77 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g, 78 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b, 79 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r) 76 80 { 77 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 78 - 79 - REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode); 80 - } 81 - 82 - void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width) 83 - { 84 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 85 - 86 - REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width); 87 - } 88 - 89 - void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits) 90 - { 91 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 92 - 93 - REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits); 81 + switch (format) { 82 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB: 83 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB: 84 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10: 85 + /* BGRA */ 86 + *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47; 87 + *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 88 + *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15; 89 + break; 90 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB: 91 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB: 92 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10: 93 + default: 94 + /* RGBA */ 95 + *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15; 96 + *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 97 + *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47; 98 + break; 99 + } 94 100 } 95 101 96 102 void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp, 97 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g, 98 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, 99 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r) 103 + const enum dc_cm_lut_pixel_format format) 100 104 { 101 105 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 106 + 107 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g = 0; 108 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b = 0; 109 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r = 0; 110 + 111 + hubp401_get_3dlut_fl_xbar_map(format, 112 + &bit_slice_y_g, 113 + &bit_slice_cb_b, 114 + &bit_slice_cr_r); 102 115 103 116 REG_UPDATE_3(HUBP_3DLUT_CONTROL, 104 117 HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g, ··· 119 106 HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r); 120 107 } 121 108 122 - void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale) 109 + static enum hubp_3dlut_fl_width hubp401_get_3dlut_fl_width( 110 + const enum dc_cm_lut_size size, 111 + const enum dc_cm_lut_swizzle swizzle) 123 112 { 124 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 113 + enum hubp_3dlut_fl_width width = 0; 125 114 126 - REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale); 115 + switch (size) { 116 + case CM_LUT_SIZE_333333: 117 + ASSERT(swizzle != CM_LUT_1D_PACKED_LINEAR); 118 + width = hubp_3dlut_fl_width_33; 119 + break; 120 + case CM_LUT_SIZE_171717: 121 + if (swizzle != CM_LUT_1D_PACKED_LINEAR) { 122 + width = hubp_3dlut_fl_width_17; 123 + } else { 124 + width = hubp_3dlut_fl_width_17_transformed; 125 + } 126 + break; 127 + default: 128 + width = 0; 129 + break; 130 + } 131 + 132 + return width; 127 133 } 128 134 129 - void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode) 135 + static enum hubp_3dlut_fl_format hubp401_get_3dlut_fl_format( 136 + const enum dc_cm_lut_pixel_format dc_format) 130 137 { 131 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 138 + enum hubp_3dlut_fl_format hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 132 139 133 - REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode); 140 + switch (dc_format) { 141 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB: 142 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB: 143 + hubp_format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 144 + break; 145 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB: 146 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB: 147 + hubp_format = hubp_3dlut_fl_format_unorm_12lsb_bitslice; 148 + break; 149 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10: 150 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10: 151 + hubp_format = hubp_3dlut_fl_format_float_fp1_5_10; 152 + break; 153 + default: 154 + BREAK_TO_DEBUGGER(); 155 + break; 156 + } 157 + 158 + return hubp_format; 134 159 } 135 160 136 - void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format) 161 + static enum hubp_3dlut_fl_addressing_mode hubp401_get_3dlut_fl_addr_mode( 162 + const enum dc_cm_lut_swizzle swizzle) 137 163 { 138 - struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 164 + enum hubp_3dlut_fl_addressing_mode addr_mode; 139 165 140 - REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format); 166 + switch (swizzle) { 167 + case CM_LUT_1D_PACKED_LINEAR: 168 + addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear; 169 + break; 170 + case CM_LUT_3D_SWIZZLE_LINEAR_RGB: 171 + case CM_LUT_3D_SWIZZLE_LINEAR_BGR: 172 + default: 173 + addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 174 + break; 175 + } 176 + 177 + return addr_mode; 141 178 } 142 179 143 - void hubp401_program_3dlut_fl_config( 144 - struct hubp *hubp, 145 - struct hubp_fl_3dlut_config *cfg) 180 + static enum hubp_3dlut_fl_mode hubp401_get_3dlut_fl_mode( 181 + const enum dc_cm_lut_swizzle swizzle) 182 + { 183 + enum hubp_3dlut_fl_mode mode; 184 + 185 + switch (swizzle) { 186 + case CM_LUT_3D_SWIZZLE_LINEAR_RGB: 187 + mode = hubp_3dlut_fl_mode_native_1; 188 + break; 189 + case CM_LUT_3D_SWIZZLE_LINEAR_BGR: 190 + mode = hubp_3dlut_fl_mode_native_2; 191 + break; 192 + case CM_LUT_1D_PACKED_LINEAR: 193 + mode = hubp_3dlut_fl_mode_transform; 194 + break; 195 + default: 196 + mode = hubp_3dlut_fl_mode_disable; 197 + break; 198 + } 199 + 200 + return mode; 201 + } 202 + 203 + void hubp401_program_3dlut_fl_config(struct hubp *hubp, 204 + const struct dc_3dlut_dma *config) 146 205 { 147 206 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 148 207 149 - uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1}; 150 - uint32_t width = {cfg->width}; 151 - 152 - if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR) 153 - width = (cfg->width == 17) ? 4916 : 35940; 208 + enum hubp_3dlut_fl_width width = hubp401_get_3dlut_fl_width(config->size, config->swizzle); 209 + enum hubp_3dlut_fl_format format = hubp401_get_3dlut_fl_format(config->format); 210 + enum hubp_3dlut_fl_addressing_mode addr_mode = hubp401_get_3dlut_fl_addr_mode(config->swizzle); 211 + enum hubp_3dlut_fl_mode mode = hubp401_get_3dlut_fl_mode(config->swizzle); 154 212 155 213 REG_UPDATE_2(_3DLUT_FL_CONFIG, 156 - HUBP0_3DLUT_FL_MODE, cfg->mode, 157 - HUBP0_3DLUT_FL_FORMAT, cfg->format); 214 + HUBP0_3DLUT_FL_MODE, mode, 215 + HUBP0_3DLUT_FL_FORMAT, format); 158 216 159 217 REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, 160 - HUBP0_3DLUT_FL_BIAS, cfg->bias, 161 - HUBP0_3DLUT_FL_SCALE, cfg->scale); 218 + HUBP0_3DLUT_FL_BIAS, config->bias, 219 + HUBP0_3DLUT_FL_SCALE, config->scale); 162 220 163 - REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, 164 - HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part); 165 - REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW, 166 - HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part); 167 - 168 - //cross bar 169 - REG_UPDATE_8(HUBP_3DLUT_CONTROL, 170 - HUBP_3DLUT_MPC_WIDTH, mpc_width, 171 - HUBP_3DLUT_WIDTH, width, 172 - HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r, 173 - HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g, 174 - HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b, 175 - HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode, 176 - HUBP_3DLUT_TMZ, cfg->protection_bits, 177 - HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0); 221 + REG_UPDATE_3(HUBP_3DLUT_CONTROL, 222 + HUBP_3DLUT_WIDTH, width, 223 + HUBP_3DLUT_ADDRESSING_MODE, addr_mode, 224 + HUBP_3DLUT_TMZ, config->addr.tmz_surface); 178 225 } 179 226 180 227 void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor) ··· 1131 1058 .hubp_update_mall_sel = hubp401_update_mall_sel, 1132 1059 .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering, 1133 1060 .hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate, 1134 - .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale, 1135 - .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode, 1136 - .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format, 1137 1061 .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr, 1062 + .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, 1138 1063 .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param, 1139 1064 .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl, 1140 - .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode, 1141 - .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width, 1142 - .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected, 1143 1065 .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar, 1144 1066 .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, 1145 1067 .hubp_clear_tiling = hubp401_clear_tiling, 1146 - .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, 1147 1068 .hubp_read_reg_state = hubp3_read_reg_state 1148 1069 }; 1149 1070
+4 -19
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h
··· 328 328 329 329 void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable); 330 330 331 - void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale); 332 - 333 331 void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp, 334 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g, 335 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, 336 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); 337 - 338 - void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits); 339 - 340 - void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width); 341 - 342 - void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode); 332 + const enum dc_cm_lut_pixel_format format); 343 333 344 334 void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable); 345 335 346 336 void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group); 347 337 348 - void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address address); 338 + void hubp401_program_3dlut_fl_addr(struct hubp *hubp, const struct dc_plane_address *address); 349 339 350 - void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format); 351 - 352 - void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode); 353 - 354 - void hubp401_program_3dlut_fl_config( 355 - struct hubp *hubp, 356 - struct hubp_fl_3dlut_config *cfg); 340 + void hubp401_program_3dlut_fl_config(struct hubp *hubp, 341 + const struct dc_3dlut_dma *config); 357 342 358 343 void hubp401_clear_tiling(struct hubp *hubp); 359 344
+75 -10
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
··· 147 147 /* don't see the need of program the xbar in DCN 1.0 */ 148 148 } 149 149 150 - void hubp42_program_deadline( 150 + static void hubp42_program_deadline( 151 151 struct hubp *hubp, 152 152 struct dml2_display_dlg_regs *dlg_attr, 153 153 struct dml2_display_ttu_regs *ttu_attr) 154 154 { 155 155 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 156 + 157 + /* put DLG in mission mode */ 158 + REG_WRITE(HUBPREQ_DEBUG_DB, 0); 156 159 157 160 /* DLG - Per hubp */ 158 161 REG_SET_2(BLANK_OFFSET_0, 0, ··· 277 274 hubp42_program_pixel_format(hubp, format); 278 275 } 279 276 277 + static void hubp42_get_3dlut_fl_xbar_map( 278 + const enum dc_cm_lut_pixel_format format, 279 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_y_g, 280 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cb_b, 281 + enum hubp_3dlut_fl_crossbar_bit_slice *bit_slice_cr_r) 282 + { 283 + switch (format) { 284 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12MSB: 285 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_UNORM_12LSB: 286 + case CM_LUT_PIXEL_FORMAT_BGRA16161616_FLOAT_FP1_5_10: 287 + /* BGRA */ 288 + *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47; 289 + *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 290 + *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15; 291 + break; 292 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12MSB: 293 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_UNORM_12LSB: 294 + case CM_LUT_PIXEL_FORMAT_RGBA16161616_FLOAT_FP1_5_10: 295 + default: 296 + /* RGBA */ 297 + *bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15; 298 + *bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 299 + *bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47; 300 + break; 301 + } 302 + } 303 + 280 304 void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp, 281 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r, 282 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g, 283 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b) 305 + const enum dc_cm_lut_pixel_format format) 284 306 { 285 307 struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 308 + 309 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g = 0; 310 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b = 0; 311 + enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r = 0; 312 + 313 + hubp42_get_3dlut_fl_xbar_map(format, 314 + &bit_slice_g, 315 + &bit_slice_b, 316 + &bit_slice_r); 286 317 287 318 REG_UPDATE_3(HUBP_3DLUT_CONTROL, 288 319 HUBP_3DLUT_CROSSBAR_SEL_R, bit_slice_r, 289 320 HUBP_3DLUT_CROSSBAR_SEL_G, bit_slice_g, 290 321 HUBP_3DLUT_CROSSBAR_SEL_B, bit_slice_b); 322 + } 323 + 324 + static uint32_t hubp42_get_3dlut_fl_mpc_width( 325 + const enum dc_cm_lut_size size) 326 + { 327 + uint32_t width = 0; 328 + 329 + switch (size) { 330 + case CM_LUT_SIZE_333333: 331 + width = 1; 332 + break; 333 + case CM_LUT_SIZE_171717: 334 + default: 335 + width = 0; 336 + break; 337 + } 338 + 339 + return width; 340 + } 341 + 342 + void hubp42_program_3dlut_fl_config(struct hubp *hubp, 343 + const struct dc_3dlut_dma *config) 344 + { 345 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 346 + 347 + uint32_t mpc_width = hubp42_get_3dlut_fl_mpc_width(config->size); 348 + 349 + REG_UPDATE(HUBP_3DLUT_CONTROL, 350 + HUBP_3DLUT_MPC_WIDTH, mpc_width); 351 + 352 + hubp401_program_3dlut_fl_config(hubp, config); 291 353 } 292 354 293 355 static bool hubp42_program_surface_flip_and_addr( ··· 616 548 .hubp_setup_interdependent2 = hubp401_setup_interdependent, 617 549 .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, 618 550 .set_blank = hubp2_set_blank, 551 + .set_blank_regs = hubp2_set_blank_regs, 619 552 .dcc_control = hubp3_dcc_control, 620 553 .hubp_reset = hubp_reset, 621 554 .mem_program_viewport = min_set_viewport, ··· 636 567 .hubp_set_flip_int = hubp1_set_flip_int, 637 568 .hubp_in_blank = hubp1_in_blank, 638 569 .program_extended_blank = hubp31_program_extended_blank_value, 639 - .hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale, 640 - .hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode, 641 - .hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format, 642 570 .hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr, 571 + .hubp_program_3dlut_fl_config = hubp42_program_3dlut_fl_config, 643 572 .hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param, 644 573 .hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl, 645 - .hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode, 646 - .hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width, 647 - .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected, 648 574 .hubp_program_3dlut_fl_crossbar = hubp42_program_3dlut_fl_crossbar, 649 575 .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, 576 + .hubp_clear_tiling = hubp3_clear_tiling, 650 577 .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, 651 578 .hubp_read_reg_state = hubp3_read_reg_state 652 579 };
+5 -11
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
··· 56 56 const struct dcn_hubp2_shift *hubp_shift, 57 57 const struct dcn_hubp2_mask *hubp_mask); 58 58 59 - void hubp42_program_3dlut_fl_crossbar( 60 - struct hubp *hubp, 61 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_r, 62 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_g, 63 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_b); 59 + void hubp42_program_3dlut_fl_crossbar(struct hubp *hubp, 60 + const enum dc_cm_lut_pixel_format format); 61 + 62 + void hubp42_program_3dlut_fl_config(struct hubp *hubp, 63 + const struct dc_3dlut_dma *config); 64 64 65 65 void hubp42_read_state(struct hubp *hubp); 66 66 ··· 69 69 struct dml2_dchub_per_pipe_register_set *pipe_regs, 70 70 union dml2_global_sync_programming *pipe_global_sync, 71 71 struct dc_crtc_timing *timing); 72 - 73 - void hubp42_program_deadline( 74 - struct hubp *hubp, 75 - struct dml2_display_dlg_regs *dlg_attr, 76 - struct dml2_display_ttu_regs *ttu_attr); 77 - 78 72 79 73 #endif /* __DC_HUBP_DCN42_H__ */
+88 -70
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
··· 86 86 hws->ctx 87 87 88 88 #define DC_LOGGER \ 89 - ctx->logger 90 - #define DC_LOGGER_INIT() \ 91 - struct dc_context *ctx = dc->ctx 89 + dc_ctx->logger 90 + #define DC_LOGGER_INIT(ctx) \ 91 + struct dc_context *dc_ctx = ctx 92 92 93 93 #define REG(reg)\ 94 94 hws->regs->reg ··· 661 661 } 662 662 663 663 static void 664 - dce110_external_encoder_control(enum bp_external_encoder_control_action action, 665 - struct dc_link *link, 666 - struct dc_crtc_timing *timing) 664 + dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable) 667 665 { 668 - struct dc *dc = link->ctx->dc; 666 + struct dc_link *link = pipe_ctx->stream->link; 669 667 struct dc_bios *bios = link->ctx->dc_bios; 670 - const struct dc_link_settings *link_settings = &link->cur_link_settings; 671 - enum bp_result bp_result = BP_RESULT_OK; 672 - struct bp_external_encoder_control ext_cntl = { 673 - .action = action, 674 - .connector_obj_id = link->link_enc->connector, 675 - .encoder_id = link->ext_enc_id, 676 - .lanes_number = link_settings->lane_count, 677 - .link_rate = link_settings->link_rate, 668 + struct bp_encoder_control encoder_control = {0}; 678 669 679 - /* Use signal type of the real link encoder, ie. DP */ 680 - .signal = link->connector_signal, 681 - 682 - /* We don't know the timing yet when executing the SETUP action, 683 - * so use a reasonably high default value. It seems that ENABLE 684 - * can change the actual pixel clock but doesn't work with higher 685 - * pixel clocks than what SETUP was called with. 686 - */ 687 - .pixel_clock = timing ? timing->pix_clk_100hz / 10 : 300000, 688 - .color_depth = timing ? timing->display_color_depth : COLOR_DEPTH_888, 689 - }; 690 - DC_LOGGER_INIT(); 691 - 692 - bp_result = bios->funcs->external_encoder_control(bios, &ext_cntl); 693 - 694 - if (bp_result != BP_RESULT_OK) 695 - DC_LOG_ERROR("Failed to execute external encoder action: 0x%x\n", action); 696 - } 697 - 698 - static void 699 - dce110_prepare_ddc(struct dc_link *link) 700 - { 701 - if (link->ext_enc_id.id) 702 - dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DDC_SETUP, link, NULL); 670 + encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE; 671 + encoder_control.engine_id = link->link_enc->analog_engine; 672 + encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10; 673 + bios->funcs->encoder_control(bios, &encoder_control); 703 674 } 704 675 705 676 static bool ··· 680 709 struct link_encoder *link_enc = link->link_enc; 681 710 enum bp_result bp_result; 682 711 683 - bp_result = bios->funcs->dac_load_detection( 684 - bios, link_enc->analog_engine, link->ext_enc_id); 712 + bp_result = bios->funcs->dac_load_detection(bios, link_enc->analog_engine); 685 713 return bp_result == BP_RESULT_OK; 686 714 } 687 715 ··· 696 726 uint32_t early_control = 0; 697 727 struct timing_generator *tg = pipe_ctx->stream_res.tg; 698 728 729 + link_hwss->setup_stream_attribute(pipe_ctx); 699 730 link_hwss->setup_stream_encoder(pipe_ctx); 700 731 701 732 dc->hwss.update_info_frame(pipe_ctx); ··· 715 744 716 745 tg->funcs->set_early_control(tg, early_control); 717 746 718 - if (link->ext_enc_id.id) 719 - dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_ENABLE, link, timing); 747 + if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 748 + dce110_dac_encoder_control(pipe_ctx, true); 720 749 } 721 750 722 751 static enum bp_result link_transmitter_control( ··· 738 767 struct dc_link *link, 739 768 bool power_up) 740 769 { 741 - struct dc_context *ctx = link->ctx; 742 770 struct graphics_object_id connector = link->link_enc->connector; 743 771 bool edp_hpd_high = false; 744 772 uint32_t time_elapsed = 0; 745 773 uint32_t timeout = power_up ? 746 774 PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 775 + 776 + DC_LOGGER_INIT(link->ctx); 747 777 748 778 if (dal_graphics_object_id_get_connector_id(connector) 749 779 != CONNECTOR_ID_EDP) { ··· 797 825 enum bp_result bp_result; 798 826 uint8_t pwrseq_instance; 799 827 828 + DC_LOGGER_INIT(ctx); 800 829 801 830 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 802 831 != CONNECTOR_ID_EDP) { ··· 965 992 uint8_t pwrseq_instance = 0; 966 993 unsigned int pre_T11_delay = (link->dpcd_sink_ext_caps.bits.oled ? OLED_PRE_T11_DELAY : 0); 967 994 unsigned int post_T7_delay = (link->dpcd_sink_ext_caps.bits.oled ? OLED_POST_T7_DELAY : 0); 995 + 996 + DC_LOGGER_INIT(ctx); 968 997 969 998 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 970 999 != CONNECTOR_ID_EDP) { ··· 1215 1240 link_enc->transmitter - TRANSMITTER_UNIPHY_A); 1216 1241 } 1217 1242 1218 - if (link->ext_enc_id.id) 1219 - dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DISABLE, link, NULL); 1243 + if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 1244 + dce110_dac_encoder_control(pipe_ctx, false); 1220 1245 } 1221 1246 1222 1247 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, ··· 1598 1623 1599 1624 return DC_OK; 1600 1625 } 1626 + static void 1627 + dce110_select_crtc_source(struct pipe_ctx *pipe_ctx) 1628 + { 1629 + struct dc_link *link = pipe_ctx->stream->link; 1630 + struct dc_bios *bios = link->ctx->dc_bios; 1631 + struct bp_crtc_source_select crtc_source_select = {0}; 1632 + enum engine_id engine_id = link->link_enc->preferred_engine; 1633 + 1634 + if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 1635 + engine_id = link->link_enc->analog_engine; 1636 + crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst; 1637 + crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth; 1638 + crtc_source_select.engine_id = engine_id; 1639 + crtc_source_select.sink_signal = pipe_ctx->stream->signal; 1640 + bios->funcs->select_crtc_source(bios, &crtc_source_select); 1641 + } 1601 1642 1602 1643 enum dc_status dce110_apply_single_controller_ctx_to_hw( 1603 1644 struct pipe_ctx *pipe_ctx, ··· 1632 1641 1633 1642 if (hws->funcs.disable_stream_gating) { 1634 1643 hws->funcs.disable_stream_gating(dc, pipe_ctx); 1644 + } 1645 + 1646 + if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) { 1647 + dce110_select_crtc_source(pipe_ctx); 1635 1648 } 1636 1649 1637 1650 if (pipe_ctx->stream_res.audio != NULL) { ··· 1717 1722 pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 1718 1723 pipe_ctx->stream_res.tg, event_triggers, 2); 1719 1724 1720 - if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1725 + if (!dc_is_virtual_signal(pipe_ctx->stream->signal) && 1726 + !dc_is_rgb_signal(pipe_ctx->stream->signal)) 1721 1727 pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1722 1728 pipe_ctx->stream_res.stream_enc, 1723 1729 pipe_ctx->stream_res.tg->inst); ··· 1940 1944 } 1941 1945 } 1942 1946 1947 + static void dc_hwss_enable_otg_pwa( 1948 + struct dc *dc, 1949 + struct pipe_ctx *pipe_ctx) 1950 + { 1951 + struct timing_generator *tg = NULL; 1952 + 1953 + if (dc->debug.enable_otg_frame_sync_pwa == 0) 1954 + return; 1955 + 1956 + if (pipe_ctx == NULL || pipe_ctx->stream_res.tg == NULL) 1957 + return; 1958 + tg = pipe_ctx->stream_res.tg; 1959 + 1960 + /*only enable this if one active*/ 1961 + if (tg->funcs->enable_otg_pwa) { 1962 + struct otc_pwa_frame_sync pwa_param = {0}; 1963 + 1964 + DC_LOGGER_INIT(dc->ctx); 1965 + /* mode 1 to choose generate pwa sync signal on line 0 counting 1966 + * from vstartup at very beginning of the frame 1967 + */ 1968 + pwa_param.pwa_frame_sync_line_offset = 0; 1969 + pwa_param.pwa_sync_mode = DC_OTG_PWA_FRAME_SYNC_MODE_VSTARTUP; 1970 + /*frame sync line for generating high frame sync*/ 1971 + tg->funcs->enable_otg_pwa(tg, &pwa_param); 1972 + DC_LOG_DC("Enable OTG PWA frame sync on TG %d\n", tg->inst); 1973 + } 1974 + } 1975 + 1943 1976 /* 1944 1977 * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 1945 1978 * 1. Power down all DC HW blocks ··· 1994 1969 bool keep_edp_vdd_on = false; 1995 1970 bool should_clean_dsc_block = true; 1996 1971 struct dc_bios *dcb = dc->ctx->dc_bios; 1997 - DC_LOGGER_INIT(); 1998 - 1972 + DC_LOGGER_INIT(dc->ctx); 1999 1973 2000 1974 get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num); 2001 1975 dc_get_edp_links(dc, edp_links, &edp_num); ··· 2045 2021 // If VBios supports it, we check it from reigster or other flags. 2046 2022 pipe_ctx->stream_res.pix_clk_params.dio_se_pix_per_cycle = 1; 2047 2023 } 2024 + dc_hwss_enable_otg_pwa(dc, pipe_ctx); 2048 2025 } 2049 2026 break; 2050 2027 } ··· 2615 2590 #endif 2616 2591 } 2617 2592 2593 + 2594 + if (dc->debug.enable_otg_frame_sync_pwa && context->stream_count == 1) { 2595 + /* only enable this on one OTG*/ 2596 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 2597 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2598 + 2599 + if (pipe_ctx && pipe_ctx->stream != NULL) { 2600 + dc_hwss_enable_otg_pwa(dc, pipe_ctx); 2601 + break; 2602 + } 2603 + } 2604 + } 2618 2605 if (dc->fbc_compressor) 2619 2606 enable_fbc(dc, dc->current_state); 2620 2607 ··· 2773 2736 struct dc_context *dc_ctx, 2774 2737 struct timing_generator *tg) 2775 2738 { 2776 - struct dc_context *ctx = dc_ctx; 2777 2739 bool rc = false; 2778 2740 2779 2741 /* To avoid endless loop we wait at most ··· 2814 2778 int group_size, 2815 2779 struct pipe_ctx *grouped_pipes[]) 2816 2780 { 2817 - struct dc_context *dc_ctx = dc->ctx; 2818 2781 struct dcp_gsl_params gsl_params = { 0 }; 2819 2782 int i; 2820 - DC_LOGGER_INIT(); 2783 + DC_LOGGER_INIT(dc->ctx); 2821 2784 2822 2785 DC_SYNC_INFO("GSL: Setting-up...\n"); 2823 2786 ··· 2859 2824 int group_size, 2860 2825 struct pipe_ctx *grouped_pipes[]) 2861 2826 { 2862 - struct dc_context *dc_ctx = dc->ctx; 2863 2827 struct dcp_gsl_params gsl_params = { 0 }; 2864 2828 int i; 2865 - DC_LOGGER_INIT(); 2829 + DC_LOGGER_INIT(dc->ctx); 2866 2830 2867 2831 gsl_params.gsl_group = 0; 2868 2832 gsl_params.gsl_master = 0; ··· 3354 3320 link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 3355 3321 } 3356 3322 3357 - static void dce110_enable_analog_link_output( 3358 - struct dc_link *link, 3359 - uint32_t pix_clk_100hz) 3360 - { 3361 - link->link_enc->funcs->enable_analog_output( 3362 - link->link_enc, 3363 - pix_clk_100hz); 3364 - } 3365 - 3366 3323 void dce110_enable_dp_link_output( 3367 3324 struct dc_link *link, 3368 3325 const struct link_resource *link_res, ··· 3399 3374 &pipes[i].pll_settings); 3400 3375 } 3401 3376 } 3402 - } 3403 - 3404 - if (link->ext_enc_id.id) { 3405 - dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_INIT, link, NULL); 3406 - dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_SETUP, link, NULL); 3407 3377 } 3408 3378 3409 3379 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { ··· 3491 3471 .enable_lvds_link_output = dce110_enable_lvds_link_output, 3492 3472 .enable_tmds_link_output = dce110_enable_tmds_link_output, 3493 3473 .enable_dp_link_output = dce110_enable_dp_link_output, 3494 - .enable_analog_link_output = dce110_enable_analog_link_output, 3495 3474 .disable_link_output = dce110_disable_link_output, 3496 3475 .dac_load_detect = dce110_dac_load_detect, 3497 - .prepare_ddc = dce110_prepare_ddc, 3498 3476 }; 3499 3477 3500 3478 static const struct hwseq_private_funcs dce110_private_funcs = {
+12 -20
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
··· 60 60 #include "dc_state_priv.h" 61 61 62 62 #define DC_LOGGER \ 63 - dc_logger 64 - #define DC_LOGGER_INIT(logger) \ 65 - struct dal_logger *dc_logger = logger 63 + dc_ctx->logger 64 + #define DC_LOGGER_INIT(ctx) \ 65 + struct dc_context *dc_ctx = ctx 66 66 67 67 #define CTX \ 68 68 hws->ctx ··· 1009 1009 struct dce_hwseq *hws, 1010 1010 int plane_id) 1011 1011 { 1012 - DC_LOGGER_INIT(hws->ctx->logger); 1012 + DC_LOGGER_INIT(hws->ctx); 1013 1013 1014 1014 if (hws->funcs.dpp_root_clock_control) 1015 1015 hws->funcs.dpp_root_clock_control(hws, plane_id, true); ··· 1286 1286 { 1287 1287 int i; 1288 1288 struct dc_link *link; 1289 - DC_LOGGER_INIT(dc->ctx->logger); 1289 + DC_LOGGER_INIT(dc->ctx); 1290 1290 if (pipe_ctx->stream_res.stream_enc == NULL) { 1291 1291 pipe_ctx->stream = NULL; 1292 1292 return; ··· 1422 1422 return; 1423 1423 1424 1424 if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) { 1425 - int i = 0; 1426 - 1427 1425 if (should_log_hw_state) 1428 1426 dcn10_log_hw_state(dc, NULL); 1429 1427 1430 - TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); 1428 + TRACE_DC_PIPE_STATE(pipe_ctx, MAX_PIPES); 1431 1429 BREAK_TO_DEBUGGER(); 1432 1430 if (dcn10_hw_wa_force_recovery(dc)) { 1433 1431 /*check again*/ ··· 1488 1490 struct hubp *hubp) 1489 1491 { 1490 1492 struct dce_hwseq *hws = dc->hwseq; 1491 - DC_LOGGER_INIT(dc->ctx->logger); 1493 + DC_LOGGER_INIT(dc->ctx); 1492 1494 1493 1495 if (REG(DC_IP_REQUEST_CNTL)) { 1494 1496 REG_SET(DC_IP_REQUEST_CNTL, 0, ··· 1552 1554 void dcn10_disable_plane(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx) 1553 1555 { 1554 1556 struct dce_hwseq *hws = dc->hwseq; 1555 - DC_LOGGER_INIT(dc->ctx->logger); 1557 + DC_LOGGER_INIT(dc->ctx); 1556 1558 1557 1559 if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated) 1558 1560 return; ··· 2266 2268 { 2267 2269 bool rc = false; 2268 2270 2269 - DC_LOGGER_INIT(dc_ctx->logger); 2270 - 2271 2271 /* To avoid endless loop we wait at most 2272 2272 * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 2273 2273 const uint32_t frames_to_wait_on_triggered_reset = 10; ··· 2380 2384 static int dcn10_align_pixel_clocks(struct dc *dc, int group_size, 2381 2385 struct pipe_ctx *grouped_pipes[]) 2382 2386 { 2383 - struct dc_context *dc_ctx = dc->ctx; 2384 2387 int i, master = -1, embedded = -1; 2385 2388 struct dc_crtc_timing *hw_crtc_timing; 2386 2389 uint64_t phase[MAX_PIPES]; ··· 2392 2397 uint32_t dp_ref_clk_100hz = 2393 2398 dc->res_pool->dp_clock_source->ctx->dc->clk_mgr->dprefclk_khz*10; 2394 2399 2395 - DC_LOGGER_INIT(dc_ctx->logger); 2400 + DC_LOGGER_INIT(dc->ctx); 2396 2401 2397 2402 hw_crtc_timing = kzalloc_objs(*hw_crtc_timing, MAX_PIPES); 2398 2403 if (!hw_crtc_timing) ··· 2472 2477 int group_size, 2473 2478 struct pipe_ctx *grouped_pipes[]) 2474 2479 { 2475 - struct dc_context *dc_ctx = dc->ctx; 2476 2480 struct output_pixel_processor *opp; 2477 2481 struct timing_generator *tg; 2478 2482 int i, width = 0, height = 0, master; 2479 2483 2480 - DC_LOGGER_INIT(dc_ctx->logger); 2484 + DC_LOGGER_INIT(dc->ctx); 2481 2485 2482 2486 for (i = 1; i < group_size; i++) { 2483 2487 opp = grouped_pipes[i]->stream_res.opp; ··· 2537 2543 int group_size, 2538 2544 struct pipe_ctx *grouped_pipes[]) 2539 2545 { 2540 - struct dc_context *dc_ctx = dc->ctx; 2541 2546 struct output_pixel_processor *opp; 2542 2547 struct timing_generator *tg; 2543 2548 int i, width = 0, height = 0; 2544 2549 2545 - DC_LOGGER_INIT(dc_ctx->logger); 2550 + DC_LOGGER_INIT(dc->ctx); 2546 2551 2547 2552 DC_SYNC_INFO("Setting up OTG reset trigger\n"); 2548 2553 ··· 2617 2624 int group_size, 2618 2625 struct pipe_ctx *grouped_pipes[]) 2619 2626 { 2620 - struct dc_context *dc_ctx = dc->ctx; 2621 2627 int i; 2622 2628 2623 - DC_LOGGER_INIT(dc_ctx->logger); 2629 + DC_LOGGER_INIT(dc->ctx); 2624 2630 2625 2631 DC_SYNC_INFO("Setting up\n"); 2626 2632 for (i = 0; i < group_size; i++)
-1
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
··· 513 513 { 514 514 struct dc_link *link; 515 515 516 - DC_LOGGER_INIT(dc->ctx->logger); 517 516 if (pipe_ctx->stream_res.stream_enc == NULL) { 518 517 pipe_ctx->stream = NULL; 519 518 return;
+6 -6
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
··· 60 60 #include "dcn20/dcn20_hwseq.h" 61 61 #include "dc_state_priv.h" 62 62 63 - #define DC_LOGGER_INIT(logger) \ 64 - struct dal_logger *dc_logger = logger 63 + #define DC_LOGGER \ 64 + dc_ctx->logger 65 + #define DC_LOGGER_INIT(ctx) \ 66 + struct dc_context *dc_ctx = ctx 65 67 66 68 #define CTX \ 67 69 hws->ctx 68 70 #define REG(reg)\ 69 71 hws->regs->reg 70 - #define DC_LOGGER \ 71 - dc_logger 72 72 73 73 74 74 #undef FN ··· 331 331 struct pipe_ctx *odm_pipe; 332 332 int opp_cnt = 1; 333 333 334 - DC_LOGGER_INIT(stream->ctx->logger); 334 + DC_LOGGER_INIT(stream->ctx); 335 335 336 336 ASSERT(dsc); 337 337 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) ··· 897 897 bool is_phantom = dc_state_get_pipe_subvp_type(state, pipe_ctx) == SUBVP_PHANTOM; 898 898 struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL; 899 899 900 - DC_LOGGER_INIT(dc->ctx->logger); 900 + DC_LOGGER_INIT(dc->ctx); 901 901 902 902 if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated) 903 903 return;
+186 -283
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
··· 95 95 unsigned int mpcc_id = pipe_ctx->plane_res.mpcc_inst; 96 96 struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; 97 97 98 - //For now assert if location is not pre-blend 99 - if (pipe_ctx->plane_state) 100 - ASSERT(pipe_ctx->plane_state->mcm_location == MPCC_MOVABLE_CM_LOCATION_BEFORE); 101 - 102 98 // program MPCC_MCM_FIRST_GAMUT_REMAP 103 99 memset(&mpc_adjust, 0, sizeof(mpc_adjust)); 104 100 mpc_adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; ··· 300 304 } 301 305 } 302 306 } 307 + 303 308 for (i = 0; i < res_pool->audio_count; i++) { 304 309 struct audio *audio = res_pool->audios[i]; 305 310 ··· 369 372 } 370 373 } 371 374 372 - static void dcn401_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx, 373 - enum MCM_LUT_XABLE *shaper_xable, 374 - enum MCM_LUT_XABLE *lut3d_xable, 375 - enum MCM_LUT_XABLE *lut1d_xable) 376 - { 377 - enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL; 378 - bool lut1d_enable = false; 379 - struct mpc *mpc = dc->res_pool->mpc; 380 - int mpcc_id = pipe_ctx->plane_res.hubp->inst; 381 - 382 - if (!pipe_ctx->plane_state) 383 - return; 384 - shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting; 385 - lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable; 386 - mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); 387 - pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE; 388 - 389 - *lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE; 390 - 391 - switch (shaper_3dlut_setting) { 392 - case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL: 393 - *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE; 394 - break; 395 - case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER: 396 - *lut3d_xable = MCM_LUT_DISABLE; 397 - *shaper_xable = MCM_LUT_ENABLE; 398 - break; 399 - case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT: 400 - *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE; 401 - break; 402 - } 403 - } 404 - 405 - void dcn401_populate_mcm_luts(struct dc *dc, 406 - struct pipe_ctx *pipe_ctx, 407 - struct dc_cm2_func_luts mcm_luts, 408 - bool lut_bank_a) 409 - { 410 - struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 411 - struct hubp *hubp = pipe_ctx->plane_res.hubp; 412 - int mpcc_id = hubp->inst; 413 - struct mpc *mpc = dc->res_pool->mpc; 414 - union mcm_lut_params m_lut_params; 415 - enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src; 416 - enum hubp_3dlut_fl_format format = 0; 417 - enum hubp_3dlut_fl_mode mode; 418 - enum hubp_3dlut_fl_width width = 0; 419 - enum hubp_3dlut_fl_addressing_mode addr_mode; 420 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0; 421 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0; 422 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0; 423 - enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE; 424 - enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE; 425 - enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE; 426 - bool rval; 427 - 428 - dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable); 429 - 430 - /* 1D LUT */ 431 - if (mcm_luts.lut1d_func) { 432 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 433 - if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL) 434 - m_lut_params.pwl = &mcm_luts.lut1d_func->pwl; 435 - else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) { 436 - rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx, 437 - mcm_luts.lut1d_func, 438 - &dpp_base->regamma_params, false); 439 - m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL; 440 - } 441 - if (m_lut_params.pwl) { 442 - if (mpc->funcs->populate_lut) 443 - mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id); 444 - } 445 - if (mpc->funcs->program_lut_mode) 446 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id); 447 - } 448 - 449 - /* Shaper */ 450 - if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) { 451 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 452 - if (mcm_luts.shaper->type == TF_TYPE_HWPWL) 453 - m_lut_params.pwl = &mcm_luts.shaper->pwl; 454 - else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { 455 - ASSERT(false); 456 - rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx, 457 - mcm_luts.shaper, 458 - &dpp_base->regamma_params, true); 459 - m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL; 460 - } 461 - if (m_lut_params.pwl) { 462 - if (mpc->funcs->mcm.populate_lut) 463 - mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id); 464 - if (mpc->funcs->program_lut_mode) 465 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id); 466 - } 467 - } 468 - 469 - /* 3DLUT */ 470 - switch (lut3d_src) { 471 - case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM: 472 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 473 - if (hubp->funcs->hubp_enable_3dlut_fl) 474 - hubp->funcs->hubp_enable_3dlut_fl(hubp, false); 475 - 476 - if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) { 477 - m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d; 478 - if (mpc->funcs->populate_lut) 479 - mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id); 480 - if (mpc->funcs->program_lut_mode) 481 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, 482 - mpcc_id); 483 - } 484 - break; 485 - case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM: 486 - switch (mcm_luts.lut3d_data.gpu_mem_params.size) { 487 - case DC_CM2_GPU_MEM_SIZE_171717: 488 - width = hubp_3dlut_fl_width_17; 489 - break; 490 - case DC_CM2_GPU_MEM_SIZE_TRANSFORMED: 491 - width = hubp_3dlut_fl_width_transformed; 492 - break; 493 - default: 494 - //TODO: handle default case 495 - break; 496 - } 497 - 498 - //check for support 499 - if (mpc->funcs->mcm.is_config_supported && 500 - !mpc->funcs->mcm.is_config_supported(width)) 501 - break; 502 - 503 - if (mpc->funcs->program_lut_read_write_control) 504 - mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id); 505 - if (mpc->funcs->program_lut_mode) 506 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id); 507 - 508 - if (hubp->funcs->hubp_program_3dlut_fl_addr) 509 - hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr); 510 - 511 - if (mpc->funcs->mcm.program_bit_depth) 512 - mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id); 513 - 514 - switch (mcm_luts.lut3d_data.gpu_mem_params.layout) { 515 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB: 516 - mode = hubp_3dlut_fl_mode_native_1; 517 - addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 518 - break; 519 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR: 520 - mode = hubp_3dlut_fl_mode_native_2; 521 - addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 522 - break; 523 - case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR: 524 - mode = hubp_3dlut_fl_mode_transform; 525 - addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear; 526 - break; 527 - default: 528 - mode = hubp_3dlut_fl_mode_disable; 529 - addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 530 - break; 531 - } 532 - if (hubp->funcs->hubp_program_3dlut_fl_mode) 533 - hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode); 534 - 535 - if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode) 536 - hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode); 537 - 538 - switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) { 539 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB: 540 - format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 541 - break; 542 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB: 543 - format = hubp_3dlut_fl_format_unorm_12lsb_bitslice; 544 - break; 545 - case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10: 546 - format = hubp_3dlut_fl_format_float_fp1_5_10; 547 - break; 548 - } 549 - if (hubp->funcs->hubp_program_3dlut_fl_format) 550 - hubp->funcs->hubp_program_3dlut_fl_format(hubp, format); 551 - if (hubp->funcs->hubp_update_3dlut_fl_bias_scale && 552 - mpc->funcs->mcm.program_bias_scale) { 553 - mpc->funcs->mcm.program_bias_scale(mpc, 554 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias, 555 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale, 556 - mpcc_id); 557 - hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp, 558 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias, 559 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale); 560 - } 561 - 562 - //navi 4x has a bug and r and blue are swapped and need to be worked around here in 563 - //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x 564 - switch (mcm_luts.lut3d_data.gpu_mem_params.component_order) { 565 - case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA: 566 - default: 567 - crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15; 568 - crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 569 - crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47; 570 - break; 571 - } 572 - 573 - if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 574 - hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, 575 - crossbar_bit_slice_cr_r, 576 - crossbar_bit_slice_y_g, 577 - crossbar_bit_slice_cb_b); 578 - 579 - if (mpc->funcs->mcm.program_lut_read_write_control) 580 - mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id); 581 - 582 - if (mpc->funcs->mcm.program_3dlut_size) 583 - mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id); 584 - 585 - if (mpc->funcs->update_3dlut_fast_load_select) 586 - mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst); 587 - 588 - if (hubp->funcs->hubp_enable_3dlut_fl) 589 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 590 - else { 591 - if (mpc->funcs->program_lut_mode) { 592 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 593 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 594 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 595 - } 596 - } 597 - break; 598 - 599 - } 600 - } 601 - 602 375 void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx) 603 376 { 604 377 struct hubp *hubp = pipe_ctx->plane_res.hubp; ··· 381 614 bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx, 382 615 const struct dc_plane_state *plane_state) 383 616 { 617 + struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc; 384 618 struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 385 - int mpcc_id = pipe_ctx->plane_res.hubp->inst; 386 - struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc; 619 + struct hubp *hubp = pipe_ctx->plane_res.hubp; 620 + const struct dc_plane_cm *cm = &plane_state->cm; 621 + int mpcc_id = hubp->inst; 387 622 struct mpc *mpc = dc->res_pool->mpc; 388 - bool result; 389 - const struct pwl_params *lut_params = NULL; 623 + union mcm_lut_params m_lut_params; 624 + struct dc_3dlut_dma lut3d_dma; 625 + bool lut_enable; 626 + bool lut_bank_a; 390 627 bool rval; 628 + bool result = true; 391 629 392 - if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) { 393 - dcn401_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a); 394 - return true; 630 + /* decide LUT bank based on current in use */ 631 + mpc->funcs->get_lut_mode(mpc, MCM_LUT_1DLUT, mpcc_id, &lut_enable, &lut_bank_a); 632 + if (!lut_enable) { 633 + mpc->funcs->get_lut_mode(mpc, MCM_LUT_SHAPER, mpcc_id, &lut_enable, &lut_bank_a); 634 + } 635 + if (!lut_enable) { 636 + mpc->funcs->get_lut_mode(mpc, MCM_LUT_3DLUT, mpcc_id, &lut_enable, &lut_bank_a); 395 637 } 396 638 639 + /* switch to the next bank */ 640 + if (lut_enable) { 641 + lut_bank_a = !lut_bank_a; 642 + } 643 + 644 + /* MCM location fixed to pre-blend */ 397 645 mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); 398 - pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE; 399 - // 1D LUT 400 - if (plane_state->blend_tf.type == TF_TYPE_HWPWL) 401 - lut_params = &plane_state->blend_tf.pwl; 402 - else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { 403 - rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 404 - &plane_state->blend_tf, 405 - &dpp_base->regamma_params, false); 406 - lut_params = rval ? &dpp_base->regamma_params : NULL; 407 - } 408 - result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id); 409 - lut_params = NULL; 410 646 411 - // Shaper 412 - if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL) 413 - lut_params = &plane_state->in_shaper_func.pwl; 414 - else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { 415 - // TODO: dpp_base replace 416 - rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 417 - &plane_state->in_shaper_func, 418 - &dpp_base->shaper_params, true); 419 - lut_params = rval ? &dpp_base->shaper_params : NULL; 420 - } 421 - result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); 647 + /* 1D LUT */ 648 + lut_enable = cm->flags.bits.blend_enable; 649 + memset(&m_lut_params, 0, sizeof(m_lut_params)); 650 + if (lut_enable) { 651 + if (cm->blend_func.type == TF_TYPE_HWPWL) 652 + m_lut_params.pwl = &cm->blend_func.pwl; 653 + else if (cm->blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) { 654 + rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 655 + &cm->blend_func, 656 + &dpp_base->regamma_params, 657 + false); 658 + m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL; 659 + } 422 660 423 - // 3D 424 - if (mpc->funcs->program_3dlut) { 425 - if (plane_state->lut3d_func.state.bits.initialized == 1) 426 - result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id); 427 - else 428 - result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id); 661 + if (!m_lut_params.pwl) { 662 + lut_enable = false; 663 + } 664 + } else { 665 + lut_enable = false; 666 + } 667 + 668 + if (mpc->funcs->program_lut_mode) 669 + mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id); 670 + if (lut_enable && mpc->funcs->populate_lut) 671 + mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, &m_lut_params, lut_bank_a, mpcc_id); 672 + 673 + /* Shaper */ 674 + lut_enable = cm->flags.bits.shaper_enable; 675 + if (lut_enable) { 676 + memset(&m_lut_params, 0, sizeof(m_lut_params)); 677 + if (cm->shaper_func.type == TF_TYPE_HWPWL) 678 + m_lut_params.pwl = &cm->shaper_func.pwl; 679 + else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { 680 + ASSERT(false); 681 + rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 682 + &cm->shaper_func, 683 + &dpp_base->shaper_params, 684 + true); 685 + m_lut_params.pwl = rval ? &dpp_base->shaper_params : NULL; 686 + } 687 + if (!m_lut_params.pwl) { 688 + lut_enable = false; 689 + } 690 + } else { 691 + lut_enable = false; 692 + } 693 + 694 + if (mpc->funcs->program_lut_mode) 695 + mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, lut_enable, lut_bank_a, CM_LUT_SIZE_NONE, mpcc_id); 696 + if (lut_enable && mpc->funcs->populate_lut) 697 + mpc->funcs->populate_lut(mpc, MCM_LUT_SHAPER, &m_lut_params, lut_bank_a, mpcc_id); 698 + 699 + /* NOTE: Toggling from DMA->Host is not supported atomically as hardware 700 + * blocks writes until 3DLUT FL mode is cleared from HUBP on VUpdate. 701 + * Expectation is either option is used consistently. 702 + */ 703 + 704 + /* 3DLUT */ 705 + lut_enable = cm->flags.bits.lut3d_enable; 706 + if (lut_enable && cm->flags.bits.lut3d_dma_enable) { 707 + /* Fast (DMA) Load Mode */ 708 + /* MPC */ 709 + if (mpc->funcs->program_lut_mode) 710 + mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut_enable, lut_bank_a, cm->lut3d_dma.size, mpcc_id); 711 + 712 + /* only supports 12 bit */ 713 + if (mpc->funcs->program_lut_read_write_control) 714 + mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id); 715 + 716 + if (mpc->funcs->update_3dlut_fast_load_select) 717 + mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst); 718 + 719 + /* HUBP */ 720 + if (hubp->funcs->hubp_program_3dlut_fl_config) 721 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 722 + 723 + if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 724 + hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format); 725 + 726 + if (hubp->funcs->hubp_program_3dlut_fl_addr) 727 + hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 728 + 729 + if (hubp->funcs->hubp_enable_3dlut_fl) { 730 + hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 731 + } else { 732 + /* GPU memory only supports fast load path */ 733 + BREAK_TO_DEBUGGER(); 734 + lut_enable = false; 735 + result = false; 736 + } 737 + } else { 738 + /* Legacy (Host) Load Mode */ 739 + memset(&m_lut_params, 0, sizeof(m_lut_params)); 740 + 741 + if (cm->flags.bits.lut3d_enable && cm->lut3d_func.state.bits.initialized) { 742 + m_lut_params.lut3d = &cm->lut3d_func.lut_3d; 743 + } else { 744 + lut_enable = false; 745 + } 746 + 747 + /* MPC */ 748 + if (mpc->funcs->program_lut_mode) 749 + mpc->funcs->program_lut_mode(mpc, 750 + MCM_LUT_3DLUT, 751 + lut_enable, 752 + lut_bank_a, 753 + cm->lut3d_func.lut_3d.use_tetrahedral_9 ? CM_LUT_SIZE_999 : CM_LUT_SIZE_171717, 754 + mpcc_id); 755 + 756 + if (lut_enable) { 757 + if (mpc->funcs->program_lut_read_write_control) 758 + mpc->funcs->program_lut_read_write_control(mpc, 759 + MCM_LUT_3DLUT, 760 + lut_bank_a, 761 + cm->lut3d_func.lut_3d.use_12bits ? 12 : 10, 762 + mpcc_id); 763 + 764 + if (mpc->funcs->update_3dlut_fast_load_select) 765 + mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, 0xf); 766 + 767 + if (mpc->funcs->populate_lut) 768 + mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, &m_lut_params, lut_bank_a, mpcc_id); 769 + } 770 + 771 + /* HUBP */ 772 + memset(&lut3d_dma, 0, sizeof(lut3d_dma)); 773 + if (hubp->funcs->hubp_program_3dlut_fl_config) 774 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma); 775 + 776 + if (hubp->funcs->hubp_enable_3dlut_fl) 777 + hubp->funcs->hubp_enable_3dlut_fl(hubp, false); 429 778 } 430 779 431 780 return result; ··· 864 981 link_enc->transmitter - TRANSMITTER_UNIPHY_A); 865 982 } 866 983 } 984 + 985 + link_hwss->setup_stream_attribute(pipe_ctx); 867 986 868 987 if (dc->res_pool->dccg->funcs->set_pixel_rate_div) { 869 988 dc->res_pool->dccg->funcs->set_pixel_rate_div( ··· 1815 1930 1816 1931 for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) { 1817 1932 for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) { 1818 - if (mpc_pipe->plane_state && mpc_pipe->plane_state->mcm_luts.lut3d_data.lut3d_src 1819 - == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM 1820 - && mpc_pipe->plane_state->mcm_shaper_3dlut_setting 1821 - == DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT) { 1933 + if (mpc_pipe->plane_state && 1934 + mpc_pipe->plane_state->cm.flags.bits.lut3d_enable && 1935 + mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) { 1822 1936 wa_pipes[wa_pipe_ct++] = mpc_pipe; 1823 1937 } 1824 1938 } ··· 1866 1982 struct dc_link *link = pipe_ctx->stream->link; 1867 1983 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); 1868 1984 1869 - DC_LOGGER_INIT(dc->ctx->logger); 1870 1985 if (pipe_ctx->stream_res.stream_enc == NULL) { 1871 1986 pipe_ctx->stream = NULL; 1872 1987 return; ··· 1944 2061 DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n", 1945 2062 pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst); 1946 2063 } 2064 + static void dc_hwss_disable_otg_pwa(struct dc *dc) 2065 + { 2066 + if (dc->debug.enable_otg_frame_sync_pwa) { 2067 + int i; 2068 + 2069 + /*reset all the otg*/ 2070 + for (i = dc->res_pool->timing_generator_count - 1; i >= 0 ; i--) { 2071 + struct timing_generator *tg = dc->res_pool->timing_generators[i]; 2072 + 2073 + if (tg->funcs->disable_otg_pwa) { 2074 + tg->funcs->disable_otg_pwa(tg); 2075 + DC_LOG_DC("otg frame sync pwa disabled on otg%d\n", tg->inst); 2076 + } 2077 + } 2078 + } 2079 + } 1947 2080 1948 2081 void dcn401_reset_hw_ctx_wrap( 1949 2082 struct dc *dc, ··· 1968 2069 int i; 1969 2070 struct dce_hwseq *hws = dc->hwseq; 1970 2071 2072 + dc_hwss_disable_otg_pwa(dc); 1971 2073 /* Reset Back End*/ 1972 2074 for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { 1973 2075 struct pipe_ctx *pipe_ctx_old = ··· 2159 2259 pipe_ctx->stream_res.test_pattern_params.height, 2160 2260 pipe_ctx->stream_res.test_pattern_params.offset); 2161 2261 } 2262 + if (pipe_ctx->plane_state 2263 + && pipe_ctx->plane_state->update_flags.bits.cm_hist_change 2264 + && hws->funcs.program_cm_hist) 2265 + hws->funcs.program_cm_hist(dc, pipe_ctx, pipe_ctx->plane_state); 2162 2266 } 2163 2267 2164 2268 /* ··· 2314 2410 pipe_ctx->stream_res.test_pattern_params.offset); 2315 2411 } 2316 2412 2413 + if (pipe_ctx->plane_state 2414 + && pipe_ctx->plane_state->update_flags.bits.cm_hist_change 2415 + && hws->funcs.program_cm_hist) { 2416 + 2417 + hwss_add_dpp_program_cm_hist(seq_state, pipe_ctx->plane_res.dpp, 2418 + pipe_ctx->plane_state->cm_hist_control, pipe_ctx->plane_state->color_space); 2419 + } 2317 2420 } 2318 2421 2319 2422 void dcn401_program_front_end_for_ctx( ··· 2332 2421 unsigned int hubp_count = 0; 2333 2422 struct dce_hwseq *hws = dc->hwseq; 2334 2423 struct pipe_ctx *pipe = NULL; 2335 - 2336 - DC_LOGGER_INIT(dc->ctx->logger); 2337 2424 2338 2425 if (resource_is_pipe_topology_changed(dc->current_state, context)) 2339 2426 resource_log_pipe_topology_update(dc, context); ··· 2495 2586 unsigned int polling_interval_us = 1; 2496 2587 struct dce_hwseq *hwseq = dc->hwseq; 2497 2588 int i; 2498 - 2499 - DC_LOGGER_INIT(dc->ctx->logger); 2500 2589 2501 2590 for (i = 0; i < dc->res_pool->pipe_count; i++) 2502 2591 if (resource_is_pipe_type(&dc->current_state->res_ctx.pipe_ctx[i], OPP_HEAD) && ··· 2875 2968 struct dce_hwseq *hws = dc->hwseq; 2876 2969 uint32_t org_ip_request_cntl = 0; 2877 2970 2878 - DC_LOGGER_INIT(dc->ctx->logger); 2879 - 2880 2971 if (REG(DC_IP_REQUEST_CNTL)) { 2881 2972 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 2882 2973 if (org_ip_request_cntl == 0) ··· 2965 3060 { 2966 3061 struct dce_hwseq *hws = dc->hwseq; 2967 3062 uint32_t org_ip_request_cntl = 0; 2968 - 2969 - DC_LOGGER_INIT(dc->ctx->logger); 2970 3063 2971 3064 /* Check and set DC_IP_REQUEST_CNTL if needed */ 2972 3065 if (REG(DC_IP_REQUEST_CNTL)) {
+87 -468
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
··· 261 261 dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); 262 262 263 263 if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0) 264 - dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc); 264 + dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->clk_mgr->bw_params->num_channels, dc->config.sdpif_request_limit_words_per_umc); 265 265 266 266 // Get DMCUB capabilities 267 267 if (dc->ctx->dmub_srv) { ··· 275 275 || res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) { 276 276 /* update bounding box if FAMS2 disabled, or if dchub clk has changed */ 277 277 if (dc->clk_mgr) 278 - dc->res_pool->funcs->update_bw_bounding_box(dc, 279 - dc->clk_mgr->bw_params); 278 + dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 280 279 } 281 280 } 282 281 if (dc->res_pool->pg_cntl) { ··· 382 383 plane_state->cm_hist_control, plane_state->color_space); 383 384 } 384 385 385 - static void dc_get_lut_xbar( 386 - enum dc_cm2_gpu_mem_pixel_component_order order, 387 - enum hubp_3dlut_fl_crossbar_bit_slice *cr_r, 388 - enum hubp_3dlut_fl_crossbar_bit_slice *y_g, 389 - enum hubp_3dlut_fl_crossbar_bit_slice *cb_b) 390 - { 391 - switch (order) { 392 - case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_RGBA: 393 - *cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47; 394 - *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 395 - *cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15; 396 - break; 397 - case DC_CM2_GPU_MEM_PIXEL_COMPONENT_ORDER_BGRA: 398 - *cr_r = hubp_3dlut_fl_crossbar_bit_slice_0_15; 399 - *y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 400 - *cb_b = hubp_3dlut_fl_crossbar_bit_slice_32_47; 401 - break; 402 - } 403 - } 404 - 405 - static void dc_get_lut_mode( 406 - enum dc_cm2_gpu_mem_layout layout, 407 - enum hubp_3dlut_fl_mode *mode, 408 - enum hubp_3dlut_fl_addressing_mode *addr_mode) 409 - { 410 - switch (layout) { 411 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB: 412 - *mode = hubp_3dlut_fl_mode_native_1; 413 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 414 - break; 415 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR: 416 - *mode = hubp_3dlut_fl_mode_native_2; 417 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 418 - break; 419 - case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR: 420 - *mode = hubp_3dlut_fl_mode_transform; 421 - *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear; 422 - break; 423 - default: 424 - *mode = hubp_3dlut_fl_mode_disable; 425 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 426 - break; 427 - } 428 - } 429 - 430 - static void dc_get_lut_format( 431 - enum dc_cm2_gpu_mem_format dc_format, 432 - enum hubp_3dlut_fl_format *format) 433 - { 434 - switch (dc_format) { 435 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB: 436 - *format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 437 - break; 438 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB: 439 - *format = hubp_3dlut_fl_format_unorm_12lsb_bitslice; 440 - break; 441 - case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10: 442 - *format = hubp_3dlut_fl_format_float_fp1_5_10; 443 - break; 444 - } 445 - } 446 - 447 386 static bool dc_is_rmcm_3dlut_supported(struct hubp *hubp, struct mpc *mpc) 448 387 { 449 388 if (mpc->funcs->rmcm.power_on_shaper_3dlut && ··· 392 455 return false; 393 456 } 394 457 395 - static bool is_rmcm_3dlut_fl_supported(struct dc *dc, enum dc_cm2_gpu_mem_size size) 396 - { 397 - if (!dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut) 398 - return false; 399 - if (size == DC_CM2_GPU_MEM_SIZE_171717) 400 - return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17); 401 - else if (size == DC_CM2_GPU_MEM_SIZE_333333) 402 - return (dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33); 403 - return false; 404 - } 405 - 406 - static void dcn42_set_mcm_location_post_blend(struct dc *dc, struct pipe_ctx *pipe_ctx, bool bPostBlend) 407 - { 408 - struct mpc *mpc = dc->res_pool->mpc; 409 - int mpcc_id = pipe_ctx->plane_res.hubp->inst; 410 - 411 - if (!pipe_ctx->plane_state) 412 - return; 413 - 414 - mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); 415 - pipe_ctx->plane_state->mcm_location = (bPostBlend) ? 416 - MPCC_MOVABLE_CM_LOCATION_AFTER : 417 - MPCC_MOVABLE_CM_LOCATION_BEFORE; 418 - } 419 - 420 - static void dcn42_get_mcm_lut_xable_from_pipe_ctx(struct dc *dc, struct pipe_ctx *pipe_ctx, 421 - enum MCM_LUT_XABLE *shaper_xable, 422 - enum MCM_LUT_XABLE *lut3d_xable, 423 - enum MCM_LUT_XABLE *lut1d_xable) 424 - { 425 - enum dc_cm2_shaper_3dlut_setting shaper_3dlut_setting = DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL; 426 - bool lut1d_enable = false; 427 - struct mpc *mpc = dc->res_pool->mpc; 428 - int mpcc_id = pipe_ctx->plane_res.hubp->inst; 429 - 430 - if (!pipe_ctx->plane_state) 431 - return; 432 - shaper_3dlut_setting = pipe_ctx->plane_state->mcm_shaper_3dlut_setting; 433 - lut1d_enable = pipe_ctx->plane_state->mcm_lut1d_enable; 434 - mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); 435 - pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE; 436 - 437 - *lut1d_xable = lut1d_enable ? MCM_LUT_ENABLE : MCM_LUT_DISABLE; 438 - 439 - switch (shaper_3dlut_setting) { 440 - case DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL: 441 - *lut3d_xable = *shaper_xable = MCM_LUT_DISABLE; 442 - break; 443 - case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER: 444 - *lut3d_xable = MCM_LUT_DISABLE; 445 - *shaper_xable = MCM_LUT_ENABLE; 446 - break; 447 - case DC_CM2_SHAPER_3DLUT_SETTING_ENABLE_SHAPER_3DLUT: 448 - *lut3d_xable = *shaper_xable = MCM_LUT_ENABLE; 449 - break; 450 - } 451 - } 452 - 453 - static void fl_get_lut_mode( 454 - enum dc_cm2_gpu_mem_layout layout, 455 - enum dc_cm2_gpu_mem_size size, 456 - enum hubp_3dlut_fl_mode *mode, 457 - enum hubp_3dlut_fl_addressing_mode *addr_mode, 458 - enum hubp_3dlut_fl_width *width) 459 - { 460 - *width = hubp_3dlut_fl_width_17; 461 - 462 - if (size == DC_CM2_GPU_MEM_SIZE_333333) 463 - *width = hubp_3dlut_fl_width_33; 464 - 465 - switch (layout) { 466 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB: 467 - *mode = hubp_3dlut_fl_mode_native_1; 468 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 469 - break; 470 - case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR: 471 - *mode = hubp_3dlut_fl_mode_native_2; 472 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 473 - break; 474 - case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR: 475 - *mode = hubp_3dlut_fl_mode_transform; 476 - *addr_mode = hubp_3dlut_fl_addressing_mode_simple_linear; 477 - break; 478 - default: 479 - *mode = hubp_3dlut_fl_mode_disable; 480 - *addr_mode = hubp_3dlut_fl_addressing_mode_sw_linear; 481 - break; 482 - } 483 - } 484 - 485 458 bool dcn42_program_rmcm_luts( 486 459 struct hubp *hubp, 487 460 struct pipe_ctx *pipe_ctx, 488 - enum dc_cm2_transfer_func_source lut3d_src, 489 - struct dc_cm2_func_luts *mcm_luts, 461 + const struct dc_plane_cm *cm, 490 462 struct mpc *mpc, 491 - bool lut_bank_a, 492 463 int mpcc_id) 493 464 { 494 465 struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 495 466 union mcm_lut_params m_lut_params = {0}; 496 - enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, lut1d_xable; 497 - enum hubp_3dlut_fl_mode mode; 498 - enum hubp_3dlut_fl_addressing_mode addr_mode; 499 - enum hubp_3dlut_fl_format format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 500 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = hubp_3dlut_fl_crossbar_bit_slice_16_31; 501 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = hubp_3dlut_fl_crossbar_bit_slice_0_15; 502 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = hubp_3dlut_fl_crossbar_bit_slice_32_47; 503 - enum hubp_3dlut_fl_width width = hubp_3dlut_fl_width_17; 504 - 505 467 506 468 struct dc *dc = hubp->ctx->dc; 507 - struct hubp_fl_3dlut_config fl_config; 508 469 struct mpc_fl_3dlut_config mpc_fl_config; 509 470 510 471 struct dc_stream_state *stream = pipe_ctx->stream; ··· 410 575 // true->false when it can be allocated at DI time 411 576 struct dc_rmcm_3dlut *rmcm_3dlut = dc_stream_get_3dlut_for_stream(dc, stream, false); 412 577 578 + bool lut_bank_a = true; // TODO get from HW 579 + 413 580 //check to see current pipe is part of a stream with allocated rmcm 3dlut 414 581 if (!rmcm_3dlut) 415 582 return false; 416 583 417 - rmcm_3dlut->protection_bits = mcm_luts->lut3d_data.rmcm_tmz; 418 - 419 - dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable); 420 - 421 584 /* Shaper */ 422 - if (mcm_luts->shaper) { 585 + if (cm->flags.bits.shaper_enable) { 423 586 memset(&m_lut_params, 0, sizeof(m_lut_params)); 424 587 425 - if (mcm_luts->shaper->type == TF_TYPE_HWPWL) { 426 - m_lut_params.pwl = &mcm_luts->shaper->pwl; 427 - } else if (mcm_luts->shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { 588 + if (cm->shaper_func.type == TF_TYPE_HWPWL) { 589 + m_lut_params.pwl = &cm->shaper_func.pwl; 590 + } else if (cm->shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { 428 591 ASSERT(false); 429 592 cm_helper_translate_curve_to_hw_format( 430 593 dc->ctx, 431 - mcm_luts->shaper, 594 + &cm->shaper_func, 432 595 &dpp_base->shaper_params, true); 433 596 m_lut_params.pwl = &dpp_base->shaper_params; 434 597 } ··· 442 609 } 443 610 444 611 /* 3DLUT */ 445 - switch (lut3d_src) { 446 - case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM: 612 + if (!cm->flags.bits.lut3d_dma_enable) { 447 613 memset(&m_lut_params, 0, sizeof(m_lut_params)); 448 614 // Don't know what to do in this case. 449 - //case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM: 450 - break; 451 - case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM: 452 - fl_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout, 453 - mcm_luts->lut3d_data.gpu_mem_params.size, 454 - &mode, 455 - &addr_mode, 456 - &width); 457 - 458 - if (!dc_is_rmcm_3dlut_supported(hubp, mpc) || 459 - !mpc->funcs->rmcm.is_config_supported( 460 - (width == hubp_3dlut_fl_width_17 || 461 - width == hubp_3dlut_fl_width_transformed) ? 17 : 33)) 615 + } else { 616 + if (!dc_is_rmcm_3dlut_supported(hubp, mpc)) 462 617 return false; 463 618 464 - // setting native or transformed mode, 465 - dc_get_lut_mode(mcm_luts->lut3d_data.gpu_mem_params.layout, &mode, &addr_mode); 466 - 467 619 //seems to be only for the MCM 468 - dc_get_lut_format(mcm_luts->lut3d_data.gpu_mem_params.format_params.format, &format); 469 - 470 - dc_get_lut_xbar( 471 - mcm_luts->lut3d_data.gpu_mem_params.component_order, 472 - &crossbar_bit_slice_cr_r, 473 - &crossbar_bit_slice_y_g, 474 - &crossbar_bit_slice_cb_b); 475 - 476 - fl_config.mode = mode; 477 - fl_config.enabled = lut3d_xable != MCM_LUT_DISABLE; 478 - fl_config.address = mcm_luts->lut3d_data.gpu_mem_params.addr; 479 - fl_config.format = format; 480 - fl_config.crossbar_bit_slice_y_g = crossbar_bit_slice_y_g; 481 - fl_config.crossbar_bit_slice_cb_b = crossbar_bit_slice_cb_b; 482 - fl_config.crossbar_bit_slice_cr_r = crossbar_bit_slice_cr_r; 483 - fl_config.width = width; 484 - fl_config.protection_bits = rmcm_3dlut->protection_bits; 485 - fl_config.addr_mode = addr_mode; 486 - fl_config.layout = mcm_luts->lut3d_data.gpu_mem_params.layout; 487 - fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias; 488 - fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale; 489 - 490 - mpc_fl_config.enabled = fl_config.enabled; 491 - mpc_fl_config.width = width; 620 + mpc_fl_config.enabled = cm->flags.bits.lut3d_enable; 621 + mpc_fl_config.size = cm->lut3d_dma.size; 492 622 mpc_fl_config.select_lut_bank_a = lut_bank_a; 493 - mpc_fl_config.bit_depth = mcm_luts->lut3d_data.gpu_mem_params.bit_depth; 623 + mpc_fl_config.bit_depth = 0; 494 624 mpc_fl_config.hubp_index = hubp->inst; 495 - mpc_fl_config.bias = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.bias; 496 - mpc_fl_config.scale = mcm_luts->lut3d_data.gpu_mem_params.format_params.float_params.scale; 625 + mpc_fl_config.bias = cm->lut3d_dma.bias; 626 + mpc_fl_config.scale = cm->lut3d_dma.scale; 497 627 498 628 //1. power down the block 499 629 mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, false); ··· 464 668 //2. program RMCM - 3dlut reg programming 465 669 mpc->funcs->rmcm.fl_3dlut_configure(mpc, &mpc_fl_config, mpcc_id); 466 670 467 - hubp->funcs->hubp_program_3dlut_fl_config(hubp, &fl_config); 671 + /* HUBP */ 672 + if (hubp->funcs->hubp_program_3dlut_fl_config) 673 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 674 + 675 + if (hubp->funcs->hubp_program_3dlut_fl_addr) 676 + hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 468 677 469 678 //3. power on the block 470 679 mpc->funcs->rmcm.power_on_shaper_3dlut(mpc, mpcc_id, true); 471 - 472 - break; 473 - default: 474 - return false; 475 680 } 476 681 477 682 return true; 478 683 } 479 684 480 - void dcn42_populate_mcm_luts(struct dc *dc, 481 - struct pipe_ctx *pipe_ctx, 482 - struct dc_cm2_func_luts mcm_luts, 483 - bool lut_bank_a) 484 - { 485 - struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 486 - struct hubp *hubp = pipe_ctx->plane_res.hubp; 487 - int mpcc_id = hubp->inst; 488 - struct mpc *mpc = dc->res_pool->mpc; 489 - union mcm_lut_params m_lut_params; 490 - enum dc_cm2_transfer_func_source lut3d_src = mcm_luts.lut3d_data.lut3d_src; 491 - enum hubp_3dlut_fl_format format = 0; 492 - enum hubp_3dlut_fl_mode mode; 493 - enum hubp_3dlut_fl_width width = 0; 494 - enum hubp_3dlut_fl_addressing_mode addr_mode; 495 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0; 496 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0; 497 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0; 498 - enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE; 499 - enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE; 500 - enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE; 501 - bool rval; 502 - 503 - dcn42_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, &lut3d_xable, &lut1d_xable); 504 - 505 - //MCM - setting its location (Before/After) blender 506 - //set to post blend (true) 507 - dcn42_set_mcm_location_post_blend( 508 - dc, 509 - pipe_ctx, 510 - mcm_luts.lut3d_data.mpc_mcm_post_blend); 511 - 512 - //RMCM - 3dLUT+Shaper 513 - if (mcm_luts.lut3d_data.rmcm_3dlut_enable && 514 - is_rmcm_3dlut_fl_supported(dc, mcm_luts.lut3d_data.gpu_mem_params.size)) { 515 - dcn42_program_rmcm_luts( 516 - hubp, 517 - pipe_ctx, 518 - lut3d_src, 519 - &mcm_luts, 520 - mpc, 521 - lut_bank_a, 522 - mpcc_id); 523 - } 524 - 525 - /* 1D LUT */ 526 - if (mcm_luts.lut1d_func) { 527 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 528 - if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL) 529 - m_lut_params.pwl = &mcm_luts.lut1d_func->pwl; 530 - else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) { 531 - rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx, 532 - mcm_luts.lut1d_func, 533 - &dpp_base->regamma_params, false); 534 - m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL; 535 - } 536 - if (m_lut_params.pwl) { 537 - if (mpc->funcs->populate_lut) 538 - mpc->funcs->populate_lut(mpc, MCM_LUT_1DLUT, m_lut_params, lut_bank_a, mpcc_id); 539 - } 540 - if (mpc->funcs->program_lut_mode) 541 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, lut1d_xable && m_lut_params.pwl, lut_bank_a, mpcc_id); 542 - } 543 - 544 - /* Shaper */ 545 - if (mcm_luts.shaper && mcm_luts.lut3d_data.mpc_3dlut_enable) { 546 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 547 - if (mcm_luts.shaper->type == TF_TYPE_HWPWL) 548 - m_lut_params.pwl = &mcm_luts.shaper->pwl; 549 - else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { 550 - ASSERT(false); 551 - rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx, 552 - mcm_luts.shaper, 553 - &dpp_base->regamma_params, true); 554 - m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL; 555 - } 556 - if (m_lut_params.pwl) { 557 - if (mpc->funcs->mcm.populate_lut) 558 - mpc->funcs->mcm.populate_lut(mpc, m_lut_params, lut_bank_a, mpcc_id); 559 - if (mpc->funcs->program_lut_mode) 560 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_ENABLE, lut_bank_a, mpcc_id); 561 - } 562 - } 563 - 564 - /* 3DLUT */ 565 - switch (lut3d_src) { 566 - case DC_CM2_TRANSFER_FUNC_SOURCE_SYSMEM: 567 - memset(&m_lut_params, 0, sizeof(m_lut_params)); 568 - if (hubp->funcs->hubp_enable_3dlut_fl) 569 - hubp->funcs->hubp_enable_3dlut_fl(hubp, false); 570 - 571 - if (mcm_luts.lut3d_data.lut3d_func && mcm_luts.lut3d_data.lut3d_func->state.bits.initialized) { 572 - m_lut_params.lut3d = &mcm_luts.lut3d_data.lut3d_func->lut_3d; 573 - if (mpc->funcs->populate_lut) 574 - mpc->funcs->populate_lut(mpc, MCM_LUT_3DLUT, m_lut_params, lut_bank_a, mpcc_id); 575 - if (mpc->funcs->program_lut_mode) 576 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, 577 - mpcc_id); 578 - } 579 - break; 580 - case DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM: 581 - switch (mcm_luts.lut3d_data.gpu_mem_params.size) { 582 - case DC_CM2_GPU_MEM_SIZE_333333: 583 - width = hubp_3dlut_fl_width_33; 584 - break; 585 - case DC_CM2_GPU_MEM_SIZE_171717: 586 - width = hubp_3dlut_fl_width_17; 587 - break; 588 - case DC_CM2_GPU_MEM_SIZE_TRANSFORMED: 589 - width = hubp_3dlut_fl_width_transformed; 590 - break; 591 - default: 592 - //TODO: Handle default case 593 - break; 594 - } 595 - 596 - //check for support 597 - if (mpc->funcs->mcm.is_config_supported && 598 - !mpc->funcs->mcm.is_config_supported(width)) 599 - break; 600 - 601 - if (mpc->funcs->program_lut_read_write_control) 602 - mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, mpcc_id); 603 - if (mpc->funcs->program_lut_mode) 604 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, lut3d_xable, lut_bank_a, mpcc_id); 605 - 606 - if (hubp->funcs->hubp_program_3dlut_fl_addr) 607 - hubp->funcs->hubp_program_3dlut_fl_addr(hubp, mcm_luts.lut3d_data.gpu_mem_params.addr); 608 - 609 - if (mpc->funcs->mcm.program_bit_depth) 610 - mpc->funcs->mcm.program_bit_depth(mpc, mcm_luts.lut3d_data.gpu_mem_params.bit_depth, mpcc_id); 611 - 612 - dc_get_lut_mode(mcm_luts.lut3d_data.gpu_mem_params.layout, &mode, &addr_mode); 613 - if (hubp->funcs->hubp_program_3dlut_fl_mode) 614 - hubp->funcs->hubp_program_3dlut_fl_mode(hubp, mode); 615 - 616 - if (hubp->funcs->hubp_program_3dlut_fl_addressing_mode) 617 - hubp->funcs->hubp_program_3dlut_fl_addressing_mode(hubp, addr_mode); 618 - 619 - switch (mcm_luts.lut3d_data.gpu_mem_params.format_params.format) { 620 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12MSB: 621 - format = hubp_3dlut_fl_format_unorm_12msb_bitslice; 622 - break; 623 - case DC_CM2_GPU_MEM_FORMAT_16161616_UNORM_12LSB: 624 - format = hubp_3dlut_fl_format_unorm_12lsb_bitslice; 625 - break; 626 - case DC_CM2_GPU_MEM_FORMAT_16161616_FLOAT_FP1_5_10: 627 - format = hubp_3dlut_fl_format_float_fp1_5_10; 628 - break; 629 - } 630 - if (hubp->funcs->hubp_program_3dlut_fl_format) 631 - hubp->funcs->hubp_program_3dlut_fl_format(hubp, format); 632 - if (hubp->funcs->hubp_update_3dlut_fl_bias_scale && 633 - mpc->funcs->mcm.program_bias_scale) { 634 - mpc->funcs->mcm.program_bias_scale(mpc, 635 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias, 636 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale, 637 - mpcc_id); 638 - hubp->funcs->hubp_update_3dlut_fl_bias_scale(hubp, 639 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.bias, 640 - mcm_luts.lut3d_data.gpu_mem_params.format_params.float_params.scale); 641 - } 642 - 643 - //navi 4x has a bug and r and blue are swapped and need to be worked around here in 644 - //TODO: need to make a method for get_xbar per asic OR do the workaround in program_crossbar for 4x 645 - dc_get_lut_xbar( 646 - mcm_luts.lut3d_data.gpu_mem_params.component_order, 647 - &crossbar_bit_slice_cr_r, 648 - &crossbar_bit_slice_y_g, 649 - &crossbar_bit_slice_cb_b); 650 - 651 - if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 652 - hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, 653 - crossbar_bit_slice_cr_r, 654 - crossbar_bit_slice_y_g, 655 - crossbar_bit_slice_cb_b); 656 - 657 - if (mpc->funcs->mcm.program_lut_read_write_control) 658 - mpc->funcs->mcm.program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, true, mpcc_id); 659 - 660 - if (mpc->funcs->mcm.program_3dlut_size) 661 - mpc->funcs->mcm.program_3dlut_size(mpc, width, mpcc_id); 662 - 663 - if (mpc->funcs->update_3dlut_fast_load_select) 664 - mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst); 665 - 666 - if (hubp->funcs->hubp_enable_3dlut_fl) 667 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 668 - else { 669 - if (mpc->funcs->program_lut_mode) { 670 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_SHAPER, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 671 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 672 - mpc->funcs->program_lut_mode(mpc, MCM_LUT_1DLUT, MCM_LUT_DISABLE, lut_bank_a, mpcc_id); 673 - } 674 - } 675 - break; 676 - } 677 - } 678 - 679 685 bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx, 680 686 const struct dc_plane_state *plane_state) 681 687 { 682 - struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 683 - int mpcc_id = pipe_ctx->plane_res.hubp->inst; 684 - struct dc *dc = pipe_ctx->stream_res.opp->ctx->dc; 688 + struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc; 689 + struct hubp *hubp = pipe_ctx->plane_res.hubp; 690 + const struct dc_plane_cm *cm = &plane_state->cm; 685 691 struct mpc *mpc = dc->res_pool->mpc; 692 + int mpcc_id = hubp->inst; 686 693 bool result; 687 - const struct pwl_params *lut_params = NULL; 688 - bool rval; 689 694 690 - if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) { 691 - dcn42_populate_mcm_luts(dc, pipe_ctx, plane_state->mcm_luts, plane_state->lut_bank_a); 692 - return true; 693 - } 695 + /* MCM */ 696 + result = dcn401_set_mcm_luts(pipe_ctx, plane_state); 694 697 695 - mpc->funcs->set_movable_cm_location(mpc, MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id); 696 - pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE; 697 - // 1D LUT 698 - if (plane_state->blend_tf.type == TF_TYPE_HWPWL) 699 - lut_params = &plane_state->blend_tf.pwl; 700 - else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { 701 - rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 702 - &plane_state->blend_tf, 703 - &dpp_base->regamma_params, false); 704 - lut_params = rval ? &dpp_base->regamma_params : NULL; 705 - } 706 - result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id); 707 - lut_params = NULL; 708 - 709 - // Shaper 710 - if (plane_state->in_shaper_func.type == TF_TYPE_HWPWL) 711 - lut_params = &plane_state->in_shaper_func.pwl; 712 - else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { 713 - // TODO: dpp_base replace 714 - rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, 715 - &plane_state->in_shaper_func, 716 - &dpp_base->shaper_params, true); 717 - lut_params = rval ? &dpp_base->shaper_params : NULL; 718 - } 719 - result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); 720 - 721 - // 3D 722 - if (mpc->funcs->program_3dlut) { 723 - if (plane_state->lut3d_func.state.bits.initialized == 1) 724 - result &= mpc->funcs->program_3dlut(mpc, &plane_state->lut3d_func.lut_3d, mpcc_id); 725 - else 726 - result &= mpc->funcs->program_3dlut(mpc, NULL, mpcc_id); 698 + /* RMCM */ 699 + if (cm->flags.bits.rmcm_enable && cm->flags.bits.lut3d_dma_enable) { 700 + /* TODO - move RMCM to its own block */ 701 + dcn42_program_rmcm_luts( 702 + hubp, 703 + pipe_ctx, 704 + cm, 705 + mpc, 706 + mpcc_id); 727 707 } 728 708 729 709 return result; ··· 622 1050 dc->hwss.hw_block_power_up(dc, &pg_update_state); 623 1051 } 624 1052 625 - dcn20_prepare_bandwidth(dc, context); 1053 + dcn401_prepare_bandwidth(dc, context); 626 1054 } 627 1055 628 1056 void dcn42_optimize_bandwidth(struct dc *dc, struct dc_state *context) ··· 1041 1469 hw_lock_cmd.bits.should_release = !lock; 1042 1470 dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd); 1043 1471 } 1472 + } 1473 + 1474 + /* In headless boot cases, DIG may be turned 1475 + * on which causes HW/SW discrepancies. 1476 + * To avoid this, power down hardware on boot 1477 + * if DIG is turned on 1478 + */ 1479 + void dcn42_power_down_on_boot(struct dc *dc) 1480 + { 1481 + struct dc_link *edp_links[MAX_NUM_EDP]; 1482 + struct dc_link *edp_link = NULL; 1483 + int edp_num; 1484 + int i = 0; 1485 + 1486 + dc_get_edp_links(dc, edp_links, &edp_num); 1487 + if (edp_num) 1488 + edp_link = edp_links[0]; 1489 + 1490 + if (edp_link && edp_link->link_enc->funcs->is_dig_enabled && 1491 + edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && 1492 + dc->hwseq->funcs.edp_backlight_control && 1493 + dc->hwseq->funcs.power_down && 1494 + dc->hwss.edp_power_control) { 1495 + dc->hwseq->funcs.edp_backlight_control(edp_link, false); 1496 + dc->hwseq->funcs.power_down(dc); 1497 + dc->hwss.edp_power_control(edp_link, false); 1498 + } else { 1499 + for (i = 0; i < dc->link_count; i++) { 1500 + struct dc_link *link = dc->links[i]; 1501 + 1502 + if (link->link_enc && link->link_enc->funcs->is_dig_enabled && 1503 + link->link_enc->funcs->is_dig_enabled(link->link_enc) && 1504 + dc->hwseq->funcs.power_down) { 1505 + dc->hwseq->funcs.power_down(dc); 1506 + break; 1507 + } 1508 + 1509 + } 1510 + } 1511 + 1512 + /* 1513 + * Call update_clocks with empty context 1514 + * to send DISPLAY_OFF 1515 + * Otherwise DISPLAY_OFF may not be asserted 1516 + */ 1517 + if (dc->clk_mgr->funcs->set_low_power_state) 1518 + dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr); 1044 1519 }
+2 -8
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.h
··· 18 18 bool dcn42_set_mcm_luts(struct pipe_ctx *pipe_ctx, 19 19 const struct dc_plane_state *plane_state); 20 20 21 - void dcn42_populate_mcm_luts(struct dc *dc, 22 - struct pipe_ctx *pipe_ctx, 23 - struct dc_cm2_func_luts mcm_luts, 24 - bool lut_bank_a); 25 - 26 21 bool dcn42_program_rmcm_luts( 27 22 struct hubp *hubp, 28 23 struct pipe_ctx *pipe_ctx, 29 - enum dc_cm2_transfer_func_source lut3d_src, 30 - struct dc_cm2_func_luts *mcm_luts, 24 + const struct dc_plane_cm *cm, 31 25 struct mpc *mpc, 32 - bool lut_bank_a, 33 26 int mpcc_id); 34 27 void dcn42_hardware_release(struct dc *dc); 35 28 ··· 43 50 void dcn42_dmub_hw_control_lock(struct dc *dc, struct dc_state *context, bool lock); 44 51 void dcn42_dmub_hw_control_lock_fast(union block_sequence_params *params); 45 52 void dcn42_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc); 53 + void dcn42_power_down_on_boot(struct dc *dc); 46 54 #endif
+7 -1
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_init.c
··· 19 19 .program_gamut_remap = dcn401_program_gamut_remap, 20 20 .init_hw = dcn42_init_hw, 21 21 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 22 - .power_down_on_boot = dcn35_power_down_on_boot, 22 + .power_down_on_boot = dcn42_power_down_on_boot, 23 23 .apply_ctx_for_surface = NULL, 24 24 .program_front_end_for_ctx = dcn401_program_front_end_for_ctx, 25 25 .clear_surface_dcc_and_tiling = dcn10_reset_surface_dcc_and_tiling, ··· 64 64 .set_cursor_position = dcn401_set_cursor_position, 65 65 .set_cursor_attribute = dcn10_set_cursor_attribute, 66 66 .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, 67 + .abort_cursor_offload_update = dcn35_abort_cursor_offload_update, 68 + .begin_cursor_offload_update = dcn35_begin_cursor_offload_update, 69 + .commit_cursor_offload_update = dcn35_commit_cursor_offload_update, 70 + .update_cursor_offload_pipe = dcn401_update_cursor_offload_pipe, 71 + .notify_cursor_offload_drr_update = dcn35_notify_cursor_offload_drr_update, 72 + .program_cursor_offload_now = dcn35_program_cursor_offload_now, 67 73 .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, 68 74 .set_clock = dcn10_set_clock, 69 75 .get_clock = dcn10_get_clock,
+1 -1
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
··· 215 215 uint32_t dcfclk_bypass; 216 216 uint32_t dprefclk_bypass; 217 217 uint32_t dispclk_bypass; 218 - uint32_t timer_threhold; 218 + uint32_t timer_threshold; 219 219 }; 220 220 221 221 struct rv1_clk_internal {
+56 -17
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
··· 243 243 CLK_SR_DCN42(CLK8_CLK3_DS_CNTL), \ 244 244 CLK_SR_DCN42(CLK8_CLK4_DS_CNTL) 245 245 246 - #define CLK_COMMON_MASK_SH_LIST_DCN42(mask_sh) 0 246 + #define CLK_COMMON_MASK_SH_LIST_DCN42(mask_sh) \ 247 + CLK_SF(CLK8_CLK_TICK_CNT_CONFIG_REG, TIMER_THRESHOLD, mask_sh), \ 248 + CLK_SF(CLK8_CLK0_BYPASS_CNTL, CLK0_BYPASS_SEL, mask_sh), \ 249 + CLK_SF(CLK8_CLK1_BYPASS_CNTL, CLK1_BYPASS_SEL, mask_sh), \ 250 + CLK_SF(CLK8_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, mask_sh), \ 251 + CLK_SF(CLK8_CLK3_BYPASS_CNTL, CLK3_BYPASS_SEL, mask_sh), \ 252 + CLK_SF(CLK8_CLK4_BYPASS_CNTL, CLK4_BYPASS_SEL, mask_sh), \ 253 + CLK_SF(CLK8_CLK0_DS_CNTL, CLK0_DS_DIV_ID, mask_sh), \ 254 + CLK_SF(CLK8_CLK1_DS_CNTL, CLK1_DS_DIV_ID, mask_sh), \ 255 + CLK_SF(CLK8_CLK2_DS_CNTL, CLK2_DS_DIV_ID, mask_sh), \ 256 + CLK_SF(CLK8_CLK3_DS_CNTL, CLK3_DS_DIV_ID, mask_sh), \ 257 + CLK_SF(CLK8_CLK4_DS_CNTL, CLK4_DS_DIV_ID, mask_sh), \ 258 + CLK_SF(CLK8_CLK0_DS_CNTL, CLK0_ALLOW_DS, mask_sh), \ 259 + CLK_SF(CLK8_CLK1_DS_CNTL, CLK1_ALLOW_DS, mask_sh), \ 260 + CLK_SF(CLK8_CLK2_DS_CNTL, CLK2_ALLOW_DS, mask_sh), \ 261 + CLK_SF(CLK8_CLK3_DS_CNTL, CLK3_ALLOW_DS, mask_sh), \ 262 + CLK_SF(CLK8_CLK4_DS_CNTL, CLK4_ALLOW_DS, mask_sh), \ 247 263 248 264 249 265 ··· 274 258 type DENTIST_DPPCLK_CHG_DONE; \ 275 259 type FbMult_int; \ 276 260 type FbMult_frac; 261 + 262 + #define CLK42_REG_LIST(clkip_num, type) \ 263 + type CLK ## clkip_num ## _CLK_TICK_CNT_CONFIG_REG; \ 264 + type CLK ## clkip_num ## _CLK0_CURRENT_CNT; \ 265 + type CLK ## clkip_num ## _CLK1_CURRENT_CNT; \ 266 + type CLK ## clkip_num ## _CLK2_CURRENT_CNT; \ 267 + type CLK ## clkip_num ## _CLK3_CURRENT_CNT; \ 268 + type CLK ## clkip_num ## _CLK4_CURRENT_CNT; \ 269 + type CLK ## clkip_num ## _CLK0_BYPASS_CNTL; \ 270 + type CLK ## clkip_num ## _CLK1_BYPASS_CNTL; \ 271 + type CLK ## clkip_num ## _CLK2_BYPASS_CNTL; \ 272 + type CLK ## clkip_num ## _CLK3_BYPASS_CNTL; \ 273 + type CLK ## clkip_num ## _CLK4_BYPASS_CNTL; \ 274 + type CLK ## clkip_num ## _CLK0_DS_CNTL; \ 275 + type CLK ## clkip_num ## _CLK1_DS_CNTL; \ 276 + type CLK ## clkip_num ## _CLK2_DS_CNTL; \ 277 + type CLK ## clkip_num ## _CLK3_DS_CNTL; \ 278 + type CLK ## clkip_num ## _CLK4_DS_CNTL; 279 + 280 + #define CLK42_REG_FIELD_LIST(type) \ 281 + type TIMER_THRESHOLD; \ 282 + type CLK0_BYPASS_SEL; \ 283 + type CLK1_BYPASS_SEL; \ 284 + type CLK2_BYPASS_SEL; \ 285 + type CLK3_BYPASS_SEL; \ 286 + type CLK4_BYPASS_SEL; \ 287 + type CLK0_DS_DIV_ID; \ 288 + type CLK1_DS_DIV_ID; \ 289 + type CLK2_DS_DIV_ID; \ 290 + type CLK3_DS_DIV_ID; \ 291 + type CLK4_DS_DIV_ID; \ 292 + type CLK0_ALLOW_DS; \ 293 + type CLK1_ALLOW_DS; \ 294 + type CLK2_ALLOW_DS; \ 295 + type CLK3_ALLOW_DS; \ 296 + type CLK4_ALLOW_DS; 277 297 278 298 /* 279 299 *************************************************************************************** ··· 374 322 uint32_t CLK1_CLK5_ALLOW_DS; 375 323 uint32_t CLK5_spll_field_8; 376 324 uint32_t CLK6_spll_field_8; 377 - uint32_t CLK8_CLK0_CURRENT_CNT; 378 - uint32_t CLK8_CLK1_CURRENT_CNT; 379 - uint32_t CLK8_CLK2_CURRENT_CNT; 380 - uint32_t CLK8_CLK3_CURRENT_CNT; 381 - uint32_t CLK8_CLK4_CURRENT_CNT; 382 - uint32_t CLK8_CLK0_DS_CNTL; 383 - uint32_t CLK8_CLK1_DS_CNTL; 384 - uint32_t CLK8_CLK2_DS_CNTL; 385 - uint32_t CLK8_CLK3_DS_CNTL; 386 - uint32_t CLK8_CLK4_DS_CNTL; 387 - uint32_t CLK8_CLK0_BYPASS_CNTL; 388 - uint32_t CLK8_CLK1_BYPASS_CNTL; 389 - uint32_t CLK8_CLK2_BYPASS_CNTL; 390 - uint32_t CLK8_CLK3_BYPASS_CNTL; 391 - uint32_t CLK8_CLK4_BYPASS_CNTL; 392 - uint32_t CLK8_CLK_TICK_CNT_CONFIG_REG; 325 + CLK42_REG_LIST(8, uint32_t) 393 326 }; 394 327 395 328 struct clk_mgr_shift { 396 329 CLK_REG_FIELD_LIST(uint8_t) 397 330 CLK20_REG_FIELD_LIST(uint8_t) 331 + CLK42_REG_FIELD_LIST(uint8_t) 398 332 }; 399 333 400 334 struct clk_mgr_mask { 401 335 CLK_REG_FIELD_LIST(uint32_t) 402 336 CLK20_REG_FIELD_LIST(uint32_t) 337 + CLK42_REG_FIELD_LIST(uint32_t) 403 338 }; 404 339 405 340 enum clock_type {
+5 -31
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
··· 89 89 enum hubp_3dlut_fl_width { 90 90 hubp_3dlut_fl_width_17 = 17, 91 91 hubp_3dlut_fl_width_33 = 33, 92 - hubp_3dlut_fl_width_transformed = 4916, //mpc default 92 + hubp_3dlut_fl_width_17_transformed = 4916, //mpc default 93 93 }; 94 94 95 95 enum hubp_3dlut_fl_crossbar_bit_slice { ··· 97 97 hubp_3dlut_fl_crossbar_bit_slice_16_31 = 1, 98 98 hubp_3dlut_fl_crossbar_bit_slice_32_47 = 2, 99 99 hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3 100 - }; 101 - 102 - struct hubp_fl_3dlut_config { 103 - bool enabled; 104 - enum hubp_3dlut_fl_width width; 105 - enum hubp_3dlut_fl_mode mode; 106 - enum hubp_3dlut_fl_format format; 107 - uint16_t bias; 108 - uint16_t scale; 109 - struct dc_plane_address address; 110 - enum hubp_3dlut_fl_addressing_mode addr_mode; 111 - enum dc_cm2_gpu_mem_layout layout; 112 - uint8_t protection_bits; 113 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; 114 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; 115 - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; 116 100 }; 117 101 118 102 struct hubp { ··· 227 243 void (*hubp_disable_control)(struct hubp *hubp, bool disable_hubp); 228 244 unsigned int (*hubp_get_underflow_status)(struct hubp *hubp); 229 245 void (*hubp_init)(struct hubp *hubp); 230 - 231 246 void (*dmdata_set_attributes)( 232 247 struct hubp *hubp, 233 248 const struct dc_dmdata_attributes *attr); ··· 273 290 274 291 void (*hubp_wait_pipe_read_start)(struct hubp *hubp); 275 292 void (*hubp_program_mcache_id_and_split_coordinate)(struct hubp *hubp, struct dml2_hubp_pipe_mcache_regs *mcache_regs); 276 - void (*hubp_update_3dlut_fl_bias_scale)(struct hubp *hubp, uint16_t bias, uint16_t scale); 277 - void (*hubp_program_3dlut_fl_mode)(struct hubp *hubp, 278 - enum hubp_3dlut_fl_mode mode); 279 - void (*hubp_program_3dlut_fl_format)(struct hubp *hubp, 280 - enum hubp_3dlut_fl_format format); 281 293 void (*hubp_program_3dlut_fl_addr)(struct hubp *hubp, 282 - const struct dc_plane_address address); 294 + const struct dc_plane_address *address); 295 + void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, 296 + const struct dc_3dlut_dma *config); 283 297 void (*hubp_program_3dlut_fl_dlg_param)(struct hubp *hubp, int refcyc_per_3dlut_group); 284 298 void (*hubp_enable_3dlut_fl)(struct hubp *hubp, bool enable); 285 - void (*hubp_program_3dlut_fl_addressing_mode)(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode); 286 - void (*hubp_program_3dlut_fl_width)(struct hubp *hubp, enum hubp_3dlut_fl_width width); 287 - void (*hubp_program_3dlut_fl_tmz_protected)(struct hubp *hubp, uint8_t protection_bits); 288 299 void (*hubp_program_3dlut_fl_crossbar)(struct hubp *hubp, 289 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g, 290 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, 291 - enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); 300 + enum dc_cm_lut_pixel_format format); 292 301 int (*hubp_get_3dlut_fl_done)(struct hubp *hubp); 293 - void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg); 294 302 void (*hubp_clear_tiling)(struct hubp *hubp); 295 303 uint32_t (*hubp_get_current_read_line)(struct hubp *hubp); 296 304 uint32_t (*hubp_get_det_config_error)(struct hubp *hubp);
+17 -1
drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
··· 152 152 uint32_t blue; 153 153 }; 154 154 155 + struct tetrahedral_33x33x33 { 156 + struct dc_rgb lut0[8985]; 157 + struct dc_rgb lut1[8984]; 158 + struct dc_rgb lut2[8984]; 159 + struct dc_rgb lut3[8984]; 160 + }; 161 + 155 162 struct tetrahedral_17x17x17 { 156 163 struct dc_rgb lut0[1229]; 157 164 struct dc_rgb lut1[1228]; ··· 172 165 struct dc_rgb lut3[182]; 173 166 }; 174 167 168 + enum lut_dimension { 169 + LUT_DIM_INVALID = 0, 170 + LUT_DIM_9 = 9, 171 + LUT_DIM_17 = 17, 172 + LUT_DIM_33 = 33, 173 + }; 174 + 175 175 struct tetrahedral_params { 176 176 union { 177 + //TODO: Uncomment when in use. 178 + // struct tetrahedral_33x33x33 tetrahedral_33; 177 179 struct tetrahedral_17x17x17 tetrahedral_17; 178 180 struct tetrahedral_9x9x9 tetrahedral_9; 179 181 }; 180 182 bool use_tetrahedral_9; 181 183 bool use_12bits; 182 - 184 + enum lut_dimension lut_dim; 183 185 }; 184 186 185 187 /* arr_curve_points - regamma regions/segments specification
+63 -49
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
··· 54 54 #include "dc_hw_types.h" 55 55 #include "hw_shared.h" 56 56 #include "transform.h" 57 + #include "dc_types.h" 57 58 58 59 #define MAX_MPCC 6 59 60 #define MAX_OPP 6 ··· 66 65 MPC_OUTPUT_CSC_COEF_A, 67 66 MPC_OUTPUT_CSC_COEF_B 68 67 }; 69 - 70 68 71 69 enum mpcc_blend_mode { 72 70 MPCC_BLEND_MODE_BYPASS, ··· 102 102 MPCC_MOVABLE_CM_LOCATION_AFTER, 103 103 }; 104 104 105 - enum MCM_LUT_XABLE { 106 - MCM_LUT_DISABLE, 107 - MCM_LUT_DISABLED = MCM_LUT_DISABLE, 108 - MCM_LUT_ENABLE, 109 - MCM_LUT_ENABLED = MCM_LUT_ENABLE, 110 - }; 111 - 112 105 enum MCM_LUT_ID { 113 106 MCM_LUT_3DLUT, 114 107 MCM_LUT_1DLUT, ··· 110 117 111 118 struct mpc_fl_3dlut_config { 112 119 bool enabled; 113 - uint16_t width; 120 + enum dc_cm_lut_size size; 114 121 bool select_lut_bank_a; 115 122 uint16_t bit_depth; 116 123 int hubp_index; ··· 1035 1042 1036 1043 void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); 1037 1044 1038 - /** 1039 - * @get_3dlut_fast_load_status: 1040 - * 1041 - * Get 3D LUT fast load status and reference them with done, soft_underflow and hard_underflow pointers. 1042 - * 1043 - * Parameters: 1044 - * - [in/out] mpc - MPC context. 1045 - * - [in] mpcc_id 1046 - * - [in/out] done 1047 - * - [in/out] soft_underflow 1048 - * - [in/out] hard_underflow 1049 - * 1050 - * Return: 1051 - * 1052 - * void 1053 - */ 1045 + /** 1046 + * @get_3dlut_fast_load_status: 1047 + * 1048 + * Get 3D LUT fast load status and reference them with done, soft_underflow and hard_underflow pointers. 1049 + * 1050 + * Parameters: 1051 + * - [in/out] mpc - MPC context. 1052 + * - [in] mpcc_id 1053 + * - [in/out] done 1054 + * - [in/out] soft_underflow 1055 + * - [in/out] hard_underflow 1056 + * 1057 + * Return: 1058 + * 1059 + * void 1060 + */ 1054 1061 void (*get_3dlut_fast_load_status)(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow); 1055 1062 1056 1063 /** ··· 1069 1076 * 1070 1077 * void 1071 1078 */ 1072 - void (*populate_lut)(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, 1073 - bool lut_bank_a, int mpcc_id); 1079 + void (*populate_lut)(struct mpc *mpc, 1080 + const enum MCM_LUT_ID id, 1081 + const union mcm_lut_params *params, 1082 + const bool lut_bank_a, 1083 + const int mpcc_id); 1074 1084 1075 1085 /** 1076 1086 * @program_lut_read_write_control: ··· 1084 1088 * - [in/out] mpc - MPC context. 1085 1089 * - [in] id 1086 1090 * - [in] lut_bank_a 1091 + * - [in] bit_depth 1087 1092 * - [in] mpcc_id 1088 1093 * 1089 1094 * Return: 1090 1095 * 1091 1096 * void 1092 1097 */ 1093 - void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id); 1098 + void (*program_lut_read_write_control)(struct mpc *mpc, 1099 + const enum MCM_LUT_ID id, 1100 + const bool lut_bank_a, 1101 + const unsigned int bit_depth, 1102 + const int mpcc_id); 1094 1103 1095 1104 /** 1096 1105 * @program_lut_mode: ··· 1105 1104 * Parameters: 1106 1105 * - [in/out] mpc - MPC context. 1107 1106 * - [in] id 1108 - * - [in] xable 1107 + * - [in] enable 1109 1108 * - [in] lut_bank_a 1109 + * - [in] size 1110 1110 * - [in] mpcc_id 1111 1111 * 1112 1112 * Return: 1113 1113 * 1114 1114 * void 1115 1115 */ 1116 - void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, const enum MCM_LUT_XABLE xable, 1117 - bool lut_bank_a, int mpcc_id); 1116 + void (*program_lut_mode)(struct mpc *mpc, 1117 + const enum MCM_LUT_ID id, 1118 + const bool enable, 1119 + const bool lut_bank_a, 1120 + const enum dc_cm_lut_size size, 1121 + const int mpcc_id); 1122 + 1118 1123 1119 1124 /** 1120 - * @mcm: 1121 - * 1122 - * MPC MCM new HW sequential programming functions 1123 - */ 1124 - struct { 1125 - void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id); 1126 - void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id); 1127 - void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id); 1128 - bool (*is_config_supported)(uint32_t width); 1129 - void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, 1130 - bool lut_bank_a, bool enabled, int mpcc_id); 1131 - 1132 - void (*populate_lut)(struct mpc *mpc, const union mcm_lut_params params, 1133 - bool lut_bank_a, int mpcc_id); 1134 - } mcm; 1125 + * @get_lut_mode: 1126 + * 1127 + * Obtains enablement and ram bank status. 1128 + * 1129 + * Parameters: 1130 + * - [in/out] mpc - MPC context. 1131 + * - [in] id 1132 + * - [in] mpcc_id 1133 + * - [out] enable 1134 + * - [out] lut_bank_a 1135 + * 1136 + * Return: 1137 + * 1138 + * void 1139 + */ 1140 + void (*get_lut_mode)(struct mpc *mpc, 1141 + const enum MCM_LUT_ID id, 1142 + const int mpcc_id, 1143 + bool *enable, 1144 + bool *lut_bank_a); 1135 1145 1136 1146 /** 1137 1147 * @rmcm: ··· 1155 1143 void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); 1156 1144 void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, 1157 1145 bool lut_bank_a, bool enabled, int mpcc_id); 1158 - void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_XABLE xable, 1159 - bool lut_bank_a, int mpcc_id); 1160 - void (*program_3dlut_size)(struct mpc *mpc, uint32_t width, int mpcc_id); 1146 + void (*program_lut_mode)(struct mpc *mpc, 1147 + bool enable, 1148 + bool lut_bank_a, 1149 + int mpcc_id); 1150 + void (*program_3dlut_size)(struct mpc *mpc, const enum dc_cm_lut_size size, int mpcc_id); 1161 1151 void (*program_bias_scale)(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id); 1162 1152 void (*program_bit_depth)(struct mpc *mpc, uint16_t bit_depth, int mpcc_id); 1163 1153 bool (*is_config_supported)(uint32_t width);
+1
drivers/gpu/drm/amd/display/dc/inc/resource.h
··· 60 60 int num_hpo_dp_stream_encoder; 61 61 int num_hpo_dp_link_encoder; 62 62 int num_mpc_3dlut; 63 + int num_rmcm; 63 64 }; 64 65 65 66 struct resource_straps {
+1 -3
drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c
··· 118 118 119 119 struct mpcc *mpc1_get_mpcc(struct mpc *mpc, int mpcc_id) 120 120 { 121 - struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); 122 - 123 - ASSERT(mpcc_id < mpc10->num_mpcc); 121 + ASSERT(mpcc_id < TO_DCN10_MPC(mpc)->num_mpcc); 124 122 return &(mpc->mpcc_array[mpcc_id]); 125 123 } 126 124
+100 -77
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c
··· 73 73 } 74 74 } 75 75 76 - static enum dc_lut_mode get3dlut_config( 77 - struct mpc *mpc, 78 - bool *is_17x17x17, 79 - bool *is_12bits_color_channel, 80 - int mpcc_id) 81 - { 82 - uint32_t i_mode, i_enable_10bits, lut_size; 83 - enum dc_lut_mode mode; 84 - struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 85 - 86 - REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], 87 - MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode); 88 - 89 - REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 90 - MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits); 91 - 92 - switch (i_mode) { 93 - case 0: 94 - mode = LUT_BYPASS; 95 - break; 96 - case 1: 97 - mode = LUT_RAM_A; 98 - break; 99 - case 2: 100 - mode = LUT_RAM_B; 101 - break; 102 - default: 103 - mode = LUT_BYPASS; 104 - break; 105 - } 106 - if (i_enable_10bits > 0) 107 - *is_12bits_color_channel = false; 108 - else 109 - *is_12bits_color_channel = true; 110 - 111 - REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size); 112 - 113 - if (lut_size == 0) 114 - *is_17x17x17 = true; 115 - else 116 - *is_17x17x17 = false; 117 - 118 - return mode; 119 - } 120 - 121 - void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id) 76 + void mpc401_populate_lut(struct mpc *mpc, 77 + const enum MCM_LUT_ID id, 78 + const union mcm_lut_params *params, 79 + const bool lut_bank_a, 80 + const int mpcc_id) 122 81 { 123 82 const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B; 124 - const struct pwl_params *lut1d = params.pwl; 125 - const struct pwl_params *lut_shaper = params.pwl; 83 + const struct pwl_params *lut1d = params->pwl; 84 + const struct pwl_params *lut_shaper = params->pwl; 126 85 bool is_17x17x17; 127 86 bool is_12bits_color_channel; 128 87 const struct dc_rgb *lut0; ··· 90 131 const struct dc_rgb *lut3; 91 132 int lut_size0; 92 133 int lut_size; 93 - const struct tetrahedral_params *lut3d = params.lut3d; 134 + const struct tetrahedral_params *lut3d = params->lut3d; 94 135 95 136 switch (id) { 96 137 case MCM_LUT_1DLUT: ··· 133 174 134 175 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); 135 176 136 - get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id); 137 - 138 177 is_17x17x17 = !lut3d->use_tetrahedral_9; 139 178 is_12bits_color_channel = lut3d->use_12bits; 140 179 if (is_17x17x17) { ··· 155 198 sizeof(lut3d->tetrahedral_9.lut1[0]); 156 199 } 157 200 158 - mpc32_select_3dlut_ram(mpc, next_mode, 159 - is_12bits_color_channel, mpcc_id); 160 201 mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id); 161 202 if (is_12bits_color_channel) 162 203 mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id); ··· 187 232 188 233 } 189 234 235 + static uint32_t mpc401_cm_lut_size_to_3dlut_size(const enum dc_cm_lut_size cm_size) 236 + { 237 + uint32_t size = 0; 238 + 239 + switch (cm_size) { 240 + case CM_LUT_SIZE_999: 241 + size = 1; 242 + break; 243 + case CM_LUT_SIZE_171717: 244 + size = 0; 245 + break; 246 + default: 247 + /* invalid LUT size */ 248 + ASSERT(false); 249 + size = 0; 250 + break; 251 + } 252 + 253 + return size; 254 + } 255 + 190 256 void mpc401_program_lut_mode( 191 257 struct mpc *mpc, 192 258 const enum MCM_LUT_ID id, 193 - const enum MCM_LUT_XABLE xable, 194 - bool lut_bank_a, 195 - int mpcc_id) 259 + const bool enable, 260 + const bool lut_bank_a, 261 + const enum dc_cm_lut_size size, 262 + const int mpcc_id) 196 263 { 264 + uint32_t lut_size; 197 265 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 198 266 199 267 switch (id) { 200 268 case MCM_LUT_3DLUT: 201 - switch (xable) { 202 - case MCM_LUT_DISABLE: 269 + if (enable) { 270 + lut_size = mpc401_cm_lut_size_to_3dlut_size(size); 271 + REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id], 272 + MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2, 273 + MPCC_MCM_3DLUT_SIZE, lut_size); 274 + } else { 275 + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 276 + mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false); 203 277 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0); 204 - break; 205 - case MCM_LUT_ENABLE: 206 - REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2); 207 - break; 208 278 } 209 279 break; 210 280 case MCM_LUT_SHAPER: 211 - switch (xable) { 212 - case MCM_LUT_DISABLE: 213 - REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0); 214 - break; 215 - case MCM_LUT_ENABLE: 281 + if (enable) { 216 282 REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2); 217 - break; 283 + } else { 284 + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 285 + mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false); 286 + REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0); 218 287 } 219 288 break; 220 289 case MCM_LUT_1DLUT: 221 - switch (xable) { 222 - case MCM_LUT_DISABLE: 223 - REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 224 - MPCC_MCM_1DLUT_MODE, 0); 225 - break; 226 - case MCM_LUT_ENABLE: 290 + if (enable) { 227 291 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 228 292 MPCC_MCM_1DLUT_MODE, 2); 229 - break; 293 + } else { 294 + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 295 + mpc32_power_on_blnd_lut(mpc, mpcc_id, false); 296 + REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 297 + MPCC_MCM_1DLUT_MODE, 0); 230 298 } 231 299 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 232 300 MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1); ··· 257 279 } 258 280 } 259 281 260 - void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id) 282 + void mpc401_program_lut_read_write_control(struct mpc *mpc, 283 + const enum MCM_LUT_ID id, 284 + const bool lut_bank_a, 285 + const unsigned int bit_depth, 286 + const int mpcc_id) 261 287 { 262 288 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 263 289 264 290 switch (id) { 265 291 case MCM_LUT_3DLUT: 266 292 mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id); 267 - REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1); 293 + REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 294 + MPCC_MCM_3DLUT_30BIT_EN, (bit_depth == 10) ? 1 : 0, 295 + MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1); 268 296 break; 269 297 case MCM_LUT_SHAPER: 270 298 mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id); ··· 562 578 arr_reg_val, ARRAY_SIZE(arr_reg_val)); 563 579 } 564 580 581 + void mpc401_get_lut_mode(struct mpc *mpc, 582 + const enum MCM_LUT_ID id, 583 + const int mpcc_id, 584 + bool *enable, 585 + bool *lut_bank_a) 586 + { 587 + struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 588 + 589 + uint32_t lut_mode = 0; 590 + uint32_t lut_select = 0; 591 + 592 + *enable = false; 593 + *lut_bank_a = true; 594 + 595 + switch (id) { 596 + case MCM_LUT_SHAPER: 597 + REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 598 + MPCC_MCM_SHAPER_MODE_CURRENT, &lut_mode); 599 + *enable = lut_mode != 0; 600 + *lut_bank_a = lut_mode != 2; 601 + break; 602 + case MCM_LUT_1DLUT: 603 + REG_GET_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 604 + MPCC_MCM_1DLUT_MODE_CURRENT, &lut_mode, 605 + MPCC_MCM_1DLUT_SELECT_CURRENT, &lut_select); 606 + *enable = lut_mode != 0; 607 + *lut_bank_a = lut_mode == 0 || lut_select == 0; 608 + break; 609 + case MCM_LUT_3DLUT: 610 + default: 611 + REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], 612 + MPCC_MCM_3DLUT_MODE_CURRENT, &lut_mode); 613 + *enable = lut_mode != 0; 614 + *lut_bank_a = lut_mode != 2; 615 + break; 616 + } 617 + } 618 + 565 619 static const struct mpc_funcs dcn401_mpc_funcs = { 566 620 .read_mpcc_state = mpc1_read_mpcc_state, 567 621 .insert_plane = mpc1_insert_plane, ··· 638 616 .populate_lut = mpc401_populate_lut, 639 617 .program_lut_read_write_control = mpc401_program_lut_read_write_control, 640 618 .program_lut_mode = mpc401_program_lut_mode, 619 + .get_lut_mode = mpc401_get_lut_mode, 641 620 }; 642 621 643 622
+18 -7
drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h
··· 206 206 int num_rmu); 207 207 208 208 void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id); 209 - void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, 210 - bool lut_bank_a, int mpcc_id); 209 + void mpc401_populate_lut(struct mpc *mpc, 210 + const enum MCM_LUT_ID id, 211 + const union mcm_lut_params *params, 212 + bool lut_bank_a, 213 + int mpcc_id); 211 214 212 215 void mpc401_program_lut_mode( 213 216 struct mpc *mpc, 214 217 const enum MCM_LUT_ID id, 215 - const enum MCM_LUT_XABLE xable, 216 - bool lut_bank_a, 217 - int mpcc_id); 218 + const bool enable, 219 + const bool lut_bank_a, 220 + const enum dc_cm_lut_size size, 221 + const int mpcc_id); 222 + 223 + void mpc401_get_lut_mode(struct mpc *mpc, 224 + const enum MCM_LUT_ID id, 225 + const int mpcc_id, 226 + bool *enable, 227 + bool *lut_bank_a); 218 228 219 229 void mpc401_program_lut_read_write_control( 220 230 struct mpc *mpc, 221 231 const enum MCM_LUT_ID id, 222 - bool lut_bank_a, 223 - int mpcc_id); 232 + const bool lut_bank_a, 233 + const unsigned int bit_depth, 234 + const int mpcc_id); 224 235 225 236 void mpc401_set_gamut_remap( 226 237 struct mpc *mpc,
+35 -359
drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.c
··· 20 20 mpc42->mpc_shift->field_name, mpc42->mpc_mask->field_name 21 21 22 22 23 - static void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst) 23 + void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst) 24 24 { 25 25 mpcc->mpcc_id = mpcc_inst; 26 26 mpcc->dpp_id = 0xf; ··· 61 61 REG_SET(MPCC_BOT_GAIN_OUTSIDE[mpcc_id], 0, MPCC_BOT_GAIN_OUTSIDE, blnd_cfg->bottom_outside_gain); 62 62 63 63 mpcc->blnd_cfg = *blnd_cfg; 64 - } 65 - 66 - /* Shaper functions */ 67 - void mpc42_power_on_shaper_3dlut( 68 - struct mpc *mpc, 69 - uint32_t mpcc_id, 70 - bool power_on) 71 - { 72 - uint32_t power_status_shaper = 2; 73 - uint32_t power_status_3dlut = 2; 74 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 75 - int max_retries = 10; 76 - 77 - REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0, 78 - MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0); 79 - REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0, 80 - MPCC_MCM_SHAPER_MEM_PWR_DIS, power_on == true ? 1:0); 81 - /* wait for memory to fully power up */ 82 - if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 83 - REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); 84 - REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); 85 - } 86 - 87 - /*read status is not mandatory, it is just for debugging*/ 88 - REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper); 89 - REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut); 90 - 91 - if (power_status_shaper != 0 && power_on == true) 92 - BREAK_TO_DEBUGGER(); 93 - 94 - if (power_status_3dlut != 0 && power_on == true) 95 - BREAK_TO_DEBUGGER(); 96 - } 97 - 98 - void mpc42_configure_shaper_lut( 99 - struct mpc *mpc, 100 - bool is_ram_a, 101 - uint32_t mpcc_id) 102 - { 103 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 104 - 105 - REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id], 106 - MPCC_MCM_SHAPER_SCALE_B, 0x7000); 107 - REG_UPDATE(MPCC_MCM_SHAPER_SCALE_G_B[mpcc_id], 108 - MPCC_MCM_SHAPER_SCALE_G, 0x7000); 109 - REG_UPDATE(MPCC_MCM_SHAPER_SCALE_R[mpcc_id], 110 - MPCC_MCM_SHAPER_SCALE_R, 0x7000); 111 - REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id], 112 - MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7); 113 - REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id], 114 - MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 115 - REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0); 116 - } 117 - 118 - 119 - void mpc42_program_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id) 120 - { 121 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 122 - uint32_t size = 0xff; 123 - 124 - REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size); 125 - 126 - REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, 127 - (width == 33) ? 2 : 128 - (width == 17) ? 0 : 2); 129 - 130 - REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &size); 131 - } 132 - 133 - void mpc42_program_3dlut_fl_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id) 134 - { 135 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 136 - 137 - REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_R[mpcc_id], 138 - MPCC_MCM_3DLUT_OUT_OFFSET_R, bias, 139 - MPCC_MCM_3DLUT_OUT_SCALE_R, scale); 140 - 141 - REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_G[mpcc_id], 142 - MPCC_MCM_3DLUT_OUT_OFFSET_G, bias, 143 - MPCC_MCM_3DLUT_OUT_SCALE_G, scale); 144 - 145 - REG_UPDATE_2(MPCC_MCM_3DLUT_OUT_OFFSET_B[mpcc_id], 146 - MPCC_MCM_3DLUT_OUT_OFFSET_B, bias, 147 - MPCC_MCM_3DLUT_OUT_SCALE_B, scale); 148 - } 149 - 150 - void mpc42_program_bit_depth(struct mpc *mpc, uint16_t bit_depth, int mpcc_id) 151 - { 152 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 153 - 154 - REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK, 0xF); 155 - 156 - //program bit_depth 157 - REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 158 - MPCC_MCM_3DLUT_30BIT_EN, 159 - (bit_depth == 10) ? 1 : 0); 160 - } 161 - 162 - bool mpc42_is_config_supported(uint32_t width) 163 - { 164 - if (width == 17) 165 - return true; 166 - 167 - return false; 168 - } 169 - 170 - void mpc42_populate_lut(struct mpc *mpc, const union mcm_lut_params params, 171 - bool lut_bank_a, int mpcc_id) 172 - { 173 - const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B; 174 - const struct pwl_params *lut_shaper = params.pwl; 175 - 176 - if (lut_shaper == NULL) 177 - return; 178 - if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 179 - mpc42_power_on_shaper_3dlut(mpc, mpcc_id, true); 180 - 181 - mpc42_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id); 182 - 183 - if (next_mode == LUT_RAM_A) 184 - mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id); 185 - else 186 - mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id); 187 - 188 - mpc32_program_shaper_lut( 189 - mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id); 190 - 191 - mpc42_power_on_shaper_3dlut(mpc, mpcc_id, false); 192 - } 193 - 194 - void mpc42_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, 195 - bool lut_bank_a, bool enabled, int mpcc_id) 196 - { 197 - struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 198 - 199 - switch (id) { 200 - case MCM_LUT_3DLUT: 201 - REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 202 - (!enabled) ? 0 : 203 - (lut_bank_a) ? 1 : 2); 204 - REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1); 205 - break; 206 - case MCM_LUT_SHAPER: 207 - mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id); 208 - break; 209 - default: 210 - break; 211 - } 212 64 } 213 65 214 66 /* RMCM Shaper functions */ ··· 526 674 } 527 675 } 528 676 529 - void mpc42_program_lut_mode(struct mpc *mpc, const enum MCM_LUT_XABLE xable, 530 - bool lut_bank_a, int mpcc_id) 677 + void mpc42_program_lut_mode(struct mpc *mpc, 678 + bool enable, 679 + bool lut_bank_a, 680 + int mpcc_id) 531 681 { 532 682 struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 533 683 534 - switch (xable) { 535 - case MCM_LUT_DISABLE: 536 - REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, 0); 537 - break; 538 - case MCM_LUT_ENABLE: 684 + if (enable) { 539 685 REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2); 540 - break; 686 + } else { 687 + REG_UPDATE(MPC_RMCM_SHAPER_CONTROL[mpcc_id], MPC_RMCM_SHAPER_LUT_MODE, 0); 541 688 } 542 689 } 543 690 544 - void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, uint32_t width, int mpcc_id) 691 + static uint32_t mpc42_get_rmcm_3dlut_width( 692 + const enum dc_cm_lut_size size) 693 + { 694 + uint32_t width = 0; 695 + 696 + switch (size) { 697 + case CM_LUT_SIZE_333333: 698 + width = 2; 699 + break; 700 + case CM_LUT_SIZE_171717: 701 + default: 702 + width = 0; 703 + break; 704 + } 705 + 706 + return width; 707 + } 708 + 709 + void mpc42_program_rmcm_3dlut_size(struct mpc *mpc, 710 + const enum dc_cm_lut_size size, 711 + int mpcc_id) 545 712 { 546 713 struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 547 - uint32_t size = 0xff; 714 + uint32_t width = mpc42_get_rmcm_3dlut_width(size); 548 715 549 - REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size); 550 - 551 - REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, 552 - (width == 33) ? 2 : 0); 553 - 554 - REG_GET(MPC_RMCM_3DLUT_MODE[mpcc_id], MPC_RMCM_3DLUT_SIZE, &size); 716 + REG_UPDATE(MPC_RMCM_3DLUT_MODE[mpcc_id], 717 + MPC_RMCM_3DLUT_SIZE, width); 555 718 } 556 719 557 720 void mpc42_program_rmcm_3dlut_fast_load_bias_scale(struct mpc *mpc, uint16_t bias, uint16_t scale, int mpcc_id) ··· 598 731 (bit_depth == 10) ? 1 : 0); 599 732 } 600 733 601 - bool mpc42_is_rmcm_config_supported(uint32_t width) 602 - { 603 - if (width == 17 || width == 33) 604 - return true; 605 - 606 - return false; 607 - } 608 - 609 734 void mpc42_set_fl_config( 610 735 struct mpc *mpc, 611 736 struct mpc_fl_3dlut_config *cfg, ··· 605 746 { 606 747 struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 607 748 749 + uint32_t width = mpc42_get_rmcm_3dlut_width(cfg->size); 608 750 /* 609 751 From: Jie Zhou 610 752 ··· 646 786 647 787 //width 648 788 REG_UPDATE_2(MPC_RMCM_3DLUT_MODE[mpcc_id], 649 - MPC_RMCM_3DLUT_SIZE, (cfg->width == 33) ? 2 : 0, 789 + MPC_RMCM_3DLUT_SIZE, width, 650 790 MPC_RMCM_3DLUT_MODE, (!cfg->enabled) ? 0 : (cfg->select_lut_bank_a) ? 1 : 2); 651 791 652 792 //connect to hubp ··· 658 798 //in future we'll select specific MPC 659 799 REG_UPDATE(MPC_RMCM_CNTL[mpcc_id], MPC_RMCM_CNTL, cfg->enabled ? 0 : 0xF); 660 800 } 661 - 662 - //static void rmcm_program_gamut_remap( 663 - // struct mpc *mpc, 664 - // unsigned int mpcc_id, 665 - // const uint16_t *regval, 666 - // enum mpcc_gamut_remap_id gamut_remap_block_id, 667 - // enum mpcc_gamut_remap_mode_select mode_select) 668 - //{ 669 - // struct color_matrices_reg gamut_regs; 670 - // struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 671 - // 672 - // if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP || 673 - // gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP || 674 - // gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) { 675 - // mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select); 676 - // return; 677 - // } 678 - // if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP) { 679 - // 680 - // if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 681 - // REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, 682 - // MPC_RMCM_GAMUT_REMAP_MODE, mode_select); 683 - // return; 684 - // } 685 - // 686 - // gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 687 - // gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 688 - // gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 689 - // gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 690 - // 691 - // switch (mode_select) { 692 - // case MPCC_GAMUT_REMAP_MODE_SELECT_1: 693 - // gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]); 694 - // gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]); 695 - // break; 696 - // case MPCC_GAMUT_REMAP_MODE_SELECT_2: 697 - // gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]); 698 - // gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]); 699 - // break; 700 - // default: 701 - // break; 702 - // } 703 - // 704 - // cm_helper_program_color_matrices( 705 - // mpc->ctx, 706 - // regval, 707 - // &gamut_regs); 708 - // 709 - // //select coefficient set to use, set A (MODE_1) or set B (MODE_2) 710 - // REG_SET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 0, MPC_RMCM_GAMUT_REMAP_MODE, mode_select); 711 - // } 712 - //} 713 - 714 - //static bool is_mpc_legacy_gamut_id(enum mpcc_gamut_remap_id gamut_remap_block_id) 715 - //{ 716 - // if (gamut_remap_block_id == MPCC_OGAM_GAMUT_REMAP || 717 - // gamut_remap_block_id == MPCC_MCM_FIRST_GAMUT_REMAP || 718 - // gamut_remap_block_id == MPCC_MCM_SECOND_GAMUT_REMAP) { 719 - // return true; 720 - // } 721 - // return false; 722 - //} 723 - //static void program_gamut_remap( 724 - // struct mpc *mpc, 725 - // unsigned int mpcc_id, 726 - // const uint16_t *regval, 727 - // enum mpcc_gamut_remap_id gamut_remap_block_id, 728 - // enum mpcc_gamut_remap_mode_select mode_select) 729 - //{ 730 - // if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) 731 - // mpc_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select); 732 - // else 733 - // rmcm_program_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select); 734 - //} 735 - 736 - //void mpc42_set_gamut_remap( 737 - // struct mpc *mpc, 738 - // int mpcc_id, 739 - // const struct mpc_grph_gamut_adjustment *adjust) 740 - //{ 741 - // struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 742 - // unsigned int i = 0; 743 - // uint32_t mode_select = 0; 744 - // 745 - // if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) { 746 - // /* Bypass / Disable if type is bypass or hw */ 747 - // program_gamut_remap(mpc, mpcc_id, NULL, 748 - // adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0); 749 - // } else { 750 - // struct fixed31_32 arr_matrix[12]; 751 - // uint16_t arr_reg_val[12]; 752 - // 753 - // for (i = 0; i < 12; i++) 754 - // arr_matrix[i] = adjust->temperature_matrix[i]; 755 - // 756 - // convert_float_matrix(arr_reg_val, arr_matrix, 12); 757 - // 758 - // if (is_mpc_legacy_gamut_id(adjust->mpcc_gamut_remap_block_id)) 759 - // REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 760 - // MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select); 761 - // else 762 - // REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], 763 - // MPC_RMCM_GAMUT_REMAP_MODE_CURRENT, &mode_select); 764 - // 765 - // //If current set in use not set A (MODE_1), then use set A, otherwise use set B 766 - // if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1) 767 - // mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1; 768 - // else 769 - // mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2; 770 - // 771 - // program_gamut_remap(mpc, mpcc_id, arr_reg_val, 772 - // adjust->mpcc_gamut_remap_block_id, mode_select); 773 - // } 774 - //} 775 - 776 - //static void read_gamut_remap(struct mpc *mpc, 777 - // int mpcc_id, 778 - // uint16_t *regval, 779 - // enum mpcc_gamut_remap_id gamut_remap_block_id, 780 - // uint32_t *mode_select) 781 - //{ 782 - // struct color_matrices_reg gamut_regs = {0}; 783 - // struct dcn42_mpc *mpc42 = TO_DCN42_MPC(mpc); 784 - // 785 - // if (is_mpc_legacy_gamut_id(gamut_remap_block_id)) { 786 - // mpc_read_gamut_remap(mpc, mpcc_id, regval, gamut_remap_block_id, mode_select); 787 - // } 788 - // if (gamut_remap_block_id == MPCC_RMCM_GAMUT_REMAP) { 789 - // //current coefficient set in use 790 - // REG_GET(MPC_RMCM_GAMUT_REMAP_MODE[mpcc_id], MPC_RMCM_GAMUT_REMAP_MODE, mode_select); 791 - // 792 - // gamut_regs.shifts.csc_c11 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 793 - // gamut_regs.masks.csc_c11 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 794 - // gamut_regs.shifts.csc_c12 = mpc42->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 795 - // gamut_regs.masks.csc_c12 = mpc42->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 796 - // 797 - // switch (*mode_select) { 798 - // case MPCC_GAMUT_REMAP_MODE_SELECT_1: 799 - // gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_A[mpcc_id]); 800 - // gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_A[mpcc_id]); 801 - // break; 802 - // case MPCC_GAMUT_REMAP_MODE_SELECT_2: 803 - // gamut_regs.csc_c11_c12 = REG(MPC_RMCM_GAMUT_REMAP_C11_C12_B[mpcc_id]); 804 - // gamut_regs.csc_c33_c34 = REG(MPC_RMCM_GAMUT_REMAP_C33_C34_B[mpcc_id]); 805 - // break; 806 - // default: 807 - // break; 808 - // } 809 - // } 810 - // 811 - // if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) { 812 - // cm_helper_read_color_matrices( 813 - // mpc42->base.ctx, 814 - // regval, 815 - // &gamut_regs); 816 - // } 817 - //} 818 - 819 - //void mpc42_get_gamut_remap(struct mpc *mpc, 820 - // int mpcc_id, 821 - // struct mpc_grph_gamut_adjustment *adjust) 822 - //{ 823 - // uint16_t arr_reg_val[12] = {0}; 824 - // uint32_t mode_select; 825 - // 826 - // read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select); 827 - // 828 - // if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 829 - // adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 830 - // return; 831 - // } 832 - // 833 - // adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 834 - // convert_hw_matrix(adjust->temperature_matrix, 835 - // arr_reg_val, ARRAY_SIZE(arr_reg_val)); 836 - //} 837 801 838 802 void mpc42_read_mpcc_state( 839 803 struct mpc *mpc, ··· 755 1071 .populate_lut = mpc401_populate_lut, 756 1072 .program_lut_read_write_control = mpc401_program_lut_read_write_control, 757 1073 .program_lut_mode = mpc401_program_lut_mode, 758 - .mcm = { 759 - .program_lut_read_write_control = mpc42_program_lut_read_write_control, 760 - .program_3dlut_size = mpc42_program_3dlut_size, 761 - .program_bias_scale = mpc42_program_3dlut_fl_bias_scale, 762 - .program_bit_depth = mpc42_program_bit_depth, 763 - .is_config_supported = mpc42_is_config_supported, 764 - .populate_lut = mpc42_populate_lut, 765 - }, 1074 + .get_lut_mode = mpc401_get_lut_mode, 766 1075 .rmcm = { 767 1076 .enable_3dlut_fl = mpc42_enable_3dlut_fl, 768 1077 .update_3dlut_fast_load_select = mpc42_update_3dlut_fast_load_select, ··· 764 1087 .program_3dlut_size = mpc42_program_rmcm_3dlut_size, 765 1088 .program_bias_scale = mpc42_program_rmcm_3dlut_fast_load_bias_scale, 766 1089 .program_bit_depth = mpc42_program_rmcm_bit_depth, 767 - .is_config_supported = mpc42_is_rmcm_config_supported, 768 1090 .power_on_shaper_3dlut = mpc42_power_on_rmcm_shaper_3dlut, 769 1091 .populate_lut = mpc42_populate_rmcm_lut, 770 1092 .fl_3dlut_configure = mpc42_set_fl_config,
+3 -47
drivers/gpu/drm/amd/display/dc/mpc/dcn42/dcn42_mpc.h
··· 882 882 int num_mpcc, 883 883 int num_rmu); 884 884 885 - 886 - void mpc42_program_shaper_lutb_settings( 887 - struct mpc *mpc, 888 - const struct pwl_params *params, 889 - uint32_t mpcc_id); 890 - void mpc42_program_shaper_luta_settings( 891 - struct mpc *mpc, 892 - const struct pwl_params *params, 893 - uint32_t mpcc_id); 894 - void mpc42_configure_shaper_lut( 895 - struct mpc *mpc, 896 - bool is_ram_a, 897 - uint32_t mpcc_id); 898 - void mpc42_power_on_shaper_3dlut( 899 - struct mpc *mpc, 900 - uint32_t mpcc_id, 901 - bool power_on); 902 - void mpc42_program_3dlut_size( 903 - struct mpc *mpc, 904 - uint32_t width, 905 - int mpcc_id); 906 - void mpc42_program_3dlut_fl_bias_scale( 907 - struct mpc *mpc, 908 - uint16_t bias, 909 - uint16_t scale, 910 - int mpcc_id); 911 - void mpc42_program_bit_depth( 912 - struct mpc *mpc, 913 - uint16_t bit_depth, 914 - int mpcc_id); 915 - void mpc42_populate_lut( 916 - struct mpc *mpc, 917 - const union mcm_lut_params params, 918 - bool lut_bank_a, 919 - int mpcc_id); 920 - void mpc42_program_lut_read_write_control( 921 - struct mpc *mpc, 922 - const enum MCM_LUT_ID id, 923 - bool lut_bank_a, 924 - bool enabled, 925 - int mpcc_id); 926 - 927 - bool mpc42_is_config_supported(uint32_t width); 885 + void mpc42_init_mpcc(struct mpcc *mpcc, int mpcc_inst); 928 886 929 887 /* RMCM */ 930 888 void mpc42_program_rmcm_shaper_lut( ··· 927 969 int mpcc_id); 928 970 void mpc42_program_lut_mode( 929 971 struct mpc *mpc, 930 - const enum MCM_LUT_XABLE xable, 972 + bool enable, 931 973 bool lut_bank_a, 932 974 int mpcc_id); 933 975 void mpc42_program_rmcm_3dlut_size( 934 976 struct mpc *mpc, 935 - uint32_t width, 977 + const enum dc_cm_lut_size size, 936 978 int mpcc_id); 937 979 void mpc42_program_rmcm_3dlut_fast_load_bias_scale( 938 980 struct mpc *mpc, ··· 943 985 struct mpc *mpc, 944 986 uint16_t bit_depth, 945 987 int mpcc_id); 946 - 947 - bool mpc42_is_rmcm_config_supported(uint32_t width); 948 988 949 989 void mpc42_set_fl_config( 950 990 struct mpc *mpc,
+6 -2
drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
··· 218 218 uint32_t OTG_CRC_SIG_BLUE_CONTROL_MASK; \ 219 219 uint32_t OTG_CRC_SIG_RED_GREEN_MASK; \ 220 220 uint32_t OTG_DLPC_CONTROL; \ 221 - uint32_t OTG_DRR_CONTROL2; \ 221 + uint32_t OTG_DRR_CONTOL2; \ 222 222 uint32_t OTG_DRR_TIMING_INT_STATUS; \ 223 223 uint32_t OTG_GLOBAL_CONTROL3; \ 224 224 uint32_t OTG_GLOBAL_SYNC_STATUS; \ ··· 676 676 type OTG_V_COUNT_STOP_TIMER; 677 677 678 678 #define TG_REG_FIELD_LIST_DCN3_6(type) \ 679 + type OPTC_RSMU_UNDERFLOW_CLEAR;\ 680 + type OPTC_RSMU_UNDERFLOW_OCCURRED_STATUS;\ 681 + type OPTC_RSMU_UNDERFLOW_INT_EN;\ 682 + type OPTC_RSMU_UNDERFLOW_INT_STATUS;\ 679 683 type OTG_CRC_POLY_SEL; \ 680 684 type CRC0_R_CR32; \ 681 685 type CRC0_G_Y32; \ ··· 707 703 TG_REG_FIELD_LIST_DCN3_5(uint8_t) 708 704 TG_REG_FIELD_LIST_DCN3_6(uint8_t) 709 705 TG_REG_FIELD_LIST_DCN401(uint8_t) 710 - TG_REG_FIELD_LIST_DCN42(uint8_t) 706 + TG_REG_FIELD_LIST_DCN42(uint8_t) 711 707 }; 712 708 713 709 struct dcn_optc_mask {
+1 -1
drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
··· 363 363 optc_reg_state->otg_crc3_data_rg = REG_READ(OTG_CRC3_DATA_RG); 364 364 optc_reg_state->otg_dlpc_control = REG_READ(OTG_DLPC_CONTROL); 365 365 optc_reg_state->otg_double_buffer_control = REG_READ(OTG_DOUBLE_BUFFER_CONTROL); 366 - optc_reg_state->otg_drr_control2 = REG_READ(OTG_DRR_CONTROL2); 366 + optc_reg_state->otg_drr_control2 = REG_READ(OTG_DRR_CONTOL2); 367 367 optc_reg_state->otg_drr_control = REG_READ(OTG_DRR_CONTROL); 368 368 optc_reg_state->otg_drr_timing_int_status = REG_READ(OTG_DRR_TIMING_INT_STATUS); 369 369 optc_reg_state->otg_drr_trigger_window = REG_READ(OTG_DRR_TRIGGER_WINDOW);
+99 -6
drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c
··· 6 6 #include "dcn30/dcn30_optc.h" 7 7 #include "dcn31/dcn31_optc.h" 8 8 #include "dcn32/dcn32_optc.h" 9 + #include "dcn35/dcn35_optc.h" 9 10 #include "dcn401/dcn401_optc.h" 10 11 #include "reg_helper.h" 11 12 #include "dc.h" 12 13 #include "dcn_calc_math.h" 13 14 #include "dc_dmub_srv.h" 15 + #include "dc_trace.h" 14 16 15 17 #define REG(reg)\ 16 18 optc1->tg_regs->reg ··· 110 108 REG_UPDATE(OTG_PWA_FRAME_SYNC_CONTROL, 111 109 OTG_PWA_FRAME_SYNC_EN, 0); 112 110 } 111 + void optc42_clear_optc_underflow(struct timing_generator *optc) 112 + { 113 + struct optc *optc1 = DCN10TG_FROM_TG(optc); 114 + 115 + REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1); 116 + REG_UPDATE(OPTC_RSMU_UNDERFLOW, OPTC_RSMU_UNDERFLOW_CLEAR, 1); 117 + } 118 + bool optc42_is_optc_underflow_occurred(struct timing_generator *optc) 119 + { 120 + struct optc *optc1 = DCN10TG_FROM_TG(optc); 121 + uint32_t underflow_occurred = 0, rsmu_underflow_occurred = 0; 122 + 123 + REG_GET(OPTC_INPUT_GLOBAL_CONTROL, 124 + OPTC_UNDERFLOW_OCCURRED_STATUS, 125 + &underflow_occurred); 126 + 127 + REG_GET(OPTC_RSMU_UNDERFLOW, 128 + OPTC_RSMU_UNDERFLOW_OCCURRED_STATUS, 129 + &rsmu_underflow_occurred); 130 + return (underflow_occurred == 1 || rsmu_underflow_occurred); 131 + } 132 + /* disable_crtc */ 133 + bool optc42_disable_crtc(struct timing_generator *optc) 134 + { 135 + optc401_disable_crtc(optc); 136 + optc42_clear_optc_underflow(optc); 137 + 138 + return true; 139 + } 140 + static void optc42_set_timing_double_buffer(struct timing_generator *optc, bool enable) 141 + { 142 + struct optc *optc1 = DCN10TG_FROM_TG(optc); 143 + uint32_t mode = enable ? 2 : 0; 144 + /* actually we have 4 modes now, use as the same as previous dcn3x 145 + * 00 OTG_DOUBLE_BUFFER_CONTROL_OTG_DRR_TIMING_DBUF_UPDATE_MODE_0 Double buffer update occurs at any time in a frame. 146 + * 01 OTG_DOUBLE_BUFFER_CONTROL_OTG_DRR_TIMING_DBUF_UPDATE_MODE_1 Double buffer update occurs at OTG start of frame. 147 + * 02 OTG_DOUBLE_BUFFER_CONTROL_OTG_DRR_TIMING_DBUF_UPDATE_MODE_2 Double buffer occurs DP start of frame. 148 + * 03 OTG_DOUBLE_BUFFER_CONTROL_OTG_DRR_TIMING_DBUF_UPDATE_MODE_3 Reserved. 149 + */ 150 + 151 + REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL, 152 + OTG_DRR_TIMING_DBUF_UPDATE_MODE, mode); 153 + } 154 + void optc42_tg_init(struct timing_generator *optc) 155 + { 156 + optc42_set_timing_double_buffer(optc, true); 157 + optc42_clear_optc_underflow(optc); 158 + } 159 + 160 + void optc42_lock_doublebuffer_enable(struct timing_generator *optc) 161 + { 162 + struct optc *optc1 = DCN10TG_FROM_TG(optc); 163 + uint32_t v_blank_start = 0; 164 + uint32_t v_blank_end = 0; 165 + uint32_t h_blank_start = 0; 166 + uint32_t h_blank_end = 0; 167 + 168 + REG_GET_2(OTG_V_BLANK_START_END, 169 + OTG_V_BLANK_START, &v_blank_start, 170 + OTG_V_BLANK_END, &v_blank_end); 171 + REG_GET_2(OTG_H_BLANK_START_END, 172 + OTG_H_BLANK_START, &h_blank_start, 173 + OTG_H_BLANK_END, &h_blank_end); 174 + 175 + REG_UPDATE_2(OTG_GLOBAL_CONTROL1, 176 + MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start, 177 + MASTER_UPDATE_LOCK_DB_END_Y, v_blank_start); 178 + REG_UPDATE_2(OTG_GLOBAL_CONTROL4, 179 + DIG_UPDATE_POSITION_X, 20, 180 + DIG_UPDATE_POSITION_Y, v_blank_start); 181 + REG_UPDATE_3(OTG_GLOBAL_CONTROL0, 182 + MASTER_UPDATE_LOCK_DB_START_X, h_blank_start - 200 - 1, 183 + MASTER_UPDATE_LOCK_DB_END_X, h_blank_end, 184 + MASTER_UPDATE_LOCK_DB_EN, 1); 185 + REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1); 186 + 187 + REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, 188 + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0, 189 + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100, 190 + OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1); 191 + 192 + TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true); 193 + } 113 194 114 195 static struct timing_generator_funcs dcn42_tg_funcs = { 115 196 .validate_timing = optc1_validate_timing, ··· 202 117 .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, 203 118 .program_global_sync = optc401_program_global_sync, 204 119 .enable_crtc = optc401_enable_crtc, 205 - .disable_crtc = optc401_disable_crtc, 120 + .disable_crtc = optc42_disable_crtc, 206 121 .phantom_crtc_post_enable = optc401_phantom_crtc_post_enable, 207 122 .disable_phantom_crtc = optc401_disable_phantom_otg, 208 123 /* used by enable_timing_synchronization. Not need for FPGA */ ··· 223 138 .disable_reset_trigger = optc1_disable_reset_trigger, 224 139 .lock = optc3_lock, 225 140 .unlock = optc1_unlock, 226 - .lock_doublebuffer_enable = optc3_lock_doublebuffer_enable, 141 + .lock_doublebuffer_enable = optc42_lock_doublebuffer_enable, 227 142 .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable, 228 143 .enable_optc_clock = optc1_enable_optc_clock, 229 144 .set_drr = optc401_set_drr, ··· 232 147 .set_static_screen_control = optc1_set_static_screen_control, 233 148 .program_stereo = optc1_program_stereo, 234 149 .is_stereo_left_eye = optc1_is_stereo_left_eye, 235 - .tg_init = optc3_tg_init, 150 + .tg_init = optc42_tg_init, 236 151 .is_tg_enabled = optc1_is_tg_enabled, 237 - .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, 238 - .clear_optc_underflow = optc1_clear_optc_underflow, 152 + .is_optc_underflow_occurred = optc42_is_optc_underflow_occurred, 153 + .clear_optc_underflow = optc42_clear_optc_underflow, 239 154 .setup_global_swap_lock = NULL, 240 155 .get_crc = optc42_get_crc, 241 - .configure_crc = optc1_configure_crc, 156 + .configure_crc = optc35_configure_crc, 242 157 .set_dsc_config = optc3_set_dsc_config, 243 158 .get_dsc_status = optc2_get_dsc_status, 244 159 .set_dwb_source = NULL, ··· 247 162 .wait_odm_doublebuffer_pending_clear = optc32_wait_odm_doublebuffer_pending_clear, 248 163 .set_h_timing_div_manual_mode = optc401_set_h_timing_div_manual_mode, 249 164 .get_optc_source = optc2_get_optc_source, 165 + .wait_otg_disable = optc35_wait_otg_disable, 250 166 .set_out_mux = optc401_set_out_mux, 251 167 .set_drr_trigger_window = optc3_set_drr_trigger_window, 252 168 .set_vtotal_change_limit = optc3_set_vtotal_change_limit, ··· 257 171 .program_manual_trigger = optc2_program_manual_trigger, 258 172 .setup_manual_trigger = optc2_setup_manual_trigger, 259 173 .get_hw_timing = optc1_get_hw_timing, 174 + .init_odm = optc3_init_odm, 175 + .set_long_vtotal = optc35_set_long_vtotal, 260 176 .is_two_pixels_per_container = optc1_is_two_pixels_per_container, 261 177 .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending, 262 178 .get_otg_double_buffer_pending = optc3_get_otg_update_pending, ··· 266 178 .set_vupdate_keepout = optc401_set_vupdate_keepout, 267 179 .wait_update_lock_status = optc401_wait_update_lock_status, 268 180 .optc_read_reg_state = optc31_read_reg_state, 181 + .read_otg_state = optc31_read_otg_state, 269 182 .enable_otg_pwa = optc42_enable_pwa, 270 183 .disable_otg_pwa = optc42_disable_pwa, 271 184 }; ··· 283 194 optc1->min_v_blank_interlace = 5; 284 195 optc1->min_h_sync_width = 4; 285 196 optc1->min_v_sync_width = 1; 197 + optc1->max_frame_count = 0xFFFFFF; 198 + 199 + dcn35_timing_generator_set_fgcg( 200 + optc1, CTX->dc->debug.enable_fine_grain_clock_gating.bits.optc); 286 201 } 287 202
+11 -2
drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h
··· 119 119 SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_OCCURRED_STATUS, mask_sh),\ 120 120 SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_DOUBLE_BUFFER_PENDING, mask_sh),\ 121 121 SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, mask_sh),\ 122 + SF(ODM0_OPTC_RSMU_UNDERFLOW, OPTC_RSMU_UNDERFLOW_OCCURRED_STATUS, mask_sh),\ 123 + SF(ODM0_OPTC_RSMU_UNDERFLOW, OPTC_RSMU_UNDERFLOW_CLEAR, mask_sh),\ 124 + SF(ODM0_OPTC_RSMU_UNDERFLOW, OPTC_RSMU_UNDERFLOW_INT_EN, mask_sh),\ 125 + SF(ODM0_OPTC_RSMU_UNDERFLOW, OPTC_RSMU_UNDERFLOW_INT_STATUS, mask_sh),\ 122 126 SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\ 123 127 SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\ 124 128 SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\ ··· 206 202 SF(OTG0_OTG_PWA_FRAME_SYNC_CONTROL, OTG_PWA_FRAME_SYNC_EN, mask_sh),\ 207 203 SF(OTG0_OTG_PWA_FRAME_SYNC_CONTROL, OTG_PWA_FRAME_SYNC_VCOUNT_MODE, mask_sh),\ 208 204 SF(OTG0_OTG_PWA_FRAME_SYNC_CONTROL, OTG_PWA_FRAME_SYNC_LINE, mask_sh),\ 209 - SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) 205 + SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh),\ 206 + SF(OPTC_CLOCK_CONTROL, OPTC_FGCG_REP_DIS, mask_sh) 210 207 211 208 void dcn42_timing_generator_init(struct optc *optc1); 212 209 void optc42_enable_pwa(struct timing_generator *optc, struct otc_pwa_frame_sync *pwa_sync_param); 213 210 void optc42_disable_pwa(struct timing_generator *optc); 214 - 211 + void optc42_tg_init(struct timing_generator *optc); 212 + void optc42_clear_optc_underflow(struct timing_generator *optc); 213 + bool optc42_is_optc_underflow_occurred(struct timing_generator *optc); 214 + bool optc42_disable_crtc(struct timing_generator *optc); 215 + void optc42_lock_doublebuffer_enable(struct timing_generator *optc); 215 216 #endif /* __DC_OPTC_DCN42_H__ */
-2
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
··· 2341 2341 struct _vcs_dpi_ip_params_st *loaded_ip = 2342 2342 get_asic_rev_ip_params(dc->ctx->asic_id.hw_internal_rev); 2343 2343 2344 - DC_LOGGER_INIT(dc->ctx->logger); 2345 - 2346 2344 if (pool->base.pp_smu) { 2347 2345 struct pp_smu_nv_clock_table max_clocks = {0}; 2348 2346 unsigned int uclk_states[8] = {0};
+5 -5
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
··· 53 53 #include "dce/dce_audio.h" 54 54 #include "dce/dce_hwseq.h" 55 55 #include "clk_mgr.h" 56 - #include "virtual/virtual_stream_encoder.h" 56 + #include "dio/virtual/virtual_stream_encoder.h" 57 57 #include "dml/display_mode_vba.h" 58 58 #include "dcn42/dcn42_dccg.h" 59 59 #include "dcn10/dcn10_resource.h" ··· 666 666 .num_vmid = 16, 667 667 .num_mpc_3dlut = 2, 668 668 .num_dsc = 4, 669 + .num_rmcm = 2, 669 670 }; 670 671 671 672 static const struct dc_plane_cap plane_cap = { ··· 756 755 .dcc_meta_propagation_delay_us = 10, 757 756 .disable_timeout = true, 758 757 .min_disp_clk_khz = 50000, 758 + .static_screen_wait_frames = 2, 759 759 .disable_z10 = false, 760 760 .ignore_pg = true, 761 761 .disable_stutter_for_wm_program = true, ··· 2304 2302 2305 2303 dc->dml2_options.max_segments_per_hubp = 24; 2306 2304 dc->dml2_options.det_segment_size = DCN42_CRB_SEGMENT_SIZE_KB; 2305 + dc->dml2_options.gpuvm_enable = true; 2306 + dc->dml2_options.hostvm_enable = true; 2307 2307 2308 2308 /* SPL */ 2309 2309 dc->caps.scl_caps.sharpener_support = true; 2310 - 2311 - /* init DC limited DML2 options */ 2312 - memcpy(&dc->dml2_dc_power_options, &dc->dml2_options, sizeof(struct dml2_configuration_options)); 2313 - dc->dml2_dc_power_options.use_clock_dc_limits = true; 2314 2310 2315 2311 return true; 2316 2312
+3
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/Makefile
··· 8 8 soc_and_ip_translator_rcflags := $(CC_FLAGS_NO_FPU) 9 9 10 10 CFLAGS_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.o := $(soc_and_ip_translator_ccflags) 11 + CFLAGS_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.o := $(soc_and_ip_translator_ccflags) 11 12 12 13 CFLAGS_REMOVE_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.o := $(soc_and_ip_translator_rcflags) 14 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.o := $(soc_and_ip_translator_rcflags) 13 15 14 16 soc_and_ip_translator := soc_and_ip_translator.o 15 17 soc_and_ip_translator += dcn401/dcn401_soc_and_ip_translator.o 18 + soc_and_ip_translator += dcn42/dcn42_soc_and_ip_translator.o 16 19 17 20 AMD_DAL_soc_and_ip_translator := $(addprefix $(AMDDALPATH)/dc/soc_and_ip_translator/, $(soc_and_ip_translator)) 18 21
+3
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.c
··· 102 102 } 103 103 } else { 104 104 dml_clk_table->uclk.clk_values_khz[i] = dc_clk_table->entries[i].memclk_mhz * 1000; 105 + #ifdef ENABLE_WCK 106 + dml_clk_table->wck_ratio.clk_values_khz[i] = dc_clk_table->entries[i].wck_ratio; 107 + #endif 105 108 } 106 109 } else { 107 110 dml_clk_table->uclk.clk_values_khz[i] = 0;
+161 -2
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
··· 3 3 // Copyright 2025 Advanced Micro Devices, Inc. 4 4 5 5 #include "dcn42_soc_and_ip_translator.h" 6 - #include "soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h" 6 + #include "../dcn401/dcn401_soc_and_ip_translator.h" 7 7 #include "bounding_boxes/dcn42_soc_bb.h" 8 8 9 9 /* soc_and_ip_translator component used to get up-to-date values for bounding box. ··· 11 11 * This component provides an interface to get DCN-specific bounding box values. 12 12 */ 13 13 14 + static void get_default_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc) 15 + { 16 + { 17 + memcpy(soc_bb, &dml2_socbb_dcn42, sizeof(struct dml2_soc_bb)); 18 + memcpy(&soc_bb->qos_parameters, &dml_dcn42_variant_a_soc_qos_params, sizeof(struct dml2_soc_qos_parameters)); 19 + } 20 + } 21 + 22 + /* 23 + * DC clock table is obtained from SMU during runtime. 24 + * SMU stands for System Management Unit. It is a power management processor. 25 + * It owns the initialization of dc's clock table and programming of clock values 26 + * based on dc's requests. 27 + * Our clock values in base soc bb is a dummy placeholder. The real clock values 28 + * are retrieved from SMU firmware to dc clock table at runtime. 29 + * This function overrides our dummy placeholder values with real values in dc 30 + * clock table. 31 + */ 32 + static void dcn42_convert_dc_clock_table_to_soc_bb_clock_table( 33 + struct dml2_soc_state_table *dml_clk_table, 34 + struct dml2_soc_vmin_clock_limits *vmin_limit, 35 + const struct clk_bw_params *dc_bw_params) 36 + { 37 + int i; 38 + const struct clk_limit_table *dc_clk_table; 39 + 40 + if (dc_bw_params == NULL) 41 + /* skip if bw params could not be obtained from smu */ 42 + return; 43 + 44 + dc_clk_table = &dc_bw_params->clk_table; 45 + 46 + /* fclk/dcfclk - dcn42 pmfw table can have 0 entries for inactive dpm levels 47 + * for use with dml we need to fill in using an active value aiming for >= 2x DCFCLK 48 + */ 49 + if (dc_clk_table->num_entries_per_clk.num_fclk_levels && dc_clk_table->num_entries_per_clk.num_dcfclk_levels) { 50 + dml_clk_table->fclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dcfclk_levels; 51 + dml_clk_table->dcfclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dcfclk_levels; 52 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 53 + if (i < dc_clk_table->num_entries_per_clk.num_dcfclk_levels) { 54 + int j, max_fclk = 0; 55 + 56 + dml_clk_table->dcfclk.clk_values_khz[i] = dc_clk_table->entries[i].dcfclk_mhz * 1000; 57 + for (j = 0; j < MAX_NUM_DPM_LVL; j++) { 58 + if (dc_clk_table->entries[j].fclk_mhz * 1000 > max_fclk) 59 + max_fclk = dc_clk_table->entries[j].fclk_mhz * 1000; 60 + dml_clk_table->fclk.clk_values_khz[i] = max_fclk; 61 + if (max_fclk >= 2 * dml_clk_table->dcfclk.clk_values_khz[i]) 62 + break; 63 + } 64 + } else { 65 + dml_clk_table->dcfclk.clk_values_khz[i] = 0; 66 + dml_clk_table->fclk.clk_values_khz[i] = 0; 67 + } 68 + } 69 + } 70 + 71 + /* uclk */ 72 + if (dc_clk_table->num_entries_per_clk.num_memclk_levels) { 73 + dml_clk_table->uclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_memclk_levels; 74 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 75 + if (i < dml_clk_table->uclk.num_clk_values) { 76 + dml_clk_table->uclk.clk_values_khz[i] = dc_clk_table->entries[i].memclk_mhz * 1000; 77 + dml_clk_table->wck_ratio.clk_values_khz[i] = dc_clk_table->entries[i].wck_ratio; 78 + } else { 79 + dml_clk_table->uclk.clk_values_khz[i] = 0; 80 + dml_clk_table->wck_ratio.clk_values_khz[i] = 0; 81 + } 82 + } 83 + } 84 + 85 + /* dispclk */ 86 + if (dc_clk_table->num_entries_per_clk.num_dispclk_levels) { 87 + dml_clk_table->dispclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dispclk_levels; 88 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 89 + if (i < dml_clk_table->dispclk.num_clk_values) { 90 + dml_clk_table->dispclk.clk_values_khz[i] = dc_clk_table->entries[i].dispclk_mhz * 1000; 91 + } else { 92 + dml_clk_table->dispclk.clk_values_khz[i] = 0; 93 + } 94 + } 95 + vmin_limit->dispclk_khz = min(dc_clk_table->entries[0].dispclk_mhz * 1000, vmin_limit->dispclk_khz); 96 + } 97 + 98 + /* dppclk */ 99 + if (dc_clk_table->num_entries_per_clk.num_dppclk_levels) { 100 + dml_clk_table->dppclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dppclk_levels; 101 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 102 + if (i < dml_clk_table->dppclk.num_clk_values) { 103 + dml_clk_table->dppclk.clk_values_khz[i] = dc_clk_table->entries[i].dppclk_mhz * 1000; 104 + } else { 105 + dml_clk_table->dppclk.clk_values_khz[i] = 0; 106 + } 107 + } 108 + } 109 + 110 + /* dtbclk */ 111 + if (dc_clk_table->num_entries_per_clk.num_dtbclk_levels) { 112 + dml_clk_table->dtbclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dtbclk_levels; 113 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 114 + if (i < dml_clk_table->dtbclk.num_clk_values) { 115 + dml_clk_table->dtbclk.clk_values_khz[i] = dc_clk_table->entries[i].dtbclk_mhz * 1000; 116 + } else { 117 + dml_clk_table->dtbclk.clk_values_khz[i] = 0; 118 + } 119 + } 120 + } 121 + 122 + /* socclk */ 123 + if (dc_clk_table->num_entries_per_clk.num_socclk_levels) { 124 + dml_clk_table->socclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_socclk_levels; 125 + for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) { 126 + if (i < dml_clk_table->socclk.num_clk_values) { 127 + dml_clk_table->socclk.clk_values_khz[i] = dc_clk_table->entries[i].socclk_mhz * 1000; 128 + } else { 129 + dml_clk_table->socclk.clk_values_khz[i] = 0; 130 + } 131 + } 132 + } 133 + 134 + /* dram config */ 135 + dml_clk_table->dram_config.channel_count = dc_bw_params->num_channels; 136 + dml_clk_table->dram_config.channel_width_bytes = dc_bw_params->dram_channel_width_bytes; 137 + } 138 + 139 + static void dcn42_update_soc_bb_with_values_from_clk_mgr(struct dml2_soc_bb *soc_bb, const struct dc *dc) 140 + { 141 + soc_bb->dprefclk_mhz = dc->clk_mgr->dprefclk_khz / 1000; 142 + soc_bb->dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 143 + soc_bb->mall_allocated_for_dcn_mbytes = dc->caps.mall_size_total / (1024 * 1024); 144 + 145 + if (dc->clk_mgr->funcs->is_smu_present && 146 + dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr)) { 147 + dcn42_convert_dc_clock_table_to_soc_bb_clock_table(&soc_bb->clk_table, &soc_bb->vmin_limit, 148 + dc->clk_mgr->bw_params); 149 + } 150 + } 151 + 152 + static void apply_soc_bb_updates(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) 153 + { 154 + /* Individual modification can be overwritten even if it was obtained by a previous function. 155 + * Modifications are acquired in order of priority (lowest to highest). 156 + */ 157 + dc_assert_fp_enabled(); 158 + 159 + dcn42_update_soc_bb_with_values_from_clk_mgr(soc_bb, dc); 160 + dcn401_update_soc_bb_with_values_from_vbios(soc_bb, dc); 161 + dcn401_update_soc_bb_with_values_from_software_policy(soc_bb, dc); 162 + } 163 + 164 + void dcn42_get_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) 165 + { 166 + //get default soc_bb with static values 167 + get_default_soc_bb(soc_bb, dc); 168 + //update soc_bb values with more accurate values 169 + apply_soc_bb_updates(soc_bb, dc, config); 170 + } 171 + 14 172 static void dcn42_get_ip_caps(struct dml2_ip_capabilities *ip_caps) 15 173 { 16 174 *ip_caps = dml2_dcn42_max_ip_caps; 17 175 } 18 176 19 177 static struct soc_and_ip_translator_funcs dcn42_translator_funcs = { 20 - .get_soc_bb = dcn401_get_soc_bb, 178 + .get_soc_bb = dcn42_get_soc_bb, 21 179 .get_ip_caps = dcn42_get_ip_caps, 22 180 }; 23 181 ··· 183 25 { 184 26 soc_and_ip_translator->translator_funcs = &dcn42_translator_funcs; 185 27 } 28 +
+1
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.h
··· 12 12 #include "soc_and_ip_translator.h" 13 13 14 14 void dcn42_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator); 15 + void dcn42_get_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config); 15 16 16 17 #endif /* _DCN42_SOC_AND_IP_TRANSLATOR_H_ */
+4
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c
··· 4 4 5 5 #include "soc_and_ip_translator.h" 6 6 #include "soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h" 7 + #include "soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.h" 7 8 8 9 static void dc_construct_soc_and_ip_translator(struct soc_and_ip_translator *soc_and_ip_translator, 9 10 enum dce_version dc_version) ··· 12 11 switch (dc_version) { 13 12 case DCN_VERSION_4_01: 14 13 dcn401_construct_soc_and_ip_translator(soc_and_ip_translator); 14 + break; 15 + case DCN_VERSION_4_2: 16 + dcn42_construct_soc_and_ip_translator(soc_and_ip_translator); 15 17 break; 16 18 default: 17 19 break;
+53 -18
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 909 909 struct { 910 910 uint32_t shared_state_link_detection : 1; /**< 1 supports link detection via shared state */ 911 911 uint32_t cursor_offload_v1_support: 1; /**< 1 supports cursor offload */ 912 - uint32_t reserved : 30; 912 + uint32_t inbox0_lock_support: 1; /**< 1 supports inbox0 lock mechanism */ 913 + uint32_t reserved : 29; 913 914 } bits; /**< status bits */ 914 915 uint32_t all; /**< 32-bit access to status bits */ 915 916 }; ··· 1536 1535 * 1 - Enable ips measurement 1537 1536 */ 1538 1537 DMUB_GPINT__IPS_RESIDENCY = 121, 1539 - 1540 1538 /** 1541 1539 * DESC: Enable measurements for various task duration 1542 1540 * ARGS: 0 - Disable measurement 1543 1541 * 1 - Enable measurement 1544 1542 */ 1545 1543 DMUB_GPINT__TRACE_DMUB_WAKE_ACTIVITY = 123, 1546 - 1547 1544 /** 1548 1545 * DESC: Gets IPS residency in microseconds 1549 1546 * ARGS: 0 - Return IPS1 residency ··· 1551 1552 * RETURN: Total residency in microseconds - lower 32 bits 1552 1553 */ 1553 1554 DMUB_GPINT__GET_IPS_RESIDENCY_DURATION_US_LO = 124, 1554 - 1555 1555 /** 1556 1556 * DESC: Gets IPS1 histogram counts 1557 1557 * ARGS: Bucket index 1558 1558 * RETURN: Total count for the bucket 1559 1559 */ 1560 1560 DMUB_GPINT__GET_IPS1_HISTOGRAM_COUNTER = 125, 1561 - 1562 1561 /** 1563 1562 * DESC: Gets IPS2 histogram counts 1564 1563 * ARGS: Bucket index 1565 1564 * RETURN: Total count for the bucket 1566 1565 */ 1567 1566 DMUB_GPINT__GET_IPS2_HISTOGRAM_COUNTER = 126, 1568 - 1569 1567 /** 1570 1568 * DESC: Gets IPS residency 1571 1569 * ARGS: 0 - Return IPS1 residency ··· 1572 1576 * RETURN: Total residency in milli-percent. 1573 1577 */ 1574 1578 DMUB_GPINT__GET_IPS_RESIDENCY_PERCENT = 127, 1575 - 1576 1579 /** 1577 1580 * DESC: Gets IPS1_RCG histogram counts 1578 1581 * ARGS: Bucket index 1579 1582 * RETURN: Total count for the bucket 1580 1583 */ 1581 1584 DMUB_GPINT__GET_IPS1_RCG_HISTOGRAM_COUNTER = 128, 1582 - 1583 1585 /** 1584 1586 * DESC: Gets IPS1_ONO2_ON histogram counts 1585 1587 * ARGS: Bucket index 1586 1588 * RETURN: Total count for the bucket 1587 1589 */ 1588 1590 DMUB_GPINT__GET_IPS1_ONO2_ON_HISTOGRAM_COUNTER = 129, 1589 - 1590 1591 /** 1591 1592 * DESC: Gets IPS entry counter during residency measurement 1592 1593 * ARGS: 0 - Return IPS1 entry counts ··· 1593 1600 * RETURN: Entry counter for selected IPS mode 1594 1601 */ 1595 1602 DMUB_GPINT__GET_IPS_RESIDENCY_ENTRY_COUNTER = 130, 1596 - 1597 1603 /** 1598 1604 * DESC: Gets IPS inactive residency in microseconds 1599 1605 * ARGS: 0 - Return IPS1_MAX residency ··· 1602 1610 * RETURN: Total inactive residency in microseconds - lower 32 bits 1603 1611 */ 1604 1612 DMUB_GPINT__GET_IPS_INACTIVE_RESIDENCY_DURATION_US_LO = 131, 1605 - 1606 1613 /** 1607 1614 * DESC: Gets IPS inactive residency in microseconds 1608 1615 * ARGS: 0 - Return IPS1_MAX residency ··· 1611 1620 * RETURN: Total inactive residency in microseconds - upper 32 bits 1612 1621 */ 1613 1622 DMUB_GPINT__GET_IPS_INACTIVE_RESIDENCY_DURATION_US_HI = 132, 1614 - 1615 1623 /** 1616 1624 * DESC: Gets IPS residency in microseconds 1617 1625 * ARGS: 0 - Return IPS1 residency ··· 1669 1679 1670 1680 uint32_t lock: 1; /**< Lock */ 1671 1681 uint32_t should_release: 1; /**< Release */ 1672 - uint32_t reserved: 7; /**< Reserved for extending more clients, HW, etc. */ 1682 + uint32_t reserved: 7; /**< Reserved for extending more clients, HW, etc. */ 1673 1683 } bits; 1674 1684 uint32_t all; 1675 1685 }; ··· 1891 1901 * Command type used for all IHC commands. 1892 1902 */ 1893 1903 DMUB_CMD__IHC = 95, 1904 + 1905 + /** 1906 + * Command type use for boot time crc commands. 1907 + */ 1908 + DMUB_CMD__BOOT_TIME_CRC = 96, 1894 1909 1895 1910 /** 1896 1911 * Command type use for VBIOS shared commands. ··· 2609 2614 uint8_t allow_to_target_delay_otg_vlines; // time from allow vline to target vline 2610 2615 union { 2611 2616 struct { 2612 - uint8_t is_drr: 1; // stream is DRR enabled 2613 - uint8_t clamp_vtotal_min: 1; // clamp vtotal to min instead of nominal 2614 - uint8_t min_ttu_vblank_usable: 1; // if min ttu vblank is above wm, no force pstate is needed in blank 2617 + uint8_t is_drr : 1; // stream is DRR enabled 2618 + uint8_t clamp_vtotal_min : 1; // clamp vtotal to min instead of nominal 2619 + uint8_t min_ttu_vblank_usable : 1; // if min ttu vblank is above wm, no force pstate is needed in blank 2615 2620 } bits; 2616 2621 uint8_t all; 2617 2622 } config; ··· 4436 4441 REPLAY_GENERAL_CMD_SET_LOW_RR_ACTIVATE, 4437 4442 REPLAY_GENERAL_CMD_VIDEO_CONFERENCING, 4438 4443 REPLAY_GENERAL_CMD_SET_CONTINUOUSLY_RESYNC, 4444 + REPLAY_GENERAL_CMD_SET_COASTING_VTOTAL_WITHOUT_FRAME_UPDATE, 4439 4445 }; 4440 4446 4441 4447 struct dmub_alpm_auxless_data { ··· 4655 4659 * This does not support HDMI/DP2 for now. 4656 4660 */ 4657 4661 uint8_t phy_rate; 4662 + /** 4663 + * @hpo_stream_enc_inst: HPO stream encoder instance 4664 + */ 4665 + uint8_t hpo_stream_enc_inst; 4666 + /** 4667 + * @hpo_link_enc_inst: HPO link encoder instance 4668 + */ 4669 + uint8_t hpo_link_enc_inst; 4670 + /** 4671 + * @pad: Align structure to 4 byte boundary. 4672 + */ 4673 + uint8_t pad[2]; 4658 4674 }; 4659 4675 4660 4676 /** ··· 5280 5272 */ 5281 5273 DMUB_CMD__LSDMA_LINEAR_COPY = 1, 5282 5274 /** 5283 - * LSDMA copies data from source to destination linearly in sub window 5284 - */ 5275 + * LSDMA copies data from source to destination linearly in sub window 5276 + */ 5285 5277 DMUB_CMD__LSDMA_LINEAR_SUB_WINDOW_COPY = 2, 5286 5278 /** 5287 5279 * Send the tiled-to-tiled copy command ··· 6844 6836 }; 6845 6837 6846 6838 /** 6839 + * Command type of a DMUB_CMD__BOOT_TIME_CRC command 6840 + */ 6841 + enum dmub_cmd_boot_time_crc_type { 6842 + DMUB_CMD__BOOT_TIME_CRC_INIT_MEM = 0 6843 + }; 6844 + 6845 + /** 6846 + * Data passed from driver to FW in a DMUB_CMD__BOOT_TIME_CRC_INIT command. 6847 + */ 6848 + struct dmub_cmd_boot_time_crc_init_data { 6849 + union dmub_addr buffer_addr; 6850 + uint32_t buffer_size; 6851 + }; 6852 + 6853 + /** 6854 + * Definition of a DMUB_CMD__BOOT_TIME_CRC_INIT command. 6855 + */ 6856 + struct dmub_rb_cmd_boot_time_crc_init { 6857 + struct dmub_cmd_header header; 6858 + struct dmub_cmd_boot_time_crc_init_data data; 6859 + }; 6860 + 6861 + /** 6847 6862 * union dmub_rb_cmd - DMUB inbox command. 6848 6863 */ 6849 6864 union dmub_rb_cmd { ··· 7227 7196 * Definition of a DMUB_CMD__IHC command. 7228 7197 */ 7229 7198 struct dmub_rb_cmd_ihc ihc; 7199 + /** 7200 + * Definition of a DMUB_CMD__BOOT_TIME_CRC_INIT command. 7201 + */ 7202 + struct dmub_rb_cmd_boot_time_crc_init boot_time_crc_init; 7230 7203 }; 7231 7204 7232 7205 /**
+3
drivers/gpu/drm/amd/display/include/dpcd_defs.h
··· 64 64 #ifndef DP_PR_ERROR_STATUS // can remove this once the define gets into linux drm_dp_helper.h 65 65 #define DP_PR_ERROR_STATUS 0x2020 /* DP 2.0 */ 66 66 #endif /* DP_PR_ERROR_STATUS */ 67 + #ifndef DP_PR_REPLAY_SINK_STATUS // can remove this once the define gets into linux drm_dp_helper.h 68 + #define DP_PR_REPLAY_SINK_STATUS 0x2022 69 + #endif /* DP_PR_REPLAY_SINK_STATUS */ 67 70 #ifndef DP_PR_LINK_CRC_ERROR // can remove this once the define gets into linux drm_dp_helper.h 68 71 #define DP_PR_LINK_CRC_ERROR (1 << 0) 69 72 #endif /* DP_PR_LINK_CRC_ERROR */
+44
drivers/gpu/drm/amd/include/asic_reg/clk/clk_15_0_0_offset.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* Copyright 2026 Advanced Micro Devices, Inc. */ 3 + 4 + #ifndef _clk_15_0_0_OFFSET_HEADER 5 + #define _clk_15_0_0_OFFSET_HEADER 6 + 7 + // addressBlock: clk_clk8_0_SmuClkDec 8 + // base address: 0x6e000 9 + #define regCLK8_CLK0_DS_CNTL 0x4c14 10 + #define regCLK8_CLK0_DS_CNTL_BASE_IDX 0 11 + #define regCLK8_CLK1_DS_CNTL 0x4c1c 12 + #define regCLK8_CLK1_DS_CNTL_BASE_IDX 0 13 + #define regCLK8_CLK2_DS_CNTL 0x4c24 14 + #define regCLK8_CLK2_DS_CNTL_BASE_IDX 0 15 + #define regCLK8_CLK3_DS_CNTL 0x4c2c 16 + #define regCLK8_CLK3_DS_CNTL_BASE_IDX 0 17 + #define regCLK8_CLK4_DS_CNTL 0x4c34 18 + #define regCLK8_CLK4_DS_CNTL_BASE_IDX 0 19 + #define regCLK8_CLK0_BYPASS_CNTL 0x4c1a 20 + #define regCLK8_CLK0_BYPASS_CNTL_BASE_IDX 0 21 + #define regCLK8_CLK1_BYPASS_CNTL 0x4c22 22 + #define regCLK8_CLK1_BYPASS_CNTL_BASE_IDX 0 23 + #define regCLK8_CLK2_BYPASS_CNTL 0x4c2a 24 + #define regCLK8_CLK2_BYPASS_CNTL_BASE_IDX 0 25 + #define regCLK8_CLK3_BYPASS_CNTL 0x4c32 26 + #define regCLK8_CLK3_BYPASS_CNTL_BASE_IDX 0 27 + #define regCLK8_CLK4_BYPASS_CNTL 0x4c3a 28 + #define regCLK8_CLK4_BYPASS_CNTL_BASE_IDX 0 29 + #define regCLK8_CLK_TICK_CNT_CONFIG_REG 0x4c51 30 + #define regCLK8_CLK_TICK_CNT_CONFIG_REG_BASE_IDX 0 31 + #define regCLK8_CLK_TICK_CNT_STATUS 0x4c52 32 + #define regCLK8_CLK_TICK_CNT_STATUS_BASE_IDX 0 33 + #define regCLK8_CLK0_CURRENT_CNT 0x4c53 34 + #define regCLK8_CLK0_CURRENT_CNT_BASE_IDX 0 35 + #define regCLK8_CLK1_CURRENT_CNT 0x4c54 36 + #define regCLK8_CLK1_CURRENT_CNT_BASE_IDX 0 37 + #define regCLK8_CLK2_CURRENT_CNT 0x4c55 38 + #define regCLK8_CLK2_CURRENT_CNT_BASE_IDX 0 39 + #define regCLK8_CLK3_CURRENT_CNT 0x4c56 40 + #define regCLK8_CLK3_CURRENT_CNT_BASE_IDX 0 41 + #define regCLK8_CLK4_CURRENT_CNT 0x4c57 42 + #define regCLK8_CLK4_CURRENT_CNT_BASE_IDX 0 43 + 44 + #endif
+52
drivers/gpu/drm/amd/include/asic_reg/clk/clk_15_0_0_sh_mask.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* Copyright 2026 Advanced Micro Devices, Inc. */ 3 + 4 + #ifndef _clk_15_0_0_SH_MASK_HEADER 5 + #define _clk_15_0_0_SH_MASK_HEADER 6 + 7 + // addressBlock: clk_clk8_0_SmuClkDec 8 + //CLK8_CLK_TICK_CNT_CONFIG_REG 9 + #define CLK8_CLK_TICK_CNT_CONFIG_REG__TIMER_THRESHOLD__SHIFT 0x0 10 + #define CLK8_CLK_TICK_CNT_CONFIG_REG__TIMER_THRESHOLD_MASK 0xFFFFL 11 + //CLK8_CLK0_BYPASS_CNTL 12 + #define CLK8_CLK0_BYPASS_CNTL__CLK0_BYPASS_SEL__SHIFT 0x0 13 + #define CLK8_CLK0_BYPASS_CNTL__CLK0_BYPASS_SEL_MASK 0x00000007L 14 + //CLK8_CLK1_BYPASS_CNTL 15 + #define CLK8_CLK1_BYPASS_CNTL__CLK1_BYPASS_SEL__SHIFT 0x0 16 + #define CLK8_CLK1_BYPASS_CNTL__CLK1_BYPASS_SEL_MASK 0x00000007L 17 + //CLK8_CLK2_BYPASS_CNTL 18 + #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0 19 + #define CLK8_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L 20 + //CLK8_CLK3_BYPASS_CNTL 21 + #define CLK8_CLK3_BYPASS_CNTL__CLK3_BYPASS_SEL__SHIFT 0x0 22 + #define CLK8_CLK3_BYPASS_CNTL__CLK3_BYPASS_SEL_MASK 0x00000007L 23 + //CLK8_CLK4_BYPASS_CNTL 24 + #define CLK8_CLK4_BYPASS_CNTL__CLK4_BYPASS_SEL__SHIFT 0x0 25 + #define CLK8_CLK4_BYPASS_CNTL__CLK4_BYPASS_SEL_MASK 0x00000007L 26 + //CLK8_CLK0_DS_CNTL 27 + #define CLK8_CLK0_DS_CNTL__CLK0_DS_DIV_ID__SHIFT 0x0 28 + #define CLK8_CLK0_DS_CNTL__CLK0_DS_DIV_ID_MASK 0x0000000FL 29 + #define CLK8_CLK0_DS_CNTL__CLK0_ALLOW_DS__SHIFT 0x4 30 + #define CLK8_CLK0_DS_CNTL__CLK0_ALLOW_DS_MASK 0x00000010L 31 + //CLK8_CLK1_DS_CNTL 32 + #define CLK8_CLK1_DS_CNTL__CLK1_DS_DIV_ID__SHIFT 0x0 33 + #define CLK8_CLK1_DS_CNTL__CLK1_DS_DIV_ID_MASK 0x0000000FL 34 + #define CLK8_CLK1_DS_CNTL__CLK1_ALLOW_DS__SHIFT 0x4 35 + #define CLK8_CLK1_DS_CNTL__CLK1_ALLOW_DS_MASK 0x00000010L 36 + //CLK8_CLK2_DS_CNTL 37 + #define CLK8_CLK2_DS_CNTL__CLK2_DS_DIV_ID__SHIFT 0x0 38 + #define CLK8_CLK2_DS_CNTL__CLK2_DS_DIV_ID_MASK 0x0000000FL 39 + #define CLK8_CLK2_DS_CNTL__CLK2_ALLOW_DS__SHIFT 0x4 40 + #define CLK8_CLK2_DS_CNTL__CLK2_ALLOW_DS_MASK 0x00000010L 41 + //CLK8_CLK3_DS_CNTL 42 + #define CLK8_CLK3_DS_CNTL__CLK3_DS_DIV_ID__SHIFT 0x0 43 + #define CLK8_CLK3_DS_CNTL__CLK3_DS_DIV_ID_MASK 0x0000000FL 44 + #define CLK8_CLK3_DS_CNTL__CLK3_ALLOW_DS__SHIFT 0x4 45 + #define CLK8_CLK3_DS_CNTL__CLK3_ALLOW_DS_MASK 0x00000010L 46 + //CLK8_CLK4_DS_CNTL 47 + #define CLK8_CLK4_DS_CNTL__CLK4_DS_DIV_ID__SHIFT 0x0 48 + #define CLK8_CLK4_DS_CNTL__CLK4_DS_DIV_ID_MASK 0x0000000FL 49 + #define CLK8_CLK4_DS_CNTL__CLK4_ALLOW_DS__SHIFT 0x4 50 + #define CLK8_CLK4_DS_CNTL__CLK4_ALLOW_DS_MASK 0x00000010L 51 + 52 + #endif
+2
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_2_0_offset.h
··· 9010 9010 // base address: 0x0 9011 9011 #define regODM0_OPTC_INPUT_GLOBAL_CONTROL 0x1aca 9012 9012 #define regODM0_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2 9013 + #define regODM0_OPTC_RSMU_UNDERFLOW 0x1acb 9014 + #define regODM0_OPTC_RSMU_UNDERFLOW_BASE_IDX 2 9013 9015 #define regODM0_OPTC_UNDERFLOW_THRESHOLD 0x1acc 9014 9016 #define regODM0_OPTC_UNDERFLOW_THRESHOLD_BASE_IDX 2 9015 9017 #define regODM0_OPTC_DATA_SOURCE_SELECT 0x1acd
+9
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_2_0_sh_mask.h
··· 33583 33583 #define ODM0_OPTC_INPUT_GLOBAL_CONTROL__OPTC_UNDERFLOW_CLEAR_MASK 0x00001000L 33584 33584 #define ODM0_OPTC_INPUT_GLOBAL_CONTROL__OPTC_UNDERFLOW_OCCURRED_CURRENT_MASK 0x00002000L 33585 33585 #define ODM0_OPTC_INPUT_GLOBAL_CONTROL__OPTC_DOUBLE_BUFFER_PENDING_MASK 0x80000000L 33586 + //ODM0_OPTC_RSMU_UNDERFLOW 33587 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_INT_EN__SHIFT 0x0 33588 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_OCCURRED_STATUS__SHIFT 0x1 33589 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_INT_STATUS__SHIFT 0x2 33590 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_CLEAR__SHIFT 0x3 33591 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_INT_EN_MASK 0x00000001L 33592 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_OCCURRED_STATUS_MASK 0x00000002L 33593 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_INT_STATUS_MASK 0x00000004L 33594 + #define ODM0_OPTC_RSMU_UNDERFLOW__OPTC_RSMU_UNDERFLOW_CLEAR_MASK 0x00000008L 33586 33595 //ODM0_OPTC_UNDERFLOW_THRESHOLD 33587 33596 #define ODM0_OPTC_UNDERFLOW_THRESHOLD__OPTC_UNDERFLOW_THRESHOLD__SHIFT 0x0 33588 33597 #define ODM0_OPTC_UNDERFLOW_THRESHOLD__OPTC_UNDERFLOW_THRESHOLD_MASK 0x01FFFFFFL
+44
drivers/gpu/drm/amd/include/asic_reg/lsdma/lsdma_7_1_0_offset.h
··· 1 + /* 2 + * Copyright 2026 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + */ 23 + #ifndef _lsdma_7_1_0_OFFSET_HEADER 24 + #define _lsdma_7_1_0_OFFSET_HEADER 25 + 26 + #define regLSDMA_PIO_SRC_ADDR_LO 0x0080 27 + #define regLSDMA_PIO_SRC_ADDR_LO_BASE_IDX 0 28 + #define regLSDMA_PIO_SRC_ADDR_HI 0x0081 29 + #define regLSDMA_PIO_SRC_ADDR_HI_BASE_IDX 0 30 + #define regLSDMA_PIO_DST_ADDR_LO 0x0082 31 + #define regLSDMA_PIO_DST_ADDR_LO_BASE_IDX 0 32 + #define regLSDMA_PIO_DST_ADDR_HI 0x0083 33 + #define regLSDMA_PIO_DST_ADDR_HI_BASE_IDX 0 34 + #define regLSDMA_PIO_COMMAND 0x0084 35 + #define regLSDMA_PIO_COMMAND_BASE_IDX 0 36 + #define regLSDMA_PIO_CONSTFILL_DATA 0x0085 37 + #define regLSDMA_PIO_CONSTFILL_DATA_BASE_IDX 0 38 + #define regLSDMA_PIO_CONTROL 0x0086 39 + #define regLSDMA_PIO_CONTROL_BASE_IDX 0 40 + 41 + #define regLSDMA_PIO_STATUS 0x008a 42 + #define regLSDMA_PIO_STATUS_BASE_IDX 0 43 + 44 + #endif
+105
drivers/gpu/drm/amd/include/asic_reg/lsdma/lsdma_7_1_0_sh_mask.h
··· 1 + /* 2 + * Copyright 2026 Advanced Micro Devices, Inc. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 + * OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + */ 23 + #ifndef _lsdma_7_1_0_SH_MASK_HEADER 24 + #define _lsdma_7_1_0_SH_MASK_HEADER 25 + 26 + 27 + // addressBlock: lsdma0_lsdma0dec 28 + //LSDMA_PIO_STATUS 29 + #define LSDMA_PIO_STATUS__CMD_IN_FIFO__SHIFT 0x0 30 + #define LSDMA_PIO_STATUS__CMD_PROCESSING__SHIFT 0x3 31 + #define LSDMA_PIO_STATUS__ERROR_INVALID_ADDR__SHIFT 0xb 32 + #define LSDMA_PIO_STATUS__ERROR_ZERO_COUNT__SHIFT 0xc 33 + #define LSDMA_PIO_STATUS__ERROR_DRAM_ECC__SHIFT 0xd 34 + #define LSDMA_PIO_STATUS__ERROR_SRAM_ECC__SHIFT 0xe 35 + #define LSDMA_PIO_STATUS__ERROR_WRRET_NACK_GEN_ERR__SHIFT 0xf 36 + #define LSDMA_PIO_STATUS__ERROR_RDRET_NACK_GEN_ERR__SHIFT 0x10 37 + #define LSDMA_PIO_STATUS__ERROR_WRRET_NACK_PRT__SHIFT 0x11 38 + #define LSDMA_PIO_STATUS__ERROR_RDRET_NACK_PRT__SHIFT 0x12 39 + #define LSDMA_PIO_STATUS__ERROR_REQ_DROP__SHIFT 0x13 40 + #define LSDMA_PIO_STATUS__PIO_FIFO_EMPTY__SHIFT 0x1c 41 + #define LSDMA_PIO_STATUS__PIO_FIFO_FULL__SHIFT 0x1d 42 + #define LSDMA_PIO_STATUS__PIO_IDLE__SHIFT 0x1f 43 + #define LSDMA_PIO_STATUS__CMD_IN_FIFO_MASK 0x00000007L 44 + #define LSDMA_PIO_STATUS__CMD_PROCESSING_MASK 0x000003F8L 45 + #define LSDMA_PIO_STATUS__ERROR_INVALID_ADDR_MASK 0x00000800L 46 + #define LSDMA_PIO_STATUS__ERROR_ZERO_COUNT_MASK 0x00001000L 47 + #define LSDMA_PIO_STATUS__ERROR_DRAM_ECC_MASK 0x00002000L 48 + #define LSDMA_PIO_STATUS__ERROR_SRAM_ECC_MASK 0x00004000L 49 + #define LSDMA_PIO_STATUS__ERROR_WRRET_NACK_GEN_ERR_MASK 0x00008000L 50 + #define LSDMA_PIO_STATUS__ERROR_RDRET_NACK_GEN_ERR_MASK 0x00010000L 51 + #define LSDMA_PIO_STATUS__ERROR_WRRET_NACK_PRT_MASK 0x00020000L 52 + #define LSDMA_PIO_STATUS__ERROR_RDRET_NACK_PRT_MASK 0x00040000L 53 + #define LSDMA_PIO_STATUS__ERROR_REQ_DROP_MASK 0x00080000L 54 + #define LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK 0x10000000L 55 + #define LSDMA_PIO_STATUS__PIO_FIFO_FULL_MASK 0x20000000L 56 + #define LSDMA_PIO_STATUS__PIO_IDLE_MASK 0x80000000L 57 + //LSDMA_PIO_SRC_ADDR_LO 58 + #define LSDMA_PIO_SRC_ADDR_LO__SRC_ADDR_LO__SHIFT 0x0 59 + #define LSDMA_PIO_SRC_ADDR_LO__SRC_ADDR_LO_MASK 0xFFFFFFFFL 60 + //LSDMA_PIO_SRC_ADDR_HI 61 + #define LSDMA_PIO_SRC_ADDR_HI__SRC_ADDR_HI__SHIFT 0x0 62 + #define LSDMA_PIO_SRC_ADDR_HI__SRC_ADDR_HI_MASK 0xFFFFFFFFL 63 + //LSDMA_PIO_DST_ADDR_LO 64 + #define LSDMA_PIO_DST_ADDR_LO__DST_ADDR_LO__SHIFT 0x0 65 + #define LSDMA_PIO_DST_ADDR_LO__DST_ADDR_LO_MASK 0xFFFFFFFFL 66 + //LSDMA_PIO_DST_ADDR_HI 67 + #define LSDMA_PIO_DST_ADDR_HI__DST_ADDR_HI__SHIFT 0x0 68 + #define LSDMA_PIO_DST_ADDR_HI__DST_ADDR_HI_MASK 0xFFFFFFFFL 69 + //LSDMA_PIO_CONTROL 70 + #define LSDMA_PIO_CONTROL__VMID__SHIFT 0x0 71 + #define LSDMA_PIO_CONTROL__DST_GPA__SHIFT 0x4 72 + #define LSDMA_PIO_CONTROL__DST_SYS__SHIFT 0x5 73 + #define LSDMA_PIO_CONTROL__DST_GCC__SHIFT 0x6 74 + #define LSDMA_PIO_CONTROL__DST_SNOOP__SHIFT 0x7 75 + #define LSDMA_PIO_CONTROL__DST_REUSE_HINT__SHIFT 0x8 76 + #define LSDMA_PIO_CONTROL__DST_COMP_EN__SHIFT 0xa 77 + #define LSDMA_PIO_CONTROL__SRC_GPA__SHIFT 0x14 78 + #define LSDMA_PIO_CONTROL__SRC_SYS__SHIFT 0x15 79 + #define LSDMA_PIO_CONTROL__SRC_SNOOP__SHIFT 0x17 80 + #define LSDMA_PIO_CONTROL__SRC_REUSE_HINT__SHIFT 0x18 81 + #define LSDMA_PIO_CONTROL__SRC_COMP_EN__SHIFT 0x1a 82 + #define LSDMA_PIO_CONTROL__VMID_MASK 0x0000000FL 83 + #define LSDMA_PIO_CONTROL__DST_GPA_MASK 0x00000010L 84 + #define LSDMA_PIO_CONTROL__DST_SYS_MASK 0x00000020L 85 + #define LSDMA_PIO_CONTROL__DST_GCC_MASK 0x00000040L 86 + #define LSDMA_PIO_CONTROL__DST_SNOOP_MASK 0x00000080L 87 + #define LSDMA_PIO_CONTROL__DST_REUSE_HINT_MASK 0x00000300L 88 + #define LSDMA_PIO_CONTROL__DST_COMP_EN_MASK 0x00000400L 89 + #define LSDMA_PIO_CONTROL__SRC_GPA_MASK 0x00100000L 90 + #define LSDMA_PIO_CONTROL__SRC_SYS_MASK 0x00200000L 91 + #define LSDMA_PIO_CONTROL__SRC_SNOOP_MASK 0x00800000L 92 + #define LSDMA_PIO_CONTROL__SRC_REUSE_HINT_MASK 0x03000000L 93 + #define LSDMA_PIO_CONTROL__SRC_COMP_EN_MASK 0x04000000L 94 + //LSDMA_PIO_COMMAND 95 + #define LSDMA_PIO_COMMAND__COUNT__SHIFT 0x0 96 + #define LSDMA_PIO_COMMAND__RAW_WAIT__SHIFT 0x1e 97 + #define LSDMA_PIO_COMMAND__CONSTANT_FILL__SHIFT 0x1f 98 + #define LSDMA_PIO_COMMAND__COUNT_MASK 0x03FFFFFFL 99 + #define LSDMA_PIO_COMMAND__RAW_WAIT_MASK 0x40000000L 100 + #define LSDMA_PIO_COMMAND__CONSTANT_FILL_MASK 0x80000000L 101 + //LSDMA_PIO_CONSTFILL_DATA 102 + #define LSDMA_PIO_CONSTFILL_DATA__DATA__SHIFT 0x0 103 + #define LSDMA_PIO_CONSTFILL_DATA__DATA_MASK 0xFFFFFFFFL 104 + 105 + #endif
+13
drivers/gpu/drm/amd/include/discovery.h
··· 64 64 table_info table_list[TOTAL_TABLES]; 65 65 } binary_header; 66 66 67 + typedef struct binary_header_v2 68 + { 69 + /* psp structure should go at the top of this structure */ 70 + uint32_t binary_signature; /* 0x7, 0x14, 0x21, 0x28 */ 71 + uint16_t version_major; /* 0x02 */ 72 + uint16_t version_minor; 73 + uint16_t binary_checksum; /* Byte sum of the binary after this field */ 74 + uint16_t binary_size; /* Binary Size*/ 75 + uint16_t num_tables; 76 + uint16_t padding; 77 + table_info table_list[] __counted_by(num_tables); 78 + } binary_header_v2; 79 + 67 80 typedef struct die_info 68 81 { 69 82 uint16_t die_id;
+3
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 584 584 AMDGPU_METRICS_ATTR_ID_GFX_BELOW_HOST_LIMIT_THM_ACC, 585 585 AMDGPU_METRICS_ATTR_ID_GFX_LOW_UTILIZATION_ACC, 586 586 AMDGPU_METRICS_ATTR_ID_GFX_BELOW_HOST_LIMIT_TOTAL_ACC, 587 + AMDGPU_METRICS_ATTR_ID_TEMPERATURE_HBM, 588 + AMDGPU_METRICS_ATTR_ID_TEMPERATURE_AID, 589 + AMDGPU_METRICS_ATTR_ID_TEMPERATURE_XCD, 587 590 AMDGPU_METRICS_ATTR_ID_MAX, 588 591 }; 589 592
+2 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
··· 2222 2222 user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | 2223 2223 BIT(PP_OD_FEATURE_UCLK_BIT) | 2224 2224 BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | 2225 - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); 2225 + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | 2226 + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); 2226 2227 res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table); 2227 2228 user_od_table->OverDriveTable.FeatureCtrlMask = 0; 2228 2229 if (res == 0)
+39 -3
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c
··· 49 49 #undef pr_info 50 50 #undef pr_debug 51 51 52 + #define hbm_stack_mask_valid(umc_mask) \ 53 + (((umc_mask) & 0x3) == 0x3) 54 + 55 + #define for_each_hbm_stack(stack_idx, umc_mask) \ 56 + for ((stack_idx) = 0; (umc_mask); \ 57 + (umc_mask) >>= 2, (stack_idx)++) \ 58 + 52 59 #define SMU_13_0_12_FEA_MAP(smu_feature, smu_13_0_12_feature) \ 53 60 [smu_feature] = { 1, (smu_13_0_12_feature) } 54 61 ··· 269 262 int ret; 270 263 271 264 if (smu_table->tables[SMU_TABLE_SMU_METRICS].version >= 0x13) { 272 - max_width = (uint8_t)static_metrics->MaxXgmiWidth; 273 - max_speed = (uint16_t)static_metrics->MaxXgmiBitrate; 265 + max_width = (uint8_t)SMUQ10_ROUND(static_metrics->MaxXgmiWidth); 266 + max_speed = 267 + (uint16_t)SMUQ10_ROUND(static_metrics->MaxXgmiBitrate); 274 268 ret = 0; 275 269 } else { 276 270 MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; ··· 842 834 struct smu_v13_0_6_gpu_metrics *gpu_metrics) 843 835 { 844 836 struct amdgpu_device *adev = smu->adev; 845 - int ret = 0, xcc_id, inst, i, j; 837 + int ret = 0, xcc_id, inst, i, j, idx; 846 838 u8 num_jpeg_rings_gpu_metrics; 847 839 MetricsTable_t *metrics; 848 840 ··· 856 848 /* Reports max temperature of all voltage rails */ 857 849 gpu_metrics->temperature_vrsoc = 858 850 SMUQ10_ROUND(metrics->MaxVrTemperature); 851 + 852 + if (smu_v13_0_6_cap_supported(smu, 853 + SMU_CAP(TEMP_AID_XCD_HBM))) { 854 + if (adev->umc.active_mask) { 855 + u64 mask = adev->umc.active_mask; 856 + int out_idx = 0; 857 + int stack_idx; 858 + 859 + if (unlikely(hweight64(mask) / 2 > SMU_13_0_6_MAX_HBM_STACKS)) { 860 + dev_warn(adev->dev, "Invalid umc mask %lld\n", mask); 861 + } else { 862 + for_each_hbm_stack(stack_idx, mask) { 863 + if (!hbm_stack_mask_valid(mask)) 864 + continue; 865 + gpu_metrics->temperature_hbm[out_idx++] = 866 + metrics->HbmTemperature[stack_idx]; 867 + } 868 + } 869 + } 870 + idx = 0; 871 + for_each_inst(i, adev->aid_mask) { 872 + gpu_metrics->temperature_aid[idx] = metrics->AidTemperature[i]; 873 + idx++; 874 + } 875 + } 859 876 860 877 gpu_metrics->average_gfx_activity = 861 878 SMUQ10_ROUND(metrics->SocketGfxBusy); ··· 997 964 [i] = SMUQ10_ROUND( 998 965 metrics->GfxclkBelowHostLimitTotalAcc[inst]); 999 966 } 967 + if (smu_v13_0_6_cap_supported(smu, 968 + SMU_CAP(TEMP_AID_XCD_HBM))) 969 + gpu_metrics->temperature_xcd[i] = metrics->XcdTemperature[inst]; 1000 970 } 1001 971 1002 972 gpu_metrics->xgmi_link_width = metrics->XgmiWidth;
+3
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
··· 373 373 } else { 374 374 smu_v13_0_12_tables_fini(smu); 375 375 } 376 + 377 + if (fw_ver >= 0x04561000) 378 + smu_v13_0_6_cap_set(smu, SMU_CAP(TEMP_AID_XCD_HBM)); 376 379 } 377 380 378 381 static void smu_v13_0_6_init_caps(struct smu_context *smu)
+12 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h
··· 78 78 SMU_CAP(RAS_EEPROM), 79 79 SMU_CAP(FAST_PPT), 80 80 SMU_CAP(SYSTEM_POWER_METRICS), 81 + SMU_CAP(TEMP_AID_XCD_HBM), 81 82 SMU_CAP(ALL), 82 83 }; 83 84 ··· 88 87 #define SMU_13_0_6_MAX_XCC 8 89 88 #define SMU_13_0_6_MAX_VCN 4 90 89 #define SMU_13_0_6_MAX_JPEG 40 90 + #define SMU_13_0_6_MAX_AID 4 91 + #define SMU_13_0_6_MAX_HBM_STACKS 8 91 92 92 93 extern void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu); 93 94 bool smu_v13_0_6_cap_supported(struct smu_context *smu, enum smu_v13_0_6_caps cap); ··· 225 222 SMU_13_0_6_MAX_XCC); \ 226 223 SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_TOTAL_ACC), SMU_MUNIT(NONE), \ 227 224 SMU_MTYPE(U64), gfx_below_host_limit_total_acc, \ 228 - SMU_13_0_6_MAX_XCC); 225 + SMU_13_0_6_MAX_XCC); \ 226 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_HBM), SMU_MUNIT(TEMP_1), \ 227 + SMU_MTYPE(U16), temperature_hbm, \ 228 + SMU_13_0_6_MAX_HBM_STACKS); \ 229 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_AID), SMU_MUNIT(TEMP_1), \ 230 + SMU_MTYPE(U16), temperature_aid, SMU_13_0_6_MAX_AID); \ 231 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_XCD), SMU_MUNIT(TEMP_1), \ 232 + SMU_MTYPE(U16), temperature_xcd, SMU_13_0_6_MAX_XCC); \ 233 + 229 234 230 235 DECLARE_SMU_METRICS_CLASS(smu_v13_0_6_gpu_metrics, SMU_13_0_6_METRICS_FIELDS); 231 236 void smu_v13_0_12_get_gpu_metrics(struct smu_context *smu, void **table,
+2 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
··· 2224 2224 user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | 2225 2225 BIT(PP_OD_FEATURE_UCLK_BIT) | 2226 2226 BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | 2227 - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); 2227 + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | 2228 + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); 2228 2229 res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table); 2229 2230 user_od_table->OverDriveTable.FeatureCtrlMask = 0; 2230 2231 if (res == 0)
+2 -1
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
··· 2311 2311 user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | 2312 2312 BIT(PP_OD_FEATURE_UCLK_BIT) | 2313 2313 BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | 2314 - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); 2314 + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | 2315 + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); 2315 2316 res = smu_v14_0_2_upload_overdrive_table(smu, user_od_table); 2316 2317 user_od_table->OverDriveTable.FeatureCtrlMask = 0; 2317 2318 if (res == 0)
+30
drivers/gpu/drm/drm_fb_helper.c
··· 37 37 #include <drm/drm_fb_helper.h> 38 38 #include <drm/drm_fourcc.h> 39 39 #include <drm/drm_framebuffer.h> 40 + #include <drm/drm_gem_framebuffer_helper.h> 40 41 #include <drm/drm_modeset_helper_vtables.h> 41 42 #include <drm/drm_print.h> 42 43 #include <drm/drm_vblank.h> ··· 1772 1771 return 0; 1773 1772 } 1774 1773 EXPORT_SYMBOL(drm_fb_helper_hotplug_event); 1774 + 1775 + /** 1776 + * drm_fb_helper_gem_is_fb - Tests if GEM object is framebuffer 1777 + * @fb_helper: fb_helper instance, can be NULL 1778 + * @obj: The GEM object to test, can be NULL 1779 + * 1780 + * Call drm_fb_helper_gem_is_fb to test is a DRM device's fbdev emulation 1781 + * uses the specified GEM object for its framebuffer. The result is always 1782 + * false if either poiner is NULL. 1783 + * 1784 + * Returns: 1785 + * True if fbdev emulation uses the provided GEM object, or false otherwise. 1786 + */ 1787 + bool drm_fb_helper_gem_is_fb(const struct drm_fb_helper *fb_helper, 1788 + const struct drm_gem_object *obj) 1789 + { 1790 + const struct drm_gem_object *gem = NULL; 1791 + 1792 + if (!fb_helper || !obj) 1793 + return false; 1794 + if (fb_helper->buffer && fb_helper->buffer->gem) 1795 + gem = fb_helper->buffer->gem; 1796 + else if (fb_helper->fb) 1797 + gem = drm_gem_fb_get_obj(fb_helper->fb, 0); 1798 + 1799 + return gem == obj; 1800 + } 1801 + EXPORT_SYMBOL_GPL(drm_fb_helper_gem_is_fb); 1802 +
+4 -3
drivers/gpu/drm/radeon/radeon_device.c
··· 37 37 #include <drm/drm_client_event.h> 38 38 #include <drm/drm_crtc_helper.h> 39 39 #include <drm/drm_device.h> 40 + #include <drm/drm_fb_helper.h> 40 41 #include <drm/drm_file.h> 41 42 #include <drm/drm_framebuffer.h> 42 43 #include <drm/drm_probe_helper.h> ··· 1575 1574 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1576 1575 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 1577 1576 struct drm_framebuffer *fb = crtc->primary->fb; 1578 - struct radeon_bo *robj; 1579 1577 1580 1578 if (radeon_crtc->cursor_bo) { 1581 1579 struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); ··· 1588 1588 if (fb == NULL || fb->obj[0] == NULL) { 1589 1589 continue; 1590 1590 } 1591 - robj = gem_to_radeon_bo(fb->obj[0]); 1592 1591 /* don't unpin kernel fb objects */ 1593 - if (!radeon_fbdev_robj_is_fb(rdev, robj)) { 1592 + if (!drm_fb_helper_gem_is_fb(dev->fb_helper, fb->obj[0])) { 1593 + struct radeon_bo *robj = gem_to_radeon_bo(fb->obj[0]); 1594 + 1594 1595 r = radeon_bo_reserve(robj, false); 1595 1596 if (r == 0) { 1596 1597 radeon_bo_unpin(robj);
-17
drivers/gpu/drm/radeon/radeon_fbdev.c
··· 274 274 radeon_fbdev_destroy_pinned_object(gobj); 275 275 return ret; 276 276 } 277 - 278 - bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) 279 - { 280 - struct drm_fb_helper *fb_helper = rdev_to_drm(rdev)->fb_helper; 281 - struct drm_gem_object *gobj; 282 - 283 - if (!fb_helper) 284 - return false; 285 - 286 - gobj = drm_gem_fb_get_obj(fb_helper->fb, 0); 287 - if (!gobj) 288 - return false; 289 - if (gobj != &robj->tbo.base) 290 - return false; 291 - 292 - return true; 293 - }
-5
drivers/gpu/drm/radeon/radeon_mode.h
··· 936 936 struct drm_fb_helper_surface_size *sizes); 937 937 #define RADEON_FBDEV_DRIVER_OPS \ 938 938 .fbdev_probe = radeon_fbdev_driver_fbdev_probe 939 - bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); 940 939 #else 941 940 #define RADEON_FBDEV_DRIVER_OPS \ 942 941 .fbdev_probe = NULL 943 - static inline bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) 944 - { 945 - return false; 946 - } 947 942 #endif 948 943 949 944 void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id);
+2
include/drm/drm_fb_helper.h
··· 271 271 272 272 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); 273 273 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); 274 + bool drm_fb_helper_gem_is_fb(const struct drm_fb_helper *fb_helper, 275 + const struct drm_gem_object *obj); 274 276 #endif 275 277 276 278 #endif