1/* 2 * Renesas Technology Europe SDK7786 Support. 3 * 4 * Copyright (C) 2010 Matt Fleming 5 * Copyright (C) 2010 Paul Mundt 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file "COPYING" in the main directory of this archive 9 * for more details. 10 */ 11#include <linux/init.h> 12#include <linux/platform_device.h> 13#include <linux/io.h> 14#include <linux/smsc911x.h> 15#include <linux/i2c.h> 16#include <linux/irq.h> 17#include <linux/clk.h> 18#include <mach/fpga.h> 19#include <mach/irq.h> 20#include <asm/machvec.h> 21#include <asm/heartbeat.h> 22#include <asm/sizes.h> 23#include <asm/reboot.h> 24#include <asm/smp-ops.h> 25 26static struct resource heartbeat_resource = { 27 .start = 0x07fff8b0, 28 .end = 0x07fff8b0 + sizeof(u16) - 1, 29 .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, 30}; 31 32static struct platform_device heartbeat_device = { 33 .name = "heartbeat", 34 .id = -1, 35 .num_resources = 1, 36 .resource = &heartbeat_resource, 37}; 38 39static struct resource smsc911x_resources[] = { 40 [0] = { 41 .name = "smsc911x-memory", 42 .start = 0x07ffff00, 43 .end = 0x07ffff00 + SZ_256 - 1, 44 .flags = IORESOURCE_MEM, 45 }, 46 [1] = { 47 .name = "smsc911x-irq", 48 .start = evt2irq(0x2c0), 49 .end = evt2irq(0x2c0), 50 .flags = IORESOURCE_IRQ, 51 }, 52}; 53 54static struct smsc911x_platform_config smsc911x_config = { 55 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 56 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, 57 .flags = SMSC911X_USE_32BIT, 58 .phy_interface = PHY_INTERFACE_MODE_MII, 59}; 60 61static struct platform_device smsc911x_device = { 62 .name = "smsc911x", 63 .id = -1, 64 .num_resources = ARRAY_SIZE(smsc911x_resources), 65 .resource = smsc911x_resources, 66 .dev = { 67 .platform_data = &smsc911x_config, 68 }, 69}; 70 71static struct resource smbus_fpga_resource = { 72 .start = 0x07fff9e0, 73 .end = 0x07fff9e0 + SZ_32 - 1, 74 .flags = IORESOURCE_MEM, 75}; 76 77static struct platform_device smbus_fpga_device = { 78 .name = "i2c-sdk7786", 79 .id = 0, 80 .num_resources = 1, 81 .resource = &smbus_fpga_resource, 82}; 83 84static struct resource smbus_pcie_resource = { 85 .start = 0x07fffc30, 86 .end = 0x07fffc30 + SZ_32 - 1, 87 .flags = IORESOURCE_MEM, 88}; 89 90static struct platform_device smbus_pcie_device = { 91 .name = "i2c-sdk7786", 92 .id = 1, 93 .num_resources = 1, 94 .resource = &smbus_pcie_resource, 95}; 96 97static struct i2c_board_info __initdata sdk7786_i2c_devices[] = { 98 { 99 I2C_BOARD_INFO("max6900", 0x68), 100 }, 101}; 102 103static struct platform_device *sh7786_devices[] __initdata = { 104 &heartbeat_device, 105 &smsc911x_device, 106 &smbus_fpga_device, 107 &smbus_pcie_device, 108}; 109 110static int sdk7786_i2c_setup(void) 111{ 112 unsigned int tmp; 113 114 /* 115 * Hand over I2C control to the FPGA. 116 */ 117 tmp = fpga_read_reg(SBCR); 118 tmp &= ~SCBR_I2CCEN; 119 tmp |= SCBR_I2CMEN; 120 fpga_write_reg(tmp, SBCR); 121 122 return i2c_register_board_info(0, sdk7786_i2c_devices, 123 ARRAY_SIZE(sdk7786_i2c_devices)); 124} 125 126static int __init sdk7786_devices_setup(void) 127{ 128 int ret; 129 130 ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices)); 131 if (unlikely(ret != 0)) 132 return ret; 133 134 return sdk7786_i2c_setup(); 135} 136__initcall(sdk7786_devices_setup); 137 138static int sdk7786_mode_pins(void) 139{ 140 return fpga_read_reg(MODSWR); 141} 142 143static int sdk7786_clk_init(void) 144{ 145 struct clk *clk; 146 int ret; 147 148 /* 149 * Only handle the EXTAL case, anyone interfacing a crystal 150 * resonator will need to provide their own input clock. 151 */ 152 if (test_mode_pin(MODE_PIN9)) 153 return -EINVAL; 154 155 clk = clk_get(NULL, "extal"); 156 if (!clk || IS_ERR(clk)) 157 return PTR_ERR(clk); 158 ret = clk_set_rate(clk, 33333333); 159 clk_put(clk); 160 161 return ret; 162} 163 164static void sdk7786_restart(char *cmd) 165{ 166 fpga_write_reg(0xa5a5, SRSTR); 167} 168 169static void sdk7786_power_off(void) 170{ 171 fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR); 172 173 /* 174 * It can take up to 20us for the R8C to do its job, back off and 175 * wait a bit until we've been shut off. Even though newer FPGA 176 * versions don't set the ACK bit, the latency issue remains. 177 */ 178 while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0) 179 cpu_sleep(); 180} 181 182/* Initialize the board */ 183static void __init sdk7786_setup(char **cmdline_p) 184{ 185 pr_info("Renesas Technology Europe SDK7786 support:\n"); 186 187 sdk7786_fpga_init(); 188 189 pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); 190 191 machine_ops.restart = sdk7786_restart; 192 pm_power_off = sdk7786_power_off; 193 194 register_smp_ops(&shx3_smp_ops); 195} 196 197/* 198 * The Machine Vector 199 */ 200static struct sh_machine_vector mv_sdk7786 __initmv = { 201 .mv_name = "SDK7786", 202 .mv_setup = sdk7786_setup, 203 .mv_mode_pins = sdk7786_mode_pins, 204 .mv_clk_init = sdk7786_clk_init, 205 .mv_init_irq = sdk7786_init_irq, 206}; 207