162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/mach-orion5x/common.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Core functions for Marvell Orion 5x SoCs 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Maintainer: Tzachi Perelstein <tzachi@marvell.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/init.h> 1262306a36Sopenharmony_ci#include <linux/io.h> 1362306a36Sopenharmony_ci#include <linux/platform_device.h> 1462306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1562306a36Sopenharmony_ci#include <linux/serial_8250.h> 1662306a36Sopenharmony_ci#include <linux/mv643xx_i2c.h> 1762306a36Sopenharmony_ci#include <linux/ata_platform.h> 1862306a36Sopenharmony_ci#include <linux/delay.h> 1962306a36Sopenharmony_ci#include <linux/clk-provider.h> 2062306a36Sopenharmony_ci#include <linux/cpu.h> 2162306a36Sopenharmony_ci#include <asm/page.h> 2262306a36Sopenharmony_ci#include <asm/setup.h> 2362306a36Sopenharmony_ci#include <asm/system_misc.h> 2462306a36Sopenharmony_ci#include <asm/mach/arch.h> 2562306a36Sopenharmony_ci#include <asm/mach/map.h> 2662306a36Sopenharmony_ci#include <asm/mach/time.h> 2762306a36Sopenharmony_ci#include <linux/platform_data/mtd-orion_nand.h> 2862306a36Sopenharmony_ci#include <linux/platform_data/usb-ehci-orion.h> 2962306a36Sopenharmony_ci#include <plat/time.h> 3062306a36Sopenharmony_ci#include <plat/common.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#include "bridge-regs.h" 3362306a36Sopenharmony_ci#include "common.h" 3462306a36Sopenharmony_ci#include "orion5x.h" 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/***************************************************************************** 3762306a36Sopenharmony_ci * I/O Address Mapping 3862306a36Sopenharmony_ci ****************************************************************************/ 3962306a36Sopenharmony_cistatic struct map_desc orion5x_io_desc[] __initdata = { 4062306a36Sopenharmony_ci { 4162306a36Sopenharmony_ci .virtual = (unsigned long) ORION5X_REGS_VIRT_BASE, 4262306a36Sopenharmony_ci .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE), 4362306a36Sopenharmony_ci .length = ORION5X_REGS_SIZE, 4462306a36Sopenharmony_ci .type = MT_DEVICE, 4562306a36Sopenharmony_ci }, { 4662306a36Sopenharmony_ci .virtual = (unsigned long) ORION5X_PCIE_WA_VIRT_BASE, 4762306a36Sopenharmony_ci .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE), 4862306a36Sopenharmony_ci .length = ORION5X_PCIE_WA_SIZE, 4962306a36Sopenharmony_ci .type = MT_DEVICE, 5062306a36Sopenharmony_ci }, 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_civoid __init orion5x_map_io(void) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc)); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/***************************************************************************** 6062306a36Sopenharmony_ci * CLK tree 6162306a36Sopenharmony_ci ****************************************************************************/ 6262306a36Sopenharmony_cistatic struct clk *tclk; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_civoid __init clk_init(void) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci tclk = clk_register_fixed_rate(NULL, "tclk", NULL, 0, orion5x_tclk); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci orion_clkdev_init(tclk); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/***************************************************************************** 7262306a36Sopenharmony_ci * EHCI0 7362306a36Sopenharmony_ci ****************************************************************************/ 7462306a36Sopenharmony_civoid __init orion5x_ehci0_init(void) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL, 7762306a36Sopenharmony_ci EHCI_PHY_ORION); 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci/***************************************************************************** 8262306a36Sopenharmony_ci * EHCI1 8362306a36Sopenharmony_ci ****************************************************************************/ 8462306a36Sopenharmony_civoid __init orion5x_ehci1_init(void) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci orion_ehci_1_init(ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL); 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/***************************************************************************** 9162306a36Sopenharmony_ci * GE00 9262306a36Sopenharmony_ci ****************************************************************************/ 9362306a36Sopenharmony_civoid __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci orion_ge00_init(eth_data, 9662306a36Sopenharmony_ci ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, 9762306a36Sopenharmony_ci IRQ_ORION5X_ETH_ERR, 9862306a36Sopenharmony_ci MV643XX_TX_CSUM_DEFAULT_LIMIT); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/***************************************************************************** 10362306a36Sopenharmony_ci * I2C 10462306a36Sopenharmony_ci ****************************************************************************/ 10562306a36Sopenharmony_civoid __init orion5x_i2c_init(void) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/***************************************************************************** 11362306a36Sopenharmony_ci * SATA 11462306a36Sopenharmony_ci ****************************************************************************/ 11562306a36Sopenharmony_civoid __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci orion_sata_init(sata_data, ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/***************************************************************************** 12262306a36Sopenharmony_ci * SPI 12362306a36Sopenharmony_ci ****************************************************************************/ 12462306a36Sopenharmony_civoid __init orion5x_spi_init(void) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci orion_spi_init(SPI_PHYS_BASE); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/***************************************************************************** 13162306a36Sopenharmony_ci * UART0 13262306a36Sopenharmony_ci ****************************************************************************/ 13362306a36Sopenharmony_civoid __init orion5x_uart0_init(void) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, 13662306a36Sopenharmony_ci IRQ_ORION5X_UART0, tclk); 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/***************************************************************************** 14062306a36Sopenharmony_ci * UART1 14162306a36Sopenharmony_ci ****************************************************************************/ 14262306a36Sopenharmony_civoid __init orion5x_uart1_init(void) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, 14562306a36Sopenharmony_ci IRQ_ORION5X_UART1, tclk); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/***************************************************************************** 14962306a36Sopenharmony_ci * XOR engine 15062306a36Sopenharmony_ci ****************************************************************************/ 15162306a36Sopenharmony_civoid __init orion5x_xor_init(void) 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci orion_xor0_init(ORION5X_XOR_PHYS_BASE, 15462306a36Sopenharmony_ci ORION5X_XOR_PHYS_BASE + 0x200, 15562306a36Sopenharmony_ci IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci/***************************************************************************** 15962306a36Sopenharmony_ci * Cryptographic Engines and Security Accelerator (CESA) 16062306a36Sopenharmony_ci ****************************************************************************/ 16162306a36Sopenharmony_cistatic void __init orion5x_crypto_init(void) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci mvebu_mbus_add_window_by_id(ORION_MBUS_SRAM_TARGET, 16462306a36Sopenharmony_ci ORION_MBUS_SRAM_ATTR, 16562306a36Sopenharmony_ci ORION5X_SRAM_PHYS_BASE, 16662306a36Sopenharmony_ci ORION5X_SRAM_SIZE); 16762306a36Sopenharmony_ci orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, 16862306a36Sopenharmony_ci SZ_8K, IRQ_ORION5X_CESA); 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci/***************************************************************************** 17262306a36Sopenharmony_ci * Watchdog 17362306a36Sopenharmony_ci ****************************************************************************/ 17462306a36Sopenharmony_cistatic struct resource orion_wdt_resource[] = { 17562306a36Sopenharmony_ci DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04), 17662306a36Sopenharmony_ci DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04), 17762306a36Sopenharmony_ci}; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic struct platform_device orion_wdt_device = { 18062306a36Sopenharmony_ci .name = "orion_wdt", 18162306a36Sopenharmony_ci .id = -1, 18262306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(orion_wdt_resource), 18362306a36Sopenharmony_ci .resource = orion_wdt_resource, 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic void __init orion5x_wdt_init(void) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci platform_device_register(&orion_wdt_device); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/***************************************************************************** 19362306a36Sopenharmony_ci * Time handling 19462306a36Sopenharmony_ci ****************************************************************************/ 19562306a36Sopenharmony_civoid __init orion5x_init_early(void) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci u32 rev, dev; 19862306a36Sopenharmony_ci const char *mbus_soc_name; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci orion_time_set_base(TIMER_VIRT_BASE); 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* Initialize the MBUS driver */ 20362306a36Sopenharmony_ci orion5x_pcie_id(&dev, &rev); 20462306a36Sopenharmony_ci if (dev == MV88F5281_DEV_ID) 20562306a36Sopenharmony_ci mbus_soc_name = "marvell,orion5x-88f5281-mbus"; 20662306a36Sopenharmony_ci else if (dev == MV88F5182_DEV_ID) 20762306a36Sopenharmony_ci mbus_soc_name = "marvell,orion5x-88f5182-mbus"; 20862306a36Sopenharmony_ci else if (dev == MV88F5181_DEV_ID) 20962306a36Sopenharmony_ci mbus_soc_name = "marvell,orion5x-88f5181-mbus"; 21062306a36Sopenharmony_ci else if (dev == MV88F6183_DEV_ID) 21162306a36Sopenharmony_ci mbus_soc_name = "marvell,orion5x-88f6183-mbus"; 21262306a36Sopenharmony_ci else 21362306a36Sopenharmony_ci mbus_soc_name = NULL; 21462306a36Sopenharmony_ci mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE, 21562306a36Sopenharmony_ci ORION5X_BRIDGE_WINS_SZ, 21662306a36Sopenharmony_ci ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ); 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_civoid orion5x_setup_wins(void) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci /* 22262306a36Sopenharmony_ci * The PCIe windows will no longer be statically allocated 22362306a36Sopenharmony_ci * here once Orion5x is migrated to the pci-mvebu driver. 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_ci mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCIE_IO_TARGET, 22662306a36Sopenharmony_ci ORION_MBUS_PCIE_IO_ATTR, 22762306a36Sopenharmony_ci ORION5X_PCIE_IO_PHYS_BASE, 22862306a36Sopenharmony_ci ORION5X_PCIE_IO_SIZE, 22962306a36Sopenharmony_ci ORION5X_PCIE_IO_BUS_BASE); 23062306a36Sopenharmony_ci mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_MEM_TARGET, 23162306a36Sopenharmony_ci ORION_MBUS_PCIE_MEM_ATTR, 23262306a36Sopenharmony_ci ORION5X_PCIE_MEM_PHYS_BASE, 23362306a36Sopenharmony_ci ORION5X_PCIE_MEM_SIZE); 23462306a36Sopenharmony_ci mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCI_IO_TARGET, 23562306a36Sopenharmony_ci ORION_MBUS_PCI_IO_ATTR, 23662306a36Sopenharmony_ci ORION5X_PCI_IO_PHYS_BASE, 23762306a36Sopenharmony_ci ORION5X_PCI_IO_SIZE, 23862306a36Sopenharmony_ci ORION5X_PCI_IO_BUS_BASE); 23962306a36Sopenharmony_ci mvebu_mbus_add_window_by_id(ORION_MBUS_PCI_MEM_TARGET, 24062306a36Sopenharmony_ci ORION_MBUS_PCI_MEM_ATTR, 24162306a36Sopenharmony_ci ORION5X_PCI_MEM_PHYS_BASE, 24262306a36Sopenharmony_ci ORION5X_PCI_MEM_SIZE); 24362306a36Sopenharmony_ci} 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ciint orion5x_tclk; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic int __init orion5x_find_tclk(void) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci u32 dev, rev; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci orion5x_pcie_id(&dev, &rev); 25262306a36Sopenharmony_ci if (dev == MV88F6183_DEV_ID && 25362306a36Sopenharmony_ci (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0) 25462306a36Sopenharmony_ci return 133333333; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci return 166666667; 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_civoid __init orion5x_timer_init(void) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci orion5x_tclk = orion5x_find_tclk(); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR, 26462306a36Sopenharmony_ci IRQ_ORION5X_BRIDGE, orion5x_tclk); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci/***************************************************************************** 26962306a36Sopenharmony_ci * General 27062306a36Sopenharmony_ci ****************************************************************************/ 27162306a36Sopenharmony_ci/* 27262306a36Sopenharmony_ci * Identify device ID and rev from PCIe configuration header space '0'. 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_civoid __init orion5x_id(u32 *dev, u32 *rev, char **dev_name) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci orion5x_pcie_id(dev, rev); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci if (*dev == MV88F5281_DEV_ID) { 27962306a36Sopenharmony_ci if (*rev == MV88F5281_REV_D2) { 28062306a36Sopenharmony_ci *dev_name = "MV88F5281-D2"; 28162306a36Sopenharmony_ci } else if (*rev == MV88F5281_REV_D1) { 28262306a36Sopenharmony_ci *dev_name = "MV88F5281-D1"; 28362306a36Sopenharmony_ci } else if (*rev == MV88F5281_REV_D0) { 28462306a36Sopenharmony_ci *dev_name = "MV88F5281-D0"; 28562306a36Sopenharmony_ci } else { 28662306a36Sopenharmony_ci *dev_name = "MV88F5281-Rev-Unsupported"; 28762306a36Sopenharmony_ci } 28862306a36Sopenharmony_ci } else if (*dev == MV88F5182_DEV_ID) { 28962306a36Sopenharmony_ci if (*rev == MV88F5182_REV_A2) { 29062306a36Sopenharmony_ci *dev_name = "MV88F5182-A2"; 29162306a36Sopenharmony_ci } else { 29262306a36Sopenharmony_ci *dev_name = "MV88F5182-Rev-Unsupported"; 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci } else if (*dev == MV88F5181_DEV_ID) { 29562306a36Sopenharmony_ci if (*rev == MV88F5181_REV_B1) { 29662306a36Sopenharmony_ci *dev_name = "MV88F5181-Rev-B1"; 29762306a36Sopenharmony_ci } else if (*rev == MV88F5181L_REV_A1) { 29862306a36Sopenharmony_ci *dev_name = "MV88F5181L-Rev-A1"; 29962306a36Sopenharmony_ci } else { 30062306a36Sopenharmony_ci *dev_name = "MV88F5181(L)-Rev-Unsupported"; 30162306a36Sopenharmony_ci } 30262306a36Sopenharmony_ci } else if (*dev == MV88F6183_DEV_ID) { 30362306a36Sopenharmony_ci if (*rev == MV88F6183_REV_B0) { 30462306a36Sopenharmony_ci *dev_name = "MV88F6183-Rev-B0"; 30562306a36Sopenharmony_ci } else { 30662306a36Sopenharmony_ci *dev_name = "MV88F6183-Rev-Unsupported"; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci } else { 30962306a36Sopenharmony_ci *dev_name = "Device-Unknown"; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci} 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_civoid __init orion5x_init(void) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci char *dev_name; 31662306a36Sopenharmony_ci u32 dev, rev; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci orion5x_id(&dev, &rev, &dev_name); 31962306a36Sopenharmony_ci printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci /* 32262306a36Sopenharmony_ci * Setup Orion address map 32362306a36Sopenharmony_ci */ 32462306a36Sopenharmony_ci orion5x_setup_wins(); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci /* Setup root of clk tree */ 32762306a36Sopenharmony_ci clk_init(); 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci /* 33062306a36Sopenharmony_ci * Don't issue "Wait for Interrupt" instruction if we are 33162306a36Sopenharmony_ci * running on D0 5281 silicon. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) { 33462306a36Sopenharmony_ci printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n"); 33562306a36Sopenharmony_ci cpu_idle_poll_ctrl(true); 33662306a36Sopenharmony_ci } 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci /* 33962306a36Sopenharmony_ci * The 5082/5181l/5182/6082/6082l/6183 have crypto 34062306a36Sopenharmony_ci * while 5180n/5181/5281 don't have crypto. 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) || 34362306a36Sopenharmony_ci dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID) 34462306a36Sopenharmony_ci orion5x_crypto_init(); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci /* 34762306a36Sopenharmony_ci * Register watchdog driver 34862306a36Sopenharmony_ci */ 34962306a36Sopenharmony_ci orion5x_wdt_init(); 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_civoid orion5x_restart(enum reboot_mode mode, const char *cmd) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci /* 35562306a36Sopenharmony_ci * Enable and issue soft reset 35662306a36Sopenharmony_ci */ 35762306a36Sopenharmony_ci orion5x_setbits(RSTOUTn_MASK, (1 << 2)); 35862306a36Sopenharmony_ci orion5x_setbits(CPU_SOFT_RESET, 1); 35962306a36Sopenharmony_ci mdelay(200); 36062306a36Sopenharmony_ci orion5x_clrbits(CPU_SOFT_RESET, 1); 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci/* 36462306a36Sopenharmony_ci * Many orion-based systems have buggy bootloader implementations. 36562306a36Sopenharmony_ci * This is a common fixup for bogus memory tags. 36662306a36Sopenharmony_ci */ 36762306a36Sopenharmony_civoid __init tag_fixup_mem32(struct tag *t, char **from) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci for (; t->hdr.size; t = tag_next(t)) 37062306a36Sopenharmony_ci if (t->hdr.tag == ATAG_MEM && 37162306a36Sopenharmony_ci (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK || 37262306a36Sopenharmony_ci t->u.mem.start & ~PAGE_MASK)) { 37362306a36Sopenharmony_ci printk(KERN_WARNING 37462306a36Sopenharmony_ci "Clearing invalid memory bank %dKB@0x%08x\n", 37562306a36Sopenharmony_ci t->u.mem.size / 1024, t->u.mem.start); 37662306a36Sopenharmony_ci t->hdr.tag = 0; 37762306a36Sopenharmony_ci } 37862306a36Sopenharmony_ci} 379