@@ -18,6 +18,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/opp.h>
+#include <linux/pm_qos_params.h>
/*
* agent_id values for use with omap_pm_set_min_bus_tput():
@@ -70,44 +71,6 @@ void omap_pm_if_exit(void);
* Device-driver-originated constraints (via board-*.c files, platform_data)
*/
-
-/**
- * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
- * @t: maximum MPU wakeup latency in microseconds
- *
- * Request that the maximum interrupt latency for the MPU to be no
- * greater than @t microseconds. "Interrupt latency" in this case is
- * defined as the elapsed time from the occurrence of a hardware or
- * timer interrupt to the time when the device driver's interrupt
- * service routine has been entered by the MPU.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the MPU powerdomain into, and
- * possibly the CORE powerdomain as well, since interrupt handling
- * code currently runs from SDRAM. Advanced PM or board*.c code may
- * also configure interrupt controller priorities, OCP bus priorities,
- * CPU speed(s), etc.
- *
- * This function will not affect device wakeup latency, e.g., time
- * elapsed from when a device driver enables a hardware device with
- * clk_enable(), to when the device is ready for register access or
- * other use. To control this device wakeup latency, use
- * omap_pm_set_max_dev_wakeup_lat()
- *
- * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
- * previous t value. To remove the latency target for the MPU, call
- * with t = -1.
- *
- * XXX This constraint will be deprecated soon in favor of the more
- * general omap_pm_set_max_dev_wakeup_lat()
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
-
-
/**
* omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
* @dev: struct device * requesting the constraint
@@ -139,7 +102,6 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
*/
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
-
/**
* omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
* @req_dev: struct device * requesting the constraint, or NULL if none
@@ -169,10 +131,53 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
long t);
+/**
+ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
+ * @qos_request: handle for the constraint
+ * @t: maximum MPU wakeup latency in microseconds
+ *
+ * Request that the maximum interrupt latency for the MPU to be no
+ * greater than @t microseconds. "Interrupt latency" in this case is
+ * defined as the elapsed time from the occurrence of a hardware or
+ * timer interrupt to the time when the device driver's interrupt
+ * service routine has been entered by the MPU.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the MPU powerdomain into, and
+ * possibly the CORE powerdomain as well, since interrupt handling
+ * code currently runs from SDRAM. Advanced PM or board*.c code may
+ * also configure interrupt controller priorities, OCP bus priorities,
+ * CPU speed(s), etc.
+ *
+ * This function will not affect device wakeup latency, e.g., time
+ * elapsed from when a device driver enables a hardware device with
+ * clk_enable(), to when the device is ready for register access or
+ * other use. To control this device wakeup latency, use
+ * omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
+ * previous t value. To remove the latency target for the MPU, call
+ * with t = -1.
+ *
+ * Notes about the qos_request handle:
+ * - the caller has to first allocate the pm_qos_request_list struct and
+ * then call pm_qos_add_request(qos_request, PM_QOS_CPU_DMA_LATENCY,
+ * PM_QOS_DEFAULT_VALUE) in order to initialize the constraint struct.
+ * - the handle is stored by the caller for later use (update or removal of
+ * the constraint).
+ *
+ * XXX This constraint will be deprecated soon in favor of the more
+ * general omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list *qos_request,
+ long t);
/**
* omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
+ * @qos_request: handle for the constraint
* @t: maximum DMA transfer start latency in microseconds
*
* Request that the maximum system DMA transfer start latency for this
@@ -194,11 +199,18 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
* value for this device. To remove the maximum DMA latency for this
* device, call with t = -1.
*
+ * Notes about the qos_request handle:
+ * - the caller has to first allocate the pm_qos_request_list struct and
+ * then call pm_qos_add_request(qos_request, PM_QOS_CPU_DMA_LATENCY,
+ * PM_QOS_DEFAULT_VALUE) in order to initialize the constraint struct.
+ * - the handle is stored by the caller for later use (update or removal of
+ * the constraint).
+ *
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list *qos_request,
+ long t);
/**
* omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
@@ -73,6 +73,7 @@ struct omap_device {
s8 pm_lat_level;
u8 hwmods_cnt;
u8 _state;
+ struct pm_qos_request_list *pm_qos_request;
};
/* Device driver interface (call via platform_data fn ptrs) */
@@ -28,38 +28,10 @@
static bool off_mode_enabled;
static u32 dummy_context_loss_counter;
+
/*
* Device-driver-originated constraints (via board-*.c files)
*/
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (t == -1)
- pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the MPU to a
- * powerdomain, then go through the list of current max lat
- * constraints on the MPU and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
@@ -118,33 +90,47 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
return 0;
}
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list *qos_request,
+ long t)
{
- if (!dev || t < -1) {
+ /*
+ * The current state is: use PM QOS with the PM_QOS_CPU_DMA_LATENCY
+ * as pm_qos class. PM QOS records and sorts the constraints.
+ * Cpuidle is using PM QOS to retrieve the strongest constraint
+ * from the list, then changes the MPU and CORE power domains
+ * states to honor the constraint.
+ * Note that only MPU and CORE power domains states are affected.
+ *
+ * This shall use omap_pm_set_max_dev_wakeup_lat with the MPU
+ * as the device to put the constraints on
+ */
+ if (!qos_request || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
};
- if (t == -1)
- pr_debug("OMAP PM: remove max DMA latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max DMA latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
+ if (t == -1) {
+ pm_qos_update_request(qos_request, PM_QOS_DEFAULT_VALUE);
+ pr_debug("OMAP PM: remove max MPU wakeup latency "
+ "constraint\n");
+ } else {
+ pm_qos_update_request(qos_request, t);
+ pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+ "t=%ld us\n", t);
+ }
+
+ return 0;
+}
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list *qos_request, long t)
+{
/*
- * For current Linux PM QOS params, this code should scan the
- * list of maximum CPU and DMA latencies and select the
- * smallest, then set cpu_dma_latency pm_qos_param
- * accordingly.
- *
- * For future Linux PM QOS params, with separate CPU and DMA
- * latency params, this code should just set the dma_latency param.
+ * Currently identical to omap_pm_set_max_mpu_wakeup_lat.
*
- * TI CDP code can call constraint_set here.
+ * This shall use omap_pm_set_max_dev_wakeup_lat with the SDMA
+ * as device to put the constraints on
*/
-
- return 0;
+ return omap_pm_set_max_mpu_wakeup_lat(qos_request, t);
}
int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
@@ -29,38 +29,10 @@
static bool off_mode_enabled;
static u32 dummy_context_loss_counter;
+
/*
* Device-driver-originated constraints (via board-*.c files)
*/
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- };
-
- if (t == -1)
- pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
- "dev %s\n", dev_name(dev));
- else
- pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the MPU to a
- * powerdomain, then go through the list of current max lat
- * constraints on the MPU and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
@@ -119,19 +91,49 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
return 0;
}
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
+int omap_pm_set_max_mpu_wakeup_lat(struct pm_qos_request_list *qos_request,
+ long t)
{
- if (!dev || t < -1) {
+ if (!qos_request || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
};
if (t == -1)
- pr_debug("OMAP PM: remove max DMA latency constraint: "
- "dev %s\n", dev_name(dev));
+ pr_debug("OMAP PM: remove max MPU wakeup latency "
+ "constraint\n");
+ else
+ pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+ "t=%ld us\n", t);
+
+ /*
+ * For current Linux, this needs to map the MPU to a
+ * powerdomain, then go through the list of current max lat
+ * constraints on the MPU and find the smallest. If
+ * the latency constraint has changed, the code should
+ * recompute the state to enter for the next powerdomain
+ * state.
+ *
+ * TI CDP code can call constraint_set here.
+ */
+
+ return 0;
+}
+
+int omap_pm_set_max_sdma_lat(struct pm_qos_request_list *qos_request,
+ long t)
+{
+ if (!qos_request || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max DMA latency "
+ "constraint\n");
else
pr_debug("OMAP PM: add max DMA latency constraint: "
- "dev %s, t = %ld usec\n", dev_name(dev), t);
+ "t=%ld us\n", t);
/*
* For current Linux PM QOS params, this code should scan the