aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-09-20 05:45:11 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-09-20 05:45:11 -0400
commitc524ebf5a6b78d25219d64a05b3876cde719b5ff (patch)
tree6cbc83e8a54e45a936ce65189b2c27de9d87004f /arch/sh/drivers
parentcecf48e23fd9270053850643a56e8e791322e3d5 (diff)
sh: pci: clock framework support for SH7786 PCIe.
This gets each port handling its MSTP bit, as well as moving the PHY clock management in to the clock framework. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c107
1 files changed, 86 insertions, 21 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index b0ef380eff28..8ec4af197388 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -13,11 +13,15 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/clk.h>
17#include <linux/sh_clk.h>
16#include "pcie-sh7786.h" 18#include "pcie-sh7786.h"
17#include <asm/sizes.h> 19#include <asm/sizes.h>
20#include <asm/clock.h>
18 21
19struct sh7786_pcie_port { 22struct sh7786_pcie_port {
20 struct pci_channel *hose; 23 struct pci_channel *hose;
24 struct clk *fclk, phy_clk;
21 unsigned int index; 25 unsigned int index;
22 int endpoint; 26 int endpoint;
23 int link; 27 int link;
@@ -121,6 +125,10 @@ static struct pci_channel sh7786_pci_channels[] = {
121 DEFINE_CONTROLLER(0xfcc00000, 2), 125 DEFINE_CONTROLLER(0xfcc00000, 2),
122}; 126};
123 127
128static struct clk fixed_pciexclkp = {
129 .rate = 100000000, /* 100 MHz reference clock */
130};
131
124static void __devinit sh7786_pci_fixup(struct pci_dev *dev) 132static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
125{ 133{
126 /* 134 /*
@@ -139,7 +147,7 @@ static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
139DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786, 147DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786,
140 sh7786_pci_fixup); 148 sh7786_pci_fixup);
141 149
142static int phy_wait_for_ack(struct pci_channel *chan) 150static int __init phy_wait_for_ack(struct pci_channel *chan)
143{ 151{
144 unsigned int timeout = 100; 152 unsigned int timeout = 100;
145 153
@@ -153,7 +161,7 @@ static int phy_wait_for_ack(struct pci_channel *chan)
153 return -ETIMEDOUT; 161 return -ETIMEDOUT;
154} 162}
155 163
156static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask) 164static int __init pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
157{ 165{
158 unsigned int timeout = 100; 166 unsigned int timeout = 100;
159 167
@@ -167,8 +175,8 @@ static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask)
167 return -ETIMEDOUT; 175 return -ETIMEDOUT;
168} 176}
169 177
170static void phy_write_reg(struct pci_channel *chan, unsigned int addr, 178static void __init phy_write_reg(struct pci_channel *chan, unsigned int addr,
171 unsigned int lane, unsigned int data) 179 unsigned int lane, unsigned int data)
172{ 180{
173 unsigned long phyaddr; 181 unsigned long phyaddr;
174 182
@@ -188,15 +196,67 @@ static void phy_write_reg(struct pci_channel *chan, unsigned int addr,
188 phy_wait_for_ack(chan); 196 phy_wait_for_ack(chan);
189} 197}
190 198
191static int phy_init(struct pci_channel *chan) 199static int __init pcie_clk_init(struct sh7786_pcie_port *port)
200{
201 struct pci_channel *chan = port->hose;
202 struct clk *clk;
203 char fclk_name[16];
204 int ret;
205
206 /*
207 * First register the fixed clock
208 */
209 ret = clk_register(&fixed_pciexclkp);
210 if (unlikely(ret != 0))
211 return ret;
212
213 /*
214 * Grab the port's function clock, which the PHY clock depends
215 * on. clock lookups don't help us much at this point, since no
216 * dev_id is available this early. Lame.
217 */
218 snprintf(fclk_name, sizeof(fclk_name), "pcie%d_fck", port->index);
219
220 port->fclk = clk_get(NULL, fclk_name);
221 if (IS_ERR(port->fclk)) {
222 ret = PTR_ERR(port->fclk);
223 goto err_fclk;
224 }
225
226 clk_enable(port->fclk);
227
228 /*
229 * And now, set up the PHY clock
230 */
231 clk = &port->phy_clk;
232
233 memset(clk, 0, sizeof(struct clk));
234
235 clk->parent = &fixed_pciexclkp;
236 clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR);
237 clk->enable_bit = BITS_CKE;
238
239 ret = sh_clk_mstp32_register(clk, 1);
240 if (unlikely(ret < 0))
241 goto err_phy;
242
243 return 0;
244
245err_phy:
246 clk_disable(port->fclk);
247 clk_put(port->fclk);
248err_fclk:
249 clk_unregister(&fixed_pciexclkp);
250
251 return ret;
252}
253
254static int __init phy_init(struct sh7786_pcie_port *port)
192{ 255{
193 unsigned long ctrl; 256 struct pci_channel *chan = port->hose;
194 unsigned int timeout = 100; 257 unsigned int timeout = 100;
195 258
196 /* Enable clock */ 259 clk_enable(&port->phy_clk);
197 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR);
198 ctrl |= (1 << BITS_CKE);
199 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
200 260
201 /* Initialize the phy */ 261 /* Initialize the phy */
202 phy_write_reg(chan, 0x60, 0xf, 0x004b008b); 262 phy_write_reg(chan, 0x60, 0xf, 0x004b008b);
@@ -212,9 +272,7 @@ static int phy_init(struct pci_channel *chan)
212 phy_write_reg(chan, 0x67, 0x1, 0x00000400); 272 phy_write_reg(chan, 0x67, 0x1, 0x00000400);
213 273
214 /* Disable clock */ 274 /* Disable clock */
215 ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); 275 clk_disable(&port->phy_clk);
216 ctrl &= ~(1 << BITS_CKE);
217 pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR);
218 276
219 while (timeout--) { 277 while (timeout--) {
220 if (pci_read_reg(chan, SH4A_PCIEPHYSR)) 278 if (pci_read_reg(chan, SH4A_PCIEPHYSR))
@@ -226,7 +284,7 @@ static int phy_init(struct pci_channel *chan)
226 return -ETIMEDOUT; 284 return -ETIMEDOUT;
227} 285}
228 286
229static void pcie_reset(struct sh7786_pcie_port *port) 287static void __init pcie_reset(struct sh7786_pcie_port *port)
230{ 288{
231 struct pci_channel *chan = port->hose; 289 struct pci_channel *chan = port->hose;
232 290
@@ -236,7 +294,7 @@ static void pcie_reset(struct sh7786_pcie_port *port)
236 pci_write_reg(chan, 0, SH4A_PCIETXVC0SR); 294 pci_write_reg(chan, 0, SH4A_PCIETXVC0SR);
237} 295}
238 296
239static int pcie_init(struct sh7786_pcie_port *port) 297static int __init pcie_init(struct sh7786_pcie_port *port)
240{ 298{
241 struct pci_channel *chan = port->hose; 299 struct pci_channel *chan = port->hose;
242 unsigned int data; 300 unsigned int data;
@@ -411,26 +469,33 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
411 return 71; 469 return 71;
412} 470}
413 471
414static int sh7786_pcie_core_init(void) 472static int __init sh7786_pcie_core_init(void)
415{ 473{
416 /* Return the number of ports */ 474 /* Return the number of ports */
417 return test_mode_pin(MODE_PIN12) ? 3 : 2; 475 return test_mode_pin(MODE_PIN12) ? 3 : 2;
418} 476}
419 477
420static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port) 478static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)
421{ 479{
422 int ret; 480 int ret;
423 481
424 ret = phy_init(port->hose);
425 if (unlikely(ret < 0))
426 return ret;
427
428 /* 482 /*
429 * Check if we are configured in endpoint or root complex mode, 483 * Check if we are configured in endpoint or root complex mode,
430 * this is a fixed pin setting that applies to all PCIe ports. 484 * this is a fixed pin setting that applies to all PCIe ports.
431 */ 485 */
432 port->endpoint = test_mode_pin(MODE_PIN11); 486 port->endpoint = test_mode_pin(MODE_PIN11);
433 487
488 /*
489 * Setup clocks, needed both for PHY and PCIe registers.
490 */
491 ret = pcie_clk_init(port);
492 if (unlikely(ret < 0))
493 return ret;
494
495 ret = phy_init(port);
496 if (unlikely(ret < 0))
497 return ret;
498
434 ret = pcie_init(port); 499 ret = pcie_init(port);
435 if (unlikely(ret < 0)) 500 if (unlikely(ret < 0))
436 return ret; 501 return ret;