0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/init.h>
0012 #include <linux/io.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/dma-mapping.h>
0015 #include <linux/serial_8250.h>
0016 #include <linux/mv643xx_i2c.h>
0017 #include <linux/ata_platform.h>
0018 #include <linux/delay.h>
0019 #include <linux/clk-provider.h>
0020 #include <linux/cpu.h>
0021 #include <linux/platform_data/dsa.h>
0022 #include <asm/page.h>
0023 #include <asm/setup.h>
0024 #include <asm/system_misc.h>
0025 #include <asm/mach/arch.h>
0026 #include <asm/mach/map.h>
0027 #include <asm/mach/time.h>
0028 #include <linux/platform_data/mtd-orion_nand.h>
0029 #include <linux/platform_data/usb-ehci-orion.h>
0030 #include <plat/time.h>
0031 #include <plat/common.h>
0032
0033 #include "bridge-regs.h"
0034 #include "common.h"
0035 #include "orion5x.h"
0036
0037
0038
0039
0040 static struct map_desc orion5x_io_desc[] __initdata = {
0041 {
0042 .virtual = (unsigned long) ORION5X_REGS_VIRT_BASE,
0043 .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
0044 .length = ORION5X_REGS_SIZE,
0045 .type = MT_DEVICE,
0046 }, {
0047 .virtual = (unsigned long) ORION5X_PCIE_WA_VIRT_BASE,
0048 .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
0049 .length = ORION5X_PCIE_WA_SIZE,
0050 .type = MT_DEVICE,
0051 },
0052 };
0053
0054 void __init orion5x_map_io(void)
0055 {
0056 iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
0057 }
0058
0059
0060
0061
0062
0063 static struct clk *tclk;
0064
0065 void __init clk_init(void)
0066 {
0067 tclk = clk_register_fixed_rate(NULL, "tclk", NULL, 0, orion5x_tclk);
0068
0069 orion_clkdev_init(tclk);
0070 }
0071
0072
0073
0074
0075 void __init orion5x_ehci0_init(void)
0076 {
0077 orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL,
0078 EHCI_PHY_ORION);
0079 }
0080
0081
0082
0083
0084
0085 void __init orion5x_ehci1_init(void)
0086 {
0087 orion_ehci_1_init(ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
0088 }
0089
0090
0091
0092
0093
0094 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
0095 {
0096 orion_ge00_init(eth_data,
0097 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
0098 IRQ_ORION5X_ETH_ERR,
0099 MV643XX_TX_CSUM_DEFAULT_LIMIT);
0100 }
0101
0102
0103
0104
0105
0106 void __init orion5x_eth_switch_init(struct dsa_chip_data *d)
0107 {
0108 orion_ge00_switch_init(d);
0109 }
0110
0111
0112
0113
0114
0115 void __init orion5x_i2c_init(void)
0116 {
0117 orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8);
0118
0119 }
0120
0121
0122
0123
0124
0125 void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
0126 {
0127 orion_sata_init(sata_data, ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
0128 }
0129
0130
0131
0132
0133
0134 void __init orion5x_spi_init(void)
0135 {
0136 orion_spi_init(SPI_PHYS_BASE);
0137 }
0138
0139
0140
0141
0142
0143 void __init orion5x_uart0_init(void)
0144 {
0145 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
0146 IRQ_ORION5X_UART0, tclk);
0147 }
0148
0149
0150
0151
0152 void __init orion5x_uart1_init(void)
0153 {
0154 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
0155 IRQ_ORION5X_UART1, tclk);
0156 }
0157
0158
0159
0160
0161 void __init orion5x_xor_init(void)
0162 {
0163 orion_xor0_init(ORION5X_XOR_PHYS_BASE,
0164 ORION5X_XOR_PHYS_BASE + 0x200,
0165 IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1);
0166 }
0167
0168
0169
0170
0171 static void __init orion5x_crypto_init(void)
0172 {
0173 mvebu_mbus_add_window_by_id(ORION_MBUS_SRAM_TARGET,
0174 ORION_MBUS_SRAM_ATTR,
0175 ORION5X_SRAM_PHYS_BASE,
0176 ORION5X_SRAM_SIZE);
0177 orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
0178 SZ_8K, IRQ_ORION5X_CESA);
0179 }
0180
0181
0182
0183
0184 static struct resource orion_wdt_resource[] = {
0185 DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
0186 DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
0187 };
0188
0189 static struct platform_device orion_wdt_device = {
0190 .name = "orion_wdt",
0191 .id = -1,
0192 .num_resources = ARRAY_SIZE(orion_wdt_resource),
0193 .resource = orion_wdt_resource,
0194 };
0195
0196 static void __init orion5x_wdt_init(void)
0197 {
0198 platform_device_register(&orion_wdt_device);
0199 }
0200
0201
0202
0203
0204
0205 void __init orion5x_init_early(void)
0206 {
0207 u32 rev, dev;
0208 const char *mbus_soc_name;
0209
0210 orion_time_set_base(TIMER_VIRT_BASE);
0211
0212
0213 orion5x_pcie_id(&dev, &rev);
0214 if (dev == MV88F5281_DEV_ID)
0215 mbus_soc_name = "marvell,orion5x-88f5281-mbus";
0216 else if (dev == MV88F5182_DEV_ID)
0217 mbus_soc_name = "marvell,orion5x-88f5182-mbus";
0218 else if (dev == MV88F5181_DEV_ID)
0219 mbus_soc_name = "marvell,orion5x-88f5181-mbus";
0220 else if (dev == MV88F6183_DEV_ID)
0221 mbus_soc_name = "marvell,orion5x-88f6183-mbus";
0222 else
0223 mbus_soc_name = NULL;
0224 mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
0225 ORION5X_BRIDGE_WINS_SZ,
0226 ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
0227 }
0228
0229 void orion5x_setup_wins(void)
0230 {
0231
0232
0233
0234
0235 mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCIE_IO_TARGET,
0236 ORION_MBUS_PCIE_IO_ATTR,
0237 ORION5X_PCIE_IO_PHYS_BASE,
0238 ORION5X_PCIE_IO_SIZE,
0239 ORION5X_PCIE_IO_BUS_BASE);
0240 mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_MEM_TARGET,
0241 ORION_MBUS_PCIE_MEM_ATTR,
0242 ORION5X_PCIE_MEM_PHYS_BASE,
0243 ORION5X_PCIE_MEM_SIZE);
0244 mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCI_IO_TARGET,
0245 ORION_MBUS_PCI_IO_ATTR,
0246 ORION5X_PCI_IO_PHYS_BASE,
0247 ORION5X_PCI_IO_SIZE,
0248 ORION5X_PCI_IO_BUS_BASE);
0249 mvebu_mbus_add_window_by_id(ORION_MBUS_PCI_MEM_TARGET,
0250 ORION_MBUS_PCI_MEM_ATTR,
0251 ORION5X_PCI_MEM_PHYS_BASE,
0252 ORION5X_PCI_MEM_SIZE);
0253 }
0254
0255 int orion5x_tclk;
0256
0257 static int __init orion5x_find_tclk(void)
0258 {
0259 u32 dev, rev;
0260
0261 orion5x_pcie_id(&dev, &rev);
0262 if (dev == MV88F6183_DEV_ID &&
0263 (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
0264 return 133333333;
0265
0266 return 166666667;
0267 }
0268
0269 void __init orion5x_timer_init(void)
0270 {
0271 orion5x_tclk = orion5x_find_tclk();
0272
0273 orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
0274 IRQ_ORION5X_BRIDGE, orion5x_tclk);
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284 void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
0285 {
0286 orion5x_pcie_id(dev, rev);
0287
0288 if (*dev == MV88F5281_DEV_ID) {
0289 if (*rev == MV88F5281_REV_D2) {
0290 *dev_name = "MV88F5281-D2";
0291 } else if (*rev == MV88F5281_REV_D1) {
0292 *dev_name = "MV88F5281-D1";
0293 } else if (*rev == MV88F5281_REV_D0) {
0294 *dev_name = "MV88F5281-D0";
0295 } else {
0296 *dev_name = "MV88F5281-Rev-Unsupported";
0297 }
0298 } else if (*dev == MV88F5182_DEV_ID) {
0299 if (*rev == MV88F5182_REV_A2) {
0300 *dev_name = "MV88F5182-A2";
0301 } else {
0302 *dev_name = "MV88F5182-Rev-Unsupported";
0303 }
0304 } else if (*dev == MV88F5181_DEV_ID) {
0305 if (*rev == MV88F5181_REV_B1) {
0306 *dev_name = "MV88F5181-Rev-B1";
0307 } else if (*rev == MV88F5181L_REV_A1) {
0308 *dev_name = "MV88F5181L-Rev-A1";
0309 } else {
0310 *dev_name = "MV88F5181(L)-Rev-Unsupported";
0311 }
0312 } else if (*dev == MV88F6183_DEV_ID) {
0313 if (*rev == MV88F6183_REV_B0) {
0314 *dev_name = "MV88F6183-Rev-B0";
0315 } else {
0316 *dev_name = "MV88F6183-Rev-Unsupported";
0317 }
0318 } else {
0319 *dev_name = "Device-Unknown";
0320 }
0321 }
0322
0323 void __init orion5x_init(void)
0324 {
0325 char *dev_name;
0326 u32 dev, rev;
0327
0328 orion5x_id(&dev, &rev, &dev_name);
0329 printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
0330
0331
0332
0333
0334 orion5x_setup_wins();
0335
0336
0337 clk_init();
0338
0339
0340
0341
0342
0343 if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
0344 printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
0345 cpu_idle_poll_ctrl(true);
0346 }
0347
0348
0349
0350
0351
0352 if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
0353 dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
0354 orion5x_crypto_init();
0355
0356
0357
0358
0359 orion5x_wdt_init();
0360 }
0361
0362 void orion5x_restart(enum reboot_mode mode, const char *cmd)
0363 {
0364
0365
0366
0367 orion5x_setbits(RSTOUTn_MASK, (1 << 2));
0368 orion5x_setbits(CPU_SOFT_RESET, 1);
0369 mdelay(200);
0370 orion5x_clrbits(CPU_SOFT_RESET, 1);
0371 }
0372
0373
0374
0375
0376
0377 void __init tag_fixup_mem32(struct tag *t, char **from)
0378 {
0379 for (; t->hdr.size; t = tag_next(t))
0380 if (t->hdr.tag == ATAG_MEM &&
0381 (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
0382 t->u.mem.start & ~PAGE_MASK)) {
0383 printk(KERN_WARNING
0384 "Clearing invalid memory bank %dKB@0x%08x\n",
0385 t->u.mem.size / 1024, t->u.mem.start);
0386 t->hdr.tag = 0;
0387 }
0388 }