summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/ipu_dev.c14
-rw-r--r--arch/arm/mach-omap2/ipu_drv.c33
-rw-r--r--drivers/dsp/syslink/devh/44xx/devh44xx.c3
-rw-r--r--drivers/dsp/syslink/ipu_pm/ipu_pm.c2843
-rw-r--r--drivers/dsp/syslink/ipu_pm/ipu_pm.h48
5 files changed, 1052 insertions, 1889 deletions
diff --git a/arch/arm/mach-omap2/ipu_dev.c b/arch/arm/mach-omap2/ipu_dev.c
index 8d3386f1f86..a24ca10d367 100644
--- a/arch/arm/mach-omap2/ipu_dev.c
+++ b/arch/arm/mach-omap2/ipu_dev.c
@@ -41,14 +41,14 @@ static char *hwmod_state_strings[] = {
"_HWMOD_STATE_IDLE",
"_HWMOD_STATE_DISABLED",
};
-static void print_hwmod_state(struct omap_hwmod *oh)
+static void print_hwmod_state(struct omap_hwmod *oh, char *desc)
{
u32 _state = (u32) oh->_state;
- pr_info("HWMOD name = %s\n", oh->name);
+ pr_debug("HWMOD name = %s\n", oh->name);
if (_state > _HWMOD_STATE_LAST)
WARN(1, "Illegal hwmod _state = %d\n", _state);
else
- pr_info("state = %s\n", hwmod_state_strings[_state]);
+ pr_debug("%s state = %s\n", desc, hwmod_state_strings[_state]);
}
inline int ipu_pm_module_start(unsigned rsrc)
@@ -58,11 +58,11 @@ inline int ipu_pm_module_start(unsigned rsrc)
pd = ipupm_get_plat_data();
- print_hwmod_state(pd[rsrc].oh);
+ print_hwmod_state(pd[rsrc].oh, "Previous");
ret = omap_device_enable(pd[rsrc].pdev);
if (ret)
pr_err("device enable failed %s", pd[rsrc].oh_name);
-
+ print_hwmod_state(pd[rsrc].oh, "New");
return ret;
}
EXPORT_SYMBOL(ipu_pm_module_start);
@@ -74,8 +74,10 @@ inline int ipu_pm_module_stop(unsigned rsrc)
pd = ipupm_get_plat_data();
- print_hwmod_state(pd[rsrc].oh);
+ print_hwmod_state(pd[rsrc].oh, "Previous");
ret = omap_device_shutdown(pd[rsrc].pdev);
+ print_hwmod_state(pd[rsrc].oh, "New");
+
if (ret)
pr_err("device disable failed %s", pd[rsrc].oh_name);
diff --git a/arch/arm/mach-omap2/ipu_drv.c b/arch/arm/mach-omap2/ipu_drv.c
index 88a78ba7be2..d4107588035 100644
--- a/arch/arm/mach-omap2/ipu_drv.c
+++ b/arch/arm/mach-omap2/ipu_drv.c
@@ -201,9 +201,6 @@ static int ipu_pm_drv_suspend(struct device *dev)
* BIOS timers could be saved locally or on Ducati
*/
- /* call our notification function */
- retval = ipu_pm_notifications(PM_SUSPEND, NULL);
-
/* FIXME: Currently sending SUSPEND is enough to send
* Ducati to hibernate, save ctx can be called at this
* point to save ctx and reset remote procs
@@ -211,14 +208,25 @@ static int ipu_pm_drv_suspend(struct device *dev)
* which ever proc_id, maybe this will change when
* Tesla support is added.
*/
- /* sysm3 is handling hibernation of ducati currently */
- ipu_pm_save_ctx(SYS_M3);
+ /* call notification function */
+ if (ipu_pm_get_handle(APP_M3)) {
+ retval = ipu_pm_notifications(APP_M3, PM_SUSPEND, NULL);
+ if (retval)
+ goto error;
+ }
+ if (ipu_pm_get_handle(SYS_M3)) {
+ retval = ipu_pm_notifications(SYS_M3, PM_SUSPEND, NULL);
+ if (retval)
+ goto error;
+ /* sysm3 is handling hibernation of ducati currently */
+ ipu_pm_save_ctx(SYS_M3);
+ }
/* return result, should be zero if all Ducati clients
* returned zero else fail code
*/
}
-
+error:
return retval;
}
@@ -234,13 +242,22 @@ static int ipu_pm_drv_resume(struct device *dev)
*/
/* call our notification function */
- retval = ipu_pm_notifications(PM_RESUME, NULL);
+ if (ipu_pm_get_handle(APP_M3)) {
+ retval = ipu_pm_notifications(APP_M3, PM_RESUME, NULL);
+ if (retval)
+ goto error;
+ }
+ if (ipu_pm_get_handle(SYS_M3)) {
+ retval = ipu_pm_notifications(SYS_M3, PM_RESUME, NULL);
+ if (retval)
+ goto error;
+ }
/* return result, should be zero if all Ducati clients
* returned zero else fail code
*/
}
-
+error:
return retval;
}
diff --git a/drivers/dsp/syslink/devh/44xx/devh44xx.c b/drivers/dsp/syslink/devh/44xx/devh44xx.c
index f76f8922c8b..2aa7425ac78 100644
--- a/drivers/dsp/syslink/devh/44xx/devh44xx.c
+++ b/drivers/dsp/syslink/devh/44xx/devh44xx.c
@@ -122,7 +122,8 @@ static int devh44xx_notifier_call(struct notifier_block *nb,
err = mutex_lock_interruptible(&local_gate);
if (err)
goto exit;
- err = ipu_pm_notifications(PM_PID_DEATH, (void *)my_pid);
+ err = ipu_pm_notifications(APP_M3, PM_PID_DEATH,
+ (void *)my_pid);
if (err) {
pinfo->brd_state = DEVH_BRDST_ERROR;
if (!strcmp(pdata->name, "SysM3")) {
diff --git a/drivers/dsp/syslink/ipu_pm/ipu_pm.c b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
index ae070006936..a33e3bc0b49 100644
--- a/drivers/dsp/syslink/ipu_pm/ipu_pm.c
+++ b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
@@ -71,16 +71,17 @@
#define SL2_RESOURCE 10
#define proc_supported(proc_id) (proc_id == SYS_M3 || proc_id == APP_M3)
+#define _has_cstrs(r) ((PM_FIRST_RES <= r && r < PM_NUM_RES_W_CSTRS) ? 1 : 0)
+#define _is_res(r) ((PM_FIRST_RES <= r && r < PM_NUM_RES) ? 1 : 0)
+#define _is_event(e) ((PM_FIRST_EVENT <= e && e < PM_LAST_EVENT) ? 1 : 0)
#define LINE_ID 0
#define NUM_SELF_PROC 2
#define IPU_KFIFO_SIZE 16
#define PM_VERSION 0x00020000
-#define SYSM3_IDLE_FLAG_PHY_ADDR 0x9E0502D8
-#define APPM3_IDLE_FLAG_PHY_ADDR 0x9E0502DC
-
-#define _is_valid_event(e) ((PM_FIRST_EVENT <= e && e <= PM_LAST_EVENT) ? 1 : 0)
+/* Flag provided by BIOS */
+#define IDLE_FLAG_PHY_ADDR 0x9E0502D8
#define NUM_IDLE_CORES ((__raw_readl(appm3Idle) << 1) + \
(__raw_readl(sysm3Idle)))
@@ -90,143 +91,175 @@
* ============================================================================
*/
-/* Request a resource on behalf of an IPU client */
-static inline int ipu_pm_req_res(u32 res_type, u32 proc_id, u32 rcb_num);
-
-/* Release a resource on behalf of an IPU client */
-static inline int ipu_pm_rel_res(u32 res_type, u32 proc_id, u32 rcb_num);
-
/* Request a sdma channels on behalf of an IPU client */
-static inline int ipu_pm_get_sdma_chan(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_sdma_chan(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request a gptimer on behalf of an IPU client */
-static inline int ipu_pm_get_gptimer(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_gptimer(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request an i2c bus on behalf of an IPU client */
-static inline int ipu_pm_get_i2c_bus(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_i2c_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request a gpio on behalf of an IPU client */
-static inline int ipu_pm_get_gpio(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_gpio(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request a regulator on behalf of an IPU client */
-static inline int ipu_pm_get_regulator(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_regulator(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request an Aux clk on behalf of an IPU client */
-static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_aux_clk(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request sys m3 on behalf of an IPU client */
-static inline int ipu_pm_get_sys_m3(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_sys_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request app m3 on behalf of an IPU client */
-static inline int ipu_pm_get_app_m3(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_app_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request L3 Bus on behalf of an IPU client */
-static inline int ipu_pm_get_l3_bus(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_l3_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request IVA HD on behalf of an IPU client */
-static inline int ipu_pm_get_iva_hd(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_iva_hd(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request FDIF on behalf of an IPU client */
-static inline int ipu_pm_get_fdif(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_fdif(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request MPU on behalf of an IPU client */
-static inline int ipu_pm_get_mpu(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_mpu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request IPU on behalf of an IPU client */
-static inline int ipu_pm_get_ipu(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_ipu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request IVA SEQ0 on behalf of an IPU client */
-static inline int ipu_pm_get_ivaseq0(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_ivaseq0(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request IVA SEQ1 on behalf of an IPU client */
-static inline int ipu_pm_get_ivaseq1(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_ivaseq1(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Request ISS on behalf of an IPU client */
-static inline int ipu_pm_get_iss(int proc_id, u32 rcb_num);
+static inline int ipu_pm_get_iss(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release a sdma on behalf of an IPU client */
-static inline int ipu_pm_rel_sdma_chan(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_sdma_chan(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release a gptimer on behalf of an IPU client */
-static inline int ipu_pm_rel_gptimer(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_gptimer(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release an i2c buses on behalf of an IPU client */
-static inline int ipu_pm_rel_i2c_bus(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_i2c_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release a gpio on behalf of an IPU client */
-static inline int ipu_pm_rel_gpio(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_gpio(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release a regulator on behalf of an IPU client */
-static inline int ipu_pm_rel_regulator(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_regulator(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release an Aux clk on behalf of an IPU client */
-static inline int ipu_pm_rel_aux_clk(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_aux_clk(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release sys m3 on behalf of an IPU client */
-static inline int ipu_pm_rel_sys_m3(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_sys_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release app m3 on behalf of an IPU client */
-static inline int ipu_pm_rel_app_m3(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_app_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release L3 Bus on behalf of an IPU client */
-static inline int ipu_pm_rel_l3_bus(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_l3_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release IVA HD on behalf of an IPU client */
-static inline int ipu_pm_rel_iva_hd(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_iva_hd(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release FDIF on behalf of an IPU client */
-static inline int ipu_pm_rel_fdif(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_fdif(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release MPU on behalf of an IPU client */
-static inline int ipu_pm_rel_mpu(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_mpu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release IPU on behalf of an IPU client */
-static inline int ipu_pm_rel_ipu(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_ipu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release IVA SEQ0 on behalf of an IPU client */
-static inline int ipu_pm_rel_ivaseq0(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_ivaseq0(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release IVA SEQ1 on behalf of an IPU client */
-static inline int ipu_pm_rel_ivaseq1(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_ivaseq1(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/* Release ISS on behalf of an IPU client */
-static inline int ipu_pm_rel_iss(int proc_id, u32 rcb_num);
-
-/* Request a FDIF constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_fdif(int proc_id, u32 rcb_num);
-
-/* Request a IPU constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_ipu(int proc_id, u32 rcb_num);
-
-/* Request a L3 Bus constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_l3_bus(int proc_id, u32 rcb_num);
-
-/* Request an IVA HD constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_iva_hd(int proc_id, u32 rcb_num);
-
-/* Request an ISS constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_iss(int proc_id, u32 rcb_num);
-
-/* Request an MPU constraint on behalf of an IPU client */
-static inline int ipu_pm_req_cstr_mpu(int proc_id, u32 rcb_num);
-
-/* Release a FDFI constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_fdif(int proc_id, u32 rcb_num);
+static inline int ipu_pm_rel_iss(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
-/* Release a IPU constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_ipu(int proc_id, u32 rcb_num);
+/* Request a res constraint on behalf of an IPU client */
+static inline int ipu_pm_req_cstr(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
-/* Release a L3 Bus constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_l3_bus(int proc_id, u32 rcb_num);
-
-/* Release an IVA HD constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_iva_hd(int proc_id, u32 rcb_num);
-
-/* Release an ISS constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_iss(int proc_id, u32 rcb_num);
-
-/* Release an MPU constraint on behalf of an IPU client */
-static inline int ipu_pm_rel_cstr_mpu(int proc_id, u32 rcb_num);
+/* Release a res constraint on behalf of an IPU client */
+static inline int ipu_pm_rel_cstr(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params);
/** ============================================================================
* Globals
@@ -241,20 +274,34 @@ static u32 AUX_CLK_USE_MASK = 0xFFFF;
/* Previous voltage value of secondary camera regulator */
static u32 cam2_prev_volt;
+/* Resources and notifications*/
static struct ipu_pm_object *pm_handle_appm3;
static struct ipu_pm_object *pm_handle_sysm3;
-static struct workqueue_struct *ipu_wq;
+struct sms *global_rcb;
+static struct workqueue_struct *ipu_resources;
+
+/* Clean up and recover */
+static struct workqueue_struct *ipu_clean_up;
+struct work_struct clean;
+static DECLARE_COMPLETION(ipu_clean_up_comp);
+static bool recover;
+
+/* Latency cstrs */
#ifdef CONFIG_OMAP_PM
static struct pm_qos_request_list *pm_qos_handle;
static struct pm_qos_request_list *pm_qos_handle_2;
#endif
+
+/* Save/restore for hibernation */
static struct omap_rproc *sys_rproc;
static struct omap_rproc *app_rproc;
static struct omap_mbox *ducati_mbox;
static struct iommu *ducati_iommu;
static bool first_time = 1;
-static bool mpu_hib_ipu;
-/* static struct omap_dm_timer *pm_gpt; */
+
+/* BIOS flags states for each core in IPU */
+static void __iomem *sysm3Idle;
+static void __iomem *appm3Idle;
/* Ducati Interrupt Capable Gptimers */
static int ipu_timer_list[NUM_IPU_TIMERS] = {
@@ -269,6 +316,7 @@ static int i2c_spinlock_list[I2C_BUS_MAX + 1] = {
I2C_3_SL,
I2C_4_SL};
+/* Camera regulator */
static char *ipu_regulator_name[REGULATOR_MAX] = {
"cam2pwr"};
@@ -297,6 +345,7 @@ static struct ipu_pm_module_object ipu_pm_state = {
.gate_handle = NULL
} ;
+/* Default params for ipu_pm handle */
static struct ipu_pm_params pm_params = {
.pm_fdif_counter = 0,
.pm_ipu_counter = 0,
@@ -325,210 +374,197 @@ static struct ipu_pm_params pm_params = {
.line_id = 0
} ;
-static void __iomem *sysm3Idle;
-static void __iomem *appm3Idle;
-static void __iomem *cm_ducati_clkstctrl;
-
-/*
- Request a resource on behalf of an IPU client
+/* Functions to request resources */
+static int (*request_fxn[PM_NUM_RES]) (struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params) = {
+ ipu_pm_get_fdif,
+ ipu_pm_get_ipu,
+ ipu_pm_get_sys_m3,
+ ipu_pm_get_app_m3,
+ ipu_pm_get_iss,
+ ipu_pm_get_iva_hd,
+ ipu_pm_get_ivaseq0,
+ ipu_pm_get_ivaseq1,
+ ipu_pm_get_l3_bus,
+ ipu_pm_get_mpu,
+ /* ipu_pm_get_sl2if, */
+ /* ipu_pm_get_dsp, */
+ ipu_pm_get_sdma_chan,
+ ipu_pm_get_gptimer,
+ ipu_pm_get_gpio,
+ ipu_pm_get_i2c_bus,
+ ipu_pm_get_regulator,
+ ipu_pm_get_aux_clk,
+};
+
+/* Functions to release resources */
+static int (*release_fxn[PM_NUM_RES]) (struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params) = {
+ ipu_pm_rel_fdif,
+ ipu_pm_rel_ipu,
+ ipu_pm_rel_sys_m3,
+ ipu_pm_rel_app_m3,
+ ipu_pm_rel_iss,
+ ipu_pm_rel_iva_hd,
+ ipu_pm_rel_ivaseq0,
+ ipu_pm_rel_ivaseq1,
+ ipu_pm_rel_l3_bus,
+ ipu_pm_rel_mpu,
+ /* ipu_pm_rel_sl2if, */
+ /* ipu_pm_rel_dsp, */
+ ipu_pm_rel_sdma_chan,
+ ipu_pm_rel_gptimer,
+ ipu_pm_rel_gpio,
+ ipu_pm_rel_i2c_bus,
+ ipu_pm_rel_regulator,
+ ipu_pm_rel_aux_clk,
+
+};
+
+/*
+ Function to schedule the recover process
*
*/
-static inline int ipu_pm_req_res(u32 res_type, u32 proc_id, u32 rcb_num)
+static void ipu_pm_recover_schedule(void)
{
- int retval = PM_SUCCESS;
-
- switch (res_type) {
- case SDMA:
- retval = ipu_pm_get_sdma_chan(proc_id, rcb_num);
- break;
- case GP_TIMER:
- retval = ipu_pm_get_gptimer(proc_id, rcb_num);
- break;
- case GP_IO:
- retval = ipu_pm_get_gpio(proc_id, rcb_num);
- break;
- case I2C:
- retval = ipu_pm_get_i2c_bus(proc_id, rcb_num);
- break;
- case REGULATOR:
- retval = ipu_pm_get_regulator(proc_id, rcb_num);
- break;
- case AUX_CLK:
- retval = ipu_pm_get_aux_clk(proc_id, rcb_num);
- break;
- case SYSM3:
- retval = ipu_pm_get_sys_m3(proc_id, rcb_num);
- break;
- case APPM3:
- retval = ipu_pm_get_app_m3(proc_id, rcb_num);
- break;
- case L3_BUS:
- retval = ipu_pm_get_l3_bus(proc_id, rcb_num);
- break;
- case IVA_HD:
- retval = ipu_pm_get_iva_hd(proc_id, rcb_num);
- break;
- case IVASEQ0:
- retval = ipu_pm_get_ivaseq0(proc_id, rcb_num);
- break;
- case IVASEQ1:
- retval = ipu_pm_get_ivaseq1(proc_id, rcb_num);
- break;
- case ISS:
- retval = ipu_pm_get_iss(proc_id, rcb_num);
- break;
- case FDIF:
- retval = ipu_pm_get_fdif(proc_id, rcb_num);
- break;
- case MPU:
- retval = ipu_pm_get_mpu(proc_id, rcb_num);
- break;
- case IPU:
- retval = ipu_pm_get_ipu(proc_id, rcb_num);
- break;
- default:
- pr_err("Unsupported resource\n");
- retval = PM_UNSUPPORTED;
- }
+ struct ipu_pm_object *handle;
- return retval;
+ INIT_COMPLETION(ipu_clean_up_comp);
+ recover = true;
+
+ /* get the handle to proper ipu pm object
+ * and flush any pending fifo message
+ */
+ handle = ipu_pm_get_handle(APP_M3);
+ if (handle)
+ kfifo_reset(&handle->fifo);
+ handle = ipu_pm_get_handle(SYS_M3);
+ if (handle)
+ kfifo_reset(&handle->fifo);
+
+ /* schedule clean up work */
+ queue_work(ipu_clean_up, &clean);
}
/*
- Release a resource on behalf of an IPU client
+ Function to clean/release all the resources
*
*/
-static inline int ipu_pm_rel_res(u32 res_type, u32 proc_id, u32 rcb_num)
+static void ipu_pm_clean_res(void)
{
- int retval = PM_SUCCESS;
-
- switch (res_type) {
- case SDMA:
- retval = ipu_pm_rel_sdma_chan(proc_id, rcb_num);
- break;
- case GP_TIMER:
- retval = ipu_pm_rel_gptimer(proc_id, rcb_num);
- break;
- case GP_IO:
- retval = ipu_pm_rel_gpio(proc_id, rcb_num);
- break;
- case I2C:
- retval = ipu_pm_rel_i2c_bus(proc_id, rcb_num);
- break;
- case REGULATOR:
- retval = ipu_pm_rel_regulator(proc_id, rcb_num);
- break;
- case AUX_CLK:
- retval = ipu_pm_rel_aux_clk(proc_id, rcb_num);
- break;
- case SYSM3:
- retval = ipu_pm_rel_sys_m3(proc_id, rcb_num);
- break;
- case APPM3:
- retval = ipu_pm_rel_app_m3(proc_id, rcb_num);
- break;
- case L3_BUS:
- retval = ipu_pm_rel_l3_bus(proc_id, rcb_num);
- break;
- case IVA_HD:
- retval = ipu_pm_rel_iva_hd(proc_id, rcb_num);
- break;
- case IVASEQ0:
- retval = ipu_pm_rel_ivaseq0(proc_id, rcb_num);
- break;
- case IVASEQ1:
- retval = ipu_pm_rel_ivaseq1(proc_id, rcb_num);
- break;
- case ISS:
- retval = ipu_pm_rel_iss(proc_id, rcb_num);
- break;
- case FDIF:
- retval = ipu_pm_rel_fdif(proc_id, rcb_num);
- break;
- case MPU:
- retval = ipu_pm_rel_mpu(proc_id, rcb_num);
- break;
- case IPU:
- retval = ipu_pm_rel_ipu(proc_id, rcb_num);
- break;
- default:
- pr_err("Unsupported resource\n");
- retval = PM_UNSUPPORTED;
+ /* Check RAT and call each release function
+ * per resource in rcb
+ */
+ unsigned used_res_mask = global_rcb->rat;
+ struct ipu_pm_object *handle;
+ struct ipu_pm_params *params;
+ struct rcb_block *rcb_p;
+ int cur_rcb = 1;
+ u32 mask;
+ int res;
+ int retval = 0;
+
+ /* The reserved RCB's are marked as valid
+ * by the remote proc but are not requesting any
+ * resource so no need to release.
+ * rcb = 0 is invalid.
+ * rcb = 1 is reserved.
+ * Start in 2
+ */
+ used_res_mask &= RESERVED_RCBS;
+ pr_debug("Resources Mask 0x%x\n", used_res_mask);
+
+ if (!used_res_mask)
+ goto complete_exit;
+
+ while (cur_rcb < RCB_MAX && used_res_mask != 0) {
+ cur_rcb++;
+ mask = 1;
+ mask = mask << cur_rcb;
+
+ if (!(mask & used_res_mask))
+ continue;
+
+ rcb_p = (struct rcb_block *)&global_rcb->rcb[cur_rcb];
+ handle = ipu_pm_get_handle(rcb_p->rqst_cpu);
+ if (!handle) {
+ pr_err("Invalid RCB, maybe corrupted!\n");
+ used_res_mask &= ~mask;
+ continue;
+ }
+ params = handle->params;
+ res = rcb_p->sub_type;
+
+ if (_has_cstrs(res)) {
+ pr_debug("Releasing res:%d cstrs\n", res);
+ retval = ipu_pm_rel_cstr(handle, rcb_p, params);
+ if (retval)
+ pr_err("Error releasing res:%d cstrs\n", res);
+ }
+
+ if (_is_res(res)) {
+ pr_debug("Releasing res:%d\n", res);
+ retval = release_fxn[res](handle, rcb_p, params);
+ if (retval)
+ pr_err("Can't release resource: %d\n", res);
+ }
+
+ /* Clear the RCB from the RAT if success */
+ if (!retval)
+ used_res_mask &= ~mask;
+ pr_debug("Mask 0x%x\n", used_res_mask);
}
- return retval;
+ global_rcb->rat = used_res_mask;
+ if (!used_res_mask)
+ goto complete_exit;
+
+ pr_warning("%s:Not all resources were released", __func__);
+ return;
+complete_exit:
+ complete_all(&ipu_clean_up_comp);
+ return;
}
/*
- Request a resource constraint on behalf of an IPU client
+ Work Function to clean up resources
*
*/
-static inline int ipu_pm_req_cstr(u32 res_type, u32 proc_id, u32 rcb_num)
+static void ipu_pm_clean_work(struct work_struct *work)
{
- int retval = PM_SUCCESS;
-
- switch (res_type) {
- case FDIF:
- retval = ipu_pm_req_cstr_fdif(proc_id, rcb_num);
- break;
- case IPU:
- retval = ipu_pm_req_cstr_ipu(proc_id, rcb_num);
- break;
- case L3_BUS:
- retval = ipu_pm_req_cstr_l3_bus(proc_id, rcb_num);
- break;
- case IVA_HD:
- retval = ipu_pm_req_cstr_iva_hd(proc_id, rcb_num);
- break;
- case ISS:
- retval = ipu_pm_req_cstr_iss(proc_id, rcb_num);
- break;
- case MPU:
- retval = ipu_pm_req_cstr_mpu(proc_id, rcb_num);
- break;
- default:
- pr_err("Resource does not support constraints\n");
- retval = PM_UNSUPPORTED;
- }
-
- return retval;
+ ipu_pm_clean_res();
}
/*
- Release a resource constraint on behalf of an IPU client
+ Notifier Function to handle IOMMU events
*
*/
-static inline int ipu_pm_rel_cstr(u32 res_type, u32 proc_id, u32 rcb_num)
+static int ipu_pm_iommu_notifier_call(struct notifier_block *nb,
+ unsigned long val, void *v)
{
- int retval = PM_SUCCESS;
-
- switch (res_type) {
- case FDIF:
- retval = ipu_pm_rel_cstr_fdif(proc_id, rcb_num);
- break;
- case IPU:
- retval = ipu_pm_rel_cstr_ipu(proc_id, rcb_num);
- break;
- case L3_BUS:
- retval = ipu_pm_rel_cstr_l3_bus(proc_id, rcb_num);
- break;
- case IVA_HD:
- retval = ipu_pm_rel_cstr_iva_hd(proc_id, rcb_num);
- break;
- case ISS:
- retval = ipu_pm_rel_cstr_iss(proc_id, rcb_num);
- break;
- case MPU:
- retval = ipu_pm_rel_cstr_mpu(proc_id, rcb_num);
- break;
+ switch ((int)val) {
+ case IOMMU_CLOSE:
+ /*
+ * restore IOMMU since it is required the IOMMU
+ * is up and running for reclaiming MMU entries
+ */
+ if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
+ iommu_restore_ctx(ducati_iommu);
+ return 0;
+ case IOMMU_FAULT:
+ ipu_pm_recover_schedule();
+ return 0;
default:
- pr_err("Resource does not support constraints\n");
- retval = PM_UNSUPPORTED;
+ return 0;
}
-
- return retval;
}
+static struct notifier_block ipu_pm_notify_nb_iommu_ducati = {
+ .notifier_call = ipu_pm_iommu_notifier_call,
+};
+
/*
Work Function to req/rel a resource
*
@@ -539,16 +575,25 @@ static void ipu_pm_work(struct work_struct *work)
container_of(work, struct ipu_pm_object, work);
struct rcb_block *rcb_p;
struct ipu_pm_msg im;
- struct ipu_pm_params *params = handle->params;
+ struct ipu_pm_params *params;
union message_slicer pm_msg;
- int action_type;
- int res_type;
+ int action;
+ int res;
int rcb_num;
- int retval = PM_SUCCESS;
+ int retval;
+
+ if (WARN_ON(handle == NULL))
+ return;
+
+ params = handle->params;
+ if (WARN_ON(params == NULL))
+ return;
while (kfifo_len(&handle->fifo) >= sizeof(im)) {
+ /* set retval for each iteration asumming error */
+ retval = PM_UNSUPPORTED;
spin_lock_irq(&handle->lock);
- retval = kfifo_out(&handle->fifo, &im, sizeof(im));
+ kfifo_out(&handle->fifo, &im, sizeof(im));
spin_unlock_irq(&handle->lock);
/* Get the payload */
@@ -556,38 +601,46 @@ static void ipu_pm_work(struct work_struct *work)
/* Get the rcb_num */
rcb_num = pm_msg.fields.rcb_num;
/* Get pointer to the proper RCB */
+ if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
+ return;
rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
/* Get the type of resource and the actions required */
- action_type = rcb_p->msg_type;
- res_type = rcb_p->sub_type;
- switch (action_type) {
+ action = rcb_p->msg_type;
+ res = rcb_p->sub_type;
+ if (!_is_res(res)) {
+ pr_err("Invalid res number: %d\n", res);
+ /* No need to continue, send error back */
+ goto send_msg;
+ }
+ switch (action) {
case PM_REQUEST_RESOURCE:
- retval = ipu_pm_req_res(res_type, im.proc_id, rcb_num);
- if (retval != PM_SUCCESS)
- pm_msg.fields.msg_type = PM_FAIL;
+ if (request_fxn[res])
+ retval = request_fxn[res](handle, rcb_p,
+ params);
break;
case PM_RELEASE_RESOURCE:
- retval = ipu_pm_rel_res(res_type, im.proc_id, rcb_num);
- if (retval != PM_SUCCESS)
- pm_msg.fields.msg_type = PM_FAIL;
+ if (release_fxn[res])
+ retval = release_fxn[res](handle, rcb_p,
+ params);
break;
case PM_REQUEST_CONSTRAINTS:
- retval = ipu_pm_req_cstr(res_type, im.proc_id, rcb_num);
- if (retval != PM_SUCCESS)
- pm_msg.fields.msg_type = PM_FAIL;
+ if (_has_cstrs(res))
+ retval = ipu_pm_req_cstr(handle, rcb_p,
+ params);
break;
case PM_RELEASE_CONSTRAINTS:
- retval = ipu_pm_rel_cstr(res_type, im.proc_id, rcb_num);
- if (retval != PM_SUCCESS)
- pm_msg.fields.msg_type = PM_FAIL;
+ if (_has_cstrs(res))
+ retval = ipu_pm_rel_cstr(handle, rcb_p,
+ params);
break;
default:
pm_msg.fields.msg_type = PM_FAIL;
- retval = PM_UNSUPPORTED;
break;
}
-
+send_msg:
+ if (retval != PM_SUCCESS)
+ pm_msg.fields.msg_type = PM_FAIL;
/* Update the payload with the reply msg */
pm_msg.fields.reply_flag = true;
pm_msg.fields.parm = retval;
@@ -617,13 +670,16 @@ void ipu_pm_callback(u16 proc_id, u16 line_id, u32 event_id,
/*get the handle to proper ipu pm object */
handle = ipu_pm_get_handle(proc_id);
+ if (WARN_ON(unlikely(handle == NULL)))
+ return;
+
im.proc_id = proc_id;
im.pm_msg = payload;
spin_lock_irq(&handle->lock);
if (kfifo_avail(&handle->fifo) >= sizeof(im)) {
kfifo_in(&handle->fifo, (unsigned char *)&im, sizeof(im));
- queue_work(ipu_wq, &handle->work);
+ queue_work(ipu_resources, &handle->work);
}
spin_unlock_irq(&handle->lock);
}
@@ -657,7 +713,7 @@ void ipu_pm_notify_callback(u16 proc_id, u16 line_id, u32 event_id,
pm_msg.whole = payload;
/* get the event type sent by remote proc */
event = pm_msg.fields.msg_subtype;
- if (!_is_valid_event(event))
+ if (!_is_event(event))
goto error;
if (event == PM_HIBERNATE) {
/* Remote Proc is ready to hibernate
@@ -673,138 +729,70 @@ void ipu_pm_notify_callback(u16 proc_id, u16 line_id, u32 event_id,
handle->pm_event[event].pm_msg = payload;
up(&handle->pm_event[event].sem_handle);
}
+
return;
error:
pr_err("Unknow event received from remote proc: %d\n", event);
}
EXPORT_SYMBOL(ipu_pm_notify_callback);
-/*
- Function for send PM Notifications
- *
+/* Function for send PM Notifications
+ * Function used by devh and dev_pm
+ * Recieves evenType: Suspend, Resume, Proc_Obit
+ * Send event to Ducati
+ * Pend semaphore based in event_type (payload)
+ * Return ACK to caller
*/
-int ipu_pm_notifications(enum pm_event_type event_type, void *data)
+int ipu_pm_notifications(int proc_id, enum pm_event_type event, void *data)
{
- /**
- * Function called by linux driver
- * Recieves evenType: Suspend, Resume, others...
- * Send event to Ducati
- * Pend semaphore based in event_type (payload)
- * Return ACK to caller
- */
-
struct ipu_pm_object *handle;
struct ipu_pm_params *params;
union message_slicer pm_msg;
int retval;
int pm_ack = 0;
- int i;
- int proc_id;
- /*get the handle to proper ipu pm object */
- for (i = 0; i < NUM_SELF_PROC; i++) {
- proc_id = i + 1;
- handle = ipu_pm_get_handle(proc_id);
- if (handle == NULL)
- continue;
- params = handle->params;
- if (params == NULL)
- continue;
- switch (event_type) {
- case PM_SUSPEND:
- pm_msg.fields.msg_type = PM_NOTIFICATIONS;
- pm_msg.fields.msg_subtype = PM_SUSPEND;
- pm_msg.fields.parm = PM_SUCCESS;
- /* put general purpose message in share memory */
- handle->rcb_table->gp_msg = (unsigned)data;
- /* send the request to IPU*/
- retval = notify_send_event(
- params->remote_proc_id,
- params->line_id,
- params->pm_notification_event | \
- (NOTIFY_SYSTEMKEY << 16),
- (unsigned int)pm_msg.whole,
- true);
- if (retval < 0)
- goto error_send;
- /* wait until event from IPU (ipu_pm_notify_callback)*/
- retval = down_timeout
- (&handle->pm_event[PM_SUSPEND]
- .sem_handle,
- msecs_to_jiffies(params->timeout));
- pm_msg.whole = handle->pm_event[PM_SUSPEND].pm_msg;
- if (WARN_ON((retval < 0) ||
- (pm_msg.fields.parm != PM_SUCCESS)))
- goto error;
- break;
- case PM_RESUME:
- pm_msg.fields.msg_type = PM_NOTIFICATIONS;
- pm_msg.fields.msg_subtype = PM_RESUME;
- pm_msg.fields.parm = PM_SUCCESS;
- /* put general purpose message in share memory */
- handle->rcb_table->gp_msg = (unsigned)data;
- /* send the request to IPU*/
- retval = notify_send_event(
- params->remote_proc_id,
- params->line_id,
- params->pm_notification_event | \
- (NOTIFY_SYSTEMKEY << 16),
- (unsigned int)pm_msg.whole,
- true);
- if (retval < 0)
- goto error_send;
- /* wait until event from IPU (ipu_pm_notify_callback)*/
- retval = down_timeout
- (&handle->pm_event[PM_RESUME]
- .sem_handle,
- msecs_to_jiffies(params->timeout));
- pm_msg.whole = handle->pm_event[PM_RESUME].pm_msg;
- if (WARN_ON((retval < 0) ||
- (pm_msg.fields.parm != PM_SUCCESS)))
- goto error;
- break;
- case PM_HIBERNATE:
- pr_err("PM_HIBERNATE event currently not supported\n");
- break;
- case PM_PID_DEATH:
- /* Just send the message to appm3 since is the one
- * running the resource manager.
- */
- if (proc_id == SYS_M3)
- break;
- pm_msg.fields.msg_type = PM_NOTIFICATIONS;
- pm_msg.fields.msg_subtype = PM_PID_DEATH;
- pm_msg.fields.parm = PM_SUCCESS;
- /* put general purpose message in share memory */
- handle->rcb_table->gp_msg = (unsigned)data;
- /* send the request to IPU*/
- retval = notify_send_event(
- params->remote_proc_id,
- params->line_id,
- params->pm_notification_event | \
- (NOTIFY_SYSTEMKEY << 16),
- (unsigned int)pm_msg.whole,
- true);
- if (retval < 0)
- goto error_send;
- /* wait until event from IPU (ipu_pm_notify_callback)*/
- retval = down_timeout
- (&handle->pm_event[PM_PID_DEATH]
- .sem_handle,
- msecs_to_jiffies(params->timeout));
- pm_msg.whole = handle->pm_event[PM_PID_DEATH].pm_msg;
- if (WARN_ON((retval < 0) ||
- (pm_msg.fields.parm != PM_SUCCESS)))
- goto error;
- break;
- }
- }
+ handle = ipu_pm_get_handle(proc_id);
+ if (handle == NULL)
+ goto error;
+ params = handle->params;
+ if (params == NULL)
+ goto error;
+
+ /* Prepare the message for remote proc */
+ pm_msg.fields.msg_type = PM_NOTIFICATIONS;
+ pm_msg.fields.msg_subtype = event;
+ pm_msg.fields.parm = PM_SUCCESS;
+
+ /* put general purpose message in share memory
+ * this message is just for devh but it can be use
+ * for sending any message to the remote proc
+ * along with the notification
+ */
+ handle->rcb_table->gp_msg = (unsigned)data;
+
+ /* send the request to IPU*/
+ retval = notify_send_event(params->remote_proc_id,
+ params->line_id,
+ params->pm_notification_event | \
+ (NOTIFY_SYSTEMKEY << 16),
+ (unsigned int)pm_msg.whole,
+ true);
+ if (retval < 0)
+ goto error_send;
+
+ /* wait for remote proc ack (ipu_pm_notify_callback)*/
+ retval = down_timeout(&handle->pm_event[event].sem_handle,
+ msecs_to_jiffies(params->timeout));
+
+ pm_msg.whole = handle->pm_event[event].pm_msg;
+ if (WARN_ON((retval < 0) || (pm_msg.fields.parm != PM_SUCCESS)))
+ goto error;
return pm_ack;
error_send:
- pr_err("Error notify_send event %d to proc %d\n", event_type, proc_id);
+ pr_err("Error notify_send event %d to proc %d\n", event, proc_id);
error:
- pr_err("Error sending Notification event %d\n", event_type);
+ pr_err("Error sending Notification event %d\n", event);
return -EBUSY;
}
EXPORT_SYMBOL(ipu_pm_notifications);
@@ -813,39 +801,29 @@ EXPORT_SYMBOL(ipu_pm_notifications);
Request a sdma channels on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_sdma_chan(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_sdma_chan(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int pm_sdmachan_num;
int pm_sdmachan_dummy;
int ch;
int ch_aux;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
/* Get number of channels from RCB */
pm_sdmachan_num = rcb_p->num_chan;
if (WARN_ON((pm_sdmachan_num <= 0) ||
- (pm_sdmachan_num > SDMA_CHANNELS_MAX)))
+ (pm_sdmachan_num > SDMA_CHANNELS_MAX))) {
+ pr_err("%s %d Not able to provide %d channels\n", __func__
+ , __LINE__
+ , pm_sdmachan_num);
return PM_INVAL_NUM_CHANNELS;
+ }
/* Request resource using PRCM API */
for (ch = 0; ch < pm_sdmachan_num; ch++) {
- retval = omap_request_dma(proc_id,
+ retval = omap_request_dma(params->proc_id,
"ducati-ss",
NULL,
NULL,
@@ -853,12 +831,17 @@ static inline int ipu_pm_get_sdma_chan(int proc_id, u32 rcb_num)
if (retval == 0) {
params->pm_sdmachan_counter++;
rcb_p->channels[ch] = (unsigned char)pm_sdmachan_dummy;
- } else
+ pr_debug("Providing sdma ch %d\n", pm_sdmachan_dummy);
+ } else {
+ pr_err("%s %d Error providing sdma channel\n", __func__
+ , __LINE__);
goto clean_sdma;
+ }
}
return PM_SUCCESS;
clean_sdma:
- /*failure, need to free the chanels*/
+ /*failure, need to free the channels*/
+ pr_debug("Freeing sdma channel because of failure\n");
for (ch_aux = 0; ch_aux < ch; ch_aux++) {
pm_sdmachan_dummy = (int)rcb_p->channels[ch_aux];
omap_free_dma(pm_sdmachan_dummy);
@@ -871,27 +854,13 @@ clean_sdma:
Request a gptimer on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_gptimer(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_gptimer(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct omap_dm_timer *p_gpt = NULL;
int pm_gp_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
/* Request resource using PRCM API */
for (pm_gp_num = 0; pm_gp_num < NUM_IPU_TIMERS; pm_gp_num++) {
if (GPTIMER_USE_MASK & (1 << ipu_timer_list[pm_gp_num])) {
@@ -900,16 +869,27 @@ static inline int ipu_pm_get_gptimer(int proc_id, u32 rcb_num)
} else
continue;
if (p_gpt != NULL) {
+ /* Check the range of the src clk */
+ if (rcb_p->data[0] < OMAP_TIMER_SRC_SYS_CLK ||
+ rcb_p->data[0] > OMAP_TIMER_SRC_32_KHZ) {
+ /* Default src clk is SYS_CLK */
+ pr_debug("Setting Default Clock Source\n");
+ rcb_p->data[0] = OMAP_TIMER_SRC_SYS_CLK;
+ }
+ /* Set the src clk of gpt */
+ omap_dm_timer_set_source(p_gpt, rcb_p->data[0]);
/* Clear the bit in the usage mask */
GPTIMER_USE_MASK &= ~(1 << ipu_timer_list[pm_gp_num]);
break;
}
}
- if (p_gpt == NULL)
+ if (p_gpt == NULL) {
+ pr_err("%s %d Error providing gp_timer\n", __func__, __LINE__);
return PM_NO_GPTIMER;
- else {
+ } else {
/* Store the gptimer number and base address */
rcb_p->fill9 = ipu_timer_list[pm_gp_num];
+ pr_debug("Providing gp_timer %d\n", rcb_p->fill9);
rcb_p->mod_base_addr = (unsigned)p_gpt;
params->pm_gptimer_counter++;
return PM_SUCCESS;
@@ -920,34 +900,19 @@ static inline int ipu_pm_get_gptimer(int proc_id, u32 rcb_num)
Request an i2c bus on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_i2c_bus(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_i2c_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct clk *p_i2c_clk;
int i2c_clk_status;
char i2c_name[I2C_NAME_SIZE];
int pm_i2c_bus_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
pm_i2c_bus_num = rcb_p->fill9;
if (WARN_ON((pm_i2c_bus_num < I2C_BUS_MIN) ||
(pm_i2c_bus_num > I2C_BUS_MAX)))
- return PM_INVAL_NUM_I2C;
+ goto error;
if (I2C_USE_MASK & (1 << pm_i2c_bus_num)) {
/* building the name for i2c_clk */
@@ -955,53 +920,52 @@ static inline int ipu_pm_get_i2c_bus(int proc_id, u32 rcb_num)
/* Request resource using PRCM API */
p_i2c_clk = omap_clk_get_by_name(i2c_name);
- if (p_i2c_clk == NULL)
- return PM_NO_I2C;
+ if (p_i2c_clk == NULL) {
+ pr_err("%s %d Error providing i2c_%d\n"
+ , __func__, __LINE__
+ , pm_i2c_bus_num);
+ goto error;
+ }
i2c_clk_status = clk_enable(p_i2c_clk);
- if (i2c_clk_status != 0)
- return PM_NO_I2C;
+ if (i2c_clk_status != 0) {
+ pr_err("%s %d Error enabling i2c_%d clock\n"
+ , __func__, __LINE__
+ , pm_i2c_bus_num);
+ goto error;
+ }
/* Clear the bit in the usage mask */
I2C_USE_MASK &= ~(1 << pm_i2c_bus_num);
rcb_p->mod_base_addr = (unsigned)p_i2c_clk;
/* Get the HW spinlock and store it in the RCB */
rcb_p->data[0] = i2c_spinlock_list[pm_i2c_bus_num];
params->pm_i2c_bus_counter++;
+ pr_debug("Providing %s\n", i2c_name);
return PM_SUCCESS;
- } else
- return PM_NO_I2C;
+ }
+error:
+ return PM_NO_I2C;
}
/*
Request a gpio on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_gpio(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_gpio(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int pm_gpio_num;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
pm_gpio_num = rcb_p->fill9;
retval = gpio_request(pm_gpio_num , "ducati-ss");
- if (retval != 0)
+ if (retval != 0) {
+ pr_err("%s %d Error providing gpio %d\n", __func__, __LINE__
+ , pm_gpio_num);
return PM_NO_GPIO;
+ }
+ pr_debug("Providing gpio %d\n", pm_gpio_num);
params->pm_gpio_counter++;
return PM_SUCCESS;
@@ -1011,47 +975,41 @@ static inline int ipu_pm_get_gpio(int proc_id, u32 rcb_num)
Request a regulator on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_regulator(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_regulator(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct regulator *p_regulator = NULL;
char *regulator_name;
int pm_regulator_num;
int retval = 0;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
pm_regulator_num = rcb_p->fill9;
if (WARN_ON((pm_regulator_num < REGULATOR_MIN) ||
- (pm_regulator_num > REGULATOR_MAX)))
- return PM_INVAL_REGULATOR;
+ (pm_regulator_num > REGULATOR_MAX))) {
+ pr_err("%s %d Invalid regulator %d\n", __func__, __LINE__
+ , pm_regulator_num);
+ goto error;
+ }
/*
FIXME:Only providing 1 regulator, if more are provided
* this check is not valid.
*/
- if (WARN_ON(params->pm_regulator_counter > 0))
- return PM_INVAL_REGULATOR;
+ if (WARN_ON(params->pm_regulator_counter > 0)) {
+ pr_err("%s %d No more regulators\n", __func__, __LINE__);
+ goto error;
+ }
/* Search the name of regulator based on the id and request it */
regulator_name = ipu_regulator_name[pm_regulator_num - 1];
p_regulator = regulator_get(NULL, regulator_name);
- if (p_regulator == NULL)
- return PM_NO_REGULATOR;
+ if (p_regulator == NULL) {
+ pr_err("%s %d Error providing regulator %s\n", __func__
+ , __LINE__
+ , regulator_name);
+ goto error;
+ }
/* Get and store the regulator default voltage */
cam2_prev_volt = regulator_get_voltage(p_regulator);
@@ -1059,50 +1017,43 @@ static inline int ipu_pm_get_regulator(int proc_id, u32 rcb_num)
/* Set the regulator voltage min = data[0]; max = data[1]*/
retval = regulator_set_voltage(p_regulator, rcb_p->data[0],
rcb_p->data[1]);
- if (retval)
- return PM_INVAL_REGULATOR;
+ if (retval) {
+ pr_err("%s %d Error setting %s voltage\n", __func__
+ , __LINE__
+ , regulator_name);
+ goto error;
+ }
/* Store the regulator handle in the RCB */
rcb_p->mod_base_addr = (unsigned)p_regulator;
params->pm_regulator_counter++;
+ pr_debug("Providing regulator %s\n", regulator_name);
return PM_SUCCESS;
+error:
+ return PM_INVAL_REGULATOR;
}
/*
Request an Aux clk on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_aux_clk(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
u32 a_clk = 0;
int ret;
int pm_aux_clk_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
pm_aux_clk_num = rcb_p->fill9;
- pr_info("Request AUX CLK %d\n", pm_aux_clk_num);
-
if (WARN_ON((pm_aux_clk_num < AUX_CLK_MIN) ||
- (pm_aux_clk_num > AUX_CLK_MAX)))
+ (pm_aux_clk_num > AUX_CLK_MAX))) {
+ pr_err("%s %d Invalid aux_clk %d\n", __func__, __LINE__
+ , pm_aux_clk_num);
return PM_INVAL_AUX_CLK;
+ }
if (AUX_CLK_USE_MASK & (1 << pm_aux_clk_num)) {
struct clk *aux_clk;
@@ -1110,25 +1061,32 @@ static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
aux_clk = clk_get(NULL, aux_clk_name[pm_aux_clk_num]);
if (!aux_clk) {
- pr_err("UNABLE TO GET AUX CLOCK: %s\n",
- aux_clk_name[pm_aux_clk_num]);
+ pr_err("%s %d Unable to get %s\n", __func__, __LINE__
+ , aux_clk_name[pm_aux_clk_num]);
return PM_NO_AUX_CLK;
}
- clk_disable(aux_clk);
+ if (unlikely(aux_clk->usecount != 0)) {
+ pr_err("%s %d aux_clk%d->usecount = %d, expected to "
+ "be zero as there should be no other users\n",
+ __func__, __LINE__, pm_aux_clk_num,
+ aux_clk->usecount);
+ }
aux_clk_src_ptr = clk_get(NULL,
aux_clk_source_name[PER_DPLL_CLK]);
if (!aux_clk_src_ptr) {
- pr_err("UNABLE TO GET AUX CLOCK SOURCE CLOCK: %s\n",
- aux_clk_source_name[PER_DPLL_CLK]);
+ pr_err("%s %d Unable to get aux_clk source %s\n"
+ , __func__, __LINE__
+ , aux_clk_source_name[PER_DPLL_CLK]);
return PM_NO_AUX_CLK;
}
ret = clk_set_parent(aux_clk, aux_clk_src_ptr);
if (ret) {
- pr_err("UNABLE TO SET CLOCK: %s"
- " AS PARENT OF AUX CLOCK: %s\n",
- aux_clk_source_name[PER_DPLL_CLK],
- aux_clk_name[pm_aux_clk_num]);
+ pr_err("%s %d Unable to set clk %s"
+ " as parent of aux_clk %s\n"
+ , __func__, __LINE__
+ , aux_clk_source_name[PER_DPLL_CLK]
+ , aux_clk_name[pm_aux_clk_num]);
return PM_NO_AUX_CLK;
}
@@ -1142,8 +1100,9 @@ static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
ret = clk_enable(aux_clk);
if (ret) {
- pr_err("UNABLE TO ENABLE AUX CLOCK: %s\n",
- aux_clk_name[pm_aux_clk_num]);
+ pr_err("%s %d Unable to enable aux_clk %s\n"
+ , __func__, __LINE__
+ , aux_clk_name[pm_aux_clk_num]);
return PM_NO_AUX_CLK;
}
@@ -1152,7 +1111,7 @@ static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
/* Clear the bit in the usage mask */
AUX_CLK_USE_MASK &= ~(1 << pm_aux_clk_num);
- pr_err("AUX_CLK_REG_%d | [0x%x] | [0x%x]\n", pm_aux_clk_num,
+ pr_debug("Providing aux_clk_%d [0x%x] [0x%x]\n", pm_aux_clk_num,
__raw_readl(AUX_CLK_REG(pm_aux_clk_num)),
__raw_readl(AUX_CLK_REG_REQ(pm_aux_clk_num)));
@@ -1160,8 +1119,11 @@ static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
rcb_p->mod_base_addr =
(unsigned __force)AUX_CLK_REG(pm_aux_clk_num);
params->pm_aux_clk_counter++;
- } else
+ } else {
+ pr_err("%s %d Error providing aux_clk %d\n", __func__, __LINE__
+ , pm_aux_clk_num);
return PM_NO_AUX_CLK;
+ }
return PM_SUCCESS;
}
@@ -1170,32 +1132,17 @@ static inline int ipu_pm_get_aux_clk(int proc_id, u32 rcb_num)
Request sys m3 on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_sys_m3(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_sys_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- if (params->pm_sys_m3_counter)
+ if (params->pm_sys_m3_counter) {
+ pr_err("%s %d SYS_M3 already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
- pr_info("Request SYS M3\n");
+ }
params->pm_sys_m3_counter++;
+ pr_debug("Request SYS M3\n");
return PM_SUCCESS;
}
@@ -1204,32 +1151,17 @@ static inline int ipu_pm_get_sys_m3(int proc_id, u32 rcb_num)
Request app m3 on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_app_m3(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_app_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- if (params->pm_app_m3_counter)
+ if (params->pm_app_m3_counter) {
+ pr_err("%s %d APP_M3 already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
- pr_info("Request APP M3\n");
+ }
params->pm_app_m3_counter++;
+ pr_debug("Request APP M3\n");
return PM_SUCCESS;
}
@@ -1238,32 +1170,17 @@ static inline int ipu_pm_get_app_m3(int proc_id, u32 rcb_num)
Request L3 Bus on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_l3_bus(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_l3_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- if (params->pm_l3_bus_counter)
+ if (params->pm_l3_bus_counter) {
+ pr_err("%s %d L3_BUS already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
- pr_info("Request L3 BUS\n");
+ }
params->pm_l3_bus_counter++;
+ pr_debug("Request L3 BUS\n");
return PM_SUCCESS;
}
@@ -1272,43 +1189,34 @@ static inline int ipu_pm_get_l3_bus(int proc_id, u32 rcb_num)
Request IVA HD on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_iva_hd(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_iva_hd(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- if (params->pm_iva_hd_counter)
+ if (params->pm_iva_hd_counter) {
+ pr_err("%s %d IVA_HD already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
- pr_info("Request IVA_HD\n");
+ retval = ipu_pm_module_start(rcb_p->sub_type);
+ if (retval) {
+ pr_err("%s %d Error requesting IVA_HD\n", __func__, __LINE__);
+ return PM_UNSUPPORTED;
+ }
+ params->pm_iva_hd_counter++;
+ pr_debug("Request IVA_HD\n");
#ifdef CONFIG_OMAP_PM
+ pr_debug("Request MPU wakeup latency\n");
retval = omap_pm_set_max_mpu_wakeup_lat(&pm_qos_handle,
IPU_PM_MM_MPU_LAT_CONSTRAINT);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error setting MPU cstr\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
#endif
- retval = ipu_pm_module_start(rcb_p->sub_type);
- if (retval)
- return PM_UNSUPPORTED;
-
- params->pm_iva_hd_counter++;
return PM_SUCCESS;
}
@@ -1317,36 +1225,24 @@ static inline int ipu_pm_get_iva_hd(int proc_id, u32 rcb_num)
Request FDIF on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_fdif(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_fdif(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Request FDIF\n");
- if (params->pm_fdif_counter)
+ if (params->pm_fdif_counter) {
+ pr_err("%s %d FDIF already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
retval = ipu_pm_module_start(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error requesting FDIF\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
+ }
params->pm_fdif_counter++;
+ pr_debug("Request FDIF\n");
return PM_SUCCESS;
}
@@ -1355,31 +1251,17 @@ static inline int ipu_pm_get_fdif(int proc_id, u32 rcb_num)
Request MPU on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_mpu(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_mpu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Request MPU\n");
- if (params->pm_mpu_counter)
+ if (params->pm_mpu_counter) {
+ pr_err("%s %d MPU already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
params->pm_mpu_counter++;
+ pr_debug("Request MPU\n");
return PM_SUCCESS;
}
@@ -1388,71 +1270,43 @@ static inline int ipu_pm_get_mpu(int proc_id, u32 rcb_num)
Request IPU on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_ipu(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_ipu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Request IPU\n");
- if (params->pm_ipu_counter)
+ if (params->pm_ipu_counter) {
+ pr_err("%s %d IPU already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
params->pm_ipu_counter++;
+ pr_debug("Request IPU\n");
return PM_SUCCESS;
}
-
-
/*
Request IVA SEQ0 on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_ivaseq0(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_ivaseq0(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Request IVASEQ0\n");
- if (params->pm_ivaseq0_counter)
+ if (params->pm_ivaseq0_counter) {
+ pr_err("%s %d IVASEQ0 already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
retval = ipu_pm_module_start(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error requesting IVASEQ0\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
+ }
params->pm_ivaseq0_counter++;
+ pr_debug("Request IVASEQ0\n");
return PM_SUCCESS;
}
@@ -1461,42 +1315,34 @@ static inline int ipu_pm_get_ivaseq0(int proc_id, u32 rcb_num)
Request IVA SEQ1 on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_ivaseq1(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_ivaseq1(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Request IVASEQ1\n");
- if (params->pm_ivaseq1_counter)
+ if (params->pm_ivaseq1_counter) {
+ pr_err("%s %d IVASEQ1 already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
retval = ipu_pm_module_start(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error requesting IVASEQ1\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
params->pm_ivaseq1_counter++;
+ pr_debug("Request IVASEQ1\n");
/*Requesting SL2*/
/* FIXME: sl2if should be moved to a independent function */
retval = ipu_pm_module_start(SL2_RESOURCE);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error requesting sl2if\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
params->pm_sl2if_counter++;
+ pr_debug("Request sl2if\n");
return PM_SUCCESS;
}
@@ -1505,45 +1351,27 @@ static inline int ipu_pm_get_ivaseq1(int proc_id, u32 rcb_num)
Request ISS on behalf of an IPU client
*
*/
-static inline int ipu_pm_get_iss(int proc_id, u32 rcb_num)
+static inline int ipu_pm_get_iss(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- if (params->pm_iss_counter)
+ if (params->pm_iss_counter) {
+ pr_err("%s %d ISS already requested\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
- pr_info("Request ISS\n");
+ }
#if TMP_AUX_CLK_HACK
rcb_p->fill9 = AUX_CLK_MIN;
- ipu_pm_get_aux_clk(proc_id, rcb_num);
-#endif
-#ifdef CONFIG_OMAP_PM
- retval = omap_pm_set_max_mpu_wakeup_lat(&pm_qos_handle,
- IPU_PM_MM_MPU_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
+ ipu_pm_get_aux_clk(handle, rcb_p, params);
#endif
+
retval = ipu_pm_module_start(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error requesting ISS\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
/* FIXME:
* enable OPTFCLKEN_CTRLCLK for camera sensors
@@ -1555,7 +1383,18 @@ static inline int ipu_pm_get_iss(int proc_id, u32 rcb_num)
OMAP4430_CM2_CAM_MOD,
OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET);
+#ifdef CONFIG_OMAP_PM
+ pr_debug("Request MPU wakeup latency\n");
+ retval = omap_pm_set_max_mpu_wakeup_lat(&pm_qos_handle,
+ IPU_PM_MM_MPU_LAT_CONSTRAINT);
+ if (retval) {
+ pr_err("%s %d Error setting MPU cstr\n", __func__, __LINE__);
+ return PM_UNSUPPORTED;
+ }
+#endif
+
params->pm_iss_counter++;
+ pr_debug("Request ISS\n");
return PM_SUCCESS;
}
@@ -1564,36 +1403,21 @@ static inline int ipu_pm_get_iss(int proc_id, u32 rcb_num)
Release a sdma on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_sdma_chan(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_sdma_chan(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int pm_sdmachan_num;
int pm_sdmachan_dummy;
int ch;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
-
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
/* Release resource using PRCM API */
pm_sdmachan_num = rcb_p->num_chan;
for (ch = 0; ch < pm_sdmachan_num; ch++) {
pm_sdmachan_dummy = (int)rcb_p->channels[ch];
omap_free_dma(pm_sdmachan_dummy);
params->pm_sdmachan_counter--;
+ pr_debug("Releasing sdma ch %d\n", pm_sdmachan_dummy);
}
return PM_SUCCESS;
}
@@ -1602,44 +1426,35 @@ static inline int ipu_pm_rel_sdma_chan(int proc_id, u32 rcb_num)
Release a gptimer on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_gptimer(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_gptimer(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct omap_dm_timer *p_gpt;
int pm_gptimer_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
-
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
p_gpt = (struct omap_dm_timer *)rcb_p->mod_base_addr;
pm_gptimer_num = rcb_p->fill9;
/* Check the usage mask */
- if (GPTIMER_USE_MASK & (1 << pm_gptimer_num))
+ if (GPTIMER_USE_MASK & (1 << pm_gptimer_num)) {
+ pr_err("%s %d Invalid gptimer %d\n", __func__, __LINE__
+ , pm_gptimer_num);
return PM_NO_GPTIMER;
+ }
/* Set the usage mask for reuse */
GPTIMER_USE_MASK |= (1 << pm_gptimer_num);
/* Release resource using PRCM API */
- if (p_gpt != NULL)
- omap_dm_timer_free(p_gpt);
+ if (!p_gpt) {
+ pr_err("%s %d Null gptimer\n", __func__, __LINE__);
+ return PM_NO_GPTIMER;
+ }
+ omap_dm_timer_free(p_gpt);
rcb_p->mod_base_addr = 0;
params->pm_gptimer_counter--;
+ pr_debug("Releasing gptimer %d\n", pm_gptimer_num);
return PM_SUCCESS;
}
@@ -1647,34 +1462,28 @@ static inline int ipu_pm_rel_gptimer(int proc_id, u32 rcb_num)
Release an i2c buses on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_i2c_bus(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_i2c_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct clk *p_i2c_clk;
int pm_i2c_bus_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
-
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
pm_i2c_bus_num = rcb_p->fill9;
p_i2c_clk = (struct clk *)rcb_p->mod_base_addr;
/* Check the usage mask */
- if (I2C_USE_MASK & (1 << pm_i2c_bus_num))
+ if (I2C_USE_MASK & (1 << pm_i2c_bus_num)) {
+ pr_err("%s %d Invalid i2c_%d\n", __func__, __LINE__
+ , pm_i2c_bus_num);
+ return PM_NO_I2C;
+ }
+
+ if (!p_i2c_clk) {
+ pr_err("%s %d Null i2c_%d\n", __func__, __LINE__
+ , pm_i2c_bus_num);
return PM_NO_I2C;
+ }
/* Release resource using PRCM API */
clk_disable(p_i2c_clk);
@@ -1684,6 +1493,7 @@ static inline int ipu_pm_rel_i2c_bus(int proc_id, u32 rcb_num)
I2C_USE_MASK |= (1 << pm_i2c_bus_num);
params->pm_i2c_bus_counter--;
+ pr_debug("Releasing i2c_%d\n", pm_i2c_bus_num);
return PM_SUCCESS;
}
@@ -1692,30 +1502,21 @@ static inline int ipu_pm_rel_i2c_bus(int proc_id, u32 rcb_num)
Release a gpio on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_gpio(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_gpio(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int pm_gpio_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
+ if (!params->pm_gpio_counter) {
+ pr_err("%s %d No gpio requested\n", __func__, __LINE__);
+ return PM_NO_GPIO;
+ }
pm_gpio_num = rcb_p->fill9;
gpio_free(pm_gpio_num);
params->pm_gpio_counter--;
+ pr_debug("Releasing gpio %d\n", pm_gpio_num);
return PM_SUCCESS;
}
@@ -1724,41 +1525,35 @@ static inline int ipu_pm_rel_gpio(int proc_id, u32 rcb_num)
Release a regulator on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_regulator(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_regulator(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct regulator *p_regulator = NULL;
int retval = 0;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
/* Get the regulator */
p_regulator = (struct regulator *)rcb_p->mod_base_addr;
+ if (!p_regulator) {
+ pr_err("%s %d Null regulator\n", __func__, __LINE__);
+ return PM_INVAL_REGULATOR;
+ }
+
/* Restart the voltage to the default value */
retval = regulator_set_voltage(p_regulator, cam2_prev_volt,
cam2_prev_volt);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error restoring voltage\n", __func__, __LINE__);
return PM_INVAL_REGULATOR;
+ }
/* Release resource using PRCM API */
regulator_put(p_regulator);
rcb_p->mod_base_addr = 0;
params->pm_regulator_counter--;
+ pr_debug("Releasing regulator\n");
return PM_SUCCESS;
}
@@ -1767,41 +1562,26 @@ static inline int ipu_pm_rel_regulator(int proc_id, u32 rcb_num)
Release an Aux clk on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_aux_clk(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_aux_clk(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
struct clk *aux_clk;
int pm_aux_clk_num;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
pm_aux_clk_num = rcb_p->fill9;
- pr_info("Release AUX CLK %d\n", pm_aux_clk_num);
-
/* Check the usage mask */
- if (AUX_CLK_USE_MASK & (1 << pm_aux_clk_num))
- return PM_NO_AUX_CLK;
+ if (AUX_CLK_USE_MASK & (1 << pm_aux_clk_num)) {
+ pr_err("%s %d Invalid aux_clk_%d\n", __func__, __LINE__
+ , pm_aux_clk_num);
+ return PM_INVAL_AUX_CLK;
+ }
aux_clk = aux_clk_ptr[pm_aux_clk_num];
if (!aux_clk) {
- pr_err("UNABLE TO DISABLE AUX CLOCK,"
- " STRUCT CLK * IS NULL: %s\n",
- aux_clk_name[pm_aux_clk_num]);
+ pr_err("%s %d Null aux_clk %s\n", __func__, __LINE__
+ , aux_clk_name[pm_aux_clk_num]);
return PM_INVAL_AUX_CLK;
}
clk_disable(aux_clk);
@@ -1813,6 +1593,7 @@ static inline int ipu_pm_rel_aux_clk(int proc_id, u32 rcb_num)
rcb_p->mod_base_addr = 0;
params->pm_aux_clk_counter--;
+ pr_debug("Releasing aux_clk_%d\n", pm_aux_clk_num);
return PM_SUCCESS;
}
@@ -1821,31 +1602,17 @@ static inline int ipu_pm_rel_aux_clk(int proc_id, u32 rcb_num)
Release sys m3 on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_sys_m3(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_sys_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release SYS M3\n");
-
- if (!params->pm_sys_m3_counter)
+ if (!params->pm_sys_m3_counter) {
+ pr_err("%s %d SYSM3 not requested\n", __func__, __LINE__);
goto error;
+ }
+
params->pm_sys_m3_counter--;
+ pr_debug("Release SYS M3\n");
return PM_SUCCESS;
error:
@@ -1856,31 +1623,17 @@ error:
Release app m3 on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_app_m3(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_app_m3(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release APP M3\n");
-
- if (!params->pm_app_m3_counter)
+ if (!params->pm_app_m3_counter) {
+ pr_err("%s %d APPM3 not requested\n", __func__, __LINE__);
goto error;
+ }
+
params->pm_app_m3_counter--;
+ pr_debug("Release APP M3\n");
return PM_SUCCESS;
error:
@@ -1891,31 +1644,17 @@ error:
Release L3 Bus on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_l3_bus(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_l3_bus(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release L3 BUS\n");
-
- if (!params->pm_l3_bus_counter)
+ if (!params->pm_l3_bus_counter) {
+ pr_err("%s %d L3_BUS not requested\n", __func__, __LINE__);
goto error;
+ }
+
params->pm_l3_bus_counter--;
+ pr_debug("Release L3 BUS\n");
return PM_SUCCESS;
error:
@@ -1926,37 +1665,22 @@ error:
Release FDIF on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_fdif(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_fdif(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release FDIF\n");
-
- if (!params->pm_fdif_counter)
+ if (!params->pm_fdif_counter) {
+ pr_err("%s %d FDIF not requested\n", __func__, __LINE__);
goto error;
+ }
retval = ipu_pm_module_stop(rcb_p->sub_type);
if (retval)
return PM_UNSUPPORTED;
-
params->pm_fdif_counter--;
+ pr_debug("Release FDIF\n");
return PM_SUCCESS;
error:
@@ -1967,32 +1691,17 @@ error:
Release MPU on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_mpu(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_mpu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release MPU\n");
-
- if (!params->pm_mpu_counter)
+ if (!params->pm_mpu_counter) {
+ pr_err("%s %d MPU not requested\n", __func__, __LINE__);
goto error;
+ }
params->pm_mpu_counter--;
+ pr_debug("Release MPU\n");
return PM_SUCCESS;
error:
@@ -2003,32 +1712,17 @@ error:
Release IPU on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_ipu(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_ipu(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release IPU\n");
-
- if (!params->pm_ipu_counter)
+ if (!params->pm_ipu_counter) {
+ pr_err("%s %d IPU not requested\n", __func__, __LINE__);
goto error;
+ }
params->pm_ipu_counter--;
+ pr_debug("Release IPU\n");
return PM_SUCCESS;
error:
@@ -2039,52 +1733,48 @@ error:
Release IVA HD on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_iva_hd(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_iva_hd(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release IVA_HD\n");
-
- if (!params->pm_iva_hd_counter)
+ if (!params->pm_iva_hd_counter) {
+ pr_err("%s %d IVA_HD not requested\n", __func__, __LINE__);
goto error;
+ }
/* Releasing SL2 */
/* FIXME: sl2if should be moved to a independent function */
if (params->pm_sl2if_counter) {
retval = ipu_pm_module_stop(SL2_RESOURCE);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error releasing sl2if\n"
+ , __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
params->pm_sl2if_counter--;
+ pr_debug("Release SL2IF\n");
}
retval = ipu_pm_module_stop(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error releasing IVA_HD\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
+ }
params->pm_iva_hd_counter--;
+ pr_debug("Release IVA_HD\n");
+
#ifdef CONFIG_OMAP_PM
if (params->pm_iva_hd_counter == 0 && params->pm_iss_counter == 0) {
+ pr_debug("Release MPU wakeup latency\n");
retval = omap_pm_set_max_mpu_wakeup_lat(&pm_qos_handle,
IPU_PM_NO_MPU_LAT_CONSTRAINT);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error setting MPU cstr\n"
+ , __func__, __LINE__);
goto error;
+ }
}
#endif
return PM_SUCCESS;
@@ -2096,37 +1786,24 @@ error:
Release IVA SEQ0 on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_ivaseq0(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_ivaseq0(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release IVASEQ0\n");
-
- if (!params->pm_ivaseq0_counter)
+ if (!params->pm_ivaseq0_counter) {
+ pr_err("%s %d IVASEQ0 not requested\n", __func__, __LINE__);
goto error;
+ }
retval = ipu_pm_module_stop(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error releasing IVASEQ0\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
+ }
params->pm_ivaseq0_counter--;
+ pr_debug("Release IVASEQ0\n");
return PM_SUCCESS;
error:
@@ -2137,37 +1814,24 @@ error:
Release IVA SEQ1 on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_ivaseq1(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_ivaseq1(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release IVASEQ1\n");
-
- if (!params->pm_ivaseq1_counter)
+ if (!params->pm_ivaseq1_counter) {
+ pr_err("%s %d IVASEQ1 not requested\n", __func__, __LINE__);
goto error;
+ }
retval = ipu_pm_module_stop(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error releasing IVASEQ1\n", __func__, __LINE__);
return PM_UNSUPPORTED;
-
+ }
params->pm_ivaseq1_counter--;
+ pr_debug("Release IVASEQ1\n");
return PM_SUCCESS;
error:
@@ -2178,39 +1842,27 @@ error:
Release ISS on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_iss(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_iss(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- pr_info("Release ISS\n");
+ if (!params->pm_iss_counter) {
+ pr_err("%s %d ISS not requested\n", __func__, __LINE__);
+ goto error;
+ }
#if TMP_AUX_CLK_HACK
rcb_p->fill9 = AUX_CLK_MIN;
- ipu_pm_rel_aux_clk(proc_id, rcb_num);
+ ipu_pm_rel_aux_clk(handle, rcb_p, params);
#endif
- if (!params->pm_iss_counter)
- goto error;
retval = ipu_pm_module_stop(rcb_p->sub_type);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error releasing ISSs\n", __func__, __LINE__);
return PM_UNSUPPORTED;
+ }
/* FIXME:
* disable OPTFCLKEN_CTRLCLK for camera sensors
@@ -2221,14 +1873,19 @@ static inline int ipu_pm_rel_iss(int proc_id, u32 rcb_num)
cm_write_mod_reg(CAM_DISABLED,
OMAP4430_CM2_CAM_MOD,
OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET);
-
params->pm_iss_counter--;
+ pr_debug("Release ISS\n");
+
#ifdef CONFIG_OMAP_PM
if (params->pm_iva_hd_counter == 0 && params->pm_iss_counter == 0) {
+ pr_debug("Release MPU wakeup latency\n");
retval = omap_pm_set_max_mpu_wakeup_lat(&pm_qos_handle,
IPU_PM_NO_MPU_LAT_CONSTRAINT);
- if (retval)
+ if (retval) {
+ pr_err("%s %d Error setting MPU cstr\n"
+ , __func__, __LINE__);
goto error;
+ }
}
#endif
return PM_SUCCESS;
@@ -2240,167 +1897,65 @@ error:
Request a FDIF constraint on behalf of an IPU client
*
*/
-static inline int ipu_pm_req_cstr_fdif(int proc_id, u32 rcb_num)
+static inline int ipu_pm_req_cstr(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
int perf;
int lat;
int bw;
- u32 cstr_flags;
int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr FDIF:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
- perf);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Request latency Cstr FDIF:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_SELF,
- lat);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr FDIF:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Request a IPU constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_req_cstr_ipu(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
+ unsigned temp_rsrc;
u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
/* Get the configurable constraints */
cstr_flags = rcb_p->data[0];
/* TODO: call the baseport APIs */
if (cstr_flags & PM_CSTR_PERF_MASK) {
+ switch (rcb_p->sub_type) {
+ case MPU:
+ temp_rsrc = IPU_PM_MPU;
+ break;
+ case IPU:
+ case ISS:
+ case FDIF:
+ temp_rsrc = IPU_PM_CORE;
+ break;
+ default:
+ temp_rsrc = rcb_p->sub_type;
+ break;
+ }
perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr IPU:%d\n", perf);
+ pr_debug("Request perfomance Cstr %d\n", perf);
retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
+ temp_rsrc,
perf);
if (retval)
return PM_UNSUPPORTED;
}
if (cstr_flags & PM_CSTR_LAT_MASK) {
+ switch (rcb_p->sub_type) {
+ case MPU:
+ temp_rsrc = IPU_PM_MPU;
+ break;
+ case IPU:
+ case L3_BUS:
+ temp_rsrc = IPU_PM_CORE;
+ break;
+ case ISS:
+ case FDIF:
+ temp_rsrc = IPU_PM_SELF;
+ break;
+ default:
+ temp_rsrc = rcb_p->sub_type;
+ break;
+ }
lat = rcb_p->data[2];
- pr_info("Request latency Cstr IPU:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_CORE,
- lat);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr IPU:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Request a L3 Bus constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_req_cstr_l3_bus(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr L3 Bus:%d\n", perf);
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Request latency Cstr L3 Bus:%d\n", lat);
+ pr_debug("Request latency Cstr %d\n", lat);
retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_CORE,
+ temp_rsrc,
lat);
if (retval)
return PM_UNSUPPORTED;
@@ -2408,7 +1963,7 @@ static inline int ipu_pm_req_cstr_l3_bus(int proc_id, u32 rcb_num)
if (cstr_flags & PM_CSTR_BW_MASK) {
bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr L3 Bus:%d\n", bw);
+ pr_debug("Request bandwidth Cstr L3bus:%d\n", bw);
retval = ipu_pm_module_set_bandwidth(rcb_p->sub_type,
rcb_p->sub_type,
bw);
@@ -2420,362 +1975,70 @@ static inline int ipu_pm_req_cstr_l3_bus(int proc_id, u32 rcb_num)
}
/*
- Request an IVA HD constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_req_cstr_iva_hd(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr IVA HD:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- rcb_p->sub_type,
- perf);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Request latency Cstr IVA HD:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- rcb_p->sub_type,
- lat);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr IVA HD:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Request an ISS constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_req_cstr_iss(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* Call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr ISS:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
- perf);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Request latency Cstr ISS:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_SELF,
- lat);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr ISS:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Request an MPU constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_req_cstr_mpu(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Request perfomance Cstr MPU:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_MPU,
- perf);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Request latency Cstr MPU:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_MPU,
- lat);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Request bandwidth Cstr MPU:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-
-/*
- Release a FDIF constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_rel_cstr_fdif(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr FDIF:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
- NO_FREQ_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr FDIF:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_SELF,
- NO_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr FDIF:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Release a IPU constraint on behalf of an IPU client
+ Release a constraint on behalf of an IPU client
*
*/
-static inline int ipu_pm_rel_cstr_ipu(int proc_id, u32 rcb_num)
+static inline int ipu_pm_rel_cstr(struct ipu_pm_object *handle,
+ struct rcb_block *rcb_p,
+ struct ipu_pm_params *params)
{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
u32 cstr_flags;
+ unsigned temp_rsrc;
int retval;
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
/* Get the configurable constraints */
cstr_flags = rcb_p->data[0];
/* TODO: call the baseport APIs */
if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr IPU:%d\n", perf);
+ switch (rcb_p->sub_type) {
+ case MPU:
+ temp_rsrc = IPU_PM_MPU;
+ break;
+ case IPU:
+ case ISS:
+ case FDIF:
+ temp_rsrc = IPU_PM_CORE;
+ break;
+ default:
+ temp_rsrc = rcb_p->sub_type;
+ break;
+ }
+ pr_debug("Release perfomance Cstr\n");
retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
+ temp_rsrc,
NO_FREQ_CONSTRAINT);
if (retval)
return PM_UNSUPPORTED;
}
if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr IPU:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_CORE,
- NO_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr IPU:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Release a L3 Bus constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_rel_cstr_l3_bus(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr L3 Bus:%d\n", perf);
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr L3 Bus:%d\n", lat);
+ switch (rcb_p->sub_type) {
+ case MPU:
+ temp_rsrc = IPU_PM_MPU;
+ break;
+ case IPU:
+ case L3_BUS:
+ temp_rsrc = IPU_PM_CORE;
+ break;
+ case ISS:
+ case FDIF:
+ temp_rsrc = IPU_PM_SELF;
+ break;
+ default:
+ temp_rsrc = rcb_p->sub_type;
+ break;
+ }
+ pr_debug("Release latency Cstr\n");
retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_CORE,
+ temp_rsrc,
NO_LAT_CONSTRAINT);
if (retval)
return PM_UNSUPPORTED;
}
if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr L3 Bus:%d\n", bw);
+ pr_debug("Release bandwidth Cstr\n");
retval = ipu_pm_module_set_bandwidth(rcb_p->sub_type,
rcb_p->sub_type,
NO_BW_CONSTRAINT);
@@ -2787,189 +2050,6 @@ static inline int ipu_pm_rel_cstr_l3_bus(int proc_id, u32 rcb_num)
}
/*
- Release an IVA HD constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_rel_cstr_iva_hd(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr IVA HD:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- rcb_p->sub_type,
- NO_FREQ_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr IVA HD:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- rcb_p->sub_type,
- NO_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr IVA HD:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Release an ISS constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_rel_cstr_iss(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr ISS:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_CORE,
- NO_FREQ_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr ISS:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_SELF,
- NO_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr ISS:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
- Release an MPU constraint on behalf of an IPU client
- *
- */
-static inline int ipu_pm_rel_cstr_mpu(int proc_id, u32 rcb_num)
-{
- struct ipu_pm_object *handle;
- struct ipu_pm_params *params;
- struct rcb_block *rcb_p;
- int perf;
- int lat;
- int bw;
- u32 cstr_flags;
- int retval;
-
- /* get the handle to proper ipu pm object */
- handle = ipu_pm_get_handle(proc_id);
- if (WARN_ON(unlikely(handle == NULL)))
- return PM_NOT_INSTANTIATED;
-
- params = handle->params;
- if (WARN_ON(unlikely(params == NULL)))
- return PM_NOT_INSTANTIATED;
-
- /* Get pointer to the proper RCB */
- if (WARN_ON((rcb_num < RCB_MIN) || (rcb_num > RCB_MAX)))
- return PM_INVAL_RCB_NUM;
- rcb_p = (struct rcb_block *)&handle->rcb_table->rcb[rcb_num];
-
- /* Get the configurable constraints */
- cstr_flags = rcb_p->data[0];
-
- /* TODO: call the baseport APIs */
- if (cstr_flags & PM_CSTR_PERF_MASK) {
- perf = rcb_p->data[1];
- pr_info("Release perfomance Cstr MPU:%d\n", perf);
- retval = ipu_pm_module_set_rate(rcb_p->sub_type,
- IPU_PM_MPU,
- NO_FREQ_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_LAT_MASK) {
- lat = rcb_p->data[2];
- pr_info("Release latency Cstr MPU:%d\n", lat);
- retval = ipu_pm_module_set_latency(rcb_p->sub_type,
- IPU_PM_MPU,
- NO_LAT_CONSTRAINT);
- if (retval)
- return PM_UNSUPPORTED;
- }
-
- if (cstr_flags & PM_CSTR_BW_MASK) {
- bw = rcb_p->data[3];
- pr_info("Release bandwidth Cstr MPU:%d\n", bw);
- }
-
- return PM_SUCCESS;
-}
-
-/*
Function to set init parameters
*
*/
@@ -3050,7 +2130,7 @@ int ipu_pm_init_transport(struct ipu_pm_object *handle)
(notify_fn_notify_cbck)ipu_pm_callback,
(void *)NULL);
if (retval < 0)
- pr_err("Error sending notify event\n");
+ pr_err("Error unregistering notify event\n");
goto pm_register_fail;
}
return retval;
@@ -3194,8 +2274,7 @@ struct ipu_pm_object *ipu_pm_create(const struct ipu_pm_params *params)
retval = -EINVAL;
exit:
- pr_err("ipu_pm_create failed! "
- "status = 0x%x\n", retval);
+ pr_err("ipu_pm_create failed! status = 0x%x\n", retval);
return NULL;
}
@@ -3231,8 +2310,7 @@ void ipu_pm_delete(struct ipu_pm_object *handle)
kfree(handle);
return;
exit:
- pr_err("ipu_pm_delete is already NULL "
- "status = 0x%x\n", retval);
+ pr_err("ipu_pm_delete is already NULL status = 0x%x\n", retval);
}
/*
@@ -3345,8 +2423,14 @@ int ipu_pm_save_ctx(int proc_id)
if (retval)
goto error;
handle->rcb_table->state_flag |= SYS_PROC_DOWN;
- omap_mbox_save_ctx(ducati_mbox);
- iommu_save_ctx(ducati_iommu);
+ if (ducati_mbox)
+ omap_mbox_save_ctx(ducati_mbox);
+ else
+ pr_err("Not able to save mbox");
+ if (ducati_iommu)
+ iommu_save_ctx(ducati_iommu);
+ else
+ pr_err("Not able to save iommu");
} else
goto error;
exit:
@@ -3359,10 +2443,8 @@ error:
}
EXPORT_SYMBOL(ipu_pm_save_ctx);
-/*
- Function to check if a processor is shutdown
- if shutdown then restore context else return.
- *
+/* Function to check if a processor is shutdown
+ * if shutdown then restore context else return.
*/
int ipu_pm_restore_ctx(int proc_id)
{
@@ -3388,12 +2470,12 @@ int ipu_pm_restore_ctx(int proc_id)
*/
if (first_time) {
/* Enable/disable ipu hibernation*/
-#ifdef CONFIG_SYSLINK_DUCATI_PM
+#ifdef CONFIG_SYSLINK_IPU_SELF_HIBERNATION
handle->rcb_table->pm_flags.hibernateAllowed = 1;
#else
handle->rcb_table->pm_flags.hibernateAllowed = 0;
#endif
- pr_info("hibernateAllowed=%d\n",
+ pr_debug("hibernateAllowed=%d\n",
handle->rcb_table->pm_flags.hibernateAllowed);
first_time = 0;
cm_write_mod_reg(HW_AUTO,
@@ -3423,8 +2505,15 @@ int ipu_pm_restore_ctx(int proc_id)
if (!(ipu_pm_get_state(proc_id) & SYS_PROC_DOWN))
goto exit;
- omap_mbox_restore_ctx(ducati_mbox);
- iommu_restore_ctx(ducati_iommu);
+ if (ducati_mbox)
+ omap_mbox_restore_ctx(ducati_mbox);
+ else
+ pr_err("Not able to restore mbox");
+ if (ducati_iommu)
+ iommu_restore_ctx(ducati_iommu);
+ else
+ pr_err("Not able to restore iommu");
+
pr_info("Wakeup SYSM3\n");
retval = rproc_wakeup(sys_rproc);
cm_write_mod_reg(HW_AUTO,
@@ -3461,9 +2550,8 @@ error:
}
EXPORT_SYMBOL(ipu_pm_restore_ctx);
-/*
- Get the default configuration for the ipu_pm module.
- needed in ipu_pm_setup.
+/* Get the default configuration for the ipu_pm module.
+ * needed in ipu_pm_setup.
*/
void ipu_pm_get_config(struct ipu_pm_config *cfg)
{
@@ -3490,14 +2578,13 @@ exit:
}
EXPORT_SYMBOL(ipu_pm_get_config);
-/*
- Function to setup ipu pm object
- This function is called in platform_setup()
- This function will load the default configuration for ipu_pm
- in this function we can decide what is going to be controled
- by ipu_pm (DVFS, NOTIFICATIONS, ...) this configuration can
- can be changed on run-time.
- Also the workqueue is created and the local mutex
+/* Function to setup ipu pm object
+ * This function is called in platform_setup()
+ * This function will load the default configuration for ipu_pm
+ * in this function we can decide what is going to be controled
+ * by ipu_pm (DVFS, NOTIFICATIONS, ...) this configuration can
+ * can be changed on run-time.
+ * Also the workqueue is created and the local mutex
*/
int ipu_pm_setup(struct ipu_pm_config *cfg)
{
@@ -3531,9 +2618,12 @@ int ipu_pm_setup(struct ipu_pm_config *cfg)
ipu_pm_state.gate_handle = lock;
/* Create the wq for req/rel resources */
- ipu_wq = create_singlethread_workqueue("ipu_wq");
+ ipu_resources = create_singlethread_workqueue("ipu_resources");
+ ipu_clean_up = create_singlethread_workqueue("ipu_clean_up");
+ INIT_WORK(&clean, ipu_pm_clean_work);
/* No proc attached yet */
+ global_rcb = NULL;
pm_handle_appm3 = NULL;
pm_handle_sysm3 = NULL;
ducati_iommu = NULL;
@@ -3544,33 +2634,20 @@ int ipu_pm_setup(struct ipu_pm_config *cfg)
memcpy(&ipu_pm_state.cfg, cfg, sizeof(struct ipu_pm_config));
ipu_pm_state.is_setup = true;
- sysm3Idle = ioremap(SYSM3_IDLE_FLAG_PHY_ADDR, sizeof(int));
+ /* BIOS flags to know the state of IPU cores */
+ sysm3Idle = ioremap(IDLE_FLAG_PHY_ADDR, (sizeof(void) * 2));
if (!sysm3Idle) {
retval = -ENOMEM;
goto exit;
}
- appm3Idle = ioremap(APPM3_IDLE_FLAG_PHY_ADDR, sizeof(int));
-
+ appm3Idle = (void *)sysm3Idle + sizeof(void *);
if (!appm3Idle) {
retval = -ENOMEM;
+ iounmap(sysm3Idle);
goto exit;
}
- cm_ducati_clkstctrl = ioremap(CM_DUCATI_M3_CLKSTCTRL, sizeof(u32));
-
- if (!cm_ducati_clkstctrl) {
- retval = -ENOMEM;
- goto exit;
- }
-
- /*Hibernation disable. GPTIMER 3 only used for hibernation*/
- /*pm_gpt = omap_dm_timer_request_specific(GP_TIMER_3);
- if (pm_gpt == NULL)
- retval = -EINVAL;*/
- /* Reset hibernation from MPU flag */
- mpu_hib_ipu = 0;
-
return retval;
exit:
pr_err("ipu_pm_setup failed! retval = 0x%x", retval);
@@ -3578,11 +2655,10 @@ exit:
}
EXPORT_SYMBOL(ipu_pm_setup);
-/*
- Function to attach ipu pm object
- This function is called in ipc_attach()
- This function will create the object based on the remoteproc id
- It is also recieving the shared address pointer to use in rcb
+/* Function to attach ipu pm object
+ * This function is called in ipc_attach()
+ * This function will create the object based on the remoteproc id
+ * It is also recieving the shared address pointer to use in rcb
*/
int ipu_pm_attach(u16 remote_proc_id, void *shared_addr)
{
@@ -3590,64 +2666,76 @@ int ipu_pm_attach(u16 remote_proc_id, void *shared_addr)
struct ipu_pm_object *handle;
int retval = 0;
+ /* Since currently the share memory used by remote cores
+ * to manage the rcb (resources) is one, a global pointer
+ * can be used to access it.
+ */
+ if (!global_rcb)
+ global_rcb = (struct sms *)shared_addr;
+
ipu_pm_params_init(&params);
params.remote_proc_id = remote_proc_id;
- params.shared_addr = (void *)shared_addr;
+ params.shared_addr = (void *)global_rcb;
params.line_id = LINE_ID;
params.shared_addr_size = ipu_pm_mem_req(NULL);
handle = ipu_pm_create(&params);
-
if (WARN_ON(unlikely(handle == NULL))) {
retval = -EINVAL;
goto exit;
}
retval = ipu_pm_init_transport(handle);
-
- if (retval < 0)
+ if (retval)
goto exit;
/* FIXME the physical address should be calculated */
- pr_info("ipu_pm_attach at va0x%x pa0x9cf00400\n",
+ pr_debug("ipu_pm_attach at va0x%x pa0x9cf00400\n",
(unsigned int)shared_addr);
/* Get remote processor handle to save/restore */
if (remote_proc_id == SYS_M3 && IS_ERR_OR_NULL(sys_rproc)) {
+ pr_debug("requesting sys_rproc\n");
sys_rproc = omap_rproc_get("ducati-proc0");
if (sys_rproc == NULL) {
retval = PTR_ERR(sys_rproc);
+ sys_rproc = NULL;
pr_err("%s %d failed to get sysm3 handle",
__func__, __LINE__);
goto exit;
}
} else if (remote_proc_id == APP_M3 && IS_ERR_OR_NULL(app_rproc)) {
+ pr_debug("requesting app_rproc\n");
app_rproc = omap_rproc_get("ducati-proc1");
if (IS_ERR_OR_NULL(app_rproc)) {
retval = PTR_ERR(app_rproc);
+ app_rproc = NULL;
pr_err("%s %d failed to get appm3 handle",
__func__, __LINE__);
goto exit;
}
}
- /* Get iommu for save/restore */
if (IS_ERR_OR_NULL(ducati_iommu)) {
+ pr_debug("requesting ducati_iommu\n");
ducati_iommu = iommu_get("ducati");
if (IS_ERR_OR_NULL(ducati_iommu)) {
retval = PTR_ERR(ducati_iommu);
+ ducati_iommu = NULL;
pr_err("%s %d failed to get iommu handle",
__func__, __LINE__);
goto exit;
}
+ iommu_register_notifier(ducati_iommu,
+ &ipu_pm_notify_nb_iommu_ducati);
}
-
/* Get mailbox for save/restore */
- /* FIXME: This is not ready for Tesla */
if (IS_ERR_OR_NULL(ducati_mbox)) {
+ pr_debug("requesting ducati_mbox\n");
ducati_mbox = omap_mbox_get("mailbox-2", NULL);
if (IS_ERR_OR_NULL(ducati_mbox)) {
retval = PTR_ERR(ducati_mbox);
+ ducati_mbox = NULL;
pr_err("%s %d failed to get mailbox handle",
__func__, __LINE__);
goto exit;
@@ -3661,12 +2749,11 @@ exit:
}
EXPORT_SYMBOL(ipu_pm_attach);
-/*
- Function to deattach ipu pm object
- This function is called in ipc_detach()
- This function will delete the object based
- on the remoteproc id and unregister the notify
- events used by ipu_pm module
+/* Function to deattach ipu pm object
+ * This function is called in ipc_detach()
+ * This function will delete the object based
+ * on the remoteproc id and unregister the notify
+ * events used by ipu_pm module
*/
int ipu_pm_detach(u16 remote_proc_id)
{
@@ -3674,22 +2761,6 @@ int ipu_pm_detach(u16 remote_proc_id)
struct ipu_pm_params *params;
int retval = 0;
- iommu_put(ducati_iommu);
- ducati_iommu = NULL;
-
- if (remote_proc_id == SYS_M3) {
- omap_rproc_put(sys_rproc);
- sys_rproc = NULL;
- } else if (remote_proc_id == APP_M3) {
- omap_rproc_put(app_rproc);
- app_rproc = NULL;
- }
-
- if (!IS_ERR_OR_NULL(ducati_mbox)) {
- omap_mbox_put(ducati_mbox, NULL);
- ducati_mbox = NULL;
- }
-
/* get the handle to proper ipu pm object */
handle = ipu_pm_get_handle(remote_proc_id);
if (WARN_ON(unlikely(handle == NULL))) {
@@ -3703,6 +2774,20 @@ int ipu_pm_detach(u16 remote_proc_id)
goto exit;
}
+ /* When recovering clean_up was called, so wait for completion.
+ * If not make sure there is no resource pending.
+ */
+ if (recover) {
+ pr_debug("Recovering IPU\n");
+ while (!wait_for_completion_timeout(&ipu_clean_up_comp,
+ msecs_to_jiffies(params->timeout)))
+ pr_warn("%s: handle(s) still opened\n", __func__);
+ /* Get rid of any pending work */
+ flush_workqueue(ipu_resources);
+ } else {
+ ipu_pm_clean_res();
+ }
+
/* unregister the events used for ipu_pm */
retval = notify_unregister_event(
params->remote_proc_id,
@@ -3711,7 +2796,7 @@ int ipu_pm_detach(u16 remote_proc_id)
(notify_fn_notify_cbck)ipu_pm_callback,
(void *)NULL);
if (retval < 0) {
- pr_err("Error registering notify event\n");
+ pr_err("Error unregistering notify event\n");
goto exit;
}
retval = notify_unregister_event(
@@ -3721,12 +2806,47 @@ int ipu_pm_detach(u16 remote_proc_id)
(notify_fn_notify_cbck)ipu_pm_notify_callback,
(void *)NULL);
if (retval < 0) {
- pr_err("Error registering notify event\n");
+ pr_err("Error unregistering notify event\n");
goto exit;
}
- /* Reset the state_flag */
- handle->rcb_table->state_flag = 0;
+ /* Put remote processor handle to save/restore */
+ if (remote_proc_id == SYS_M3 && !IS_ERR_OR_NULL(sys_rproc)) {
+ pr_debug("releasing sys_rproc\n");
+ omap_rproc_put(sys_rproc);
+ sys_rproc = NULL;
+ } else if (remote_proc_id == APP_M3 && !IS_ERR_OR_NULL(app_rproc)) {
+ pr_debug("releasing app_rproc\n");
+ omap_rproc_put(app_rproc);
+ app_rproc = NULL;
+ }
+
+ if (IS_ERR_OR_NULL(sys_rproc) && IS_ERR_OR_NULL(app_rproc)) {
+ if (!IS_ERR_OR_NULL(ducati_iommu)) {
+ /*
+ * Restore iommu to allow process's iommu cleanup
+ * after ipu_pm is shutdown
+ */
+ if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
+ iommu_restore_ctx(ducati_iommu);
+ iommu_unregister_notifier(ducati_iommu,
+ &ipu_pm_notify_nb_iommu_ducati);
+ pr_debug("releasing ducati_iommu\n");
+ iommu_put(ducati_iommu);
+ ducati_iommu = NULL;
+ }
+ /* Get mailbox for save/restore */
+ if (!IS_ERR_OR_NULL(ducati_mbox)) {
+ pr_debug("releasing ducati_mbox\n");
+ omap_mbox_put(ducati_mbox, NULL);
+ ducati_mbox = NULL;
+ }
+ /* Reset the state_flag */
+ handle->rcb_table->state_flag = 0;
+ if (recover)
+ recover = false;
+ global_rcb = NULL;
+ }
/* Deleting the handle based on remote_proc_id */
ipu_pm_delete(handle);
@@ -3738,10 +2858,9 @@ exit:
}
EXPORT_SYMBOL(ipu_pm_detach);
-/*
- Function to destroy ipu_pm module
- this function will destroy the structs
- created to set the configuration
+/* Function to destroy ipu_pm module
+ * this function will destroy the structs
+ * created to set the configuration
*/
int ipu_pm_destroy(void)
{
@@ -3776,12 +2895,14 @@ int ipu_pm_destroy(void)
mutex_unlock(lock);
kfree(lock);
/* Delete the wq for req/rel resources */
- destroy_workqueue(ipu_wq);
+ destroy_workqueue(ipu_resources);
+ destroy_workqueue(ipu_clean_up);
first_time = 1;
-
- /*Hibernation disable. GPTIMER 3 only used for hibernation*/
- /*omap_dm_timer_free(pm_gpt);*/
+ iounmap(sysm3Idle);
+ sysm3Idle = NULL;
+ appm3Idle = NULL;
+ global_rcb = NULL;
return retval;
exit:
diff --git a/drivers/dsp/syslink/ipu_pm/ipu_pm.h b/drivers/dsp/syslink/ipu_pm/ipu_pm.h
index b2a5ad2a5ed..42021d5e7f1 100644
--- a/drivers/dsp/syslink/ipu_pm/ipu_pm.h
+++ b/drivers/dsp/syslink/ipu_pm/ipu_pm.h
@@ -92,6 +92,11 @@
#include <linux/kfifo.h>
/* Pm notify ducati driver */
+#define A9 3
+#define SYS_M3 2
+#define APP_M3 1
+#define TESLA 0
+
/* Suspend/resume/other... */
#define NUMBER_PM_EVENTS 4
@@ -129,7 +134,7 @@
#define GP_TIMER_4 4
#define GP_TIMER_9 9
#define GP_TIMER_11 11
-#define NUM_IPU_TIMERS 4
+#define NUM_IPU_TIMERS 2
#define I2C_SL_INVAL -1
#define I2C_1_SL 0
@@ -138,7 +143,14 @@
#define I2C_4_SL 3
#define RCB_MIN 1
-#define RCB_MAX 33
+#define RCB_MAX 32
+/* In some cases remote proc may need rcb's for internal
+ * use without requesting any resource, those need to be
+ * set as 0 in this mask in order to not release it.
+ * i.e. Ducati is using 0 to 4 (b00000011) rcb's for internal purpose
+ * without requestig any resource.
+ */
+#define RESERVED_RCBS 0xFFFFFFFC
#define PM_RESOURCE 2
#define PM_NOTIFICATION 3
@@ -182,7 +194,6 @@
#define CAM_ENABLED 0x2
#define CAM_DISABLED 0x0
-
/* Macro to set a val in a bitfield*/
#define MASK_SET_FIELD(tmp, bitfield, val) { \
tmp |= \
@@ -204,7 +215,6 @@
#define AUX_CLK_REG_REQ(clk) (SCRM_BASE + (SCRM_BASE_AUX_CLK_REQ + \
(SCRM_AUX_CLK_OFFSET * clk)))
-
/*
* IPU_PM_MODULEID
* Unique module ID
@@ -281,8 +291,19 @@ enum pm_regulator_action{PM_SET_VOLTAGE,
PM_GET_VOLTAGE
};
+/* Resources id should start at zero,
+ * should be always consecutive and should match
+ * IPU side.
+ */
+#define PM_FIRST_RES 0
+
+/* Resources that can handle cstrs should be
+ * consecutive and first in the res_type enum
+ */
+#define PM_NUM_RES_W_CSTRS 10
+
enum res_type{
- FDIF,
+ FDIF = PM_FIRST_RES,
IPU,
SYSM3,
APPM3,
@@ -292,29 +313,30 @@ enum res_type{
IVASEQ1,
L3_BUS,
MPU,
+ /* SL2IF, */
+ /* DSP, */
SDMA,
GP_TIMER,
GP_IO,
I2C,
REGULATOR,
AUX_CLK,
+ PM_NUM_RES
};
-/* Events can start at any number but
+/* Events should start at zero and
* should be always consecutive
*/
#define PM_FIRST_EVENT 0
-enum pm_event_type{PM_SUSPEND = PM_FIRST_EVENT,
+enum pm_event_type{
+ PM_SUSPEND = PM_FIRST_EVENT,
PM_RESUME,
PM_PID_DEATH,
- PM_HIBERNATE
+ PM_HIBERNATE,
+ PM_LAST_EVENT
};
-#define PM_LAST_EVENT ((sizeof(enum pm_event_type) / sizeof(void)) \
- + PM_FIRST_EVENT\
- - 1)
-
struct rcb_message {
unsigned rcb_flag:1;
unsigned rcb_num:6;
@@ -454,7 +476,7 @@ void ipu_pm_notify_callback(u16 proc_id, u16 line_id, u32 event_id,
uint *arg, u32 payload);
/* Function for send PM Notifications */
-int ipu_pm_notifications(enum pm_event_type event_type, void *data);
+int ipu_pm_notifications(int proc_id, enum pm_event_type event, void *data);
/* Function to set init parameters */
void ipu_pm_params_init(struct ipu_pm_params *params);