summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/msm')
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c3
-rw-r--r--drivers/gpu/msm/kgsl.c2
-rw-r--r--drivers/gpu/msm/kgsl_debugfs.c7
-rw-r--r--drivers/gpu/msm/kgsl_debugfs.h4
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.c69
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.h7
-rw-r--r--drivers/gpu/msm/kgsl_snapshot.c8
7 files changed, 93 insertions, 7 deletions
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 973884c2c5e7..87300096fbf1 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -161,6 +161,7 @@ static const struct {
{ adreno_is_a530, a530_efuse_speed_bin },
{ adreno_is_a505, a530_efuse_speed_bin },
{ adreno_is_a512, a530_efuse_speed_bin },
+ { adreno_is_a508, a530_efuse_speed_bin },
};
static void a5xx_check_features(struct adreno_device *adreno_dev)
@@ -1166,7 +1167,7 @@ static const struct kgsl_hwcg_reg a512_hwcg_regs[] = {
{A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
{A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
{A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
- {A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555},
+ {A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
{A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
{A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
{A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 601e7a23101b..1de8e212a703 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -4753,6 +4753,7 @@ error_close_mmu:
error_pwrctrl_close:
kgsl_pwrctrl_close(device);
error:
+ kgsl_device_debugfs_close(device);
_unregister_device(device);
return status;
}
@@ -4782,6 +4783,7 @@ void kgsl_device_platform_remove(struct kgsl_device *device)
kgsl_pwrctrl_close(device);
+ kgsl_device_debugfs_close(device);
_unregister_device(device);
}
EXPORT_SYMBOL(kgsl_device_platform_remove);
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 7758fc956055..37d92428f02c 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2008-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -87,6 +87,11 @@ void kgsl_device_debugfs_init(struct kgsl_device *device)
&pwr_log_fops);
}
+void kgsl_device_debugfs_close(struct kgsl_device *device)
+{
+ debugfs_remove_recursive(device->d_debugfs);
+}
+
struct type_entry {
int type;
const char *str;
diff --git a/drivers/gpu/msm/kgsl_debugfs.h b/drivers/gpu/msm/kgsl_debugfs.h
index 34875954bb8b..949aed81581c 100644
--- a/drivers/gpu/msm/kgsl_debugfs.h
+++ b/drivers/gpu/msm/kgsl_debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011,2013,2015 The Linux Foundation.
+/* Copyright (c) 2002,2008-2011,2013,2015,2017 The Linux Foundation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@ void kgsl_core_debugfs_init(void);
void kgsl_core_debugfs_close(void);
void kgsl_device_debugfs_init(struct kgsl_device *device);
+void kgsl_device_debugfs_close(struct kgsl_device *device);
extern struct dentry *kgsl_debugfs_dir;
static inline struct dentry *kgsl_get_debugfs_dir(void)
@@ -34,6 +35,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *);
#else
static inline void kgsl_core_debugfs_init(void) { }
static inline void kgsl_device_debugfs_init(struct kgsl_device *device) { }
+static inline void kgsl_device_debugfs_close(struct kgsl_device *device) { }
static inline void kgsl_core_debugfs_close(void) { }
static inline struct dentry *kgsl_get_debugfs_dir(void) { return NULL; }
static inline void kgsl_process_init_debugfs(struct kgsl_process_private *priv)
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index fe6aa45901d0..e639e197de93 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -361,6 +361,26 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
if (new_level == old_level)
return;
+ if (pwr->gpu_cx_ipeak) {
+ unsigned int old_freq = pwr->pwrlevels[old_level].gpu_freq;
+ unsigned int new_freq = pwr->pwrlevels[new_level].gpu_freq;
+
+ /*
+ * Set Cx ipeak vote for GPU if it tries to cross
+ * threshold frequency.
+ */
+ if (old_freq < pwr->gpu_cx_ipeak_clk &&
+ new_freq >= pwr->gpu_cx_ipeak_clk) {
+ int ret = cx_ipeak_update(pwr->gpu_cx_ipeak, true);
+
+ if (ret) {
+ KGSL_PWR_ERR(device,
+ "cx_ipeak_update failed %d\n", ret);
+ return;
+ }
+ }
+ }
+
kgsl_pwrscale_update_stats(device);
/*
@@ -422,6 +442,24 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
/* Timestamp the frequency change */
device->pwrscale.freq_change_time = ktime_to_ms(ktime_get());
+
+ if (pwr->gpu_cx_ipeak) {
+ unsigned int old_freq = pwr->pwrlevels[old_level].gpu_freq;
+ unsigned int new_freq = pwr->pwrlevels[new_level].gpu_freq;
+
+ /*
+ * Reset Cx ipeak vote for GPU if it goes below
+ * threshold frequency.
+ */
+ if (old_freq >= pwr->gpu_cx_ipeak_clk &&
+ new_freq < pwr->gpu_cx_ipeak_clk) {
+ int ret = cx_ipeak_update(pwr->gpu_cx_ipeak, false);
+
+ if (ret)
+ KGSL_PWR_ERR(device,
+ "cx_ipeak_update failed %d\n", ret);
+ }
+ }
}
EXPORT_SYMBOL(kgsl_pwrctrl_pwrlevel_change);
@@ -2217,8 +2255,37 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
of_property_read_string(pdev->dev.of_node, "qcom,tsens-name",
&pwr->tsens_name);
+ /* Cx ipeak client support */
+ if (of_find_property(pdev->dev.of_node, "qcom,gpu-cx-ipeak", NULL)) {
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "qcom,gpu-cx-ipeak-clk", &pwr->gpu_cx_ipeak_clk)) {
+ pwr->gpu_cx_ipeak = cx_ipeak_register(pdev->dev.of_node,
+ "qcom,gpu-cx-ipeak");
+ } else {
+ KGSL_PWR_ERR(device, "failed to get gpu cxip clk\n");
+ result = -EINVAL;
+ goto error_cleanup_pwr_limit;
+ }
+
+ if (IS_ERR(pwr->gpu_cx_ipeak)) {
+ result = PTR_ERR(pwr->gpu_cx_ipeak);
+ KGSL_PWR_ERR(device,
+ "Failed to register Cx ipeak client %d\n",
+ result);
+ goto error_cleanup_pwr_limit;
+ }
+ }
return result;
+error_cleanup_pwr_limit:
+ pwr->power_flags = 0;
+
+ if (!IS_ERR_OR_NULL(pwr->sysfs_pwr_limit)) {
+ list_del(&pwr->sysfs_pwr_limit->node);
+ kfree(pwr->sysfs_pwr_limit);
+ pwr->sysfs_pwr_limit = NULL;
+ }
+ kfree(pwr->bus_ib);
error_cleanup_pcl:
_close_pcl(pwr);
error_cleanup_ocmem_pcl:
@@ -2238,6 +2305,8 @@ void kgsl_pwrctrl_close(struct kgsl_device *device)
KGSL_PWR_INFO(device, "close device %d\n", device->id);
+ cx_ipeak_unregister(pwr->gpu_cx_ipeak);
+
pwr->power_flags = 0;
if (!IS_ERR_OR_NULL(pwr->sysfs_pwr_limit)) {
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 2de42d87bcbe..42f918b80fcd 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#define __KGSL_PWRCTRL_H
#include <linux/pm_qos.h>
+#include <soc/qcom/cx_ipeak.h>
/*****************************************************************************
** power flags
@@ -153,6 +154,8 @@ struct kgsl_regulator {
* isense_clk_indx - index of isense clock, 0 if no isense
* isense_clk_on_level - isense clock rate is XO rate below this level.
* tsens_name - pointer to temperature sensor name of GPU temperature sensor
+ * gpu_cx_ipeak - pointer to cx ipeak client used by GPU
+ * gpu_cx_ipeak_clk - GPU threshold frequency to call cx ipeak driver API
*/
struct kgsl_pwrctrl {
@@ -206,6 +209,8 @@ struct kgsl_pwrctrl {
unsigned int gpu_bimc_int_clk_freq;
bool gpu_bimc_interface_enabled;
const char *tsens_name;
+ struct cx_ipeak_client *gpu_cx_ipeak;
+ unsigned int gpu_cx_ipeak_clk;
};
int kgsl_pwrctrl_init(struct kgsl_device *device);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 1caa673db6ff..7de43dd27ffe 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -156,8 +156,10 @@ static size_t snapshot_os(struct kgsl_device *device,
header->osid = KGSL_SNAPSHOT_OS_LINUX_V3;
/* Get the kernel build information */
- strlcpy(header->release, utsname()->release, sizeof(header->release));
- strlcpy(header->version, utsname()->version, sizeof(header->version));
+ strlcpy(header->release, init_utsname()->release,
+ sizeof(header->release));
+ strlcpy(header->version, init_utsname()->version,
+ sizeof(header->version));
/* Get the Unix time for the timestamp */
header->seconds = get_seconds();