diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-08-20 03:04:59 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-08-20 03:04:59 -0400 |
commit | 53178d71b9f2d5c96bfcd2dd2c4b99c4e95a77d5 (patch) | |
tree | 4fbba9a4d9991ca74eb2578f3f9bf9a78c61e69f /arch/sh/drivers | |
parent | 7656e2486cb1ab7cdee65652ee695bdff894ea73 (diff) |
sh: Fix up SH7786 PCIe PHY initialization.
This brings the clocking and register setting in line with the somewhat
factually ambiguous specification.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r-- | arch/sh/drivers/pci/pcie-sh7786.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 68cb9b0ac9d2..03e6d8217b0c 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -148,16 +148,11 @@ static int pci_wait_for_irq(struct pci_channel *chan, unsigned int mask) | |||
148 | static void phy_write_reg(struct pci_channel *chan, unsigned int addr, | 148 | static void phy_write_reg(struct pci_channel *chan, unsigned int addr, |
149 | unsigned int lane, unsigned int data) | 149 | unsigned int lane, unsigned int data) |
150 | { | 150 | { |
151 | unsigned long phyaddr, ctrl; | 151 | unsigned long phyaddr; |
152 | 152 | ||
153 | phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) + | 153 | phyaddr = (1 << BITS_CMD) + ((lane & 0xf) << BITS_LANE) + |
154 | ((addr & 0xff) << BITS_ADR); | 154 | ((addr & 0xff) << BITS_ADR); |
155 | 155 | ||
156 | /* Enable clock */ | ||
157 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | ||
158 | ctrl |= (1 << BITS_CKE); | ||
159 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | ||
160 | |||
161 | /* Set write data */ | 156 | /* Set write data */ |
162 | pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR); | 157 | pci_write_reg(chan, data, SH4A_PCIEPHYDOUTR); |
163 | pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR); | 158 | pci_write_reg(chan, phyaddr, SH4A_PCIEPHYADRR); |
@@ -165,20 +160,22 @@ static void phy_write_reg(struct pci_channel *chan, unsigned int addr, | |||
165 | phy_wait_for_ack(chan); | 160 | phy_wait_for_ack(chan); |
166 | 161 | ||
167 | /* Clear command */ | 162 | /* Clear command */ |
163 | pci_write_reg(chan, 0, SH4A_PCIEPHYDOUTR); | ||
168 | pci_write_reg(chan, 0, SH4A_PCIEPHYADRR); | 164 | pci_write_reg(chan, 0, SH4A_PCIEPHYADRR); |
169 | 165 | ||
170 | phy_wait_for_ack(chan); | 166 | phy_wait_for_ack(chan); |
171 | |||
172 | /* Disable clock */ | ||
173 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | ||
174 | ctrl &= ~(1 << BITS_CKE); | ||
175 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | ||
176 | } | 167 | } |
177 | 168 | ||
178 | static int phy_init(struct pci_channel *chan) | 169 | static int phy_init(struct pci_channel *chan) |
179 | { | 170 | { |
171 | unsigned long ctrl; | ||
180 | unsigned int timeout = 100; | 172 | unsigned int timeout = 100; |
181 | 173 | ||
174 | /* Enable clock */ | ||
175 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | ||
176 | ctrl |= (1 << BITS_CKE); | ||
177 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | ||
178 | |||
182 | /* Initialize the phy */ | 179 | /* Initialize the phy */ |
183 | phy_write_reg(chan, 0x60, 0xf, 0x004b008b); | 180 | phy_write_reg(chan, 0x60, 0xf, 0x004b008b); |
184 | phy_write_reg(chan, 0x61, 0xf, 0x00007b41); | 181 | phy_write_reg(chan, 0x61, 0xf, 0x00007b41); |
@@ -187,9 +184,15 @@ static int phy_init(struct pci_channel *chan) | |||
187 | phy_write_reg(chan, 0x66, 0xf, 0x00000010); | 184 | phy_write_reg(chan, 0x66, 0xf, 0x00000010); |
188 | phy_write_reg(chan, 0x74, 0xf, 0x0007001c); | 185 | phy_write_reg(chan, 0x74, 0xf, 0x0007001c); |
189 | phy_write_reg(chan, 0x79, 0xf, 0x01fc000d); | 186 | phy_write_reg(chan, 0x79, 0xf, 0x01fc000d); |
187 | phy_write_reg(chan, 0xb0, 0xf, 0x00000610); | ||
190 | 188 | ||
191 | /* Deassert Standby */ | 189 | /* Deassert Standby */ |
192 | phy_write_reg(chan, 0x67, 0xf, 0x00000400); | 190 | phy_write_reg(chan, 0x67, 0x1, 0x00000400); |
191 | |||
192 | /* Disable clock */ | ||
193 | ctrl = pci_read_reg(chan, SH4A_PCIEPHYCTLR); | ||
194 | ctrl &= ~(1 << BITS_CKE); | ||
195 | pci_write_reg(chan, ctrl, SH4A_PCIEPHYCTLR); | ||
193 | 196 | ||
194 | while (timeout--) { | 197 | while (timeout--) { |
195 | if (pci_read_reg(chan, SH4A_PCIEPHYSR)) | 198 | if (pci_read_reg(chan, SH4A_PCIEPHYSR)) |
@@ -287,6 +290,9 @@ static int pcie_init(struct sh7786_pcie_port *port) | |||
287 | __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); | 290 | __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); |
288 | __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); | 291 | __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); |
289 | 292 | ||
293 | __raw_writel(memphys, chan->reg_base + SH4A_PCIEPCICONF4); | ||
294 | __raw_writel(0, chan->reg_base + SH4A_PCIEPCICONF5); | ||
295 | |||
290 | /* Finish initialization */ | 296 | /* Finish initialization */ |
291 | data = pci_read_reg(chan, SH4A_PCIETCTLR); | 297 | data = pci_read_reg(chan, SH4A_PCIETCTLR); |
292 | data |= 0x1; | 298 | data |= 0x1; |