diff options
Diffstat (limited to 'arch/arm/mach-kirkwood/common.c')
| -rw-r--r-- | arch/arm/mach-kirkwood/common.c | 274 |
1 files changed, 187 insertions, 87 deletions
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index a02cae881f2f..25fb3fd418ef 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <linux/ata_platform.h> | 15 | #include <linux/ata_platform.h> |
| 16 | #include <linux/mtd/nand.h> | 16 | #include <linux/mtd/nand.h> |
| 17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
| 18 | #include <linux/clk-provider.h> | ||
| 19 | #include <linux/spinlock.h> | ||
| 18 | #include <net/dsa.h> | 20 | #include <net/dsa.h> |
| 19 | #include <asm/page.h> | 21 | #include <asm/page.h> |
| 20 | #include <asm/timex.h> | 22 | #include <asm/timex.h> |
| @@ -31,6 +33,7 @@ | |||
| 31 | #include <plat/common.h> | 33 | #include <plat/common.h> |
| 32 | #include <plat/time.h> | 34 | #include <plat/time.h> |
| 33 | #include <plat/addr-map.h> | 35 | #include <plat/addr-map.h> |
| 36 | #include <plat/mv_xor.h> | ||
| 34 | #include "common.h" | 37 | #include "common.h" |
| 35 | 38 | ||
| 36 | /***************************************************************************** | 39 | /***************************************************************************** |
| @@ -60,20 +63,188 @@ void __init kirkwood_map_io(void) | |||
| 60 | iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); | 63 | iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); |
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | /* | 66 | /***************************************************************************** |
| 64 | * Default clock control bits. Any bit _not_ set in this variable | 67 | * CLK tree |
| 65 | * will be cleared from the hardware after platform devices have been | 68 | ****************************************************************************/ |
| 66 | * registered. Some reserved bits must be set to 1. | 69 | |
| 67 | */ | 70 | static void disable_sata0(void) |
| 68 | unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; | 71 | { |
| 72 | /* Disable PLL and IVREF */ | ||
| 73 | writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); | ||
| 74 | /* Disable PHY */ | ||
| 75 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void disable_sata1(void) | ||
| 79 | { | ||
| 80 | /* Disable PLL and IVREF */ | ||
| 81 | writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); | ||
| 82 | /* Disable PHY */ | ||
| 83 | writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); | ||
| 84 | } | ||
| 85 | |||
| 86 | static void disable_pcie0(void) | ||
| 87 | { | ||
| 88 | writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); | ||
| 89 | while (1) | ||
| 90 | if (readl(PCIE_STATUS) & 0x1) | ||
| 91 | break; | ||
| 92 | writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void disable_pcie1(void) | ||
| 96 | { | ||
| 97 | u32 dev, rev; | ||
| 98 | |||
| 99 | kirkwood_pcie_id(&dev, &rev); | ||
| 100 | |||
| 101 | if (dev == MV88F6282_DEV_ID) { | ||
| 102 | writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); | ||
| 103 | while (1) | ||
| 104 | if (readl(PCIE1_STATUS) & 0x1) | ||
| 105 | break; | ||
| 106 | writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | /* An extended version of the gated clk. This calls fn() before | ||
| 111 | * disabling the clock. We use this to turn off PHYs etc. */ | ||
| 112 | struct clk_gate_fn { | ||
| 113 | struct clk_gate gate; | ||
| 114 | void (*fn)(void); | ||
| 115 | }; | ||
| 69 | 116 | ||
| 117 | #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) | ||
| 118 | #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) | ||
| 119 | |||
| 120 | static void clk_gate_fn_disable(struct clk_hw *hw) | ||
| 121 | { | ||
| 122 | struct clk_gate *gate = to_clk_gate(hw); | ||
| 123 | struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); | ||
| 124 | |||
| 125 | if (gate_fn->fn) | ||
| 126 | gate_fn->fn(); | ||
| 127 | |||
| 128 | clk_gate_ops.disable(hw); | ||
| 129 | } | ||
| 130 | |||
| 131 | static struct clk_ops clk_gate_fn_ops; | ||
| 132 | |||
| 133 | static struct clk __init *clk_register_gate_fn(struct device *dev, | ||
| 134 | const char *name, | ||
| 135 | const char *parent_name, unsigned long flags, | ||
| 136 | void __iomem *reg, u8 bit_idx, | ||
| 137 | u8 clk_gate_flags, spinlock_t *lock, | ||
| 138 | void (*fn)(void)) | ||
| 139 | { | ||
| 140 | struct clk_gate_fn *gate_fn; | ||
| 141 | struct clk *clk; | ||
| 142 | struct clk_init_data init; | ||
| 143 | |||
| 144 | gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL); | ||
| 145 | if (!gate_fn) { | ||
| 146 | pr_err("%s: could not allocate gated clk\n", __func__); | ||
| 147 | return ERR_PTR(-ENOMEM); | ||
| 148 | } | ||
| 149 | |||
| 150 | init.name = name; | ||
| 151 | init.ops = &clk_gate_fn_ops; | ||
| 152 | init.flags = flags; | ||
| 153 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
| 154 | init.num_parents = (parent_name ? 1 : 0); | ||
| 155 | |||
| 156 | /* struct clk_gate assignments */ | ||
| 157 | gate_fn->gate.reg = reg; | ||
| 158 | gate_fn->gate.bit_idx = bit_idx; | ||
| 159 | gate_fn->gate.flags = clk_gate_flags; | ||
| 160 | gate_fn->gate.lock = lock; | ||
| 161 | gate_fn->gate.hw.init = &init; | ||
| 162 | |||
| 163 | /* ops is the gate ops, but with our disable function */ | ||
| 164 | if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { | ||
| 165 | clk_gate_fn_ops = clk_gate_ops; | ||
| 166 | clk_gate_fn_ops.disable = clk_gate_fn_disable; | ||
| 167 | } | ||
| 168 | |||
| 169 | clk = clk_register(dev, &gate_fn->gate.hw); | ||
| 170 | |||
| 171 | if (IS_ERR(clk)) | ||
| 172 | kfree(gate_fn); | ||
| 173 | |||
| 174 | return clk; | ||
| 175 | } | ||
| 176 | |||
| 177 | static DEFINE_SPINLOCK(gating_lock); | ||
| 178 | static struct clk *tclk; | ||
| 179 | |||
| 180 | static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) | ||
| 181 | { | ||
| 182 | return clk_register_gate(NULL, name, "tclk", 0, | ||
| 183 | (void __iomem *)CLOCK_GATING_CTRL, | ||
| 184 | bit_idx, 0, &gating_lock); | ||
| 185 | } | ||
| 186 | |||
| 187 | static struct clk __init *kirkwood_register_gate_fn(const char *name, | ||
| 188 | u8 bit_idx, | ||
| 189 | void (*fn)(void)) | ||
| 190 | { | ||
| 191 | return clk_register_gate_fn(NULL, name, "tclk", 0, | ||
| 192 | (void __iomem *)CLOCK_GATING_CTRL, | ||
| 193 | bit_idx, 0, &gating_lock, fn); | ||
| 194 | } | ||
| 195 | |||
| 196 | void __init kirkwood_clk_init(void) | ||
| 197 | { | ||
| 198 | struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; | ||
| 199 | struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; | ||
| 200 | |||
| 201 | tclk = clk_register_fixed_rate(NULL, "tclk", NULL, | ||
| 202 | CLK_IS_ROOT, kirkwood_tclk); | ||
| 203 | |||
| 204 | runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); | ||
| 205 | ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); | ||
| 206 | ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); | ||
| 207 | sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, | ||
| 208 | disable_sata0); | ||
| 209 | sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, | ||
| 210 | disable_sata1); | ||
| 211 | usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); | ||
| 212 | sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); | ||
| 213 | crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); | ||
| 214 | xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); | ||
| 215 | xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); | ||
| 216 | pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, | ||
| 217 | disable_pcie0); | ||
| 218 | pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, | ||
| 219 | disable_pcie1); | ||
| 220 | audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); | ||
| 221 | kirkwood_register_gate("tdm", CGC_BIT_TDM); | ||
| 222 | kirkwood_register_gate("tsu", CGC_BIT_TSU); | ||
| 223 | |||
| 224 | /* clkdev entries, mapping clks to devices */ | ||
| 225 | orion_clkdev_add(NULL, "orion_spi.0", runit); | ||
| 226 | orion_clkdev_add(NULL, "orion_spi.1", runit); | ||
| 227 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); | ||
| 228 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); | ||
| 229 | orion_clkdev_add(NULL, "orion_wdt", tclk); | ||
| 230 | orion_clkdev_add("0", "sata_mv.0", sata0); | ||
| 231 | orion_clkdev_add("1", "sata_mv.0", sata1); | ||
| 232 | orion_clkdev_add(NULL, "orion-ehci.0", usb0); | ||
| 233 | orion_clkdev_add(NULL, "orion_nand", runit); | ||
| 234 | orion_clkdev_add(NULL, "mvsdio", sdio); | ||
| 235 | orion_clkdev_add(NULL, "mv_crypto", crypto); | ||
| 236 | orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); | ||
| 237 | orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); | ||
| 238 | orion_clkdev_add("0", "pcie", pex0); | ||
| 239 | orion_clkdev_add("1", "pcie", pex1); | ||
| 240 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | ||
| 241 | } | ||
| 70 | 242 | ||
| 71 | /***************************************************************************** | 243 | /***************************************************************************** |
| 72 | * EHCI0 | 244 | * EHCI0 |
| 73 | ****************************************************************************/ | 245 | ****************************************************************************/ |
| 74 | void __init kirkwood_ehci_init(void) | 246 | void __init kirkwood_ehci_init(void) |
| 75 | { | 247 | { |
| 76 | kirkwood_clk_ctrl |= CGC_USB0; | ||
| 77 | orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); | 248 | orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); |
| 78 | } | 249 | } |
| 79 | 250 | ||
| @@ -83,11 +254,9 @@ void __init kirkwood_ehci_init(void) | |||
| 83 | ****************************************************************************/ | 254 | ****************************************************************************/ |
| 84 | void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) | 255 | void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) |
| 85 | { | 256 | { |
| 86 | kirkwood_clk_ctrl |= CGC_GE0; | ||
| 87 | |||
| 88 | orion_ge00_init(eth_data, | 257 | orion_ge00_init(eth_data, |
| 89 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, | 258 | GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, |
| 90 | IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); | 259 | IRQ_KIRKWOOD_GE00_ERR); |
| 91 | } | 260 | } |
| 92 | 261 | ||
| 93 | 262 | ||
| @@ -96,12 +265,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) | |||
| 96 | ****************************************************************************/ | 265 | ****************************************************************************/ |
| 97 | void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) | 266 | void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) |
| 98 | { | 267 | { |
| 99 | |||
| 100 | kirkwood_clk_ctrl |= CGC_GE1; | ||
| 101 | |||
| 102 | orion_ge01_init(eth_data, | 268 | orion_ge01_init(eth_data, |
| 103 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, | 269 | GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, |
| 104 | IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); | 270 | IRQ_KIRKWOOD_GE01_ERR); |
| 105 | } | 271 | } |
| 106 | 272 | ||
| 107 | 273 | ||
| @@ -143,7 +309,6 @@ static struct platform_device kirkwood_nand_flash = { | |||
| 143 | void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, | 309 | void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, |
| 144 | int chip_delay) | 310 | int chip_delay) |
| 145 | { | 311 | { |
| 146 | kirkwood_clk_ctrl |= CGC_RUNIT; | ||
| 147 | kirkwood_nand_data.parts = parts; | 312 | kirkwood_nand_data.parts = parts; |
| 148 | kirkwood_nand_data.nr_parts = nr_parts; | 313 | kirkwood_nand_data.nr_parts = nr_parts; |
| 149 | kirkwood_nand_data.chip_delay = chip_delay; | 314 | kirkwood_nand_data.chip_delay = chip_delay; |
| @@ -153,7 +318,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, | |||
| 153 | void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, | 318 | void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, |
| 154 | int (*dev_ready)(struct mtd_info *)) | 319 | int (*dev_ready)(struct mtd_info *)) |
| 155 | { | 320 | { |
| 156 | kirkwood_clk_ctrl |= CGC_RUNIT; | ||
| 157 | kirkwood_nand_data.parts = parts; | 321 | kirkwood_nand_data.parts = parts; |
| 158 | kirkwood_nand_data.nr_parts = nr_parts; | 322 | kirkwood_nand_data.nr_parts = nr_parts; |
| 159 | kirkwood_nand_data.dev_ready = dev_ready; | 323 | kirkwood_nand_data.dev_ready = dev_ready; |
| @@ -174,10 +338,6 @@ static void __init kirkwood_rtc_init(void) | |||
| 174 | ****************************************************************************/ | 338 | ****************************************************************************/ |
| 175 | void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) | 339 | void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) |
| 176 | { | 340 | { |
| 177 | kirkwood_clk_ctrl |= CGC_SATA0; | ||
| 178 | if (sata_data->n_ports > 1) | ||
| 179 | kirkwood_clk_ctrl |= CGC_SATA1; | ||
| 180 | |||
| 181 | orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); | 341 | orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); |
| 182 | } | 342 | } |
| 183 | 343 | ||
| @@ -220,7 +380,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) | |||
| 220 | mvsdio_data->clock = 100000000; | 380 | mvsdio_data->clock = 100000000; |
| 221 | else | 381 | else |
| 222 | mvsdio_data->clock = 200000000; | 382 | mvsdio_data->clock = 200000000; |
| 223 | kirkwood_clk_ctrl |= CGC_SDIO; | ||
| 224 | kirkwood_sdio.dev.platform_data = mvsdio_data; | 383 | kirkwood_sdio.dev.platform_data = mvsdio_data; |
| 225 | platform_device_register(&kirkwood_sdio); | 384 | platform_device_register(&kirkwood_sdio); |
| 226 | } | 385 | } |
| @@ -231,8 +390,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) | |||
| 231 | ****************************************************************************/ | 390 | ****************************************************************************/ |
| 232 | void __init kirkwood_spi_init() | 391 | void __init kirkwood_spi_init() |
| 233 | { | 392 | { |
| 234 | kirkwood_clk_ctrl |= CGC_RUNIT; | 393 | orion_spi_init(SPI_PHYS_BASE); |
| 235 | orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk); | ||
| 236 | } | 394 | } |
| 237 | 395 | ||
| 238 | 396 | ||
| @@ -252,7 +410,7 @@ void __init kirkwood_i2c_init(void) | |||
| 252 | void __init kirkwood_uart0_init(void) | 410 | void __init kirkwood_uart0_init(void) |
| 253 | { | 411 | { |
| 254 | orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, | 412 | orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, |
| 255 | IRQ_KIRKWOOD_UART_0, kirkwood_tclk); | 413 | IRQ_KIRKWOOD_UART_0, tclk); |
| 256 | } | 414 | } |
| 257 | 415 | ||
| 258 | 416 | ||
| @@ -262,7 +420,7 @@ void __init kirkwood_uart0_init(void) | |||
| 262 | void __init kirkwood_uart1_init(void) | 420 | void __init kirkwood_uart1_init(void) |
| 263 | { | 421 | { |
| 264 | orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, | 422 | orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, |
| 265 | IRQ_KIRKWOOD_UART_1, kirkwood_tclk); | 423 | IRQ_KIRKWOOD_UART_1, tclk); |
| 266 | } | 424 | } |
| 267 | 425 | ||
| 268 | /***************************************************************************** | 426 | /***************************************************************************** |
| @@ -270,7 +428,6 @@ void __init kirkwood_uart1_init(void) | |||
| 270 | ****************************************************************************/ | 428 | ****************************************************************************/ |
| 271 | void __init kirkwood_crypto_init(void) | 429 | void __init kirkwood_crypto_init(void) |
| 272 | { | 430 | { |
| 273 | kirkwood_clk_ctrl |= CGC_CRYPTO; | ||
| 274 | orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, | 431 | orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, |
| 275 | KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); | 432 | KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); |
| 276 | } | 433 | } |
| @@ -281,8 +438,6 @@ void __init kirkwood_crypto_init(void) | |||
| 281 | ****************************************************************************/ | 438 | ****************************************************************************/ |
| 282 | void __init kirkwood_xor0_init(void) | 439 | void __init kirkwood_xor0_init(void) |
| 283 | { | 440 | { |
| 284 | kirkwood_clk_ctrl |= CGC_XOR0; | ||
| 285 | |||
| 286 | orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, | 441 | orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, |
| 287 | IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); | 442 | IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); |
| 288 | } | 443 | } |
| @@ -293,8 +448,6 @@ void __init kirkwood_xor0_init(void) | |||
| 293 | ****************************************************************************/ | 448 | ****************************************************************************/ |
| 294 | void __init kirkwood_xor1_init(void) | 449 | void __init kirkwood_xor1_init(void) |
| 295 | { | 450 | { |
| 296 | kirkwood_clk_ctrl |= CGC_XOR1; | ||
| 297 | |||
| 298 | orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, | 451 | orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, |
| 299 | IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); | 452 | IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); |
| 300 | } | 453 | } |
| @@ -305,7 +458,7 @@ void __init kirkwood_xor1_init(void) | |||
| 305 | ****************************************************************************/ | 458 | ****************************************************************************/ |
| 306 | void __init kirkwood_wdt_init(void) | 459 | void __init kirkwood_wdt_init(void) |
| 307 | { | 460 | { |
| 308 | orion_wdt_init(kirkwood_tclk); | 461 | orion_wdt_init(); |
| 309 | } | 462 | } |
| 310 | 463 | ||
| 311 | 464 | ||
| @@ -381,7 +534,6 @@ static struct platform_device kirkwood_pcm_device = { | |||
| 381 | 534 | ||
| 382 | void __init kirkwood_audio_init(void) | 535 | void __init kirkwood_audio_init(void) |
| 383 | { | 536 | { |
| 384 | kirkwood_clk_ctrl |= CGC_AUDIO; | ||
| 385 | platform_device_register(&kirkwood_i2s_device); | 537 | platform_device_register(&kirkwood_i2s_device); |
| 386 | platform_device_register(&kirkwood_pcm_device); | 538 | platform_device_register(&kirkwood_pcm_device); |
| 387 | } | 539 | } |
| @@ -465,6 +617,9 @@ void __init kirkwood_init(void) | |||
| 465 | kirkwood_l2_init(); | 617 | kirkwood_l2_init(); |
| 466 | #endif | 618 | #endif |
| 467 | 619 | ||
| 620 | /* Setup root of clk tree */ | ||
| 621 | kirkwood_clk_init(); | ||
| 622 | |||
| 468 | /* internal devices that every board has */ | 623 | /* internal devices that every board has */ |
| 469 | kirkwood_rtc_init(); | 624 | kirkwood_rtc_init(); |
| 470 | kirkwood_wdt_init(); | 625 | kirkwood_wdt_init(); |
| @@ -477,61 +632,6 @@ void __init kirkwood_init(void) | |||
| 477 | #endif | 632 | #endif |
| 478 | } | 633 | } |
| 479 | 634 | ||
| 480 | static int __init kirkwood_clock_gate(void) | ||
| 481 | { | ||
| 482 | unsigned int curr = readl(CLOCK_GATING_CTRL); | ||
| 483 | u32 dev, rev; | ||
| 484 | |||
| 485 | kirkwood_pcie_id(&dev, &rev); | ||
| 486 | printk(KERN_DEBUG "Gating clock of unused units\n"); | ||
| 487 | printk(KERN_DEBUG "before: 0x%08x\n", curr); | ||
| 488 | |||
| 489 | /* Make sure those units are accessible */ | ||
| 490 | writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL); | ||
| 491 | |||
| 492 | /* For SATA: first shutdown the phy */ | ||
| 493 | if (!(kirkwood_clk_ctrl & CGC_SATA0)) { | ||
| 494 | /* Disable PLL and IVREF */ | ||
| 495 | writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); | ||
| 496 | /* Disable PHY */ | ||
| 497 | writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); | ||
| 498 | } | ||
| 499 | if (!(kirkwood_clk_ctrl & CGC_SATA1)) { | ||
| 500 | /* Disable PLL and IVREF */ | ||
| 501 | writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); | ||
| 502 | /* Disable PHY */ | ||
| 503 | writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); | ||
| 504 | } | ||
| 505 | |||
| 506 | /* For PCIe: first shutdown the phy */ | ||
| 507 | if (!(kirkwood_clk_ctrl & CGC_PEX0)) { | ||
| 508 | writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); | ||
| 509 | while (1) | ||
| 510 | if (readl(PCIE_STATUS) & 0x1) | ||
| 511 | break; | ||
| 512 | writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); | ||
| 513 | } | ||
| 514 | |||
| 515 | /* For PCIe 1: first shutdown the phy */ | ||
| 516 | if (dev == MV88F6282_DEV_ID) { | ||
| 517 | if (!(kirkwood_clk_ctrl & CGC_PEX1)) { | ||
| 518 | writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); | ||
| 519 | while (1) | ||
| 520 | if (readl(PCIE1_STATUS) & 0x1) | ||
| 521 | break; | ||
| 522 | writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); | ||
| 523 | } | ||
| 524 | } else /* keep this bit set for devices that don't have PCIe1 */ | ||
| 525 | kirkwood_clk_ctrl |= CGC_PEX1; | ||
| 526 | |||
| 527 | /* Now gate clock the required units */ | ||
| 528 | writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL); | ||
| 529 | printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL)); | ||
| 530 | |||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | late_initcall(kirkwood_clock_gate); | ||
| 534 | |||
| 535 | void kirkwood_restart(char mode, const char *cmd) | 635 | void kirkwood_restart(char mode, const char *cmd) |
| 536 | { | 636 | { |
| 537 | /* | 637 | /* |
