diff options
-rw-r--r-- | arch/arm/plat-omap/include/plat/rpres.h | 13 | ||||
-rw-r--r-- | drivers/remoteproc/rpres.c | 48 | ||||
-rw-r--r-- | drivers/remoteproc/rpres_dev.c | 40 |
3 files changed, 96 insertions, 5 deletions
diff --git a/arch/arm/plat-omap/include/plat/rpres.h b/arch/arm/plat-omap/include/plat/rpres.h index c80514b..a1e8c7b 100644 --- a/arch/arm/plat-omap/include/plat/rpres.h +++ b/arch/arm/plat-omap/include/plat/rpres.h @@ -14,6 +14,12 @@ #ifndef _PLAT_OMAP_RPRES_H #define _PLAT_OMAP_RPRES_H +enum rpres_constraint { + RPRES_CONSTRAINT_SCALE, + RPRES_CONSTRAINT_LATENCY, + RPRES_CONSTRAINT_BANDWIDTH, +}; + enum { RPRES_INACTIVE, RPRES_ACTIVE, @@ -22,9 +28,9 @@ enum { struct rpres_ops { int (*start)(struct platform_device *pdev); int (*stop)(struct platform_device *pdev); - /* no PM for the momment */ - //int (*set_constraint)(struct device *dev, void *arg); - //int (*remove_constraint)(struct device *dev); + int (*set_lat)(struct platform_device *pdev, long v); + int (*set_bw)(struct platform_device *pdev, long v); + int (*scale_dev)(struct platform_device *pdev, long v); }; struct rpres_platform_data { @@ -46,4 +52,5 @@ struct rpres { struct rpres *rpres_get(const char *); void rpres_put(struct rpres *); +int rpres_set_constraints(struct rpres *, enum rpres_constraint type, long val); #endif /* _PLAT_OMAP_RPRES_H */ diff --git a/drivers/remoteproc/rpres.c b/drivers/remoteproc/rpres.c index 522b1ce..c52e6a1 100644 --- a/drivers/remoteproc/rpres.c +++ b/drivers/remoteproc/rpres.c @@ -75,6 +75,54 @@ void rpres_put(struct rpres *obj) } EXPORT_SYMBOL(rpres_put); +int rpres_set_constraints(struct rpres *obj, enum rpres_constraint type, long val) +{ + int ret; + struct rpres_platform_data *pdata = obj->pdev->dev.platform_data; + struct platform_device *pdev = obj->pdev; + static const char *cname[] = {"scale", "latency", "bandwidth"}; + int (*func)(struct platform_device *, long); + + switch (type) { + case RPRES_CONSTRAINT_SCALE: + func = pdata->ops->scale_dev; + break; + case RPRES_CONSTRAINT_LATENCY: + func = pdata->ops->set_lat; + break; + case RPRES_CONSTRAINT_BANDWIDTH: + func = pdata->ops->set_bw; + break; + default: + dev_err(&pdev->dev, "%s: invalid constraint %d\n", + __func__, type); + return -EINVAL; + } + + if (!func) { + dev_err(&pdev->dev, "%s: No %s constraint\n", + __func__, cname[type]); + return -EINVAL; + } + + mutex_lock(&obj->lock); + if (obj->state == RPRES_INACTIVE) { + mutex_unlock(&obj->lock); + pr_err("%s: resource inactive\n", __func__); + return -EPERM; + } + + dev_dbg(&pdev->dev, "set %s constraint %ld\n", cname[type], val); + ret = func(pdev, val); + if (ret) + dev_err(&pdev->dev, "%s: error setting constraint %s\n", + __func__, cname[type]); + mutex_unlock(&obj->lock); + + return ret; +} +EXPORT_SYMBOL(rpres_set_constraints); + static int rpres_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; diff --git a/drivers/remoteproc/rpres_dev.c b/drivers/remoteproc/rpres_dev.c index c5d770c..782e1b7 100644 --- a/drivers/remoteproc/rpres_dev.c +++ b/drivers/remoteproc/rpres_dev.c @@ -19,6 +19,10 @@ #include <plat/omap_hwmod.h> #include <plat/clock.h> #include <plat/rpres.h> +#include <linux/pm_qos_params.h> +#include <plat/common.h> +#include <plat/omap-pm.h> +#include "../../arch/arm/mach-omap2/dvfs.h" static void _enable_optional_clocks(struct omap_hwmod *oh) { @@ -68,9 +72,41 @@ static int rpres_iss_shutdown(struct platform_device *pdev) return ret; } +static int rpres_scale_ivahd(struct platform_device *pdev, long val) +{ + return omap_device_scale(&pdev->dev, &pdev->dev, val); +} + +static int rpres_set_dev_lat(struct platform_device *pdev, long val) +{ + return omap_pm_set_max_dev_wakeup_lat(&pdev->dev, &pdev->dev, val); +} + +static int rpres_set_l3_bw(struct platform_device *pdev, long val) +{ + return omap_pm_set_min_bus_tput(&pdev->dev, OCP_INITIATOR_AGENT, val); +} + static struct rpres_ops iss_ops = { .start = rpres_iss_enable, .stop = rpres_iss_shutdown, + .set_lat = rpres_set_dev_lat, + .set_bw = rpres_set_l3_bw, +}; + +static struct rpres_ops ivahd_ops = { + .start = omap_device_enable, + .stop = omap_device_shutdown, + .set_lat = rpres_set_dev_lat, + .set_bw = rpres_set_l3_bw, + .scale_dev = rpres_scale_ivahd, +}; + +static struct rpres_ops fdif_ops = { + .start = omap_device_enable, + .stop = omap_device_shutdown, + .set_lat = rpres_set_dev_lat, + .set_bw = rpres_set_l3_bw, }; static struct rpres_ops gen_ops = { @@ -90,7 +126,7 @@ static struct rpres_platform_data rpres_data[] = { { .name = "rpres_iva", .oh_name = "iva", - .ops = &gen_ops, + .ops = &ivahd_ops, }, { .name = "rpres_iva_seq0", @@ -111,7 +147,7 @@ static struct rpres_platform_data rpres_data[] = { { .name = "rpres_fdif", .oh_name = "fdif", - .ops = &gen_ops, + .ops = &fdif_ops, }, { .name = "rpres_sl2if", |