ARM: tegra: clock: Enumerate iso-exempt shared ceiling mode
Alex Frid [Thu, 2 May 2013 07:06:42 +0000 (00:06 -0700)]
Added to enumeration of shared user modes SHARED_CEILING_BUT_ISO mode
to distinguish shared ceiling users that can not throttle iso bw users
(current SHARED_CEILING mode users caps all users including iso).

For now, SHARED_CEILING_BUT_ISO mode is not applied to any user, and
no iso exemption mechanism is implemented.

Bug 1001227

Change-Id: I558d965ecaa81b82ef94a3b6b2fbaec40b36b59b
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/224969
Reviewed-by: Mrutyunjay Sawant <msawant@nvidia.com>
Tested-by: Mrutyunjay Sawant <msawant@nvidia.com>

arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/clock.h
arch/arm/mach-tegra/tegra11_clocks.c
arch/arm/mach-tegra/tegra14_clocks.c

index 591353e..eb7a282 100644 (file)
@@ -1280,11 +1280,14 @@ static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
                35 - level * 3, c->name,
                c->cansleep ? '$' : ' ',
                state, c->refcnt, div, rate);
-       if (c->parent && !list_empty(&c->parent->shared_bus_list))
+       if (c->parent && !list_empty(&c->parent->shared_bus_list)) {
+               enum shared_bus_users_mode mode = c->u.shared_bus_user.mode;
                seq_printf(s, " (%lu%s)", c->u.shared_bus_user.rate,
-                          c->u.shared_bus_user.mode == SHARED_CEILING ? "^" :
-                          c->u.shared_bus_user.mode == SHARED_ISO_BW ? "+" :
-                          c->u.shared_bus_user.mode == SHARED_BW ? "+" : "");
+                          mode == SHARED_CEILING_BUT_ISO ? "^" :
+                          mode == SHARED_CEILING ? "^" :
+                          mode == SHARED_ISO_BW ? "+" :
+                          mode == SHARED_BW ? "+" : "");
+       }
        seq_printf(s, "\n");
 
        if (c->dvfs)
index c45660e..e1f7da8 100644 (file)
@@ -148,6 +148,7 @@ enum shared_bus_users_mode {
        SHARED_AUTO,
        SHARED_OVERRIDE,
        SHARED_ISO_BW,
+       SHARED_CEILING_BUT_ISO,
 };
 
 struct clk {
index e83095b..7622fad 100644 (file)
@@ -5085,6 +5085,7 @@ static unsigned long tegra11_clk_shared_bus_update(struct clk *bus,
        unsigned long bw = 0;
        unsigned long iso_bw = 0;
        unsigned long ceiling = bus->max_rate;
+       unsigned long ceiling_but_iso = bus->max_rate;
        u32 usage_flags = 0;
 
        list_for_each_entry(c, &bus->shared_bus_list,
@@ -5096,7 +5097,8 @@ static unsigned long tegra11_clk_shared_bus_update(struct clk *bus,
                 * bus just because ceiling is set.
                 */
                if (c->u.shared_bus_user.enabled ||
-                   (c->u.shared_bus_user.mode == SHARED_CEILING)) {
+                   (c->u.shared_bus_user.mode == SHARED_CEILING) ||
+                   (c->u.shared_bus_user.mode == SHARED_CEILING_BUT_ISO)) {
                        unsigned long request_rate = c->u.shared_bus_user.rate *
                                (c->div ? : 1);
                        usage_flags |= c->u.shared_bus_user.usage_flag;
@@ -5112,6 +5114,10 @@ static unsigned long tegra11_clk_shared_bus_update(struct clk *bus,
                                if (bw > bus->max_rate)
                                        bw = bus->max_rate;
                                break;
+                       case SHARED_CEILING_BUT_ISO:
+                               ceiling_but_iso =
+                                       min(request_rate, ceiling_but_iso);
+                               break;
                        case SHARED_CEILING:
                                ceiling = min(request_rate, ceiling);
                                break;
@@ -5146,6 +5152,7 @@ static unsigned long tegra11_clk_shared_bus_update(struct clk *bus,
                        bw, iso_bw, bus->max_rate, usage_flags);
 
        rate = override_rate ? : max(rate, bw);
+       ceiling = min(ceiling, ceiling_but_iso);
        ceiling = override_rate ? bus->max_rate : ceiling;
 
        if (bus_top && bus_slow && rate_cap) {
@@ -5194,7 +5201,8 @@ static void tegra_clk_shared_bus_user_init(struct clk *c)
        c->state = OFF;
        c->set = true;
 
-       if (c->u.shared_bus_user.mode == SHARED_CEILING) {
+       if ((c->u.shared_bus_user.mode == SHARED_CEILING) ||
+           (c->u.shared_bus_user.mode == SHARED_CEILING_BUT_ISO)) {
                c->state = ON;
                c->refcnt++;
        }
index cf132e0..66a5177 100644 (file)
@@ -4577,6 +4577,7 @@ static unsigned long tegra14_clk_shared_bus_update(struct clk *bus,
        unsigned long bw = 0;
        unsigned long iso_bw = 0;
        unsigned long ceiling = bus->max_rate;
+       unsigned long ceiling_but_iso = bus->max_rate;
        u32 usage_flags = 0;
 
        list_for_each_entry(c, &bus->shared_bus_list,
@@ -4589,7 +4590,8 @@ static unsigned long tegra14_clk_shared_bus_update(struct clk *bus,
                 * to propagate flat max request.
                 */
                if (c->u.shared_bus_user.enabled ||
-                   (c->u.shared_bus_user.mode == SHARED_CEILING)) {
+                   (c->u.shared_bus_user.mode == SHARED_CEILING) ||
+                   (c->u.shared_bus_user.mode == SHARED_CEILING_BUT_ISO)) {
                        unsigned long request_rate = c->u.shared_bus_user.rate;
                        if (!(c->flags & DIV_BUS))
                                rate *= c->div ? : 1;
@@ -4606,6 +4608,10 @@ static unsigned long tegra14_clk_shared_bus_update(struct clk *bus,
                                if (bw > bus->max_rate)
                                        bw = bus->max_rate;
                                break;
+                       case SHARED_CEILING_BUT_ISO:
+                               ceiling_but_iso =
+                                       min(request_rate, ceiling_but_iso);
+                               break;
                        case SHARED_CEILING:
                                ceiling = min(request_rate, ceiling);
                                break;
@@ -4640,6 +4646,7 @@ static unsigned long tegra14_clk_shared_bus_update(struct clk *bus,
                        bw, iso_bw, bus->max_rate, usage_flags);
 
        rate = override_rate ? : max(rate, bw);
+       ceiling = min(ceiling, ceiling_but_iso);
        ceiling = override_rate ? bus->max_rate : ceiling;
        bus->override_rate = override_rate;
 
@@ -4689,7 +4696,8 @@ static void tegra_clk_shared_bus_user_init(struct clk *c)
        c->state = OFF;
        c->set = true;
 
-       if (c->u.shared_bus_user.mode == SHARED_CEILING) {
+       if ((c->u.shared_bus_user.mode == SHARED_CEILING) ||
+           (c->u.shared_bus_user.mode == SHARED_CEILING_BUT_ISO)) {
                c->state = ON;
                c->refcnt++;
        }