18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Li Yang <LeoLi@freescale.com> 68c2ecf20Sopenharmony_ci * Yin Olivia <Hong-hua.Yin@freescale.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Description: 98c2ecf20Sopenharmony_ci * MPC8360E MDS board specific routines. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Changelog: 128c2ecf20Sopenharmony_ci * Jun 21, 2006 Initial version 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/stddef.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/compiler.h> 188c2ecf20Sopenharmony_ci#include <linux/init.h> 198c2ecf20Sopenharmony_ci#include <linux/errno.h> 208c2ecf20Sopenharmony_ci#include <linux/reboot.h> 218c2ecf20Sopenharmony_ci#include <linux/pci.h> 228c2ecf20Sopenharmony_ci#include <linux/kdev_t.h> 238c2ecf20Sopenharmony_ci#include <linux/major.h> 248c2ecf20Sopenharmony_ci#include <linux/console.h> 258c2ecf20Sopenharmony_ci#include <linux/delay.h> 268c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 278c2ecf20Sopenharmony_ci#include <linux/root_dev.h> 288c2ecf20Sopenharmony_ci#include <linux/initrd.h> 298c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 308c2ecf20Sopenharmony_ci#include <linux/of_device.h> 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include <linux/atomic.h> 338c2ecf20Sopenharmony_ci#include <asm/time.h> 348c2ecf20Sopenharmony_ci#include <asm/io.h> 358c2ecf20Sopenharmony_ci#include <asm/machdep.h> 368c2ecf20Sopenharmony_ci#include <asm/ipic.h> 378c2ecf20Sopenharmony_ci#include <asm/irq.h> 388c2ecf20Sopenharmony_ci#include <asm/prom.h> 398c2ecf20Sopenharmony_ci#include <asm/udbg.h> 408c2ecf20Sopenharmony_ci#include <sysdev/fsl_soc.h> 418c2ecf20Sopenharmony_ci#include <sysdev/fsl_pci.h> 428c2ecf20Sopenharmony_ci#include <soc/fsl/qe/qe.h> 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#include "mpc83xx.h" 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#undef DEBUG 478c2ecf20Sopenharmony_ci#ifdef DEBUG 488c2ecf20Sopenharmony_ci#define DBG(fmt...) udbg_printf(fmt) 498c2ecf20Sopenharmony_ci#else 508c2ecf20Sopenharmony_ci#define DBG(fmt...) 518c2ecf20Sopenharmony_ci#endif 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* ************************************************************************ 548c2ecf20Sopenharmony_ci * 558c2ecf20Sopenharmony_ci * Setup the architecture 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_cistatic void __init mpc836x_mds_setup_arch(void) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci struct device_node *np; 618c2ecf20Sopenharmony_ci u8 __iomem *bcsr_regs = NULL; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci mpc83xx_setup_arch(); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci /* Map BCSR area */ 668c2ecf20Sopenharmony_ci np = of_find_node_by_name(NULL, "bcsr"); 678c2ecf20Sopenharmony_ci if (np) { 688c2ecf20Sopenharmony_ci struct resource res; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci of_address_to_resource(np, 0, &res); 718c2ecf20Sopenharmony_ci bcsr_regs = ioremap(res.start, resource_size(&res)); 728c2ecf20Sopenharmony_ci of_node_put(np); 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#ifdef CONFIG_QUICC_ENGINE 768c2ecf20Sopenharmony_ci if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { 778c2ecf20Sopenharmony_ci par_io_init(np); 788c2ecf20Sopenharmony_ci of_node_put(np); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci for_each_node_by_name(np, "ucc") 818c2ecf20Sopenharmony_ci par_io_of_config(np); 828c2ecf20Sopenharmony_ci#ifdef CONFIG_QE_USB 838c2ecf20Sopenharmony_ci /* Must fixup Par IO before QE GPIO chips are registered. */ 848c2ecf20Sopenharmony_ci par_io_config_pin(1, 2, 1, 0, 3, 0); /* USBOE */ 858c2ecf20Sopenharmony_ci par_io_config_pin(1, 3, 1, 0, 3, 0); /* USBTP */ 868c2ecf20Sopenharmony_ci par_io_config_pin(1, 8, 1, 0, 1, 0); /* USBTN */ 878c2ecf20Sopenharmony_ci par_io_config_pin(1, 10, 2, 0, 3, 0); /* USBRXD */ 888c2ecf20Sopenharmony_ci par_io_config_pin(1, 9, 2, 1, 3, 0); /* USBRP */ 898c2ecf20Sopenharmony_ci par_io_config_pin(1, 11, 2, 1, 3, 0); /* USBRN */ 908c2ecf20Sopenharmony_ci par_io_config_pin(2, 20, 2, 0, 1, 0); /* CLK21 */ 918c2ecf20Sopenharmony_ci#endif /* CONFIG_QE_USB */ 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci if ((np = of_find_compatible_node(NULL, "network", "ucc_geth")) 958c2ecf20Sopenharmony_ci != NULL){ 968c2ecf20Sopenharmony_ci uint svid; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci /* Reset the Ethernet PHY */ 998c2ecf20Sopenharmony_ci#define BCSR9_GETHRST 0x20 1008c2ecf20Sopenharmony_ci clrbits8(&bcsr_regs[9], BCSR9_GETHRST); 1018c2ecf20Sopenharmony_ci udelay(1000); 1028c2ecf20Sopenharmony_ci setbits8(&bcsr_regs[9], BCSR9_GETHRST); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */ 1058c2ecf20Sopenharmony_ci svid = mfspr(SPRN_SVR); 1068c2ecf20Sopenharmony_ci if (svid == 0x80480021) { 1078c2ecf20Sopenharmony_ci void __iomem *immap; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci immap = ioremap(get_immrbase() + 0x14a8, 8); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci /* 1128c2ecf20Sopenharmony_ci * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2) 1138c2ecf20Sopenharmony_ci * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1) 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci setbits32(immap, 0x0c003000); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci /* 1188c2ecf20Sopenharmony_ci * IMMR + 0x14AC[20:27] = 10101010 1198c2ecf20Sopenharmony_ci * (data delay for both UCC's) 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_ci clrsetbits_be32(immap + 4, 0xff0, 0xaa0); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci iounmap(immap); 1248c2ecf20Sopenharmony_ci } 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci iounmap(bcsr_regs); 1278c2ecf20Sopenharmony_ci of_node_put(np); 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci#endif /* CONFIG_QUICC_ENGINE */ 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cimachine_device_initcall(mpc836x_mds, mpc83xx_declare_of_platform_devices); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#ifdef CONFIG_QE_USB 1358c2ecf20Sopenharmony_cistatic int __init mpc836x_usb_cfg(void) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci u8 __iomem *bcsr; 1388c2ecf20Sopenharmony_ci struct device_node *np; 1398c2ecf20Sopenharmony_ci const char *mode; 1408c2ecf20Sopenharmony_ci int ret = 0; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,mpc8360mds-bcsr"); 1438c2ecf20Sopenharmony_ci if (!np) 1448c2ecf20Sopenharmony_ci return -ENODEV; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci bcsr = of_iomap(np, 0); 1478c2ecf20Sopenharmony_ci of_node_put(np); 1488c2ecf20Sopenharmony_ci if (!bcsr) 1498c2ecf20Sopenharmony_ci return -ENOMEM; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,mpc8323-qe-usb"); 1528c2ecf20Sopenharmony_ci if (!np) { 1538c2ecf20Sopenharmony_ci ret = -ENODEV; 1548c2ecf20Sopenharmony_ci goto err; 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci#define BCSR8_TSEC1M_MASK (0x3 << 6) 1588c2ecf20Sopenharmony_ci#define BCSR8_TSEC1M_RGMII (0x0 << 6) 1598c2ecf20Sopenharmony_ci#define BCSR8_TSEC2M_MASK (0x3 << 4) 1608c2ecf20Sopenharmony_ci#define BCSR8_TSEC2M_RGMII (0x0 << 4) 1618c2ecf20Sopenharmony_ci /* 1628c2ecf20Sopenharmony_ci * Default is GMII (2), but we should set it to RGMII (0) if we use 1638c2ecf20Sopenharmony_ci * USB (Eth PHY is in RGMII mode anyway). 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_ci clrsetbits_8(&bcsr[8], BCSR8_TSEC1M_MASK | BCSR8_TSEC2M_MASK, 1668c2ecf20Sopenharmony_ci BCSR8_TSEC1M_RGMII | BCSR8_TSEC2M_RGMII); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci#define BCSR13_USBMASK 0x0f 1698c2ecf20Sopenharmony_ci#define BCSR13_nUSBEN 0x08 /* 1 - Disable, 0 - Enable */ 1708c2ecf20Sopenharmony_ci#define BCSR13_USBSPEED 0x04 /* 1 - Full, 0 - Low */ 1718c2ecf20Sopenharmony_ci#define BCSR13_USBMODE 0x02 /* 1 - Host, 0 - Function */ 1728c2ecf20Sopenharmony_ci#define BCSR13_nUSBVCC 0x01 /* 1 - gets VBUS, 0 - supplies VBUS */ 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci clrsetbits_8(&bcsr[13], BCSR13_USBMASK, BCSR13_USBSPEED); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci mode = of_get_property(np, "mode", NULL); 1778c2ecf20Sopenharmony_ci if (mode && !strcmp(mode, "peripheral")) { 1788c2ecf20Sopenharmony_ci setbits8(&bcsr[13], BCSR13_nUSBVCC); 1798c2ecf20Sopenharmony_ci qe_usb_clock_set(QE_CLK21, 48000000); 1808c2ecf20Sopenharmony_ci } else { 1818c2ecf20Sopenharmony_ci setbits8(&bcsr[13], BCSR13_USBMODE); 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci of_node_put(np); 1858c2ecf20Sopenharmony_cierr: 1868c2ecf20Sopenharmony_ci iounmap(bcsr); 1878c2ecf20Sopenharmony_ci return ret; 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_cimachine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); 1908c2ecf20Sopenharmony_ci#endif /* CONFIG_QE_USB */ 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci/* 1938c2ecf20Sopenharmony_ci * Called very early, MMU is off, device-tree isn't unflattened 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_cistatic int __init mpc836x_mds_probe(void) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci return of_machine_is_compatible("MPC836xMDS"); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cidefine_machine(mpc836x_mds) { 2018c2ecf20Sopenharmony_ci .name = "MPC836x MDS", 2028c2ecf20Sopenharmony_ci .probe = mpc836x_mds_probe, 2038c2ecf20Sopenharmony_ci .setup_arch = mpc836x_mds_setup_arch, 2048c2ecf20Sopenharmony_ci .init_IRQ = mpc83xx_ipic_init_IRQ, 2058c2ecf20Sopenharmony_ci .get_irq = ipic_get_irq, 2068c2ecf20Sopenharmony_ci .restart = mpc83xx_restart, 2078c2ecf20Sopenharmony_ci .time_init = mpc83xx_time_init, 2088c2ecf20Sopenharmony_ci .calibrate_decr = generic_calibrate_decr, 2098c2ecf20Sopenharmony_ci .progress = udbg_progress, 2108c2ecf20Sopenharmony_ci}; 211