mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
Merge "msm: kgsl: Set up the adreno device at runtime"
This commit is contained in:
commit
a0aff6fc73
10 changed files with 175 additions and 197 deletions
|
|
@ -32,43 +32,7 @@ static void adreno_input_work(struct work_struct *work);
|
|||
static unsigned int counter_delta(struct kgsl_device *device,
|
||||
unsigned int reg, unsigned int *counter);
|
||||
|
||||
static struct devfreq_msm_adreno_tz_data adreno_tz_data = {
|
||||
.bus = {
|
||||
.max = 350,
|
||||
.floating = true,
|
||||
},
|
||||
.device_id = 0,
|
||||
};
|
||||
|
||||
static const struct kgsl_functable adreno_functable;
|
||||
|
||||
static struct adreno_device device_3d0 = {
|
||||
.dev = {
|
||||
KGSL_DEVICE_COMMON_INIT(device_3d0.dev),
|
||||
.pwrscale = KGSL_PWRSCALE_INIT(&adreno_tz_data),
|
||||
.name = DEVICE_3D0_NAME,
|
||||
.id = 0,
|
||||
.iomemname = "kgsl_3d0_reg_memory",
|
||||
.ftbl = &adreno_functable,
|
||||
},
|
||||
.ft_policy = KGSL_FT_DEFAULT_POLICY,
|
||||
.ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY,
|
||||
.long_ib_detect = 1,
|
||||
.input_work = __WORK_INITIALIZER(device_3d0.input_work,
|
||||
adreno_input_work),
|
||||
.pwrctrl_flag = BIT(ADRENO_SPTP_PC_CTRL) |
|
||||
BIT(ADRENO_THROTTLING_CTRL) | BIT(ADRENO_HWCG_CTRL),
|
||||
.profile.enabled = false,
|
||||
.active_list = LIST_HEAD_INIT(device_3d0.active_list),
|
||||
.active_list_lock = __SPIN_LOCK_UNLOCKED(device_3d0.active_list_lock),
|
||||
.gpu_llc_slice_enable = true,
|
||||
.gpuhtw_llc_slice_enable = true,
|
||||
.preempt = {
|
||||
.preempt_level = 1,
|
||||
.skipsaverestore = 1,
|
||||
.usesgmem = 1,
|
||||
},
|
||||
};
|
||||
static struct adreno_device device_3d0;
|
||||
|
||||
/* Ptr to array for the current set of fault detect registers */
|
||||
unsigned int *adreno_ft_regs;
|
||||
|
|
@ -858,7 +822,7 @@ static int adreno_identify_gpu(struct adreno_device *adreno_dev)
|
|||
}
|
||||
|
||||
static const struct platform_device_id adreno_id_table[] = {
|
||||
{ DEVICE_3D0_NAME, (unsigned long) &device_3d0, },
|
||||
{ "kgsl-3d0", (unsigned long) &device_3d0, },
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
@ -1140,7 +1104,8 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
|
|||
|
||||
/* Get starting physical address of device registers */
|
||||
res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
|
||||
device->iomemname);
|
||||
"kgsl_3d0_reg_memory");
|
||||
|
||||
if (res == NULL) {
|
||||
dev_err(device->dev,
|
||||
"platform_get_resource_byname failed\n");
|
||||
|
|
@ -1356,6 +1321,47 @@ static int adreno_probe_efuse(struct platform_device *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct kgsl_functable adreno_functable;
|
||||
|
||||
static void adreno_setup_device(struct adreno_device *adreno_dev)
|
||||
{
|
||||
memset(adreno_dev, 0, sizeof(*adreno_dev));
|
||||
|
||||
adreno_dev->dev.name = "kgsl-3d0";
|
||||
adreno_dev->dev.ftbl = &adreno_functable;
|
||||
|
||||
init_completion(&adreno_dev->dev.hwaccess_gate);
|
||||
init_completion(&adreno_dev->dev.halt_gate);
|
||||
|
||||
idr_init(&adreno_dev->dev.context_idr);
|
||||
|
||||
mutex_init(&adreno_dev->dev.mutex);
|
||||
INIT_LIST_HEAD(&adreno_dev->dev.globals);
|
||||
|
||||
/* Set the fault tolerance policy to replay, skip, throttle */
|
||||
adreno_dev->ft_policy = BIT(KGSL_FT_REPLAY) |
|
||||
BIT(KGSL_FT_SKIPCMD) | BIT(KGSL_FT_THROTTLE);
|
||||
|
||||
/* Enable command timeouts by default */
|
||||
adreno_dev->long_ib_detect = true;
|
||||
|
||||
INIT_WORK(&adreno_dev->input_work, adreno_input_work);
|
||||
|
||||
/*
|
||||
* Enable SPTP power collapse, throttling and hardware clock gating by
|
||||
* default where applicable
|
||||
*/
|
||||
adreno_dev->pwrctrl_flag = BIT(ADRENO_SPTP_PC_CTRL) |
|
||||
BIT(ADRENO_THROTTLING_CTRL) | BIT(ADRENO_HWCG_CTRL);
|
||||
|
||||
INIT_LIST_HEAD(&adreno_dev->active_list);
|
||||
spin_lock_init(&adreno_dev->active_list_lock);
|
||||
|
||||
/* Enable use of the LLC slices where applicable */
|
||||
adreno_dev->gpu_llc_slice_enable = true;
|
||||
adreno_dev->gpuhtw_llc_slice_enable = true;
|
||||
}
|
||||
|
||||
static int adreno_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id;
|
||||
|
|
@ -1370,6 +1376,10 @@ static int adreno_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
|
||||
adreno_dev = (struct adreno_device *) of_id->data;
|
||||
|
||||
/* Initialize the adreno device structure */
|
||||
adreno_setup_device(adreno_dev);
|
||||
|
||||
device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
device->pdev = pdev;
|
||||
|
|
@ -3750,35 +3760,6 @@ static struct platform_driver adreno_platform_driver = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct of_device_id busmon_match_table[] = {
|
||||
{ .compatible = "qcom,kgsl-busmon", .data = &device_3d0 },
|
||||
{}
|
||||
};
|
||||
|
||||
static int adreno_busmon_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct kgsl_device *device;
|
||||
const struct of_device_id *pdid =
|
||||
of_match_device(busmon_match_table, &pdev->dev);
|
||||
|
||||
if (pdid == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
device = (struct kgsl_device *)pdid->data;
|
||||
device->busmondev = &pdev->dev;
|
||||
dev_set_drvdata(device->busmondev, device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver kgsl_bus_platform_driver = {
|
||||
.probe = adreno_busmon_probe,
|
||||
.driver = {
|
||||
.name = "kgsl-busmon",
|
||||
.of_match_table = busmon_match_table,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init kgsl_3d_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -3787,17 +3768,9 @@ static int __init kgsl_3d_init(void)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = platform_driver_register(&kgsl_bus_platform_driver);
|
||||
if (ret) {
|
||||
kgsl_core_exit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&adreno_platform_driver);
|
||||
if (ret) {
|
||||
platform_driver_unregister(&kgsl_bus_platform_driver);
|
||||
if (ret)
|
||||
kgsl_core_exit();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -3805,8 +3778,6 @@ static int __init kgsl_3d_init(void)
|
|||
static void __exit kgsl_3d_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&adreno_platform_driver);
|
||||
platform_driver_unregister(&kgsl_bus_platform_driver);
|
||||
|
||||
kgsl_core_exit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
#include "adreno_ringbuffer.h"
|
||||
#include "kgsl_sharedmem.h"
|
||||
|
||||
#define DEVICE_3D0_NAME "kgsl-3d0"
|
||||
|
||||
/* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */
|
||||
#define ADRENO_DEVICE(device) \
|
||||
container_of(device, struct adreno_device, dev)
|
||||
|
|
@ -476,7 +474,7 @@ struct adreno_device {
|
|||
struct adreno_ringbuffer *prev_rb;
|
||||
unsigned int fast_hang_detect;
|
||||
unsigned long ft_policy;
|
||||
unsigned int long_ib_detect;
|
||||
bool long_ib_detect;
|
||||
unsigned long ft_pf_policy;
|
||||
bool cooperative_reset;
|
||||
struct adreno_profile profile;
|
||||
|
|
@ -839,13 +837,13 @@ struct adreno_gpudev {
|
|||
*/
|
||||
enum kgsl_ft_policy_bits {
|
||||
KGSL_FT_OFF = 0,
|
||||
KGSL_FT_REPLAY = 1,
|
||||
KGSL_FT_SKIPIB = 2,
|
||||
KGSL_FT_SKIPFRAME = 3,
|
||||
KGSL_FT_DISABLE = 4,
|
||||
KGSL_FT_TEMP_DISABLE = 5,
|
||||
KGSL_FT_THROTTLE = 6,
|
||||
KGSL_FT_SKIPCMD = 7,
|
||||
KGSL_FT_REPLAY,
|
||||
KGSL_FT_SKIPIB,
|
||||
KGSL_FT_SKIPFRAME,
|
||||
KGSL_FT_DISABLE,
|
||||
KGSL_FT_TEMP_DISABLE,
|
||||
KGSL_FT_THROTTLE,
|
||||
KGSL_FT_SKIPCMD,
|
||||
/* KGSL_FT_MAX_BITS is used to calculate the mask */
|
||||
KGSL_FT_MAX_BITS,
|
||||
/* Internal bits - set during GFT */
|
||||
|
|
@ -855,11 +853,6 @@ enum kgsl_ft_policy_bits {
|
|||
|
||||
#define KGSL_FT_POLICY_MASK GENMASK(KGSL_FT_MAX_BITS - 1, 0)
|
||||
|
||||
#define KGSL_FT_DEFAULT_POLICY \
|
||||
(BIT(KGSL_FT_REPLAY) | \
|
||||
BIT(KGSL_FT_SKIPCMD) | \
|
||||
BIT(KGSL_FT_THROTTLE))
|
||||
|
||||
/**
|
||||
* enum kgsl_ft_pagefault_policy_bits - KGSL pagefault policy bits
|
||||
* @KGSL_FT_PAGEFAULT_INT_ENABLE: No longer used, but retained for compatibility
|
||||
|
|
|
|||
|
|
@ -2205,6 +2205,10 @@ static void a6xx_platform_setup(struct adreno_device *adreno_dev)
|
|||
{
|
||||
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
|
||||
adreno_dev->preempt.preempt_level = 1;
|
||||
adreno_dev->preempt.skipsaverestore = true;
|
||||
adreno_dev->preempt.usesgmem = true;
|
||||
|
||||
if (adreno_has_gbif(adreno_dev)) {
|
||||
a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].regs =
|
||||
a6xx_perfcounters_gbif;
|
||||
|
|
|
|||
|
|
@ -210,10 +210,6 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
|
|||
unsigned long flags;
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
cntl = (((preempt->preempt_level << 6) & 0xC0) |
|
||||
((preempt->skipsaverestore << 9) & 0x200) |
|
||||
((preempt->usesgmem << 8) & 0x100) | 0x1);
|
||||
|
||||
/* Put ourselves into a possible trigger state */
|
||||
if (!adreno_move_preempt_state(adreno_dev,
|
||||
ADRENO_PREEMPT_NONE, ADRENO_PREEMPT_START))
|
||||
|
|
@ -352,6 +348,16 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
|
|||
mod_timer(&adreno_dev->preempt.timer,
|
||||
jiffies + msecs_to_jiffies(ADRENO_PREEMPT_TIMEOUT));
|
||||
|
||||
cntl = (preempt->preempt_level << 6) | 0x01;
|
||||
|
||||
/* Skip save/restore during L1 preemption */
|
||||
if (preempt->skipsaverestore)
|
||||
cntl |= (1 << 9);
|
||||
|
||||
/* Enable GMEM save/restore across preemption */
|
||||
if (preempt->usesgmem)
|
||||
cntl |= (1 << 8);
|
||||
|
||||
trace_adreno_preempt_trigger(adreno_dev->cur_rb, adreno_dev->next_rb,
|
||||
cntl);
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
|||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->usesgmem = val ? 1 : 0;
|
||||
preempt->usesgmem = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
|||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->skipsaverestore = val ? 1 : 0;
|
||||
preempt->skipsaverestore = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ static bool _gpuhtw_llc_slice_enable_show(struct adreno_device *adreno_dev)
|
|||
|
||||
static int _ft_long_ib_detect_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
adreno_dev->long_ib_detect = val;
|
||||
adreno_dev->long_ib_detect = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -263,7 +263,6 @@ struct kgsl_device {
|
|||
|
||||
atomic_t active_cnt;
|
||||
|
||||
wait_queue_head_t wait_queue;
|
||||
wait_queue_head_t active_cnt_wq;
|
||||
struct platform_device *pdev;
|
||||
struct dentry *d_debugfs;
|
||||
|
|
@ -297,8 +296,6 @@ struct kgsl_device {
|
|||
int reset_counter; /* Track how many GPU core resets have occurred */
|
||||
struct workqueue_struct *events_wq;
|
||||
|
||||
struct device *busmondev; /* pseudo dev for GPU BW voting governor */
|
||||
|
||||
/* Number of active contexts seen globally for this device */
|
||||
int active_context_count;
|
||||
struct kobject *gpu_sysfs_kobj;
|
||||
|
|
@ -322,19 +319,6 @@ struct kgsl_device {
|
|||
#define KGSL_MMU_DEVICE(_mmu) \
|
||||
container_of((_mmu), struct kgsl_device, mmu)
|
||||
|
||||
#define KGSL_DEVICE_COMMON_INIT(_dev) \
|
||||
.hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
|
||||
.halt_gate = COMPLETION_INITIALIZER((_dev).halt_gate),\
|
||||
.idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
|
||||
kgsl_idle_check),\
|
||||
.context_idr = IDR_INIT((_dev).context_idr),\
|
||||
.wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
|
||||
.active_cnt_wq = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).active_cnt_wq),\
|
||||
.mutex = __MUTEX_INITIALIZER((_dev).mutex),\
|
||||
.state = KGSL_STATE_NONE, \
|
||||
.globals = LIST_HEAD_INIT((_dev).globals)
|
||||
|
||||
|
||||
/**
|
||||
* enum bits for struct kgsl_context.priv
|
||||
* @KGSL_CONTEXT_PRIV_SUBMITTED - The context has submitted commands to gpu.
|
||||
|
|
|
|||
|
|
@ -1643,6 +1643,8 @@ static u32 *kgsl_bus_get_table(struct platform_device *pdev, int *count)
|
|||
return levels;
|
||||
}
|
||||
|
||||
static void kgsl_idle_check(struct work_struct *work);
|
||||
|
||||
int kgsl_pwrctrl_init(struct kgsl_device *device)
|
||||
{
|
||||
int i, result, freq, levels_count;
|
||||
|
|
@ -1679,6 +1681,9 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
|
||||
init_waitqueue_head(&device->active_cnt_wq);
|
||||
|
||||
/* Initialize the user and thermal clock constraints */
|
||||
|
||||
pwr->max_pwrlevel = 0;
|
||||
|
|
@ -1786,15 +1791,12 @@ void kgsl_pwrctrl_close(struct kgsl_device *device)
|
|||
pm_runtime_disable(&device->pdev->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* kgsl_idle_check() - Work function for GPU interrupts and idle timeouts.
|
||||
* @device: The device
|
||||
*
|
||||
/*
|
||||
* This function is called for work that is queued by the interrupt
|
||||
* handler or the idle timer. It attempts to transition to a clocks
|
||||
* off state if the active_cnt is 0 and the hardware is idle.
|
||||
*/
|
||||
void kgsl_idle_check(struct work_struct *work)
|
||||
static void kgsl_idle_check(struct work_struct *work)
|
||||
{
|
||||
struct kgsl_device *device = container_of(work, struct kgsl_device,
|
||||
idle_check_ws);
|
||||
|
|
|
|||
|
|
@ -158,7 +158,6 @@ struct kgsl_pwrctrl {
|
|||
int kgsl_pwrctrl_init(struct kgsl_device *device);
|
||||
void kgsl_pwrctrl_close(struct kgsl_device *device);
|
||||
void kgsl_timer(struct timer_list *t);
|
||||
void kgsl_idle_check(struct work_struct *work);
|
||||
void kgsl_pre_hwaccess(struct kgsl_device *device);
|
||||
void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
|
||||
unsigned int level);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@
|
|||
#include "kgsl_pwrscale.h"
|
||||
#include "kgsl_trace.h"
|
||||
|
||||
static struct devfreq_msm_adreno_tz_data adreno_tz_data = {
|
||||
.bus = {
|
||||
.max = 350,
|
||||
.floating = true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kgsl_midframe_info - midframe power stats sampling info
|
||||
* @timer - midframe sampling timer
|
||||
|
|
@ -654,22 +661,74 @@ static int opp_notify(struct notifier_block *nb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void pwrscale_busmon_create(struct kgsl_device *device,
|
||||
struct platform_device *pdev, unsigned long *table)
|
||||
{
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
struct kgsl_pwrscale *pwrscale = &device->pwrscale;
|
||||
struct device *dev = &pwrscale->busmondev;
|
||||
struct msm_busmon_extended_profile *bus_profile;
|
||||
struct devfreq *bus_devfreq;
|
||||
int i;
|
||||
|
||||
bus_profile = &pwrscale->bus_profile;
|
||||
bus_profile->private_data = &adreno_tz_data;
|
||||
|
||||
bus_profile->profile.target = kgsl_busmon_target;
|
||||
bus_profile->profile.get_dev_status = kgsl_busmon_get_dev_status;
|
||||
bus_profile->profile.get_cur_freq = kgsl_busmon_get_cur_freq;
|
||||
|
||||
bus_profile->profile.max_state = pwr->num_pwrlevels - 1;
|
||||
bus_profile->profile.freq_table = table;
|
||||
|
||||
dev->parent = &pdev->dev;
|
||||
|
||||
dev_set_name(dev, "kgsl-busmon");
|
||||
if (device_register(dev))
|
||||
return;
|
||||
|
||||
/* Build out the OPP table for the busmon device */
|
||||
for (i = 0; i < pwr->num_pwrlevels; i++) {
|
||||
if (!pwr->pwrlevels[i].gpu_freq)
|
||||
continue;
|
||||
|
||||
dev_pm_opp_add(dev, pwr->pwrlevels[i].gpu_freq, 0);
|
||||
}
|
||||
|
||||
bus_devfreq = devfreq_add_device(dev, &pwrscale->bus_profile.profile,
|
||||
"gpubw_mon", NULL);
|
||||
|
||||
if (IS_ERR_OR_NULL(bus_devfreq)) {
|
||||
dev_err(&pdev->dev, "Bus scaling not enabled\n");
|
||||
put_device(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
pwrscale->gpu_profile.bus_devfreq = bus_devfreq;
|
||||
}
|
||||
|
||||
int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
|
||||
const char *governor)
|
||||
{
|
||||
struct kgsl_pwrscale *pwrscale;
|
||||
struct kgsl_pwrctrl *pwr;
|
||||
struct kgsl_pwrscale *pwrscale = &device->pwrscale;
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
struct devfreq *devfreq;
|
||||
struct devfreq *bus_devfreq = NULL;
|
||||
struct msm_adreno_extended_profile *gpu_profile;
|
||||
struct devfreq_dev_profile *profile;
|
||||
struct devfreq_msm_adreno_tz_data *data;
|
||||
int i, ret;
|
||||
|
||||
pwrscale = &device->pwrscale;
|
||||
pwr = &device->pwrctrl;
|
||||
pwrscale->enabled = true;
|
||||
|
||||
gpu_profile = &pwrscale->gpu_profile;
|
||||
profile = &pwrscale->gpu_profile.profile;
|
||||
gpu_profile->private_data = &adreno_tz_data;
|
||||
|
||||
gpu_profile->profile.target = kgsl_devfreq_target;
|
||||
gpu_profile->profile.get_dev_status = kgsl_devfreq_get_dev_status;
|
||||
gpu_profile->profile.get_cur_freq = kgsl_devfreq_get_cur_freq;
|
||||
|
||||
gpu_profile->profile.initial_freq =
|
||||
pwr->pwrlevels[pwr->default_pwrlevel].gpu_freq;
|
||||
|
||||
gpu_profile->profile.polling_ms = 10;
|
||||
|
||||
pwr->nb.notifier_call = opp_notify;
|
||||
|
||||
|
|
@ -677,39 +736,33 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
|
|||
|
||||
srcu_init_notifier_head(&pwrscale->nh);
|
||||
|
||||
profile->initial_freq =
|
||||
pwr->pwrlevels[pwr->default_pwrlevel].gpu_freq;
|
||||
/* Let's start with 10 ms and tune in later */
|
||||
profile->polling_ms = 10;
|
||||
|
||||
/* do not include the 'off' level or duplicate freq. levels */
|
||||
for (i = 0; i < (pwr->num_pwrlevels - 1); i++)
|
||||
pwrscale->freq_table[out++] = pwr->pwrlevels[i].gpu_freq;
|
||||
pwrscale->freq_table[i] = pwr->pwrlevels[i].gpu_freq;
|
||||
|
||||
/*
|
||||
* Max_state is the number of valid power levels.
|
||||
* The valid power levels range from 0 - (max_state - 1)
|
||||
*/
|
||||
profile->max_state = pwr->num_pwrlevels - 1;
|
||||
gpu_profile->profile.max_state = pwr->num_pwrlevels - 1;
|
||||
/* link storage array to the devfreq profile pointer */
|
||||
profile->freq_table = pwrscale->freq_table;
|
||||
gpu_profile->profile.freq_table = pwrscale->freq_table;
|
||||
|
||||
/* if there is only 1 freq, no point in running a governor */
|
||||
if (profile->max_state == 1)
|
||||
if (gpu_profile->profile.max_state == 1)
|
||||
governor = "performance";
|
||||
|
||||
/* initialize msm-adreno-tz governor specific data here */
|
||||
data = gpu_profile->private_data;
|
||||
|
||||
data->disable_busy_time_burst =
|
||||
adreno_tz_data.disable_busy_time_burst =
|
||||
of_property_read_bool(pdev->dev.of_node,
|
||||
"qcom,disable-busy-time-burst");
|
||||
|
||||
if (pwrscale->ctxt_aware_enable) {
|
||||
data->ctxt_aware_enable = pwrscale->ctxt_aware_enable;
|
||||
data->bin.ctxt_aware_target_pwrlevel =
|
||||
adreno_tz_data.ctxt_aware_enable = pwrscale->ctxt_aware_enable;
|
||||
adreno_tz_data.bin.ctxt_aware_target_pwrlevel =
|
||||
pwrscale->ctxt_aware_target_pwrlevel;
|
||||
data->bin.ctxt_aware_busy_penalty =
|
||||
adreno_tz_data.bin.ctxt_aware_busy_penalty =
|
||||
pwrscale->ctxt_aware_busy_penalty;
|
||||
}
|
||||
|
||||
|
|
@ -734,18 +787,17 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
|
|||
* the bus bandwidth vote.
|
||||
*/
|
||||
if (pwr->bus_control) {
|
||||
data->bus.num = pwr->bus_ibs_count;
|
||||
data->bus.ib_mbps = pwr->bus_ibs;
|
||||
data->bus.width = pwr->bus_width;
|
||||
adreno_tz_data.bus.num = pwr->bus_ibs_count;
|
||||
adreno_tz_data.bus.ib_mbps = pwr->bus_ibs;
|
||||
adreno_tz_data.bus.width = pwr->bus_width;
|
||||
|
||||
if (!kgsl_of_property_read_ddrtype(device->pdev->dev.of_node,
|
||||
"qcom,bus-accesses", &data->bus.max))
|
||||
data->bus.floating = false;
|
||||
} else
|
||||
data->bus.num = 0;
|
||||
"qcom,bus-accesses", &adreno_tz_data.bus.max))
|
||||
adreno_tz_data.bus.floating = false;
|
||||
}
|
||||
|
||||
devfreq = devfreq_add_device(&pdev->dev, &pwrscale->gpu_profile.profile,
|
||||
governor, pwrscale->gpu_profile.private_data);
|
||||
devfreq = devfreq_add_device(&pdev->dev, &gpu_profile->profile,
|
||||
governor, &adreno_tz_data);
|
||||
if (IS_ERR(devfreq)) {
|
||||
device->pwrscale.enabled = false;
|
||||
return PTR_ERR(devfreq);
|
||||
|
|
@ -758,34 +810,9 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
|
|||
pwrscale->cooling_dev = NULL;
|
||||
|
||||
pwrscale->gpu_profile.bus_devfreq = NULL;
|
||||
if (data->bus.num) {
|
||||
pwrscale->bus_profile.profile.max_state
|
||||
= pwr->num_pwrlevels - 1;
|
||||
pwrscale->bus_profile.profile.freq_table
|
||||
= pwrscale->freq_table;
|
||||
|
||||
/*
|
||||
* This is needed because devfreq expects the device
|
||||
* to have an opp table handle to calculate the min/max
|
||||
* frequency.
|
||||
*/
|
||||
ret = dev_pm_opp_of_add_table(device->busmondev);
|
||||
/*
|
||||
* Disable OPP which are not supported as per GPU freq plan.
|
||||
* This is need to ensure freq_table specified in bus_profile
|
||||
* above matches OPP table.
|
||||
*/
|
||||
kgsl_pwrctrl_disable_unused_opp(device, device->busmondev);
|
||||
if (!ret)
|
||||
bus_devfreq = devfreq_add_device(device->busmondev,
|
||||
&pwrscale->bus_profile.profile, "gpubw_mon",
|
||||
NULL);
|
||||
|
||||
if (IS_ERR_OR_NULL(bus_devfreq))
|
||||
dev_err(device->dev, "Bus scaling not enabled\n");
|
||||
else
|
||||
pwrscale->gpu_profile.bus_devfreq = bus_devfreq;
|
||||
}
|
||||
if (adreno_tz_data.bus.num)
|
||||
pwrscale_busmon_create(device, pdev, pwrscale->freq_table);
|
||||
|
||||
ret = sysfs_create_link(&device->dev->kobj,
|
||||
&devfreq->dev.kobj, "devfreq");
|
||||
|
|
@ -825,6 +852,12 @@ void kgsl_pwrscale_close(struct kgsl_device *device)
|
|||
|
||||
pwr = &device->pwrctrl;
|
||||
pwrscale = &device->pwrscale;
|
||||
|
||||
if (pwrscale->gpu_profile.bus_devfreq) {
|
||||
devfreq_remove_device(pwrscale->gpu_profile.bus_devfreq);
|
||||
put_device(&pwrscale->busmondev);
|
||||
}
|
||||
|
||||
if (!pwrscale->devfreqptr)
|
||||
return;
|
||||
if (pwrscale->cooling_dev)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ struct kgsl_pwrscale {
|
|||
bool ctxt_aware_enable;
|
||||
unsigned int ctxt_aware_target_pwrlevel;
|
||||
unsigned int ctxt_aware_busy_penalty;
|
||||
/** @busmondev: A child device for the busmon governor */
|
||||
struct device busmondev;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -99,20 +101,4 @@ int kgsl_busmon_get_dev_status(struct device *dev,
|
|||
struct devfreq_dev_status *stat);
|
||||
int kgsl_busmon_get_cur_freq(struct device *dev, unsigned long *freq);
|
||||
|
||||
#define KGSL_PWRSCALE_INIT(_priv_data) { \
|
||||
.enabled = true, \
|
||||
.gpu_profile = { \
|
||||
.private_data = _priv_data, \
|
||||
.profile = { \
|
||||
.target = kgsl_devfreq_target, \
|
||||
.get_dev_status = kgsl_devfreq_get_dev_status, \
|
||||
.get_cur_freq = kgsl_devfreq_get_cur_freq, \
|
||||
} }, \
|
||||
.bus_profile = { \
|
||||
.private_data = _priv_data, \
|
||||
.profile = { \
|
||||
.target = kgsl_busmon_target, \
|
||||
.get_dev_status = kgsl_busmon_get_dev_status, \
|
||||
.get_cur_freq = kgsl_busmon_get_cur_freq, \
|
||||
} } }
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue