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 26 static struct resource heartbeat_resource = { 27 .start = 0x07fff8b0, 28 .end = 0x07fff8b0 + sizeof(u16) - 1, 29 .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, 30 }; 31 32 static struct platform_device heartbeat_device = { 33 .name = "heartbeat", 34 .id = -1, 35 .num_resources = 1, 36 .resource = &heartbeat_resource, 37 }; 38 39 static 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 54 static 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 61 static 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 71 static struct resource smbus_fpga_resource = { 72 .start = 0x07fff9e0, 73 .end = 0x07fff9e0 + SZ_32 - 1, 74 .flags = IORESOURCE_MEM, 75 }; 76 77 static struct platform_device smbus_fpga_device = { 78 .name = "i2c-sdk7786", 79 .id = 0, 80 .num_resources = 1, 81 .resource = &smbus_fpga_resource, 82 }; 83 84 static struct resource smbus_pcie_resource = { 85 .start = 0x07fffc30, 86 .end = 0x07fffc30 + SZ_32 - 1, 87 .flags = IORESOURCE_MEM, 88 }; 89 90 static struct platform_device smbus_pcie_device = { 91 .name = "i2c-sdk7786", 92 .id = 1, 93 .num_resources = 1, 94 .resource = &smbus_pcie_resource, 95 }; 96 97 static struct i2c_board_info __initdata sdk7786_i2c_devices[] = { 98 { 99 I2C_BOARD_INFO("max6900", 0x68), 100 }, 101 }; 102 103 static struct platform_device *sh7786_devices[] __initdata = { 104 &heartbeat_device, 105 &smsc911x_device, 106 &smbus_fpga_device, 107 &smbus_pcie_device, 108 }; 109 110 static 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 126 static 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 138 static int sdk7786_mode_pins(void) 139 { 140 return fpga_read_reg(MODSWR); 141 } 142 143 static 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 164 static void sdk7786_restart(char *cmd) 165 { 166 fpga_write_reg(0xa5a5, SRSTR); 167 } 168 169 static 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 */ 183 static 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 */ 200 static 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