diff options
author | Guillaume Aubertin <g-aubertin@ti.com> | 2012-08-09 09:10:10 +0200 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-09-07 13:07:08 +0800 |
commit | ee03b914dba2d18e404ae97de5299d471ba7e78c (patch) | |
tree | 3bff7c87f481755714238160f9e6b88cb96da447 /drivers | |
parent | 8e00036db8b5782567286c03a66a095f654fd50a (diff) |
dce: pm_runtime implementation
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/omapdce/dce.c | 61 | ||||
-rw-r--r-- | drivers/staging/omapdce/omap_dce.h | 5 |
2 files changed, 65 insertions, 1 deletions
diff --git a/drivers/staging/omapdce/dce.c b/drivers/staging/omapdce/dce.c index 6b122f8cb656..6453e16e2639 100644 --- a/drivers/staging/omapdce/dce.c +++ b/drivers/staging/omapdce/dce.c @@ -20,6 +20,9 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/rpmsg.h> +#include <linux/pm_runtime.h> +#include <plat/omap-pm.h> +#include <plat/clock.h> #include "../omapdrm/omap_drm.h" #include "../omapdrm/omap_drv.h" @@ -116,6 +119,34 @@ static atomic_t next_req_id = ATOMIC_INIT(0); static DECLARE_WAIT_QUEUE_HEAD(wq); static DEFINE_MUTEX(lock); // TODO probably more locking needed.. +/* PM runtime implementation */ +/* PM dependencies of each "device" is defined by its position in the array */ +/* get_sync : iva -> sl2if -> seq0 -> seq1 */ +/* put_sync: seq1 -> seq0 -> sl2if -> iva */ + +#define NB_PM_DEVICES 4 + +struct dce_pm_device dce_pm_device_list[NB_PM_DEVICES] = { + {.name = "iva.0", .dev = NULL}, + {.name = "sl2if", .dev = NULL}, + {.name = "iva_seq0.0", .dev = NULL}, + {.name = "iva_seq1.0", .dev = NULL} +}; + +static void dce_pm_runtime_get_sync(void) +{ + int i; + for (i = 0; i < NB_PM_DEVICES; i++) + pm_runtime_get_sync(dce_pm_device_list[i].dev); +} + +static void dce_pm_runtime_put_sync(void) +{ + int i; + for (i = (NB_PM_DEVICES - 1); i >= 0; i--) + pm_runtime_put_sync(dce_pm_device_list[i].dev); +} + /* * Utils: */ @@ -1160,6 +1191,18 @@ static struct omap_drm_plugin plugin = { * RPMSG API: */ +static int dce_pm_find_device(struct dce_pm_device *pm_device) +{ + int ret = 0; + + pm_device->dev = bus_find_device_by_name(&platform_bus_type, + NULL, pm_device->name); + if (!pm_device->dev) + ret = -1; + + return ret; +} + static int rpmsg_probe(struct rpmsg_channel *_rpdev) { struct dce_rpc_connect_req req = { @@ -1167,11 +1210,26 @@ static int rpmsg_probe(struct rpmsg_channel *_rpdev) .chipset_id = GET_OMAP_TYPE, .debug = drm_debug ? 1 : 3, }; - int ret; + int ret, i; DBG(""); rpdev = _rpdev; + /* pm_runtime initialisation */ + for (i = 0 ;i < NB_PM_DEVICES; i++) { + ret = dce_pm_find_device(&dce_pm_device_list[i]); + if (ret) { + DBG("couldn't find pm device %s \n", + dce_pm_device_list[i].name); + return ret; + } + + if (!pm_runtime_enabled(dce_pm_device_list[i].dev)) + pm_runtime_enable(dce_pm_device_list[i].dev); + } + + dce_pm_runtime_get_sync(); + /* send connect msg: */ ret = rpsend(NULL, NULL, hdr(&req), sizeof(req)); if (ret) { @@ -1186,6 +1244,7 @@ static void __devexit rpmsg_remove(struct rpmsg_channel *_rpdev) { DBG(""); omap_drm_unregister_plugin(&plugin); + dce_pm_runtime_put_sync(); rpdev = NULL; } diff --git a/drivers/staging/omapdce/omap_dce.h b/drivers/staging/omapdce/omap_dce.h index 5853793762ce..d4fa53803654 100644 --- a/drivers/staging/omapdce/omap_dce.h +++ b/drivers/staging/omapdce/omap_dce.h @@ -48,6 +48,11 @@ * response from coprocessor rather than starting a new request. */ +struct dce_pm_device { + char name[32]; + struct device *dev; +}; + enum omap_dce_codec { OMAP_DCE_VIDENC2 = 1, OMAP_DCE_VIDDEC3 = 2, |