summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ci_dpm.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v3_0.c89
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c32
-rw-r--r--drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c1
-rw-r--r--drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c9
-rw-r--r--drivers/gpu/drm/amd/powerplay/eventmgr/psm.c3
-rw-r--r--drivers/gpu/drm/amd/powerplay/eventmgr/psm.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c75
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c64
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c12
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c13
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c18
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c3
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h555
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c15
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c40
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c20
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h6
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/pp_instance.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c10
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c2
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c141
-rw-r--r--drivers/gpu/drm/radeon/r100.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c2
33 files changed, 670 insertions, 509 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 6fa0feac27f8..59485d0b3cfb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -843,15 +843,15 @@ static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
if (info->input_count > 0) {
if (info->pinput_argument == NULL)
return -EINVAL;
- argument = info->pinput_argument;
- func_no = argument->value;
- for (i = 0; i < info->input_count; i++) {
- if (((argument->type == ACPI_TYPE_STRING) ||
- (argument->type == ACPI_TYPE_BUFFER))
- && (argument->pointer == NULL))
- return -EINVAL;
- argument++;
- }
+ argument = info->pinput_argument;
+ func_no = argument->value;
+ for (i = 0; i < info->input_count; i++) {
+ if (((argument->type == ACPI_TYPE_STRING) ||
+ (argument->type == ACPI_TYPE_BUFFER)) &&
+ (argument->pointer == NULL))
+ return -EINVAL;
+ argument++;
+ }
}
if (info->output_count > 0) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index ea756e77b023..5107fb291bdb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -96,6 +96,7 @@ static inline void amdgpu_bo_unreserve(struct amdgpu_bo *bo)
*/
static inline u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
{
+ WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
return bo->tbo.offset;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 3b78982abaf1..4386cbac7f97 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -807,7 +807,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
struct amdgpu_ring *ring = adev->rings[i];
if (ring && ring->ready)
amdgpu_fence_wait_empty(ring);
- }
+ }
mutex_unlock(&adev->ring_lock);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL);
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index 57a2e347f04d..8b4731d4e10e 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -1395,7 +1395,6 @@ static void ci_thermal_stop_thermal_controller(struct amdgpu_device *adev)
ci_fan_ctrl_set_default_mode(adev);
}
-#if 0
static int ci_read_smc_soft_register(struct amdgpu_device *adev,
u16 reg_offset, u32 *value)
{
@@ -1405,7 +1404,6 @@ static int ci_read_smc_soft_register(struct amdgpu_device *adev,
pi->soft_regs_start + reg_offset,
value, pi->sram_end);
}
-#endif
static int ci_write_smc_soft_register(struct amdgpu_device *adev,
u16 reg_offset, u32 value)
@@ -6084,11 +6082,23 @@ ci_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
struct amdgpu_ps *rps = &pi->current_rps;
u32 sclk = ci_get_average_sclk_freq(adev);
u32 mclk = ci_get_average_mclk_freq(adev);
+ u32 activity_percent = 50;
+ int ret;
+
+ ret = ci_read_smc_soft_register(adev, offsetof(SMU7_SoftRegisters, AverageGraphicsA),
+ &activity_percent);
+
+ if (ret == 0) {
+ activity_percent += 0x80;
+ activity_percent >>= 8;
+ activity_percent = activity_percent > 100 ? 100 : activity_percent;
+ }
seq_printf(m, "uvd %sabled\n", pi->uvd_enabled ? "en" : "dis");
seq_printf(m, "vce %sabled\n", rps->vce_active ? "en" : "dis");
seq_printf(m, "power level avg sclk: %u mclk: %u\n",
sclk, mclk);
+ seq_printf(m, "GPU load: %u %%\n", activity_percent);
}
static void ci_dpm_print_power_state(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 8701661a8868..8e67249d4367 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -211,9 +211,9 @@ static bool dce_v11_0_is_counter_moving(struct amdgpu_device *adev, int crtc)
*/
static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc)
{
- unsigned i = 0;
+ unsigned i = 100;
- if (crtc >= adev->mode_info.num_crtc)
+ if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
return;
if (!(RREG32(mmCRTC_CONTROL + crtc_offsets[crtc]) & CRTC_CONTROL__CRTC_MASTER_EN_MASK))
@@ -223,14 +223,16 @@ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc)
* wait for another frame.
*/
while (dce_v11_0_is_in_vblank(adev, crtc)) {
- if (i++ % 100 == 0) {
+ if (i++ == 100) {
+ i = 0;
if (!dce_v11_0_is_counter_moving(adev, crtc))
break;
}
}
while (!dce_v11_0_is_in_vblank(adev, crtc)) {
- if (i++ % 100 == 0) {
+ if (i++ == 100) {
+ i = 0;
if (!dce_v11_0_is_counter_moving(adev, crtc))
break;
}
@@ -239,7 +241,7 @@ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc)
static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
{
- if (crtc >= adev->mode_info.num_crtc)
+ if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
return 0;
else
return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
@@ -3384,7 +3386,7 @@ static void dce_v11_0_crtc_vblank_int_ack(struct amdgpu_device *adev,
{
u32 tmp;
- if (crtc >= adev->mode_info.num_crtc) {
+ if (crtc < 0 || crtc >= adev->mode_info.num_crtc) {
DRM_DEBUG("invalid crtc %d\n", crtc);
return;
}
@@ -3399,7 +3401,7 @@ static void dce_v11_0_crtc_vline_int_ack(struct amdgpu_device *adev,
{
u32 tmp;
- if (crtc >= adev->mode_info.num_crtc) {
+ if (crtc < 0 || crtc >= adev->mode_info.num_crtc) {
DRM_DEBUG("invalid crtc %d\n", crtc);
return;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index dababe40a685..3f956065d069 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -1016,7 +1016,6 @@ static int gmc_v7_0_suspend(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->vm_manager.enabled) {
- amdgpu_vm_manager_fini(adev);
gmc_v7_0_vm_fini(adev);
adev->vm_manager.enabled = false;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index adc25f87fc18..c0c9a0101eb4 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -1037,7 +1037,6 @@ static int gmc_v8_0_suspend(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->vm_manager.enabled) {
- amdgpu_vm_manager_fini(adev);
gmc_v8_0_vm_fini(adev);
adev->vm_manager.enabled = false;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index 35f48ad7644d..e99af81e4aec 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -314,14 +314,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
{
u32 tmp;
- unsigned ret;
/* Fiji, Stoney are single pipe */
if ((adev->asic_type == CHIP_FIJI) ||
- (adev->asic_type == CHIP_STONEY)){
- ret = AMDGPU_VCE_HARVEST_VCE1;
- return ret;
- }
+ (adev->asic_type == CHIP_STONEY))
+ return AMDGPU_VCE_HARVEST_VCE1;
/* Tonga and CZ are dual or single pipe */
if (adev->flags & AMD_IS_APU)
@@ -335,19 +332,14 @@ static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
switch (tmp) {
case 1:
- ret = AMDGPU_VCE_HARVEST_VCE0;
- break;
+ return AMDGPU_VCE_HARVEST_VCE0;
case 2:
- ret = AMDGPU_VCE_HARVEST_VCE1;
- break;
+ return AMDGPU_VCE_HARVEST_VCE1;
case 3:
- ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
- break;
+ return AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
default:
- ret = 0;
+ return 0;
}
-
- return ret;
}
static int vce_v3_0_early_init(void *handle)
@@ -422,28 +414,22 @@ static int vce_v3_0_sw_fini(void *handle)
static int vce_v3_0_hw_init(void *handle)
{
- struct amdgpu_ring *ring;
- int r;
+ int r, i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = vce_v3_0_start(adev);
if (r)
return r;
- ring = &adev->vce.ring[0];
- ring->ready = true;
- r = amdgpu_ring_test_ring(ring);
- if (r) {
- ring->ready = false;
- return r;
- }
+ adev->vce.ring[0].ready = false;
+ adev->vce.ring[1].ready = false;
- ring = &adev->vce.ring[1];
- ring->ready = true;
- r = amdgpu_ring_test_ring(ring);
- if (r) {
- ring->ready = false;
- return r;
+ for (i = 0; i < 2; i++) {
+ r = amdgpu_ring_test_ring(&adev->vce.ring[i]);
+ if (r)
+ return r;
+ else
+ adev->vce.ring[i].ready = true;
}
DRM_INFO("VCE initialized successfully.\n");
@@ -543,17 +529,9 @@ static bool vce_v3_0_is_idle(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 mask = 0;
- int idx;
- for (idx = 0; idx < 2; ++idx) {
- if (adev->vce.harvest_config & (1 << idx))
- continue;
-
- if (idx == 0)
- mask |= SRBM_STATUS2__VCE0_BUSY_MASK;
- else
- mask |= SRBM_STATUS2__VCE1_BUSY_MASK;
- }
+ mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK;
+ mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK;
return !(RREG32(mmSRBM_STATUS2) & mask);
}
@@ -562,23 +540,11 @@ static int vce_v3_0_wait_for_idle(void *handle)
{
unsigned i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- u32 mask = 0;
- int idx;
-
- for (idx = 0; idx < 2; ++idx) {
- if (adev->vce.harvest_config & (1 << idx))
- continue;
-
- if (idx == 0)
- mask |= SRBM_STATUS2__VCE0_BUSY_MASK;
- else
- mask |= SRBM_STATUS2__VCE1_BUSY_MASK;
- }
- for (i = 0; i < adev->usec_timeout; i++) {
- if (!(RREG32(mmSRBM_STATUS2) & mask))
+ for (i = 0; i < adev->usec_timeout; i++)
+ if (vce_v3_0_is_idle(handle))
return 0;
- }
+
return -ETIMEDOUT;
}
@@ -586,17 +552,10 @@ static int vce_v3_0_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
u32 mask = 0;
- int idx;
- for (idx = 0; idx < 2; ++idx) {
- if (adev->vce.harvest_config & (1 << idx))
- continue;
+ mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK;
+ mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK;
- if (idx == 0)
- mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK;
- else
- mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK;
- }
WREG32_P(mmSRBM_SOFT_RESET, mask,
~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK |
SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK));
@@ -698,10 +657,8 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
switch (entry->src_data) {
case 0:
- amdgpu_fence_process(&adev->vce.ring[0]);
- break;
case 1:
- amdgpu_fence_process(&adev->vce.ring[1]);
+ amdgpu_fence_process(&adev->vce.ring[entry->src_data]);
break;
default:
DRM_ERROR("Unhandled interrupt: %d %d\n",
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index db0370bd60e3..8f5d5edcf193 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -30,6 +30,12 @@
#include "power_state.h"
#include "eventmanager.h"
+#define PP_CHECK(handle) \
+ do { \
+ if ((handle) == NULL || (handle)->pp_valid != PP_VALID) \
+ return -EINVAL; \
+ } while (0)
+
static int pp_early_init(void *handle)
{
return 0;
@@ -197,13 +203,29 @@ static int pp_resume(void *handle)
struct pp_instance *pp_handle;
struct pp_eventmgr *eventmgr;
struct pem_event_data event_data = { {0} };
+ struct pp_smumgr *smumgr;
+ int ret;
if (handle == NULL)
return -EINVAL;
pp_handle = (struct pp_instance *)handle;
+ smumgr = pp_handle->smu_mgr;
+
+ if (smumgr == NULL || smumgr->smumgr_funcs == NULL ||
+ smumgr->smumgr_funcs->start_smu == NULL)
+ return -EINVAL;
+
+ ret = smumgr->smumgr_funcs->start_smu(smumgr);
+ if (ret) {
+ printk(KERN_ERR "[ powerplay ] smc start failed\n");
+ smumgr->smumgr_funcs->smu_fini(smumgr);
+ return ret;
+ }
+
eventmgr = pp_handle->eventmgr;
pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
+
return 0;
}
@@ -537,6 +559,8 @@ static int amd_pp_instance_init(struct amd_pp_init *pp_init,
if (handle == NULL)
return -ENOMEM;
+ handle->pp_valid = PP_VALID;
+
ret = smum_init(pp_init, handle);
if (ret)
goto fail_smum;
@@ -611,12 +635,12 @@ int amd_powerplay_display_configuration_change(void *handle, const void *input)
struct pp_hwmgr *hwmgr;
const struct amd_pp_display_configuration *display_config = input;
- if (handle == NULL)
- return -EINVAL;
+ PP_CHECK((struct pp_instance *)handle);
hwmgr = ((struct pp_instance *)handle)->hwmgr;
phm_store_dal_configuration_data(hwmgr, display_config);
+
return 0;
}
@@ -625,7 +649,9 @@ int amd_powerplay_get_display_power_level(void *handle,
{
struct pp_hwmgr *hwmgr;
- if (handle == NULL || output == NULL)
+ PP_CHECK((struct pp_instance *)handle);
+
+ if (output == NULL)
return -EINVAL;
hwmgr = ((struct pp_instance *)handle)->hwmgr;
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
index 9458394aec05..83be3cf210e0 100644
--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
@@ -143,6 +143,7 @@ static const pem_event_action *resume_event[] = {
enable_dynamic_state_management_tasks,
enable_clock_power_gatings_tasks,
enable_disable_bapm_tasks,
+ initialize_thermal_controller_tasks,
reset_boot_state_tasks,
adjust_power_state_tasks,
enable_disable_fps_tasks,
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c
index f0700d077925..5cd123472db4 100644
--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c
+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c
@@ -68,13 +68,14 @@ int pem_task_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_d
int pem_task_power_down_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
{
- /* TODO */
- return 0;
+ return phm_power_down_asic(eventmgr->hwmgr);
}
int pem_task_set_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
{
- /* TODO */
+ if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID))
+ return psm_set_states(eventmgr, &(event_data->requested_state_id));
+
return 0;
}
@@ -343,7 +344,7 @@ int pem_task_disable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_e
int pem_task_set_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data)
{
if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID))
- return psm_set_performance_states(eventmgr, &(event_data->requested_state_id));
+ return psm_set_states(eventmgr, &(event_data->requested_state_id));
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
index 5740fbfcbeab..a46225c0fc01 100644
--- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
@@ -62,7 +62,7 @@ int psm_get_state_by_classification(struct pp_eventmgr *eventmgr, enum PP_StateC
return -1;
}
-int psm_set_performance_states(struct pp_eventmgr *eventmgr, unsigned long *state_id)
+int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id)
{
struct pp_power_state *state;
int table_entries;
@@ -82,7 +82,6 @@ int psm_set_performance_states(struct pp_eventmgr *eventmgr, unsigned long *stat
return -1;
}
-
int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip)
{
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.h b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.h
index 1380470fdb1c..fbdff3e02aa3 100644
--- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.h
+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.h
@@ -31,7 +31,7 @@ int psm_get_ui_state(struct pp_eventmgr *eventmgr, enum PP_StateUILabel ui_label
int psm_get_state_by_classification(struct pp_eventmgr *eventmgr, enum PP_StateClassificationFlag flag, unsigned long *state_id);
-int psm_set_performance_states(struct pp_eventmgr *eventmgr, unsigned long *state_id);
+int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id);
int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index 5bac36baa13c..0874ab42ee95 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -579,7 +579,7 @@ static int cz_tf_init_sclk_limit(struct pp_hwmgr *hwmgr, void *input,
hwmgr->dyn_state.vddc_dependency_on_sclk;
unsigned long clock = 0, level;
- if (NULL == table && table->count <= 0)
+ if (NULL == table || table->count <= 0)
return -EINVAL;
cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk;
@@ -606,7 +606,7 @@ static int cz_tf_init_uvd_limit(struct pp_hwmgr *hwmgr, void *input,
hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
unsigned long clock = 0, level;
- if (NULL == table && table->count <= 0)
+ if (NULL == table || table->count <= 0)
return -EINVAL;
cz_hwmgr->uvd_dpm.soft_min_clk = 0;
@@ -634,7 +634,7 @@ static int cz_tf_init_vce_limit(struct pp_hwmgr *hwmgr, void *input,
hwmgr->dyn_state.vce_clock_voltage_dependency_table;
unsigned long clock = 0, level;
- if (NULL == table && table->count <= 0)
+ if (NULL == table || table->count <= 0)
return -EINVAL;
cz_hwmgr->vce_dpm.soft_min_clk = 0;
@@ -662,7 +662,7 @@ static int cz_tf_init_acp_limit(struct pp_hwmgr *hwmgr, void *input,
hwmgr->dyn_state.acp_clock_voltage_dependency_table;
unsigned long clock = 0, level;
- if (NULL == table && table->count <= 0)
+ if (NULL == table || table->count <= 0)
return -EINVAL;
cz_hwmgr->acp_dpm.soft_min_clk = 0;
@@ -925,6 +925,54 @@ static struct phm_master_table_header cz_setup_asic_master = {
cz_setup_asic_list
};
+static int cz_tf_power_up_display_clock_sys_pll(struct pp_hwmgr *hwmgr,
+ void *input, void *output,
+ void *storage, int result)
+{
+ struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+ hw_data->disp_clk_bypass_pending = false;
+ hw_data->disp_clk_bypass = false;
+
+ return 0;
+}
+
+static int cz_tf_clear_nb_dpm_flag(struct pp_hwmgr *hwmgr,
+ void *input, void *output,
+ void *storage, int result)
+{
+ struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+ hw_data->is_nb_dpm_enabled = false;
+
+ return 0;
+}
+
+static int cz_tf_reset_cc6_data(struct pp_hwmgr *hwmgr,
+ void *input, void *output,
+ void *storage, int result)
+{
+ struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend);
+
+ hw_data->cc6_settings.cc6_setting_changed = false;
+ hw_data->cc6_settings.cpu_pstate_separation_time = 0;
+ hw_data->cc6_settings.cpu_cc6_disable = false;
+ hw_data->cc6_settings.cpu_pstate_disable = false;
+
+ return 0;
+}
+
+static struct phm_master_table_item cz_power_down_asic_list[] = {
+ {NULL, cz_tf_power_up_display_clock_sys_pll},
+ {NULL, cz_tf_clear_nb_dpm_flag},
+ {NULL, cz_tf_reset_cc6_data},
+ {NULL, NULL}
+};
+
+static struct phm_master_table_header cz_power_down_asic_master = {
+ 0,
+ PHM_MasterTableFlag_None,
+ cz_power_down_asic_list
+};
+
static int cz_tf_program_voting_clients(struct pp_hwmgr *hwmgr, void *input,
void *output, void *storage, int result)
{
@@ -1126,6 +1174,13 @@ static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
return result;
}
+ result = phm_construct_table(hwmgr, &cz_power_down_asic_master,
+ &(hwmgr->power_down_asic));
+ if (result != 0) {
+ printk(KERN_ERR "[ powerplay ] Fail to construct power down ASIC\n");
+ return result;
+ }
+
result = phm_construct_table(hwmgr, &cz_disable_dpm_master,
&(hwmgr->disable_dynamic_state_management));
if (result != 0) {
@@ -1183,7 +1238,7 @@ int cz_phm_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
hwmgr->dyn_state.vddc_dependency_on_sclk;
unsigned long clock = 0, level;
- if (NULL == table && table->count <= 0)
+ if (NULL == table || table->count <= 0)
return -EINVAL;
cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk;
@@ -1494,7 +1549,7 @@ cz_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
uint32_t vce_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX_2),
TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_VCE_INDEX);
- uint32_t sclk, vclk, dclk, ecclk, tmp, active_percent;
+ uint32_t sclk, vclk, dclk, ecclk, tmp, activity_percent;
uint16_t vddnb, vddgfx;
int result;
@@ -1536,13 +1591,13 @@ cz_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
result = smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetAverageGraphicsActivity);
if (0 == result) {
- active_percent = cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0);
- active_percent = active_percent > 100 ? 100 : active_percent;
+ activity_percent = cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0);
+ activity_percent = activity_percent > 100 ? 100 : activity_percent;
} else {
- active_percent = 50;
+ activity_percent = 50;
}
- seq_printf(m, "\n [GPU load]: %u %%\n\n", active_percent);
+ seq_printf(m, "\n [GPU load]: %u %%\n\n", activity_percent);
}
static void cz_hw_print_display_cfg(
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
index 94f404c121b7..28031a7eddba 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
@@ -914,7 +914,7 @@ static int fiji_trim_voltage_table(struct pp_hwmgr *hwmgr,
GFP_KERNEL);
if (NULL == table)
- return -EINVAL;
+ return -ENOMEM;
table->mask_low = vol_table->mask_low;
table->phase_delay = vol_table->phase_delay;
@@ -941,8 +941,9 @@ static int fiji_trim_voltage_table(struct pp_hwmgr *hwmgr,
memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
kfree(table);
- return 0;
+ return 0;
}
+
static int fiji_get_svi2_mvdd_voltage_table(struct pp_hwmgr *hwmgr,
phm_ppt_v1_clock_voltage_dependency_table *dep_table)
{
@@ -1112,7 +1113,7 @@ static int fiji_construct_voltage_tables(struct pp_hwmgr *hwmgr)
fiji_trim_voltage_table_to_fit_state_table(hwmgr,
SMU73_MAX_LEVELS_MVDD, &(data->mvdd_voltage_table)));
- return 0;
+ return 0;
}
static int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
@@ -1158,7 +1159,7 @@ static int fiji_program_static_screen_threshold_parameters(
CG_STATIC_SCREEN_PARAMETER, STATIC_SCREEN_THRESHOLD,
data->static_screen_threshold);
- return 0;
+ return 0;
}
/**
@@ -1295,7 +1296,7 @@ static int fiji_process_firmware_header(struct pp_hwmgr *hwmgr)
error |= (0 != result);
- return error ? -1 : 0;
+ return error ? -1 : 0;
}
/* Copy one arb setting to another and then switch the active set.
@@ -1339,12 +1340,12 @@ static int fiji_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
return -EINVAL;
}
- mc_cg_config = cgs_read_register(hwmgr->device, mmMC_CG_CONFIG);
- mc_cg_config |= 0x0000000F;
- cgs_write_register(hwmgr->device, mmMC_CG_CONFIG, mc_cg_config);
- PHM_WRITE_FIELD(hwmgr->device, MC_ARB_CG, CG_ARB_REQ, arb_dest);
+ mc_cg_config = cgs_read_register(hwmgr->device, mmMC_CG_CONFIG);
+ mc_cg_config |= 0x0000000F;
+ cgs_write_register(hwmgr->device, mmMC_CG_CONFIG, mc_cg_config);
+ PHM_WRITE_FIELD(hwmgr->device, MC_ARB_CG, CG_ARB_REQ, arb_dest);
- return 0;
+ return 0;
}
/**
@@ -1927,17 +1928,17 @@ static int fiji_populate_single_graphic_level(struct pp_hwmgr *hwmgr,
threshold = clock * data->fast_watermark_threshold / 100;
- /*
- * TODO: get minimum clocks from dal configaration
- * PECI_GetMinClockSettings(hwmgr->pPECI, &minClocks);
- */
- /* data->DisplayTiming.minClockInSR = minClocks.engineClockInSR; */
+ /*
+ * TODO: get minimum clocks from dal configaration
+ * PECI_GetMinClockSettings(hwmgr->pPECI, &minClocks);
+ */
+ /* data->DisplayTiming.minClockInSR = minClocks.engineClockInSR; */
- /* get level->DeepSleepDivId
- if (phm_cap_enabled(hwmgr->platformDescriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
- {
- level->DeepSleepDivId = PhwFiji_GetSleepDividerIdFromClock(hwmgr, clock, minClocks.engineClockInSR);
- } */
+ /* get level->DeepSleepDivId
+ if (phm_cap_enabled(hwmgr->platformDescriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep))
+ {
+ level->DeepSleepDivId = PhwFiji_GetSleepDividerIdFromClock(hwmgr, clock, minClocks.engineClockInSR);
+ } */
/* Default to slow, highest DPM level will be
* set to PPSMC_DISPLAY_WATERMARK_LOW later.
@@ -2756,7 +2757,7 @@ static int fiji_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
SclkFrequency) / 100);
if (fiji_clock_stretcher_lookup_table[stretch_amount2][0] <
clock_freq_u16 &&
- fiji_clock_stretcher_lookup_table[stretch_amount2][1] >
+ fiji_clock_stretcher_lookup_table[stretch_amount2][1] >
clock_freq_u16) {
/* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */
value |= (fiji_clock_stretcher_lookup_table[stretch_amount2][3]) << 16;
@@ -3172,9 +3173,9 @@ static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
/* enable SCLK dpm */
if(!data->sclk_dpm_key_disabled)
PP_ASSERT_WITH_CODE(
- (0 == smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DPM_Enable)),
- "Failed to enable SCLK DPM during DPM Start Function!",
- return -1);
+ (0 == smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DPM_Enable)),
+ "Failed to enable SCLK DPM during DPM Start Function!",
+ return -1);
/* enable MCLK dpm */
if(0 == data->mclk_dpm_key_disabled) {
@@ -3320,7 +3321,7 @@ static int fiji_start_dpm(struct pp_hwmgr *hwmgr)
return -1);
}
- return 0;
+ return 0;
}
static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr,
@@ -3378,7 +3379,7 @@ static int fiji_enable_auto_throttle_source(struct pp_hwmgr *hwmgr,
static int fiji_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr)
{
- return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
+ return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
}
static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
@@ -4865,7 +4866,9 @@ static int fiji_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
static void fiji_print_current_perforce_level(
struct pp_hwmgr *hwmgr, struct seq_file *m)
{
- uint32_t sclk, mclk;
+ uint32_t sclk, mclk, activity_percent = 0;
+ uint32_t offset;
+ struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
@@ -4876,6 +4879,13 @@ static void fiji_print_current_perforce_level(
mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
seq_printf(m, "\n [ mclk ]: %u MHz\n\n [ sclk ]: %u MHz\n",
mclk / 100, sclk / 100);
+
+ offset = data->soft_regs_start + offsetof(SMU73_SoftRegisters, AverageGraphicsActivity);
+ activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
+ activity_percent += 0x80;
+ activity_percent >>= 8;
+
+ seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent);
}
static int fiji_program_display_gap(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
index f89c98fd759e..6efcb2bac45f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_powertune.c
@@ -93,9 +93,9 @@ void fiji_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
*/
static uint16_t scale_fan_gain_settings(uint16_t raw_setting)
{
- uint32_t tmp;
- tmp = raw_setting * 4096 / 100;
- return (uint16_t)tmp;
+ uint32_t tmp;
+ tmp = raw_setting * 4096 / 100;
+ return (uint16_t)tmp;
}
static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda)
@@ -546,8 +546,8 @@ int fiji_power_control_set_level(struct pp_hwmgr *hwmgr)
* but message to be 8 bit fraction for messages
*/
target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100;
- result = fiji_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp);
- }
+ result = fiji_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp);
+ }
- return result;
+ return result;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c
index 5abde8f6d108..9deadabbc81c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c
@@ -66,7 +66,7 @@ int phm_dispatch_table(struct pp_hwmgr *hwmgr,
temp_storage = kzalloc(rt_table->storage_size, GFP_KERNEL);
if (temp_storage == NULL) {
printk(KERN_ERR "[ powerplay ] Could not allocate table temporary storage\n");
- return -1;
+ return -ENOMEM;
}
}
@@ -90,7 +90,7 @@ int phm_construct_table(struct pp_hwmgr *hwmgr,
if (hwmgr == NULL || master_table == NULL || rt_table == NULL) {
printk(KERN_ERR "[ powerplay ] Invalid Parameter!\n");
- return -1;
+ return -EINVAL;
}
for (table_item = master_table->master_list;
@@ -102,8 +102,9 @@ int phm_construct_table(struct pp_hwmgr *hwmgr,
size = (function_count + 1) * sizeof(phm_table_function);
run_time_list = kzalloc(size, GFP_KERNEL);
+
if (NULL == run_time_list)
- return -1;
+ return -ENOMEM;
rtf = run_time_list;
for (table_item = master_table->master_list;
@@ -111,7 +112,7 @@ int phm_construct_table(struct pp_hwmgr *hwmgr,
if ((rtf - run_time_list) > function_count) {
printk(KERN_ERR "[ powerplay ] Check function results have changed\n");
kfree(run_time_list);
- return -1;
+ return -EINVAL;
}
if ((NULL == table_item->isFunctionNeededInRuntimeTable) ||
@@ -123,7 +124,7 @@ int phm_construct_table(struct pp_hwmgr *hwmgr,
if ((rtf - run_time_list) > function_count) {
printk(KERN_ERR "[ powerplay ] Check function results have changed\n");
kfree(run_time_list);
- return -1;
+ return -EINVAL;
}
*rtf = NULL;
@@ -138,7 +139,7 @@ int phm_destroy_table(struct pp_hwmgr *hwmgr,
{
if (hwmgr == NULL || rt_table == NULL) {
printk(KERN_ERR "[ powerplay ] Invalid Parameter\n");
- return -1;
+ return -EINVAL;
}
if (NULL == rt_table->function_list)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
index 001b8bb4143d..0f2d5e4bc241 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
@@ -90,6 +90,22 @@ int phm_setup_asic(struct pp_hwmgr *hwmgr)
return 0;
}
+int phm_power_down_asic(struct pp_hwmgr *hwmgr)
+{
+ PHM_FUNC_CHECK(hwmgr);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_TablelessHardwareInterface)) {
+ if (NULL != hwmgr->hwmgr_func->power_off_asic)
+ return hwmgr->hwmgr_func->power_off_asic(hwmgr);
+ } else {
+ return phm_dispatch_table(hwmgr, &(hwmgr->power_down_asic),
+ NULL, NULL);
+ }
+
+ return 0;
+}
+
int phm_set_power_state(struct pp_hwmgr *hwmgr,
const struct pp_hw_power_state *pcurrent_state,
const struct pp_hw_power_state *pnew_power_state)
@@ -247,7 +263,6 @@ int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info)
*/
int phm_start_thermal_controller(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *temperature_range)
{
-
return phm_dispatch_table(hwmgr, &(hwmgr->start_thermal_controller), temperature_range, NULL);
}
@@ -317,4 +332,3 @@ int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr)
return 0;
}
-
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index ca4554b402f9..5fb98aa2e719 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -111,6 +111,9 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
+ if (hwmgr->ps == NULL)
+ return -ENOMEM;
+
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h
index 42f2423cddea..b7429a527828 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h
@@ -117,379 +117,380 @@ int GetRoundedValue(fInt); /* Incomplete function - Usef
*/
fInt fExponential(fInt exponent) /*Can be used to calculate e^exponent*/
{
- uint32_t i;
- bool bNegated = false;
+ uint32_t i;
+ bool bNegated = false;
- fInt fPositiveOne = ConvertToFraction(1);
- fInt fZERO = ConvertToFraction(0);
+ fInt fPositiveOne = ConvertToFraction(1);
+ fInt fZERO = ConvertToFraction(0);
- fInt lower_bound = Divide(78, 10000);
- fInt solution = fPositiveOne; /*Starting off with baseline of 1 */
- fInt error_term;
+ fInt lower_bound = Divide(78, 10000);
+ fInt solution = fPositiveOne; /*Starting off with baseline of 1 */
+ fInt error_term;
- uint32_t k_array[11] = {55452, 27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
- uint32_t expk_array[11] = {2560000, 160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
+ uint32_t k_array[11] = {55452, 27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
+ uint32_t expk_array[11] = {2560000, 160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
- if (GreaterThan(fZERO, exponent)) {
- exponent = fNegate(exponent);
- bNegated = true;
- }
+ if (GreaterThan(fZERO, exponent)) {
+ exponent = fNegate(exponent);
+ bNegated = true;
+ }
- while (GreaterThan(exponent, lower_bound)) {
- for (i = 0; i < 11; i++) {
- if (GreaterThan(exponent, GetScaledFraction(k_array[i], 10000))) {
- exponent = fSubtract(exponent, GetScaledFraction(k_array[i], 10000));
- solution = fMultiply(solution, GetScaledFraction(expk_array[i], 10000));
- }
- }
- }
+ while (GreaterThan(exponent, lower_bound)) {
+ for (i = 0; i < 11; i++) {
+ if (GreaterThan(exponent, GetScaledFraction(k_array[i], 10000))) {
+ exponent = fSubtract(exponent, GetScaledFraction(k_array[i], 10000));
+ solution = fMultiply(solution, GetScaledFraction(expk_array[i], 10000));
+ }
+ }
+ }
- error_term = fAdd(fPositiveOne, exponent);
+ error_term = fAdd(fPositiveOne, exponent);
- solution = fMultiply(solution, error_term);
+ solution = fMultiply(solution, error_term);
- if (bNegated)
- solution = fDivide(fPositiveOne, solution);
+ if (bNegated)
+ solution = fDivide(fPositiveOne, solution);
- return solution;
+ return solution;
}
fInt fNaturalLog(fInt value)
{
- uint32_t i;
- fInt upper_bound = Divide(8, 1000);
- fInt fNegativeOne = ConvertToFraction(-1);
- fInt solution = ConvertToFraction(0); /*Starting off with baseline of 0 */
- fInt error_term;
-
- uint32_t k_array[10] = {160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
- uint32_t logk_array[10] = {27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
-
- while (GreaterThan(fAdd(value, fNegativeOne), upper_bound)) {
- for (i = 0; i < 10; i++) {
- if (GreaterThan(value, GetScaledFraction(k_array[i], 10000))) {
- value = fDivide(value, GetScaledFraction(k_array[i], 10000));
- solution = fAdd(solution, GetScaledFraction(logk_array[i], 10000));
- }
- }
- }
-
- error_term = fAdd(fNegativeOne, value);
-
- return (fAdd(solution, error_term));
+ uint32_t i;
+ fInt upper_bound = Divide(8, 1000);
+ fInt fNegativeOne = ConvertToFraction(-1);
+ fInt solution = ConvertToFraction(0); /*Starting off with baseline of 0 */
+ fInt error_term;
+
+ uint32_t k_array[10] = {160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
+ uint32_t logk_array[10] = {27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
+
+ while (GreaterThan(fAdd(value, fNegativeOne), upper_bound)) {
+ for (i = 0; i < 10; i++) {
+ if (GreaterThan(value, GetScaledFraction(k_array[i], 10000))) {
+ value = fDivide(value, GetScaledFraction(k_array[i], 10000));
+ solution = fAdd(solution, GetScaledFraction(logk_array[i], 10000));
+ }
+ }
+ }
+
+ error_term = fAdd(fNegativeOne, value);
+
+ return (fAdd(solution, error_term));
}
fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength)
{
- fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
- fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+ fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
+ fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
- fInt f_decoded_value;
+ fInt f_decoded_value;
- f_decoded_value = fDivide(f_fuse_value, f_bit_max_value);
- f_decoded_value = fMultiply(f_decoded_value, f_range);
- f_decoded_value = fAdd(f_decoded_value, f_min);
+ f_decoded_value = fDivide(f_fuse_value, f_bit_max_value);
+ f_decoded_value = fMultiply(f_decoded_value, f_range);
+ f_decoded_value = fAdd(f_decoded_value, f_min);
- return f_decoded_value;
+ return f_decoded_value;
}
fInt fDecodeLogisticFuse(uint32_t fuse_value, fInt f_average, fInt f_range, uint32_t bitlength)
{
- fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
- fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+ fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
+ fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
- fInt f_CONSTANT_NEG13 = ConvertToFraction(-13);
- fInt f_CONSTANT1 = ConvertToFraction(1);
+ fInt f_CONSTANT_NEG13 = ConvertToFraction(-13);
+ fInt f_CONSTANT1 = ConvertToFraction(1);
- fInt f_decoded_value;
+ fInt f_decoded_value;
- f_decoded_value = fSubtract(fDivide(f_bit_max_value, f_fuse_value), f_CONSTANT1);
- f_decoded_value = fNaturalLog(f_decoded_value);
- f_decoded_value = fMultiply(f_decoded_value, fDivide(f_range, f_CONSTANT_NEG13));
- f_decoded_value = fAdd(f_decoded_value, f_average);
+ f_decoded_value = fSubtract(fDivide(f_bit_max_value, f_fuse_value), f_CONSTANT1);
+ f_decoded_value = fNaturalLog(f_decoded_value);
+ f_decoded_value = fMultiply(f_decoded_value, fDivide(f_range, f_CONSTANT_NEG13));
+ f_decoded_value = fAdd(f_decoded_value, f_average);
- return f_decoded_value;
+ return f_decoded_value;
}
fInt fDecodeLeakageID (uint32_t leakageID_fuse, fInt ln_max_div_min, fInt f_min, uint32_t bitlength)
{
- fInt fLeakage;
- fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
+ fInt fLeakage;
+ fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
- fLeakage = fMultiply(ln_max_div_min, Convert_ULONG_ToFraction(leakageID_fuse));
- fLeakage = fDivide(fLeakage, f_bit_max_value);
- fLeakage = fExponential(fLeakage);
- fLeakage = fMultiply(fLeakage, f_min);
+ fLeakage = fMultiply(ln_max_div_min, Convert_ULONG_ToFraction(leakageID_fuse));
+ fLeakage = fDivide(fLeakage, f_bit_max_value);
+ fLeakage = fExponential(fLeakage);
+ fLeakage = fMultiply(fLeakage, f_min);
- return fLeakage;
+ return fLeakage;
}
fInt ConvertToFraction(int X) /*Add all range checking here. Is it possible to make fInt a private declaration? */
{
- fInt temp;
+ fInt temp;
- if (X <= MAX)
- temp.full = (X << SHIFT_AMOUNT);
- else
- temp.full = 0;
+ if (X <= MAX)
+ temp.full = (X << SHIFT_AMOUNT);
+ else
+ temp.full = 0;
- return temp;
+ return temp;
}
fInt fNegate(fInt X)
{
- fInt CONSTANT_NEGONE = ConvertToFraction(-1);
- return (fMultiply(X, CONSTANT_NEGONE));
+ fInt CONSTANT_NEGONE = ConvertToFraction(-1);
+ return (fMultiply(X, CONSTANT_NEGONE));
}
fInt Convert_ULONG_ToFraction(uint32_t X)
{
- fInt temp;
+ fInt temp;
- if (X <= MAX)
- temp.full = (X << SHIFT_AMOUNT);
- else
- temp.full = 0;
+ if (X <= MAX)
+ temp.full = (X << SHIFT_AMOUNT);
+ else
+ temp.full = 0;
- return temp;
+ return temp;
}
fInt GetScaledFraction(int X, int factor)
{
- int times_shifted, factor_shifted;
- bool bNEGATED;
- fInt fValue;
-
- times_shifted = 0;
- factor_shifted = 0;
- bNEGATED = false;
-
- if (X < 0) {
- X = -1*X;
- bNEGATED = true;
- }
-
- if (factor < 0) {
- factor = -1*factor;
-
- bNEGATED = !bNEGATED; /*If bNEGATED = true due to X < 0, this will cover the case of negative cancelling negative */
- }
-
- if ((X > MAX) || factor > MAX) {
- if ((X/factor) <= MAX) {
- while (X > MAX) {
- X = X >> 1;
- times_shifted++;
- }
-
- while (factor > MAX) {
- factor = factor >> 1;
- factor_shifted++;
- }
- } else {
- fValue.full = 0;
- return fValue;
- }
- }
-
- if (factor == 1)
- return (ConvertToFraction(X));
-
- fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor));
-
- fValue.full = fValue.full << times_shifted;
- fValue.full = fValue.full >> factor_shifted;
-
- return fValue;
+ int times_shifted, factor_shifted;
+ bool bNEGATED;
+ fInt fValue;
+
+ times_shifted = 0;
+ factor_shifted = 0;
+ bNEGATED = false;
+
+ if (X < 0) {
+ X = -1*X;
+ bNEGATED = true;
+ }
+
+ if (factor < 0) {
+ factor = -1*factor;
+ bNEGATED = !bNEGATED; /*If bNEGATED = true due to X < 0, this will cover the case of negative cancelling negative */
+ }
+
+ if ((X > MAX) || factor > MAX) {
+ if ((X/factor) <= MAX) {
+ while (X > MAX) {
+ X = X >> 1;
+ times_shifted++;
+ }
+
+ while (factor > MAX) {
+ factor = factor >> 1;
+ factor_shifted++;
+ }
+ } else {
+ fValue.full = 0;
+ return fValue;
+ }
+ }
+
+ if (factor == 1)
+ return (ConvertToFraction(X));
+
+ fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor));
+
+ fValue.full = fValue.full << times_shifted;
+ fValue.full = fValue.full >> factor_shifted;
+
+ return fValue;
}
/* Addition using two fInts */
fInt fAdd (fInt X, fInt Y)
{
- fInt Sum;
+ fInt Sum;
- Sum.full = X.full + Y.full;
+ Sum.full = X.full + Y.full;
- return Sum;
+ return Sum;
}
/* Addition using two fInts */
fInt fSubtract (fInt X, fInt Y)
{
- fInt Difference;
+ fInt Difference;
- Difference.full = X.full - Y.full;
+ Difference.full = X.full - Y.full;
- return Difference;
+ return Difference;
}
bool Equal(fInt A, fInt B)
{
- if (A.full == B.full)
- return true;
- else
- return false;
+ if (A.full == B.full)
+ return true;
+ else
+ return false;
}
bool GreaterThan(fInt A, fInt B)
{
- if (A.full > B.full)
- return true;
- else
- return false;
+ if (A.full > B.full)
+ return true;
+ else
+ return false;
}
fInt fMultiply (fInt X, fInt Y) /* Uses 64-bit integers (int64_t) */
{
- fInt Product;
- int64_t tempProduct;
- bool X_LessThanOne, Y_LessThanOne;
+ fInt Product;
+ int64_t tempProduct;
+ bool X_LessThanOne, Y_LessThanOne;
- X_LessThanOne = (X.partial.real == 0 && X.partial.decimal != 0 && X.full >= 0);
- Y_LessThanOne = (Y.partial.real == 0 && Y.partial.decimal != 0 && Y.full >= 0);
+ X_LessThanOne = (X.partial.real == 0 && X.partial.decimal != 0 && X.full >= 0);
+ Y_LessThanOne = (Y.partial.real == 0 && Y.partial.decimal != 0 && Y.full >= 0);
- /*The following is for a very specific common case: Non-zero number with ONLY fractional portion*/
- /* TEMPORARILY DISABLED - CAN BE USED TO IMPROVE PRECISION
+ /*The following is for a very specific common case: Non-zero number with ONLY fractional portion*/
+ /* TEMPORARILY DISABLED - CAN BE USED TO IMPROVE PRECISION
- if (X_LessThanOne && Y_LessThanOne) {
- Product.full = X.full * Y.full;
- return Product
- }*/
+ if (X_LessThanOne && Y_LessThanOne) {
+ Product.full = X.full * Y.full;
+ return Product
+ }*/
- tempProduct = ((int64_t)X.full) * ((int64_t)Y.full); /*Q(16,16)*Q(16,16) = Q(32, 32) - Might become a negative number! */
- tempProduct = tempProduct >> 16; /*Remove lagging 16 bits - Will lose some precision from decimal; */
- Product.full = (int)tempProduct; /*The int64_t will lose the leading 16 bits that were part of the integer portion */
+ tempProduct = ((int64_t)X.full) * ((int64_t)Y.full); /*Q(16,16)*Q(16,16) = Q(32, 32) - Might become a negative number! */
+ tempProduct = tempProduct >> 16; /*Remove lagging 16 bits - Will lose some precision from decimal; */
+ Product.full = (int)tempProduct; /*The int64_t will lose the leading 16 bits that were part of the integer portion */
- return Product;
+ return Product;
}
fInt fDivide (fInt X, fInt Y)
{
- fInt fZERO, fQuotient;
- int64_t longlongX, longlongY;
+ fInt fZERO, fQuotient;
+ int64_t longlongX, longlongY;
- fZERO = ConvertToFraction(0);
+ fZERO = ConvertToFraction(0);
- if (Equal(Y, fZERO))
- return fZERO;
+ if (Equal(Y, fZERO))
+ return fZERO;
- longlongX = (int64_t)X.full;
- longlongY = (int64_t)Y.full;
+ longlongX = (int64_t)X.full;
+ longlongY = (int64_t)Y.full;
- longlongX = longlongX << 16; /*Q(16,16) -> Q(32,32) */
+ longlongX = longlongX << 16; /*Q(16,16) -> Q(32,32) */
- do_div(longlongX, longlongY); /*Q(32,32) divided by Q(16,16) = Q(16,16) Back to original format */
+ div64_s64(longlongX, longlongY); /*Q(32,32) divided by Q(16,16) = Q(16,16) Back to original format */
- fQuotient.full = (int)longlongX;
- return fQuotient;
+ fQuotient.full = (int)longlongX;
+ return fQuotient;
}
int ConvertBackToInteger (fInt A) /*THIS is the function that will be used to check with the Golden settings table*/
{
- fInt fullNumber, scaledDecimal, scaledReal;
+ fInt fullNumber, scaledDecimal, scaledReal;
- scaledReal.full = GetReal(A) * uPow(10, PRECISION-1); /* DOUBLE CHECK THISSSS!!! */
+ scaledReal.full = GetReal(A) * uPow(10, PRECISION-1); /* DOUBLE CHECK THISSSS!!! */
- scaledDecimal.full = uGetScaledDecimal(A);
+ scaledDecimal.full = uGetScaledDecimal(A);
- fullNumber = fAdd(scaledDecimal,scaledReal);
+ fullNumber = fAdd(scaledDecimal,scaledReal);
- return fullNumber.full;
+ return fullNumber.full;
}
fInt fGetSquare(fInt A)
{
- return fMultiply(A,A);
+ return fMultiply(A,A);
}
/* x_new = x_old - (x_old^2 - C) / (2 * x_old) */
fInt fSqrt(fInt num)
{
- fInt F_divide_Fprime, Fprime;
- fInt test;
- fInt twoShifted;
- int seed, counter, error;
- fInt x_new, x_old, C, y;
+ fInt F_divide_Fprime, Fprime;
+ fInt test;
+ fInt twoShifted;
+ int seed, counter, error;
+ fInt x_new, x_old, C, y;
- fInt fZERO = ConvertToFraction(0);
- /* (0 > num) is the same as (num < 0), i.e., num is negative */
- if (GreaterThan(fZERO, num) || Equal(fZERO, num))
- return fZERO;
+ fInt fZERO = ConvertToFraction(0);
- C = num;
+ /* (0 > num) is the same as (num < 0), i.e., num is negative */
- if (num.partial.real > 3000)
- seed = 60;
- else if (num.partial.real > 1000)
- seed = 30;
- else if (num.partial.real > 100)
- seed = 10;
- else
- seed = 2;
+ if (GreaterThan(fZERO, num) || Equal(fZERO, num))
+ return fZERO;
- counter = 0;
+ C = num;
- if (Equal(num, fZERO)) /*Square Root of Zero is zero */
- return fZERO;
+ if (num.partial.real > 3000)
+ seed = 60;
+ else if (num.partial.real > 1000)
+ seed = 30;
+ else if (num.partial.real > 100)
+ seed = 10;
+ else
+ seed = 2;
+
+ counter = 0;
- twoShifted = ConvertToFraction(2);
- x_new = ConvertToFraction(seed);
+ if (Equal(num, fZERO)) /*Square Root of Zero is zero */
+ return fZERO;
- do {
- counter++;
+ twoShifted = ConvertToFraction(2);
+ x_new = ConvertToFraction(seed);
- x_old.full = x_new.full;
+ do {
+ counter++;
- test = fGetSquare(x_old); /*1.75*1.75 is reverting back to 1 when shifted down */
- y = fSubtract(test, C); /*y = f(x) = x^2 - C; */
+ x_old.full = x_new.full;
- Fprime = fMultiply(twoShifted, x_old);
- F_divide_Fprime = fDivide(y, Fprime);
+ test = fGetSquare(x_old); /*1.75*1.75 is reverting back to 1 when shifted down */
+ y = fSubtract(test, C); /*y = f(x) = x^2 - C; */
- x_new = fSubtract(x_old, F_divide_Fprime);
+ Fprime = fMultiply(twoShifted, x_old);
+ F_divide_Fprime = fDivide(y, Fprime);
- error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old);
+ x_new = fSubtract(x_old, F_divide_Fprime);
- if (counter > 20) /*20 is already way too many iterations. If we dont have an answer by then, we never will*/
- return x_new;
+ error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old);
- } while (uAbs(error) > 0);
+ if (counter > 20) /*20 is already way too many iterations. If we dont have an answer by then, we never will*/
+ return x_new;
- return (x_new);
+ } while (uAbs(error) > 0);
+
+ return (x_new);
}
void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[])
{
- fInt* pRoots = &Roots[0];
- fInt temp, root_first, root_second;
- fInt f_CONSTANT10, f_CONSTANT100;
+ fInt *pRoots = &Roots[0];
+ fInt temp, root_first, root_second;
+ fInt f_CONSTANT10, f_CONSTANT100;
- f_CONSTANT100 = ConvertToFraction(100);
- f_CONSTANT10 = ConvertToFraction(10);
+ f_CONSTANT100 = ConvertToFraction(100);
+ f_CONSTANT10 = ConvertToFraction(10);
- while(GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) {
- A = fDivide(A, f_CONSTANT10);
- B = fDivide(B, f_CONSTANT10);
- C = fDivide(C, f_CONSTANT10);
- }
+ while(GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) {
+ A = fDivide(A, f_CONSTANT10);
+ B = fDivide(B, f_CONSTANT10);
+ C = fDivide(C, f_CONSTANT10);
+ }
- temp = fMultiply(ConvertToFraction(4), A); /* root = 4*A */
- temp = fMultiply(temp, C); /* root = 4*A*C */
- temp = fSubtract(fGetSquare(B), temp); /* root = b^2 - 4AC */
- temp = fSqrt(temp); /*root = Sqrt (b^2 - 4AC); */
+ temp = fMultiply(ConvertToFraction(4), A); /* root = 4*A */
+ temp = fMultiply(temp, C); /* root = 4*A*C */
+ temp = fSubtract(fGetSquare(B), temp); /* root = b^2 - 4AC */
+ temp = fSqrt(temp); /*root = Sqrt (b^2 - 4AC); */
- root_first = fSubtract(fNegate(B), temp); /* b - Sqrt(b^2 - 4AC) */
- root_second = fAdd(fNegate(B), temp); /* b + Sqrt(b^2 - 4AC) */
+ root_first = fSubtract(fNegate(B), temp); /* b - Sqrt(b^2 - 4AC) */
+ root_second = fAdd(fNegate(B), temp); /* b + Sqrt(b^2 - 4AC) */
- root_first = fDivide(root_first, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
- root_first = fDivide(root_first, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
+ root_first = fDivide(root_first, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
+ root_first = fDivide(root_first, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
- root_second = fDivide(root_second, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
- root_second = fDivide(root_second, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
+ root_second = fDivide(root_second, ConvertToFraction(2)); /* [b +- Sqrt(b^2 - 4AC)]/[2] */
+ root_second = fDivide(root_second, A); /*[b +- Sqrt(b^2 - 4AC)]/[2*A] */
- *(pRoots + 0) = root_first;
- *(pRoots + 1) = root_second;
+ *(pRoots + 0) = root_first;
+ *(pRoots + 1) = root_second;
}
/* -----------------------------------------------------------------------------
@@ -500,61 +501,58 @@ void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[])
/* Addition using two normal ints - Temporary - Use only for testing purposes?. */
fInt Add (int X, int Y)
{
- fInt A, B, Sum;
+ fInt A, B, Sum;
- A.full = (X << SHIFT_AMOUNT);
- B.full = (Y << SHIFT_AMOUNT);
+ A.full = (X << SHIFT_AMOUNT);
+ B.full = (Y << SHIFT_AMOUNT);
- Sum.full = A.full + B.full;
+ Sum.full = A.full + B.full;
- return Sum;
+ return Sum;
}
/* Conversion Functions */
int GetReal (fInt A)
{
- return (A.full >> SHIFT_AMOUNT);
+ return (A.full >> SHIFT_AMOUNT);
}
/* Temporarily Disabled */
int GetRoundedValue(fInt A) /*For now, round the 3rd decimal place */
{
- /* ROUNDING TEMPORARLY DISABLED
- int temp = A.full;
-
- int decimal_cutoff, decimal_mask = 0x000001FF;
-
- decimal_cutoff = temp & decimal_mask;
-
-
- if (decimal_cutoff > 0x147) {
- temp += 673;
- }*/
-
- return ConvertBackToInteger(A)/10000; /*Temporary - in case this was used somewhere else */
+ /* ROUNDING TEMPORARLY DISABLED
+ int temp = A.full;
+ int decimal_cutoff, decimal_mask = 0x000001FF;
+ decimal_cutoff = temp & decimal_mask;
+ if (decimal_cutoff > 0x147) {
+ temp += 673;
+ }*/
+
+ return ConvertBackToInteger(A)/10000; /*Temporary - in case this was used somewhere else */
}
fInt Multiply (int X, int Y)
{
- fInt A, B, Product;
+ fInt A, B, Product;
- A.full = X << SHIFT_AMOUNT;
- B.full = Y << SHIFT_AMOUNT;
+ A.full = X << SHIFT_AMOUNT;
+ B.full = Y << SHIFT_AMOUNT;
- Product = fMultiply(A, B);
+ Product = fMultiply(A, B);
- return Product;
+ return Product;
}
+
fInt Divide (int X, int Y)
{
- fInt A, B, Quotient;
+ fInt A, B, Quotient;
- A.full = X << SHIFT_AMOUNT;
- B.full = Y << SHIFT_AMOUNT;
+ A.full = X << SHIFT_AMOUNT;
+ B.full = Y << SHIFT_AMOUNT;
- Quotient = fDivide(A, B);
+ Quotient = fDivide(A, B);
- return Quotient;
+ return Quotient;
}
int uGetScaledDecimal (fInt A) /*Converts the fractional portion to whole integers - Costly function */
@@ -563,16 +561,13 @@ int uGetScaledDecimal (fInt A) /*Converts the fractional portion to whole intege
int i, scaledDecimal = 0, tmp = A.partial.decimal;
for (i = 0; i < PRECISION; i++) {
- dec[i] = tmp / (1 << SHIFT_AMOUNT);
-
- tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]);
-
- tmp *= 10;
-
- scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i);
- }
+ dec[i] = tmp / (1 << SHIFT_AMOUNT);
+ tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]);
+ tmp *= 10;
+ scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i);
+ }
- return scaledDecimal;
+ return scaledDecimal;
}
int uPow(int base, int power)
@@ -601,17 +596,17 @@ int uAbs(int X)
fInt fRoundUpByStepSize(fInt A, fInt fStepSize, bool error_term)
{
- fInt solution;
+ fInt solution;
- solution = fDivide(A, fStepSize);
- solution.partial.decimal = 0; /*All fractional digits changes to 0 */
+ solution = fDivide(A, fStepSize);
+ solution.partial.decimal = 0; /*All fractional digits changes to 0 */
- if (error_term)
- solution.partial.real += 1; /*Error term of 1 added */
+ if (error_term)
+ solution.partial.real += 1; /*Error term of 1 added */
- solution = fMultiply(solution, fStepSize);
- solution = fAdd(solution, fStepSize);
+ solution = fMultiply(solution, fStepSize);
+ solution = fAdd(solution, fStepSize);
- return solution;
+ return solution;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
index 1d385f473776..2f1a14fe05b1 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
@@ -735,8 +735,8 @@ static int init_non_clock_fields(struct pp_hwmgr *hwmgr,
ps->memory.dllOff = (0 != tmp);
- ps->memory.m3arb = (uint8_t)(le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
- ATOM_PPLIB_M3ARB_MASK) >> ATOM_PPLIB_M3ARB_SHIFT;
+ ps->memory.m3arb = (le32_to_cpu(pnon_clock_info->ulCapsAndSettings) &
+ ATOM_PPLIB_M3ARB_MASK) >> ATOM_PPLIB_M3ARB_SHIFT;
ps->temperatures.min = PP_TEMPERATURE_UNITS_PER_CENTIGRADES *
pnon_clock_info->ucMinTemperature;
@@ -1322,11 +1322,17 @@ static int get_cac_leakage_table(struct pp_hwmgr *hwmgr,
struct phm_cac_leakage_table *cac_leakage_table;
unsigned long table_size, i;
+ if (hwmgr == NULL || table == NULL || ptable == NULL)
+ return -EINVAL;
+
table_size = sizeof(ULONG) +
(sizeof(struct phm_cac_leakage_table) * table->ucNumEntries);
cac_leakage_table = kzalloc(table_size, GFP_KERNEL);
+ if (cac_leakage_table == NULL)
+ return -ENOMEM;
+
cac_leakage_table->count = (ULONG)table->ucNumEntries;
for (i = 0; i < cac_leakage_table->count; i++) {
@@ -1349,7 +1355,7 @@ static int get_cac_leakage_table(struct pp_hwmgr *hwmgr,
static int get_platform_power_management_table(struct pp_hwmgr *hwmgr,
ATOM_PPLIB_PPM_Table *atom_ppm_table)
{
- struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_PPLIB_PPM_Table), GFP_KERNEL);
+ struct phm_ppm_table *ptr = kzalloc(sizeof(struct phm_ppm_table), GFP_KERNEL);
if (NULL == ptr)
return -ENOMEM;
@@ -1466,6 +1472,9 @@ static int init_phase_shedding_table(struct pp_hwmgr *hwmgr,
table = kzalloc(size, GFP_KERNEL);
+ if (table == NULL)
+ return -ENOMEM;
+
table->count = (unsigned long)ptable->ucNumEntries;
for (i = 0; i < table->count; i++) {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
index 3cb5d041b3cf..44a925006479 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
@@ -115,9 +115,12 @@ const unsigned long PhwTonga_Magic = (unsigned long)(PHM_VIslands_Magic);
struct tonga_power_state *cast_phw_tonga_power_state(
struct pp_hw_power_state *hw_ps)
{
+ if (hw_ps == NULL)
+ return NULL;
+
PP_ASSERT_WITH_CODE((PhwTonga_Magic == hw_ps->magic),
"Invalid Powerstate Type!",
- return NULL;);
+ return NULL);
return (struct tonga_power_state *)hw_ps;
}
@@ -125,9 +128,12 @@ struct tonga_power_state *cast_phw_tonga_power_state(
const struct tonga_power_state *cast_const_phw_tonga_power_state(
const struct pp_hw_power_state *hw_ps)
{
+ if (hw_ps == NULL)
+ return NULL;
+
PP_ASSERT_WITH_CODE((PhwTonga_Magic == hw_ps->magic),
"Invalid Powerstate Type!",
- return NULL;);
+ return NULL);
return (const struct tonga_power_state *)hw_ps;
}
@@ -1678,9 +1684,9 @@ static int tonga_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].VclkFrequency);
CONVERT_FROM_HOST_TO_SMC_UL(table->UvdLevel[count].DclkFrequency);
//CONVERT_FROM_HOST_TO_SMC_UL((uint32_t)table->UvdLevel[count].MinVoltage);
- }
+ }
- return result;
+ return result;
}
@@ -1719,7 +1725,7 @@ static int tonga_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
PP_ASSERT_WITH_CODE((0 == result),
"can not find divide id for VCE engine clock", return result);
- table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+ table->VceLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
CONVERT_FROM_HOST_TO_SMC_UL(table->VceLevel[count].Frequency);
}
@@ -1804,7 +1810,7 @@ static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
PP_ASSERT_WITH_CODE((0 == result),
"can not find divide id for samu clock", return result);
- table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
+ table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider;
CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency);
}
@@ -1847,7 +1853,7 @@ static int tonga_calculate_mclk_params(
"Error retrieving Memory Clock Parameters from VBIOS.", return result);
/* MPLL_FUNC_CNTL setup*/
- mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl);
+ mpll_func_cntl = PHM_SET_FIELD(mpll_func_cntl, MPLL_FUNC_CNTL, BWCTRL, mpll_param.bw_ctrl);
/* MPLL_FUNC_CNTL_1 setup*/
mpll_func_cntl_1 = PHM_SET_FIELD(mpll_func_cntl_1,
@@ -3864,6 +3870,7 @@ int tonga_copy_vbios_smc_reg_table(const pp_atomctrl_mc_reg_table *table, phw_to
table->mc_reg_table_entry[i].mc_data[j];
}
}
+
ni_table->num_entries = table->num_entries;
return 0;
@@ -3989,7 +3996,7 @@ int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr)
table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL);
if (NULL == table)
- return -1;
+ return -ENOMEM;
/* Program additional LP registers that are no longer programmed by VBIOS */
cgs_write_register(hwmgr->device, mmMC_SEQ_RAS_TIMING_LP, cgs_read_register(hwmgr->device, mmMC_SEQ_RAS_TIMING));
@@ -5150,7 +5157,7 @@ static int tonga_get_pp_table_entry(struct pp_hwmgr *hwmgr,
static void
tonga_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
{
- uint32_t sclk, mclk, active_percent;
+ uint32_t sclk, mclk, activity_percent;
uint32_t offset;
struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
@@ -5165,11 +5172,11 @@ tonga_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
offset = data->soft_regs_start + offsetof(SMU72_SoftRegisters, AverageGraphicsActivity);
- active_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
- active_percent += 80;
- active_percent >>= 8;
+ activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
+ activity_percent += 0x80;
+ activity_percent >>= 8;
- seq_printf(m, "\n [GPU load]: %u%%\n\n", active_percent > 100 ? 100 : active_percent);
+ seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent);
}
@@ -5470,7 +5477,6 @@ static int tonga_generate_dpm_level_enable_mask(struct pp_hwmgr *hwmgr, const vo
struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
const struct tonga_power_state *tonga_ps = cast_const_phw_tonga_power_state(states->pnew_state);
-
result = tonga_trim_dpm_states(hwmgr, tonga_ps);
if (0 != result)
return result;
@@ -5732,7 +5738,7 @@ static int tonga_set_max_fan_pwm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_
if (phm_is_hw_access_blocked(hwmgr))
return 0;
- return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm) ? 0 : -EINVAL);
+ return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanPwmMax, us_max_fan_pwm) ? 0 : -1);
}
int tonga_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr)
@@ -5826,7 +5832,7 @@ static int tonga_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_
if (phm_is_hw_access_blocked(hwmgr))
return 0;
- return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanRpmMax, us_max_fan_pwm) ? 0 : -EINVAL);
+ return (0 == smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_SetFanRpmMax, us_max_fan_pwm) ? 0 : -1);
}
uint32_t tonga_get_xclk(struct pp_hwmgr *hwmgr)
@@ -5962,7 +5968,7 @@ int tonga_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_st
const struct tonga_power_state *psb = cast_const_phw_tonga_power_state(pstate2);
int i;
- if (pstate1 == NULL || pstate2 == NULL || equal == NULL)
+ if (equal == NULL || psa == NULL || psb == NULL)
return -EINVAL;
/* If the two states don't even have the same number of performance levels they cannot be the same state. */
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
index ae216fe8547d..34f4bef3691f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
@@ -168,7 +168,7 @@ static int get_vddc_lookup_table(
kzalloc(table_size, GFP_KERNEL);
if (NULL == table)
- return -1;
+ return -ENOMEM;
memset(table, 0x00, table_size);
@@ -206,7 +206,7 @@ static int get_platform_power_management_table(
(struct phm_ppt_v1_information *)(hwmgr->pptable);
if (NULL == ptr)
- return -1;
+ return -ENOMEM;
ptr->ppm_design
= atom_ppm_table->ucPpmDesign;
@@ -327,7 +327,7 @@ static int get_valid_clk(
table = (struct phm_clock_array *)kzalloc(table_size, GFP_KERNEL);
if (NULL == table)
- return -1;
+ return -ENOMEM;
memset(table, 0x00, table_size);
@@ -378,7 +378,7 @@ static int get_mclk_voltage_dependency_table(
kzalloc(table_size, GFP_KERNEL);
if (NULL == mclk_table)
- return -1;
+ return -ENOMEM;
memset(mclk_table, 0x00, table_size);
@@ -421,7 +421,7 @@ static int get_sclk_voltage_dependency_table(
kzalloc(table_size, GFP_KERNEL);
if (NULL == sclk_table)
- return -1;
+ return -ENOMEM;
memset(sclk_table, 0x00, table_size);
@@ -464,7 +464,7 @@ static int get_pcie_table(
pcie_table = (phm_ppt_v1_pcie_table *)kzalloc(table_size, GFP_KERNEL);
if (NULL == pcie_table)
- return -1;
+ return -ENOMEM;
memset(pcie_table, 0x00, table_size);
@@ -506,14 +506,14 @@ static int get_cac_tdp_table(
tdp_table = kzalloc(table_size, GFP_KERNEL);
if (NULL == tdp_table)
- return -1;
+ return -ENOMEM;
memset(tdp_table, 0x00, table_size);
hwmgr->dyn_state.cac_dtp_table = kzalloc(table_size, GFP_KERNEL);
if (NULL == hwmgr->dyn_state.cac_dtp_table)
- return -1;
+ return -ENOMEM;
memset(hwmgr->dyn_state.cac_dtp_table, 0x00, table_size);
@@ -614,7 +614,7 @@ static int get_mm_clock_voltage_table(
kzalloc(table_size, GFP_KERNEL);
if (NULL == mm_table)
- return -1;
+ return -ENOMEM;
memset(mm_table, 0x00, table_size);
@@ -943,7 +943,7 @@ int tonga_pp_tables_initialize(struct pp_hwmgr *hwmgr)
hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v1_information), GFP_KERNEL);
PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable),
- "Failed to allocate hwmgr->pptable!", return -1);
+ "Failed to allocate hwmgr->pptable!", return -ENOMEM);
memset(hwmgr->pptable, 0x00, sizeof(struct phm_ppt_v1_information));
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
index a503306c3d0e..91795efe1336 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
@@ -379,5 +379,7 @@ extern int phm_get_dal_power_level(struct pp_hwmgr *hwmgr,
extern int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr);
+extern int phm_power_down_asic(struct pp_hwmgr *hwmgr);
+
#endif /* _HARDWARE_MANAGER_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index eb0f1b22d42d..aeaa3dbba525 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -325,7 +325,8 @@ struct pp_hwmgr_func {
bool cc6_disable, bool pstate_disable,
bool pstate_switch_disable);
int (*get_dal_power_level)(struct pp_hwmgr *hwmgr,
- struct amd_pp_dal_clock_info*info);
+ struct amd_pp_dal_clock_info *info);
+ int (*power_off_asic)(struct pp_hwmgr *hwmgr);
};
struct pp_table_func {
@@ -576,9 +577,10 @@ struct pp_hwmgr {
void *pptable;
struct phm_platform_descriptor platform_descriptor;
void *backend;
- enum PP_DAL_POWERLEVEL dal_power_level;
+ enum PP_DAL_POWERLEVEL dal_power_level;
struct phm_dynamic_state_info dyn_state;
struct phm_runtime_table_header setup_asic;
+ struct phm_runtime_table_header power_down_asic;
struct phm_runtime_table_header disable_dynamic_state_management;
struct phm_runtime_table_header enable_dynamic_state_management;
struct phm_runtime_table_header set_power_state;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h
index 7b60b617dff6..4d8ed1f33de4 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/pp_instance.h
@@ -27,7 +27,10 @@
#include "hwmgr.h"
#include "eventmgr.h"
+#define PP_VALID 0x1F1F1F1F
+
struct pp_instance {
+ uint32_t pp_valid;
struct pp_smumgr *smu_mgr;
struct pp_hwmgr *hwmgr;
struct pp_eventmgr *eventmgr;
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
index e74023bd4e0d..873a8d264d5c 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c
@@ -818,7 +818,7 @@ static int cz_smu_fini(struct pp_smumgr *smumgr)
return -EINVAL;
cz_smu = (struct cz_smumgr *)smumgr->backend;
- if (!cz_smu) {
+ if (cz_smu) {
cgs_free_gpu_mem(smumgr->device,
cz_smu->toc_buffer.handle);
cgs_free_gpu_mem(smumgr->device,
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index 45997e609fd6..cdbb9f89bf36 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -228,9 +228,9 @@ int fiji_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
}
cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
- SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
+ SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
- return 0;
+ return 0;
}
/**
@@ -557,7 +557,7 @@ static int fiji_request_smu_specific_fw_load(struct pp_smumgr *smumgr, uint32_t
/* For non-virtualization cases,
* SMU loads all FWs at once in fiji_request_smu_load_fw.
*/
- return 0;
+ return 0;
}
static int fiji_start_smu_in_protection_mode(struct pp_smumgr *smumgr)
@@ -723,7 +723,7 @@ static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
/* clear reset */
cgs_write_register(smumgr->device, mmGRBM_SOFT_RESET, 0);
- return result;
+ return result;
}
int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
@@ -1033,7 +1033,7 @@ int fiji_smum_init(struct pp_smumgr *smumgr)
fiji_smu = kzalloc(sizeof(struct fiji_smumgr), GFP_KERNEL);
if (fiji_smu == NULL)
- return -1;
+ return -ENOMEM;
smumgr->backend = fiji_smu;
smumgr->smumgr_funcs = &fiji_smu_funcs;
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
index 62ff76010aa6..d166fd925dbb 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
@@ -810,7 +810,7 @@ int tonga_smum_init(struct pp_smumgr *smumgr)
tonga_smu = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
if (tonga_smu == NULL)
- return -1;
+ return -ENOMEM;
smumgr->backend = tonga_smu;
smumgr->smumgr_funcs = &tonga_smu_funcs;
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index c5a942b15d63..6ed90a2437e5 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -978,17 +978,17 @@ static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u
static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
u8 *rad)
{
- int lct = port->parent->lct;
+ int parent_lct = port->parent->lct;
int shift = 4;
- int idx = lct / 2;
- if (lct > 1) {
- memcpy(rad, port->parent->rad, idx);
- shift = (lct % 2) ? 4 : 0;
+ int idx = (parent_lct - 1) / 2;
+ if (parent_lct > 1) {
+ memcpy(rad, port->parent->rad, idx + 1);
+ shift = (parent_lct % 2) ? 4 : 0;
} else
rad[0] = 0;
rad[idx] |= port->port_num << shift;
- return lct + 1;
+ return parent_lct + 1;
}
/*
@@ -1044,7 +1044,7 @@ static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
for (i = 0; i < (mstb->lct - 1); i++) {
int shift = (i % 2) ? 0 : 4;
- int port_num = mstb->rad[i / 2] >> shift;
+ int port_num = (mstb->rad[i / 2] >> shift) & 0xf;
snprintf(temp, sizeof(temp), "-%d", port_num);
strlcat(proppath, temp, proppath_size);
}
@@ -1195,7 +1195,7 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
for (i = 0; i < lct - 1; i++) {
int shift = (i % 2) ? 0 : 4;
- int port_num = rad[i / 2] >> shift;
+ int port_num = (rad[i / 2] >> shift) & 0xf;
list_for_each_entry(port, &mstb->ports, next) {
if (port->port_num == port_num) {
@@ -1215,6 +1215,50 @@ out:
return mstb;
}
+static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
+ struct drm_dp_mst_branch *mstb,
+ uint8_t *guid)
+{
+ struct drm_dp_mst_branch *found_mstb;
+ struct drm_dp_mst_port *port;
+
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (!port->mstb)
+ continue;
+
+ if (port->guid_valid && memcmp(port->guid, guid, 16) == 0)
+ return port->mstb;
+
+ found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);
+
+ if (found_mstb)
+ return found_mstb;
+ }
+
+ return NULL;
+}
+
+static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid(
+ struct drm_dp_mst_topology_mgr *mgr,
+ uint8_t *guid)
+{
+ struct drm_dp_mst_branch *mstb;
+
+ /* find the port by iterating down */
+ mutex_lock(&mgr->lock);
+
+ if (mgr->guid_valid && memcmp(mgr->guid, guid, 16) == 0)
+ mstb = mgr->mst_primary;
+ else
+ mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
+
+ if (mstb)
+ kref_get(&mstb->kref);
+
+ mutex_unlock(&mgr->lock);
+ return mstb;
+}
+
static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_branch *mstb)
{
@@ -1325,6 +1369,7 @@ static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,
struct drm_dp_sideband_msg_tx *txmsg)
{
struct drm_dp_mst_branch *mstb = txmsg->dst;
+ u8 req_type;
/* both msg slots are full */
if (txmsg->seqno == -1) {
@@ -1341,7 +1386,13 @@ static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,
txmsg->seqno = 1;
mstb->tx_slots[txmsg->seqno] = txmsg;
}
- hdr->broadcast = 0;
+
+ req_type = txmsg->msg[0] & 0x7f;
+ if (req_type == DP_CONNECTION_STATUS_NOTIFY ||
+ req_type == DP_RESOURCE_STATUS_NOTIFY)
+ hdr->broadcast = 1;
+ else
+ hdr->broadcast = 0;
hdr->path_msg = txmsg->path_msg;
hdr->lct = mstb->lct;
hdr->lcr = mstb->lct - 1;
@@ -1443,26 +1494,18 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
}
/* called holding qlock */
-static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
+static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_sideband_msg_tx *txmsg)
{
- struct drm_dp_sideband_msg_tx *txmsg;
int ret;
/* construct a chunk from the first msg in the tx_msg queue */
- if (list_empty(&mgr->tx_msg_upq)) {
- mgr->tx_up_in_progress = false;
- return;
- }
-
- txmsg = list_first_entry(&mgr->tx_msg_upq, struct drm_dp_sideband_msg_tx, next);
ret = process_single_tx_qlock(mgr, txmsg, true);
- if (ret == 1) {
- /* up txmsgs aren't put in slots - so free after we send it */
- list_del(&txmsg->next);
- kfree(txmsg);
- } else if (ret)
+
+ if (ret != 1)
DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
- mgr->tx_up_in_progress = true;
+
+ txmsg->dst->tx_slots[txmsg->seqno] = NULL;
}
static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
@@ -1856,11 +1899,12 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
drm_dp_encode_up_ack_reply(txmsg, req_type);
mutex_lock(&mgr->qlock);
- list_add_tail(&txmsg->next, &mgr->tx_msg_upq);
- if (!mgr->tx_up_in_progress) {
- process_single_up_tx_qlock(mgr);
- }
+
+ process_single_up_tx_qlock(mgr, txmsg);
+
mutex_unlock(&mgr->qlock);
+
+ kfree(txmsg);
return 0;
}
@@ -2157,28 +2201,50 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
if (mgr->up_req_recv.have_eomt) {
struct drm_dp_sideband_msg_req_body msg;
- struct drm_dp_mst_branch *mstb;
+ struct drm_dp_mst_branch *mstb = NULL;
bool seqno;
- mstb = drm_dp_get_mst_branch_device(mgr,
- mgr->up_req_recv.initial_hdr.lct,
- mgr->up_req_recv.initial_hdr.rad);
- if (!mstb) {
- DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
- memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
- return 0;
+
+ if (!mgr->up_req_recv.initial_hdr.broadcast) {
+ mstb = drm_dp_get_mst_branch_device(mgr,
+ mgr->up_req_recv.initial_hdr.lct,
+ mgr->up_req_recv.initial_hdr.rad);
+ if (!mstb) {
+ DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+ memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
}
seqno = mgr->up_req_recv.initial_hdr.seqno;
drm_dp_sideband_parse_req(&mgr->up_req_recv, &msg);
if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
- drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+ drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
+
+ if (!mstb)
+ mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.conn_stat.guid);
+
+ if (!mstb) {
+ DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+ memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
+
drm_dp_update_port(mstb, &msg.u.conn_stat);
DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
(*mgr->cbs->hotplug)(mgr);
} else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
- drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+ drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
+ if (!mstb)
+ mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.resource_stat.guid);
+
+ if (!mstb) {
+ DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+ memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
+
DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
}
@@ -2770,7 +2836,6 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
mutex_init(&mgr->qlock);
mutex_init(&mgr->payload_lock);
mutex_init(&mgr->destroy_connector_lock);
- INIT_LIST_HEAD(&mgr->tx_msg_upq);
INIT_LIST_HEAD(&mgr->tx_msg_downq);
INIT_LIST_HEAD(&mgr->destroy_connector_list);
INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 9e7e2bf03b81..5eae0a88dd3e 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3150,7 +3150,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
{
fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff;
fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff;
- fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff;
+ fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff;
+ fixed20_12 crit_point_ff = {0};
uint32_t temp, data, mem_trcd, mem_trp, mem_tras;
fixed20_12 memtcas_ff[8] = {
dfixed_init(1),
@@ -3204,7 +3205,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)
fixed20_12 min_mem_eff;
fixed20_12 mc_latency_sclk, mc_latency_mclk, k1;
fixed20_12 cur_latency_mclk, cur_latency_sclk;
- fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate,
+ fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate = {0},
disp_drain_rate2, read_return_rate;
fixed20_12 time_disp1_drop_priority;
int c;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index d690df545b4d..902b59cebac5 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1150,7 +1150,7 @@ static void radeon_check_arguments(struct radeon_device *rdev)
}
if (radeon_vm_size < 1) {
- dev_warn(rdev->dev, "VM size (%d) to small, min is 1GB\n",
+ dev_warn(rdev->dev, "VM size (%d) too small, min is 1GB\n",
radeon_vm_size);
radeon_vm_size = 4;
}
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 4fab44e0f36b..414953c46a38 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -759,7 +759,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe)
u32 count;
struct radeon_device *rdev = dev->dev_private;
- if (pipe < 0 || pipe >= rdev->num_crtc) {
+ if (pipe >= rdev->num_crtc) {
DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
}