diff options
author | Alex Frid <afrid@nvidia.com> | 2011-06-24 16:22:26 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-06 16:21:28 -0700 |
commit | 825d451873ac741292f30aaa969e96fbdd37b571 (patch) | |
tree | de00a384e9367fd23c6acb2636577df65ca0b32f | |
parent | 8d1ac5a5b001e27d77e2e8c979e08b214e298075 (diff) |
ARM: tegra: clock: Expand Tegra3 shared bus modes
Implemented 3 different modes of combining rate requests from shared
bus users :
- SHARED_FLOOR: cumulative floor request is determined by maximum rate
among all users in this mode and minimum bus rate
- SHARED_BW: cumulative bandwidth request is determined by adding rates
of all users in this mode together
- SHRED_CEILING: cumulative ceiling request is determined by minimum
rate among all users in this mode and maximum bus rate
Final shared bus rate is determined as minimum rate between cumulative
ceiling request and maximum of floor or bandwidth cumulative requests.
Up to now shared bus clocks supported only SHARED_FLOOR mode, and this
mode is kept as default mode for all users. Hence, no change in actual
shared bus operations.
Bug 837005
Change-Id: I29f8215ba7bab4998fdd23b74c4f96611f5848fe
Reviewed-on: http://git-master/r/39139
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_clocks.c | 76 |
2 files changed, 53 insertions, 30 deletions
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index bd4cf0516efc..f7521b5f92c0 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h @@ -103,6 +103,12 @@ enum cpu_mode { MODE_LP, }; +enum shared_bus_users_mode { + SHARED_FLOOR = 0, + SHARED_BW, + SHARED_CEILING, +}; + enum clk_state { UNINITIALIZED = 0, ON, @@ -182,6 +188,7 @@ struct clk { const char *client_id; struct clk *client; u32 client_div; + enum shared_bus_users_mode mode; } shared_bus_user; } u; diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 1084d7b70251..b70fa89d01bf 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -2607,6 +2607,8 @@ static void tegra_clk_shared_bus_update(struct clk *bus) { struct clk *c; unsigned long rate = bus->min_rate; + unsigned long bw = 0; + unsigned long ceiling = bus->max_rate; if (detach_shared_bus) return; @@ -2616,9 +2618,22 @@ static void tegra_clk_shared_bus_update(struct clk *bus) /* Ignore requests from disabled users and from users with fixed bus-to-client ratio */ if ((c->u.shared_bus_user.enabled) && - (!c->u.shared_bus_user.client_div)) - rate = max(c->u.shared_bus_user.rate, rate); + (!c->u.shared_bus_user.client_div)) { + switch (c->u.shared_bus_user.mode) { + case SHARED_BW: + bw += c->u.shared_bus_user.rate; + break; + case SHARED_CEILING: + ceiling = min(c->u.shared_bus_user.rate, + ceiling); + break; + case SHARED_FLOOR: + default: + rate = max(c->u.shared_bus_user.rate, rate); + } + } } + rate = min(max(rate, bw), ceiling); if (rate != clk_get_rate(bus)) clk_set_rate(bus, rate); @@ -3673,7 +3688,7 @@ static struct clk tegra_clk_cbus = { }, \ } -#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div)\ +#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\ { \ .name = _name, \ .lookup = { \ @@ -3685,6 +3700,7 @@ static struct clk tegra_clk_cbus = { .u.shared_bus_user = { \ .client_id = _id, \ .client_div = _div, \ + .mode = _mode, \ }, \ } struct clk tegra_list_clks[] = { @@ -3780,33 +3796,33 @@ struct clk tegra_list_clks[] = { PERIPH_CLK("afi", "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0), PERIPH_CLK("se", "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71| DIV_U71_INT), - SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("mon.avp", "tegra_actmon", "avp", &tegra_clk_sbus_cmplx, NULL, 0), - SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc, NULL, 0), - SHARED_CLK("mon.emc", "tegra_actmon", "emc", &tegra_clk_emc, NULL, 0), - - SHARED_CLK("host1x.cbus","tegra_grhost", "host1x", &tegra_clk_cbus, "host1x", 2), - SHARED_CLK("3d.cbus", "tegra_grhost", "gr3d", &tegra_clk_cbus, "3d", 0), - SHARED_CLK("3d2.cbus", "tegra_grhost", "gr3d2",&tegra_clk_cbus, "3d2", 0), - SHARED_CLK("2d.cbus", "tegra_grhost", "gr2d", &tegra_clk_cbus, "2d", 0), - SHARED_CLK("epp.cbus", "tegra_grhost", "epp", &tegra_clk_cbus, "epp", 0), - SHARED_CLK("mpe.cbus", "tegra_grhost", "mpe", &tegra_clk_cbus, "mpe", 0), - SHARED_CLK("vde.cbus", "tegra-avp", "vde", &tegra_clk_cbus, "vde", 0), - SHARED_CLK("se.cbus", "tegra-se", NULL, &tegra_clk_cbus, "se", 0), + SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("mon.avp", "tegra_actmon", "avp", &tegra_clk_sbus_cmplx, NULL, 0, 0), + SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc, NULL, 0, 0), + SHARED_CLK("mon.emc", "tegra_actmon", "emc", &tegra_clk_emc, NULL, 0, 0), + + SHARED_CLK("host1x.cbus","tegra_grhost", "host1x", &tegra_clk_cbus, "host1x", 2, 0), + SHARED_CLK("3d.cbus", "tegra_grhost", "gr3d", &tegra_clk_cbus, "3d", 0, 0), + SHARED_CLK("3d2.cbus", "tegra_grhost", "gr3d2",&tegra_clk_cbus, "3d2", 0, 0), + SHARED_CLK("2d.cbus", "tegra_grhost", "gr2d", &tegra_clk_cbus, "2d", 0, 0), + SHARED_CLK("epp.cbus", "tegra_grhost", "epp", &tegra_clk_cbus, "epp", 0, 0), + SHARED_CLK("mpe.cbus", "tegra_grhost", "mpe", &tegra_clk_cbus, "mpe", 0, 0), + SHARED_CLK("vde.cbus", "tegra-avp", "vde", &tegra_clk_cbus, "vde", 0, 0), + SHARED_CLK("se.cbus", "tegra-se", NULL, &tegra_clk_cbus, "se", 0, 0), }; #define CLK_DUPLICATE(_name, _dev, _con) \ |