162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas Technology Corp. SH7786 Urquell Support. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> 662306a36Sopenharmony_ci * Copyright (C) 2009, 2010 Paul Mundt 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Based on board-sh7785lcr.c 962306a36Sopenharmony_ci * Copyright (C) 2008 Yoshihiro Shimoda 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include <linux/init.h> 1262306a36Sopenharmony_ci#include <linux/platform_device.h> 1362306a36Sopenharmony_ci#include <linux/fb.h> 1462306a36Sopenharmony_ci#include <linux/smc91x.h> 1562306a36Sopenharmony_ci#include <linux/mtd/physmap.h> 1662306a36Sopenharmony_ci#include <linux/delay.h> 1762306a36Sopenharmony_ci#include <linux/gpio.h> 1862306a36Sopenharmony_ci#include <linux/irq.h> 1962306a36Sopenharmony_ci#include <linux/clk.h> 2062306a36Sopenharmony_ci#include <linux/sh_intc.h> 2162306a36Sopenharmony_ci#include <mach/urquell.h> 2262306a36Sopenharmony_ci#include <cpu/sh7786.h> 2362306a36Sopenharmony_ci#include <asm/heartbeat.h> 2462306a36Sopenharmony_ci#include <linux/sizes.h> 2562306a36Sopenharmony_ci#include <asm/smp-ops.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * bit 1234 5678 2962306a36Sopenharmony_ci *---------------------------- 3062306a36Sopenharmony_ci * SW1 0101 0010 -> Pck 33MHz version 3162306a36Sopenharmony_ci * (1101 0010) Pck 66MHz version 3262306a36Sopenharmony_ci * SW2 0x1x xxxx -> little endian 3362306a36Sopenharmony_ci * 29bit mode 3462306a36Sopenharmony_ci * SW47 0001 1000 -> CS0 : on-board flash 3562306a36Sopenharmony_ci * CS1 : SRAM, registers, LAN, PCMCIA 3662306a36Sopenharmony_ci * 38400 bps for SCIF1 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * Address 3962306a36Sopenharmony_ci * 0x00000000 - 0x04000000 (CS0) Nor Flash 4062306a36Sopenharmony_ci * 0x04000000 - 0x04200000 (CS1) SRAM 4162306a36Sopenharmony_ci * 0x05000000 - 0x05800000 (CS1) on board register 4262306a36Sopenharmony_ci * 0x05800000 - 0x06000000 (CS1) LAN91C111 4362306a36Sopenharmony_ci * 0x06000000 - 0x06400000 (CS1) PCMCIA 4462306a36Sopenharmony_ci * 0x08000000 - 0x10000000 (CS2-CS3) DDR3 4562306a36Sopenharmony_ci * 0x10000000 - 0x14000000 (CS4) PCIe 4662306a36Sopenharmony_ci * 0x14000000 - 0x14800000 (CS5) Core0 LRAM/URAM 4762306a36Sopenharmony_ci * 0x14800000 - 0x15000000 (CS5) Core1 LRAM/URAM 4862306a36Sopenharmony_ci * 0x18000000 - 0x1C000000 (CS6) ATA/NAND-Flash 4962306a36Sopenharmony_ci * 0x1C000000 - (CS7) SH7786 Control register 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* HeartBeat */ 5362306a36Sopenharmony_cistatic struct resource heartbeat_resource = { 5462306a36Sopenharmony_ci .start = BOARDREG(SLEDR), 5562306a36Sopenharmony_ci .end = BOARDREG(SLEDR), 5662306a36Sopenharmony_ci .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic struct platform_device heartbeat_device = { 6062306a36Sopenharmony_ci .name = "heartbeat", 6162306a36Sopenharmony_ci .id = -1, 6262306a36Sopenharmony_ci .num_resources = 1, 6362306a36Sopenharmony_ci .resource = &heartbeat_resource, 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* LAN91C111 */ 6762306a36Sopenharmony_cistatic struct smc91x_platdata smc91x_info = { 6862306a36Sopenharmony_ci .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic struct resource smc91x_eth_resources[] = { 7262306a36Sopenharmony_ci [0] = { 7362306a36Sopenharmony_ci .name = "SMC91C111" , 7462306a36Sopenharmony_ci .start = 0x05800300, 7562306a36Sopenharmony_ci .end = 0x0580030f, 7662306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 7762306a36Sopenharmony_ci }, 7862306a36Sopenharmony_ci [1] = { 7962306a36Sopenharmony_ci .start = evt2irq(0x360), 8062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 8162306a36Sopenharmony_ci }, 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic struct platform_device smc91x_eth_device = { 8562306a36Sopenharmony_ci .name = "smc91x", 8662306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(smc91x_eth_resources), 8762306a36Sopenharmony_ci .resource = smc91x_eth_resources, 8862306a36Sopenharmony_ci .dev = { 8962306a36Sopenharmony_ci .platform_data = &smc91x_info, 9062306a36Sopenharmony_ci }, 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci/* Nor Flash */ 9462306a36Sopenharmony_cistatic struct mtd_partition nor_flash_partitions[] = { 9562306a36Sopenharmony_ci { 9662306a36Sopenharmony_ci .name = "loader", 9762306a36Sopenharmony_ci .offset = 0x00000000, 9862306a36Sopenharmony_ci .size = SZ_512K, 9962306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, /* Read-only */ 10062306a36Sopenharmony_ci }, 10162306a36Sopenharmony_ci { 10262306a36Sopenharmony_ci .name = "bootenv", 10362306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 10462306a36Sopenharmony_ci .size = SZ_512K, 10562306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, /* Read-only */ 10662306a36Sopenharmony_ci }, 10762306a36Sopenharmony_ci { 10862306a36Sopenharmony_ci .name = "kernel", 10962306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 11062306a36Sopenharmony_ci .size = SZ_4M, 11162306a36Sopenharmony_ci }, 11262306a36Sopenharmony_ci { 11362306a36Sopenharmony_ci .name = "data", 11462306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 11562306a36Sopenharmony_ci .size = MTDPART_SIZ_FULL, 11662306a36Sopenharmony_ci }, 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic struct physmap_flash_data nor_flash_data = { 12062306a36Sopenharmony_ci .width = 2, 12162306a36Sopenharmony_ci .parts = nor_flash_partitions, 12262306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(nor_flash_partitions), 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic struct resource nor_flash_resources[] = { 12662306a36Sopenharmony_ci [0] = { 12762306a36Sopenharmony_ci .start = NOR_FLASH_ADDR, 12862306a36Sopenharmony_ci .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1, 12962306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic struct platform_device nor_flash_device = { 13462306a36Sopenharmony_ci .name = "physmap-flash", 13562306a36Sopenharmony_ci .dev = { 13662306a36Sopenharmony_ci .platform_data = &nor_flash_data, 13762306a36Sopenharmony_ci }, 13862306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(nor_flash_resources), 13962306a36Sopenharmony_ci .resource = nor_flash_resources, 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic struct platform_device *urquell_devices[] __initdata = { 14362306a36Sopenharmony_ci &heartbeat_device, 14462306a36Sopenharmony_ci &smc91x_eth_device, 14562306a36Sopenharmony_ci &nor_flash_device, 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic int __init urquell_devices_setup(void) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci /* USB */ 15162306a36Sopenharmony_ci gpio_request(GPIO_FN_USB_OVC0, NULL); 15262306a36Sopenharmony_ci gpio_request(GPIO_FN_USB_PENC0, NULL); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* enable LAN */ 15562306a36Sopenharmony_ci __raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001, 15662306a36Sopenharmony_ci UBOARDREG(IRL2MSKR)); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci return platform_add_devices(urquell_devices, 15962306a36Sopenharmony_ci ARRAY_SIZE(urquell_devices)); 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_cidevice_initcall(urquell_devices_setup); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic void urquell_power_off(void) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci __raw_writew(0xa5a5, UBOARDREG(SRSTR)); 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic void __init urquell_init_irq(void) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic int urquell_mode_pins(void) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci return __raw_readw(UBOARDREG(MDSWMR)); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic int urquell_clk_init(void) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci struct clk *clk; 18162306a36Sopenharmony_ci int ret; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci /* 18462306a36Sopenharmony_ci * Only handle the EXTAL case, anyone interfacing a crystal 18562306a36Sopenharmony_ci * resonator will need to provide their own input clock. 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_ci if (test_mode_pin(MODE_PIN9)) 18862306a36Sopenharmony_ci return -EINVAL; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci clk = clk_get(NULL, "extal"); 19162306a36Sopenharmony_ci if (IS_ERR(clk)) 19262306a36Sopenharmony_ci return PTR_ERR(clk); 19362306a36Sopenharmony_ci ret = clk_set_rate(clk, 33333333); 19462306a36Sopenharmony_ci clk_put(clk); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci return ret; 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/* Initialize the board */ 20062306a36Sopenharmony_cistatic void __init urquell_setup(char **cmdline_p) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n"); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci pm_power_off = urquell_power_off; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci register_smp_ops(&shx3_smp_ops); 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/* 21062306a36Sopenharmony_ci * The Machine Vector 21162306a36Sopenharmony_ci */ 21262306a36Sopenharmony_cistatic struct sh_machine_vector mv_urquell __initmv = { 21362306a36Sopenharmony_ci .mv_name = "Urquell", 21462306a36Sopenharmony_ci .mv_setup = urquell_setup, 21562306a36Sopenharmony_ci .mv_init_irq = urquell_init_irq, 21662306a36Sopenharmony_ci .mv_mode_pins = urquell_mode_pins, 21762306a36Sopenharmony_ci .mv_clk_init = urquell_clk_init, 21862306a36Sopenharmony_ci}; 219