aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/tegra
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-12-26 13:33:05 -0500
committerOlof Johansson <olof@lixom.net>2013-12-26 13:33:05 -0500
commite7d248f0e0f93b86c56466ede82c46234f622615 (patch)
tree36adb8e2ff0b4cc570334372389f82a73e352002 /drivers/clk/tegra
parent1c7af42fe579b5cf8c942319cbed38801305dda4 (diff)
parent8a0a1af30cbf56b41220a02e34835022c4d72f41 (diff)
Merge tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/cleanup
From Stephen Warren: ARM: tegra: implement common DMA and resets DT bindings This series converts the Tegra DTs and drivers to use the common/ standard DMA and reset bindings, rather than custom bindings. It also adds complete documentation for the Tegra clock bindings without actually changing any binding definitions. This conversion relies on a few sets of patches in branches from outside the Tegra tree: 1) A patch to add an DMA channel request API which allows deferred probe to be implemented. 2) A patch to implement a common part of the of_xlate function for DMA controllers. 3) Some ASoC patches (which in turn rely on (1) above), which support deferred probe during DMA channel allocation. 4) The Tegra clock driver changes for 3.14. Consequently, this branch is based on a merge of all of those external branches. In turn, this branch is or will be pulled into a few places that either rely on features introduced here, or would otherwise conflict with the patches: a) Tegra's own for-3.14/powergate and for-4.14/dt branches, to avoid conflicts. b) The DRM tree, which introduces new code that relies on the reset controller framework introduced in this branch, and to avoid conflicts. * tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: (30 commits) spi: tegra: checking for ERR_PTR instead of NULL ASoC: tegra: update module reset list for Tegra124 clk: tegra: remove bogus PCIE_XCLK clk: tegra: remove legacy reset APIs ARM: tegra: remove legacy DMA entries from DT ARM: tegra: remove legacy clock entries from DT USB: EHCI: tegra: use reset framework Input: tegra-kbc - use reset framework serial: tegra: convert to standard DMA DT bindings serial: tegra: use reset framework spi: tegra: convert to standard DMA DT bindings spi: tegra: use reset framework staging: nvec: use reset framework i2c: tegra: use reset framework ASoC: tegra: convert to standard DMA DT bindings ASoC: tegra: allocate AHUB FIFO during probe() not startup() ASoC: tegra: call pm_runtime APIs around register accesses ASoC: tegra: use reset framework dma: tegra: register as an OF DMA controller dma: tegra: use reset framework ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/clk/tegra')
-rw-r--r--drivers/clk/tegra/clk-periph-gate.c22
-rw-r--r--drivers/clk/tegra/clk-periph.c40
-rw-r--r--drivers/clk/tegra/clk-tegra114.c3
-rw-r--r--drivers/clk/tegra/clk-tegra124.c2
-rw-r--r--drivers/clk/tegra/clk-tegra20.c9
-rw-r--r--drivers/clk/tegra/clk-tegra30.c10
-rw-r--r--drivers/clk/tegra/clk.c50
-rw-r--r--drivers/clk/tegra/clk.h3
8 files changed, 57 insertions, 82 deletions
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
index f38f33e3c65d..507015314827 100644
--- a/drivers/clk/tegra/clk-periph-gate.c
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock);
36 36
37#define read_rst(gate) \ 37#define read_rst(gate) \
38 readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) 38 readl_relaxed(gate->clk_base + (gate->regs->rst_reg))
39#define write_rst_set(val, gate) \
40 writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg))
41#define write_rst_clr(val, gate) \ 39#define write_rst_clr(val, gate) \
42 writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) 40 writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
43 41
@@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw)
123 spin_unlock_irqrestore(&periph_ref_lock, flags); 121 spin_unlock_irqrestore(&periph_ref_lock, flags);
124} 122}
125 123
126void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert)
127{
128 if (gate->flags & TEGRA_PERIPH_NO_RESET)
129 return;
130
131 if (assert) {
132 /*
133 * If peripheral is in the APB bus then read the APB bus to
134 * flush the write operation in apb bus. This will avoid the
135 * peripheral access after disabling clock
136 */
137 if (gate->flags & TEGRA_PERIPH_ON_APB)
138 tegra_read_chipid();
139
140 write_rst_set(periph_clk_to_bit(gate), gate);
141 } else {
142 write_rst_clr(periph_clk_to_bit(gate), gate);
143 }
144}
145
146const struct clk_ops tegra_clk_periph_gate_ops = { 124const struct clk_ops tegra_clk_periph_gate_ops = {
147 .is_enabled = clk_periph_is_enabled, 125 .is_enabled = clk_periph_is_enabled,
148 .enable = clk_periph_enable, 126 .enable = clk_periph_enable,
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index d62b396863c1..c534043c0481 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw)
111 gate_ops->disable(gate_hw); 111 gate_ops->disable(gate_hw);
112} 112}
113 113
114void tegra_periph_reset_deassert(struct clk *c)
115{
116 struct clk_hw *hw = __clk_get_hw(c);
117 struct tegra_clk_periph *periph = to_clk_periph(hw);
118 struct tegra_clk_periph_gate *gate;
119
120 if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
121 gate = to_clk_periph_gate(hw);
122 if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
123 WARN_ON(1);
124 return;
125 }
126 } else {
127 gate = &periph->gate;
128 }
129
130 tegra_periph_reset(gate, 0);
131}
132EXPORT_SYMBOL(tegra_periph_reset_deassert);
133
134void tegra_periph_reset_assert(struct clk *c)
135{
136 struct clk_hw *hw = __clk_get_hw(c);
137 struct tegra_clk_periph *periph = to_clk_periph(hw);
138 struct tegra_clk_periph_gate *gate;
139
140 if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) {
141 gate = to_clk_periph_gate(hw);
142 if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) {
143 WARN_ON(1);
144 return;
145 }
146 } else {
147 gate = &periph->gate;
148 }
149
150 tegra_periph_reset(gate, 1);
151}
152EXPORT_SYMBOL(tegra_periph_reset_assert);
153
154const struct clk_ops tegra_clk_periph_ops = { 114const struct clk_ops tegra_clk_periph_ops = {
155 .get_parent = clk_periph_get_parent, 115 .get_parent = clk_periph_get_parent,
156 .set_parent = clk_periph_set_parent, 116 .set_parent = clk_periph_set_parent,
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 29b912582e3d..90d9d25f2228 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -1460,7 +1460,8 @@ static void __init tegra114_clock_init(struct device_node *np)
1460 return; 1460 return;
1461 } 1461 }
1462 1462
1463 clks = tegra_clk_init(TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_PERIPH_BANKS); 1463 clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX,
1464 TEGRA114_CLK_PERIPH_BANKS);
1464 if (!clks) 1465 if (!clks)
1465 return; 1466 return;
1466 1467
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 0ef4485e9b0a..aff86b5bc745 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1398,7 +1398,7 @@ static void __init tegra124_clock_init(struct device_node *np)
1398 return; 1398 return;
1399 } 1399 }
1400 1400
1401 clks = tegra_clk_init(TEGRA124_CLK_CLK_MAX, 6); 1401 clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6);
1402 if (!clks) 1402 if (!clks)
1403 return; 1403 return;
1404 1404
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index b3b7204acfe7..dbace152b2fa 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -468,7 +468,6 @@ static struct tegra_devclk devclks[] __initdata = {
468 { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP }, 468 { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP },
469 { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX }, 469 { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX },
470 { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI }, 470 { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI },
471 { .con_id = "pcie_xclk", .dt_id = TEGRA20_CLK_PCIE_XCLK },
472 { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, 471 { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 },
473 { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, 472 { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 },
474 { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, 473 { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K },
@@ -834,11 +833,6 @@ static void __init tegra20_periph_clk_init(void)
834 periph_clk_enb_refcnt); 833 periph_clk_enb_refcnt);
835 clks[TEGRA20_CLK_PEX] = clk; 834 clks[TEGRA20_CLK_PEX] = clk;
836 835
837 /* pcie_xclk */
838 clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base,
839 0, 74, periph_clk_enb_refcnt);
840 clks[TEGRA20_CLK_PCIE_XCLK] = clk;
841
842 /* cdev1 */ 836 /* cdev1 */
843 clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, 837 clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT,
844 26000000); 838 26000000);
@@ -1109,7 +1103,8 @@ static void __init tegra20_clock_init(struct device_node *np)
1109 BUG(); 1103 BUG();
1110 } 1104 }
1111 1105
1112 clks = tegra_clk_init(TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_PERIPH_BANKS); 1106 clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX,
1107 TEGRA20_CLK_PERIPH_BANKS);
1113 if (!clks) 1108 if (!clks)
1114 return; 1109 return;
1115 1110
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index dcb6843b3a89..8b10c38b6e3c 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -649,7 +649,6 @@ static struct tegra_devclk devclks[] __initdata = {
649 { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP }, 649 { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP },
650 { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, 650 { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE },
651 { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, 651 { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI },
652 { .con_id = "pciex", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIEX },
653 { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE }, 652 { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE },
654 { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, 653 { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN },
655 { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, 654 { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF },
@@ -1150,11 +1149,6 @@ static void __init tegra30_periph_clk_init(void)
1150 periph_clk_enb_refcnt); 1149 periph_clk_enb_refcnt);
1151 clks[TEGRA30_CLK_AFI] = clk; 1150 clks[TEGRA30_CLK_AFI] = clk;
1152 1151
1153 /* pciex */
1154 clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0,
1155 74, periph_clk_enb_refcnt);
1156 clks[TEGRA30_CLK_PCIEX] = clk;
1157
1158 /* emc */ 1152 /* emc */
1159 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 1153 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
1160 ARRAY_SIZE(mux_pllmcp_clkm), 1154 ARRAY_SIZE(mux_pllmcp_clkm),
@@ -1395,7 +1389,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
1395 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"), 1389 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"),
1396 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL), 1390 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL),
1397 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"), 1391 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"),
1398 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_PCIEX, "tegra_pcie", "pciex"),
1399 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"), 1392 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"),
1400 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ 1393 TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */
1401}; 1394};
@@ -1427,7 +1420,8 @@ static void __init tegra30_clock_init(struct device_node *np)
1427 BUG(); 1420 BUG();
1428 } 1421 }
1429 1422
1430 clks = tegra_clk_init(TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_PERIPH_BANKS); 1423 clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX,
1424 TEGRA30_CLK_PERIPH_BANKS);
1431 if (!clks) 1425 if (!clks)
1432 return; 1426 return;
1433 1427
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index a12a5f5107ec..c0a7d7723510 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -18,6 +18,8 @@
18#include <linux/clk-provider.h> 18#include <linux/clk-provider.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/clk/tegra.h> 20#include <linux/clk/tegra.h>
21#include <linux/reset-controller.h>
22#include <linux/tegra-soc.h>
21 23
22#include "clk.h" 24#include "clk.h"
23 25
@@ -121,6 +123,35 @@ static struct tegra_clk_periph_regs periph_regs[] = {
121 }, 123 },
122}; 124};
123 125
126static void __iomem *clk_base;
127
128static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev,
129 unsigned long id)
130{
131 /*
132 * If peripheral is on the APB bus then we must read the APB bus to
133 * flush the write operation in apb bus. This will avoid peripheral
134 * access after disabling clock. Since the reset driver has no
135 * knowledge of which reset IDs represent which devices, simply do
136 * this all the time.
137 */
138 tegra_read_chipid();
139
140 writel_relaxed(BIT(id % 32),
141 clk_base + periph_regs[id / 32].rst_set_reg);
142
143 return 0;
144}
145
146static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev,
147 unsigned long id)
148{
149 writel_relaxed(BIT(id % 32),
150 clk_base + periph_regs[id / 32].rst_clr_reg);
151
152 return 0;
153}
154
124struct tegra_clk_periph_regs *get_reg_bank(int clkid) 155struct tegra_clk_periph_regs *get_reg_bank(int clkid)
125{ 156{
126 int reg_bank = clkid / 32; 157 int reg_bank = clkid / 32;
@@ -133,8 +164,10 @@ struct tegra_clk_periph_regs *get_reg_bank(int clkid)
133 } 164 }
134} 165}
135 166
136struct clk ** __init tegra_clk_init(int num, int banks) 167struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
137{ 168{
169 clk_base = regs;
170
138 if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) 171 if (WARN_ON(banks > ARRAY_SIZE(periph_regs)))
139 return NULL; 172 return NULL;
140 173
@@ -203,6 +236,17 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
203 } 236 }
204} 237}
205 238
239static struct reset_control_ops rst_ops = {
240 .assert = tegra_clk_rst_assert,
241 .deassert = tegra_clk_rst_deassert,
242};
243
244static struct reset_controller_dev rst_ctlr = {
245 .ops = &rst_ops,
246 .owner = THIS_MODULE,
247 .of_reset_n_cells = 1,
248};
249
206void __init tegra_add_of_provider(struct device_node *np) 250void __init tegra_add_of_provider(struct device_node *np)
207{ 251{
208 int i; 252 int i;
@@ -220,6 +264,10 @@ void __init tegra_add_of_provider(struct device_node *np)
220 clk_data.clks = clks; 264 clk_data.clks = clks;
221 clk_data.clk_num = clk_num; 265 clk_data.clk_num = clk_num;
222 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 266 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
267
268 rst_ctlr.of_node = np;
269 rst_ctlr.nr_resets = clk_num * 32;
270 reset_controller_register(&rst_ctlr);
223} 271}
224 272
225void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) 273void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 40fb011233c0..16ec8d6bb87f 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -393,7 +393,6 @@ struct tegra_clk_periph_gate {
393#define TEGRA_PERIPH_NO_DIV BIT(4) 393#define TEGRA_PERIPH_NO_DIV BIT(4)
394#define TEGRA_PERIPH_NO_GATE BIT(5) 394#define TEGRA_PERIPH_NO_GATE BIT(5)
395 395
396void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
397extern const struct clk_ops tegra_clk_periph_gate_ops; 396extern const struct clk_ops tegra_clk_periph_gate_ops;
398struct clk *tegra_clk_register_periph_gate(const char *name, 397struct clk *tegra_clk_register_periph_gate(const char *name,
399 const char *parent_name, u8 gate_flags, void __iomem *clk_base, 398 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
@@ -597,7 +596,7 @@ void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
597 struct clk *clks[], int clk_max); 596 struct clk *clks[], int clk_max);
598 597
599struct tegra_clk_periph_regs *get_reg_bank(int clkid); 598struct tegra_clk_periph_regs *get_reg_bank(int clkid);
600struct clk **tegra_clk_init(int num, int periph_banks); 599struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
601 600
602struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); 601struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
603 602