summaryrefslogtreecommitdiff
path: root/drivers/mxc
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-10-09 16:47:47 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-10-09 16:47:47 +0800
commiteba86309d9ba74153b7853cd8fb97f2484679219 (patch)
tree2eca312c9a1dde28c0e376156e5cad1704de08c9 /drivers/mxc
parent58d8257e51439a6c1ac2c95441f7ec119568dd5b (diff)
parent45c27e3123e45eb27f3e5933862936e9beda38cd (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.35' into imx_3.0.35_android
Conflicts: arch/arm/configs/imx6s_updater_defconfig arch/arm/include/asm/hardware/coresight.h arch/arm/kernel/etm.c arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/mach-mx6/cpu_op-mx6.c arch/arm/mach-mx6/mx6_suspend.S arch/arm/mach-mx6/pm.c arch/arm/mach-mx6/system.c arch/arm/plat-mxc/cpufreq.c drivers/mfd/mxc-hdmi-core.c drivers/power/sabresd_battery.c drivers/video/mxc/mxc_ipuv3_fb.c drivers/video/mxc_hdmi.c include/linux/mfd/mxc-hdmi-core.h
Diffstat (limited to 'drivers/mxc')
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c21
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c9
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h3
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h1
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c12
-rw-r--r--drivers/mxc/ipu3/ipu_device.c24
-rw-r--r--drivers/mxc/thermal/cooling.c3
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c30
9 files changed, 100 insertions, 5 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index e09a46b3d7b5..36b7bcfab997 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -4282,7 +4282,7 @@ gckHARDWARE_SetFscaleValue(
gctUINT32 clock;
gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Hardware=0x%x FscaleVal=%d", Hardware, FscaleVal);
+ gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
index 8cf0509cfd92..e05a143f41c3 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
@@ -30,6 +30,9 @@
#define _GC_OBJ_ZONE gcvZONE_COMMAND
+#if gcdENABLE_FSCALE_VAL_ADJUST
+extern int thermal_hot;
+#endif
/******************************************************************************\
********************************* Support Code *********************************
\******************************************************************************/
@@ -1080,6 +1083,24 @@ gckCOMMAND_Commit(
/* Extract the gckHARDWARE and gckEVENT objects. */
hardware = Command->kernel->hardware;
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ if(hardware->core == gcvCORE_MAJOR){
+ static gctUINT orgFscale,minFscale,maxFscale;
+ static gctBOOL bAlreadyTooHot = gcvFALSE;
+ if((thermal_hot > 0) && (!bAlreadyTooHot)) {
+ gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
+ gckHARDWARE_SetFscaleValue(hardware, minFscale);
+ bAlreadyTooHot = gcvTRUE;
+ gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
+ } else if((!(thermal_hot > 0)) && bAlreadyTooHot) {
+ gckHARDWARE_SetFscaleValue(hardware, orgFscale);
+ gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
+ bAlreadyTooHot = gcvFALSE;
+ }
+
+ }
+#endif
+
/* Check wehther we need to copy the structures or not. */
gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index 890d13e17c50..eba81b64be92 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -358,6 +358,15 @@ gckGALDEVICE_Construct(
gckDebugFileSystemSetCurrentNode(device->dbgnode);
}
}
+ /*get gpu regulator*/
+ device->gpu_regulator = regulator_get(NULL, "cpu_vddgpu");
+ if (IS_ERR(device->gpu_regulator)) {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to get gpu regulator %s/%s \n",
+ __FUNCTION__, __LINE__,
+ PARENT_FILE, DEBUG_FILE);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
/*Initialize the clock structure*/
if (IrqLine != -1) {
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
index 03f7f9b2201e..c15989894600 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -89,6 +89,9 @@ typedef struct _gckGALDEVICE
struct clk *clk_2d_axi;
struct clk *clk_vg_axi;
+ /*Power management.*/
+ struct regulator *gpu_regulator;
+
}
* gckGALDEVICE;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
index 30fb13596dda..a6ed03ffc0f9 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
@@ -47,6 +47,7 @@
#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
#endif
#define NTSTRSAFE_NO_CCH_FUNCTIONS
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index 4d1a71dfa91a..4091ccdb61d4 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -6947,6 +6947,7 @@ gckOS_SetGPUPower(
struct clk *clk_vg_axi = Os->device->clk_vg_axi;
gctBOOL oldClockState = gcvFALSE;
+ gctBOOL oldPowerState = gcvFALSE;
gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
@@ -6956,15 +6957,20 @@ gckOS_SetGPUPower(
if (Core == gcvCORE_VG)
{
oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
+ oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
}
else
{
#endif
oldClockState = Os->device->kernels[Core]->hardware->clockState;
+ oldPowerState = Os->device->kernels[Core]->hardware->powerState;
#if gcdENABLE_VG
}
#endif
}
+ if((Power == gcvTRUE) && (oldPowerState == gcvFALSE) &&
+ !IS_ERR(Os->device->gpu_regulator))
+ regulator_enable(Os->device->gpu_regulator);
if (Clock == gcvTRUE) {
if (oldClockState == gcvFALSE) {
@@ -7007,8 +7013,10 @@ gckOS_SetGPUPower(
}
}
}
-
-
+ if((Power == gcvFALSE) && (oldPowerState == gcvTRUE) &&
+ !IS_ERR(Os->device->gpu_regulator))
+ regulator_disable(Os->device->gpu_regulator);
+ /* TODO: Put your code here. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index d12ffdfc7847..be1725129ce2 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -340,6 +340,7 @@ struct ipu_alloc_list {
dma_addr_t phy_addr;
void *cpu_addr;
u32 size;
+ void *file_index;
};
static LIST_HEAD(ipu_alloc_list);
@@ -350,6 +351,7 @@ static DEFINE_SPINLOCK(ipu_task_list_lock);
static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
static atomic_t req_cnt;
+static atomic_t file_index = ATOMIC_INIT(1);
static int major;
static int max_ipu_no;
static int thread_id;
@@ -3274,6 +3276,7 @@ EXPORT_SYMBOL_GPL(ipu_queue_task);
static int mxc_ipu_open(struct inode *inode, struct file *file)
{
+ file->private_data = (void *)atomic_inc_return(&file_index);
return 0;
}
@@ -3330,6 +3333,7 @@ static long mxc_ipu_ioctl(struct file *file,
kfree(mem);
return -ENOMEM;
}
+ mem->file_index = file->private_data;
mutex_lock(&ipu_alloc_lock);
list_add(&mem->list, &ipu_alloc_list);
mutex_unlock(&ipu_alloc_lock);
@@ -3413,6 +3417,26 @@ static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
static int mxc_ipu_release(struct inode *inode, struct file *file)
{
+ struct ipu_alloc_list *mem;
+ struct ipu_alloc_list *n;
+
+ mutex_lock(&ipu_alloc_lock);
+ list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
+ if ((mem->cpu_addr != 0) &&
+ (file->private_data == mem->file_index)) {
+ list_del(&mem->list);
+ dma_free_coherent(ipu_dev,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+ kfree(mem);
+ }
+ }
+ mutex_unlock(&ipu_alloc_lock);
+ atomic_dec(&file_index);
+
return 0;
}
diff --git a/drivers/mxc/thermal/cooling.c b/drivers/mxc/thermal/cooling.c
index 0feefeaa6008..7019d9949c8a 100644
--- a/drivers/mxc/thermal/cooling.c
+++ b/drivers/mxc/thermal/cooling.c
@@ -57,6 +57,7 @@ cpufreq, it minor 1, and when we promote cpufreq, it add 1, so
if it is 0, mean we didn't change the cpufreq */
static int cpufreq_change_count;
+extern int thermal_hot;
int anatop_thermal_get_cpufreq_cur(void)
{
int ret = -EINVAL;
@@ -237,6 +238,7 @@ imx_processor_set_cur_state(struct thermal_cooling_device *cdev,
secondary CPUs that detached by thermal driver */
if (cooling_cpuhotplug) {
if (!state) {
+ thermal_hot = 0;
for (i = 1; i < 4; i++) {
if (cpu_mask && (0x1 << i)) {
anatop_thermal_cpu_hotplug(true);
@@ -247,6 +249,7 @@ imx_processor_set_cur_state(struct thermal_cooling_device *cdev,
}
} else {
if (!state) {
+ thermal_hot = 0;
if (cpufreq_change_count < 0)
anatop_thermal_cpufreq_up();
else if (cpufreq_change_count > 0)
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 92a1d0dc98c7..8178824ab80a 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -39,6 +39,7 @@
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
+#include <linux/regulator/consumer.h>
#include <linux/page-flags.h>
#include <linux/mm_types.h>
#include <linux/types.h>
@@ -110,6 +111,7 @@ static int vpu_jpu_irq;
#endif
static unsigned int regBk[64];
+static struct regulator *vpu_regulator;
#define READ_REG(x) __raw_readl(vpu_base + x)
#define WRITE_REG(val, x) __raw_writel(val, vpu_base + x)
@@ -245,8 +247,12 @@ bool vpu_is_valid_phy_memory(u32 paddr)
*/
static int vpu_open(struct inode *inode, struct file *filp)
{
+
mutex_lock(&vpu_data.lock);
- open_count++;
+
+ if (open_count++ == 0 && !IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
+
filp->private_data = (void *)(&vpu_data);
mutex_unlock(&vpu_data.lock);
return 0;
@@ -531,6 +537,9 @@ static int vpu_release(struct inode *inode, struct file *filp)
mutex_lock(&vpu_data.lock);
if (open_count > 0 && !(--open_count)) {
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
+
vpu_free_buffers();
/* Free shared memory when vpu device is idle */
@@ -705,6 +714,12 @@ static int vpu_dev_probe(struct platform_device *pdev)
(void *)(&vpu_data));
if (err)
goto err_out_class;
+ vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
+ if (IS_ERR(vpu_regulator)) {
+ printk(KERN_ERR
+ "%s: failed to get vpu regulator\n", __func__);
+ goto err_out_class;
+ }
#ifdef MXC_VPU_HAS_JPU
vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
@@ -752,7 +767,8 @@ static int vpu_dev_remove(struct platform_device *pdev)
iounmap(vpu_base);
if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
iram_free(iram.start, vpu_plat->iram_size);
-
+ if (!IS_ERR(vpu_regulator))
+ regulator_put(vpu_regulator);
return 0;
}
@@ -762,6 +778,8 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
int i;
unsigned long timeout;
+ if (!IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
/* Wait for vpu go to idle state, suspect vpu cannot be changed
to idle state after about 1 sec */
if (open_count > 0) {
@@ -794,10 +812,14 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
if (vpu_plat->pg)
vpu_plat->pg(1);
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return 0;
out:
clk_disable(vpu_clk);
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return -EAGAIN;
}
@@ -809,6 +831,8 @@ static int vpu_resume(struct platform_device *pdev)
if (cpu_is_mx53())
goto recover_clk;
+ if (!IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
if (vpu_plat->pg)
vpu_plat->pg(0);
@@ -869,6 +893,8 @@ recover_clk:
/* Recover vpu clock */
for (i = 0; i < vpu_clk_usercount; i++)
clk_enable(vpu_clk);
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return 0;
}