18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Board setup routines for the Emerson KSI8560 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Author: Alexandr Smirnov <asmirnov@ru.mvista.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Based on mpc85xx_ads.c maintained by Kumar Gala 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * 2008 (c) MontaVista, Software, Inc. This file is licensed under 98c2ecf20Sopenharmony_ci * the terms of the GNU General Public License version 2. This program 108c2ecf20Sopenharmony_ci * is licensed "as is" without any warranty of any kind, whether express 118c2ecf20Sopenharmony_ci * or implied. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/stddef.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/pci.h> 188c2ecf20Sopenharmony_ci#include <linux/kdev_t.h> 198c2ecf20Sopenharmony_ci#include <linux/delay.h> 208c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 218c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <asm/time.h> 248c2ecf20Sopenharmony_ci#include <asm/machdep.h> 258c2ecf20Sopenharmony_ci#include <asm/pci-bridge.h> 268c2ecf20Sopenharmony_ci#include <asm/mpic.h> 278c2ecf20Sopenharmony_ci#include <mm/mmu_decl.h> 288c2ecf20Sopenharmony_ci#include <asm/udbg.h> 298c2ecf20Sopenharmony_ci#include <asm/prom.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <sysdev/fsl_soc.h> 328c2ecf20Sopenharmony_ci#include <sysdev/fsl_pci.h> 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <asm/cpm2.h> 358c2ecf20Sopenharmony_ci#include <sysdev/cpm2_pic.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "mpc85xx.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */ 408c2ecf20Sopenharmony_ci#define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */ 418c2ecf20Sopenharmony_ci#define KSI8560_CPLD_RCR1 0x30 /* Reset Command Register 1 */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define KSI8560_CPLD_RCR1_CPUHR 0x80 /* CPU Hard Reset */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic void __iomem *cpld_base = NULL; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic void __noreturn machine_restart(char *cmd) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci if (cpld_base) 508c2ecf20Sopenharmony_ci out_8(cpld_base + KSI8560_CPLD_RCR1, KSI8560_CPLD_RCR1_CPUHR); 518c2ecf20Sopenharmony_ci else 528c2ecf20Sopenharmony_ci printk(KERN_ERR "Can't find CPLD base, hang forever\n"); 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci for (;;); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic void __init ksi8560_pic_init(void) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN, 608c2ecf20Sopenharmony_ci 0, 256, " OpenPIC "); 618c2ecf20Sopenharmony_ci BUG_ON(mpic == NULL); 628c2ecf20Sopenharmony_ci mpic_init(mpic); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci mpc85xx_cpm2_pic_init(); 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#ifdef CONFIG_CPM2 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * Setup I/O ports 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_cistruct cpm_pin { 728c2ecf20Sopenharmony_ci int port, pin, flags; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic struct cpm_pin __initdata ksi8560_pins[] = { 768c2ecf20Sopenharmony_ci /* SCC1 */ 778c2ecf20Sopenharmony_ci {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 788c2ecf20Sopenharmony_ci {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 798c2ecf20Sopenharmony_ci {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci /* SCC2 */ 828c2ecf20Sopenharmony_ci {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 838c2ecf20Sopenharmony_ci {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 848c2ecf20Sopenharmony_ci {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* FCC1 */ 878c2ecf20Sopenharmony_ci {0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 888c2ecf20Sopenharmony_ci {0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 898c2ecf20Sopenharmony_ci {0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 908c2ecf20Sopenharmony_ci {0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 918c2ecf20Sopenharmony_ci {0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 928c2ecf20Sopenharmony_ci {0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 938c2ecf20Sopenharmony_ci {0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 948c2ecf20Sopenharmony_ci {0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 958c2ecf20Sopenharmony_ci {0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, 968c2ecf20Sopenharmony_ci {0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, 978c2ecf20Sopenharmony_ci {0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 988c2ecf20Sopenharmony_ci {0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 998c2ecf20Sopenharmony_ci {0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, 1008c2ecf20Sopenharmony_ci {0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, 1018c2ecf20Sopenharmony_ci {2, 23, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK9 */ 1028c2ecf20Sopenharmony_ci {2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK10 */ 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci}; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic void __init init_ioports(void) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci int i; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ksi8560_pins); i++) { 1118c2ecf20Sopenharmony_ci struct cpm_pin *pin = &ksi8560_pins[i]; 1128c2ecf20Sopenharmony_ci cpm2_set_pin(pin->port, pin->pin, pin->flags); 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX); 1168c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX); 1178c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX); 1188c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX); 1198c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK9, CPM_CLK_RX); 1208c2ecf20Sopenharmony_ci cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX); 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci#endif 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/* 1258c2ecf20Sopenharmony_ci * Setup the architecture 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_cistatic void __init ksi8560_setup_arch(void) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci struct device_node *cpld; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci cpld = of_find_compatible_node(NULL, NULL, "emerson,KSI8560-cpld"); 1328c2ecf20Sopenharmony_ci if (cpld) 1338c2ecf20Sopenharmony_ci cpld_base = of_iomap(cpld, 0); 1348c2ecf20Sopenharmony_ci else 1358c2ecf20Sopenharmony_ci printk(KERN_ERR "Can't find CPLD in device tree\n"); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci if (ppc_md.progress) 1388c2ecf20Sopenharmony_ci ppc_md.progress("ksi8560_setup_arch()", 0); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#ifdef CONFIG_CPM2 1418c2ecf20Sopenharmony_ci cpm2_reset(); 1428c2ecf20Sopenharmony_ci init_ioports(); 1438c2ecf20Sopenharmony_ci#endif 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic void ksi8560_show_cpuinfo(struct seq_file *m) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci uint pvid, svid, phid1; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci pvid = mfspr(SPRN_PVR); 1518c2ecf20Sopenharmony_ci svid = mfspr(SPRN_SVR); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci seq_printf(m, "Vendor\t\t: Emerson Network Power\n"); 1548c2ecf20Sopenharmony_ci seq_printf(m, "Board\t\t: KSI8560\n"); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci if (cpld_base) { 1578c2ecf20Sopenharmony_ci seq_printf(m, "Hardware rev\t: %d\n", 1588c2ecf20Sopenharmony_ci in_8(cpld_base + KSI8560_CPLD_HVR)); 1598c2ecf20Sopenharmony_ci seq_printf(m, "CPLD rev\t: %d\n", 1608c2ecf20Sopenharmony_ci in_8(cpld_base + KSI8560_CPLD_PVR)); 1618c2ecf20Sopenharmony_ci } else 1628c2ecf20Sopenharmony_ci seq_printf(m, "Unknown Hardware and CPLD revs\n"); 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 1658c2ecf20Sopenharmony_ci seq_printf(m, "SVR\t\t: 0x%x\n", svid); 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* Display cpu Pll setting */ 1688c2ecf20Sopenharmony_ci phid1 = mfspr(SPRN_HID1); 1698c2ecf20Sopenharmony_ci seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cimachine_device_initcall(ksi8560, mpc85xx_common_publish_devices); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci/* 1758c2ecf20Sopenharmony_ci * Called very early, device-tree isn't unflattened 1768c2ecf20Sopenharmony_ci */ 1778c2ecf20Sopenharmony_cistatic int __init ksi8560_probe(void) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci return of_machine_is_compatible("emerson,KSI8560"); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cidefine_machine(ksi8560) { 1838c2ecf20Sopenharmony_ci .name = "KSI8560", 1848c2ecf20Sopenharmony_ci .probe = ksi8560_probe, 1858c2ecf20Sopenharmony_ci .setup_arch = ksi8560_setup_arch, 1868c2ecf20Sopenharmony_ci .init_IRQ = ksi8560_pic_init, 1878c2ecf20Sopenharmony_ci .show_cpuinfo = ksi8560_show_cpuinfo, 1888c2ecf20Sopenharmony_ci .get_irq = mpic_get_irq, 1898c2ecf20Sopenharmony_ci .restart = machine_restart, 1908c2ecf20Sopenharmony_ci .calibrate_decr = generic_calibrate_decr, 1918c2ecf20Sopenharmony_ci}; 192