From 6a53b31349e7fbe6f742b7f09d7c2118d4fe81e3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 1 Jan 2016 14:07:41 +0100 Subject: [PATCH 01/33] drm: powerplay: use div64_s64 instead of do_div MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The newly added code for Fiji creates a correct compiler warning about invalid use of the do_div macro: In file included from powerplay/hwmgr/ppatomctrl.c:31:0: drivers/gpu/drm/amd/amdgpu/../powerplay/hwmgr/ppevvmath.h: In function 'fDivide': drivers/gpu/drm/amd/amdgpu/../powerplay/hwmgr/ppevvmath.h:382:89: warning: comparison of distinct pointer types lacks a cast do_div(longlongX, longlongY); /*Q(32,32) divided by Q(16,16) = Q(16,16) Back to original format */ do_div() divides an unsigned 64-bit number by an unsigned 32-bit number. The code instead wants to divide two signed 64-bit numbers, which is done using the div64_s64 function. Reviewed-by: Thierry Reding Reviewed-by: Christian König Signed-off-by: Arnd Bergmann Fixes: 770911a3cfbb ("drm/amd/powerplay: add/update headers for Fiji SMU and DPM") Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h index 42f2423cddea..411cb0fcdf98 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h @@ -379,7 +379,7 @@ fInt fDivide (fInt X, fInt Y) 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; From bd9343208704fcc70a5b919f228a7d26ae472727 Mon Sep 17 00:00:00 2001 From: Mykola Lysenko Date: Fri, 18 Dec 2015 17:14:42 -0500 Subject: [PATCH 02/33] drm/dp/mst: process broadcast messages correctly In case broadcast message received in UP request, RAD cannot be used to identify message originator. Message should be parsed, originator should be found by GUID from parsed message. Also reply with broadcast in case broadcast message received (for now it is always broadcast) Acked-by: Dave Airlie Signed-off-by: Mykola Lysenko Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 95 +++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index c5a942b15d63..7710de6e8a55 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1215,6 +1215,50 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ 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; @@ -2157,28 +2208,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); } From 1f16ee7fa13649f4e55aa48ad31c3eb0722a62d3 Mon Sep 17 00:00:00 2001 From: Mykola Lysenko Date: Fri, 18 Dec 2015 17:14:43 -0500 Subject: [PATCH 03/33] drm/dp/mst: always send reply for UP request We should always send reply for UP request in order to make downstream device clean-up resources appropriately. Issue was that reply for UP request was sent only once. Acked-by: Dave Airlie Signed-off-by: Mykola Lysenko Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 30 ++++++++++----------------- include/drm/drm_dp_mst_helper.h | 2 -- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 7710de6e8a55..ca92a3217465 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1494,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, @@ -1907,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; } @@ -2843,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/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 74b5888bbc73..4fc55a87dfee 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -451,9 +451,7 @@ struct drm_dp_mst_topology_mgr { the mstb tx_slots and txmsg->state once they are queued */ struct mutex qlock; struct list_head tx_msg_downq; - struct list_head tx_msg_upq; bool tx_down_in_progress; - bool tx_up_in_progress; /* payload info + lock for it */ struct mutex payload_lock; From 75af4c8c4c0f60d7ad135419805798f144e9baf9 Mon Sep 17 00:00:00 2001 From: Mykola Lysenko Date: Fri, 25 Dec 2015 16:14:47 +0800 Subject: [PATCH 04/33] drm/dp/mst: fix in MSTB RAD initialization This fix is needed to support more then two branch displays, so RAD address consist at least of 2 elements Acked-by: Dave Airlie Signed-off-by: Mykola Lysenko Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index ca92a3217465..d809ce8a4f28 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; } /* From 7a11a334aa6af4c65c6a0d81b60c97fc18673532 Mon Sep 17 00:00:00 2001 From: Mykola Lysenko Date: Fri, 25 Dec 2015 16:14:48 +0800 Subject: [PATCH 05/33] drm/dp/mst: fix in RAD element access This is needed to receive correct port number from RAD, so MSTB could be found Acked-by: Dave Airlie Signed-off-by: Mykola Lysenko Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index d809ce8a4f28..6ed90a2437e5 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -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) { From 85a21eafbc2218ffba59b1dda2ce9d7148bf43d2 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 4 Jan 2016 18:19:12 +0100 Subject: [PATCH 06/33] drm/radeon: Drop unnecessary unsigned int < 0 check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unsigned integers can never be negative, so drop this check. Cc: Christian König Cc: Alex Deucher Signed-off-by: Thierry Reding Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From 2500a3c9e06d349defdca00f2efd7fab189ae72f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Jan 2016 23:42:55 +0300 Subject: [PATCH 07/33] drm/amd/powerplay: fix a reversed condition This test was reversed so it would end up leading to a NULL dereference. Fixes: 4630f0faae80 ('drm/amd/powerplay: add Carrizo smu support') Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, From b92c26d1808ccd2acac17b660dce750ba9b0a0db Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Jan 2016 23:43:47 +0300 Subject: [PATCH 08/33] drm/amdgpu/cgs: cleanup some indenting This code is indented too far. Also we normally use spaces to align if statement conditions. Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 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) { From 7c9574f262a25c7ca0779df31098ba4e0c382e86 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Jan 2016 23:44:24 +0300 Subject: [PATCH 09/33] drm/amd/powerplay: precedence bug in init_non_clock_fields() The cast to uint8_t happens before the right shift so this always sets .m3arb to zero. The cast is actually a no-op so we can remove it. Fixes: 3bace3591493 ('drm/amd/powerplay: add hardware manager sub-component') Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index 1d385f473776..8f9d705bbde2 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; From e1de741529412f31cb53899307bd63286918c49c Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 29 Dec 2015 11:57:38 +0800 Subject: [PATCH 10/33] drm/amdgpu: fix NULL in vm_grab_id while S3 back vm_manager_fini shouldn't be in suspend phase. Signed-off-by: Chunming Zhou Reviewed-by: Ken Wang --- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 1 - drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 1 - 2 files changed, 2 deletions(-) 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; } From 1dab5f067e1371e5ed88aa6c47a3cd800f061cfa Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 10:21:46 -0500 Subject: [PATCH 11/33] amdgpu/vce3: Cleanup harvest config function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Basic LOC reduction. Signed-off-by: Tom St Denis Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 35f48ad7644d..0de86dea4bfa 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) From 92988e604b8a7c7d541396905433021eedfc28bb Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 10:35:56 -0500 Subject: [PATCH 12/33] amdgpu/vce3: Simplify idle and wait for idle code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More LOC reductions in VCE3 code. This patch simplifies the is_idle and wait_for_idle logic. Signed-off-by: Tom St Denis Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 30 +++++---------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 0de86dea4bfa..f20529d5cb84 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -535,17 +535,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 & (1<<0)) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK; + mask |= (adev->vce.harvest_config & (1<<1)) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK; return !(RREG32(mmSRBM_STATUS2) & mask); } @@ -554,23 +546,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; } From af18b0f7fb635e5b18d541bf05058723412d749f Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 10:40:16 -0500 Subject: [PATCH 13/33] amdgpu/vce3: Simplify vce_v3_0_soft_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LOC reduction and simplification. Signed-off-by: Tom St Denis Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index f20529d5cb84..d50db761e327 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -558,17 +558,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 & (1<<0)) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; + mask |= (adev->vce.harvest_config & (1<<1)) ? 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)); From 81da2edef935adc6091deb20963c29d8463f1440 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 10:42:39 -0500 Subject: [PATCH 14/33] amdgpu/vce3: Simplify vce_v3_0_process_interrupt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold two cases into one for a LOC reduction. Signed-off-by: Tom St Denis Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index d50db761e327..d3e7ba60d99c 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -663,10 +663,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", From 74af12762de65cbbc11e11501dacd652fae75de9 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Mon, 4 Jan 2016 10:46:41 -0500 Subject: [PATCH 15/33] amdgpu/vce3: Remove magic constants from harvest register masks. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index d3e7ba60d99c..ad56b1f49b09 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -536,8 +536,8 @@ static bool vce_v3_0_is_idle(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; u32 mask = 0; - mask |= (adev->vce.harvest_config & (1<<0)) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK; - mask |= (adev->vce.harvest_config & (1<<1)) ? 0 : 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); } @@ -559,8 +559,8 @@ static int vce_v3_0_soft_reset(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; u32 mask = 0; - mask |= (adev->vce.harvest_config & (1<<0)) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK; - mask |= (adev->vce.harvest_config & (1<<1)) ? 0 : SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK; + 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; WREG32_P(mmSRBM_SOFT_RESET, mask, ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK | From 691ca86a3a15a9c5054edb3c517a1aeb40e9fadc Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 10:55:34 -0500 Subject: [PATCH 16/33] amdgpu/vce3: Simplify vce_v3_0_hw_init and ensure both rings default to not ready. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplified the ring test and added logic to ensure rings are marked not ready by default. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index ad56b1f49b09..e99af81e4aec 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -414,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"); From 9e4e1ae82f2479a32bee61132206367a710e961e Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 13:01:49 -0500 Subject: [PATCH 17/33] amdgpu/dce11: Remove division from dce_v11_0_vblank_wait() Mimics odd behaviour where (i++ % 100 == 0) is true in the first iteration of each loop... Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 8701661a8868..80be62a0b99b 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -211,7 +211,7 @@ 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) return; @@ -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; } From 15c3277ff60286860b3dc98651fc241875e678fa Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 15 Dec 2015 13:03:43 -0500 Subject: [PATCH 18/33] amdgpu/dce11: Add test for crtc < 0 to various DCEv11 functions To be consistent with other DCE11 functions test for crtc < 0. Signed-off-by: Tom St Denis Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 80be62a0b99b..8e67249d4367 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -213,7 +213,7 @@ static void dce_v11_0_vblank_wait(struct amdgpu_device *adev, int crtc) { 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)) @@ -241,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]); @@ -3386,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; } @@ -3401,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; } From 53d3de140b668d37e1ebfe01c94ec36d369edcbf Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 16:22:07 +0800 Subject: [PATCH 19/33] drm/amd/powerplay: fix bug that NULL checks are reversed. && was used instead of ||. Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Reviewed-by: Ken Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 5bac36baa13c..c0e6aae8fa1d 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; @@ -1183,7 +1183,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; From 75ac63dbc3b0f4d3af67a5857790749e954e2ba6 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 16:38:48 +0800 Subject: [PATCH 20/33] drm/amd/powerplay: fix Smatch static checker warnings with indenting (v2) v2: AGD: rebase on upstream Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Reviewed-by: Ken Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- .../gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 51 +- .../drm/amd/powerplay/hwmgr/fiji_powertune.c | 12 +- .../drm/amd/powerplay/hwmgr/hardwaremanager.c | 1 - .../gpu/drm/amd/powerplay/hwmgr/ppevvmath.h | 527 +++++++++--------- .../drm/amd/powerplay/smumgr/fiji_smumgr.c | 8 +- 6 files changed, 298 insertions(+), 303 deletions(-) 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/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 94f404c121b7..6dba5bf73e52 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c @@ -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) 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/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index 001b8bb4143d..f9bf4fccbc79 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c @@ -317,4 +317,3 @@ int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr) return 0; } - diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h index 411cb0fcdf98..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 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}; + 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)); - } - } - } + 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); + error_term = fAdd(fNegativeOne, value); - return (fAdd(solution, error_term)); + 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; + int times_shifted, factor_shifted; + bool bNEGATED; + fInt fValue; - times_shifted = 0; - factor_shifted = 0; - bNEGATED = false; + times_shifted = 0; + factor_shifted = 0; + bNEGATED = false; - if (X < 0) { - X = -1*X; - bNEGATED = true; - } + if (X < 0) { + X = -1*X; + bNEGATED = true; + } - if (factor < 0) { - factor = -1*factor; + if (factor < 0) { + factor = -1*factor; + bNEGATED = !bNEGATED; /*If bNEGATED = true due to X < 0, this will cover the case of negative cancelling negative */ + } - 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++; + } - 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; + } + } - while (factor > MAX) { - factor = factor >> 1; - factor_shifted++; - } - } else { - fValue.full = 0; - return fValue; - } - } + if (factor == 1) + return (ConvertToFraction(X)); - if (factor == 1) - return (ConvertToFraction(X)); + fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor)); - fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor)); + fValue.full = fValue.full << times_shifted; + fValue.full = fValue.full >> factor_shifted; - fValue.full = fValue.full << times_shifted; - fValue.full = fValue.full >> factor_shifted; - - return fValue; + 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) */ - div64_s64(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; - twoShifted = ConvertToFraction(2); - x_new = ConvertToFraction(seed); + counter = 0; - do { - counter++; + if (Equal(num, fZERO)) /*Square Root of Zero is zero */ + return fZERO; - x_old.full = x_new.full; + twoShifted = ConvertToFraction(2); + x_new = ConvertToFraction(seed); - 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; */ + do { + counter++; - Fprime = fMultiply(twoShifted, x_old); - F_divide_Fprime = fDivide(y, Fprime); + x_old.full = x_new.full; - x_new = fSubtract(x_old, F_divide_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; */ - error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old); + Fprime = fMultiply(twoShifted, x_old); + F_divide_Fprime = fDivide(y, 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; + x_new = fSubtract(x_old, F_divide_Fprime); - } while (uAbs(error) > 0); + error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old); - return (x_new); + if (counter > 20) /*20 is already way too many iterations. If we dont have an answer by then, we never will*/ + 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; + /* ROUNDING TEMPORARLY DISABLED + int temp = A.full; + int decimal_cutoff, decimal_mask = 0x000001FF; + decimal_cutoff = temp & decimal_mask; + if (decimal_cutoff > 0x147) { + temp += 673; + }*/ - 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 */ + 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); + dec[i] = tmp / (1 << SHIFT_AMOUNT); + tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]); + tmp *= 10; + scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i); + } - 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/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 45997e609fd6..21c31db0df26 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) From c15c8d70207d467bb4312d6ac5536c101246fdc6 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 16:48:38 +0800 Subject: [PATCH 21/33] drm/amd/powerplay: fix Smatch static checker warnings 1. return -1 instead of -ENOMEM 2. The struct type mismatch warnings. Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Reviewed-by: Ken Wang Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 2 +- .../drm/amd/powerplay/hwmgr/functiontables.c | 13 ++++---- drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 3 ++ .../drm/amd/powerplay/hwmgr/processpptables.c | 11 ++++++- .../gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | 30 +++++++++++-------- .../powerplay/hwmgr/tonga_processpptables.c | 20 ++++++------- .../drm/amd/powerplay/smumgr/fiji_smumgr.c | 2 +- .../drm/amd/powerplay/smumgr/tonga_smumgr.c | 2 +- 8 files changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 6dba5bf73e52..3f3009d6b6e0 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; 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/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/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index 8f9d705bbde2..2f1a14fe05b1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c @@ -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..0b188d13364f 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)); @@ -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/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 21c31db0df26..cdbb9f89bf36 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -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; From a969e163a4ac1b0cfa2dc7ab890aaa9ab092951c Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 13:56:03 +0800 Subject: [PATCH 22/33] drm/amd/powerplay: add powerplay valid check to avoid null point. (v2) In case CONFIG_DRM_AMD_POWERPLAY is defined and amdgpu.powerplay=0. some functions in powrplay can also be called by DAL. and the input parameter is *adev. if just check point not NULL was not enough and will lead to NULL point error. V2: AGD: rebase on upstream Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 15 ++++++++++++--- drivers/gpu/drm/amd/powerplay/inc/pp_instance.h | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index db0370bd60e3..2764bd327034 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; @@ -537,6 +543,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,8 +619,7 @@ 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; @@ -625,7 +632,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/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; From e0b71a7eff644ca256aee6478bf220ba0a835bed Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 10:25:19 +0800 Subject: [PATCH 23/33] drm/amd/powerplay: Reload and initialize the smc firmware on powerplay resume. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 2764bd327034..8f5d5edcf193 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -203,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; } @@ -624,6 +640,7 @@ int amd_powerplay_display_configuration_change(void *handle, const void *input) hwmgr = ((struct pp_instance *)handle)->hwmgr; phm_store_dal_configuration_data(hwmgr, display_config); + return 0; } From 9354573d76f599e05a34e0b468ffce681769115f Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 17:08:46 +0800 Subject: [PATCH 24/33] drm/amdgpu: Show gpu load when display gpu performance for Ci. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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, From 0cfd9f26975be88e8d902f9bc7070f98dfdfeea2 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 17:15:59 +0800 Subject: [PATCH 25/33] drm/amdgpu: Show gpu load when display gpu performance for Fiji of VI. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 3f3009d6b6e0..28031a7eddba 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c @@ -4866,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); @@ -4877,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) From ab4f4b14c36f7ae6fa204ca304477e42f6696453 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jan 2016 17:17:53 +0800 Subject: [PATCH 26/33] drm/amdgpu: fix hex/decimal bug when show gpu load. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 10 +++++----- drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index c0e6aae8fa1d..65ad24a498a6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -1494,7 +1494,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 +1536,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/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 0b188d13364f..44a925006479 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c @@ -5157,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); @@ -5172,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); } From f556c2744a8e7508493cf409849d5a248ed3fb9d Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 11:23:57 +0800 Subject: [PATCH 27/33] drm/amd/powerplay: add thermal control task when resume. Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c | 1 + 1 file changed, 1 insertion(+) 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, From 018462d015c5672de0be8045b1acff19f5df6010 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 11:19:14 +0800 Subject: [PATCH 28/33] drm/amd/powerplay: enable set boot state task Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c | 6 ++++-- drivers/gpu/drm/amd/powerplay/eventmgr/psm.c | 3 +-- drivers/gpu/drm/amd/powerplay/eventmgr/psm.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c index f0700d077925..f0b449157653 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c @@ -74,7 +74,9 @@ int pem_task_power_down_asic(struct pp_eventmgr *eventmgr, struct pem_event_data 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 +345,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); From e1d32e607b5ce25a7852bef4ab4de2a80f30c546 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 11:22:34 +0800 Subject: [PATCH 29/33] drm/amd/powerplay: enable power down asic task. (v2) v2: AGD: rebase on upstream Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/eventmgr/eventtasks.c | 3 +-- .../drm/amd/powerplay/hwmgr/hardwaremanager.c | 17 ++++++++++++++++- .../gpu/drm/amd/powerplay/inc/hardwaremanager.h | 2 ++ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 6 ++++-- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c index f0b449157653..5cd123472db4 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventtasks.c @@ -68,8 +68,7 @@ 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) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index f9bf4fccbc79..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); } 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; From 4d42fa492eb80aed28d2237efaee004453579556 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 29 Dec 2015 11:23:16 +0800 Subject: [PATCH 30/33] drm/amd/powerplay: implement power down asic task for CZ Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index 65ad24a498a6..0874ab42ee95 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -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) { From 191caba6cc4c95ba282304a10a2a9cba85450317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 15 Dec 2015 11:10:30 +0100 Subject: [PATCH 31/33] drm/amdgpu: add warning to amdgpu_bo_gpu_offset() v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check if there really is a valid offset for the BO. v2: user WARN_ON_ONCE Signed-off-by: Christian König Reviewed-by: Michel Dänzer Reviewed-by: Alex Deucher (v1) Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 + 1 file changed, 1 insertion(+) 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; } From 1ef897e4645392c6c5230f2ae92c6bc658e44345 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Thu, 7 Jan 2016 10:31:32 -0700 Subject: [PATCH 32/33] radeon: r100: Silence 'may be used uninitialized' warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC [M] drivers/gpu/drm/radeon/r100.o In file included from drivers/gpu/drm/radeon/radeon_mode.h:37:0, from drivers/gpu/drm/radeon/radeon.h:80, from drivers/gpu/drm/radeon/r100.c:33: drivers/gpu/drm/radeon/r100.c: In function 'r100_bandwidth_update': include/drm/drm_fixed.h:64:13: warning: 'crit_point_ff.full' may be used uninitialized in this function [-Wmaybe-uninitialized] u64 tmp = ((u64)A.full << 13); ^ drivers/gpu/drm/radeon/r100.c:3153:63: note: 'crit_point_ff.full' was declared here fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; ^ drivers/gpu/drm/radeon/r100.c:3583:42: warning: 'disp_drain_rate.full' may be used uninitialized in this function [-Wmaybe-uninitialized] temp_ff.full = read_return_rate.full - disp_drain_rate.full; gcc version 5.3.1 20151219 (Ubuntu 5.3.1-4ubuntu1) Cc: Alex Deucher Cc: "Christian König" Cc: David Airlie Signed-off-by: Tim Gardner Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r100.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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; From 13c240ef95e6569956ba9c731a650cecb3603f0e Mon Sep 17 00:00:00 2001 From: Alexandre Demers Date: Thu, 7 Jan 2016 19:22:44 -0500 Subject: [PATCH 33/33] drm/radeon: fix trivial typo in warning message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Alexandre Demers Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; }