diff options
Diffstat (limited to 'drivers/gpu')
156 files changed, 1633 insertions, 808 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 992f00b65be4..e055d5be1c3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -1820,6 +1820,8 @@ struct amdgpu_asic_funcs { | |||
| 1820 | /* MM block clocks */ | 1820 | /* MM block clocks */ |
| 1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); | 1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); |
| 1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); | 1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); |
| 1823 | /* query virtual capabilities */ | ||
| 1824 | u32 (*get_virtual_caps)(struct amdgpu_device *adev); | ||
| 1823 | }; | 1825 | }; |
| 1824 | 1826 | ||
| 1825 | /* | 1827 | /* |
| @@ -1914,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); | |||
| 1914 | 1916 | ||
| 1915 | 1917 | ||
| 1916 | /* GPU virtualization */ | 1918 | /* GPU virtualization */ |
| 1919 | #define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0) | ||
| 1920 | #define AMDGPU_VIRT_CAPS_IS_VF (1 << 1) | ||
| 1917 | struct amdgpu_virtualization { | 1921 | struct amdgpu_virtualization { |
| 1918 | bool supports_sr_iov; | 1922 | bool supports_sr_iov; |
| 1923 | bool is_virtual; | ||
| 1924 | u32 caps; | ||
| 1919 | }; | 1925 | }; |
| 1920 | 1926 | ||
| 1921 | /* | 1927 | /* |
| @@ -2204,6 +2210,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
| 2204 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) | 2210 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) |
| 2205 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) | 2211 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) |
| 2206 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) | 2212 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) |
| 2213 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) | ||
| 2207 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) | 2214 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) |
| 2208 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) | 2215 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) |
| 2209 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) | 2216 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 199f76baf22c..cf6f49fc1c75 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
| @@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) | |||
| 696 | return result; | 696 | return result; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type) | ||
| 700 | { | ||
| 701 | CGS_FUNC_ADEV; | ||
| 702 | if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) { | ||
| 703 | release_firmware(adev->pm.fw); | ||
| 704 | return 0; | ||
| 705 | } | ||
| 706 | /* cannot release other firmware because they are not created by cgs */ | ||
| 707 | return -EINVAL; | ||
| 708 | } | ||
| 709 | |||
| 699 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | 710 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, |
| 700 | enum cgs_ucode_id type, | 711 | enum cgs_ucode_id type, |
| 701 | struct cgs_firmware_info *info) | 712 | struct cgs_firmware_info *info) |
| @@ -898,7 +909,7 @@ static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device, | |||
| 898 | struct cgs_acpi_method_argument *argument = NULL; | 909 | struct cgs_acpi_method_argument *argument = NULL; |
| 899 | uint32_t i, count; | 910 | uint32_t i, count; |
| 900 | acpi_status status; | 911 | acpi_status status; |
| 901 | int result; | 912 | int result = 0; |
| 902 | uint32_t func_no = 0xFFFFFFFF; | 913 | uint32_t func_no = 0xFFFFFFFF; |
| 903 | 914 | ||
| 904 | handle = ACPI_HANDLE(&adev->pdev->dev); | 915 | handle = ACPI_HANDLE(&adev->pdev->dev); |
| @@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
| 1125 | amdgpu_cgs_pm_query_clock_limits, | 1136 | amdgpu_cgs_pm_query_clock_limits, |
| 1126 | amdgpu_cgs_set_camera_voltages, | 1137 | amdgpu_cgs_set_camera_voltages, |
| 1127 | amdgpu_cgs_get_firmware_info, | 1138 | amdgpu_cgs_get_firmware_info, |
| 1139 | amdgpu_cgs_rel_firmware, | ||
| 1128 | amdgpu_cgs_set_powergating_state, | 1140 | amdgpu_cgs_set_powergating_state, |
| 1129 | amdgpu_cgs_set_clockgating_state, | 1141 | amdgpu_cgs_set_clockgating_state, |
| 1130 | amdgpu_cgs_get_active_displays_info, | 1142 | amdgpu_cgs_get_active_displays_info, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bb8b149786d7..6e920086af46 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | |||
| 827 | */ | 827 | */ |
| 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) | 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) |
| 829 | { | 829 | { |
| 830 | if (adev->mode_info.atom_context) | 830 | if (adev->mode_info.atom_context) { |
| 831 | kfree(adev->mode_info.atom_context->scratch); | 831 | kfree(adev->mode_info.atom_context->scratch); |
| 832 | kfree(adev->mode_info.atom_context->iio); | ||
| 833 | } | ||
| 832 | kfree(adev->mode_info.atom_context); | 834 | kfree(adev->mode_info.atom_context); |
| 833 | adev->mode_info.atom_context = NULL; | 835 | adev->mode_info.atom_context = NULL; |
| 834 | kfree(adev->mode_info.atom_card_info); | 836 | kfree(adev->mode_info.atom_card_info); |
| @@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1325 | adev->ip_block_status[i].valid = false; | 1327 | adev->ip_block_status[i].valid = false; |
| 1326 | } | 1328 | } |
| 1327 | 1329 | ||
| 1330 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | ||
| 1331 | if (adev->ip_blocks[i].funcs->late_fini) | ||
| 1332 | adev->ip_blocks[i].funcs->late_fini((void *)adev); | ||
| 1333 | } | ||
| 1334 | |||
| 1328 | return 0; | 1335 | return 0; |
| 1329 | } | 1336 | } |
| 1330 | 1337 | ||
| @@ -1378,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
| 1378 | return 0; | 1385 | return 0; |
| 1379 | } | 1386 | } |
| 1380 | 1387 | ||
| 1388 | static bool amdgpu_device_is_virtual(void) | ||
| 1389 | { | ||
| 1390 | #ifdef CONFIG_X86 | ||
| 1391 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
| 1392 | #else | ||
| 1393 | return false; | ||
| 1394 | #endif | ||
| 1395 | } | ||
| 1396 | |||
| 1381 | /** | 1397 | /** |
| 1382 | * amdgpu_device_init - initialize the driver | 1398 | * amdgpu_device_init - initialize the driver |
| 1383 | * | 1399 | * |
| @@ -1512,9 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
| 1512 | adev->virtualization.supports_sr_iov = | 1528 | adev->virtualization.supports_sr_iov = |
| 1513 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1529 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
| 1514 | 1530 | ||
| 1531 | /* Check if we are executing in a virtualized environment */ | ||
| 1532 | adev->virtualization.is_virtual = amdgpu_device_is_virtual(); | ||
| 1533 | adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev); | ||
| 1534 | |||
| 1515 | /* Post card if necessary */ | 1535 | /* Post card if necessary */ |
| 1516 | if (!amdgpu_card_posted(adev) || | 1536 | if (!amdgpu_card_posted(adev) || |
| 1517 | adev->virtualization.supports_sr_iov) { | 1537 | (adev->virtualization.is_virtual && |
| 1538 | !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) { | ||
| 1518 | if (!adev->bios) { | 1539 | if (!adev->bios) { |
| 1519 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1540 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
| 1520 | return -EINVAL; | 1541 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 40a23704a981..d851ea15059f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -447,7 +447,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 447 | dev_info.max_memory_clock = adev->pm.default_mclk * 10; | 447 | dev_info.max_memory_clock = adev->pm.default_mclk * 10; |
| 448 | } | 448 | } |
| 449 | dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; | 449 | dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; |
| 450 | dev_info.num_rb_pipes = adev->gfx.config.num_rbs; | 450 | dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se * |
| 451 | adev->gfx.config.max_shader_engines; | ||
| 451 | dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts; | 452 | dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts; |
| 452 | dev_info._pad = 0; | 453 | dev_info._pad = 0; |
| 453 | dev_info.ids_flags = 0; | 454 | dev_info.ids_flags = 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 589b36e8c5cf..0e13d80d2a95 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
| @@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
| 270 | struct drm_device *ddev = dev_get_drvdata(dev); | 270 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 271 | struct amdgpu_device *adev = ddev->dev_private; | 271 | struct amdgpu_device *adev = ddev->dev_private; |
| 272 | enum amd_pm_state_type state = 0; | 272 | enum amd_pm_state_type state = 0; |
| 273 | long idx; | 273 | unsigned long idx; |
| 274 | int ret; | 274 | int ret; |
| 275 | 275 | ||
| 276 | if (strlen(buf) == 1) | 276 | if (strlen(buf) == 1) |
| 277 | adev->pp_force_state_enabled = false; | 277 | adev->pp_force_state_enabled = false; |
| 278 | else { | 278 | else if (adev->pp_enabled) { |
| 279 | ret = kstrtol(buf, 0, &idx); | 279 | struct pp_states_info data; |
| 280 | 280 | ||
| 281 | if (ret) { | 281 | ret = kstrtoul(buf, 0, &idx); |
| 282 | if (ret || idx >= ARRAY_SIZE(data.states)) { | ||
| 282 | count = -EINVAL; | 283 | count = -EINVAL; |
| 283 | goto fail; | 284 | goto fail; |
| 284 | } | 285 | } |
| 285 | 286 | ||
| 286 | if (adev->pp_enabled) { | 287 | amdgpu_dpm_get_pp_num_states(adev, &data); |
| 287 | struct pp_states_info data; | 288 | state = data.states[idx]; |
| 288 | amdgpu_dpm_get_pp_num_states(adev, &data); | 289 | /* only set user selected power states */ |
| 289 | state = data.states[idx]; | 290 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && |
| 290 | /* only set user selected power states */ | 291 | state != POWER_STATE_TYPE_DEFAULT) { |
| 291 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && | 292 | amdgpu_dpm_dispatch_task(adev, |
| 292 | state != POWER_STATE_TYPE_DEFAULT) { | 293 | AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); |
| 293 | amdgpu_dpm_dispatch_task(adev, | 294 | adev->pp_force_state_enabled = true; |
| 294 | AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); | ||
| 295 | adev->pp_force_state_enabled = true; | ||
| 296 | } | ||
| 297 | } | 295 | } |
| 298 | } | 296 | } |
| 299 | fail: | 297 | fail: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 6bd961fb43dc..82256558e0f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
| @@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle) | |||
| 183 | if (ret) | 183 | if (ret) |
| 184 | return ret; | 184 | return ret; |
| 185 | 185 | ||
| 186 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
| 187 | if (adev->pp_enabled) { | ||
| 188 | amdgpu_pm_sysfs_fini(adev); | ||
| 189 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
| 190 | } | ||
| 191 | #endif | ||
| 192 | |||
| 193 | return ret; | 186 | return ret; |
| 194 | } | 187 | } |
| 195 | 188 | ||
| @@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle) | |||
| 223 | return ret; | 216 | return ret; |
| 224 | } | 217 | } |
| 225 | 218 | ||
| 219 | static void amdgpu_pp_late_fini(void *handle) | ||
| 220 | { | ||
| 221 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
| 222 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 223 | |||
| 224 | if (adev->pp_enabled) { | ||
| 225 | amdgpu_pm_sysfs_fini(adev); | ||
| 226 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
| 227 | } | ||
| 228 | |||
| 229 | if (adev->powerplay.ip_funcs->late_fini) | ||
| 230 | adev->powerplay.ip_funcs->late_fini( | ||
| 231 | adev->powerplay.pp_handle); | ||
| 232 | #endif | ||
| 233 | } | ||
| 234 | |||
| 226 | static int amdgpu_pp_suspend(void *handle) | 235 | static int amdgpu_pp_suspend(void *handle) |
| 227 | { | 236 | { |
| 228 | int ret = 0; | 237 | int ret = 0; |
| @@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = { | |||
| 311 | .sw_fini = amdgpu_pp_sw_fini, | 320 | .sw_fini = amdgpu_pp_sw_fini, |
| 312 | .hw_init = amdgpu_pp_hw_init, | 321 | .hw_init = amdgpu_pp_hw_init, |
| 313 | .hw_fini = amdgpu_pp_hw_fini, | 322 | .hw_fini = amdgpu_pp_hw_fini, |
| 323 | .late_fini = amdgpu_pp_late_fini, | ||
| 314 | .suspend = amdgpu_pp_suspend, | 324 | .suspend = amdgpu_pp_suspend, |
| 315 | .resume = amdgpu_pp_resume, | 325 | .resume = amdgpu_pp_resume, |
| 316 | .is_idle = amdgpu_pp_is_idle, | 326 | .is_idle = amdgpu_pp_is_idle, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 3b02272db678..870f9494252c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
| @@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
| 343 | ring->ring = NULL; | 343 | ring->ring = NULL; |
| 344 | ring->ring_obj = NULL; | 344 | ring->ring_obj = NULL; |
| 345 | 345 | ||
| 346 | amdgpu_wb_free(ring->adev, ring->cond_exe_offs); | ||
| 346 | amdgpu_wb_free(ring->adev, ring->fence_offs); | 347 | amdgpu_wb_free(ring->adev, ring->fence_offs); |
| 347 | amdgpu_wb_free(ring->adev, ring->rptr_offs); | 348 | amdgpu_wb_free(ring->adev, ring->rptr_offs); |
| 348 | amdgpu_wb_free(ring->adev, ring->wptr_offs); | 349 | amdgpu_wb_free(ring->adev, ring->wptr_offs); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 8bf84efafb04..48618ee324eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | |||
| @@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, | |||
| 115 | return r; | 115 | return r; |
| 116 | } | 116 | } |
| 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); | 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); |
| 118 | memset(sa_manager->cpu_ptr, 0, sa_manager->size); | ||
| 118 | amdgpu_bo_unreserve(sa_manager->bo); | 119 | amdgpu_bo_unreserve(sa_manager->bo); |
| 119 | return r; | 120 | return r; |
| 120 | } | 121 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 01abfc21b4a2..e19520c4b4b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
| @@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
| 253 | { | 253 | { |
| 254 | int r; | 254 | int r; |
| 255 | 255 | ||
| 256 | if (adev->uvd.vcpu_bo == NULL) | 256 | kfree(adev->uvd.saved_bo); |
| 257 | return 0; | ||
| 258 | 257 | ||
| 259 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); | 258 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); |
| 260 | 259 | ||
| 261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); | 260 | if (adev->uvd.vcpu_bo) { |
| 262 | if (!r) { | 261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); |
| 263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); | 262 | if (!r) { |
| 264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); | 263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); |
| 265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); | 264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); |
| 266 | } | 265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); |
| 266 | } | ||
| 267 | 267 | ||
| 268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); | 268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); |
| 269 | } | ||
| 269 | 270 | ||
| 270 | amdgpu_ring_fini(&adev->uvd.ring); | 271 | amdgpu_ring_fini(&adev->uvd.ring); |
| 271 | 272 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index ea407db1fbcf..5ec1f1e9c983 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
| @@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle) | |||
| 6221 | ci_dpm_fini(adev); | 6221 | ci_dpm_fini(adev); |
| 6222 | mutex_unlock(&adev->pm.mutex); | 6222 | mutex_unlock(&adev->pm.mutex); |
| 6223 | 6223 | ||
| 6224 | release_firmware(adev->pm.fw); | ||
| 6225 | adev->pm.fw = NULL; | ||
| 6226 | |||
| 6224 | return 0; | 6227 | return 0; |
| 6225 | } | 6228 | } |
| 6226 | 6229 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 07bc795a4ca9..910431808542 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
| @@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, | |||
| 962 | return true; | 962 | return true; |
| 963 | } | 963 | } |
| 964 | 964 | ||
| 965 | static u32 cik_get_virtual_caps(struct amdgpu_device *adev) | ||
| 966 | { | ||
| 967 | /* CIK does not support SR-IOV */ | ||
| 968 | return 0; | ||
| 969 | } | ||
| 970 | |||
| 965 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { | 971 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { |
| 966 | {mmGRBM_STATUS, false}, | 972 | {mmGRBM_STATUS, false}, |
| 967 | {mmGB_ADDR_CONFIG, false}, | 973 | {mmGB_ADDR_CONFIG, false}, |
| @@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = | |||
| 2007 | .get_xclk = &cik_get_xclk, | 2013 | .get_xclk = &cik_get_xclk, |
| 2008 | .set_uvd_clocks = &cik_set_uvd_clocks, | 2014 | .set_uvd_clocks = &cik_set_uvd_clocks, |
| 2009 | .set_vce_clocks = &cik_set_vce_clocks, | 2015 | .set_vce_clocks = &cik_set_vce_clocks, |
| 2016 | .get_virtual_caps = &cik_get_virtual_caps, | ||
| 2010 | /* these should be moved to their own ip modules */ | 2017 | /* these should be moved to their own ip modules */ |
| 2011 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | 2018 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, |
| 2012 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, | 2019 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 518dca43b133..9dc4e24e31e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
| @@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); | |||
| 66 | 66 | ||
| 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); | 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); |
| 68 | 68 | ||
| 69 | |||
| 70 | static void cik_sdma_free_microcode(struct amdgpu_device *adev) | ||
| 71 | { | ||
| 72 | int i; | ||
| 73 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 74 | release_firmware(adev->sdma.instance[i].fw); | ||
| 75 | adev->sdma.instance[i].fw = NULL; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 69 | /* | 79 | /* |
| 70 | * sDMA - System DMA | 80 | * sDMA - System DMA |
| 71 | * Starting with CIK, the GPU has new asynchronous | 81 | * Starting with CIK, the GPU has new asynchronous |
| @@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
| 419 | /* Initialize the ring buffer's read and write pointers */ | 429 | /* Initialize the ring buffer's read and write pointers */ |
| 420 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 430 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 421 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 431 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 432 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 433 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 422 | 434 | ||
| 423 | /* set the wb address whether it's enabled or not */ | 435 | /* set the wb address whether it's enabled or not */ |
| 424 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 436 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -446,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
| 446 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 458 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 447 | 459 | ||
| 448 | ring->ready = true; | 460 | ring->ready = true; |
| 461 | } | ||
| 462 | |||
| 463 | cik_sdma_enable(adev, true); | ||
| 449 | 464 | ||
| 465 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 466 | ring = &adev->sdma.instance[i].ring; | ||
| 450 | r = amdgpu_ring_test_ring(ring); | 467 | r = amdgpu_ring_test_ring(ring); |
| 451 | if (r) { | 468 | if (r) { |
| 452 | ring->ready = false; | 469 | ring->ready = false; |
| @@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev) | |||
| 529 | if (r) | 546 | if (r) |
| 530 | return r; | 547 | return r; |
| 531 | 548 | ||
| 532 | /* unhalt the MEs */ | 549 | /* halt the engine before programing */ |
| 533 | cik_sdma_enable(adev, true); | 550 | cik_sdma_enable(adev, false); |
| 534 | 551 | ||
| 535 | /* start the gfx rings and rlc compute queues */ | 552 | /* start the gfx rings and rlc compute queues */ |
| 536 | r = cik_sdma_gfx_resume(adev); | 553 | r = cik_sdma_gfx_resume(adev); |
| @@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle) | |||
| 998 | for (i = 0; i < adev->sdma.num_instances; i++) | 1015 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 999 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1016 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1000 | 1017 | ||
| 1018 | cik_sdma_free_microcode(adev); | ||
| 1001 | return 0; | 1019 | return 0; |
| 1002 | } | 1020 | } |
| 1003 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c index 245cabf06575..ed03b75175d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c | |||
| @@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle) | |||
| 72 | 72 | ||
| 73 | static int fiji_dpm_sw_fini(void *handle) | 73 | static int fiji_dpm_sw_fini(void *handle) |
| 74 | { | 74 | { |
| 75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 76 | |||
| 77 | release_firmware(adev->pm.fw); | ||
| 78 | adev->pm.fw = NULL; | ||
| 79 | |||
| 75 | return 0; | 80 | return 0; |
| 76 | } | 81 | } |
| 77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 7f18a53ab53a..fc8ff4d3ccf8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
| @@ -991,6 +991,22 @@ out: | |||
| 991 | return err; | 991 | return err; |
| 992 | } | 992 | } |
| 993 | 993 | ||
| 994 | static void gfx_v7_0_free_microcode(struct amdgpu_device *adev) | ||
| 995 | { | ||
| 996 | release_firmware(adev->gfx.pfp_fw); | ||
| 997 | adev->gfx.pfp_fw = NULL; | ||
| 998 | release_firmware(adev->gfx.me_fw); | ||
| 999 | adev->gfx.me_fw = NULL; | ||
| 1000 | release_firmware(adev->gfx.ce_fw); | ||
| 1001 | adev->gfx.ce_fw = NULL; | ||
| 1002 | release_firmware(adev->gfx.mec_fw); | ||
| 1003 | adev->gfx.mec_fw = NULL; | ||
| 1004 | release_firmware(adev->gfx.mec2_fw); | ||
| 1005 | adev->gfx.mec2_fw = NULL; | ||
| 1006 | release_firmware(adev->gfx.rlc_fw); | ||
| 1007 | adev->gfx.rlc_fw = NULL; | ||
| 1008 | } | ||
| 1009 | |||
| 994 | /** | 1010 | /** |
| 995 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table | 1011 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table |
| 996 | * | 1012 | * |
| @@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle) | |||
| 4489 | gfx_v7_0_cp_compute_fini(adev); | 4505 | gfx_v7_0_cp_compute_fini(adev); |
| 4490 | gfx_v7_0_rlc_fini(adev); | 4506 | gfx_v7_0_rlc_fini(adev); |
| 4491 | gfx_v7_0_mec_fini(adev); | 4507 | gfx_v7_0_mec_fini(adev); |
| 4508 | gfx_v7_0_free_microcode(adev); | ||
| 4492 | 4509 | ||
| 4493 | return 0; | 4510 | return 0; |
| 4494 | } | 4511 | } |
| @@ -4816,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev, | |||
| 4816 | case 2: | 4833 | case 2: |
| 4817 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 4834 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
| 4818 | ring = &adev->gfx.compute_ring[i]; | 4835 | ring = &adev->gfx.compute_ring[i]; |
| 4819 | if ((ring->me == me_id) & (ring->pipe == pipe_id)) | 4836 | if ((ring->me == me_id) && (ring->pipe == pipe_id)) |
| 4820 | amdgpu_fence_process(ring); | 4837 | amdgpu_fence_process(ring); |
| 4821 | } | 4838 | } |
| 4822 | break; | 4839 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index f19bab68fd83..1a5cbaff1e34 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
| @@ -297,7 +297,8 @@ static const u32 polaris11_golden_common_all[] = | |||
| 297 | static const u32 golden_settings_polaris10_a11[] = | 297 | static const u32 golden_settings_polaris10_a11[] = |
| 298 | { | 298 | { |
| 299 | mmATC_MISC_CG, 0x000c0fc0, 0x000c0200, | 299 | mmATC_MISC_CG, 0x000c0fc0, 0x000c0200, |
| 300 | mmCB_HW_CONTROL, 0xfffdf3cf, 0x00006208, | 300 | mmCB_HW_CONTROL, 0xfffdf3cf, 0x00007208, |
| 301 | mmCB_HW_CONTROL_2, 0, 0x0f000000, | ||
| 301 | mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040, | 302 | mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040, |
| 302 | mmDB_DEBUG2, 0xf00fffff, 0x00000400, | 303 | mmDB_DEBUG2, 0xf00fffff, 0x00000400, |
| 303 | mmPA_SC_ENHANCE, 0xffffffff, 0x20000001, | 304 | mmPA_SC_ENHANCE, 0xffffffff, 0x20000001, |
| @@ -836,6 +837,26 @@ err1: | |||
| 836 | return r; | 837 | return r; |
| 837 | } | 838 | } |
| 838 | 839 | ||
| 840 | |||
| 841 | static void gfx_v8_0_free_microcode(struct amdgpu_device *adev) { | ||
| 842 | release_firmware(adev->gfx.pfp_fw); | ||
| 843 | adev->gfx.pfp_fw = NULL; | ||
| 844 | release_firmware(adev->gfx.me_fw); | ||
| 845 | adev->gfx.me_fw = NULL; | ||
| 846 | release_firmware(adev->gfx.ce_fw); | ||
| 847 | adev->gfx.ce_fw = NULL; | ||
| 848 | release_firmware(adev->gfx.rlc_fw); | ||
| 849 | adev->gfx.rlc_fw = NULL; | ||
| 850 | release_firmware(adev->gfx.mec_fw); | ||
| 851 | adev->gfx.mec_fw = NULL; | ||
| 852 | if ((adev->asic_type != CHIP_STONEY) && | ||
| 853 | (adev->asic_type != CHIP_TOPAZ)) | ||
| 854 | release_firmware(adev->gfx.mec2_fw); | ||
| 855 | adev->gfx.mec2_fw = NULL; | ||
| 856 | |||
| 857 | kfree(adev->gfx.rlc.register_list_format); | ||
| 858 | } | ||
| 859 | |||
| 839 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | 860 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) |
| 840 | { | 861 | { |
| 841 | const char *chip_name; | 862 | const char *chip_name; |
| @@ -1983,7 +2004,7 @@ static int gfx_v8_0_sw_fini(void *handle) | |||
| 1983 | 2004 | ||
| 1984 | gfx_v8_0_rlc_fini(adev); | 2005 | gfx_v8_0_rlc_fini(adev); |
| 1985 | 2006 | ||
| 1986 | kfree(adev->gfx.rlc.register_list_format); | 2007 | gfx_v8_0_free_microcode(adev); |
| 1987 | 2008 | ||
| 1988 | return 0; | 2009 | return 0; |
| 1989 | } | 2010 | } |
| @@ -3974,11 +3995,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) | |||
| 3974 | amdgpu_ring_write(ring, 0x3a00161a); | 3995 | amdgpu_ring_write(ring, 0x3a00161a); |
| 3975 | amdgpu_ring_write(ring, 0x0000002e); | 3996 | amdgpu_ring_write(ring, 0x0000002e); |
| 3976 | break; | 3997 | break; |
| 3977 | case CHIP_TOPAZ: | ||
| 3978 | case CHIP_CARRIZO: | 3998 | case CHIP_CARRIZO: |
| 3979 | amdgpu_ring_write(ring, 0x00000002); | 3999 | amdgpu_ring_write(ring, 0x00000002); |
| 3980 | amdgpu_ring_write(ring, 0x00000000); | 4000 | amdgpu_ring_write(ring, 0x00000000); |
| 3981 | break; | 4001 | break; |
| 4002 | case CHIP_TOPAZ: | ||
| 4003 | amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ? | ||
| 4004 | 0x00000000 : 0x00000002); | ||
| 4005 | amdgpu_ring_write(ring, 0x00000000); | ||
| 4006 | break; | ||
| 3982 | case CHIP_STONEY: | 4007 | case CHIP_STONEY: |
| 3983 | amdgpu_ring_write(ring, 0x00000000); | 4008 | amdgpu_ring_write(ring, 0x00000000); |
| 3984 | amdgpu_ring_write(ring, 0x00000000); | 4009 | amdgpu_ring_write(ring, 0x00000000); |
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c index 460bc8ad37e6..825ccd63f2dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | |||
| @@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle) | |||
| 72 | 72 | ||
| 73 | static int iceland_dpm_sw_fini(void *handle) | 73 | static int iceland_dpm_sw_fini(void *handle) |
| 74 | { | 74 | { |
| 75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 76 | |||
| 77 | release_firmware(adev->pm.fw); | ||
| 78 | adev->pm.fw = NULL; | ||
| 79 | |||
| 75 | return 0; | 80 | return 0; |
| 76 | } | 81 | } |
| 77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index f4c3130d3fdb..b556bd0a8797 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
| @@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev) | |||
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void sdma_v2_4_free_microcode(struct amdgpu_device *adev) | ||
| 109 | { | ||
| 110 | int i; | ||
| 111 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 112 | release_firmware(adev->sdma.instance[i].fw); | ||
| 113 | adev->sdma.instance[i].fw = NULL; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 108 | /** | 117 | /** |
| 109 | * sdma_v2_4_init_microcode - load ucode images from disk | 118 | * sdma_v2_4_init_microcode - load ucode images from disk |
| 110 | * | 119 | * |
| @@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
| 461 | /* Initialize the ring buffer's read and write pointers */ | 470 | /* Initialize the ring buffer's read and write pointers */ |
| 462 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 471 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 463 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 472 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 473 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 474 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 464 | 475 | ||
| 465 | /* set the wb address whether it's enabled or not */ | 476 | /* set the wb address whether it's enabled or not */ |
| 466 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 477 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -489,7 +500,11 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
| 489 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 500 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 490 | 501 | ||
| 491 | ring->ready = true; | 502 | ring->ready = true; |
| 503 | } | ||
| 492 | 504 | ||
| 505 | sdma_v2_4_enable(adev, true); | ||
| 506 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 507 | ring = &adev->sdma.instance[i].ring; | ||
| 493 | r = amdgpu_ring_test_ring(ring); | 508 | r = amdgpu_ring_test_ring(ring); |
| 494 | if (r) { | 509 | if (r) { |
| 495 | ring->ready = false; | 510 | ring->ready = false; |
| @@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) | |||
| 580 | return -EINVAL; | 595 | return -EINVAL; |
| 581 | } | 596 | } |
| 582 | 597 | ||
| 583 | /* unhalt the MEs */ | 598 | /* halt the engine before programing */ |
| 584 | sdma_v2_4_enable(adev, true); | 599 | sdma_v2_4_enable(adev, false); |
| 585 | 600 | ||
| 586 | /* start the gfx rings and rlc compute queues */ | 601 | /* start the gfx rings and rlc compute queues */ |
| 587 | r = sdma_v2_4_gfx_resume(adev); | 602 | r = sdma_v2_4_gfx_resume(adev); |
| @@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle) | |||
| 1012 | for (i = 0; i < adev->sdma.num_instances; i++) | 1027 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1013 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1028 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1014 | 1029 | ||
| 1030 | sdma_v2_4_free_microcode(adev); | ||
| 1015 | return 0; | 1031 | return 0; |
| 1016 | } | 1032 | } |
| 1017 | 1033 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 31d99b0010f7..532ea88da66a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
| @@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev) | |||
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | static void sdma_v3_0_free_microcode(struct amdgpu_device *adev) | ||
| 240 | { | ||
| 241 | int i; | ||
| 242 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 243 | release_firmware(adev->sdma.instance[i].fw); | ||
| 244 | adev->sdma.instance[i].fw = NULL; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 239 | /** | 248 | /** |
| 240 | * sdma_v3_0_init_microcode - load ucode images from disk | 249 | * sdma_v3_0_init_microcode - load ucode images from disk |
| 241 | * | 250 | * |
| @@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
| 672 | /* Initialize the ring buffer's read and write pointers */ | 681 | /* Initialize the ring buffer's read and write pointers */ |
| 673 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 682 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 674 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 683 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 684 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 685 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 675 | 686 | ||
| 676 | /* set the wb address whether it's enabled or not */ | 687 | /* set the wb address whether it's enabled or not */ |
| 677 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 688 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -711,7 +722,15 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
| 711 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 722 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 712 | 723 | ||
| 713 | ring->ready = true; | 724 | ring->ready = true; |
| 725 | } | ||
| 726 | |||
| 727 | /* unhalt the MEs */ | ||
| 728 | sdma_v3_0_enable(adev, true); | ||
| 729 | /* enable sdma ring preemption */ | ||
| 730 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
| 714 | 731 | ||
| 732 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 733 | ring = &adev->sdma.instance[i].ring; | ||
| 715 | r = amdgpu_ring_test_ring(ring); | 734 | r = amdgpu_ring_test_ring(ring); |
| 716 | if (r) { | 735 | if (r) { |
| 717 | ring->ready = false; | 736 | ring->ready = false; |
| @@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) | |||
| 804 | } | 823 | } |
| 805 | } | 824 | } |
| 806 | 825 | ||
| 807 | /* unhalt the MEs */ | 826 | /* disble sdma engine before programing it */ |
| 808 | sdma_v3_0_enable(adev, true); | 827 | sdma_v3_0_ctx_switch_enable(adev, false); |
| 809 | /* enable sdma ring preemption */ | 828 | sdma_v3_0_enable(adev, false); |
| 810 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
| 811 | 829 | ||
| 812 | /* start the gfx rings and rlc compute queues */ | 830 | /* start the gfx rings and rlc compute queues */ |
| 813 | r = sdma_v3_0_gfx_resume(adev); | 831 | r = sdma_v3_0_gfx_resume(adev); |
| @@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle) | |||
| 1247 | for (i = 0; i < adev->sdma.num_instances; i++) | 1265 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1248 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1266 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1249 | 1267 | ||
| 1268 | sdma_v3_0_free_microcode(adev); | ||
| 1250 | return 0; | 1269 | return 0; |
| 1251 | } | 1270 | } |
| 1252 | 1271 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index b7615cefcac4..f06f6f4dc3a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c | |||
| @@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle) | |||
| 71 | 71 | ||
| 72 | static int tonga_dpm_sw_fini(void *handle) | 72 | static int tonga_dpm_sw_fini(void *handle) |
| 73 | { | 73 | { |
| 74 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 75 | |||
| 76 | release_firmware(adev->pm.fw); | ||
| 77 | adev->pm.fw = NULL; | ||
| 78 | |||
| 74 | return 0; | 79 | return 0; |
| 75 | } | 80 | } |
| 76 | 81 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2c88d0b66cf3..a65c96029476 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
| @@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, | |||
| 421 | return true; | 421 | return true; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | static u32 vi_get_virtual_caps(struct amdgpu_device *adev) | ||
| 425 | { | ||
| 426 | u32 caps = 0; | ||
| 427 | u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER); | ||
| 428 | |||
| 429 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE)) | ||
| 430 | caps |= AMDGPU_VIRT_CAPS_SRIOV_EN; | ||
| 431 | |||
| 432 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER)) | ||
| 433 | caps |= AMDGPU_VIRT_CAPS_IS_VF; | ||
| 434 | |||
| 435 | return caps; | ||
| 436 | } | ||
| 437 | |||
| 424 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { | 438 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { |
| 425 | {mmGB_MACROTILE_MODE7, true}, | 439 | {mmGB_MACROTILE_MODE7, true}, |
| 426 | }; | 440 | }; |
| @@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = | |||
| 1118 | .get_xclk = &vi_get_xclk, | 1132 | .get_xclk = &vi_get_xclk, |
| 1119 | .set_uvd_clocks = &vi_set_uvd_clocks, | 1133 | .set_uvd_clocks = &vi_set_uvd_clocks, |
| 1120 | .set_vce_clocks = &vi_set_vce_clocks, | 1134 | .set_vce_clocks = &vi_set_vce_clocks, |
| 1135 | .get_virtual_caps = &vi_get_virtual_caps, | ||
| 1121 | /* these should be moved to their own ip modules */ | 1136 | /* these should be moved to their own ip modules */ |
| 1122 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | 1137 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, |
| 1123 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, | 1138 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ac005796b71c..7708d90b9da9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
| @@ -242,13 +242,19 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, | |||
| 242 | pqm_uninit(&p->pqm); | 242 | pqm_uninit(&p->pqm); |
| 243 | 243 | ||
| 244 | /* Iterate over all process device data structure and check | 244 | /* Iterate over all process device data structure and check |
| 245 | * if we should reset all wavefronts */ | 245 | * if we should delete debug managers and reset all wavefronts |
| 246 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) | 246 | */ |
| 247 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) { | ||
| 248 | if ((pdd->dev->dbgmgr) && | ||
| 249 | (pdd->dev->dbgmgr->pasid == p->pasid)) | ||
| 250 | kfd_dbgmgr_destroy(pdd->dev->dbgmgr); | ||
| 251 | |||
| 247 | if (pdd->reset_wavefronts) { | 252 | if (pdd->reset_wavefronts) { |
| 248 | pr_warn("amdkfd: Resetting all wave fronts\n"); | 253 | pr_warn("amdkfd: Resetting all wave fronts\n"); |
| 249 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 254 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
| 250 | pdd->reset_wavefronts = false; | 255 | pdd->reset_wavefronts = false; |
| 251 | } | 256 | } |
| 257 | } | ||
| 252 | 258 | ||
| 253 | mutex_unlock(&p->mutex); | 259 | mutex_unlock(&p->mutex); |
| 254 | 260 | ||
| @@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) | |||
| 404 | 410 | ||
| 405 | idx = srcu_read_lock(&kfd_processes_srcu); | 411 | idx = srcu_read_lock(&kfd_processes_srcu); |
| 406 | 412 | ||
| 413 | /* | ||
| 414 | * Look for the process that matches the pasid. If there is no such | ||
| 415 | * process, we either released it in amdkfd's own notifier, or there | ||
| 416 | * is a bug. Unfortunately, there is no way to tell... | ||
| 417 | */ | ||
| 407 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) | 418 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) |
| 408 | if (p->pasid == pasid) | 419 | if (p->pasid == pasid) { |
| 409 | break; | ||
| 410 | 420 | ||
| 411 | srcu_read_unlock(&kfd_processes_srcu, idx); | 421 | srcu_read_unlock(&kfd_processes_srcu, idx); |
| 412 | 422 | ||
| 413 | BUG_ON(p->pasid != pasid); | 423 | pr_debug("Unbinding process %d from IOMMU\n", pasid); |
| 414 | 424 | ||
| 415 | mutex_lock(&p->mutex); | 425 | mutex_lock(&p->mutex); |
| 416 | 426 | ||
| 417 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) | 427 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) |
| 418 | kfd_dbgmgr_destroy(dev->dbgmgr); | 428 | kfd_dbgmgr_destroy(dev->dbgmgr); |
| 419 | 429 | ||
| 420 | pqm_uninit(&p->pqm); | 430 | pqm_uninit(&p->pqm); |
| 421 | 431 | ||
| 422 | pdd = kfd_get_process_device_data(dev, p); | 432 | pdd = kfd_get_process_device_data(dev, p); |
| 423 | 433 | ||
| 424 | if (!pdd) { | 434 | if (!pdd) { |
| 425 | mutex_unlock(&p->mutex); | 435 | mutex_unlock(&p->mutex); |
| 426 | return; | 436 | return; |
| 427 | } | 437 | } |
| 428 | 438 | ||
| 429 | if (pdd->reset_wavefronts) { | 439 | if (pdd->reset_wavefronts) { |
| 430 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 440 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
| 431 | pdd->reset_wavefronts = false; | 441 | pdd->reset_wavefronts = false; |
| 432 | } | 442 | } |
| 433 | 443 | ||
| 434 | /* | 444 | /* |
| 435 | * Just mark pdd as unbound, because we still need it to call | 445 | * Just mark pdd as unbound, because we still need it |
| 436 | * amd_iommu_unbind_pasid() in when the process exits. | 446 | * to call amd_iommu_unbind_pasid() in when the |
| 437 | * We don't call amd_iommu_unbind_pasid() here | 447 | * process exits. |
| 438 | * because the IOMMU called us. | 448 | * We don't call amd_iommu_unbind_pasid() here |
| 439 | */ | 449 | * because the IOMMU called us. |
| 440 | pdd->bound = false; | 450 | */ |
| 451 | pdd->bound = false; | ||
| 441 | 452 | ||
| 442 | mutex_unlock(&p->mutex); | 453 | mutex_unlock(&p->mutex); |
| 454 | |||
| 455 | return; | ||
| 456 | } | ||
| 457 | |||
| 458 | srcu_read_unlock(&kfd_processes_srcu, idx); | ||
| 443 | } | 459 | } |
| 444 | 460 | ||
| 445 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) | 461 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 74909e72a009..884c96f50c3d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
| @@ -666,7 +666,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
| 666 | dev->node_props.simd_count); | 666 | dev->node_props.simd_count); |
| 667 | 667 | ||
| 668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { | 668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { |
| 669 | pr_warn("kfd: mem_banks_count truncated from %d to %d\n", | 669 | pr_info_once("kfd: mem_banks_count truncated from %d to %d\n", |
| 670 | dev->node_props.mem_banks_count, | 670 | dev->node_props.mem_banks_count, |
| 671 | dev->mem_bank_count); | 671 | dev->mem_bank_count); |
| 672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", | 672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", |
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 6080951d539d..afce1edbe250 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
| @@ -157,6 +157,7 @@ struct amd_ip_funcs { | |||
| 157 | int (*hw_init)(void *handle); | 157 | int (*hw_init)(void *handle); |
| 158 | /* tears down the hw state */ | 158 | /* tears down the hw state */ |
| 159 | int (*hw_fini)(void *handle); | 159 | int (*hw_fini)(void *handle); |
| 160 | void (*late_fini)(void *handle); | ||
| 160 | /* handles IP specific hw/sw changes for suspend */ | 161 | /* handles IP specific hw/sw changes for suspend */ |
| 161 | int (*suspend)(void *handle); | 162 | int (*suspend)(void *handle); |
| 162 | /* handles IP specific hw/sw changes for resume */ | 163 | /* handles IP specific hw/sw changes for resume */ |
diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h index 32f3e345de08..3493da5c8f0e 100644 --- a/drivers/gpu/drm/amd/include/atombios.h +++ b/drivers/gpu/drm/amd/include/atombios.h | |||
| @@ -5538,6 +5538,78 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V3_5 | |||
| 5538 | ULONG ulReserved[12]; | 5538 | ULONG ulReserved[12]; |
| 5539 | }ATOM_ASIC_PROFILING_INFO_V3_5; | 5539 | }ATOM_ASIC_PROFILING_INFO_V3_5; |
| 5540 | 5540 | ||
| 5541 | /* for Polars10/11 AVFS parameters */ | ||
| 5542 | typedef struct _ATOM_ASIC_PROFILING_INFO_V3_6 | ||
| 5543 | { | ||
| 5544 | ATOM_COMMON_TABLE_HEADER asHeader; | ||
| 5545 | ULONG ulMaxVddc; | ||
| 5546 | ULONG ulMinVddc; | ||
| 5547 | USHORT usLkgEuseIndex; | ||
| 5548 | UCHAR ucLkgEfuseBitLSB; | ||
| 5549 | UCHAR ucLkgEfuseLength; | ||
| 5550 | ULONG ulLkgEncodeLn_MaxDivMin; | ||
| 5551 | ULONG ulLkgEncodeMax; | ||
| 5552 | ULONG ulLkgEncodeMin; | ||
| 5553 | EFUSE_LINEAR_FUNC_PARAM sRoFuse; | ||
| 5554 | ULONG ulEvvDefaultVddc; | ||
| 5555 | ULONG ulEvvNoCalcVddc; | ||
| 5556 | ULONG ulSpeed_Model; | ||
| 5557 | ULONG ulSM_A0; | ||
| 5558 | ULONG ulSM_A1; | ||
| 5559 | ULONG ulSM_A2; | ||
| 5560 | ULONG ulSM_A3; | ||
| 5561 | ULONG ulSM_A4; | ||
| 5562 | ULONG ulSM_A5; | ||
| 5563 | ULONG ulSM_A6; | ||
| 5564 | ULONG ulSM_A7; | ||
| 5565 | UCHAR ucSM_A0_sign; | ||
| 5566 | UCHAR ucSM_A1_sign; | ||
| 5567 | UCHAR ucSM_A2_sign; | ||
| 5568 | UCHAR ucSM_A3_sign; | ||
| 5569 | UCHAR ucSM_A4_sign; | ||
| 5570 | UCHAR ucSM_A5_sign; | ||
| 5571 | UCHAR ucSM_A6_sign; | ||
| 5572 | UCHAR ucSM_A7_sign; | ||
| 5573 | ULONG ulMargin_RO_a; | ||
| 5574 | ULONG ulMargin_RO_b; | ||
| 5575 | ULONG ulMargin_RO_c; | ||
| 5576 | ULONG ulMargin_fixed; | ||
| 5577 | ULONG ulMargin_Fmax_mean; | ||
| 5578 | ULONG ulMargin_plat_mean; | ||
| 5579 | ULONG ulMargin_Fmax_sigma; | ||
| 5580 | ULONG ulMargin_plat_sigma; | ||
| 5581 | ULONG ulMargin_DC_sigma; | ||
| 5582 | ULONG ulLoadLineSlop; | ||
| 5583 | ULONG ulaTDClimitPerDPM[8]; | ||
| 5584 | ULONG ulaNoCalcVddcPerDPM[8]; | ||
| 5585 | ULONG ulAVFS_meanNsigma_Acontant0; | ||
| 5586 | ULONG ulAVFS_meanNsigma_Acontant1; | ||
| 5587 | ULONG ulAVFS_meanNsigma_Acontant2; | ||
| 5588 | USHORT usAVFS_meanNsigma_DC_tol_sigma; | ||
| 5589 | USHORT usAVFS_meanNsigma_Platform_mean; | ||
| 5590 | USHORT usAVFS_meanNsigma_Platform_sigma; | ||
| 5591 | ULONG ulGB_VDROOP_TABLE_CKSOFF_a0; | ||
| 5592 | ULONG ulGB_VDROOP_TABLE_CKSOFF_a1; | ||
| 5593 | ULONG ulGB_VDROOP_TABLE_CKSOFF_a2; | ||
| 5594 | ULONG ulGB_VDROOP_TABLE_CKSON_a0; | ||
| 5595 | ULONG ulGB_VDROOP_TABLE_CKSON_a1; | ||
| 5596 | ULONG ulGB_VDROOP_TABLE_CKSON_a2; | ||
| 5597 | ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_m1; | ||
| 5598 | USHORT usAVFSGB_FUSE_TABLE_CKSOFF_m2; | ||
| 5599 | ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_b; | ||
| 5600 | ULONG ulAVFSGB_FUSE_TABLE_CKSON_m1; | ||
| 5601 | USHORT usAVFSGB_FUSE_TABLE_CKSON_m2; | ||
| 5602 | ULONG ulAVFSGB_FUSE_TABLE_CKSON_b; | ||
| 5603 | USHORT usMaxVoltage_0_25mv; | ||
| 5604 | UCHAR ucEnableGB_VDROOP_TABLE_CKSOFF; | ||
| 5605 | UCHAR ucEnableGB_VDROOP_TABLE_CKSON; | ||
| 5606 | UCHAR ucEnableGB_FUSE_TABLE_CKSOFF; | ||
| 5607 | UCHAR ucEnableGB_FUSE_TABLE_CKSON; | ||
| 5608 | USHORT usPSM_Age_ComFactor; | ||
| 5609 | UCHAR ucEnableApplyAVFS_CKS_OFF_Voltage; | ||
| 5610 | UCHAR ucReserved; | ||
| 5611 | }ATOM_ASIC_PROFILING_INFO_V3_6; | ||
| 5612 | |||
| 5541 | 5613 | ||
| 5542 | typedef struct _ATOM_SCLK_FCW_RANGE_ENTRY_V1{ | 5614 | typedef struct _ATOM_SCLK_FCW_RANGE_ENTRY_V1{ |
| 5543 | ULONG ulMaxSclkFreq; | 5615 | ULONG ulMaxSclkFreq; |
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index a461e155a160..7464daf89ca1 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h | |||
| @@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, | |||
| 581 | enum cgs_ucode_id type, | 581 | enum cgs_ucode_id type, |
| 582 | struct cgs_firmware_info *info); | 582 | struct cgs_firmware_info *info); |
| 583 | 583 | ||
| 584 | typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device, | ||
| 585 | enum cgs_ucode_id type); | ||
| 586 | |||
| 584 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, | 587 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, |
| 585 | enum amd_ip_block_type block_type, | 588 | enum amd_ip_block_type block_type, |
| 586 | enum amd_powergating_state state); | 589 | enum amd_powergating_state state); |
| @@ -645,6 +648,7 @@ struct cgs_ops { | |||
| 645 | cgs_set_camera_voltages_t set_camera_voltages; | 648 | cgs_set_camera_voltages_t set_camera_voltages; |
| 646 | /* Firmware Info */ | 649 | /* Firmware Info */ |
| 647 | cgs_get_firmware_info get_firmware_info; | 650 | cgs_get_firmware_info get_firmware_info; |
| 651 | cgs_rel_firmware rel_firmware; | ||
| 648 | /* cg pg interface*/ | 652 | /* cg pg interface*/ |
| 649 | cgs_set_powergating_state set_powergating_state; | 653 | cgs_set_powergating_state set_powergating_state; |
| 650 | cgs_set_clockgating_state set_clockgating_state; | 654 | cgs_set_clockgating_state set_clockgating_state; |
| @@ -738,6 +742,8 @@ struct cgs_device | |||
| 738 | CGS_CALL(set_camera_voltages,dev,mask,voltages) | 742 | CGS_CALL(set_camera_voltages,dev,mask,voltages) |
| 739 | #define cgs_get_firmware_info(dev, type, info) \ | 743 | #define cgs_get_firmware_info(dev, type, info) \ |
| 740 | CGS_CALL(get_firmware_info, dev, type, info) | 744 | CGS_CALL(get_firmware_info, dev, type, info) |
| 745 | #define cgs_rel_firmware(dev, type) \ | ||
| 746 | CGS_CALL(rel_firmware, dev, type) | ||
| 741 | #define cgs_set_powergating_state(dev, block_type, state) \ | 747 | #define cgs_set_powergating_state(dev, block_type, state) \ |
| 742 | CGS_CALL(set_powergating_state, dev, block_type, state) | 748 | CGS_CALL(set_powergating_state, dev, block_type, state) |
| 743 | #define cgs_set_clockgating_state(dev, block_type, state) \ | 749 | #define cgs_set_clockgating_state(dev, block_type, state) \ |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8e345bfddb69..e629f8a9fe93 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
| @@ -73,11 +73,14 @@ static int pp_sw_init(void *handle) | |||
| 73 | 73 | ||
| 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); | 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); |
| 75 | if (ret) | 75 | if (ret) |
| 76 | goto err; | 76 | goto err1; |
| 77 | 77 | ||
| 78 | pr_info("amdgpu: powerplay initialized\n"); | 78 | pr_info("amdgpu: powerplay initialized\n"); |
| 79 | 79 | ||
| 80 | return 0; | 80 | return 0; |
| 81 | err1: | ||
| 82 | if (hwmgr->pptable_func->pptable_fini) | ||
| 83 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
| 81 | err: | 84 | err: |
| 82 | pr_err("amdgpu: powerplay initialization failed\n"); | 85 | pr_err("amdgpu: powerplay initialization failed\n"); |
| 83 | return ret; | 86 | return ret; |
| @@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle) | |||
| 100 | if (hwmgr->hwmgr_func->backend_fini != NULL) | 103 | if (hwmgr->hwmgr_func->backend_fini != NULL) |
| 101 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); | 104 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); |
| 102 | 105 | ||
| 106 | if (hwmgr->pptable_func->pptable_fini) | ||
| 107 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
| 108 | |||
| 103 | return ret; | 109 | return ret; |
| 104 | } | 110 | } |
| 105 | 111 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index 46410e3c7349..fb88e4e5d625 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | |||
| @@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr) | |||
| 58 | pem_unregister_interrupts(eventmgr); | 58 | pem_unregister_interrupts(eventmgr); |
| 59 | 59 | ||
| 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); | 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); |
| 61 | |||
| 62 | if (eventmgr != NULL) | ||
| 63 | kfree(eventmgr); | ||
| 64 | } | 61 | } |
| 65 | 62 | ||
| 66 | int eventmgr_init(struct pp_instance *handle) | 63 | int eventmgr_init(struct pp_instance *handle) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 24a16e49b571..92912ab20944 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
| @@ -633,6 +633,8 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
| 633 | data->vddci_control = FIJI_VOLTAGE_CONTROL_NONE; | 633 | data->vddci_control = FIJI_VOLTAGE_CONTROL_NONE; |
| 634 | data->mvdd_control = FIJI_VOLTAGE_CONTROL_NONE; | 634 | data->mvdd_control = FIJI_VOLTAGE_CONTROL_NONE; |
| 635 | 635 | ||
| 636 | data->force_pcie_gen = PP_PCIEGenInvalid; | ||
| 637 | |||
| 636 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, | 638 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, |
| 637 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) | 639 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) |
| 638 | data->voltage_control = FIJI_VOLTAGE_CONTROL_BY_SVID2; | 640 | data->voltage_control = FIJI_VOLTAGE_CONTROL_BY_SVID2; |
| @@ -1830,7 +1832,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci) | |||
| 1830 | 1832 | ||
| 1831 | PP_ASSERT_WITH_CODE(false, | 1833 | PP_ASSERT_WITH_CODE(false, |
| 1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 1834 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 1833 | return vddci_table->entries[i].value); | 1835 | return vddci_table->entries[i-1].value); |
| 1834 | } | 1836 | } |
| 1835 | 1837 | ||
| 1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | 1838 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index fa208ada6892..efb77eda7508 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | |||
| @@ -306,10 +306,14 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr, | |||
| 306 | { | 306 | { |
| 307 | PHM_FUNC_CHECK(hwmgr); | 307 | PHM_FUNC_CHECK(hwmgr); |
| 308 | 308 | ||
| 309 | if (hwmgr->hwmgr_func->store_cc6_data == NULL) | 309 | if (display_config == NULL) |
| 310 | return -EINVAL; | 310 | return -EINVAL; |
| 311 | 311 | ||
| 312 | hwmgr->display_config = *display_config; | 312 | hwmgr->display_config = *display_config; |
| 313 | |||
| 314 | if (hwmgr->hwmgr_func->store_cc6_data == NULL) | ||
| 315 | return -EINVAL; | ||
| 316 | |||
| 313 | /* to do pass other display configuration in furture */ | 317 | /* to do pass other display configuration in furture */ |
| 314 | 318 | ||
| 315 | if (hwmgr->hwmgr_func->store_cc6_data) | 319 | if (hwmgr->hwmgr_func->store_cc6_data) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 1c48917da3cf..20f20e075588 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
| @@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) | |||
| 93 | if (hwmgr == NULL || hwmgr->ps == NULL) | 93 | if (hwmgr == NULL || hwmgr->ps == NULL) |
| 94 | return -EINVAL; | 94 | return -EINVAL; |
| 95 | 95 | ||
| 96 | /* do hwmgr finish*/ | ||
| 97 | kfree(hwmgr->backend); | ||
| 98 | |||
| 99 | kfree(hwmgr->start_thermal_controller.function_list); | ||
| 100 | |||
| 101 | kfree(hwmgr->set_temperature_range.function_list); | ||
| 102 | |||
| 96 | kfree(hwmgr->ps); | 103 | kfree(hwmgr->ps); |
| 97 | kfree(hwmgr); | 104 | kfree(hwmgr); |
| 98 | return 0; | 105 | return 0; |
| @@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u | |||
| 462 | 469 | ||
| 463 | PP_ASSERT_WITH_CODE(false, | 470 | PP_ASSERT_WITH_CODE(false, |
| 464 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 471 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 465 | return vddci_table->entries[i].value); | 472 | return vddci_table->entries[i-1].value); |
| 466 | } | 473 | } |
| 467 | 474 | ||
| 468 | int phm_find_boot_level(void *table, | 475 | int phm_find_boot_level(void *table, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h index 347fef127ce9..2930a3355948 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h | |||
| @@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record { | |||
| 39 | uint8_t phases; | 39 | uint8_t phases; |
| 40 | uint8_t cks_enable; | 40 | uint8_t cks_enable; |
| 41 | uint8_t cks_voffset; | 41 | uint8_t cks_voffset; |
| 42 | uint32_t sclk_offset; | ||
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| 44 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; | 45 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index aa6be033f21b..64ee78f7d41e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | |||
| @@ -999,7 +999,7 @@ static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | |||
| 999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), | 999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), |
| 1000 | (dep_table->entries[i].vddc - | 1000 | (dep_table->entries[i].vddc - |
| 1001 | (uint16_t)data->vddc_vddci_delta)); | 1001 | (uint16_t)data->vddc_vddci_delta)); |
| 1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; | 1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) | 1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) |
| @@ -1296,7 +1296,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr, | |||
| 1296 | } | 1296 | } |
| 1297 | 1297 | ||
| 1298 | mem_level->MclkFrequency = clock; | 1298 | mem_level->MclkFrequency = clock; |
| 1299 | mem_level->StutterEnable = 0; | ||
| 1300 | mem_level->EnabledForThrottle = 1; | 1299 | mem_level->EnabledForThrottle = 1; |
| 1301 | mem_level->EnabledForActivity = 0; | 1300 | mem_level->EnabledForActivity = 0; |
| 1302 | mem_level->UpHyst = 0; | 1301 | mem_level->UpHyst = 0; |
| @@ -1304,7 +1303,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr, | |||
| 1304 | mem_level->VoltageDownHyst = 0; | 1303 | mem_level->VoltageDownHyst = 0; |
| 1305 | mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; | 1304 | mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target; |
| 1306 | mem_level->StutterEnable = false; | 1305 | mem_level->StutterEnable = false; |
| 1307 | |||
| 1308 | mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; | 1306 | mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; |
| 1309 | 1307 | ||
| 1310 | data->display_timing.num_existing_displays = info.display_count; | 1308 | data->display_timing.num_existing_displays = info.display_count; |
| @@ -1363,7 +1361,7 @@ static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr) | |||
| 1363 | * a higher state by default such that we are not effected by | 1361 | * a higher state by default such that we are not effected by |
| 1364 | * up threshold or and MCLK DPM latency. | 1362 | * up threshold or and MCLK DPM latency. |
| 1365 | */ | 1363 | */ |
| 1366 | levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target; | 1364 | levels[0].ActivityLevel = 0x1f; |
| 1367 | CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); | 1365 | CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel); |
| 1368 | 1366 | ||
| 1369 | data->smc_state_table.MemoryDpmLevelCount = | 1367 | data->smc_state_table.MemoryDpmLevelCount = |
| @@ -1761,12 +1759,9 @@ static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr) | |||
| 1761 | 1759 | ||
| 1762 | static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) | 1760 | static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) |
| 1763 | { | 1761 | { |
| 1764 | uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks, | 1762 | uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min; |
| 1765 | volt_with_cks, value; | ||
| 1766 | uint16_t clock_freq_u16; | ||
| 1767 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 1763 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
| 1768 | uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2, | 1764 | uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0; |
| 1769 | volt_offset = 0; | ||
| 1770 | struct phm_ppt_v1_information *table_info = | 1765 | struct phm_ppt_v1_information *table_info = |
| 1771 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1766 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
| 1772 | struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = | 1767 | struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = |
| @@ -1778,50 +1773,38 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) | |||
| 1778 | * if the part is SS or FF. if RO >= 1660MHz, part is FF. | 1773 | * if the part is SS or FF. if RO >= 1660MHz, part is FF. |
| 1779 | */ | 1774 | */ |
| 1780 | efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, | 1775 | efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, |
| 1781 | ixSMU_EFUSE_0 + (146 * 4)); | 1776 | ixSMU_EFUSE_0 + (67 * 4)); |
| 1782 | efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
| 1783 | ixSMU_EFUSE_0 + (148 * 4)); | ||
| 1784 | efuse &= 0xFF000000; | 1777 | efuse &= 0xFF000000; |
| 1785 | efuse = efuse >> 24; | 1778 | efuse = efuse >> 24; |
| 1786 | efuse2 &= 0xF; | ||
| 1787 | |||
| 1788 | if (efuse2 == 1) | ||
| 1789 | ro = (2300 - 1350) * efuse / 255 + 1350; | ||
| 1790 | else | ||
| 1791 | ro = (2500 - 1000) * efuse / 255 + 1000; | ||
| 1792 | 1779 | ||
| 1793 | if (ro >= 1660) | 1780 | if (hwmgr->chip_id == CHIP_POLARIS10) { |
| 1794 | type = 0; | 1781 | min = 1000; |
| 1795 | else | 1782 | max = 2300; |
| 1796 | type = 1; | 1783 | } else { |
| 1784 | min = 1100; | ||
| 1785 | max = 2100; | ||
| 1786 | } | ||
| 1797 | 1787 | ||
| 1798 | /* Populate Stretch amount */ | 1788 | ro = efuse * (max -min)/255 + min; |
| 1799 | data->smc_state_table.ClockStretcherAmount = stretch_amount; | ||
| 1800 | 1789 | ||
| 1801 | /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ | 1790 | /* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */ |
| 1802 | for (i = 0; i < sclk_table->count; i++) { | 1791 | for (i = 0; i < sclk_table->count; i++) { |
| 1803 | data->smc_state_table.Sclk_CKS_masterEn0_7 |= | 1792 | data->smc_state_table.Sclk_CKS_masterEn0_7 |= |
| 1804 | sclk_table->entries[i].cks_enable << i; | 1793 | sclk_table->entries[i].cks_enable << i; |
| 1805 | volt_without_cks = (uint32_t)((14041 * | 1794 | |
| 1806 | (sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 / | 1795 | volt_without_cks = (uint32_t)(((ro - 40) * 1000 - 2753594 - sclk_table->entries[i].clk/100 * 136418 /1000) / \ |
| 1807 | (4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000))); | 1796 | (sclk_table->entries[i].clk/100 * 1132925 /10000 - 242418)/100); |
| 1808 | volt_with_cks = (uint32_t)((13946 * | 1797 | |
| 1809 | (sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 / | 1798 | volt_with_cks = (uint32_t)((ro * 1000 -2396351 - sclk_table->entries[i].clk/100 * 329021/1000) / \ |
| 1810 | (3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000))); | 1799 | (sclk_table->entries[i].clk/10000 * 649434 /1000 - 18005)/10); |
| 1800 | |||
| 1811 | if (volt_without_cks >= volt_with_cks) | 1801 | if (volt_without_cks >= volt_with_cks) |
| 1812 | volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + | 1802 | volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks + |
| 1813 | sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); | 1803 | sclk_table->entries[i].cks_voffset) * 100 / 625) + 1); |
| 1804 | |||
| 1814 | data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; | 1805 | data->smc_state_table.Sclk_voltageOffset[i] = volt_offset; |
| 1815 | } | 1806 | } |
| 1816 | 1807 | ||
| 1817 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, | ||
| 1818 | STRETCH_ENABLE, 0x0); | ||
| 1819 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, | ||
| 1820 | masterReset, 0x1); | ||
| 1821 | /* PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, staticEnable, 0x1); */ | ||
| 1822 | PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, | ||
| 1823 | masterReset, 0x0); | ||
| 1824 | |||
| 1825 | /* Populate CKS Lookup Table */ | 1808 | /* Populate CKS Lookup Table */ |
| 1826 | if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) | 1809 | if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5) |
| 1827 | stretch_amount2 = 0; | 1810 | stretch_amount2 = 0; |
| @@ -1835,69 +1818,6 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) | |||
| 1835 | return -EINVAL); | 1818 | return -EINVAL); |
| 1836 | } | 1819 | } |
| 1837 | 1820 | ||
| 1838 | value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
| 1839 | ixPWR_CKS_CNTL); | ||
| 1840 | value &= 0xFFC2FF87; | ||
| 1841 | data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq = | ||
| 1842 | polaris10_clock_stretcher_lookup_table[stretch_amount2][0]; | ||
| 1843 | data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq = | ||
| 1844 | polaris10_clock_stretcher_lookup_table[stretch_amount2][1]; | ||
| 1845 | clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(data->smc_state_table. | ||
| 1846 | GraphicsLevel[data->smc_state_table.GraphicsDpmLevelCount - 1].SclkSetting.SclkFrequency) / 100); | ||
| 1847 | if (polaris10_clock_stretcher_lookup_table[stretch_amount2][0] < clock_freq_u16 | ||
| 1848 | && polaris10_clock_stretcher_lookup_table[stretch_amount2][1] > clock_freq_u16) { | ||
| 1849 | /* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */ | ||
| 1850 | value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 16; | ||
| 1851 | /* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */ | ||
| 1852 | value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][2]) << 18; | ||
| 1853 | /* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */ | ||
| 1854 | value |= (polaris10_clock_stretch_amount_conversion | ||
| 1855 | [polaris10_clock_stretcher_lookup_table[stretch_amount2][3]] | ||
| 1856 | [stretch_amount]) << 3; | ||
| 1857 | } | ||
| 1858 | CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq); | ||
| 1859 | CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq); | ||
| 1860 | data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting = | ||
| 1861 | polaris10_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F; | ||
| 1862 | data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |= | ||
| 1863 | (polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 7; | ||
| 1864 | |||
| 1865 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
| 1866 | ixPWR_CKS_CNTL, value); | ||
| 1867 | |||
| 1868 | /* Populate DDT Lookup Table */ | ||
| 1869 | for (i = 0; i < 4; i++) { | ||
| 1870 | /* Assign the minimum and maximum VID stored | ||
| 1871 | * in the last row of Clock Stretcher Voltage Table. | ||
| 1872 | */ | ||
| 1873 | data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].minVID = | ||
| 1874 | (uint8_t) polaris10_clock_stretcher_ddt_table[type][i][2]; | ||
| 1875 | data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].maxVID = | ||
| 1876 | (uint8_t) polaris10_clock_stretcher_ddt_table[type][i][3]; | ||
| 1877 | /* Loop through each SCLK and check the frequency | ||
| 1878 | * to see if it lies within the frequency for clock stretcher. | ||
| 1879 | */ | ||
| 1880 | for (j = 0; j < data->smc_state_table.GraphicsDpmLevelCount; j++) { | ||
| 1881 | cks_setting = 0; | ||
| 1882 | clock_freq = PP_SMC_TO_HOST_UL( | ||
| 1883 | data->smc_state_table.GraphicsLevel[j].SclkSetting.SclkFrequency); | ||
| 1884 | /* Check the allowed frequency against the sclk level[j]. | ||
| 1885 | * Sclk's endianness has already been converted, | ||
| 1886 | * and it's in 10Khz unit, | ||
| 1887 | * as opposed to Data table, which is in Mhz unit. | ||
| 1888 | */ | ||
| 1889 | if (clock_freq >= (polaris10_clock_stretcher_ddt_table[type][i][0]) * 100) { | ||
| 1890 | cks_setting |= 0x2; | ||
| 1891 | if (clock_freq < (polaris10_clock_stretcher_ddt_table[type][i][1]) * 100) | ||
| 1892 | cks_setting |= 0x1; | ||
| 1893 | } | ||
| 1894 | data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting | ||
| 1895 | |= cks_setting << (j * 2); | ||
| 1896 | } | ||
| 1897 | CONVERT_FROM_HOST_TO_SMC_US( | ||
| 1898 | data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting); | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); | 1821 | value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL); |
| 1902 | value &= 0xFFFFFFFE; | 1822 | value &= 0xFFFFFFFE; |
| 1903 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); | 1823 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value); |
| @@ -1956,6 +1876,90 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr, | |||
| 1956 | return 0; | 1876 | return 0; |
| 1957 | } | 1877 | } |
| 1958 | 1878 | ||
| 1879 | |||
| 1880 | int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) | ||
| 1881 | { | ||
| 1882 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
| 1883 | SMU74_Discrete_DpmTable *table = &(data->smc_state_table); | ||
| 1884 | int result = 0; | ||
| 1885 | struct pp_atom_ctrl__avfs_parameters avfs_params = {0}; | ||
| 1886 | AVFS_meanNsigma_t AVFS_meanNsigma = { {0} }; | ||
| 1887 | AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} }; | ||
| 1888 | uint32_t tmp, i; | ||
| 1889 | struct pp_smumgr *smumgr = hwmgr->smumgr; | ||
| 1890 | struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend); | ||
| 1891 | |||
| 1892 | struct phm_ppt_v1_information *table_info = | ||
| 1893 | (struct phm_ppt_v1_information *)hwmgr->pptable; | ||
| 1894 | struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = | ||
| 1895 | table_info->vdd_dep_on_sclk; | ||
| 1896 | |||
| 1897 | |||
| 1898 | if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) | ||
| 1899 | return result; | ||
| 1900 | |||
| 1901 | result = atomctrl_get_avfs_information(hwmgr, &avfs_params); | ||
| 1902 | |||
| 1903 | if (0 == result) { | ||
| 1904 | table->BTCGB_VDROOP_TABLE[0].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0); | ||
| 1905 | table->BTCGB_VDROOP_TABLE[0].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1); | ||
| 1906 | table->BTCGB_VDROOP_TABLE[0].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2); | ||
| 1907 | table->BTCGB_VDROOP_TABLE[1].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0); | ||
| 1908 | table->BTCGB_VDROOP_TABLE[1].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1); | ||
| 1909 | table->BTCGB_VDROOP_TABLE[1].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2); | ||
| 1910 | table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1); | ||
| 1911 | table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2); | ||
| 1912 | table->AVFSGB_VDROOP_TABLE[0].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b); | ||
| 1913 | table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24; | ||
| 1914 | table->AVFSGB_VDROOP_TABLE[0].m2_shift = 12; | ||
| 1915 | table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1); | ||
| 1916 | table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2); | ||
| 1917 | table->AVFSGB_VDROOP_TABLE[1].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b); | ||
| 1918 | table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24; | ||
| 1919 | table->AVFSGB_VDROOP_TABLE[1].m2_shift = 12; | ||
| 1920 | table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv); | ||
| 1921 | AVFS_meanNsigma.Aconstant[0] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0); | ||
| 1922 | AVFS_meanNsigma.Aconstant[1] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1); | ||
| 1923 | AVFS_meanNsigma.Aconstant[2] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2); | ||
| 1924 | AVFS_meanNsigma.DC_tol_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma); | ||
| 1925 | AVFS_meanNsigma.Platform_mean = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean); | ||
| 1926 | AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor); | ||
| 1927 | AVFS_meanNsigma.Platform_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma); | ||
| 1928 | |||
| 1929 | for (i = 0; i < NUM_VFT_COLUMNS; i++) { | ||
| 1930 | AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625); | ||
| 1931 | AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100); | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | result = polaris10_read_smc_sram_dword(smumgr, | ||
| 1935 | SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma), | ||
| 1936 | &tmp, data->sram_end); | ||
| 1937 | |||
| 1938 | polaris10_copy_bytes_to_smc(smumgr, | ||
| 1939 | tmp, | ||
| 1940 | (uint8_t *)&AVFS_meanNsigma, | ||
| 1941 | sizeof(AVFS_meanNsigma_t), | ||
| 1942 | data->sram_end); | ||
| 1943 | |||
| 1944 | result = polaris10_read_smc_sram_dword(smumgr, | ||
| 1945 | SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable), | ||
| 1946 | &tmp, data->sram_end); | ||
| 1947 | polaris10_copy_bytes_to_smc(smumgr, | ||
| 1948 | tmp, | ||
| 1949 | (uint8_t *)&AVFS_SclkOffset, | ||
| 1950 | sizeof(AVFS_Sclk_Offset_t), | ||
| 1951 | data->sram_end); | ||
| 1952 | |||
| 1953 | data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) | | ||
| 1954 | (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) | | ||
| 1955 | (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) | | ||
| 1956 | (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT); | ||
| 1957 | data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false; | ||
| 1958 | } | ||
| 1959 | return result; | ||
| 1960 | } | ||
| 1961 | |||
| 1962 | |||
| 1959 | /** | 1963 | /** |
| 1960 | * Initializes the SMC table and uploads it | 1964 | * Initializes the SMC table and uploads it |
| 1961 | * | 1965 | * |
| @@ -2056,6 +2060,10 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr) | |||
| 2056 | "Failed to populate Clock Stretcher Data Table!", | 2060 | "Failed to populate Clock Stretcher Data Table!", |
| 2057 | return result); | 2061 | return result); |
| 2058 | } | 2062 | } |
| 2063 | |||
| 2064 | result = polaris10_populate_avfs_parameters(hwmgr); | ||
| 2065 | PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;); | ||
| 2066 | |||
| 2059 | table->CurrSclkPllRange = 0xff; | 2067 | table->CurrSclkPllRange = 0xff; |
| 2060 | table->GraphicsVoltageChangeEnable = 1; | 2068 | table->GraphicsVoltageChangeEnable = 1; |
| 2061 | table->GraphicsThermThrottleEnable = 1; | 2069 | table->GraphicsThermThrottleEnable = 1; |
| @@ -2252,6 +2260,9 @@ static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | |||
| 2252 | static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | 2260 | static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) |
| 2253 | { | 2261 | { |
| 2254 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 2262 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
| 2263 | uint32_t soft_register_value = 0; | ||
| 2264 | uint32_t handshake_disables_offset = data->soft_regs_start | ||
| 2265 | + offsetof(SMU74_SoftRegisters, HandshakeDisables); | ||
| 2255 | 2266 | ||
| 2256 | /* enable SCLK dpm */ | 2267 | /* enable SCLK dpm */ |
| 2257 | if (!data->sclk_dpm_key_disabled) | 2268 | if (!data->sclk_dpm_key_disabled) |
| @@ -2262,6 +2273,12 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | |||
| 2262 | 2273 | ||
| 2263 | /* enable MCLK dpm */ | 2274 | /* enable MCLK dpm */ |
| 2264 | if (0 == data->mclk_dpm_key_disabled) { | 2275 | if (0 == data->mclk_dpm_key_disabled) { |
| 2276 | /* Disable UVD - SMU handshake for MCLK. */ | ||
| 2277 | soft_register_value = cgs_read_ind_register(hwmgr->device, | ||
| 2278 | CGS_IND_REG__SMC, handshake_disables_offset); | ||
| 2279 | soft_register_value |= SMU7_UVD_MCLK_HANDSHAKE_DISABLE; | ||
| 2280 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, | ||
| 2281 | handshake_disables_offset, soft_register_value); | ||
| 2265 | 2282 | ||
| 2266 | PP_ASSERT_WITH_CODE( | 2283 | PP_ASSERT_WITH_CODE( |
| 2267 | (0 == smum_send_msg_to_smc(hwmgr->smumgr, | 2284 | (0 == smum_send_msg_to_smc(hwmgr->smumgr, |
| @@ -2269,7 +2286,6 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | |||
| 2269 | "Failed to enable MCLK DPM during DPM Start Function!", | 2286 | "Failed to enable MCLK DPM during DPM Start Function!", |
| 2270 | return -1); | 2287 | return -1); |
| 2271 | 2288 | ||
| 2272 | |||
| 2273 | PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1); | 2289 | PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1); |
| 2274 | 2290 | ||
| 2275 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x5); | 2291 | cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x5); |
| @@ -2606,6 +2622,7 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr) | |||
| 2606 | 2622 | ||
| 2607 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 2623 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 2608 | PHM_PlatformCaps_FanSpeedInTableIsRPM); | 2624 | PHM_PlatformCaps_FanSpeedInTableIsRPM); |
| 2625 | |||
| 2609 | if (hwmgr->chip_id == CHIP_POLARIS11) | 2626 | if (hwmgr->chip_id == CHIP_POLARIS11) |
| 2610 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 2627 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 2611 | PHM_PlatformCaps_SPLLShutdownSupport); | 2628 | PHM_PlatformCaps_SPLLShutdownSupport); |
| @@ -2938,6 +2955,11 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
| 2938 | data->vddci_control = POLARIS10_VOLTAGE_CONTROL_NONE; | 2955 | data->vddci_control = POLARIS10_VOLTAGE_CONTROL_NONE; |
| 2939 | data->mvdd_control = POLARIS10_VOLTAGE_CONTROL_NONE; | 2956 | data->mvdd_control = POLARIS10_VOLTAGE_CONTROL_NONE; |
| 2940 | 2957 | ||
| 2958 | data->enable_tdc_limit_feature = true; | ||
| 2959 | data->enable_pkg_pwr_tracking_feature = true; | ||
| 2960 | data->force_pcie_gen = PP_PCIEGenInvalid; | ||
| 2961 | data->mclk_stutter_mode_threshold = 40000; | ||
| 2962 | |||
| 2941 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, | 2963 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, |
| 2942 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) | 2964 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) |
| 2943 | data->voltage_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2; | 2965 | data->voltage_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2; |
| @@ -2962,6 +2984,10 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
| 2962 | data->vddci_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2; | 2984 | data->vddci_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2; |
| 2963 | } | 2985 | } |
| 2964 | 2986 | ||
| 2987 | if (table_info->cac_dtp_table->usClockStretchAmount != 0) | ||
| 2988 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
| 2989 | PHM_PlatformCaps_ClockStretcher); | ||
| 2990 | |||
| 2965 | polaris10_set_features_platform_caps(hwmgr); | 2991 | polaris10_set_features_platform_caps(hwmgr); |
| 2966 | 2992 | ||
| 2967 | polaris10_init_dpm_defaults(hwmgr); | 2993 | polaris10_init_dpm_defaults(hwmgr); |
| @@ -3520,10 +3546,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
| 3520 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; | 3546 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; |
| 3521 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = | 3547 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = |
| 3522 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; | 3548 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; |
| 3523 | ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 3549 | PPTable_Generic_SubTable_Header *sclk_dep_table = |
| 3524 | (ATOM_Tonga_SCLK_Dependency_Table *) | 3550 | (PPTable_Generic_SubTable_Header *) |
| 3525 | (((unsigned long)powerplay_table) + | 3551 | (((unsigned long)powerplay_table) + |
| 3526 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 3552 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
| 3553 | |||
| 3527 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 3554 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
| 3528 | (ATOM_Tonga_MCLK_Dependency_Table *) | 3555 | (ATOM_Tonga_MCLK_Dependency_Table *) |
| 3529 | (((unsigned long)powerplay_table) + | 3556 | (((unsigned long)powerplay_table) + |
| @@ -3575,7 +3602,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
| 3575 | /* Performance levels are arranged from low to high. */ | 3602 | /* Performance levels are arranged from low to high. */ |
| 3576 | performance_level->memory_clock = mclk_dep_table->entries | 3603 | performance_level->memory_clock = mclk_dep_table->entries |
| 3577 | [state_entry->ucMemoryClockIndexLow].ulMclk; | 3604 | [state_entry->ucMemoryClockIndexLow].ulMclk; |
| 3578 | performance_level->engine_clock = sclk_dep_table->entries | 3605 | if (sclk_dep_table->ucRevId == 0) |
| 3606 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
| 3607 | [state_entry->ucEngineClockIndexLow].ulSclk; | ||
| 3608 | else if (sclk_dep_table->ucRevId == 1) | ||
| 3609 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
| 3579 | [state_entry->ucEngineClockIndexLow].ulSclk; | 3610 | [state_entry->ucEngineClockIndexLow].ulSclk; |
| 3580 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3611 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
| 3581 | state_entry->ucPCIEGenLow); | 3612 | state_entry->ucPCIEGenLow); |
| @@ -3586,8 +3617,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
| 3586 | [polaris10_power_state->performance_level_count++]); | 3617 | [polaris10_power_state->performance_level_count++]); |
| 3587 | performance_level->memory_clock = mclk_dep_table->entries | 3618 | performance_level->memory_clock = mclk_dep_table->entries |
| 3588 | [state_entry->ucMemoryClockIndexHigh].ulMclk; | 3619 | [state_entry->ucMemoryClockIndexHigh].ulMclk; |
| 3589 | performance_level->engine_clock = sclk_dep_table->entries | 3620 | |
| 3621 | if (sclk_dep_table->ucRevId == 0) | ||
| 3622 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
| 3590 | [state_entry->ucEngineClockIndexHigh].ulSclk; | 3623 | [state_entry->ucEngineClockIndexHigh].ulSclk; |
| 3624 | else if (sclk_dep_table->ucRevId == 1) | ||
| 3625 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
| 3626 | [state_entry->ucEngineClockIndexHigh].ulSclk; | ||
| 3627 | |||
| 3591 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3628 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
| 3592 | state_entry->ucPCIEGenHigh); | 3629 | state_entry->ucPCIEGenHigh); |
| 3593 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, | 3630 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, |
| @@ -3645,7 +3682,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
| 3645 | switch (state->classification.ui_label) { | 3682 | switch (state->classification.ui_label) { |
| 3646 | case PP_StateUILabel_Performance: | 3683 | case PP_StateUILabel_Performance: |
| 3647 | data->use_pcie_performance_levels = true; | 3684 | data->use_pcie_performance_levels = true; |
| 3648 | |||
| 3649 | for (i = 0; i < ps->performance_level_count; i++) { | 3685 | for (i = 0; i < ps->performance_level_count; i++) { |
| 3650 | if (data->pcie_gen_performance.max < | 3686 | if (data->pcie_gen_performance.max < |
| 3651 | ps->performance_levels[i].pcie_gen) | 3687 | ps->performance_levels[i].pcie_gen) |
| @@ -3661,7 +3697,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
| 3661 | ps->performance_levels[i].pcie_lane) | 3697 | ps->performance_levels[i].pcie_lane) |
| 3662 | data->pcie_lane_performance.max = | 3698 | data->pcie_lane_performance.max = |
| 3663 | ps->performance_levels[i].pcie_lane; | 3699 | ps->performance_levels[i].pcie_lane; |
| 3664 | |||
| 3665 | if (data->pcie_lane_performance.min > | 3700 | if (data->pcie_lane_performance.min > |
| 3666 | ps->performance_levels[i].pcie_lane) | 3701 | ps->performance_levels[i].pcie_lane) |
| 3667 | data->pcie_lane_performance.min = | 3702 | data->pcie_lane_performance.min = |
| @@ -4187,12 +4222,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) | |||
| 4187 | { | 4222 | { |
| 4188 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 4223 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
| 4189 | uint32_t mm_boot_level_offset, mm_boot_level_value; | 4224 | uint32_t mm_boot_level_offset, mm_boot_level_value; |
| 4190 | struct phm_ppt_v1_information *table_info = | ||
| 4191 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
| 4192 | 4225 | ||
| 4193 | if (!bgate) { | 4226 | if (!bgate) { |
| 4194 | data->smc_state_table.SamuBootLevel = | 4227 | data->smc_state_table.SamuBootLevel = 0; |
| 4195 | (uint8_t) (table_info->mm_dep_table->count - 1); | ||
| 4196 | mm_boot_level_offset = data->dpm_table_start + | 4228 | mm_boot_level_offset = data->dpm_table_start + |
| 4197 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); | 4229 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); |
| 4198 | mm_boot_level_offset /= 4; | 4230 | mm_boot_level_offset /= 4; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h index beedf35cbfa6..d717789441f5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.h | |||
| @@ -312,6 +312,9 @@ struct polaris10_hwmgr { | |||
| 312 | 312 | ||
| 313 | /* soft pptable for re-uploading into smu */ | 313 | /* soft pptable for re-uploading into smu */ |
| 314 | void *soft_pp_table; | 314 | void *soft_pp_table; |
| 315 | |||
| 316 | uint32_t avfs_vdroop_override_setting; | ||
| 317 | bool apply_avfs_cks_off_voltage; | ||
| 315 | }; | 318 | }; |
| 316 | 319 | ||
| 317 | /* To convert to Q8.8 format for firmware */ | 320 | /* To convert to Q8.8 format for firmware */ |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c index 0b99ab3ba0c5..ae96f14b827c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c | |||
| @@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) | |||
| 286 | 286 | ||
| 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, | 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, |
| 288 | (uint8_t *)&data->power_tune_table, | 288 | (uint8_t *)&data->power_tune_table, |
| 289 | sizeof(struct SMU74_Discrete_PmFuses), data->sram_end)) | 289 | (sizeof(struct SMU74_Discrete_PmFuses) - 92), data->sram_end)) |
| 290 | PP_ASSERT_WITH_CODE(false, | 290 | PP_ASSERT_WITH_CODE(false, |
| 291 | "Attempt to download PmFuseTable Failed!", | 291 | "Attempt to download PmFuseTable Failed!", |
| 292 | return -EINVAL); | 292 | return -EINVAL); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c index aba167f7d167..b206632d4650 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_thermal.c | |||
| @@ -625,10 +625,14 @@ static int tf_polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr, | |||
| 625 | int ret; | 625 | int ret; |
| 626 | struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr); | 626 | struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr); |
| 627 | struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend); | 627 | struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend); |
| 628 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | ||
| 628 | 629 | ||
| 629 | if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS) | 630 | if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED) |
| 630 | return 0; | 631 | return 0; |
| 631 | 632 | ||
| 633 | ret = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | ||
| 634 | PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting); | ||
| 635 | |||
| 632 | ret = (smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs) == 0) ? | 636 | ret = (smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs) == 0) ? |
| 633 | 0 : -1; | 637 | 0 : -1; |
| 634 | 638 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c index 58742e0d1492..a3c38bbd1e94 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c | |||
| @@ -44,6 +44,20 @@ bool acpi_atcs_functions_supported(void *device, uint32_t index) | |||
| 44 | return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false; | 44 | return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | bool acpi_atcs_notify_pcie_device_ready(void *device) | ||
| 48 | { | ||
| 49 | int32_t temp_buffer = 1; | ||
| 50 | |||
| 51 | return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS, | ||
| 52 | ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, | ||
| 53 | &temp_buffer, | ||
| 54 | NULL, | ||
| 55 | 0, | ||
| 56 | sizeof(temp_buffer), | ||
| 57 | 0); | ||
| 58 | } | ||
| 59 | |||
| 60 | |||
| 47 | int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise) | 61 | int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise) |
| 48 | { | 62 | { |
| 49 | struct atcs_pref_req_input atcs_input; | 63 | struct atcs_pref_req_input atcs_input; |
| @@ -52,7 +66,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise) | |||
| 52 | int result; | 66 | int result; |
| 53 | struct cgs_system_info info = {0}; | 67 | struct cgs_system_info info = {0}; |
| 54 | 68 | ||
| 55 | if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST)) | 69 | if( 0 != acpi_atcs_notify_pcie_device_ready(device)) |
| 56 | return -EINVAL; | 70 | return -EINVAL; |
| 57 | 71 | ||
| 58 | info.size = sizeof(struct cgs_system_info); | 72 | info.size = sizeof(struct cgs_system_info); |
| @@ -77,7 +91,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise) | |||
| 77 | ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, | 91 | ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, |
| 78 | &atcs_input, | 92 | &atcs_input, |
| 79 | &atcs_output, | 93 | &atcs_output, |
| 80 | 0, | 94 | 1, |
| 81 | sizeof(atcs_input), | 95 | sizeof(atcs_input), |
| 82 | sizeof(atcs_output)); | 96 | sizeof(atcs_output)); |
| 83 | if (result != 0) | 97 | if (result != 0) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c index da9f5f1b6dc2..bf4e18fd3872 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c | |||
| @@ -1302,3 +1302,46 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr | |||
| 1302 | 1302 | ||
| 1303 | return 0; | 1303 | return 0; |
| 1304 | } | 1304 | } |
| 1305 | |||
| 1306 | int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param) | ||
| 1307 | { | ||
| 1308 | ATOM_ASIC_PROFILING_INFO_V3_6 *profile = NULL; | ||
| 1309 | |||
| 1310 | if (param == NULL) | ||
| 1311 | return -EINVAL; | ||
| 1312 | |||
| 1313 | profile = (ATOM_ASIC_PROFILING_INFO_V3_6 *) | ||
| 1314 | cgs_atom_get_data_table(hwmgr->device, | ||
| 1315 | GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo), | ||
| 1316 | NULL, NULL, NULL); | ||
| 1317 | if (!profile) | ||
| 1318 | return -1; | ||
| 1319 | |||
| 1320 | param->ulAVFS_meanNsigma_Acontant0 = profile->ulAVFS_meanNsigma_Acontant0; | ||
| 1321 | param->ulAVFS_meanNsigma_Acontant1 = profile->ulAVFS_meanNsigma_Acontant1; | ||
| 1322 | param->ulAVFS_meanNsigma_Acontant2 = profile->ulAVFS_meanNsigma_Acontant2; | ||
| 1323 | param->usAVFS_meanNsigma_DC_tol_sigma = profile->usAVFS_meanNsigma_DC_tol_sigma; | ||
| 1324 | param->usAVFS_meanNsigma_Platform_mean = profile->usAVFS_meanNsigma_Platform_mean; | ||
| 1325 | param->usAVFS_meanNsigma_Platform_sigma = profile->usAVFS_meanNsigma_Platform_sigma; | ||
| 1326 | param->ulGB_VDROOP_TABLE_CKSOFF_a0 = profile->ulGB_VDROOP_TABLE_CKSOFF_a0; | ||
| 1327 | param->ulGB_VDROOP_TABLE_CKSOFF_a1 = profile->ulGB_VDROOP_TABLE_CKSOFF_a1; | ||
| 1328 | param->ulGB_VDROOP_TABLE_CKSOFF_a2 = profile->ulGB_VDROOP_TABLE_CKSOFF_a2; | ||
| 1329 | param->ulGB_VDROOP_TABLE_CKSON_a0 = profile->ulGB_VDROOP_TABLE_CKSON_a0; | ||
| 1330 | param->ulGB_VDROOP_TABLE_CKSON_a1 = profile->ulGB_VDROOP_TABLE_CKSON_a1; | ||
| 1331 | param->ulGB_VDROOP_TABLE_CKSON_a2 = profile->ulGB_VDROOP_TABLE_CKSON_a2; | ||
| 1332 | param->ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_m1; | ||
| 1333 | param->usAVFSGB_FUSE_TABLE_CKSOFF_m2 = profile->usAVFSGB_FUSE_TABLE_CKSOFF_m2; | ||
| 1334 | param->ulAVFSGB_FUSE_TABLE_CKSOFF_b = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_b; | ||
| 1335 | param->ulAVFSGB_FUSE_TABLE_CKSON_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSON_m1; | ||
| 1336 | param->usAVFSGB_FUSE_TABLE_CKSON_m2 = profile->usAVFSGB_FUSE_TABLE_CKSON_m2; | ||
| 1337 | param->ulAVFSGB_FUSE_TABLE_CKSON_b = profile->ulAVFSGB_FUSE_TABLE_CKSON_b; | ||
| 1338 | param->usMaxVoltage_0_25mv = profile->usMaxVoltage_0_25mv; | ||
| 1339 | param->ucEnableGB_VDROOP_TABLE_CKSOFF = profile->ucEnableGB_VDROOP_TABLE_CKSOFF; | ||
| 1340 | param->ucEnableGB_VDROOP_TABLE_CKSON = profile->ucEnableGB_VDROOP_TABLE_CKSON; | ||
| 1341 | param->ucEnableGB_FUSE_TABLE_CKSOFF = profile->ucEnableGB_FUSE_TABLE_CKSOFF; | ||
| 1342 | param->ucEnableGB_FUSE_TABLE_CKSON = profile->ucEnableGB_FUSE_TABLE_CKSON; | ||
| 1343 | param->usPSM_Age_ComFactor = profile->usPSM_Age_ComFactor; | ||
| 1344 | param->ucEnableApplyAVFS_CKS_OFF_Voltage = profile->ucEnableApplyAVFS_CKS_OFF_Voltage; | ||
| 1345 | |||
| 1346 | return 0; | ||
| 1347 | } | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h index d24ebb566905..248c5db5f380 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.h | |||
| @@ -250,6 +250,35 @@ struct pp_atomctrl_gpio_pin_assignment { | |||
| 250 | }; | 250 | }; |
| 251 | typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment; | 251 | typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment; |
| 252 | 252 | ||
| 253 | struct pp_atom_ctrl__avfs_parameters { | ||
| 254 | uint32_t ulAVFS_meanNsigma_Acontant0; | ||
| 255 | uint32_t ulAVFS_meanNsigma_Acontant1; | ||
| 256 | uint32_t ulAVFS_meanNsigma_Acontant2; | ||
| 257 | uint16_t usAVFS_meanNsigma_DC_tol_sigma; | ||
| 258 | uint16_t usAVFS_meanNsigma_Platform_mean; | ||
| 259 | uint16_t usAVFS_meanNsigma_Platform_sigma; | ||
| 260 | uint32_t ulGB_VDROOP_TABLE_CKSOFF_a0; | ||
| 261 | uint32_t ulGB_VDROOP_TABLE_CKSOFF_a1; | ||
| 262 | uint32_t ulGB_VDROOP_TABLE_CKSOFF_a2; | ||
| 263 | uint32_t ulGB_VDROOP_TABLE_CKSON_a0; | ||
| 264 | uint32_t ulGB_VDROOP_TABLE_CKSON_a1; | ||
| 265 | uint32_t ulGB_VDROOP_TABLE_CKSON_a2; | ||
| 266 | uint32_t ulAVFSGB_FUSE_TABLE_CKSOFF_m1; | ||
| 267 | uint16_t usAVFSGB_FUSE_TABLE_CKSOFF_m2; | ||
| 268 | uint32_t ulAVFSGB_FUSE_TABLE_CKSOFF_b; | ||
| 269 | uint32_t ulAVFSGB_FUSE_TABLE_CKSON_m1; | ||
| 270 | uint16_t usAVFSGB_FUSE_TABLE_CKSON_m2; | ||
| 271 | uint32_t ulAVFSGB_FUSE_TABLE_CKSON_b; | ||
| 272 | uint16_t usMaxVoltage_0_25mv; | ||
| 273 | uint8_t ucEnableGB_VDROOP_TABLE_CKSOFF; | ||
| 274 | uint8_t ucEnableGB_VDROOP_TABLE_CKSON; | ||
| 275 | uint8_t ucEnableGB_FUSE_TABLE_CKSOFF; | ||
| 276 | uint8_t ucEnableGB_FUSE_TABLE_CKSON; | ||
| 277 | uint16_t usPSM_Age_ComFactor; | ||
| 278 | uint8_t ucEnableApplyAVFS_CKS_OFF_Voltage; | ||
| 279 | uint8_t ucReserved; | ||
| 280 | }; | ||
| 281 | |||
| 253 | extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment); | 282 | extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment); |
| 254 | extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage); | 283 | extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage); |
| 255 | extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr); | 284 | extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr); |
| @@ -278,5 +307,8 @@ extern int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clo | |||
| 278 | extern int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type, | 307 | extern int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type, |
| 279 | uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage); | 308 | uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage); |
| 280 | extern int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl_sclk_range_table *table); | 309 | extern int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl_sclk_range_table *table); |
| 310 | |||
| 311 | extern int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param); | ||
| 312 | |||
| 281 | #endif | 313 | #endif |
| 282 | 314 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 16fed487973b..233eb7f36c1d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
| @@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | |||
| 2847 | } | 2847 | } |
| 2848 | } | 2848 | } |
| 2849 | 2849 | ||
| 2850 | /* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */ | ||
| 2851 | for (i = 0; i < allowed_vdd_sclk_table->count; i++) { | ||
| 2852 | data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc; | ||
| 2853 | /* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */ | ||
| 2854 | /* param1 is for corresponding std voltage */ | ||
| 2855 | data->dpm_table.vddc_table.dpm_levels[i].enabled = 1; | ||
| 2856 | } | ||
| 2857 | data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count; | ||
| 2858 | |||
| 2859 | if (NULL != allowed_vdd_mclk_table) { | ||
| 2860 | /* Initialize Vddci DPM table based on allow Mclk values */ | ||
| 2861 | for (i = 0; i < allowed_vdd_mclk_table->count; i++) { | ||
| 2862 | data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci; | ||
| 2863 | data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1; | ||
| 2864 | data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd; | ||
| 2865 | data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1; | ||
| 2866 | } | ||
| 2867 | data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count; | ||
| 2868 | data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count; | ||
| 2869 | } | ||
| 2870 | |||
| 2871 | /* setup PCIE gen speed levels*/ | 2850 | /* setup PCIE gen speed levels*/ |
| 2872 | tonga_setup_default_pcie_tables(hwmgr); | 2851 | tonga_setup_default_pcie_tables(hwmgr); |
| 2873 | 2852 | ||
| @@ -4510,6 +4489,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | |||
| 4510 | data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_NONE; | 4489 | data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_NONE; |
| 4511 | data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_NONE; | 4490 | data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_NONE; |
| 4512 | data->mvdd_control = TONGA_VOLTAGE_CONTROL_NONE; | 4491 | data->mvdd_control = TONGA_VOLTAGE_CONTROL_NONE; |
| 4492 | data->force_pcie_gen = PP_PCIEGenInvalid; | ||
| 4513 | 4493 | ||
| 4514 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, | 4494 | if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr, |
| 4515 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) { | 4495 | VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) { |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h index 1b44f4e9b8f5..f127198aafc4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h | |||
| @@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table { | |||
| 197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | 197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ |
| 198 | } ATOM_Tonga_SCLK_Dependency_Table; | 198 | } ATOM_Tonga_SCLK_Dependency_Table; |
| 199 | 199 | ||
| 200 | typedef struct _ATOM_Polaris_SCLK_Dependency_Record { | ||
| 201 | UCHAR ucVddInd; /* Base voltage */ | ||
| 202 | USHORT usVddcOffset; /* Offset relative to base voltage */ | ||
| 203 | ULONG ulSclk; | ||
| 204 | USHORT usEdcCurrent; | ||
| 205 | UCHAR ucReliabilityTemperature; | ||
| 206 | UCHAR ucCKSVOffsetandDisable; /* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */ | ||
| 207 | ULONG ulSclkOffset; | ||
| 208 | } ATOM_Polaris_SCLK_Dependency_Record; | ||
| 209 | |||
| 210 | typedef struct _ATOM_Polaris_SCLK_Dependency_Table { | ||
| 211 | UCHAR ucRevId; | ||
| 212 | UCHAR ucNumEntries; /* Number of entries. */ | ||
| 213 | ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | ||
| 214 | } ATOM_Polaris_SCLK_Dependency_Table; | ||
| 215 | |||
| 200 | typedef struct _ATOM_Tonga_PCIE_Record { | 216 | typedef struct _ATOM_Tonga_PCIE_Record { |
| 201 | UCHAR ucPCIEGenSpeed; | 217 | UCHAR ucPCIEGenSpeed; |
| 202 | UCHAR usPCIELaneWidth; | 218 | UCHAR usPCIELaneWidth; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 10e3630ee39d..671fdb4d615a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | |||
| @@ -408,41 +408,78 @@ static int get_mclk_voltage_dependency_table( | |||
| 408 | static int get_sclk_voltage_dependency_table( | 408 | static int get_sclk_voltage_dependency_table( |
| 409 | struct pp_hwmgr *hwmgr, | 409 | struct pp_hwmgr *hwmgr, |
| 410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, | 410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, |
| 411 | const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table | 411 | const PPTable_Generic_SubTable_Header *sclk_dep_table |
| 412 | ) | 412 | ) |
| 413 | { | 413 | { |
| 414 | uint32_t table_size, i; | 414 | uint32_t table_size, i; |
| 415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; | 415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; |
| 416 | 416 | ||
| 417 | PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries), | 417 | if (sclk_dep_table->ucRevId < 1) { |
| 418 | "Invalid PowerPlay Table!", return -1); | 418 | const ATOM_Tonga_SCLK_Dependency_Table *tonga_table = |
| 419 | (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table; | ||
| 419 | 420 | ||
| 420 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | 421 | PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries), |
| 421 | * sclk_dep_table->ucNumEntries; | 422 | "Invalid PowerPlay Table!", return -1); |
| 422 | 423 | ||
| 423 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | 424 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) |
| 424 | kzalloc(table_size, GFP_KERNEL); | 425 | * tonga_table->ucNumEntries; |
| 425 | 426 | ||
| 426 | if (NULL == sclk_table) | 427 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) |
| 427 | return -ENOMEM; | 428 | kzalloc(table_size, GFP_KERNEL); |
| 428 | 429 | ||
| 429 | memset(sclk_table, 0x00, table_size); | 430 | if (NULL == sclk_table) |
| 430 | 431 | return -ENOMEM; | |
| 431 | sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries; | 432 | |
| 432 | 433 | memset(sclk_table, 0x00, table_size); | |
| 433 | for (i = 0; i < sclk_dep_table->ucNumEntries; i++) { | 434 | |
| 434 | sclk_table->entries[i].vddInd = | 435 | sclk_table->count = (uint32_t)tonga_table->ucNumEntries; |
| 435 | sclk_dep_table->entries[i].ucVddInd; | 436 | |
| 436 | sclk_table->entries[i].vdd_offset = | 437 | for (i = 0; i < tonga_table->ucNumEntries; i++) { |
| 437 | sclk_dep_table->entries[i].usVddcOffset; | 438 | sclk_table->entries[i].vddInd = |
| 438 | sclk_table->entries[i].clk = | 439 | tonga_table->entries[i].ucVddInd; |
| 439 | sclk_dep_table->entries[i].ulSclk; | 440 | sclk_table->entries[i].vdd_offset = |
| 440 | sclk_table->entries[i].cks_enable = | 441 | tonga_table->entries[i].usVddcOffset; |
| 441 | (((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | 442 | sclk_table->entries[i].clk = |
| 442 | sclk_table->entries[i].cks_voffset = | 443 | tonga_table->entries[i].ulSclk; |
| 443 | (sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | 444 | sclk_table->entries[i].cks_enable = |
| 444 | } | 445 | (((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; |
| 446 | sclk_table->entries[i].cks_voffset = | ||
| 447 | (tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
| 448 | } | ||
| 449 | } else { | ||
| 450 | const ATOM_Polaris_SCLK_Dependency_Table *polaris_table = | ||
| 451 | (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table; | ||
| 452 | |||
| 453 | PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries), | ||
| 454 | "Invalid PowerPlay Table!", return -1); | ||
| 455 | |||
| 456 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | ||
| 457 | * polaris_table->ucNumEntries; | ||
| 458 | |||
| 459 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | ||
| 460 | kzalloc(table_size, GFP_KERNEL); | ||
| 445 | 461 | ||
| 462 | if (NULL == sclk_table) | ||
| 463 | return -ENOMEM; | ||
| 464 | |||
| 465 | memset(sclk_table, 0x00, table_size); | ||
| 466 | |||
| 467 | sclk_table->count = (uint32_t)polaris_table->ucNumEntries; | ||
| 468 | |||
| 469 | for (i = 0; i < polaris_table->ucNumEntries; i++) { | ||
| 470 | sclk_table->entries[i].vddInd = | ||
| 471 | polaris_table->entries[i].ucVddInd; | ||
| 472 | sclk_table->entries[i].vdd_offset = | ||
| 473 | polaris_table->entries[i].usVddcOffset; | ||
| 474 | sclk_table->entries[i].clk = | ||
| 475 | polaris_table->entries[i].ulSclk; | ||
| 476 | sclk_table->entries[i].cks_enable = | ||
| 477 | (((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | ||
| 478 | sclk_table->entries[i].cks_voffset = | ||
| 479 | (polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
| 480 | sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset; | ||
| 481 | } | ||
| 482 | } | ||
| 446 | *pp_tonga_sclk_dep_table = sclk_table; | 483 | *pp_tonga_sclk_dep_table = sclk_table; |
| 447 | 484 | ||
| 448 | return 0; | 485 | return 0; |
| @@ -708,8 +745,8 @@ static int init_clock_voltage_dependency( | |||
| 708 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 745 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
| 709 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 746 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + |
| 710 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); | 747 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); |
| 711 | const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 748 | const PPTable_Generic_SubTable_Header *sclk_dep_table = |
| 712 | (const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 749 | (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) + |
| 713 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 750 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
| 714 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = | 751 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = |
| 715 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + | 752 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + |
| @@ -1040,48 +1077,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | |||
| 1040 | struct phm_ppt_v1_information *pp_table_information = | 1077 | struct phm_ppt_v1_information *pp_table_information = |
| 1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1078 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
| 1042 | 1079 | ||
| 1043 | if (NULL != hwmgr->soft_pp_table) { | 1080 | if (NULL != hwmgr->soft_pp_table) |
| 1044 | kfree(hwmgr->soft_pp_table); | ||
| 1045 | hwmgr->soft_pp_table = NULL; | 1081 | hwmgr->soft_pp_table = NULL; |
| 1046 | } | ||
| 1047 | 1082 | ||
| 1048 | if (NULL != pp_table_information->vdd_dep_on_sclk) | 1083 | kfree(pp_table_information->vdd_dep_on_sclk); |
| 1049 | pp_table_information->vdd_dep_on_sclk = NULL; | 1084 | pp_table_information->vdd_dep_on_sclk = NULL; |
| 1050 | 1085 | ||
| 1051 | if (NULL != pp_table_information->vdd_dep_on_mclk) | 1086 | kfree(pp_table_information->vdd_dep_on_mclk); |
| 1052 | pp_table_information->vdd_dep_on_mclk = NULL; | 1087 | pp_table_information->vdd_dep_on_mclk = NULL; |
| 1053 | 1088 | ||
| 1054 | if (NULL != pp_table_information->valid_mclk_values) | 1089 | kfree(pp_table_information->valid_mclk_values); |
| 1055 | pp_table_information->valid_mclk_values = NULL; | 1090 | pp_table_information->valid_mclk_values = NULL; |
| 1056 | 1091 | ||
| 1057 | if (NULL != pp_table_information->valid_sclk_values) | 1092 | kfree(pp_table_information->valid_sclk_values); |
| 1058 | pp_table_information->valid_sclk_values = NULL; | 1093 | pp_table_information->valid_sclk_values = NULL; |
| 1059 | 1094 | ||
| 1060 | if (NULL != pp_table_information->vddc_lookup_table) | 1095 | kfree(pp_table_information->vddc_lookup_table); |
| 1061 | pp_table_information->vddc_lookup_table = NULL; | 1096 | pp_table_information->vddc_lookup_table = NULL; |
| 1062 | 1097 | ||
| 1063 | if (NULL != pp_table_information->vddgfx_lookup_table) | 1098 | kfree(pp_table_information->vddgfx_lookup_table); |
| 1064 | pp_table_information->vddgfx_lookup_table = NULL; | 1099 | pp_table_information->vddgfx_lookup_table = NULL; |
| 1065 | 1100 | ||
| 1066 | if (NULL != pp_table_information->mm_dep_table) | 1101 | kfree(pp_table_information->mm_dep_table); |
| 1067 | pp_table_information->mm_dep_table = NULL; | 1102 | pp_table_information->mm_dep_table = NULL; |
| 1068 | 1103 | ||
| 1069 | if (NULL != pp_table_information->cac_dtp_table) | 1104 | kfree(pp_table_information->cac_dtp_table); |
| 1070 | pp_table_information->cac_dtp_table = NULL; | 1105 | pp_table_information->cac_dtp_table = NULL; |
| 1071 | 1106 | ||
| 1072 | if (NULL != hwmgr->dyn_state.cac_dtp_table) | 1107 | kfree(hwmgr->dyn_state.cac_dtp_table); |
| 1073 | hwmgr->dyn_state.cac_dtp_table = NULL; | 1108 | hwmgr->dyn_state.cac_dtp_table = NULL; |
| 1074 | 1109 | ||
| 1075 | if (NULL != pp_table_information->ppm_parameter_table) | 1110 | kfree(pp_table_information->ppm_parameter_table); |
| 1076 | pp_table_information->ppm_parameter_table = NULL; | 1111 | pp_table_information->ppm_parameter_table = NULL; |
| 1077 | 1112 | ||
| 1078 | if (NULL != pp_table_information->pcie_table) | 1113 | kfree(pp_table_information->pcie_table); |
| 1079 | pp_table_information->pcie_table = NULL; | 1114 | pp_table_information->pcie_table = NULL; |
| 1080 | 1115 | ||
| 1081 | if (NULL != hwmgr->pptable) { | 1116 | kfree(hwmgr->pptable); |
| 1082 | kfree(hwmgr->pptable); | 1117 | hwmgr->pptable = NULL; |
| 1083 | hwmgr->pptable = NULL; | ||
| 1084 | } | ||
| 1085 | 1118 | ||
| 1086 | return result; | 1119 | return result; |
| 1087 | } | 1120 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/polaris10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/polaris10_ppsmc.h index 0c6a413eaa5b..d41d37ab5b7c 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/polaris10_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/polaris10_ppsmc.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #pragma pack(push, 1) | 28 | #pragma pack(push, 1) |
| 29 | 29 | ||
| 30 | #define PPSMC_MSG_SetGBDroopSettings ((uint16_t) 0x305) | ||
| 30 | 31 | ||
| 31 | #define PPSMC_SWSTATE_FLAG_DC 0x01 | 32 | #define PPSMC_SWSTATE_FLAG_DC 0x01 |
| 32 | #define PPSMC_SWSTATE_FLAG_UVD 0x02 | 33 | #define PPSMC_SWSTATE_FLAG_UVD 0x02 |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h b/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h index 3bd5e69b9045..3df5de2cdab0 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h | |||
| @@ -26,3 +26,4 @@ extern bool acpi_atcs_functions_supported(void *device, | |||
| 26 | extern int acpi_pcie_perf_request(void *device, | 26 | extern int acpi_pcie_perf_request(void *device, |
| 27 | uint8_t perf_req, | 27 | uint8_t perf_req, |
| 28 | bool advertise); | 28 | bool advertise); |
| 29 | extern bool acpi_atcs_notify_pcie_device_ready(void *device); | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu74.h b/drivers/gpu/drm/amd/powerplay/inc/smu74.h index 1a12d85b8e97..fd10a9fa843d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu74.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu74.h | |||
| @@ -34,6 +34,30 @@ | |||
| 34 | #define SMU__NUM_LCLK_DPM_LEVELS 8 | 34 | #define SMU__NUM_LCLK_DPM_LEVELS 8 |
| 35 | #define SMU__NUM_PCIE_DPM_LEVELS 8 | 35 | #define SMU__NUM_PCIE_DPM_LEVELS 8 |
| 36 | 36 | ||
| 37 | #define EXP_M1 35 | ||
| 38 | #define EXP_M2 92821 | ||
| 39 | #define EXP_B 66629747 | ||
| 40 | |||
| 41 | #define EXP_M1_1 365 | ||
| 42 | #define EXP_M2_1 658700 | ||
| 43 | #define EXP_B_1 305506134 | ||
| 44 | |||
| 45 | #define EXP_M1_2 189 | ||
| 46 | #define EXP_M2_2 379692 | ||
| 47 | #define EXP_B_2 194609469 | ||
| 48 | |||
| 49 | #define EXP_M1_3 99 | ||
| 50 | #define EXP_M2_3 217915 | ||
| 51 | #define EXP_B_3 122255994 | ||
| 52 | |||
| 53 | #define EXP_M1_4 51 | ||
| 54 | #define EXP_M2_4 122643 | ||
| 55 | #define EXP_B_4 74893384 | ||
| 56 | |||
| 57 | #define EXP_M1_5 423 | ||
| 58 | #define EXP_M2_5 1103326 | ||
| 59 | #define EXP_B_5 728122621 | ||
| 60 | |||
| 37 | enum SID_OPTION { | 61 | enum SID_OPTION { |
| 38 | SID_OPTION_HI, | 62 | SID_OPTION_HI, |
| 39 | SID_OPTION_LO, | 63 | SID_OPTION_LO, |
| @@ -548,20 +572,20 @@ struct SMU74_Firmware_Header { | |||
| 548 | uint32_t CacConfigTable; | 572 | uint32_t CacConfigTable; |
| 549 | uint32_t CacStatusTable; | 573 | uint32_t CacStatusTable; |
| 550 | 574 | ||
| 551 | |||
| 552 | uint32_t mcRegisterTable; | 575 | uint32_t mcRegisterTable; |
| 553 | 576 | ||
| 554 | |||
| 555 | uint32_t mcArbDramTimingTable; | 577 | uint32_t mcArbDramTimingTable; |
| 556 | 578 | ||
| 557 | |||
| 558 | |||
| 559 | |||
| 560 | uint32_t PmFuseTable; | 579 | uint32_t PmFuseTable; |
| 561 | uint32_t Globals; | 580 | uint32_t Globals; |
| 562 | uint32_t ClockStretcherTable; | 581 | uint32_t ClockStretcherTable; |
| 563 | uint32_t VftTable; | 582 | uint32_t VftTable; |
| 564 | uint32_t Reserved[21]; | 583 | uint32_t Reserved1; |
| 584 | uint32_t AvfsTable; | ||
| 585 | uint32_t AvfsCksOffGbvTable; | ||
| 586 | uint32_t AvfsMeanNSigma; | ||
| 587 | uint32_t AvfsSclkOffsetTable; | ||
| 588 | uint32_t Reserved[16]; | ||
| 565 | uint32_t Signature; | 589 | uint32_t Signature; |
| 566 | }; | 590 | }; |
| 567 | 591 | ||
| @@ -701,8 +725,6 @@ VR Config info is contained in dpmTable.VRConfig */ | |||
| 701 | struct SMU_ClockStretcherDataTableEntry { | 725 | struct SMU_ClockStretcherDataTableEntry { |
| 702 | uint8_t minVID; | 726 | uint8_t minVID; |
| 703 | uint8_t maxVID; | 727 | uint8_t maxVID; |
| 704 | |||
| 705 | |||
| 706 | uint16_t setting; | 728 | uint16_t setting; |
| 707 | }; | 729 | }; |
| 708 | typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry; | 730 | typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry; |
| @@ -769,6 +791,43 @@ struct VFT_TABLE_t { | |||
| 769 | typedef struct VFT_TABLE_t VFT_TABLE_t; | 791 | typedef struct VFT_TABLE_t VFT_TABLE_t; |
| 770 | 792 | ||
| 771 | 793 | ||
| 794 | /* Total margin, root mean square of Fmax + DC + Platform */ | ||
| 795 | struct AVFS_Margin_t { | ||
| 796 | VFT_CELL_t Cell[NUM_VFT_COLUMNS]; | ||
| 797 | }; | ||
| 798 | typedef struct AVFS_Margin_t AVFS_Margin_t; | ||
| 799 | |||
| 800 | #define BTCGB_VDROOP_TABLE_MAX_ENTRIES 2 | ||
| 801 | #define AVFSGB_VDROOP_TABLE_MAX_ENTRIES 2 | ||
| 802 | |||
| 803 | struct GB_VDROOP_TABLE_t { | ||
| 804 | int32_t a0; | ||
| 805 | int32_t a1; | ||
| 806 | int32_t a2; | ||
| 807 | uint32_t spare; | ||
| 808 | }; | ||
| 809 | typedef struct GB_VDROOP_TABLE_t GB_VDROOP_TABLE_t; | ||
| 810 | |||
| 811 | struct AVFS_CksOff_Gbv_t { | ||
| 812 | VFT_CELL_t Cell[NUM_VFT_COLUMNS]; | ||
| 813 | }; | ||
| 814 | typedef struct AVFS_CksOff_Gbv_t AVFS_CksOff_Gbv_t; | ||
| 815 | |||
| 816 | struct AVFS_meanNsigma_t { | ||
| 817 | uint32_t Aconstant[3]; | ||
| 818 | uint16_t DC_tol_sigma; | ||
| 819 | uint16_t Platform_mean; | ||
| 820 | uint16_t Platform_sigma; | ||
| 821 | uint16_t PSM_Age_CompFactor; | ||
| 822 | uint8_t Static_Voltage_Offset[NUM_VFT_COLUMNS]; | ||
| 823 | }; | ||
| 824 | typedef struct AVFS_meanNsigma_t AVFS_meanNsigma_t; | ||
| 825 | |||
| 826 | struct AVFS_Sclk_Offset_t { | ||
| 827 | uint16_t Sclk_Offset[8]; | ||
| 828 | }; | ||
| 829 | typedef struct AVFS_Sclk_Offset_t AVFS_Sclk_Offset_t; | ||
| 830 | |||
| 772 | #endif | 831 | #endif |
| 773 | 832 | ||
| 774 | 833 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu74_discrete.h b/drivers/gpu/drm/amd/powerplay/inc/smu74_discrete.h index 0dfe82336dc7..b85ff5400e57 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu74_discrete.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu74_discrete.h | |||
| @@ -223,6 +223,16 @@ struct SMU74_Discrete_StateInfo { | |||
| 223 | 223 | ||
| 224 | typedef struct SMU74_Discrete_StateInfo SMU74_Discrete_StateInfo; | 224 | typedef struct SMU74_Discrete_StateInfo SMU74_Discrete_StateInfo; |
| 225 | 225 | ||
| 226 | struct SMU_QuadraticCoeffs { | ||
| 227 | int32_t m1; | ||
| 228 | uint32_t b; | ||
| 229 | |||
| 230 | int16_t m2; | ||
| 231 | uint8_t m1_shift; | ||
| 232 | uint8_t m2_shift; | ||
| 233 | }; | ||
| 234 | typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs; | ||
| 235 | |||
| 226 | struct SMU74_Discrete_DpmTable { | 236 | struct SMU74_Discrete_DpmTable { |
| 227 | 237 | ||
| 228 | SMU74_PIDController GraphicsPIDController; | 238 | SMU74_PIDController GraphicsPIDController; |
| @@ -258,7 +268,14 @@ struct SMU74_Discrete_DpmTable { | |||
| 258 | uint8_t ThermOutPolarity; | 268 | uint8_t ThermOutPolarity; |
| 259 | uint8_t ThermOutMode; | 269 | uint8_t ThermOutMode; |
| 260 | uint8_t BootPhases; | 270 | uint8_t BootPhases; |
| 261 | uint32_t Reserved[4]; | 271 | |
| 272 | uint8_t VRHotLevel; | ||
| 273 | uint8_t Reserved1[3]; | ||
| 274 | uint16_t FanStartTemperature; | ||
| 275 | uint16_t FanStopTemperature; | ||
| 276 | uint16_t MaxVoltage; | ||
| 277 | uint16_t Reserved2; | ||
| 278 | uint32_t Reserved[1]; | ||
| 262 | 279 | ||
| 263 | SMU74_Discrete_GraphicsLevel GraphicsLevel[SMU74_MAX_LEVELS_GRAPHICS]; | 280 | SMU74_Discrete_GraphicsLevel GraphicsLevel[SMU74_MAX_LEVELS_GRAPHICS]; |
| 264 | SMU74_Discrete_MemoryLevel MemoryACPILevel; | 281 | SMU74_Discrete_MemoryLevel MemoryACPILevel; |
| @@ -347,6 +364,8 @@ struct SMU74_Discrete_DpmTable { | |||
| 347 | 364 | ||
| 348 | uint32_t CurrSclkPllRange; | 365 | uint32_t CurrSclkPllRange; |
| 349 | sclkFcwRange_t SclkFcwRangeTable[NUM_SCLK_RANGE]; | 366 | sclkFcwRange_t SclkFcwRangeTable[NUM_SCLK_RANGE]; |
| 367 | GB_VDROOP_TABLE_t BTCGB_VDROOP_TABLE[BTCGB_VDROOP_TABLE_MAX_ENTRIES]; | ||
| 368 | SMU_QuadraticCoeffs AVFSGB_VDROOP_TABLE[AVFSGB_VDROOP_TABLE_MAX_ENTRIES]; | ||
| 350 | }; | 369 | }; |
| 351 | 370 | ||
| 352 | typedef struct SMU74_Discrete_DpmTable SMU74_Discrete_DpmTable; | 371 | typedef struct SMU74_Discrete_DpmTable SMU74_Discrete_DpmTable; |
| @@ -550,16 +569,6 @@ struct SMU7_AcpiScoreboard { | |||
| 550 | 569 | ||
| 551 | typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard; | 570 | typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard; |
| 552 | 571 | ||
| 553 | struct SMU_QuadraticCoeffs { | ||
| 554 | int32_t m1; | ||
| 555 | uint32_t b; | ||
| 556 | |||
| 557 | int16_t m2; | ||
| 558 | uint8_t m1_shift; | ||
| 559 | uint8_t m2_shift; | ||
| 560 | }; | ||
| 561 | typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs; | ||
| 562 | |||
| 563 | struct SMU74_Discrete_PmFuses { | 572 | struct SMU74_Discrete_PmFuses { |
| 564 | uint8_t BapmVddCVidHiSidd[8]; | 573 | uint8_t BapmVddCVidHiSidd[8]; |
| 565 | uint8_t BapmVddCVidLoSidd[8]; | 574 | uint8_t BapmVddCVidLoSidd[8]; |
| @@ -821,6 +830,17 @@ typedef struct SMU7_GfxCuPgScoreboard SMU7_GfxCuPgScoreboard; | |||
| 821 | #define DB_PCC_SHIFT 26 | 830 | #define DB_PCC_SHIFT 26 |
| 822 | #define DB_EDC_SHIFT 27 | 831 | #define DB_EDC_SHIFT 27 |
| 823 | 832 | ||
| 833 | #define BTCGB0_Vdroop_Enable_MASK 0x1 | ||
| 834 | #define BTCGB1_Vdroop_Enable_MASK 0x2 | ||
| 835 | #define AVFSGB0_Vdroop_Enable_MASK 0x4 | ||
| 836 | #define AVFSGB1_Vdroop_Enable_MASK 0x8 | ||
| 837 | |||
| 838 | #define BTCGB0_Vdroop_Enable_SHIFT 0 | ||
| 839 | #define BTCGB1_Vdroop_Enable_SHIFT 1 | ||
| 840 | #define AVFSGB0_Vdroop_Enable_SHIFT 2 | ||
| 841 | #define AVFSGB1_Vdroop_Enable_SHIFT 3 | ||
| 842 | |||
| 843 | |||
| 824 | #pragma pack(pop) | 844 | #pragma pack(pop) |
| 825 | 845 | ||
| 826 | 846 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 673a75c74e18..8e52a2e82db5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | |||
| @@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr) | |||
| 1006 | 1006 | ||
| 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) | 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) |
| 1008 | { | 1008 | { |
| 1009 | struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend); | ||
| 1010 | |||
| 1011 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
| 1012 | |||
| 1009 | if (smumgr->backend) { | 1013 | if (smumgr->backend) { |
| 1010 | kfree(smumgr->backend); | 1014 | kfree(smumgr->backend); |
| 1011 | smumgr->backend = NULL; | 1015 | smumgr->backend = NULL; |
| 1012 | } | 1016 | } |
| 1017 | |||
| 1018 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 1013 | return 0; | 1019 | return 0; |
| 1014 | } | 1020 | } |
| 1015 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index de618ead9db8..5dba7c509710 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | |||
| @@ -52,19 +52,18 @@ | |||
| 52 | static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = { | 52 | static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = { |
| 53 | /* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */ | 53 | /* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */ |
| 54 | /* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */ | 54 | /* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */ |
| 55 | { 0x3c0fd047, 0x00, 0x03, 0x1e00, 0x00200410, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x30750000, 0, 0, 0, 0, 0, 0, 0 } }, | 55 | { 0x100ea446, 0x00, 0x03, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x30750000, 0x3000, 0, 0x2600, 0, 0, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } }, |
| 56 | { 0xa00fd047, 0x01, 0x04, 0x1e00, 0x00800510, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x409c0000, 0, 0, 0, 0, 0, 0, 0 } }, | 56 | { 0x400ea446, 0x01, 0x04, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x409c0000, 0x2000, 0, 0x1e00, 1, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } }, |
| 57 | { 0x0410d047, 0x01, 0x00, 0x1e00, 0x00600410, 0x87020000, 0, 0, 0x0e, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x50c30000, 0, 0, 0, 0, 0, 0, 0 } }, | 57 | { 0x740ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x50c30000, 0x2800, 0, 0x2000, 1, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } }, |
| 58 | { 0x6810d047, 0x01, 0x00, 0x1e00, 0x00800410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x60ea0000, 0, 0, 0, 0, 0, 0, 0 } }, | 58 | { 0xa40ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x60ea0000, 0x3000, 0, 0x2600, 1, 1, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } }, |
| 59 | { 0xcc10d047, 0x01, 0x00, 0x1e00, 0x00e00410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xe8fd0000, 0, 0, 0, 0, 0, 0, 0 } }, | 59 | { 0xd80ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x70110100, 0x3800, 0, 0x2c00, 1, 1, 0x0004, 0x1203, 0xffff, 0x3600, 0xc9e2, 0x2e00 } }, |
| 60 | { 0x3011d047, 0x01, 0x00, 0x1e00, 0x00400510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x70110100, 0, 0, 0, 0, 0, 0, 0 } }, | 60 | { 0x3c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x80380100, 0x2000, 0, 0x1e00, 2, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } }, |
| 61 | { 0x9411d047, 0x01, 0x00, 0x1e00, 0x00a00510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xf8240100, 0, 0, 0, 0, 0, 0, 0 } }, | 61 | { 0x6c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x905f0100, 0x2400, 0, 0x1e00, 2, 1, 0x0004, 0x8901, 0xffff, 0x2300, 0x314c, 0x1d00 } }, |
| 62 | { 0xf811d047, 0x01, 0x00, 0x1e00, 0x00000610, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x80380100, 0, 0, 0, 0, 0, 0, 0 } } | 62 | { 0xa00fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0xa0860100, 0x2800, 0, 0x2000, 2, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } } |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = | 65 | static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = |
| 66 | {0x50140000, 0x50140000, 0x00320000, 0x00, 0x00, | 66 | {0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00}; |
| 67 | 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0000, 0x00, 0x00}; | ||
| 68 | 67 | ||
| 69 | /** | 68 | /** |
| 70 | * Set the address for reading/writing the SMC SRAM space. | 69 | * Set the address for reading/writing the SMC SRAM space. |
| @@ -219,6 +218,18 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr) | |||
| 219 | && (0x20100 <= cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMC_PC_C))); | 218 | && (0x20100 <= cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMC_PC_C))); |
| 220 | } | 219 | } |
| 221 | 220 | ||
| 221 | static bool polaris10_is_hw_avfs_present(struct pp_smumgr *smumgr) | ||
| 222 | { | ||
| 223 | uint32_t efuse; | ||
| 224 | |||
| 225 | efuse = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMU_EFUSE_0 + (49*4)); | ||
| 226 | efuse &= 0x00000001; | ||
| 227 | if (efuse) | ||
| 228 | return true; | ||
| 229 | |||
| 230 | return false; | ||
| 231 | } | ||
| 232 | |||
| 222 | /** | 233 | /** |
| 223 | * Send a message to the SMC, and wait for its response. | 234 | * Send a message to the SMC, and wait for its response. |
| 224 | * | 235 | * |
| @@ -228,21 +239,27 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr) | |||
| 228 | */ | 239 | */ |
| 229 | int polaris10_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg) | 240 | int polaris10_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg) |
| 230 | { | 241 | { |
| 242 | int ret; | ||
| 243 | |||
| 231 | if (!polaris10_is_smc_ram_running(smumgr)) | 244 | if (!polaris10_is_smc_ram_running(smumgr)) |
| 232 | return -1; | 245 | return -1; |
| 233 | 246 | ||
| 247 | |||
| 234 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | 248 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); |
| 235 | 249 | ||
| 236 | if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP)) | 250 | ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP); |
| 237 | printk("Failed to send Previous Message.\n"); | ||
| 238 | 251 | ||
| 252 | if (ret != 1) | ||
| 253 | printk("\n failed to send pre message %x ret is %d \n", msg, ret); | ||
| 239 | 254 | ||
| 240 | cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg); | 255 | cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg); |
| 241 | 256 | ||
| 242 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); | 257 | SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0); |
| 243 | 258 | ||
| 244 | if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP)) | 259 | ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP); |
| 245 | printk("Failed to send Message.\n"); | 260 | |
| 261 | if (ret != 1) | ||
| 262 | printk("\n failed to send message %x ret is %d \n", msg, ret); | ||
| 246 | 263 | ||
| 247 | return 0; | 264 | return 0; |
| 248 | } | 265 | } |
| @@ -469,6 +486,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr) | |||
| 469 | kfree(smumgr->backend); | 486 | kfree(smumgr->backend); |
| 470 | smumgr->backend = NULL; | 487 | smumgr->backend = NULL; |
| 471 | } | 488 | } |
| 489 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 472 | return 0; | 490 | return 0; |
| 473 | } | 491 | } |
| 474 | 492 | ||
| @@ -952,6 +970,11 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr) | |||
| 952 | (cgs_handle_t)smu_data->smu_buffer.handle); | 970 | (cgs_handle_t)smu_data->smu_buffer.handle); |
| 953 | return -1;); | 971 | return -1;); |
| 954 | 972 | ||
| 973 | if (polaris10_is_hw_avfs_present(smumgr)) | ||
| 974 | smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT; | ||
| 975 | else | ||
| 976 | smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED; | ||
| 977 | |||
| 955 | return 0; | 978 | return 0; |
| 956 | } | 979 | } |
| 957 | 980 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index c483baf6b4fb..0728c1e3d97a 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
| @@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
| 81 | 81 | ||
| 82 | int smum_fini(struct pp_smumgr *smumgr) | 82 | int smum_fini(struct pp_smumgr *smumgr) |
| 83 | { | 83 | { |
| 84 | kfree(smumgr->device); | ||
| 84 | kfree(smumgr); | 85 | kfree(smumgr); |
| 85 | return 0; | 86 | return 0; |
| 86 | } | 87 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index 32820b680d88..b22722eabafc 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | |||
| @@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, | |||
| 328 | 328 | ||
| 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) | 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) |
| 330 | { | 330 | { |
| 331 | struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend); | ||
| 332 | |||
| 333 | smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle); | ||
| 334 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
| 335 | |||
| 331 | if (smumgr->backend != NULL) { | 336 | if (smumgr->backend != NULL) { |
| 332 | kfree(smumgr->backend); | 337 | kfree(smumgr->backend); |
| 333 | smumgr->backend = NULL; | 338 | smumgr->backend = NULL; |
| 334 | } | 339 | } |
| 340 | |||
| 341 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 335 | return 0; | 342 | return 0; |
| 336 | } | 343 | } |
| 337 | 344 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index fef1b04c2aab..0813c2f06931 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c | |||
| @@ -33,8 +33,17 @@ | |||
| 33 | * | 33 | * |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | static void hdlcd_crtc_cleanup(struct drm_crtc *crtc) | ||
| 37 | { | ||
| 38 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | ||
| 39 | |||
| 40 | /* stop the controller on cleanup */ | ||
| 41 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | ||
| 42 | drm_crtc_cleanup(crtc); | ||
| 43 | } | ||
| 44 | |||
| 36 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { | 45 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { |
| 37 | .destroy = drm_crtc_cleanup, | 46 | .destroy = hdlcd_crtc_cleanup, |
| 38 | .set_config = drm_atomic_helper_set_config, | 47 | .set_config = drm_atomic_helper_set_config, |
| 39 | .page_flip = drm_atomic_helper_page_flip, | 48 | .page_flip = drm_atomic_helper_page_flip, |
| 40 | .reset = drm_atomic_helper_crtc_reset, | 49 | .reset = drm_atomic_helper_crtc_reset, |
| @@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 97 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 106 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 98 | struct drm_display_mode *m = &crtc->state->adjusted_mode; | 107 | struct drm_display_mode *m = &crtc->state->adjusted_mode; |
| 99 | struct videomode vm; | 108 | struct videomode vm; |
| 100 | unsigned int polarities, line_length, err; | 109 | unsigned int polarities, err; |
| 101 | 110 | ||
| 102 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; | 111 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; |
| 103 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; | 112 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; |
| @@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 113 | if (m->flags & DRM_MODE_FLAG_PVSYNC) | 122 | if (m->flags & DRM_MODE_FLAG_PVSYNC) |
| 114 | polarities |= HDLCD_POLARITY_VSYNC; | 123 | polarities |= HDLCD_POLARITY_VSYNC; |
| 115 | 124 | ||
| 116 | line_length = crtc->primary->state->fb->pitches[0]; | ||
| 117 | |||
| 118 | /* Allow max number of outstanding requests and largest burst size */ | 125 | /* Allow max number of outstanding requests and largest burst size */ |
| 119 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, | 126 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, |
| 120 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); | 127 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); |
| 121 | 128 | ||
| 122 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length); | ||
| 123 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length); | ||
| 124 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1); | ||
| 125 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); | 129 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); |
| 126 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); | 130 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); |
| 127 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); | 131 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); |
| 128 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); | 132 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); |
| 133 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 129 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); | 134 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); |
| 130 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); | 135 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); |
| 131 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); | 136 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); |
| 132 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 133 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); | 137 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); |
| 134 | 138 | ||
| 135 | err = hdlcd_set_pxl_fmt(crtc); | 139 | err = hdlcd_set_pxl_fmt(crtc); |
| @@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc) | |||
| 144 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 148 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 145 | 149 | ||
| 146 | clk_prepare_enable(hdlcd->clk); | 150 | clk_prepare_enable(hdlcd->clk); |
| 151 | hdlcd_crtc_mode_set_nofb(crtc); | ||
| 147 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); | 152 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); |
| 148 | drm_crtc_vblank_on(crtc); | ||
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) | 155 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) |
| 152 | { | 156 | { |
| 153 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 157 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 154 | 158 | ||
| 155 | if (!crtc->primary->fb) | 159 | if (!crtc->state->active) |
| 156 | return; | 160 | return; |
| 157 | 161 | ||
| 158 | clk_disable_unprepare(hdlcd->clk); | ||
| 159 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | 162 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); |
| 160 | drm_crtc_vblank_off(crtc); | 163 | clk_disable_unprepare(hdlcd->clk); |
| 161 | } | 164 | } |
| 162 | 165 | ||
| 163 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | 166 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, |
| @@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | |||
| 179 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, | 182 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, |
| 180 | struct drm_crtc_state *state) | 183 | struct drm_crtc_state *state) |
| 181 | { | 184 | { |
| 182 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 185 | struct drm_pending_vblank_event *event = crtc->state->event; |
| 183 | unsigned long flags; | ||
| 184 | |||
| 185 | if (crtc->state->event) { | ||
| 186 | struct drm_pending_vblank_event *event = crtc->state->event; | ||
| 187 | 186 | ||
| 187 | if (event) { | ||
| 188 | crtc->state->event = NULL; | 188 | crtc->state->event = NULL; |
| 189 | event->pipe = drm_crtc_index(crtc); | ||
| 190 | |||
| 191 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
| 192 | 189 | ||
| 193 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | 190 | spin_lock_irq(&crtc->dev->event_lock); |
| 194 | list_add_tail(&event->base.link, &hdlcd->event_list); | 191 | if (drm_crtc_vblank_get(crtc) == 0) |
| 195 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | 192 | drm_crtc_arm_vblank_event(crtc, event); |
| 193 | else | ||
| 194 | drm_crtc_send_vblank_event(crtc, event); | ||
| 195 | spin_unlock_irq(&crtc->dev->event_lock); | ||
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | 198 | ||
| @@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { | |||
| 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, | 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, |
| 226 | struct drm_plane_state *state) | 226 | struct drm_plane_state *state) |
| 227 | { | 227 | { |
| 228 | u32 src_w, src_h; | ||
| 229 | |||
| 230 | src_w = state->src_w >> 16; | ||
| 231 | src_h = state->src_h >> 16; | ||
| 232 | |||
| 233 | /* we can't do any scaling of the plane source */ | ||
| 234 | if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) | ||
| 235 | return -EINVAL; | ||
| 236 | |||
| 228 | return 0; | 237 | return 0; |
| 229 | } | 238 | } |
| 230 | 239 | ||
| @@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, | |||
| 233 | { | 242 | { |
| 234 | struct hdlcd_drm_private *hdlcd; | 243 | struct hdlcd_drm_private *hdlcd; |
| 235 | struct drm_gem_cma_object *gem; | 244 | struct drm_gem_cma_object *gem; |
| 245 | unsigned int depth, bpp; | ||
| 246 | u32 src_w, src_h, dest_w, dest_h; | ||
| 236 | dma_addr_t scanout_start; | 247 | dma_addr_t scanout_start; |
| 237 | 248 | ||
| 238 | if (!plane->state->crtc || !plane->state->fb) | 249 | if (!plane->state->fb) |
| 239 | return; | 250 | return; |
| 240 | 251 | ||
| 241 | hdlcd = crtc_to_hdlcd_priv(plane->state->crtc); | 252 | drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp); |
| 253 | src_w = plane->state->src_w >> 16; | ||
| 254 | src_h = plane->state->src_h >> 16; | ||
| 255 | dest_w = plane->state->crtc_w; | ||
| 256 | dest_h = plane->state->crtc_h; | ||
| 242 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); | 257 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); |
| 243 | scanout_start = gem->paddr; | 258 | scanout_start = gem->paddr + plane->state->fb->offsets[0] + |
| 259 | plane->state->crtc_y * plane->state->fb->pitches[0] + | ||
| 260 | plane->state->crtc_x * bpp / 8; | ||
| 261 | |||
| 262 | hdlcd = plane->dev->dev_private; | ||
| 263 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]); | ||
| 264 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]); | ||
| 265 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1); | ||
| 244 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); | 266 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); |
| 245 | } | 267 | } |
| 246 | 268 | ||
| 247 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { | 269 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { |
| 248 | .prepare_fb = NULL, | ||
| 249 | .cleanup_fb = NULL, | ||
| 250 | .atomic_check = hdlcd_plane_atomic_check, | 270 | .atomic_check = hdlcd_plane_atomic_check, |
| 251 | .atomic_update = hdlcd_plane_atomic_update, | 271 | .atomic_update = hdlcd_plane_atomic_update, |
| 252 | }; | 272 | }; |
| @@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) | |||
| 294 | return plane; | 314 | return plane; |
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | void hdlcd_crtc_suspend(struct drm_crtc *crtc) | ||
| 298 | { | ||
| 299 | hdlcd_crtc_disable(crtc); | ||
| 300 | } | ||
| 301 | |||
| 302 | void hdlcd_crtc_resume(struct drm_crtc *crtc) | ||
| 303 | { | ||
| 304 | hdlcd_crtc_enable(crtc); | ||
| 305 | } | ||
| 306 | |||
| 307 | int hdlcd_setup_crtc(struct drm_device *drm) | 317 | int hdlcd_setup_crtc(struct drm_device *drm) |
| 308 | { | 318 | { |
| 309 | struct hdlcd_drm_private *hdlcd = drm->dev_private; | 319 | struct hdlcd_drm_private *hdlcd = drm->dev_private; |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index b987c63ba8d6..a6ca36f0096f 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
| @@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 49 | atomic_set(&hdlcd->dma_end_count, 0); | 49 | atomic_set(&hdlcd->dma_end_count, 0); |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | INIT_LIST_HEAD(&hdlcd->event_list); | ||
| 53 | |||
| 54 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 52 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 55 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); | 53 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); |
| 56 | if (IS_ERR(hdlcd->mmio)) { | 54 | if (IS_ERR(hdlcd->mmio)) { |
| @@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 84 | goto setup_fail; | 82 | goto setup_fail; |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | pm_runtime_enable(drm->dev); | ||
| 88 | |||
| 89 | pm_runtime_get_sync(drm->dev); | ||
| 90 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); | 85 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); |
| 91 | pm_runtime_put_sync(drm->dev); | ||
| 92 | if (ret < 0) { | 86 | if (ret < 0) { |
| 93 | DRM_ERROR("failed to install IRQ handler\n"); | 87 | DRM_ERROR("failed to install IRQ handler\n"); |
| 94 | goto irq_fail; | 88 | goto irq_fail; |
| @@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) | |||
| 164 | atomic_inc(&hdlcd->vsync_count); | 158 | atomic_inc(&hdlcd->vsync_count); |
| 165 | 159 | ||
| 166 | #endif | 160 | #endif |
| 167 | if (irq_status & HDLCD_INTERRUPT_VSYNC) { | 161 | if (irq_status & HDLCD_INTERRUPT_VSYNC) |
| 168 | bool events_sent = false; | ||
| 169 | unsigned long flags; | ||
| 170 | struct drm_pending_vblank_event *e, *t; | ||
| 171 | |||
| 172 | drm_crtc_handle_vblank(&hdlcd->crtc); | 162 | drm_crtc_handle_vblank(&hdlcd->crtc); |
| 173 | 163 | ||
| 174 | spin_lock_irqsave(&drm->event_lock, flags); | ||
| 175 | list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) { | ||
| 176 | list_del(&e->base.link); | ||
| 177 | drm_crtc_send_vblank_event(&hdlcd->crtc, e); | ||
| 178 | events_sent = true; | ||
| 179 | } | ||
| 180 | if (events_sent) | ||
| 181 | drm_crtc_vblank_put(&hdlcd->crtc); | ||
| 182 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
| 183 | } | ||
| 184 | |||
| 185 | /* acknowledge interrupt(s) */ | 164 | /* acknowledge interrupt(s) */ |
| 186 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); | 165 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); |
| 187 | 166 | ||
| @@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) | |||
| 275 | static struct drm_info_list hdlcd_debugfs_list[] = { | 254 | static struct drm_info_list hdlcd_debugfs_list[] = { |
| 276 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, | 255 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, |
| 277 | { "clocks", hdlcd_show_pxlclock, 0 }, | 256 | { "clocks", hdlcd_show_pxlclock, 0 }, |
| 257 | { "fb", drm_fb_cma_debugfs_show, 0 }, | ||
| 278 | }; | 258 | }; |
| 279 | 259 | ||
| 280 | static int hdlcd_debugfs_init(struct drm_minor *minor) | 260 | static int hdlcd_debugfs_init(struct drm_minor *minor) |
| @@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 357 | return -ENOMEM; | 337 | return -ENOMEM; |
| 358 | 338 | ||
| 359 | drm->dev_private = hdlcd; | 339 | drm->dev_private = hdlcd; |
| 340 | dev_set_drvdata(dev, drm); | ||
| 341 | |||
| 360 | hdlcd_setup_mode_config(drm); | 342 | hdlcd_setup_mode_config(drm); |
| 361 | ret = hdlcd_load(drm, 0); | 343 | ret = hdlcd_load(drm, 0); |
| 362 | if (ret) | 344 | if (ret) |
| @@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 366 | if (ret) | 348 | if (ret) |
| 367 | goto err_unload; | 349 | goto err_unload; |
| 368 | 350 | ||
| 369 | dev_set_drvdata(dev, drm); | ||
| 370 | |||
| 371 | ret = component_bind_all(dev, drm); | 351 | ret = component_bind_all(dev, drm); |
| 372 | if (ret) { | 352 | if (ret) { |
| 373 | DRM_ERROR("Failed to bind all components\n"); | 353 | DRM_ERROR("Failed to bind all components\n"); |
| 374 | goto err_unregister; | 354 | goto err_unregister; |
| 375 | } | 355 | } |
| 376 | 356 | ||
| 357 | ret = pm_runtime_set_active(dev); | ||
| 358 | if (ret) | ||
| 359 | goto err_pm_active; | ||
| 360 | |||
| 361 | pm_runtime_enable(dev); | ||
| 362 | |||
| 377 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 363 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
| 378 | if (ret < 0) { | 364 | if (ret < 0) { |
| 379 | DRM_ERROR("failed to initialise vblank\n"); | 365 | DRM_ERROR("failed to initialise vblank\n"); |
| @@ -399,16 +385,16 @@ err_fbdev: | |||
| 399 | drm_mode_config_cleanup(drm); | 385 | drm_mode_config_cleanup(drm); |
| 400 | drm_vblank_cleanup(drm); | 386 | drm_vblank_cleanup(drm); |
| 401 | err_vblank: | 387 | err_vblank: |
| 388 | pm_runtime_disable(drm->dev); | ||
| 389 | err_pm_active: | ||
| 402 | component_unbind_all(dev, drm); | 390 | component_unbind_all(dev, drm); |
| 403 | err_unregister: | 391 | err_unregister: |
| 404 | drm_dev_unregister(drm); | 392 | drm_dev_unregister(drm); |
| 405 | err_unload: | 393 | err_unload: |
| 406 | pm_runtime_get_sync(drm->dev); | ||
| 407 | drm_irq_uninstall(drm); | 394 | drm_irq_uninstall(drm); |
| 408 | pm_runtime_put_sync(drm->dev); | ||
| 409 | pm_runtime_disable(drm->dev); | ||
| 410 | of_reserved_mem_device_release(drm->dev); | 395 | of_reserved_mem_device_release(drm->dev); |
| 411 | err_free: | 396 | err_free: |
| 397 | dev_set_drvdata(dev, NULL); | ||
| 412 | drm_dev_unref(drm); | 398 | drm_dev_unref(drm); |
| 413 | 399 | ||
| 414 | return ret; | 400 | return ret; |
| @@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); | |||
| 495 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) | 481 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) |
| 496 | { | 482 | { |
| 497 | struct drm_device *drm = dev_get_drvdata(dev); | 483 | struct drm_device *drm = dev_get_drvdata(dev); |
| 498 | struct drm_crtc *crtc; | 484 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 499 | 485 | ||
| 500 | if (pm_runtime_suspended(dev)) | 486 | if (!hdlcd) |
| 501 | return 0; | 487 | return 0; |
| 502 | 488 | ||
| 503 | drm_modeset_lock_all(drm); | 489 | drm_kms_helper_poll_disable(drm); |
| 504 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 490 | |
| 505 | hdlcd_crtc_suspend(crtc); | 491 | hdlcd->state = drm_atomic_helper_suspend(drm); |
| 506 | drm_modeset_unlock_all(drm); | 492 | if (IS_ERR(hdlcd->state)) { |
| 493 | drm_kms_helper_poll_enable(drm); | ||
| 494 | return PTR_ERR(hdlcd->state); | ||
| 495 | } | ||
| 496 | |||
| 507 | return 0; | 497 | return 0; |
| 508 | } | 498 | } |
| 509 | 499 | ||
| 510 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) | 500 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) |
| 511 | { | 501 | { |
| 512 | struct drm_device *drm = dev_get_drvdata(dev); | 502 | struct drm_device *drm = dev_get_drvdata(dev); |
| 513 | struct drm_crtc *crtc; | 503 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 514 | 504 | ||
| 515 | if (!pm_runtime_suspended(dev)) | 505 | if (!hdlcd) |
| 516 | return 0; | 506 | return 0; |
| 517 | 507 | ||
| 518 | drm_modeset_lock_all(drm); | 508 | drm_atomic_helper_resume(drm, hdlcd->state); |
| 519 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 509 | drm_kms_helper_poll_enable(drm); |
| 520 | hdlcd_crtc_resume(crtc); | 510 | pm_runtime_set_active(dev); |
| 521 | drm_modeset_unlock_all(drm); | 511 | |
| 522 | return 0; | 512 | return 0; |
| 523 | } | 513 | } |
| 524 | 514 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h index aa234784f053..e3950a071152 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.h +++ b/drivers/gpu/drm/arm/hdlcd_drv.h | |||
| @@ -9,10 +9,9 @@ struct hdlcd_drm_private { | |||
| 9 | void __iomem *mmio; | 9 | void __iomem *mmio; |
| 10 | struct clk *clk; | 10 | struct clk *clk; |
| 11 | struct drm_fbdev_cma *fbdev; | 11 | struct drm_fbdev_cma *fbdev; |
| 12 | struct drm_framebuffer *fb; | ||
| 13 | struct list_head event_list; | ||
| 14 | struct drm_crtc crtc; | 12 | struct drm_crtc crtc; |
| 15 | struct drm_plane *plane; | 13 | struct drm_plane *plane; |
| 14 | struct drm_atomic_state *state; | ||
| 16 | #ifdef CONFIG_DEBUG_FS | 15 | #ifdef CONFIG_DEBUG_FS |
| 17 | atomic_t buffer_underrun_count; | 16 | atomic_t buffer_underrun_count; |
| 18 | atomic_t bus_error_count; | 17 | atomic_t bus_error_count; |
| @@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg) | |||
| 36 | 35 | ||
| 37 | int hdlcd_setup_crtc(struct drm_device *dev); | 36 | int hdlcd_setup_crtc(struct drm_device *dev); |
| 38 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); | 37 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); |
| 39 | void hdlcd_crtc_suspend(struct drm_crtc *crtc); | ||
| 40 | void hdlcd_crtc_resume(struct drm_crtc *crtc); | ||
| 41 | 38 | ||
| 42 | #endif /* __HDLCD_DRV_H__ */ | 39 | #endif /* __HDLCD_DRV_H__ */ |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index cf23a755f777..bd12231ab0cd 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | |||
| @@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) | |||
| 391 | { | 391 | { |
| 392 | struct atmel_hlcdc_crtc_state *state; | 392 | struct atmel_hlcdc_crtc_state *state; |
| 393 | 393 | ||
| 394 | if (crtc->state && crtc->state->mode_blob) | ||
| 395 | drm_property_unreference_blob(crtc->state->mode_blob); | ||
| 396 | |||
| 397 | if (crtc->state) { | 394 | if (crtc->state) { |
| 395 | __drm_atomic_helper_crtc_destroy_state(crtc->state); | ||
| 398 | state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); | 396 | state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); |
| 399 | kfree(state); | 397 | kfree(state); |
| 398 | crtc->state = NULL; | ||
| 400 | } | 399 | } |
| 401 | 400 | ||
| 402 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 401 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
| @@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) | |||
| 415 | return NULL; | 414 | return NULL; |
| 416 | 415 | ||
| 417 | state = kmalloc(sizeof(*state), GFP_KERNEL); | 416 | state = kmalloc(sizeof(*state), GFP_KERNEL); |
| 418 | if (state) | 417 | if (!state) |
| 419 | __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); | 418 | return NULL; |
| 419 | __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); | ||
| 420 | 420 | ||
| 421 | cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); | 421 | cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); |
| 422 | state->output_mode = cur->output_mode; | 422 | state->output_mode = cur->output_mode; |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c index 39802c0539b6..3d34fc4ca826 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c | |||
| @@ -266,9 +266,10 @@ int atmel_hlcdc_create_outputs(struct drm_device *dev) | |||
| 266 | if (!ret) | 266 | if (!ret) |
| 267 | ret = atmel_hlcdc_check_endpoint(dev, &ep); | 267 | ret = atmel_hlcdc_check_endpoint(dev, &ep); |
| 268 | 268 | ||
| 269 | of_node_put(ep_np); | 269 | if (ret) { |
| 270 | if (ret) | 270 | of_node_put(ep_np); |
| 271 | return ret; | 271 | return ret; |
| 272 | } | ||
| 272 | } | 273 | } |
| 273 | 274 | ||
| 274 | for_each_endpoint_of_node(dev->dev->of_node, ep_np) { | 275 | for_each_endpoint_of_node(dev->dev->of_node, ep_np) { |
| @@ -276,9 +277,10 @@ int atmel_hlcdc_create_outputs(struct drm_device *dev) | |||
| 276 | if (!ret) | 277 | if (!ret) |
| 277 | ret = atmel_hlcdc_attach_endpoint(dev, &ep); | 278 | ret = atmel_hlcdc_attach_endpoint(dev, &ep); |
| 278 | 279 | ||
| 279 | of_node_put(ep_np); | 280 | if (ret) { |
| 280 | if (ret) | 281 | of_node_put(ep_np); |
| 281 | return ret; | 282 | return ret; |
| 283 | } | ||
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | return 0; | 286 | return 0; |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index aef3ca8a81fa..016c191221f3 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | |||
| @@ -339,6 +339,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane, | |||
| 339 | 339 | ||
| 340 | atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, | 340 | atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, |
| 341 | factor_reg); | 341 | factor_reg); |
| 342 | } else { | ||
| 343 | atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0); | ||
| 342 | } | 344 | } |
| 343 | } | 345 | } |
| 344 | 346 | ||
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3ff1ed7b33db..9bb99e274d23 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
| @@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
| 351 | drm_property_unreference_blob(state->mode_blob); | 351 | drm_property_unreference_blob(state->mode_blob); |
| 352 | state->mode_blob = NULL; | 352 | state->mode_blob = NULL; |
| 353 | 353 | ||
| 354 | memset(&state->mode, 0, sizeof(state->mode)); | ||
| 355 | |||
| 354 | if (blob) { | 356 | if (blob) { |
| 355 | if (blob->length != sizeof(struct drm_mode_modeinfo) || | 357 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
| 356 | drm_mode_convert_umode(&state->mode, | 358 | drm_mode_convert_umode(&state->mode, |
| @@ -363,7 +365,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
| 363 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", | 365 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
| 364 | state->mode.name, state); | 366 | state->mode.name, state); |
| 365 | } else { | 367 | } else { |
| 366 | memset(&state->mode, 0, sizeof(state->mode)); | ||
| 367 | state->enable = false; | 368 | state->enable = false; |
| 368 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", | 369 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
| 369 | state); | 370 | state); |
| @@ -1295,14 +1296,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_planes); | |||
| 1295 | */ | 1296 | */ |
| 1296 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state) | 1297 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state) |
| 1297 | { | 1298 | { |
| 1299 | struct drm_device *dev = state->dev; | ||
| 1300 | unsigned crtc_mask = 0; | ||
| 1301 | struct drm_crtc *crtc; | ||
| 1298 | int ret; | 1302 | int ret; |
| 1303 | bool global = false; | ||
| 1304 | |||
| 1305 | drm_for_each_crtc(crtc, dev) { | ||
| 1306 | if (crtc->acquire_ctx != state->acquire_ctx) | ||
| 1307 | continue; | ||
| 1308 | |||
| 1309 | crtc_mask |= drm_crtc_mask(crtc); | ||
| 1310 | crtc->acquire_ctx = NULL; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) { | ||
| 1314 | global = true; | ||
| 1315 | |||
| 1316 | dev->mode_config.acquire_ctx = NULL; | ||
| 1317 | } | ||
| 1299 | 1318 | ||
| 1300 | retry: | 1319 | retry: |
| 1301 | drm_modeset_backoff(state->acquire_ctx); | 1320 | drm_modeset_backoff(state->acquire_ctx); |
| 1302 | 1321 | ||
| 1303 | ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx); | 1322 | ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx); |
| 1304 | if (ret) | 1323 | if (ret) |
| 1305 | goto retry; | 1324 | goto retry; |
| 1325 | |||
| 1326 | drm_for_each_crtc(crtc, dev) | ||
| 1327 | if (drm_crtc_mask(crtc) & crtc_mask) | ||
| 1328 | crtc->acquire_ctx = state->acquire_ctx; | ||
| 1329 | |||
| 1330 | if (global) | ||
| 1331 | dev->mode_config.acquire_ctx = state->acquire_ctx; | ||
| 1306 | } | 1332 | } |
| 1307 | EXPORT_SYMBOL(drm_atomic_legacy_backoff); | 1333 | EXPORT_SYMBOL(drm_atomic_legacy_backoff); |
| 1308 | 1334 | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d2a6d958ca76..0e3cc66aa8b7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
| 2821 | goto out; | 2821 | goto out; |
| 2822 | } | 2822 | } |
| 2823 | 2823 | ||
| 2824 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); | ||
| 2825 | |||
| 2826 | /* | 2824 | /* |
| 2827 | * Check whether the primary plane supports the fb pixel format. | 2825 | * Check whether the primary plane supports the fb pixel format. |
| 2828 | * Drivers not implementing the universal planes API use a | 2826 | * Drivers not implementing the universal planes API use a |
| @@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property, | |||
| 4841 | if (value == 0) | 4839 | if (value == 0) |
| 4842 | return true; | 4840 | return true; |
| 4843 | 4841 | ||
| 4844 | return _object_find(property->dev, value, property->values[0]) != NULL; | 4842 | *ref = _object_find(property->dev, value, property->values[0]); |
| 4843 | return *ref != NULL; | ||
| 4845 | } | 4844 | } |
| 4846 | 4845 | ||
| 4847 | for (i = 0; i < property->num_values; i++) | 4846 | for (i = 0; i < property->num_values; i++) |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a6e42433ef0e..26feb2f8453f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -528,11 +528,11 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) | |||
| 528 | int drm_crtc_helper_set_config(struct drm_mode_set *set) | 528 | int drm_crtc_helper_set_config(struct drm_mode_set *set) |
| 529 | { | 529 | { |
| 530 | struct drm_device *dev; | 530 | struct drm_device *dev; |
| 531 | struct drm_crtc *new_crtc; | 531 | struct drm_crtc **save_encoder_crtcs, *new_crtc; |
| 532 | struct drm_encoder *save_encoders, *new_encoder, *encoder; | 532 | struct drm_encoder **save_connector_encoders, *new_encoder, *encoder; |
| 533 | bool mode_changed = false; /* if true do a full mode set */ | 533 | bool mode_changed = false; /* if true do a full mode set */ |
| 534 | bool fb_changed = false; /* if true and !mode_changed just do a flip */ | 534 | bool fb_changed = false; /* if true and !mode_changed just do a flip */ |
| 535 | struct drm_connector *save_connectors, *connector; | 535 | struct drm_connector *connector; |
| 536 | int count = 0, ro, fail = 0; | 536 | int count = 0, ro, fail = 0; |
| 537 | const struct drm_crtc_helper_funcs *crtc_funcs; | 537 | const struct drm_crtc_helper_funcs *crtc_funcs; |
| 538 | struct drm_mode_set save_set; | 538 | struct drm_mode_set save_set; |
| @@ -574,15 +574,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 574 | * Allocate space for the backup of all (non-pointer) encoder and | 574 | * Allocate space for the backup of all (non-pointer) encoder and |
| 575 | * connector data. | 575 | * connector data. |
| 576 | */ | 576 | */ |
| 577 | save_encoders = kzalloc(dev->mode_config.num_encoder * | 577 | save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder * |
| 578 | sizeof(struct drm_encoder), GFP_KERNEL); | 578 | sizeof(struct drm_crtc *), GFP_KERNEL); |
| 579 | if (!save_encoders) | 579 | if (!save_encoder_crtcs) |
| 580 | return -ENOMEM; | 580 | return -ENOMEM; |
| 581 | 581 | ||
| 582 | save_connectors = kzalloc(dev->mode_config.num_connector * | 582 | save_connector_encoders = kzalloc(dev->mode_config.num_connector * |
| 583 | sizeof(struct drm_connector), GFP_KERNEL); | 583 | sizeof(struct drm_encoder *), GFP_KERNEL); |
| 584 | if (!save_connectors) { | 584 | if (!save_connector_encoders) { |
| 585 | kfree(save_encoders); | 585 | kfree(save_encoder_crtcs); |
| 586 | return -ENOMEM; | 586 | return -ENOMEM; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| @@ -593,12 +593,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 593 | */ | 593 | */ |
| 594 | count = 0; | 594 | count = 0; |
| 595 | drm_for_each_encoder(encoder, dev) { | 595 | drm_for_each_encoder(encoder, dev) { |
| 596 | save_encoders[count++] = *encoder; | 596 | save_encoder_crtcs[count++] = encoder->crtc; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | count = 0; | 599 | count = 0; |
| 600 | drm_for_each_connector(connector, dev) { | 600 | drm_for_each_connector(connector, dev) { |
| 601 | save_connectors[count++] = *connector; | 601 | save_connector_encoders[count++] = connector->encoder; |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | save_set.crtc = set->crtc; | 604 | save_set.crtc = set->crtc; |
| @@ -631,8 +631,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 631 | mode_changed = true; | 631 | mode_changed = true; |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | /* take a reference on all connectors in set */ | 634 | /* take a reference on all unbound connectors in set, reuse the |
| 635 | * already taken reference for bound connectors | ||
| 636 | */ | ||
| 635 | for (ro = 0; ro < set->num_connectors; ro++) { | 637 | for (ro = 0; ro < set->num_connectors; ro++) { |
| 638 | if (set->connectors[ro]->encoder) | ||
| 639 | continue; | ||
| 636 | drm_connector_reference(set->connectors[ro]); | 640 | drm_connector_reference(set->connectors[ro]); |
| 637 | } | 641 | } |
| 638 | 642 | ||
| @@ -754,30 +758,28 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 754 | } | 758 | } |
| 755 | } | 759 | } |
| 756 | 760 | ||
| 757 | /* after fail drop reference on all connectors in save set */ | 761 | kfree(save_connector_encoders); |
| 758 | count = 0; | 762 | kfree(save_encoder_crtcs); |
| 759 | drm_for_each_connector(connector, dev) { | ||
| 760 | drm_connector_unreference(&save_connectors[count++]); | ||
| 761 | } | ||
| 762 | |||
| 763 | kfree(save_connectors); | ||
| 764 | kfree(save_encoders); | ||
| 765 | return 0; | 763 | return 0; |
| 766 | 764 | ||
| 767 | fail: | 765 | fail: |
| 768 | /* Restore all previous data. */ | 766 | /* Restore all previous data. */ |
| 769 | count = 0; | 767 | count = 0; |
| 770 | drm_for_each_encoder(encoder, dev) { | 768 | drm_for_each_encoder(encoder, dev) { |
| 771 | *encoder = save_encoders[count++]; | 769 | encoder->crtc = save_encoder_crtcs[count++]; |
| 772 | } | 770 | } |
| 773 | 771 | ||
| 774 | count = 0; | 772 | count = 0; |
| 775 | drm_for_each_connector(connector, dev) { | 773 | drm_for_each_connector(connector, dev) { |
| 776 | *connector = save_connectors[count++]; | 774 | connector->encoder = save_connector_encoders[count++]; |
| 777 | } | 775 | } |
| 778 | 776 | ||
| 779 | /* after fail drop reference on all connectors in set */ | 777 | /* after fail drop reference on all unbound connectors in set, let |
| 778 | * bound connectors keep their reference | ||
| 779 | */ | ||
| 780 | for (ro = 0; ro < set->num_connectors; ro++) { | 780 | for (ro = 0; ro < set->num_connectors; ro++) { |
| 781 | if (set->connectors[ro]->encoder) | ||
| 782 | continue; | ||
| 781 | drm_connector_unreference(set->connectors[ro]); | 783 | drm_connector_unreference(set->connectors[ro]); |
| 782 | } | 784 | } |
| 783 | 785 | ||
| @@ -787,8 +789,8 @@ fail: | |||
| 787 | save_set.y, save_set.fb)) | 789 | save_set.y, save_set.fb)) |
| 788 | DRM_ERROR("failed to restore config after modeset failure\n"); | 790 | DRM_ERROR("failed to restore config after modeset failure\n"); |
| 789 | 791 | ||
| 790 | kfree(save_connectors); | 792 | kfree(save_connector_encoders); |
| 791 | kfree(save_encoders); | 793 | kfree(save_encoder_crtcs); |
| 792 | return ret; | 794 | return ret; |
| 793 | } | 795 | } |
| 794 | EXPORT_SYMBOL(drm_crtc_helper_set_config); | 796 | EXPORT_SYMBOL(drm_crtc_helper_set_config); |
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index a13edf5de2d6..6537908050d7 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
| @@ -2927,11 +2927,9 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) | |||
| 2927 | drm_dp_port_teardown_pdt(port, port->pdt); | 2927 | drm_dp_port_teardown_pdt(port, port->pdt); |
| 2928 | 2928 | ||
| 2929 | if (!port->input && port->vcpi.vcpi > 0) { | 2929 | if (!port->input && port->vcpi.vcpi > 0) { |
| 2930 | if (mgr->mst_state) { | 2930 | drm_dp_mst_reset_vcpi_slots(mgr, port); |
| 2931 | drm_dp_mst_reset_vcpi_slots(mgr, port); | 2931 | drm_dp_update_payload_part1(mgr); |
| 2932 | drm_dp_update_payload_part1(mgr); | 2932 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); |
| 2933 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); | ||
| 2934 | } | ||
| 2935 | } | 2933 | } |
| 2936 | 2934 | ||
| 2937 | kref_put(&port->kref, drm_dp_free_mst_port); | 2935 | kref_put(&port->kref, drm_dp_free_mst_port); |
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 172cafe11c71..5075fae3c4e2 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
| @@ -445,7 +445,7 @@ err_cma_destroy: | |||
| 445 | err_fb_info_destroy: | 445 | err_fb_info_destroy: |
| 446 | drm_fb_helper_release_fbi(helper); | 446 | drm_fb_helper_release_fbi(helper); |
| 447 | err_gem_free_object: | 447 | err_gem_free_object: |
| 448 | dev->driver->gem_free_object(&obj->base); | 448 | drm_gem_object_unreference_unlocked(&obj->base); |
| 449 | return ret; | 449 | return ret; |
| 450 | } | 450 | } |
| 451 | EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); | 451 | EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); |
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index e1ab008b3f08..1d6c335584ec 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c | |||
| @@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, | |||
| 121 | return cma_obj; | 121 | return cma_obj; |
| 122 | 122 | ||
| 123 | error: | 123 | error: |
| 124 | drm->driver->gem_free_object(&cma_obj->base); | 124 | drm_gem_object_unreference_unlocked(&cma_obj->base); |
| 125 | return ERR_PTR(ret); | 125 | return ERR_PTR(ret); |
| 126 | } | 126 | } |
| 127 | EXPORT_SYMBOL_GPL(drm_gem_cma_create); | 127 | EXPORT_SYMBOL_GPL(drm_gem_cma_create); |
| @@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, | |||
| 162 | * and handle has the id what user can see. | 162 | * and handle has the id what user can see. |
| 163 | */ | 163 | */ |
| 164 | ret = drm_gem_handle_create(file_priv, gem_obj, handle); | 164 | ret = drm_gem_handle_create(file_priv, gem_obj, handle); |
| 165 | if (ret) | ||
| 166 | goto err_handle_create; | ||
| 167 | |||
| 168 | /* drop reference from allocate - handle holds it now. */ | 165 | /* drop reference from allocate - handle holds it now. */ |
| 169 | drm_gem_object_unreference_unlocked(gem_obj); | 166 | drm_gem_object_unreference_unlocked(gem_obj); |
| 167 | if (ret) | ||
| 168 | return ERR_PTR(ret); | ||
| 170 | 169 | ||
| 171 | return cma_obj; | 170 | return cma_obj; |
| 172 | |||
| 173 | err_handle_create: | ||
| 174 | drm->driver->gem_free_object(gem_obj); | ||
| 175 | |||
| 176 | return ERR_PTR(ret); | ||
| 177 | } | 171 | } |
| 178 | 172 | ||
| 179 | /** | 173 | /** |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 7def3d58da18..e5e6f504d8cc 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
| @@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out, | |||
| 1518 | if (out->status != MODE_OK) | 1518 | if (out->status != MODE_OK) |
| 1519 | goto out; | 1519 | goto out; |
| 1520 | 1520 | ||
| 1521 | drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V); | ||
| 1522 | |||
| 1521 | ret = 0; | 1523 | ret = 0; |
| 1522 | 1524 | ||
| 1523 | out: | 1525 | out: |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 522cfd447892..16353ee81651 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c | |||
| @@ -225,6 +225,7 @@ struct iommu_domain *etnaviv_iommu_domain_alloc(struct etnaviv_gpu *gpu) | |||
| 225 | 225 | ||
| 226 | etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; | 226 | etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; |
| 227 | etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; | 227 | etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; |
| 228 | etnaviv_domain->domain.pgsize_bitmap = SZ_4K; | ||
| 228 | etnaviv_domain->domain.geometry.aperture_start = GPU_MEM_START; | 229 | etnaviv_domain->domain.geometry.aperture_start = GPU_MEM_START; |
| 229 | etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START + PT_ENTRIES * SZ_4K - 1; | 230 | etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START + PT_ENTRIES * SZ_4K - 1; |
| 230 | 231 | ||
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index f6223f907c15..7f9901b7777b 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include "exynos_drm_plane.h" | 31 | #include "exynos_drm_plane.h" |
| 32 | #include "exynos_drm_drv.h" | 32 | #include "exynos_drm_drv.h" |
| 33 | #include "exynos_drm_fb.h" | 33 | #include "exynos_drm_fb.h" |
| 34 | #include "exynos_drm_fbdev.h" | ||
| 35 | #include "exynos_drm_iommu.h" | 34 | #include "exynos_drm_iommu.h" |
| 36 | 35 | ||
| 37 | /* | 36 | /* |
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 468498e3fec1..4c1fb3f8b5a6 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | struct exynos_dp_device { | 35 | struct exynos_dp_device { |
| 36 | struct drm_encoder encoder; | 36 | struct drm_encoder encoder; |
| 37 | struct drm_connector connector; | 37 | struct drm_connector *connector; |
| 38 | struct drm_bridge *ptn_bridge; | 38 | struct drm_bridge *ptn_bridge; |
| 39 | struct drm_device *drm_dev; | 39 | struct drm_device *drm_dev; |
| 40 | struct device *dev; | 40 | struct device *dev; |
| @@ -70,7 +70,7 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data) | |||
| 70 | static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data) | 70 | static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data) |
| 71 | { | 71 | { |
| 72 | struct exynos_dp_device *dp = to_dp(plat_data); | 72 | struct exynos_dp_device *dp = to_dp(plat_data); |
| 73 | struct drm_connector *connector = &dp->connector; | 73 | struct drm_connector *connector = dp->connector; |
| 74 | struct drm_display_mode *mode; | 74 | struct drm_display_mode *mode; |
| 75 | int num_modes = 0; | 75 | int num_modes = 0; |
| 76 | 76 | ||
| @@ -103,6 +103,7 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, | |||
| 103 | int ret; | 103 | int ret; |
| 104 | 104 | ||
| 105 | drm_connector_register(connector); | 105 | drm_connector_register(connector); |
| 106 | dp->connector = connector; | ||
| 106 | 107 | ||
| 107 | /* Pre-empt DP connector creation if there's a bridge */ | 108 | /* Pre-empt DP connector creation if there's a bridge */ |
| 108 | if (dp->ptn_bridge) { | 109 | if (dp->ptn_bridge) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 011211e4167d..edbd98ff293e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <drm/drmP.h> | 15 | #include <drm/drmP.h> |
| 16 | #include "exynos_drm_drv.h" | 16 | #include "exynos_drm_drv.h" |
| 17 | #include "exynos_drm_crtc.h" | 17 | #include "exynos_drm_crtc.h" |
| 18 | #include "exynos_drm_fbdev.h" | ||
| 19 | 18 | ||
| 20 | static LIST_HEAD(exynos_drm_subdrv_list); | 19 | static LIST_HEAD(exynos_drm_subdrv_list); |
| 21 | 20 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 3efe1aa89416..d47216488985 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | 30 | ||
| 31 | #include "exynos_drm_drv.h" | 31 | #include "exynos_drm_drv.h" |
| 32 | #include "exynos_drm_fb.h" | 32 | #include "exynos_drm_fb.h" |
| 33 | #include "exynos_drm_fbdev.h" | ||
| 34 | #include "exynos_drm_crtc.h" | 33 | #include "exynos_drm_crtc.h" |
| 35 | #include "exynos_drm_plane.h" | 34 | #include "exynos_drm_plane.h" |
| 36 | #include "exynos_drm_iommu.h" | 35 | #include "exynos_drm_iommu.h" |
| @@ -120,7 +119,6 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = { | |||
| 120 | .timing_base = 0x0, | 119 | .timing_base = 0x0, |
| 121 | .has_clksel = 1, | 120 | .has_clksel = 1, |
| 122 | .has_limited_fmt = 1, | 121 | .has_limited_fmt = 1, |
| 123 | .has_hw_trigger = 1, | ||
| 124 | }; | 122 | }; |
| 125 | 123 | ||
| 126 | static struct fimd_driver_data exynos3_fimd_driver_data = { | 124 | static struct fimd_driver_data exynos3_fimd_driver_data = { |
| @@ -171,14 +169,11 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = { | |||
| 171 | .lcdblk_vt_shift = 24, | 169 | .lcdblk_vt_shift = 24, |
| 172 | .lcdblk_bypass_shift = 15, | 170 | .lcdblk_bypass_shift = 15, |
| 173 | .lcdblk_mic_bypass_shift = 11, | 171 | .lcdblk_mic_bypass_shift = 11, |
| 174 | .trg_type = I80_HW_TRG, | ||
| 175 | .has_shadowcon = 1, | 172 | .has_shadowcon = 1, |
| 176 | .has_vidoutcon = 1, | 173 | .has_vidoutcon = 1, |
| 177 | .has_vtsel = 1, | 174 | .has_vtsel = 1, |
| 178 | .has_mic_bypass = 1, | 175 | .has_mic_bypass = 1, |
| 179 | .has_dp_clk = 1, | 176 | .has_dp_clk = 1, |
| 180 | .has_hw_trigger = 1, | ||
| 181 | .has_trigger_per_te = 1, | ||
| 182 | }; | 177 | }; |
| 183 | 178 | ||
| 184 | struct fimd_context { | 179 | struct fimd_context { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 493552368295..8564c3da0d22 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
| @@ -48,13 +48,13 @@ | |||
| 48 | 48 | ||
| 49 | /* registers for base address */ | 49 | /* registers for base address */ |
| 50 | #define G2D_SRC_BASE_ADDR 0x0304 | 50 | #define G2D_SRC_BASE_ADDR 0x0304 |
| 51 | #define G2D_SRC_STRIDE_REG 0x0308 | 51 | #define G2D_SRC_STRIDE 0x0308 |
| 52 | #define G2D_SRC_COLOR_MODE 0x030C | 52 | #define G2D_SRC_COLOR_MODE 0x030C |
| 53 | #define G2D_SRC_LEFT_TOP 0x0310 | 53 | #define G2D_SRC_LEFT_TOP 0x0310 |
| 54 | #define G2D_SRC_RIGHT_BOTTOM 0x0314 | 54 | #define G2D_SRC_RIGHT_BOTTOM 0x0314 |
| 55 | #define G2D_SRC_PLANE2_BASE_ADDR 0x0318 | 55 | #define G2D_SRC_PLANE2_BASE_ADDR 0x0318 |
| 56 | #define G2D_DST_BASE_ADDR 0x0404 | 56 | #define G2D_DST_BASE_ADDR 0x0404 |
| 57 | #define G2D_DST_STRIDE_REG 0x0408 | 57 | #define G2D_DST_STRIDE 0x0408 |
| 58 | #define G2D_DST_COLOR_MODE 0x040C | 58 | #define G2D_DST_COLOR_MODE 0x040C |
| 59 | #define G2D_DST_LEFT_TOP 0x0410 | 59 | #define G2D_DST_LEFT_TOP 0x0410 |
| 60 | #define G2D_DST_RIGHT_BOTTOM 0x0414 | 60 | #define G2D_DST_RIGHT_BOTTOM 0x0414 |
| @@ -563,7 +563,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) | |||
| 563 | 563 | ||
| 564 | switch (reg_offset) { | 564 | switch (reg_offset) { |
| 565 | case G2D_SRC_BASE_ADDR: | 565 | case G2D_SRC_BASE_ADDR: |
| 566 | case G2D_SRC_STRIDE_REG: | 566 | case G2D_SRC_STRIDE: |
| 567 | case G2D_SRC_COLOR_MODE: | 567 | case G2D_SRC_COLOR_MODE: |
| 568 | case G2D_SRC_LEFT_TOP: | 568 | case G2D_SRC_LEFT_TOP: |
| 569 | case G2D_SRC_RIGHT_BOTTOM: | 569 | case G2D_SRC_RIGHT_BOTTOM: |
| @@ -573,7 +573,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) | |||
| 573 | reg_type = REG_TYPE_SRC_PLANE2; | 573 | reg_type = REG_TYPE_SRC_PLANE2; |
| 574 | break; | 574 | break; |
| 575 | case G2D_DST_BASE_ADDR: | 575 | case G2D_DST_BASE_ADDR: |
| 576 | case G2D_DST_STRIDE_REG: | 576 | case G2D_DST_STRIDE: |
| 577 | case G2D_DST_COLOR_MODE: | 577 | case G2D_DST_COLOR_MODE: |
| 578 | case G2D_DST_LEFT_TOP: | 578 | case G2D_DST_LEFT_TOP: |
| 579 | case G2D_DST_RIGHT_BOTTOM: | 579 | case G2D_DST_RIGHT_BOTTOM: |
| @@ -968,8 +968,8 @@ static int g2d_check_reg_offset(struct device *dev, | |||
| 968 | } else | 968 | } else |
| 969 | buf_info->types[reg_type] = BUF_TYPE_GEM; | 969 | buf_info->types[reg_type] = BUF_TYPE_GEM; |
| 970 | break; | 970 | break; |
| 971 | case G2D_SRC_STRIDE_REG: | 971 | case G2D_SRC_STRIDE: |
| 972 | case G2D_DST_STRIDE_REG: | 972 | case G2D_DST_STRIDE: |
| 973 | if (for_addr) | 973 | if (for_addr) |
| 974 | goto err; | 974 | goto err; |
| 975 | 975 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 55f1d37c666a..77f12c00abf9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
| @@ -242,7 +242,7 @@ exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config, | |||
| 242 | state->v_ratio == (1 << 15)) | 242 | state->v_ratio == (1 << 15)) |
| 243 | height_ok = true; | 243 | height_ok = true; |
| 244 | 244 | ||
| 245 | if (width_ok & height_ok) | 245 | if (width_ok && height_ok) |
| 246 | return 0; | 246 | return 0; |
| 247 | 247 | ||
| 248 | DRM_DEBUG_KMS("scaling mode is not supported"); | 248 | DRM_DEBUG_KMS("scaling mode is not supported"); |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 0ec1ad961e0d..dc723f7ead7d 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | |||
| @@ -42,9 +42,10 @@ static const struct regmap_config fsl_dcu_regmap_config = { | |||
| 42 | .reg_bits = 32, | 42 | .reg_bits = 32, |
| 43 | .reg_stride = 4, | 43 | .reg_stride = 4, |
| 44 | .val_bits = 32, | 44 | .val_bits = 32, |
| 45 | .cache_type = REGCACHE_RBTREE, | 45 | .cache_type = REGCACHE_FLAT, |
| 46 | 46 | ||
| 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, | 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, |
| 48 | .max_register = 0x11fc, | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) | 51 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5faacc6e548d..7c334e902266 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -3481,6 +3481,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv); | |||
| 3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); | 3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); |
| 3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); | 3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); |
| 3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); | 3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); |
| 3484 | bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port); | ||
| 3484 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); | 3485 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); |
| 3485 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); | 3486 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); |
| 3486 | bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); | 3487 | bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b235b6e88ead..b9022fa053d6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -139,6 +139,11 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | |||
| 139 | else | 139 | else |
| 140 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | 140 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; |
| 141 | 141 | ||
| 142 | panel_fixed_mode->width_mm = (dvo_timing->himage_hi << 8) | | ||
| 143 | dvo_timing->himage_lo; | ||
| 144 | panel_fixed_mode->height_mm = (dvo_timing->vimage_hi << 8) | | ||
| 145 | dvo_timing->vimage_lo; | ||
| 146 | |||
| 142 | /* Some VBTs have bogus h/vtotal values */ | 147 | /* Some VBTs have bogus h/vtotal values */ |
| 143 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 148 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
| 144 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | 149 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
| @@ -1187,7 +1192,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
| 1187 | } | 1192 | } |
| 1188 | if (bdb->version < 106) { | 1193 | if (bdb->version < 106) { |
| 1189 | expected_size = 22; | 1194 | expected_size = 22; |
| 1190 | } else if (bdb->version < 109) { | 1195 | } else if (bdb->version < 111) { |
| 1191 | expected_size = 27; | 1196 | expected_size = 27; |
| 1192 | } else if (bdb->version < 195) { | 1197 | } else if (bdb->version < 195) { |
| 1193 | BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); | 1198 | BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); |
| @@ -1546,6 +1551,45 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin) | |||
| 1546 | } | 1551 | } |
| 1547 | 1552 | ||
| 1548 | /** | 1553 | /** |
| 1554 | * intel_bios_is_port_present - is the specified digital port present | ||
| 1555 | * @dev_priv: i915 device instance | ||
| 1556 | * @port: port to check | ||
| 1557 | * | ||
| 1558 | * Return true if the device in %port is present. | ||
| 1559 | */ | ||
| 1560 | bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port) | ||
| 1561 | { | ||
| 1562 | static const struct { | ||
| 1563 | u16 dp, hdmi; | ||
| 1564 | } port_mapping[] = { | ||
| 1565 | [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, | ||
| 1566 | [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, | ||
| 1567 | [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, | ||
| 1568 | [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, | ||
| 1569 | }; | ||
| 1570 | int i; | ||
| 1571 | |||
| 1572 | /* FIXME maybe deal with port A as well? */ | ||
| 1573 | if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping)) | ||
| 1574 | return false; | ||
| 1575 | |||
| 1576 | if (!dev_priv->vbt.child_dev_num) | ||
| 1577 | return false; | ||
| 1578 | |||
| 1579 | for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { | ||
| 1580 | const union child_device_config *p_child = | ||
| 1581 | &dev_priv->vbt.child_dev[i]; | ||
| 1582 | if ((p_child->common.dvo_port == port_mapping[port].dp || | ||
| 1583 | p_child->common.dvo_port == port_mapping[port].hdmi) && | ||
| 1584 | (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING | | ||
| 1585 | DEVICE_TYPE_DISPLAYPORT_OUTPUT))) | ||
| 1586 | return true; | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | return false; | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | /** | ||
| 1549 | * intel_bios_is_port_edp - is the device in given port eDP | 1593 | * intel_bios_is_port_edp - is the device in given port eDP |
| 1550 | * @dev_priv: i915 device instance | 1594 | * @dev_priv: i915 device instance |
| 1551 | * @port: port to check | 1595 | * @port: port to check |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2113f401f0ba..56a1637c864f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -8275,12 +8275,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
| 8275 | { | 8275 | { |
| 8276 | struct drm_i915_private *dev_priv = dev->dev_private; | 8276 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 8277 | struct intel_encoder *encoder; | 8277 | struct intel_encoder *encoder; |
| 8278 | int i; | ||
| 8278 | u32 val, final; | 8279 | u32 val, final; |
| 8279 | bool has_lvds = false; | 8280 | bool has_lvds = false; |
| 8280 | bool has_cpu_edp = false; | 8281 | bool has_cpu_edp = false; |
| 8281 | bool has_panel = false; | 8282 | bool has_panel = false; |
| 8282 | bool has_ck505 = false; | 8283 | bool has_ck505 = false; |
| 8283 | bool can_ssc = false; | 8284 | bool can_ssc = false; |
| 8285 | bool using_ssc_source = false; | ||
| 8284 | 8286 | ||
| 8285 | /* We need to take the global config into account */ | 8287 | /* We need to take the global config into account */ |
| 8286 | for_each_intel_encoder(dev, encoder) { | 8288 | for_each_intel_encoder(dev, encoder) { |
| @@ -8307,8 +8309,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
| 8307 | can_ssc = true; | 8309 | can_ssc = true; |
| 8308 | } | 8310 | } |
| 8309 | 8311 | ||
| 8310 | DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n", | 8312 | /* Check if any DPLLs are using the SSC source */ |
| 8311 | has_panel, has_lvds, has_ck505); | 8313 | for (i = 0; i < dev_priv->num_shared_dpll; i++) { |
| 8314 | u32 temp = I915_READ(PCH_DPLL(i)); | ||
| 8315 | |||
| 8316 | if (!(temp & DPLL_VCO_ENABLE)) | ||
| 8317 | continue; | ||
| 8318 | |||
| 8319 | if ((temp & PLL_REF_INPUT_MASK) == | ||
| 8320 | PLLB_REF_INPUT_SPREADSPECTRUMIN) { | ||
| 8321 | using_ssc_source = true; | ||
| 8322 | break; | ||
| 8323 | } | ||
| 8324 | } | ||
| 8325 | |||
| 8326 | DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n", | ||
| 8327 | has_panel, has_lvds, has_ck505, using_ssc_source); | ||
| 8312 | 8328 | ||
| 8313 | /* Ironlake: try to setup display ref clock before DPLL | 8329 | /* Ironlake: try to setup display ref clock before DPLL |
| 8314 | * enabling. This is only under driver's control after | 8330 | * enabling. This is only under driver's control after |
| @@ -8345,9 +8361,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
| 8345 | final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | 8361 | final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; |
| 8346 | } else | 8362 | } else |
| 8347 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | 8363 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; |
| 8348 | } else { | 8364 | } else if (using_ssc_source) { |
| 8349 | final |= DREF_SSC_SOURCE_DISABLE; | 8365 | final |= DREF_SSC_SOURCE_ENABLE; |
| 8350 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | 8366 | final |= DREF_SSC1_ENABLE; |
| 8351 | } | 8367 | } |
| 8352 | 8368 | ||
| 8353 | if (final == val) | 8369 | if (final == val) |
| @@ -8393,7 +8409,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
| 8393 | POSTING_READ(PCH_DREF_CONTROL); | 8409 | POSTING_READ(PCH_DREF_CONTROL); |
| 8394 | udelay(200); | 8410 | udelay(200); |
| 8395 | } else { | 8411 | } else { |
| 8396 | DRM_DEBUG_KMS("Disabling SSC entirely\n"); | 8412 | DRM_DEBUG_KMS("Disabling CPU source output\n"); |
| 8397 | 8413 | ||
| 8398 | val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | 8414 | val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; |
| 8399 | 8415 | ||
| @@ -8404,16 +8420,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
| 8404 | POSTING_READ(PCH_DREF_CONTROL); | 8420 | POSTING_READ(PCH_DREF_CONTROL); |
| 8405 | udelay(200); | 8421 | udelay(200); |
| 8406 | 8422 | ||
| 8407 | /* Turn off the SSC source */ | 8423 | if (!using_ssc_source) { |
| 8408 | val &= ~DREF_SSC_SOURCE_MASK; | 8424 | DRM_DEBUG_KMS("Disabling SSC source\n"); |
| 8409 | val |= DREF_SSC_SOURCE_DISABLE; | ||
| 8410 | 8425 | ||
| 8411 | /* Turn off SSC1 */ | 8426 | /* Turn off the SSC source */ |
| 8412 | val &= ~DREF_SSC1_ENABLE; | 8427 | val &= ~DREF_SSC_SOURCE_MASK; |
| 8428 | val |= DREF_SSC_SOURCE_DISABLE; | ||
| 8413 | 8429 | ||
| 8414 | I915_WRITE(PCH_DREF_CONTROL, val); | 8430 | /* Turn off SSC1 */ |
| 8415 | POSTING_READ(PCH_DREF_CONTROL); | 8431 | val &= ~DREF_SSC1_ENABLE; |
| 8416 | udelay(200); | 8432 | |
| 8433 | I915_WRITE(PCH_DREF_CONTROL, val); | ||
| 8434 | POSTING_READ(PCH_DREF_CONTROL); | ||
| 8435 | udelay(200); | ||
| 8436 | } | ||
| 8417 | } | 8437 | } |
| 8418 | 8438 | ||
| 8419 | BUG_ON(val != final); | 8439 | BUG_ON(val != final); |
| @@ -14554,6 +14574,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
| 14554 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | 14574 | if (I915_READ(PCH_DP_D) & DP_DETECTED) |
| 14555 | intel_dp_init(dev, PCH_DP_D, PORT_D); | 14575 | intel_dp_init(dev, PCH_DP_D, PORT_D); |
| 14556 | } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { | 14576 | } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { |
| 14577 | bool has_edp, has_port; | ||
| 14578 | |||
| 14557 | /* | 14579 | /* |
| 14558 | * The DP_DETECTED bit is the latched state of the DDC | 14580 | * The DP_DETECTED bit is the latched state of the DDC |
| 14559 | * SDA pin at boot. However since eDP doesn't require DDC | 14581 | * SDA pin at boot. However since eDP doesn't require DDC |
| @@ -14562,27 +14584,37 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
| 14562 | * Thus we can't rely on the DP_DETECTED bit alone to detect | 14584 | * Thus we can't rely on the DP_DETECTED bit alone to detect |
| 14563 | * eDP ports. Consult the VBT as well as DP_DETECTED to | 14585 | * eDP ports. Consult the VBT as well as DP_DETECTED to |
| 14564 | * detect eDP ports. | 14586 | * detect eDP ports. |
| 14587 | * | ||
| 14588 | * Sadly the straps seem to be missing sometimes even for HDMI | ||
| 14589 | * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap | ||
| 14590 | * and VBT for the presence of the port. Additionally we can't | ||
| 14591 | * trust the port type the VBT declares as we've seen at least | ||
| 14592 | * HDMI ports that the VBT claim are DP or eDP. | ||
| 14565 | */ | 14593 | */ |
| 14566 | if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && | 14594 | has_edp = intel_dp_is_edp(dev, PORT_B); |
| 14567 | !intel_dp_is_edp(dev, PORT_B)) | 14595 | has_port = intel_bios_is_port_present(dev_priv, PORT_B); |
| 14596 | if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port) | ||
| 14597 | has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B); | ||
| 14598 | if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) | ||
| 14568 | intel_hdmi_init(dev, VLV_HDMIB, PORT_B); | 14599 | intel_hdmi_init(dev, VLV_HDMIB, PORT_B); |
| 14569 | if (I915_READ(VLV_DP_B) & DP_DETECTED || | ||
| 14570 | intel_dp_is_edp(dev, PORT_B)) | ||
| 14571 | intel_dp_init(dev, VLV_DP_B, PORT_B); | ||
| 14572 | 14600 | ||
| 14573 | if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && | 14601 | has_edp = intel_dp_is_edp(dev, PORT_C); |
| 14574 | !intel_dp_is_edp(dev, PORT_C)) | 14602 | has_port = intel_bios_is_port_present(dev_priv, PORT_C); |
| 14603 | if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port) | ||
| 14604 | has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C); | ||
| 14605 | if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) | ||
| 14575 | intel_hdmi_init(dev, VLV_HDMIC, PORT_C); | 14606 | intel_hdmi_init(dev, VLV_HDMIC, PORT_C); |
| 14576 | if (I915_READ(VLV_DP_C) & DP_DETECTED || | ||
| 14577 | intel_dp_is_edp(dev, PORT_C)) | ||
| 14578 | intel_dp_init(dev, VLV_DP_C, PORT_C); | ||
| 14579 | 14607 | ||
| 14580 | if (IS_CHERRYVIEW(dev)) { | 14608 | if (IS_CHERRYVIEW(dev)) { |
| 14581 | /* eDP not supported on port D, so don't check VBT */ | 14609 | /* |
| 14582 | if (I915_READ(CHV_HDMID) & SDVO_DETECTED) | 14610 | * eDP not supported on port D, |
| 14583 | intel_hdmi_init(dev, CHV_HDMID, PORT_D); | 14611 | * so no need to worry about it |
| 14584 | if (I915_READ(CHV_DP_D) & DP_DETECTED) | 14612 | */ |
| 14613 | has_port = intel_bios_is_port_present(dev_priv, PORT_D); | ||
| 14614 | if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port) | ||
| 14585 | intel_dp_init(dev, CHV_DP_D, PORT_D); | 14615 | intel_dp_init(dev, CHV_DP_D, PORT_D); |
| 14616 | if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port) | ||
| 14617 | intel_hdmi_init(dev, CHV_HDMID, PORT_D); | ||
| 14586 | } | 14618 | } |
| 14587 | 14619 | ||
| 14588 | intel_dsi_init(dev); | 14620 | intel_dsi_init(dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f192f58708c2..79cf2d5f5a20 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -4977,9 +4977,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
| 4977 | intel_display_power_get(dev_priv, power_domain); | 4977 | intel_display_power_get(dev_priv, power_domain); |
| 4978 | 4978 | ||
| 4979 | if (long_hpd) { | 4979 | if (long_hpd) { |
| 4980 | /* indicate that we need to restart link training */ | ||
| 4981 | intel_dp->train_set_valid = false; | ||
| 4982 | |||
| 4983 | intel_dp_long_pulse(intel_dp->attached_connector); | 4980 | intel_dp_long_pulse(intel_dp->attached_connector); |
| 4984 | if (intel_dp->is_mst) | 4981 | if (intel_dp->is_mst) |
| 4985 | ret = IRQ_HANDLED; | 4982 | ret = IRQ_HANDLED; |
| @@ -5725,8 +5722,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
| 5725 | if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { | 5722 | if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { |
| 5726 | fixed_mode = drm_mode_duplicate(dev, | 5723 | fixed_mode = drm_mode_duplicate(dev, |
| 5727 | dev_priv->vbt.lfp_lvds_vbt_mode); | 5724 | dev_priv->vbt.lfp_lvds_vbt_mode); |
| 5728 | if (fixed_mode) | 5725 | if (fixed_mode) { |
| 5729 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; | 5726 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 5727 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
| 5728 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
| 5729 | } | ||
| 5730 | } | 5730 | } |
| 5731 | mutex_unlock(&dev->mode_config.mutex); | 5731 | mutex_unlock(&dev->mode_config.mutex); |
| 5732 | 5732 | ||
| @@ -5923,9 +5923,9 @@ fail: | |||
| 5923 | return false; | 5923 | return false; |
| 5924 | } | 5924 | } |
| 5925 | 5925 | ||
| 5926 | void | 5926 | bool intel_dp_init(struct drm_device *dev, |
| 5927 | intel_dp_init(struct drm_device *dev, | 5927 | i915_reg_t output_reg, |
| 5928 | i915_reg_t output_reg, enum port port) | 5928 | enum port port) |
| 5929 | { | 5929 | { |
| 5930 | struct drm_i915_private *dev_priv = dev->dev_private; | 5930 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5931 | struct intel_digital_port *intel_dig_port; | 5931 | struct intel_digital_port *intel_dig_port; |
| @@ -5935,7 +5935,7 @@ intel_dp_init(struct drm_device *dev, | |||
| 5935 | 5935 | ||
| 5936 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); | 5936 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); |
| 5937 | if (!intel_dig_port) | 5937 | if (!intel_dig_port) |
| 5938 | return; | 5938 | return false; |
| 5939 | 5939 | ||
| 5940 | intel_connector = intel_connector_alloc(); | 5940 | intel_connector = intel_connector_alloc(); |
| 5941 | if (!intel_connector) | 5941 | if (!intel_connector) |
| @@ -5992,7 +5992,7 @@ intel_dp_init(struct drm_device *dev, | |||
| 5992 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) | 5992 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) |
| 5993 | goto err_init_connector; | 5993 | goto err_init_connector; |
| 5994 | 5994 | ||
| 5995 | return; | 5995 | return true; |
| 5996 | 5996 | ||
| 5997 | err_init_connector: | 5997 | err_init_connector: |
| 5998 | drm_encoder_cleanup(encoder); | 5998 | drm_encoder_cleanup(encoder); |
| @@ -6000,8 +6000,7 @@ err_encoder_init: | |||
| 6000 | kfree(intel_connector); | 6000 | kfree(intel_connector); |
| 6001 | err_connector_alloc: | 6001 | err_connector_alloc: |
| 6002 | kfree(intel_dig_port); | 6002 | kfree(intel_dig_port); |
| 6003 | 6003 | return false; | |
| 6004 | return; | ||
| 6005 | } | 6004 | } |
| 6006 | 6005 | ||
| 6007 | void intel_dp_mst_suspend(struct drm_device *dev) | 6006 | void intel_dp_mst_suspend(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 0b8eefc2acc5..60fb39cd220b 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c | |||
| @@ -85,8 +85,7 @@ static bool | |||
| 85 | intel_dp_reset_link_train(struct intel_dp *intel_dp, | 85 | intel_dp_reset_link_train(struct intel_dp *intel_dp, |
| 86 | uint8_t dp_train_pat) | 86 | uint8_t dp_train_pat) |
| 87 | { | 87 | { |
| 88 | if (!intel_dp->train_set_valid) | 88 | memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); |
| 89 | memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); | ||
| 90 | intel_dp_set_signal_levels(intel_dp); | 89 | intel_dp_set_signal_levels(intel_dp); |
| 91 | return intel_dp_set_link_train(intel_dp, dp_train_pat); | 90 | return intel_dp_set_link_train(intel_dp, dp_train_pat); |
| 92 | } | 91 | } |
| @@ -161,23 +160,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) | |||
| 161 | break; | 160 | break; |
| 162 | } | 161 | } |
| 163 | 162 | ||
| 164 | /* | ||
| 165 | * if we used previously trained voltage and pre-emphasis values | ||
| 166 | * and we don't get clock recovery, reset link training values | ||
| 167 | */ | ||
| 168 | if (intel_dp->train_set_valid) { | ||
| 169 | DRM_DEBUG_KMS("clock recovery not ok, reset"); | ||
| 170 | /* clear the flag as we are not reusing train set */ | ||
| 171 | intel_dp->train_set_valid = false; | ||
| 172 | if (!intel_dp_reset_link_train(intel_dp, | ||
| 173 | DP_TRAINING_PATTERN_1 | | ||
| 174 | DP_LINK_SCRAMBLING_DISABLE)) { | ||
| 175 | DRM_ERROR("failed to enable link training\n"); | ||
| 176 | return; | ||
| 177 | } | ||
| 178 | continue; | ||
| 179 | } | ||
| 180 | |||
| 181 | /* Check to see if we've tried the max voltage */ | 163 | /* Check to see if we've tried the max voltage */ |
| 182 | for (i = 0; i < intel_dp->lane_count; i++) | 164 | for (i = 0; i < intel_dp->lane_count; i++) |
| 183 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 165 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
| @@ -284,7 +266,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) | |||
| 284 | /* Make sure clock is still ok */ | 266 | /* Make sure clock is still ok */ |
| 285 | if (!drm_dp_clock_recovery_ok(link_status, | 267 | if (!drm_dp_clock_recovery_ok(link_status, |
| 286 | intel_dp->lane_count)) { | 268 | intel_dp->lane_count)) { |
| 287 | intel_dp->train_set_valid = false; | ||
| 288 | intel_dp_link_training_clock_recovery(intel_dp); | 269 | intel_dp_link_training_clock_recovery(intel_dp); |
| 289 | intel_dp_set_link_train(intel_dp, | 270 | intel_dp_set_link_train(intel_dp, |
| 290 | training_pattern | | 271 | training_pattern | |
| @@ -301,7 +282,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) | |||
| 301 | 282 | ||
| 302 | /* Try 5 times, then try clock recovery if that fails */ | 283 | /* Try 5 times, then try clock recovery if that fails */ |
| 303 | if (tries > 5) { | 284 | if (tries > 5) { |
| 304 | intel_dp->train_set_valid = false; | ||
| 305 | intel_dp_link_training_clock_recovery(intel_dp); | 285 | intel_dp_link_training_clock_recovery(intel_dp); |
| 306 | intel_dp_set_link_train(intel_dp, | 286 | intel_dp_set_link_train(intel_dp, |
| 307 | training_pattern | | 287 | training_pattern | |
| @@ -322,10 +302,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) | |||
| 322 | 302 | ||
| 323 | intel_dp_set_idle_link_train(intel_dp); | 303 | intel_dp_set_idle_link_train(intel_dp); |
| 324 | 304 | ||
| 325 | if (channel_eq) { | 305 | if (channel_eq) |
| 326 | intel_dp->train_set_valid = true; | ||
| 327 | DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); | 306 | DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); |
| 328 | } | ||
| 329 | } | 307 | } |
| 330 | 308 | ||
| 331 | void intel_dp_stop_link_train(struct intel_dp *intel_dp) | 309 | void intel_dp_stop_link_train(struct intel_dp *intel_dp) |
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 3ac705936b04..baf6f5584cbd 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c | |||
| @@ -366,6 +366,9 @@ ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
| 366 | DPLL_ID_PCH_PLL_B); | 366 | DPLL_ID_PCH_PLL_B); |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | if (!pll) | ||
| 370 | return NULL; | ||
| 371 | |||
| 369 | /* reference the pll */ | 372 | /* reference the pll */ |
| 370 | intel_reference_shared_dpll(pll, crtc_state); | 373 | intel_reference_shared_dpll(pll, crtc_state); |
| 371 | 374 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a28b4aac1e02..f7f0f01814f6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -863,8 +863,6 @@ struct intel_dp { | |||
| 863 | /* This is called before a link training is starterd */ | 863 | /* This is called before a link training is starterd */ |
| 864 | void (*prepare_link_retrain)(struct intel_dp *intel_dp); | 864 | void (*prepare_link_retrain)(struct intel_dp *intel_dp); |
| 865 | 865 | ||
| 866 | bool train_set_valid; | ||
| 867 | |||
| 868 | /* Displayport compliance testing */ | 866 | /* Displayport compliance testing */ |
| 869 | unsigned long compliance_test_type; | 867 | unsigned long compliance_test_type; |
| 870 | unsigned long compliance_test_data; | 868 | unsigned long compliance_test_data; |
| @@ -1284,7 +1282,7 @@ void intel_csr_ucode_suspend(struct drm_i915_private *); | |||
| 1284 | void intel_csr_ucode_resume(struct drm_i915_private *); | 1282 | void intel_csr_ucode_resume(struct drm_i915_private *); |
| 1285 | 1283 | ||
| 1286 | /* intel_dp.c */ | 1284 | /* intel_dp.c */ |
| 1287 | void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port); | 1285 | bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port); |
| 1288 | bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | 1286 | bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, |
| 1289 | struct intel_connector *intel_connector); | 1287 | struct intel_connector *intel_connector); |
| 1290 | void intel_dp_set_link_params(struct intel_dp *intel_dp, | 1288 | void intel_dp_set_link_params(struct intel_dp *intel_dp, |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 366ad6c67ce4..4756ef639648 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
| @@ -1545,6 +1545,9 @@ void intel_dsi_init(struct drm_device *dev) | |||
| 1545 | goto err; | 1545 | goto err; |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
| 1549 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
| 1550 | |||
| 1548 | intel_panel_init(&intel_connector->panel, fixed_mode, NULL); | 1551 | intel_panel_init(&intel_connector->panel, fixed_mode, NULL); |
| 1549 | 1552 | ||
| 1550 | intel_dsi_add_properties(intel_connector); | 1553 | intel_dsi_add_properties(intel_connector); |
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index d5a7cfec589b..647127f3aaff 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c | |||
| @@ -824,8 +824,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) | |||
| 824 | { | 824 | { |
| 825 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | 825 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
| 826 | struct intel_fbc *fbc = &dev_priv->fbc; | 826 | struct intel_fbc *fbc = &dev_priv->fbc; |
| 827 | bool enable_by_default = IS_HASWELL(dev_priv) || | 827 | bool enable_by_default = IS_BROADWELL(dev_priv); |
| 828 | IS_BROADWELL(dev_priv); | ||
| 829 | 828 | ||
| 830 | if (intel_vgpu_active(dev_priv->dev)) { | 829 | if (intel_vgpu_active(dev_priv->dev)) { |
| 831 | fbc->no_fbc_reason = "VGPU is active"; | 830 | fbc->no_fbc_reason = "VGPU is active"; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2c3bd9c2573e..a8844702d11b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -2142,6 +2142,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | |||
| 2142 | enum port port = intel_dig_port->port; | 2142 | enum port port = intel_dig_port->port; |
| 2143 | uint8_t alternate_ddc_pin; | 2143 | uint8_t alternate_ddc_pin; |
| 2144 | 2144 | ||
| 2145 | DRM_DEBUG_KMS("Adding HDMI connector on port %c\n", | ||
| 2146 | port_name(port)); | ||
| 2147 | |||
| 2145 | if (WARN(intel_dig_port->max_lanes < 4, | 2148 | if (WARN(intel_dig_port->max_lanes < 4, |
| 2146 | "Not enough lanes (%d) for HDMI on port %c\n", | 2149 | "Not enough lanes (%d) for HDMI on port %c\n", |
| 2147 | intel_dig_port->max_lanes, port_name(port))) | 2150 | intel_dig_port->max_lanes, port_name(port))) |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index bc53c0dd34d0..96281e628d2a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -1082,6 +1082,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 1082 | fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); | 1082 | fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); |
| 1083 | if (fixed_mode) { | 1083 | if (fixed_mode) { |
| 1084 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; | 1084 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 1085 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
| 1086 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
| 1085 | goto out; | 1087 | goto out; |
| 1086 | } | 1088 | } |
| 1087 | } | 1089 | } |
diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h index c15051de8023..44fb0b35eed3 100644 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h | |||
| @@ -403,9 +403,10 @@ struct lvds_dvo_timing { | |||
| 403 | u8 vsync_off:4; | 403 | u8 vsync_off:4; |
| 404 | u8 rsvd0:6; | 404 | u8 rsvd0:6; |
| 405 | u8 hsync_off_hi:2; | 405 | u8 hsync_off_hi:2; |
| 406 | u8 h_image; | 406 | u8 himage_lo; |
| 407 | u8 v_image; | 407 | u8 vimage_lo; |
| 408 | u8 max_hv; | 408 | u8 vimage_hi:4; |
| 409 | u8 himage_hi:4; | ||
| 409 | u8 h_border; | 410 | u8 h_border; |
| 410 | u8 v_border; | 411 | u8 v_border; |
| 411 | u8 rsvd1:3; | 412 | u8 rsvd1:3; |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 1f14b602882b..82656654fb21 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
| @@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) | |||
| 97 | return NULL; | 97 | return NULL; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, | 100 | int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, |
| 101 | int hsync_pin, int vsync_pin) | 101 | int hsync_pin, int vsync_pin, u32 bus_flags) |
| 102 | { | 102 | { |
| 103 | struct imx_drm_crtc_helper_funcs *helper; | 103 | struct imx_drm_crtc_helper_funcs *helper; |
| 104 | struct imx_drm_crtc *imx_crtc; | 104 | struct imx_drm_crtc *imx_crtc; |
| @@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, | |||
| 110 | helper = &imx_crtc->imx_drm_helper_funcs; | 110 | helper = &imx_crtc->imx_drm_helper_funcs; |
| 111 | if (helper->set_interface_pix_fmt) | 111 | if (helper->set_interface_pix_fmt) |
| 112 | return helper->set_interface_pix_fmt(encoder->crtc, | 112 | return helper->set_interface_pix_fmt(encoder->crtc, |
| 113 | bus_format, hsync_pin, vsync_pin); | 113 | bus_format, hsync_pin, vsync_pin, |
| 114 | bus_flags); | ||
| 114 | return 0; | 115 | return 0; |
| 115 | } | 116 | } |
| 116 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins); | 117 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_config); |
| 117 | 118 | ||
| 118 | int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) | 119 | int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) |
| 119 | { | 120 | { |
| 120 | return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3); | 121 | return imx_drm_set_bus_config(encoder, bus_format, 2, 3, |
| 122 | DRM_BUS_FLAG_DE_HIGH | | ||
| 123 | DRM_BUS_FLAG_PIXDATA_NEGEDGE); | ||
| 121 | } | 124 | } |
| 122 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); | 125 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); |
| 123 | 126 | ||
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h index b0241b9d1334..74320a1723b7 100644 --- a/drivers/gpu/drm/imx/imx-drm.h +++ b/drivers/gpu/drm/imx/imx-drm.h | |||
| @@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs { | |||
| 19 | int (*enable_vblank)(struct drm_crtc *crtc); | 19 | int (*enable_vblank)(struct drm_crtc *crtc); |
| 20 | void (*disable_vblank)(struct drm_crtc *crtc); | 20 | void (*disable_vblank)(struct drm_crtc *crtc); |
| 21 | int (*set_interface_pix_fmt)(struct drm_crtc *crtc, | 21 | int (*set_interface_pix_fmt)(struct drm_crtc *crtc, |
| 22 | u32 bus_format, int hsync_pin, int vsync_pin); | 22 | u32 bus_format, int hsync_pin, int vsync_pin, |
| 23 | u32 bus_flags); | ||
| 23 | const struct drm_crtc_helper_funcs *crtc_helper_funcs; | 24 | const struct drm_crtc_helper_funcs *crtc_helper_funcs; |
| 24 | const struct drm_crtc_funcs *crtc_funcs; | 25 | const struct drm_crtc_funcs *crtc_funcs; |
| 25 | }; | 26 | }; |
| @@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm); | |||
| 41 | 42 | ||
| 42 | struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); | 43 | struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); |
| 43 | 44 | ||
| 44 | int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, | 45 | int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, |
| 45 | u32 bus_format, int hsync_pin, int vsync_pin); | 46 | int hsync_pin, int vsync_pin, u32 bus_flags); |
| 46 | int imx_drm_set_bus_format(struct drm_encoder *encoder, | 47 | int imx_drm_set_bus_format(struct drm_encoder *encoder, |
| 47 | u32 bus_format); | 48 | u32 bus_format); |
| 48 | 49 | ||
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index a58eee59550a..beff793bb717 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 25 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
| 26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
| 27 | #include <linux/of_graph.h> | 27 | #include <linux/of_graph.h> |
| 28 | #include <video/of_display_timing.h> | ||
| 28 | #include <video/of_videomode.h> | 29 | #include <video/of_videomode.h> |
| 29 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
| 30 | #include <linux/videodev2.h> | 31 | #include <linux/videodev2.h> |
| @@ -59,6 +60,7 @@ struct imx_ldb_channel { | |||
| 59 | struct drm_encoder encoder; | 60 | struct drm_encoder encoder; |
| 60 | struct drm_panel *panel; | 61 | struct drm_panel *panel; |
| 61 | struct device_node *child; | 62 | struct device_node *child; |
| 63 | struct i2c_adapter *ddc; | ||
| 62 | int chno; | 64 | int chno; |
| 63 | void *edid; | 65 | void *edid; |
| 64 | int edid_len; | 66 | int edid_len; |
| @@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) | |||
| 107 | return num_modes; | 109 | return num_modes; |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 112 | if (!imx_ldb_ch->edid && imx_ldb_ch->ddc) | ||
| 113 | imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc); | ||
| 114 | |||
| 110 | if (imx_ldb_ch->edid) { | 115 | if (imx_ldb_ch->edid) { |
| 111 | drm_mode_connector_update_edid_property(connector, | 116 | drm_mode_connector_update_edid_property(connector, |
| 112 | imx_ldb_ch->edid); | 117 | imx_ldb_ch->edid); |
| @@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 553 | 558 | ||
| 554 | for_each_child_of_node(np, child) { | 559 | for_each_child_of_node(np, child) { |
| 555 | struct imx_ldb_channel *channel; | 560 | struct imx_ldb_channel *channel; |
| 556 | struct device_node *port; | 561 | struct device_node *ddc_node; |
| 562 | struct device_node *ep; | ||
| 557 | 563 | ||
| 558 | ret = of_property_read_u32(child, "reg", &i); | 564 | ret = of_property_read_u32(child, "reg", &i); |
| 559 | if (ret || i < 0 || i > 1) | 565 | if (ret || i < 0 || i > 1) |
| @@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 576 | * The output port is port@4 with an external 4-port mux or | 582 | * The output port is port@4 with an external 4-port mux or |
| 577 | * port@2 with the internal 2-port mux. | 583 | * port@2 with the internal 2-port mux. |
| 578 | */ | 584 | */ |
| 579 | port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2); | 585 | ep = of_graph_get_endpoint_by_regs(child, |
| 580 | if (port) { | 586 | imx_ldb->lvds_mux ? 4 : 2, |
| 581 | struct device_node *endpoint, *remote; | 587 | -1); |
| 582 | 588 | if (ep) { | |
| 583 | endpoint = of_get_child_by_name(port, "endpoint"); | 589 | struct device_node *remote; |
| 584 | if (endpoint) { | 590 | |
| 585 | remote = of_graph_get_remote_port_parent(endpoint); | 591 | remote = of_graph_get_remote_port_parent(ep); |
| 586 | if (remote) | 592 | of_node_put(ep); |
| 587 | channel->panel = of_drm_find_panel(remote); | 593 | if (remote) |
| 588 | else | 594 | channel->panel = of_drm_find_panel(remote); |
| 589 | return -EPROBE_DEFER; | 595 | else |
| 590 | if (!channel->panel) { | 596 | return -EPROBE_DEFER; |
| 591 | dev_err(dev, "panel not found: %s\n", | 597 | of_node_put(remote); |
| 592 | remote->full_name); | 598 | if (!channel->panel) { |
| 593 | return -EPROBE_DEFER; | 599 | dev_err(dev, "panel not found: %s\n", |
| 594 | } | 600 | remote->full_name); |
| 601 | return -EPROBE_DEFER; | ||
| 595 | } | 602 | } |
| 596 | } | 603 | } |
| 597 | 604 | ||
| 598 | edidp = of_get_property(child, "edid", &channel->edid_len); | 605 | ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); |
| 599 | if (edidp) { | 606 | if (ddc_node) { |
| 600 | channel->edid = kmemdup(edidp, channel->edid_len, | 607 | channel->ddc = of_find_i2c_adapter_by_node(ddc_node); |
| 601 | GFP_KERNEL); | 608 | of_node_put(ddc_node); |
| 602 | } else if (!channel->panel) { | 609 | if (!channel->ddc) { |
| 603 | ret = of_get_drm_display_mode(child, &channel->mode, 0); | 610 | dev_warn(dev, "failed to get ddc i2c adapter\n"); |
| 604 | if (!ret) | 611 | return -EPROBE_DEFER; |
| 605 | channel->mode_valid = 1; | 612 | } |
| 613 | } | ||
| 614 | |||
| 615 | if (!channel->ddc) { | ||
| 616 | /* if no DDC available, fallback to hardcoded EDID */ | ||
| 617 | dev_dbg(dev, "no ddc available\n"); | ||
| 618 | |||
| 619 | edidp = of_get_property(child, "edid", | ||
| 620 | &channel->edid_len); | ||
| 621 | if (edidp) { | ||
| 622 | channel->edid = kmemdup(edidp, | ||
| 623 | channel->edid_len, | ||
| 624 | GFP_KERNEL); | ||
| 625 | } else if (!channel->panel) { | ||
| 626 | /* fallback to display-timings node */ | ||
| 627 | ret = of_get_drm_display_mode(child, | ||
| 628 | &channel->mode, | ||
| 629 | OF_USE_NATIVE_MODE); | ||
| 630 | if (!ret) | ||
| 631 | channel->mode_valid = 1; | ||
| 632 | } | ||
| 606 | } | 633 | } |
| 607 | 634 | ||
| 608 | channel->bus_format = of_get_bus_format(dev, child); | 635 | channel->bus_format = of_get_bus_format(dev, child); |
| @@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, | |||
| 647 | channel->encoder.funcs->destroy(&channel->encoder); | 674 | channel->encoder.funcs->destroy(&channel->encoder); |
| 648 | 675 | ||
| 649 | kfree(channel->edid); | 676 | kfree(channel->edid); |
| 677 | i2c_put_adapter(channel->ddc); | ||
| 650 | } | 678 | } |
| 651 | } | 679 | } |
| 652 | 680 | ||
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index ae7a9fb3b8a2..baf788121287 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c | |||
| @@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder) | |||
| 294 | 294 | ||
| 295 | switch (tve->mode) { | 295 | switch (tve->mode) { |
| 296 | case TVE_MODE_VGA: | 296 | case TVE_MODE_VGA: |
| 297 | imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24, | 297 | imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24, |
| 298 | tve->hsync_pin, tve->vsync_pin); | 298 | tve->hsync_pin, tve->vsync_pin, |
| 299 | DRM_BUS_FLAG_DE_HIGH | | ||
| 300 | DRM_BUS_FLAG_PIXDATA_NEGEDGE); | ||
| 299 | break; | 301 | break; |
| 300 | case TVE_MODE_TVOUT: | 302 | case TVE_MODE_TVOUT: |
| 301 | imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); | 303 | imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); |
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index b2c30b8d9816..fc040417e1e8 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c | |||
| @@ -66,6 +66,7 @@ struct ipu_crtc { | |||
| 66 | struct ipu_flip_work *flip_work; | 66 | struct ipu_flip_work *flip_work; |
| 67 | int irq; | 67 | int irq; |
| 68 | u32 bus_format; | 68 | u32 bus_format; |
| 69 | u32 bus_flags; | ||
| 69 | int di_hsync_pin; | 70 | int di_hsync_pin; |
| 70 | int di_vsync_pin; | 71 | int di_vsync_pin; |
| 71 | }; | 72 | }; |
| @@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, | |||
| 271 | else | 272 | else |
| 272 | sig_cfg.clkflags = 0; | 273 | sig_cfg.clkflags = 0; |
| 273 | 274 | ||
| 274 | sig_cfg.enable_pol = 1; | 275 | sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW); |
| 275 | sig_cfg.clk_pol = 0; | 276 | /* Default to driving pixel data on negative clock edges */ |
| 277 | sig_cfg.clk_pol = !!(ipu_crtc->bus_flags & | ||
| 278 | DRM_BUS_FLAG_PIXDATA_POSEDGE); | ||
| 276 | sig_cfg.bus_format = ipu_crtc->bus_format; | 279 | sig_cfg.bus_format = ipu_crtc->bus_format; |
| 277 | sig_cfg.v_to_h_sync = 0; | 280 | sig_cfg.v_to_h_sync = 0; |
| 278 | sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; | 281 | sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; |
| @@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) | |||
| 396 | } | 399 | } |
| 397 | 400 | ||
| 398 | static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, | 401 | static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, |
| 399 | u32 bus_format, int hsync_pin, int vsync_pin) | 402 | u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags) |
| 400 | { | 403 | { |
| 401 | struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); | 404 | struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); |
| 402 | 405 | ||
| 403 | ipu_crtc->bus_format = bus_format; | 406 | ipu_crtc->bus_format = bus_format; |
| 407 | ipu_crtc->bus_flags = bus_flags; | ||
| 404 | ipu_crtc->di_hsync_pin = hsync_pin; | 408 | ipu_crtc->di_hsync_pin = hsync_pin; |
| 405 | ipu_crtc->di_vsync_pin = vsync_pin; | 409 | ipu_crtc->di_vsync_pin = vsync_pin; |
| 406 | 410 | ||
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 681ec6eb77d9..a4bb44118d33 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
| @@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = { | |||
| 38 | DRM_FORMAT_RGBX8888, | 38 | DRM_FORMAT_RGBX8888, |
| 39 | DRM_FORMAT_BGRA8888, | 39 | DRM_FORMAT_BGRA8888, |
| 40 | DRM_FORMAT_BGRA8888, | 40 | DRM_FORMAT_BGRA8888, |
| 41 | DRM_FORMAT_UYVY, | ||
| 42 | DRM_FORMAT_VYUY, | ||
| 41 | DRM_FORMAT_YUYV, | 43 | DRM_FORMAT_YUYV, |
| 42 | DRM_FORMAT_YVYU, | 44 | DRM_FORMAT_YVYU, |
| 43 | DRM_FORMAT_YUV420, | 45 | DRM_FORMAT_YUV420, |
| @@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 428 | if (crtc != plane->crtc) | 430 | if (crtc != plane->crtc) |
| 429 | dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", | 431 | dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", |
| 430 | plane->crtc, crtc); | 432 | plane->crtc, crtc); |
| 431 | plane->crtc = crtc; | ||
| 432 | 433 | ||
| 433 | if (!ipu_plane->enabled) | 434 | if (!ipu_plane->enabled) |
| 434 | ipu_plane_enable(ipu_plane); | 435 | ipu_plane_enable(ipu_plane); |
| @@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane) | |||
| 461 | kfree(ipu_plane); | 462 | kfree(ipu_plane); |
| 462 | } | 463 | } |
| 463 | 464 | ||
| 464 | static struct drm_plane_funcs ipu_plane_funcs = { | 465 | static const struct drm_plane_funcs ipu_plane_funcs = { |
| 465 | .update_plane = ipu_update_plane, | 466 | .update_plane = ipu_update_plane, |
| 466 | .disable_plane = ipu_disable_plane, | 467 | .disable_plane = ipu_disable_plane, |
| 467 | .destroy = ipu_plane_destroy, | 468 | .destroy = ipu_plane_destroy, |
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 363e2c7741e2..2d1fd02cd3d6 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c | |||
| @@ -35,7 +35,6 @@ struct imx_parallel_display { | |||
| 35 | void *edid; | 35 | void *edid; |
| 36 | int edid_len; | 36 | int edid_len; |
| 37 | u32 bus_format; | 37 | u32 bus_format; |
| 38 | int mode_valid; | ||
| 39 | struct drm_display_mode mode; | 38 | struct drm_display_mode mode; |
| 40 | struct drm_panel *panel; | 39 | struct drm_panel *panel; |
| 41 | }; | 40 | }; |
| @@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) | |||
| 68 | num_modes = drm_add_edid_modes(connector, imxpd->edid); | 67 | num_modes = drm_add_edid_modes(connector, imxpd->edid); |
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | if (imxpd->mode_valid) { | ||
| 72 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | ||
| 73 | |||
| 74 | if (!mode) | ||
| 75 | return -EINVAL; | ||
| 76 | drm_mode_copy(mode, &imxpd->mode); | ||
| 77 | mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, | ||
| 78 | drm_mode_probed_add(connector, mode); | ||
| 79 | num_modes++; | ||
| 80 | } | ||
| 81 | |||
| 82 | if (np) { | 70 | if (np) { |
| 83 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 71 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
| 84 | 72 | ||
| @@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 115 | static void imx_pd_encoder_prepare(struct drm_encoder *encoder) | 103 | static void imx_pd_encoder_prepare(struct drm_encoder *encoder) |
| 116 | { | 104 | { |
| 117 | struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); | 105 | struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); |
| 118 | 106 | imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, | |
| 119 | imx_drm_set_bus_format(encoder, imxpd->bus_format); | 107 | imxpd->connector.display_info.bus_flags); |
| 120 | } | 108 | } |
| 121 | 109 | ||
| 122 | static void imx_pd_encoder_commit(struct drm_encoder *encoder) | 110 | static void imx_pd_encoder_commit(struct drm_encoder *encoder) |
| @@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 203 | { | 191 | { |
| 204 | struct drm_device *drm = data; | 192 | struct drm_device *drm = data; |
| 205 | struct device_node *np = dev->of_node; | 193 | struct device_node *np = dev->of_node; |
| 206 | struct device_node *port; | 194 | struct device_node *ep; |
| 207 | const u8 *edidp; | 195 | const u8 *edidp; |
| 208 | struct imx_parallel_display *imxpd; | 196 | struct imx_parallel_display *imxpd; |
| 209 | int ret; | 197 | int ret; |
| @@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 230 | } | 218 | } |
| 231 | 219 | ||
| 232 | /* port@1 is the output port */ | 220 | /* port@1 is the output port */ |
| 233 | port = of_graph_get_port_by_id(np, 1); | 221 | ep = of_graph_get_endpoint_by_regs(np, 1, -1); |
| 234 | if (port) { | 222 | if (ep) { |
| 235 | struct device_node *endpoint, *remote; | 223 | struct device_node *remote; |
| 236 | 224 | ||
| 237 | endpoint = of_get_child_by_name(port, "endpoint"); | 225 | remote = of_graph_get_remote_port_parent(ep); |
| 238 | if (endpoint) { | 226 | of_node_put(ep); |
| 239 | remote = of_graph_get_remote_port_parent(endpoint); | 227 | if (remote) { |
| 240 | if (remote) | 228 | imxpd->panel = of_drm_find_panel(remote); |
| 241 | imxpd->panel = of_drm_find_panel(remote); | 229 | of_node_put(remote); |
| 242 | if (!imxpd->panel) | ||
| 243 | return -EPROBE_DEFER; | ||
| 244 | } | 230 | } |
| 231 | if (!imxpd->panel) | ||
| 232 | return -EPROBE_DEFER; | ||
| 245 | } | 233 | } |
| 246 | 234 | ||
| 247 | imxpd->dev = dev; | 235 | imxpd->dev = dev; |
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index d05ca7901315..0186e500d2a5 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c | |||
| @@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, | |||
| 432 | unsigned long pll_rate; | 432 | unsigned long pll_rate; |
| 433 | unsigned int factor; | 433 | unsigned int factor; |
| 434 | 434 | ||
| 435 | if (!dpi) { | ||
| 436 | dev_err(dpi->dev, "invalid argument\n"); | ||
| 437 | return -EINVAL; | ||
| 438 | } | ||
| 439 | |||
| 440 | pix_rate = 1000UL * mode->clock; | 435 | pix_rate = 1000UL * mode->clock; |
| 441 | if (mode->clock <= 74000) | 436 | if (mode->clock <= 74000) |
| 442 | factor = 8 * 3; | 437 | factor = 8 * 3; |
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 2d808e59fefd..769559124562 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c | |||
| @@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi) | |||
| 695 | { | 695 | { |
| 696 | drm_encoder_cleanup(&dsi->encoder); | 696 | drm_encoder_cleanup(&dsi->encoder); |
| 697 | /* Skip connector cleanup if creation was delegated to the bridge */ | 697 | /* Skip connector cleanup if creation was delegated to the bridge */ |
| 698 | if (dsi->conn.dev) { | 698 | if (dsi->conn.dev) |
| 699 | drm_connector_unregister(&dsi->conn); | ||
| 700 | drm_connector_cleanup(&dsi->conn); | 699 | drm_connector_cleanup(&dsi->conn); |
| 701 | } | ||
| 702 | } | 700 | } |
| 703 | 701 | ||
| 704 | static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) | 702 | static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 14e64e08909e..d347dca17267 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
| @@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) | |||
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | fvv = pllreffreq * testn / testm; | 185 | fvv = pllreffreq * (n + 1) / (m + 1); |
| 186 | fvv = (fvv - 800000) / 50000; | 186 | fvv = (fvv - 800000) / 50000; |
| 187 | 187 | ||
| 188 | if (fvv > 15) | 188 | if (fvv > 15) |
| @@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) | |||
| 202 | WREG_DAC(MGA1064_PIX_PLLC_M, m); | 202 | WREG_DAC(MGA1064_PIX_PLLC_M, m); |
| 203 | WREG_DAC(MGA1064_PIX_PLLC_N, n); | 203 | WREG_DAC(MGA1064_PIX_PLLC_N, n); |
| 204 | WREG_DAC(MGA1064_PIX_PLLC_P, p); | 204 | WREG_DAC(MGA1064_PIX_PLLC_P, p); |
| 205 | |||
| 206 | if (mdev->unique_rev_id >= 0x04) { | ||
| 207 | WREG_DAC(0x1a, 0x09); | ||
| 208 | msleep(20); | ||
| 209 | WREG_DAC(0x1a, 0x01); | ||
| 210 | |||
| 211 | } | ||
| 212 | |||
| 205 | return 0; | 213 | return 0; |
| 206 | } | 214 | } |
| 207 | 215 | ||
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index fbe304ee6c80..2aec27dbb5bb 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c | |||
| @@ -408,7 +408,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, | |||
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); | 410 | adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); |
| 411 | if (!adreno_gpu->memptrs) { | 411 | if (IS_ERR(adreno_gpu->memptrs)) { |
| 412 | dev_err(drm->dev, "could not vmap memptrs\n"); | 412 | dev_err(drm->dev, "could not vmap memptrs\n"); |
| 413 | return -ENOMEM; | 413 | return -ENOMEM; |
| 414 | } | 414 | } |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d9759bf3482e..c6cf837c5193 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
| @@ -159,6 +159,10 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, | |||
| 159 | dev->mode_config.fb_base = paddr; | 159 | dev->mode_config.fb_base = paddr; |
| 160 | 160 | ||
| 161 | fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); | 161 | fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); |
| 162 | if (IS_ERR(fbi->screen_base)) { | ||
| 163 | ret = PTR_ERR(fbi->screen_base); | ||
| 164 | goto fail_unlock; | ||
| 165 | } | ||
| 162 | fbi->screen_size = fbdev->bo->size; | 166 | fbi->screen_size = fbdev->bo->size; |
| 163 | fbi->fix.smem_start = paddr; | 167 | fbi->fix.smem_start = paddr; |
| 164 | fbi->fix.smem_len = fbdev->bo->size; | 168 | fbi->fix.smem_len = fbdev->bo->size; |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 7daf4054dd2b..69836f5685b1 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -398,6 +398,8 @@ void *msm_gem_vaddr_locked(struct drm_gem_object *obj) | |||
| 398 | return ERR_CAST(pages); | 398 | return ERR_CAST(pages); |
| 399 | msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, | 399 | msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, |
| 400 | VM_MAP, pgprot_writecombine(PAGE_KERNEL)); | 400 | VM_MAP, pgprot_writecombine(PAGE_KERNEL)); |
| 401 | if (msm_obj->vaddr == NULL) | ||
| 402 | return ERR_PTR(-ENOMEM); | ||
| 401 | } | 403 | } |
| 402 | return msm_obj->vaddr; | 404 | return msm_obj->vaddr; |
| 403 | } | 405 | } |
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index b89ca5174863..eb4bb8b2f3a5 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
| @@ -40,12 +40,14 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, | |||
| 40 | 40 | ||
| 41 | submit->dev = dev; | 41 | submit->dev = dev; |
| 42 | submit->gpu = gpu; | 42 | submit->gpu = gpu; |
| 43 | submit->fence = NULL; | ||
| 43 | submit->pid = get_pid(task_pid(current)); | 44 | submit->pid = get_pid(task_pid(current)); |
| 44 | 45 | ||
| 45 | /* initially, until copy_from_user() and bo lookup succeeds: */ | 46 | /* initially, until copy_from_user() and bo lookup succeeds: */ |
| 46 | submit->nr_bos = 0; | 47 | submit->nr_bos = 0; |
| 47 | submit->nr_cmds = 0; | 48 | submit->nr_cmds = 0; |
| 48 | 49 | ||
| 50 | INIT_LIST_HEAD(&submit->node); | ||
| 49 | INIT_LIST_HEAD(&submit->bo_list); | 51 | INIT_LIST_HEAD(&submit->bo_list); |
| 50 | ww_acquire_init(&submit->ticket, &reservation_ww_class); | 52 | ww_acquire_init(&submit->ticket, &reservation_ww_class); |
| 51 | 53 | ||
| @@ -75,6 +77,11 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
| 75 | void __user *userptr = | 77 | void __user *userptr = |
| 76 | u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); | 78 | u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); |
| 77 | 79 | ||
| 80 | /* make sure we don't have garbage flags, in case we hit | ||
| 81 | * error path before flags is initialized: | ||
| 82 | */ | ||
| 83 | submit->bos[i].flags = 0; | ||
| 84 | |||
| 78 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | 85 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); |
| 79 | if (ret) { | 86 | if (ret) { |
| 80 | ret = -EFAULT; | 87 | ret = -EFAULT; |
diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index b48f73ac6389..0857710c2ff2 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c | |||
| @@ -312,6 +312,9 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) | |||
| 312 | struct msm_gem_object *obj = submit->bos[idx].obj; | 312 | struct msm_gem_object *obj = submit->bos[idx].obj; |
| 313 | const char *buf = msm_gem_vaddr_locked(&obj->base); | 313 | const char *buf = msm_gem_vaddr_locked(&obj->base); |
| 314 | 314 | ||
| 315 | if (IS_ERR(buf)) | ||
| 316 | continue; | ||
| 317 | |||
| 315 | buf += iova - submit->bos[idx].iova; | 318 | buf += iova - submit->bos[idx].iova; |
| 316 | 319 | ||
| 317 | rd_write_section(rd, RD_GPUADDR, | 320 | rd_write_section(rd, RD_GPUADDR, |
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 1f14b908b221..42f5359cf988 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c | |||
| @@ -40,6 +40,10 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | ring->start = msm_gem_vaddr_locked(ring->bo); | 42 | ring->start = msm_gem_vaddr_locked(ring->bo); |
| 43 | if (IS_ERR(ring->start)) { | ||
| 44 | ret = PTR_ERR(ring->start); | ||
| 45 | goto fail; | ||
| 46 | } | ||
| 43 | ring->end = ring->start + (size / 4); | 47 | ring->end = ring->start + (size / 4); |
| 44 | ring->cur = ring->start; | 48 | ring->cur = ring->start; |
| 45 | 49 | ||
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index c612dc1f1eb4..126a85cc81bc 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h | |||
| @@ -16,9 +16,9 @@ enum nvkm_devidx { | |||
| 16 | NVKM_SUBDEV_MC, | 16 | NVKM_SUBDEV_MC, |
| 17 | NVKM_SUBDEV_BUS, | 17 | NVKM_SUBDEV_BUS, |
| 18 | NVKM_SUBDEV_TIMER, | 18 | NVKM_SUBDEV_TIMER, |
| 19 | NVKM_SUBDEV_INSTMEM, | ||
| 19 | NVKM_SUBDEV_FB, | 20 | NVKM_SUBDEV_FB, |
| 20 | NVKM_SUBDEV_LTC, | 21 | NVKM_SUBDEV_LTC, |
| 21 | NVKM_SUBDEV_INSTMEM, | ||
| 22 | NVKM_SUBDEV_MMU, | 22 | NVKM_SUBDEV_MMU, |
| 23 | NVKM_SUBDEV_BAR, | 23 | NVKM_SUBDEV_BAR, |
| 24 | NVKM_SUBDEV_PMU, | 24 | NVKM_SUBDEV_PMU, |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h index db10c11f0595..c5a6ebd5a478 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h | |||
| @@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask, | |||
| 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); | 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); |
| 26 | 26 | ||
| 27 | struct nvbios_ocfg { | 27 | struct nvbios_ocfg { |
| 28 | u16 match; | 28 | u8 proto; |
| 29 | u8 flags; | ||
| 29 | u16 clkcmp[2]; | 30 | u16 clkcmp[2]; |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| @@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx, | |||
| 33 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | 34 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); |
| 34 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, | 35 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, |
| 35 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 36 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 36 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type, | 37 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags, |
| 37 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 38 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 38 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); | 39 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); |
| 39 | #endif | 40 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 57aaf98a26f9..d1f248fd3506 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -552,6 +552,8 @@ nouveau_fbcon_init(struct drm_device *dev) | |||
| 552 | if (ret) | 552 | if (ret) |
| 553 | goto fini; | 553 | goto fini; |
| 554 | 554 | ||
| 555 | if (fbcon->helper.fbdev) | ||
| 556 | fbcon->helper.fbdev->pixmap.buf_align = 4; | ||
| 555 | return 0; | 557 | return 0; |
| 556 | 558 | ||
| 557 | fini: | 559 | fini: |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 0f3e4bb411cc..7d9248b8c664 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
| @@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 82 | uint32_t fg; | 82 | uint32_t fg; |
| 83 | uint32_t bg; | 83 | uint32_t bg; |
| 84 | uint32_t dsize; | 84 | uint32_t dsize; |
| 85 | uint32_t width; | ||
| 86 | uint32_t *data = (uint32_t *)image->data; | 85 | uint32_t *data = (uint32_t *)image->data; |
| 87 | int ret; | 86 | int ret; |
| 88 | 87 | ||
| @@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 93 | if (ret) | 92 | if (ret) |
| 94 | return ret; | 93 | return ret; |
| 95 | 94 | ||
| 96 | width = ALIGN(image->width, 8); | ||
| 97 | dsize = ALIGN(width * image->height, 32) >> 5; | ||
| 98 | |||
| 99 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 95 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 100 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 96 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| 101 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; | 97 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; |
| @@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 111 | ((image->dx + image->width) & 0xffff)); | 107 | ((image->dx + image->width) & 0xffff)); |
| 112 | OUT_RING(chan, bg); | 108 | OUT_RING(chan, bg); |
| 113 | OUT_RING(chan, fg); | 109 | OUT_RING(chan, fg); |
| 114 | OUT_RING(chan, (image->height << 16) | width); | 110 | OUT_RING(chan, (image->height << 16) | image->width); |
| 115 | OUT_RING(chan, (image->height << 16) | image->width); | 111 | OUT_RING(chan, (image->height << 16) | image->width); |
| 116 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); | 112 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); |
| 117 | 113 | ||
| 114 | dsize = ALIGN(image->width * image->height, 32) >> 5; | ||
| 118 | while (dsize) { | 115 | while (dsize) { |
| 119 | int iter_len = dsize > 128 ? 128 : dsize; | 116 | int iter_len = dsize > 128 ? 128 : dsize; |
| 120 | 117 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 33d9ee0fac40..1aeb698e9707 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
| @@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
| 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | int ret; | 101 | int ret; |
| @@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 107 | if (ret) | 107 | if (ret) |
| 108 | return ret; | 108 | return ret; |
| 109 | 109 | ||
| 110 | width = ALIGN(image->width, 32); | ||
| 111 | dwords = (width * image->height) >> 5; | ||
| 112 | |||
| 113 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); |
| 114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 128 | OUT_RING(chan, 0); | 125 | OUT_RING(chan, 0); |
| 129 | OUT_RING(chan, image->dy); | 126 | OUT_RING(chan, image->dy); |
| 130 | 127 | ||
| 128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
| 131 | while (dwords) { | 129 | while (dwords) { |
| 132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index a0913359ac05..839f4c8c1805 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c | |||
| @@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
| 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | int ret; | 101 | int ret; |
| @@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 107 | if (ret) | 107 | if (ret) |
| 108 | return ret; | 108 | return ret; |
| 109 | 109 | ||
| 110 | width = ALIGN(image->width, 32); | ||
| 111 | dwords = (width * image->height) >> 5; | ||
| 112 | |||
| 113 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); |
| 114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 128 | OUT_RING (chan, 0); | 125 | OUT_RING (chan, 0); |
| 129 | OUT_RING (chan, image->dy); | 126 | OUT_RING (chan, image->dy); |
| 130 | 127 | ||
| 128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
| 131 | while (dwords) { | 129 | while (dwords) { |
| 132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 18fab3973ce5..62ad0300cfa5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | |||
| @@ -1614,7 +1614,7 @@ nvkm_device_pci_func = { | |||
| 1614 | .fini = nvkm_device_pci_fini, | 1614 | .fini = nvkm_device_pci_fini, |
| 1615 | .resource_addr = nvkm_device_pci_resource_addr, | 1615 | .resource_addr = nvkm_device_pci_resource_addr, |
| 1616 | .resource_size = nvkm_device_pci_resource_size, | 1616 | .resource_size = nvkm_device_pci_resource_size, |
| 1617 | .cpu_coherent = !IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64), | 1617 | .cpu_coherent = !IS_ENABLED(CONFIG_ARM), |
| 1618 | }; | 1618 | }; |
| 1619 | 1619 | ||
| 1620 | int | 1620 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index a74c5dd27dc0..e2a64ed14b22 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | |||
| @@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o | |||
| 18 | nvkm-y += nvkm/engine/disp/sornv50.o | 18 | nvkm-y += nvkm/engine/disp/sornv50.o |
| 19 | nvkm-y += nvkm/engine/disp/sorg94.o | 19 | nvkm-y += nvkm/engine/disp/sorg94.o |
| 20 | nvkm-y += nvkm/engine/disp/sorgf119.o | 20 | nvkm-y += nvkm/engine/disp/sorgf119.o |
| 21 | nvkm-y += nvkm/engine/disp/sorgm107.o | ||
| 21 | nvkm-y += nvkm/engine/disp/sorgm200.o | 22 | nvkm-y += nvkm/engine/disp/sorgm200.o |
| 22 | nvkm-y += nvkm/engine/disp/dport.o | 23 | nvkm-y += nvkm/engine/disp/dport.o |
| 23 | 24 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index f0314664349c..5dd34382f55a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | |||
| @@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl, | |||
| 76 | mask |= 0x0001 << or; | 76 | mask |= 0x0001 << or; |
| 77 | mask |= 0x0100 << head; | 77 | mask |= 0x0100 << head; |
| 78 | 78 | ||
| 79 | |||
| 79 | list_for_each_entry(outp, &disp->base.outp, head) { | 80 | list_for_each_entry(outp, &disp->base.outp, head) { |
| 80 | if ((outp->info.hasht & 0xff) == type && | 81 | if ((outp->info.hasht & 0xff) == type && |
| 81 | (outp->info.hashm & mask) == mask) { | 82 | (outp->info.hashm & mask) == mask) { |
| @@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 155 | if (!outp) | 156 | if (!outp) |
| 156 | return NULL; | 157 | return NULL; |
| 157 | 158 | ||
| 159 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 158 | switch (outp->info.type) { | 160 | switch (outp->info.type) { |
| 159 | case DCB_OUTPUT_TMDS: | 161 | case DCB_OUTPUT_TMDS: |
| 160 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 161 | if (*conf == 5) | 162 | if (*conf == 5) |
| 162 | *conf |= 0x0100; | 163 | *conf |= 0x0100; |
| 163 | break; | 164 | break; |
| 164 | case DCB_OUTPUT_LVDS: | 165 | case DCB_OUTPUT_LVDS: |
| 165 | *conf = disp->sor.lvdsconf; | 166 | *conf |= disp->sor.lvdsconf; |
| 166 | break; | ||
| 167 | case DCB_OUTPUT_DP: | ||
| 168 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 169 | break; | 167 | break; |
| 170 | case DCB_OUTPUT_ANALOG: | ||
| 171 | default: | 168 | default: |
| 172 | *conf = 0x00ff; | ||
| 173 | break; | 169 | break; |
| 174 | } | 170 | } |
| 175 | 171 | ||
| 176 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 172 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
| 173 | &ver, &hdr, &cnt, &len, &info2); | ||
| 177 | if (data && id < 0xff) { | 174 | if (data && id < 0xff) { |
| 178 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 175 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 179 | if (data) { | 176 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index b6944142d616..f4b9cf8574be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | |||
| @@ -36,7 +36,7 @@ gm107_disp = { | |||
| 36 | .outp.internal.crt = nv50_dac_output_new, | 36 | .outp.internal.crt = nv50_dac_output_new, |
| 37 | .outp.internal.tmds = nv50_sor_output_new, | 37 | .outp.internal.tmds = nv50_sor_output_new, |
| 38 | .outp.internal.lvds = nv50_sor_output_new, | 38 | .outp.internal.lvds = nv50_sor_output_new, |
| 39 | .outp.internal.dp = gf119_sor_dp_new, | 39 | .outp.internal.dp = gm107_sor_dp_new, |
| 40 | .dac.nr = 3, | 40 | .dac.nr = 3, |
| 41 | .dac.power = nv50_dac_power, | 41 | .dac.power = nv50_dac_power, |
| 42 | .dac.sense = nv50_dac_sense, | 42 | .dac.sense = nv50_dac_sense, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 4226d2153b9c..fcb1b0c46d64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | |||
| @@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 387 | if (!outp) | 387 | if (!outp) |
| 388 | return NULL; | 388 | return NULL; |
| 389 | 389 | ||
| 390 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 390 | if (outp->info.location == 0) { | 391 | if (outp->info.location == 0) { |
| 391 | switch (outp->info.type) { | 392 | switch (outp->info.type) { |
| 392 | case DCB_OUTPUT_TMDS: | 393 | case DCB_OUTPUT_TMDS: |
| 393 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 394 | if (*conf == 5) | 394 | if (*conf == 5) |
| 395 | *conf |= 0x0100; | 395 | *conf |= 0x0100; |
| 396 | break; | 396 | break; |
| 397 | case DCB_OUTPUT_LVDS: | 397 | case DCB_OUTPUT_LVDS: |
| 398 | *conf = disp->sor.lvdsconf; | 398 | *conf |= disp->sor.lvdsconf; |
| 399 | break; | 399 | break; |
| 400 | case DCB_OUTPUT_DP: | ||
| 401 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 402 | break; | ||
| 403 | case DCB_OUTPUT_ANALOG: | ||
| 404 | default: | 400 | default: |
| 405 | *conf = 0x00ff; | ||
| 406 | break; | 401 | break; |
| 407 | } | 402 | } |
| 408 | } else { | 403 | } else { |
| @@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 410 | pclk = pclk / 2; | 405 | pclk = pclk / 2; |
| 411 | } | 406 | } |
| 412 | 407 | ||
| 413 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 408 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
| 409 | &ver, &hdr, &cnt, &len, &info2); | ||
| 414 | if (data && id < 0xff) { | 410 | if (data && id < 0xff) { |
| 415 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 411 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 416 | if (data) { | 412 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h index e9067ba4e179..4e983f6d7032 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h | |||
| @@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int); | |||
| 62 | int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | 62 | int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, |
| 63 | struct nvkm_output **); | 63 | struct nvkm_output **); |
| 64 | int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); | 64 | int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); |
| 65 | int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int); | ||
| 65 | 66 | ||
| 66 | int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | 67 | int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, |
| 67 | struct nvkm_output **); | 68 | struct nvkm_output **); |
| 69 | int gm107_sor_dp_pattern(struct nvkm_output_dp *, int); | ||
| 70 | |||
| 71 | int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | ||
| 72 | struct nvkm_output **); | ||
| 68 | #endif | 73 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index b4b41b135643..22706c0a54b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | |||
| @@ -40,8 +40,7 @@ static int | |||
| 40 | gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | 40 | gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) |
| 41 | { | 41 | { |
| 42 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | 42 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; |
| 43 | const u32 loff = gf119_sor_loff(outp); | 43 | nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern); |
| 44 | nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); | ||
| 45 | return 0; | 44 | return 0; |
| 46 | } | 45 | } |
| 47 | 46 | ||
| @@ -64,7 +63,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) | |||
| 64 | return 0; | 63 | return 0; |
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | static int | 66 | int |
| 68 | gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp, | 67 | gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp, |
| 69 | int ln, int vs, int pe, int pc) | 68 | int ln, int vs, int pe, int pc) |
| 70 | { | 69 | { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c new file mode 100644 index 000000000000..37790b2617c5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Red Hat 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 | * Authors: Ben Skeggs <bskeggs@redhat.com> | ||
| 23 | */ | ||
| 24 | #include "nv50.h" | ||
| 25 | #include "outpdp.h" | ||
| 26 | |||
| 27 | int | ||
| 28 | gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | ||
| 29 | { | ||
| 30 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | ||
| 31 | const u32 soff = outp->base.or * 0x800; | ||
| 32 | const u32 data = 0x01010101 * pattern; | ||
| 33 | if (outp->base.info.sorconf.link & 1) | ||
| 34 | nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | ||
| 35 | else | ||
| 36 | nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | static const struct nvkm_output_dp_func | ||
| 41 | gm107_sor_dp_func = { | ||
| 42 | .pattern = gm107_sor_dp_pattern, | ||
| 43 | .lnk_pwr = g94_sor_dp_lnk_pwr, | ||
| 44 | .lnk_ctl = gf119_sor_dp_lnk_ctl, | ||
| 45 | .drv_ctl = gf119_sor_dp_drv_ctl, | ||
| 46 | }; | ||
| 47 | |||
| 48 | int | ||
| 49 | gm107_sor_dp_new(struct nvkm_disp *disp, int index, | ||
| 50 | struct dcb_output *dcbE, struct nvkm_output **poutp) | ||
| 51 | { | ||
| 52 | return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp); | ||
| 53 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index 2cfbef9c344f..c44fa7ea672a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | |||
| @@ -57,19 +57,6 @@ gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane) | |||
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static int | 59 | static int |
| 60 | gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | ||
| 61 | { | ||
| 62 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | ||
| 63 | const u32 soff = gm200_sor_soff(outp); | ||
| 64 | const u32 data = 0x01010101 * pattern; | ||
| 65 | if (outp->base.info.sorconf.link & 1) | ||
| 66 | nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | ||
| 67 | else | ||
| 68 | nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int | ||
| 73 | gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) | 60 | gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) |
| 74 | { | 61 | { |
| 75 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | 62 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; |
| @@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp, | |||
| 129 | 116 | ||
| 130 | static const struct nvkm_output_dp_func | 117 | static const struct nvkm_output_dp_func |
| 131 | gm200_sor_dp_func = { | 118 | gm200_sor_dp_func = { |
| 132 | .pattern = gm200_sor_dp_pattern, | 119 | .pattern = gm107_sor_dp_pattern, |
| 133 | .lnk_pwr = gm200_sor_dp_lnk_pwr, | 120 | .lnk_pwr = gm200_sor_dp_lnk_pwr, |
| 134 | .lnk_ctl = gf119_sor_dp_lnk_ctl, | 121 | .lnk_ctl = gf119_sor_dp_lnk_ctl, |
| 135 | .drv_ctl = gm200_sor_dp_drv_ctl, | 122 | .drv_ctl = gm200_sor_dp_drv_ctl, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 9513badb8220..ae9ab5b1ab97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | |||
| @@ -949,22 +949,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc) | |||
| 949 | } | 949 | } |
| 950 | 950 | ||
| 951 | static const struct nvkm_enum gf100_mp_warp_error[] = { | 951 | static const struct nvkm_enum gf100_mp_warp_error[] = { |
| 952 | { 0x00, "NO_ERROR" }, | 952 | { 0x01, "STACK_ERROR" }, |
| 953 | { 0x01, "STACK_MISMATCH" }, | 953 | { 0x02, "API_STACK_ERROR" }, |
| 954 | { 0x03, "RET_EMPTY_STACK_ERROR" }, | ||
| 955 | { 0x04, "PC_WRAP" }, | ||
| 954 | { 0x05, "MISALIGNED_PC" }, | 956 | { 0x05, "MISALIGNED_PC" }, |
| 955 | { 0x08, "MISALIGNED_GPR" }, | 957 | { 0x06, "PC_OVERFLOW" }, |
| 956 | { 0x09, "INVALID_OPCODE" }, | 958 | { 0x07, "MISALIGNED_IMMC_ADDR" }, |
| 957 | { 0x0d, "GPR_OUT_OF_BOUNDS" }, | 959 | { 0x08, "MISALIGNED_REG" }, |
| 958 | { 0x0e, "MEM_OUT_OF_BOUNDS" }, | 960 | { 0x09, "ILLEGAL_INSTR_ENCODING" }, |
| 959 | { 0x0f, "UNALIGNED_MEM_ACCESS" }, | 961 | { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" }, |
| 962 | { 0x0b, "ILLEGAL_INSTR_PARAM" }, | ||
| 963 | { 0x0c, "INVALID_CONST_ADDR" }, | ||
| 964 | { 0x0d, "OOR_REG" }, | ||
| 965 | { 0x0e, "OOR_ADDR" }, | ||
| 966 | { 0x0f, "MISALIGNED_ADDR" }, | ||
| 960 | { 0x10, "INVALID_ADDR_SPACE" }, | 967 | { 0x10, "INVALID_ADDR_SPACE" }, |
| 961 | { 0x11, "INVALID_PARAM" }, | 968 | { 0x11, "ILLEGAL_INSTR_PARAM2" }, |
| 969 | { 0x12, "INVALID_CONST_ADDR_LDC" }, | ||
| 970 | { 0x13, "GEOMETRY_SM_ERROR" }, | ||
| 971 | { 0x14, "DIVERGENT" }, | ||
| 972 | { 0x15, "WARP_EXIT" }, | ||
| 962 | {} | 973 | {} |
| 963 | }; | 974 | }; |
| 964 | 975 | ||
| 965 | static const struct nvkm_bitfield gf100_mp_global_error[] = { | 976 | static const struct nvkm_bitfield gf100_mp_global_error[] = { |
| 977 | { 0x00000001, "SM_TO_SM_FAULT" }, | ||
| 978 | { 0x00000002, "L1_ERROR" }, | ||
| 966 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, | 979 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, |
| 967 | { 0x00000008, "OUT_OF_STACK_SPACE" }, | 980 | { 0x00000008, "PHYSICAL_STACK_OVERFLOW" }, |
| 981 | { 0x00000010, "BPT_INT" }, | ||
| 982 | { 0x00000020, "BPT_PAUSE" }, | ||
| 983 | { 0x00000040, "SINGLE_STEP_COMPLETE" }, | ||
| 984 | { 0x20000000, "ECC_SEC_ERROR" }, | ||
| 985 | { 0x40000000, "ECC_DED_ERROR" }, | ||
| 986 | { 0x80000000, "TIMEOUT" }, | ||
| 968 | {} | 987 | {} |
| 969 | }; | 988 | }; |
| 970 | 989 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c index a5e92135cd77..9efb1b48cd54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c | |||
| @@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
| 141 | { | 141 | { |
| 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); | 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); |
| 143 | if (data) { | 143 | if (data) { |
| 144 | info->match = nvbios_rd16(bios, data + 0x00); | 144 | info->proto = nvbios_rd08(bios, data + 0x00); |
| 145 | info->flags = nvbios_rd16(bios, data + 0x01); | ||
| 145 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); | 146 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); |
| 146 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); | 147 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); |
| 147 | } | 148 | } |
| @@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | u16 | 152 | u16 |
| 152 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type, | 153 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags, |
| 153 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) | 154 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) |
| 154 | { | 155 | { |
| 155 | u16 data, idx = 0; | 156 | u16 data, idx = 0; |
| 156 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { | 157 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { |
| 157 | if (info->match == type) | 158 | if ((info->proto == proto || info->proto == 0xff) && |
| 159 | (info->flags == flags)) | ||
| 158 | break; | 160 | break; |
| 159 | } | 161 | } |
| 160 | return data; | 162 | return data; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c index 323c79abe468..41bd5d0f7692 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | |||
| @@ -276,6 +276,8 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) | |||
| 276 | struct pwr_rail_t *r = &stbl.rail[i]; | 276 | struct pwr_rail_t *r = &stbl.rail[i]; |
| 277 | struct nvkm_iccsense_rail *rail; | 277 | struct nvkm_iccsense_rail *rail; |
| 278 | struct nvkm_iccsense_sensor *sensor; | 278 | struct nvkm_iccsense_sensor *sensor; |
| 279 | int (*read)(struct nvkm_iccsense *, | ||
| 280 | struct nvkm_iccsense_rail *); | ||
| 279 | 281 | ||
| 280 | if (!r->mode || r->resistor_mohm == 0) | 282 | if (!r->mode || r->resistor_mohm == 0) |
| 281 | continue; | 283 | continue; |
| @@ -284,31 +286,31 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) | |||
| 284 | if (!sensor) | 286 | if (!sensor) |
| 285 | continue; | 287 | continue; |
| 286 | 288 | ||
| 287 | rail = kmalloc(sizeof(*rail), GFP_KERNEL); | ||
| 288 | if (!rail) | ||
| 289 | return -ENOMEM; | ||
| 290 | |||
| 291 | switch (sensor->type) { | 289 | switch (sensor->type) { |
| 292 | case NVBIOS_EXTDEV_INA209: | 290 | case NVBIOS_EXTDEV_INA209: |
| 293 | if (r->rail != 0) | 291 | if (r->rail != 0) |
| 294 | continue; | 292 | continue; |
| 295 | rail->read = nvkm_iccsense_ina209_read; | 293 | read = nvkm_iccsense_ina209_read; |
| 296 | break; | 294 | break; |
| 297 | case NVBIOS_EXTDEV_INA219: | 295 | case NVBIOS_EXTDEV_INA219: |
| 298 | if (r->rail != 0) | 296 | if (r->rail != 0) |
| 299 | continue; | 297 | continue; |
| 300 | rail->read = nvkm_iccsense_ina219_read; | 298 | read = nvkm_iccsense_ina219_read; |
| 301 | break; | 299 | break; |
| 302 | case NVBIOS_EXTDEV_INA3221: | 300 | case NVBIOS_EXTDEV_INA3221: |
| 303 | if (r->rail >= 3) | 301 | if (r->rail >= 3) |
| 304 | continue; | 302 | continue; |
| 305 | rail->read = nvkm_iccsense_ina3221_read; | 303 | read = nvkm_iccsense_ina3221_read; |
| 306 | break; | 304 | break; |
| 307 | default: | 305 | default: |
| 308 | continue; | 306 | continue; |
| 309 | } | 307 | } |
| 310 | 308 | ||
| 309 | rail = kmalloc(sizeof(*rail), GFP_KERNEL); | ||
| 310 | if (!rail) | ||
| 311 | return -ENOMEM; | ||
| 311 | sensor->rail_mask |= 1 << r->rail; | 312 | sensor->rail_mask |= 1 << r->rail; |
| 313 | rail->read = read; | ||
| 312 | rail->sensor = sensor; | 314 | rail->sensor = sensor; |
| 313 | rail->idx = r->rail; | 315 | rail->idx = r->rail; |
| 314 | rail->mohm = r->resistor_mohm; | 316 | rail->mohm = r->resistor_mohm; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c index e292f5679418..389fb13a1998 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c | |||
| @@ -69,11 +69,11 @@ gm107_ltc_zbc_clear_depth(struct nvkm_ltc *ltc, int i, const u32 depth) | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static void | 71 | static void |
| 72 | gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s) | 72 | gm107_ltc_intr_lts(struct nvkm_ltc *ltc, int c, int s) |
| 73 | { | 73 | { |
| 74 | struct nvkm_subdev *subdev = <c->subdev; | 74 | struct nvkm_subdev *subdev = <c->subdev; |
| 75 | struct nvkm_device *device = subdev->device; | 75 | struct nvkm_device *device = subdev->device; |
| 76 | u32 base = 0x140000 + (c * 0x2000) + (s * 0x200); | 76 | u32 base = 0x140400 + (c * 0x2000) + (s * 0x200); |
| 77 | u32 stat = nvkm_rd32(device, base + 0x00c); | 77 | u32 stat = nvkm_rd32(device, base + 0x00c); |
| 78 | 78 | ||
| 79 | if (stat) { | 79 | if (stat) { |
| @@ -92,7 +92,7 @@ gm107_ltc_intr(struct nvkm_ltc *ltc) | |||
| 92 | while (mask) { | 92 | while (mask) { |
| 93 | u32 s, c = __ffs(mask); | 93 | u32 s, c = __ffs(mask); |
| 94 | for (s = 0; s < ltc->lts_nr; s++) | 94 | for (s = 0; s < ltc->lts_nr; s++) |
| 95 | gm107_ltc_lts_isr(ltc, c, s); | 95 | gm107_ltc_intr_lts(ltc, c, s); |
| 96 | mask &= ~(1 << c); | 96 | mask &= ~(1 << c); |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c index 2a29bfd5125a..e18e0dc19ec8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c | |||
| @@ -46,7 +46,7 @@ static const struct nvkm_ltc_func | |||
| 46 | gm200_ltc = { | 46 | gm200_ltc = { |
| 47 | .oneinit = gm200_ltc_oneinit, | 47 | .oneinit = gm200_ltc_oneinit, |
| 48 | .init = gm200_ltc_init, | 48 | .init = gm200_ltc_init, |
| 49 | .intr = gm107_ltc_intr, /*XXX: not validated */ | 49 | .intr = gm107_ltc_intr, |
| 50 | .cbc_clear = gm107_ltc_cbc_clear, | 50 | .cbc_clear = gm107_ltc_cbc_clear, |
| 51 | .cbc_wait = gm107_ltc_cbc_wait, | 51 | .cbc_wait = gm107_ltc_cbc_wait, |
| 52 | .zbc = 16, | 52 | .zbc = 16, |
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index 73241c4eb7aa..336ad4de9981 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig | |||
| @@ -2,6 +2,7 @@ config DRM_OMAP | |||
| 2 | tristate "OMAP DRM" | 2 | tristate "OMAP DRM" |
| 3 | depends on DRM | 3 | depends on DRM |
| 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM | 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM |
| 5 | select OMAP2_DSS | ||
| 5 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 6 | select DRM_KMS_FB_HELPER | 7 | select DRM_KMS_FB_HELPER |
| 7 | select FB_SYS_FILLRECT | 8 | select FB_SYS_FILLRECT |
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 225fd8d6ab31..667ca4a24ece 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio/consumer.h> | ||
| 12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c index 8c246c213e06..9594ff7a2b0c 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * the Free Software Foundation. | 14 | * the Free Software Foundation. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c index 2fd5602880a7..671806ca7d6a 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio.h> | 12 | #include <linux/gpio/consumer.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c index e780fd4f8b46..7c2331be8d15 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio.h> | 12 | #include <linux/gpio/consumer.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c index 36485c2137ce..2b118071b5a1 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/backlight.h> | 14 | #include <linux/backlight.h> |
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c index 458f77bc473d..ac680e1de603 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| 18 | #include <linux/gpio/consumer.h> | ||
| 18 | 19 | ||
| 19 | #include <video/omapdss.h> | 20 | #include <video/omapdss.h> |
| 20 | #include <video/omap-panel-data.h> | 21 | #include <video/omap-panel-data.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index 780cb263a318..38d2920a95e6 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
| 17 | #include <linux/fb.h> | 17 | #include <linux/fb.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/consumer.h> |
| 19 | #include <linux/of_gpio.h> | 19 | #include <linux/of_gpio.h> |
| 20 | 20 | ||
| 21 | #include <video/omapdss.h> | 21 | #include <video/omapdss.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c index 529a017602e4..4363fffc87e3 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
| 13 | #include <linux/gpio.h> | 13 | #include <linux/gpio/consumer.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/of_gpio.h> | 16 | #include <linux/of_gpio.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index 31efcca801bd..deb416736aad 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/backlight.h> | 30 | #include <linux/backlight.h> |
| 31 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
| 32 | #include <linux/gpio.h> | 32 | #include <linux/gpio/consumer.h> |
| 33 | #include <linux/of.h> | 33 | #include <linux/of.h> |
| 34 | #include <linux/of_gpio.h> | 34 | #include <linux/of_gpio.h> |
| 35 | 35 | ||
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 03e2beb7b4f0..d93175b03a12 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/regulator/consumer.h> | 16 | #include <linux/regulator/consumer.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 8730646a0cbb..56c43f355ce3 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c | |||
| @@ -1167,7 +1167,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) | |||
| 1167 | { | 1167 | { |
| 1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 1169 | struct regulator *vdds_dsi; | 1169 | struct regulator *vdds_dsi; |
| 1170 | int r; | ||
| 1171 | 1170 | ||
| 1172 | if (dsi->vdds_dsi_reg != NULL) | 1171 | if (dsi->vdds_dsi_reg != NULL) |
| 1173 | return 0; | 1172 | return 0; |
| @@ -1180,15 +1179,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) | |||
| 1180 | return PTR_ERR(vdds_dsi); | 1179 | return PTR_ERR(vdds_dsi); |
| 1181 | } | 1180 | } |
| 1182 | 1181 | ||
| 1183 | if (regulator_can_change_voltage(vdds_dsi)) { | ||
| 1184 | r = regulator_set_voltage(vdds_dsi, 1800000, 1800000); | ||
| 1185 | if (r) { | ||
| 1186 | devm_regulator_put(vdds_dsi); | ||
| 1187 | DSSERR("can't set the DSI regulator voltage\n"); | ||
| 1188 | return r; | ||
| 1189 | } | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | dsi->vdds_dsi_reg = vdds_dsi; | 1182 | dsi->vdds_dsi_reg = vdds_dsi; |
| 1193 | 1183 | ||
| 1194 | return 0; | 1184 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index f95ff319e68e..3303cfad4838 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
| 32 | #include <linux/clk.h> | 32 | #include <linux/clk.h> |
| 33 | #include <linux/pinctrl/consumer.h> | ||
| 33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
| 35 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index f892ae157ff3..4d46cdf7a037 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
| 34 | #include <linux/regulator/consumer.h> | 34 | #include <linux/regulator/consumer.h> |
| 35 | #include <linux/component.h> | 35 | #include <linux/component.h> |
| 36 | #include <linux/of.h> | ||
| 36 | #include <video/omapdss.h> | 37 | #include <video/omapdss.h> |
| 37 | #include <sound/omap-hdmi-audio.h> | 38 | #include <sound/omap-hdmi-audio.h> |
| 38 | 39 | ||
| @@ -100,7 +101,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) | |||
| 100 | 101 | ||
| 101 | static int hdmi_init_regulator(void) | 102 | static int hdmi_init_regulator(void) |
| 102 | { | 103 | { |
| 103 | int r; | ||
| 104 | struct regulator *reg; | 104 | struct regulator *reg; |
| 105 | 105 | ||
| 106 | if (hdmi.vdda_reg != NULL) | 106 | if (hdmi.vdda_reg != NULL) |
| @@ -114,15 +114,6 @@ static int hdmi_init_regulator(void) | |||
| 114 | return PTR_ERR(reg); | 114 | return PTR_ERR(reg); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | if (regulator_can_change_voltage(reg)) { | ||
| 118 | r = regulator_set_voltage(reg, 1800000, 1800000); | ||
| 119 | if (r) { | ||
| 120 | devm_regulator_put(reg); | ||
| 121 | DSSWARN("can't set the regulator voltage\n"); | ||
| 122 | return r; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | hdmi.vdda_reg = reg; | 117 | hdmi.vdda_reg = reg; |
| 127 | 118 | ||
| 128 | return 0; | 119 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index fa72e735dad2..ef3afe99e487 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | |||
| @@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) | |||
| 211 | static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) | 211 | static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) |
| 212 | { | 212 | { |
| 213 | DSSDBG("Enter hdmi_core_powerdown_disable\n"); | 213 | DSSDBG("Enter hdmi_core_powerdown_disable\n"); |
| 214 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); | 214 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0); |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void hdmi_core_swreset_release(struct hdmi_core_data *core) | 217 | static void hdmi_core_swreset_release(struct hdmi_core_data *core) |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index a43f7b10e113..9255c0e1e4a7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/gpio.h> | 38 | #include <linux/gpio.h> |
| 39 | #include <linux/regulator/consumer.h> | 39 | #include <linux/regulator/consumer.h> |
| 40 | #include <linux/component.h> | 40 | #include <linux/component.h> |
| 41 | #include <linux/of.h> | ||
| 41 | #include <video/omapdss.h> | 42 | #include <video/omapdss.h> |
| 42 | #include <sound/omap-hdmi-audio.h> | 43 | #include <sound/omap-hdmi-audio.h> |
| 43 | 44 | ||
| @@ -119,7 +120,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) | |||
| 119 | 120 | ||
| 120 | static int hdmi_init_regulator(void) | 121 | static int hdmi_init_regulator(void) |
| 121 | { | 122 | { |
| 122 | int r; | ||
| 123 | struct regulator *reg; | 123 | struct regulator *reg; |
| 124 | 124 | ||
| 125 | if (hdmi.vdda_reg != NULL) | 125 | if (hdmi.vdda_reg != NULL) |
| @@ -131,15 +131,6 @@ static int hdmi_init_regulator(void) | |||
| 131 | return PTR_ERR(reg); | 131 | return PTR_ERR(reg); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (regulator_can_change_voltage(reg)) { | ||
| 135 | r = regulator_set_voltage(reg, 1800000, 1800000); | ||
| 136 | if (r) { | ||
| 137 | devm_regulator_put(reg); | ||
| 138 | DSSWARN("can't set the regulator voltage\n"); | ||
| 139 | return r; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | hdmi.vdda_reg = reg; | 134 | hdmi.vdda_reg = reg; |
| 144 | 135 | ||
| 145 | return 0; | 136 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c index 6a397520cae5..8ab2093daa12 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | |||
| @@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core) | |||
| 51 | { | 51 | { |
| 52 | void __iomem *base = core->base; | 52 | void __iomem *base = core->base; |
| 53 | const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ | 53 | const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ |
| 54 | const unsigned ss_scl_high = 4000; /* ns */ | 54 | const unsigned ss_scl_high = 4600; /* ns */ |
| 55 | const unsigned ss_scl_low = 4700; /* ns */ | 55 | const unsigned ss_scl_low = 5400; /* ns */ |
| 56 | const unsigned fs_scl_high = 600; /* ns */ | 56 | const unsigned fs_scl_high = 600; /* ns */ |
| 57 | const unsigned fs_scl_low = 1300; /* ns */ | 57 | const unsigned fs_scl_low = 1300; /* ns */ |
| 58 | const unsigned sda_hold = 1000; /* ns */ | 58 | const unsigned sda_hold = 1000; /* ns */ |
| @@ -458,7 +458,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, | |||
| 458 | 458 | ||
| 459 | c = (ptr[1] >> 6) & 0x3; | 459 | c = (ptr[1] >> 6) & 0x3; |
| 460 | m = (ptr[1] >> 4) & 0x3; | 460 | m = (ptr[1] >> 4) & 0x3; |
| 461 | r = (ptr[1] >> 0) & 0x3; | 461 | r = (ptr[1] >> 0) & 0xf; |
| 462 | 462 | ||
| 463 | itc = (ptr[2] >> 7) & 0x1; | 463 | itc = (ptr[2] >> 7) & 0x1; |
| 464 | ec = (ptr[2] >> 4) & 0x7; | 464 | ec = (ptr[2] >> 4) & 0x7; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c index 1f5d19c119ce..f98b750fc499 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/seq_file.h> | ||
| 16 | #include <video/omapdss.h> | 17 | #include <video/omapdss.h> |
| 17 | 18 | ||
| 18 | #include "dss.h" | 19 | #include "dss.h" |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c index 06e23a7c432c..f1015e8b8267 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| 19 | #include <linux/seq_file.h> | ||
| 19 | 20 | ||
| 20 | #include <video/omapdss.h> | 21 | #include <video/omapdss.h> |
| 21 | 22 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c index 13442b9052d1..055f62fca5dc 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/seq_file.h> | ||
| 17 | #include <video/omapdss.h> | 18 | #include <video/omapdss.h> |
| 18 | 19 | ||
| 19 | #include "dss.h" | 20 | #include "dss.h" |
diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index 6f5fc14fc015..479bf24050f8 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 20 | #include <drm/drm_crtc.h> | 22 | #include <drm/drm_crtc.h> |
| 21 | #include <drm/drm_fb_helper.h> | 23 | #include <drm/drm_fb_helper.h> |
| 22 | 24 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index de275a5be1db..4ceed7a9762f 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/platform_device.h> /* platform_device() */ | 28 | #include <linux/platform_device.h> /* platform_device() */ |
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/seq_file.h> | ||
| 30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 31 | #include <linux/time.h> | 32 | #include <linux/time.h> |
| 32 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 94ec06d3d737..f84570d1636c 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 20 | #include <drm/drm_crtc.h> | 22 | #include <drm/drm_crtc.h> |
| 21 | #include <drm/drm_crtc_helper.h> | 23 | #include <drm/drm_crtc_helper.h> |
| 22 | 24 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index b97afc281778..03698b6c806c 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 20 | #include <linux/shmem_fs.h> | 21 | #include <linux/shmem_fs.h> |
| 21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 22 | #include <linux/pfn_t.h> | 23 | #include <linux/pfn_t.h> |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2e216e2ea78c..259cd6e6d71c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -589,7 +589,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 589 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev)) | 589 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev)) |
| 590 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 590 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 591 | /* use frac fb div on RS780/RS880 */ | 591 | /* use frac fb div on RS780/RS880 */ |
| 592 | if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) | 592 | if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) |
| 593 | && !radeon_crtc->ss_enabled) | ||
| 593 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 594 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 594 | if (ASIC_IS_DCE32(rdev) && mode->clock > 165000) | 595 | if (ASIC_IS_DCE32(rdev) && mode->clock > 165000) |
| 595 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 596 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| @@ -626,7 +627,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 626 | if (radeon_crtc->ss.refdiv) { | 627 | if (radeon_crtc->ss.refdiv) { |
| 627 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; | 628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
| 628 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; | 629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
| 629 | if (ASIC_IS_AVIVO(rdev)) | 630 | if (rdev->family >= CHIP_RV770) |
| 630 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 631 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
| 631 | } | 632 | } |
| 632 | } | 633 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e721e6b2766e..21c44b2293bc 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
| 630 | /* | 630 | /* |
| 631 | * GPU helpers function. | 631 | * GPU helpers function. |
| 632 | */ | 632 | */ |
| 633 | |||
| 634 | /** | ||
| 635 | * radeon_device_is_virtual - check if we are running is a virtual environment | ||
| 636 | * | ||
| 637 | * Check if the asic has been passed through to a VM (all asics). | ||
| 638 | * Used at driver startup. | ||
| 639 | * Returns true if virtual or false if not. | ||
| 640 | */ | ||
| 641 | static bool radeon_device_is_virtual(void) | ||
| 642 | { | ||
| 643 | #ifdef CONFIG_X86 | ||
| 644 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
| 645 | #else | ||
| 646 | return false; | ||
| 647 | #endif | ||
| 648 | } | ||
| 649 | |||
| 633 | /** | 650 | /** |
| 634 | * radeon_card_posted - check if the hw has already been initialized | 651 | * radeon_card_posted - check if the hw has already been initialized |
| 635 | * | 652 | * |
| @@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
| 643 | { | 660 | { |
| 644 | uint32_t reg; | 661 | uint32_t reg; |
| 645 | 662 | ||
| 663 | /* for pass through, always force asic_init */ | ||
| 664 | if (radeon_device_is_virtual()) | ||
| 665 | return false; | ||
| 666 | |||
| 646 | /* required for EFI mode on macbook2,1 which uses an r5xx asic */ | 667 | /* required for EFI mode on macbook2,1 which uses an r5xx asic */ |
| 647 | if (efi_enabled(EFI_BOOT) && | 668 | if (efi_enabled(EFI_BOOT) && |
| 648 | (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && | 669 | (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && |
| @@ -1631,7 +1652,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, | |||
| 1631 | radeon_agp_suspend(rdev); | 1652 | radeon_agp_suspend(rdev); |
| 1632 | 1653 | ||
| 1633 | pci_save_state(dev->pdev); | 1654 | pci_save_state(dev->pdev); |
| 1634 | if (freeze && rdev->family >= CHIP_R600) { | 1655 | if (freeze && rdev->family >= CHIP_CEDAR) { |
| 1635 | rdev->asic->asic_reset(rdev, true); | 1656 | rdev->asic->asic_reset(rdev, true); |
| 1636 | pci_restore_state(dev->pdev); | 1657 | pci_restore_state(dev->pdev); |
| 1637 | } else if (suspend) { | 1658 | } else if (suspend) { |
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index 505620c7c2c8..e04deedabd4a 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c | |||
| @@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc) | |||
| 51 | mixer->status = STI_MIXER_DISABLING; | 51 | mixer->status = STI_MIXER_DISABLING; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | static bool sti_crtc_mode_fixup(struct drm_crtc *crtc, | ||
| 55 | const struct drm_display_mode *mode, | ||
| 56 | struct drm_display_mode *adjusted_mode) | ||
| 57 | { | ||
| 58 | /* accept the provided drm_display_mode, do not fix it up */ | ||
| 59 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | static int | 54 | static int |
| 64 | sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) | 55 | sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) |
| 65 | { | 56 | { |
| @@ -230,7 +221,6 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 230 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { | 221 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { |
| 231 | .enable = sti_crtc_enable, | 222 | .enable = sti_crtc_enable, |
| 232 | .disable = sti_crtc_disabling, | 223 | .disable = sti_crtc_disabling, |
| 233 | .mode_fixup = sti_crtc_mode_fixup, | ||
| 234 | .mode_set = drm_helper_crtc_mode_set, | 224 | .mode_set = drm_helper_crtc_mode_set, |
| 235 | .mode_set_nofb = sti_crtc_mode_set_nofb, | 225 | .mode_set_nofb = sti_crtc_mode_set_nofb, |
| 236 | .mode_set_base = drm_helper_crtc_mode_set_base, | 226 | .mode_set_base = drm_helper_crtc_mode_set_base, |
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig index 99510e64e91a..a4b357db8856 100644 --- a/drivers/gpu/drm/sun4i/Kconfig +++ b/drivers/gpu/drm/sun4i/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config DRM_SUN4I | 1 | config DRM_SUN4I |
| 2 | tristate "DRM Support for Allwinner A10 Display Engine" | 2 | tristate "DRM Support for Allwinner A10 Display Engine" |
| 3 | depends on DRM && ARM | 3 | depends on DRM && ARM && COMMON_CLK |
| 4 | depends on ARCH_SUNXI || COMPILE_TEST | 4 | depends on ARCH_SUNXI || COMPILE_TEST |
| 5 | select DRM_GEM_CMA_HELPER | 5 | select DRM_GEM_CMA_HELPER |
| 6 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index f7a15c1a93bf..3ab560450a82 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c | |||
| @@ -190,7 +190,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, | |||
| 190 | /* Get the physical address of the buffer in memory */ | 190 | /* Get the physical address of the buffer in memory */ |
| 191 | gem = drm_fb_cma_get_gem_obj(fb, 0); | 191 | gem = drm_fb_cma_get_gem_obj(fb, 0); |
| 192 | 192 | ||
| 193 | DRM_DEBUG_DRIVER("Using GEM @ 0x%x\n", gem->paddr); | 193 | DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->paddr); |
| 194 | 194 | ||
| 195 | /* Compute the start of the displayed memory */ | 195 | /* Compute the start of the displayed memory */ |
| 196 | bpp = drm_format_plane_cpp(fb->pixel_format, 0); | 196 | bpp = drm_format_plane_cpp(fb->pixel_format, 0); |
| @@ -198,7 +198,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, | |||
| 198 | paddr += (state->src_x >> 16) * bpp; | 198 | paddr += (state->src_x >> 16) * bpp; |
| 199 | paddr += (state->src_y >> 16) * fb->pitches[0]; | 199 | paddr += (state->src_y >> 16) * fb->pitches[0]; |
| 200 | 200 | ||
| 201 | DRM_DEBUG_DRIVER("Setting buffer address to 0x%x\n", paddr); | 201 | DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr); |
| 202 | 202 | ||
| 203 | /* Write the 32 lower bits of the address (in bits) */ | 203 | /* Write the 32 lower bits of the address (in bits) */ |
| 204 | lo_paddr = paddr << 3; | 204 | lo_paddr = paddr << 3; |
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_dotclock.c index 3ff668cb463c..5b3463197c48 100644 --- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c +++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c | |||
| @@ -72,14 +72,40 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw, | |||
| 72 | static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate, | 72 | static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate, |
| 73 | unsigned long *parent_rate) | 73 | unsigned long *parent_rate) |
| 74 | { | 74 | { |
| 75 | return *parent_rate / DIV_ROUND_CLOSEST(*parent_rate, rate); | 75 | unsigned long best_parent = 0; |
| 76 | u8 best_div = 1; | ||
| 77 | int i; | ||
| 78 | |||
| 79 | for (i = 6; i < 127; i++) { | ||
| 80 | unsigned long ideal = rate * i; | ||
| 81 | unsigned long rounded; | ||
| 82 | |||
| 83 | rounded = clk_hw_round_rate(clk_hw_get_parent(hw), | ||
| 84 | ideal); | ||
| 85 | |||
| 86 | if (rounded == ideal) { | ||
| 87 | best_parent = rounded; | ||
| 88 | best_div = i; | ||
| 89 | goto out; | ||
| 90 | } | ||
| 91 | |||
| 92 | if ((rounded < ideal) && (rounded > best_parent)) { | ||
| 93 | best_parent = rounded; | ||
| 94 | best_div = i; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | out: | ||
| 99 | *parent_rate = best_parent; | ||
| 100 | |||
| 101 | return best_parent / best_div; | ||
| 76 | } | 102 | } |
| 77 | 103 | ||
| 78 | static int sun4i_dclk_set_rate(struct clk_hw *hw, unsigned long rate, | 104 | static int sun4i_dclk_set_rate(struct clk_hw *hw, unsigned long rate, |
| 79 | unsigned long parent_rate) | 105 | unsigned long parent_rate) |
| 80 | { | 106 | { |
| 81 | struct sun4i_dclk *dclk = hw_to_dclk(hw); | 107 | struct sun4i_dclk *dclk = hw_to_dclk(hw); |
| 82 | int div = DIV_ROUND_CLOSEST(parent_rate, rate); | 108 | u8 div = parent_rate / rate; |
| 83 | 109 | ||
| 84 | return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG, | 110 | return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG, |
| 85 | GENMASK(6, 0), div); | 111 | GENMASK(6, 0), div); |
| @@ -127,10 +153,14 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon) | |||
| 127 | const char *clk_name, *parent_name; | 153 | const char *clk_name, *parent_name; |
| 128 | struct clk_init_data init; | 154 | struct clk_init_data init; |
| 129 | struct sun4i_dclk *dclk; | 155 | struct sun4i_dclk *dclk; |
| 156 | int ret; | ||
| 130 | 157 | ||
| 131 | parent_name = __clk_get_name(tcon->sclk0); | 158 | parent_name = __clk_get_name(tcon->sclk0); |
| 132 | of_property_read_string_index(dev->of_node, "clock-output-names", 0, | 159 | ret = of_property_read_string_index(dev->of_node, |
| 133 | &clk_name); | 160 | "clock-output-names", 0, |
| 161 | &clk_name); | ||
| 162 | if (ret) | ||
| 163 | return ret; | ||
| 134 | 164 | ||
| 135 | dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL); | 165 | dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL); |
| 136 | if (!dclk) | 166 | if (!dclk) |
| @@ -140,6 +170,7 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon) | |||
| 140 | init.ops = &sun4i_dclk_ops; | 170 | init.ops = &sun4i_dclk_ops; |
| 141 | init.parent_names = &parent_name; | 171 | init.parent_names = &parent_name; |
| 142 | init.num_parents = 1; | 172 | init.num_parents = 1; |
| 173 | init.flags = CLK_SET_RATE_PARENT; | ||
| 143 | 174 | ||
| 144 | dclk->regmap = tcon->regs; | 175 | dclk->regmap = tcon->regs; |
| 145 | dclk->hw.init = &init; | 176 | dclk->hw.init = &init; |
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 76e922bb60e5..257d2b4f3645 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
| @@ -24,34 +24,6 @@ | |||
| 24 | #include "sun4i_layer.h" | 24 | #include "sun4i_layer.h" |
| 25 | #include "sun4i_tcon.h" | 25 | #include "sun4i_tcon.h" |
| 26 | 26 | ||
| 27 | static int sun4i_drv_connector_plug_all(struct drm_device *drm) | ||
| 28 | { | ||
| 29 | struct drm_connector *connector, *failed; | ||
| 30 | int ret; | ||
| 31 | |||
| 32 | mutex_lock(&drm->mode_config.mutex); | ||
| 33 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
| 34 | ret = drm_connector_register(connector); | ||
| 35 | if (ret) { | ||
| 36 | failed = connector; | ||
| 37 | goto err; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | mutex_unlock(&drm->mode_config.mutex); | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | err: | ||
| 44 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
| 45 | if (failed == connector) | ||
| 46 | break; | ||
| 47 | |||
| 48 | drm_connector_unregister(connector); | ||
| 49 | } | ||
| 50 | mutex_unlock(&drm->mode_config.mutex); | ||
| 51 | |||
| 52 | return ret; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) | 27 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) |
| 56 | { | 28 | { |
| 57 | struct sun4i_drv *drv = drm->dev_private; | 29 | struct sun4i_drv *drv = drm->dev_private; |
| @@ -125,6 +97,22 @@ static struct drm_driver sun4i_drv_driver = { | |||
| 125 | .disable_vblank = sun4i_drv_disable_vblank, | 97 | .disable_vblank = sun4i_drv_disable_vblank, |
| 126 | }; | 98 | }; |
| 127 | 99 | ||
| 100 | static void sun4i_remove_framebuffers(void) | ||
| 101 | { | ||
| 102 | struct apertures_struct *ap; | ||
| 103 | |||
| 104 | ap = alloc_apertures(1); | ||
| 105 | if (!ap) | ||
| 106 | return; | ||
| 107 | |||
| 108 | /* The framebuffer can be located anywhere in RAM */ | ||
| 109 | ap->ranges[0].base = 0; | ||
| 110 | ap->ranges[0].size = ~0; | ||
| 111 | |||
| 112 | remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false); | ||
| 113 | kfree(ap); | ||
| 114 | } | ||
| 115 | |||
| 128 | static int sun4i_drv_bind(struct device *dev) | 116 | static int sun4i_drv_bind(struct device *dev) |
| 129 | { | 117 | { |
| 130 | struct drm_device *drm; | 118 | struct drm_device *drm; |
| @@ -172,6 +160,9 @@ static int sun4i_drv_bind(struct device *dev) | |||
| 172 | } | 160 | } |
| 173 | drm->irq_enabled = true; | 161 | drm->irq_enabled = true; |
| 174 | 162 | ||
| 163 | /* Remove early framebuffers (ie. simplefb) */ | ||
| 164 | sun4i_remove_framebuffers(); | ||
| 165 | |||
| 175 | /* Create our framebuffer */ | 166 | /* Create our framebuffer */ |
| 176 | drv->fbdev = sun4i_framebuffer_init(drm); | 167 | drv->fbdev = sun4i_framebuffer_init(drm); |
| 177 | if (IS_ERR(drv->fbdev)) { | 168 | if (IS_ERR(drv->fbdev)) { |
| @@ -187,7 +178,7 @@ static int sun4i_drv_bind(struct device *dev) | |||
| 187 | if (ret) | 178 | if (ret) |
| 188 | goto free_drm; | 179 | goto free_drm; |
| 189 | 180 | ||
| 190 | ret = sun4i_drv_connector_plug_all(drm); | 181 | ret = drm_connector_register_all(drm); |
| 191 | if (ret) | 182 | if (ret) |
| 192 | goto unregister_drm; | 183 | goto unregister_drm; |
| 193 | 184 | ||
| @@ -204,6 +195,7 @@ static void sun4i_drv_unbind(struct device *dev) | |||
| 204 | { | 195 | { |
| 205 | struct drm_device *drm = dev_get_drvdata(dev); | 196 | struct drm_device *drm = dev_get_drvdata(dev); |
| 206 | 197 | ||
| 198 | drm_connector_unregister_all(drm); | ||
| 207 | drm_dev_unregister(drm); | 199 | drm_dev_unregister(drm); |
| 208 | drm_kms_helper_poll_fini(drm); | 200 | drm_kms_helper_poll_fini(drm); |
| 209 | sun4i_framebuffer_free(drm); | 201 | sun4i_framebuffer_free(drm); |
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index ab6494818050..aaffe9e64ffb 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c | |||
| @@ -54,8 +54,13 @@ static int sun4i_rgb_get_modes(struct drm_connector *connector) | |||
| 54 | static int sun4i_rgb_mode_valid(struct drm_connector *connector, | 54 | static int sun4i_rgb_mode_valid(struct drm_connector *connector, |
| 55 | struct drm_display_mode *mode) | 55 | struct drm_display_mode *mode) |
| 56 | { | 56 | { |
| 57 | struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector); | ||
| 58 | struct sun4i_drv *drv = rgb->drv; | ||
| 59 | struct sun4i_tcon *tcon = drv->tcon; | ||
| 57 | u32 hsync = mode->hsync_end - mode->hsync_start; | 60 | u32 hsync = mode->hsync_end - mode->hsync_start; |
| 58 | u32 vsync = mode->vsync_end - mode->vsync_start; | 61 | u32 vsync = mode->vsync_end - mode->vsync_start; |
| 62 | unsigned long rate = mode->clock * 1000; | ||
| 63 | long rounded_rate; | ||
| 59 | 64 | ||
| 60 | DRM_DEBUG_DRIVER("Validating modes...\n"); | 65 | DRM_DEBUG_DRIVER("Validating modes...\n"); |
| 61 | 66 | ||
| @@ -87,6 +92,15 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector, | |||
| 87 | 92 | ||
| 88 | DRM_DEBUG_DRIVER("Vertical parameters OK\n"); | 93 | DRM_DEBUG_DRIVER("Vertical parameters OK\n"); |
| 89 | 94 | ||
| 95 | rounded_rate = clk_round_rate(tcon->dclk, rate); | ||
| 96 | if (rounded_rate < rate) | ||
| 97 | return MODE_CLOCK_LOW; | ||
| 98 | |||
| 99 | if (rounded_rate > rate) | ||
| 100 | return MODE_CLOCK_HIGH; | ||
| 101 | |||
| 102 | DRM_DEBUG_DRIVER("Clock rate OK\n"); | ||
| 103 | |||
| 90 | return MODE_OK; | 104 | return MODE_OK; |
| 91 | } | 105 | } |
| 92 | 106 | ||
| @@ -203,7 +217,7 @@ int sun4i_rgb_init(struct drm_device *drm) | |||
| 203 | int ret; | 217 | int ret; |
| 204 | 218 | ||
| 205 | /* If we don't have a panel, there's no point in going on */ | 219 | /* If we don't have a panel, there's no point in going on */ |
| 206 | if (!tcon->panel) | 220 | if (IS_ERR(tcon->panel)) |
| 207 | return -ENODEV; | 221 | return -ENODEV; |
| 208 | 222 | ||
| 209 | rgb = devm_kzalloc(drm->dev, sizeof(*rgb), GFP_KERNEL); | 223 | rgb = devm_kzalloc(drm->dev, sizeof(*rgb), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 9f19b0e08560..652385f09735 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | |||
| @@ -425,11 +425,11 @@ static struct drm_panel *sun4i_tcon_find_panel(struct device_node *node) | |||
| 425 | 425 | ||
| 426 | remote = of_graph_get_remote_port_parent(end_node); | 426 | remote = of_graph_get_remote_port_parent(end_node); |
| 427 | if (!remote) { | 427 | if (!remote) { |
| 428 | DRM_DEBUG_DRIVER("Enable to parse remote node\n"); | 428 | DRM_DEBUG_DRIVER("Unable to parse remote node\n"); |
| 429 | return ERR_PTR(-EINVAL); | 429 | return ERR_PTR(-EINVAL); |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | return of_drm_find_panel(remote); | 432 | return of_drm_find_panel(remote) ?: ERR_PTR(-EPROBE_DEFER); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | static int sun4i_tcon_bind(struct device *dev, struct device *master, | 435 | static int sun4i_tcon_bind(struct device *dev, struct device *master, |
| @@ -490,7 +490,11 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, | |||
| 490 | return 0; | 490 | return 0; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | return sun4i_rgb_init(drm); | 493 | ret = sun4i_rgb_init(drm); |
| 494 | if (ret < 0) | ||
| 495 | goto err_free_clocks; | ||
| 496 | |||
| 497 | return 0; | ||
| 494 | 498 | ||
| 495 | err_free_clocks: | 499 | err_free_clocks: |
| 496 | sun4i_tcon_free_clocks(tcon); | 500 | sun4i_tcon_free_clocks(tcon); |
| @@ -522,12 +526,13 @@ static int sun4i_tcon_probe(struct platform_device *pdev) | |||
| 522 | * Defer the probe. | 526 | * Defer the probe. |
| 523 | */ | 527 | */ |
| 524 | panel = sun4i_tcon_find_panel(node); | 528 | panel = sun4i_tcon_find_panel(node); |
| 525 | if (IS_ERR(panel)) { | 529 | |
| 526 | /* | 530 | /* |
| 527 | * If we don't have a panel endpoint, just go on | 531 | * If we don't have a panel endpoint, just go on |
| 528 | */ | 532 | */ |
| 529 | if (PTR_ERR(panel) != -ENODEV) | 533 | if (PTR_ERR(panel) == -EPROBE_DEFER) { |
| 530 | return -EPROBE_DEFER; | 534 | DRM_DEBUG_DRIVER("Still waiting for our panel. Deferring...\n"); |
| 535 | return -EPROBE_DEFER; | ||
| 531 | } | 536 | } |
| 532 | 537 | ||
| 533 | return component_add(&pdev->dev, &sun4i_tcon_ops); | 538 | return component_add(&pdev->dev, &sun4i_tcon_ops); |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 904d0754ad78..0f18b76c7906 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
| @@ -456,14 +456,6 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 456 | 456 | ||
| 457 | WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); | 457 | WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); |
| 458 | 458 | ||
| 459 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 460 | vc4_state->mm.start); | ||
| 461 | |||
| 462 | if (debug_dump_regs) { | ||
| 463 | DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | ||
| 464 | vc4_hvs_dump_state(dev); | ||
| 465 | } | ||
| 466 | |||
| 467 | if (crtc->state->event) { | 459 | if (crtc->state->event) { |
| 468 | unsigned long flags; | 460 | unsigned long flags; |
| 469 | 461 | ||
| @@ -473,8 +465,20 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 473 | 465 | ||
| 474 | spin_lock_irqsave(&dev->event_lock, flags); | 466 | spin_lock_irqsave(&dev->event_lock, flags); |
| 475 | vc4_crtc->event = crtc->state->event; | 467 | vc4_crtc->event = crtc->state->event; |
| 476 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 477 | crtc->state->event = NULL; | 468 | crtc->state->event = NULL; |
| 469 | |||
| 470 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 471 | vc4_state->mm.start); | ||
| 472 | |||
| 473 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 474 | } else { | ||
| 475 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 476 | vc4_state->mm.start); | ||
| 477 | } | ||
| 478 | |||
| 479 | if (debug_dump_regs) { | ||
| 480 | DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | ||
| 481 | vc4_hvs_dump_state(dev); | ||
| 478 | } | 482 | } |
| 479 | } | 483 | } |
| 480 | 484 | ||
| @@ -500,12 +504,17 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) | |||
| 500 | { | 504 | { |
| 501 | struct drm_crtc *crtc = &vc4_crtc->base; | 505 | struct drm_crtc *crtc = &vc4_crtc->base; |
| 502 | struct drm_device *dev = crtc->dev; | 506 | struct drm_device *dev = crtc->dev; |
| 507 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 508 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); | ||
| 509 | u32 chan = vc4_crtc->channel; | ||
| 503 | unsigned long flags; | 510 | unsigned long flags; |
| 504 | 511 | ||
| 505 | spin_lock_irqsave(&dev->event_lock, flags); | 512 | spin_lock_irqsave(&dev->event_lock, flags); |
| 506 | if (vc4_crtc->event) { | 513 | if (vc4_crtc->event && |
| 514 | (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)))) { | ||
| 507 | drm_crtc_send_vblank_event(crtc, vc4_crtc->event); | 515 | drm_crtc_send_vblank_event(crtc, vc4_crtc->event); |
| 508 | vc4_crtc->event = NULL; | 516 | vc4_crtc->event = NULL; |
| 517 | drm_crtc_vblank_put(crtc); | ||
| 509 | } | 518 | } |
| 510 | spin_unlock_irqrestore(&dev->event_lock, flags); | 519 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 511 | } | 520 | } |
| @@ -556,6 +565,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) | |||
| 556 | spin_unlock_irqrestore(&dev->event_lock, flags); | 565 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 557 | } | 566 | } |
| 558 | 567 | ||
| 568 | drm_crtc_vblank_put(crtc); | ||
| 559 | drm_framebuffer_unreference(flip_state->fb); | 569 | drm_framebuffer_unreference(flip_state->fb); |
| 560 | kfree(flip_state); | 570 | kfree(flip_state); |
| 561 | 571 | ||
| @@ -598,6 +608,8 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
| 598 | return ret; | 608 | return ret; |
| 599 | } | 609 | } |
| 600 | 610 | ||
| 611 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
| 612 | |||
| 601 | /* Immediately update the plane's legacy fb pointer, so that later | 613 | /* Immediately update the plane's legacy fb pointer, so that later |
| 602 | * modeset prep sees the state that will be present when the semaphore | 614 | * modeset prep sees the state that will be present when the semaphore |
| 603 | * is released. | 615 | * is released. |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 3446ece21b4a..250ed7e3754c 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -66,12 +66,12 @@ static const struct file_operations vc4_drm_fops = { | |||
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | static const struct drm_ioctl_desc vc4_drm_ioctls[] = { | 68 | static const struct drm_ioctl_desc vc4_drm_ioctls[] = { |
| 69 | DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), | 69 | DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW), |
| 70 | DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), | 70 | DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, DRM_RENDER_ALLOW), |
| 71 | DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), | 71 | DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, DRM_RENDER_ALLOW), |
| 72 | DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), | 72 | DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, DRM_RENDER_ALLOW), |
| 73 | DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), | 73 | DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, DRM_RENDER_ALLOW), |
| 74 | DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), | 74 | DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW), |
| 75 | DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, | 75 | DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, |
| 76 | DRM_ROOT_ONLY), | 76 | DRM_ROOT_ONLY), |
| 77 | }; | 77 | }; |
| @@ -91,7 +91,7 @@ static struct drm_driver vc4_drm_driver = { | |||
| 91 | 91 | ||
| 92 | .enable_vblank = vc4_enable_vblank, | 92 | .enable_vblank = vc4_enable_vblank, |
| 93 | .disable_vblank = vc4_disable_vblank, | 93 | .disable_vblank = vc4_disable_vblank, |
| 94 | .get_vblank_counter = drm_vblank_count, | 94 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 95 | 95 | ||
| 96 | #if defined(CONFIG_DEBUG_FS) | 96 | #if defined(CONFIG_DEBUG_FS) |
| 97 | .debugfs_init = vc4_debugfs_init, | 97 | .debugfs_init = vc4_debugfs_init, |
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index cb37751bc99f..861a623bc185 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c | |||
| @@ -117,10 +117,18 @@ static int vc4_atomic_commit(struct drm_device *dev, | |||
| 117 | return -ENOMEM; | 117 | return -ENOMEM; |
| 118 | 118 | ||
| 119 | /* Make sure that any outstanding modesets have finished. */ | 119 | /* Make sure that any outstanding modesets have finished. */ |
| 120 | ret = down_interruptible(&vc4->async_modeset); | 120 | if (nonblock) { |
| 121 | if (ret) { | 121 | ret = down_trylock(&vc4->async_modeset); |
| 122 | kfree(c); | 122 | if (ret) { |
| 123 | return ret; | 123 | kfree(c); |
| 124 | return -EBUSY; | ||
| 125 | } | ||
| 126 | } else { | ||
| 127 | ret = down_interruptible(&vc4->async_modeset); | ||
| 128 | if (ret) { | ||
| 129 | kfree(c); | ||
| 130 | return ret; | ||
| 131 | } | ||
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | ret = drm_atomic_helper_prepare_planes(dev, state); | 134 | ret = drm_atomic_helper_prepare_planes(dev, state); |
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 6163b95c5411..f99eece4cc97 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h | |||
| @@ -341,6 +341,10 @@ | |||
| 341 | #define SCALER_DISPLACT0 0x00000030 | 341 | #define SCALER_DISPLACT0 0x00000030 |
| 342 | #define SCALER_DISPLACT1 0x00000034 | 342 | #define SCALER_DISPLACT1 0x00000034 |
| 343 | #define SCALER_DISPLACT2 0x00000038 | 343 | #define SCALER_DISPLACT2 0x00000038 |
| 344 | #define SCALER_DISPLACTX(x) (SCALER_DISPLACT0 + \ | ||
| 345 | (x) * (SCALER_DISPLACT1 - \ | ||
| 346 | SCALER_DISPLACT0)) | ||
| 347 | |||
| 344 | #define SCALER_DISPCTRL0 0x00000040 | 348 | #define SCALER_DISPCTRL0 0x00000040 |
| 345 | # define SCALER_DISPCTRLX_ENABLE BIT(31) | 349 | # define SCALER_DISPCTRLX_ENABLE BIT(31) |
| 346 | # define SCALER_DISPCTRLX_RESET BIT(30) | 350 | # define SCALER_DISPCTRLX_RESET BIT(30) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 6de283c8fa3e..f0374f9b56ca 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/frame.h> | ||
| 31 | #include <asm/hypervisor.h> | 32 | #include <asm/hypervisor.h> |
| 32 | #include "drmP.h" | 33 | #include "drmP.h" |
| 33 | #include "vmwgfx_msg.h" | 34 | #include "vmwgfx_msg.h" |
| @@ -194,7 +195,7 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg) | |||
| 194 | 195 | ||
| 195 | return -EINVAL; | 196 | return -EINVAL; |
| 196 | } | 197 | } |
| 197 | 198 | STACK_FRAME_NON_STANDARD(vmw_send_msg); | |
| 198 | 199 | ||
| 199 | 200 | ||
| 200 | /** | 201 | /** |
| @@ -304,6 +305,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, | |||
| 304 | 305 | ||
| 305 | return 0; | 306 | return 0; |
| 306 | } | 307 | } |
| 308 | STACK_FRAME_NON_STANDARD(vmw_recv_msg); | ||
| 307 | 309 | ||
| 308 | 310 | ||
| 309 | /** | 311 | /** |
