setup.c (6182B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Renesas Technology Europe SDK7786 Support. 4 * 5 * Copyright (C) 2010 Matt Fleming 6 * Copyright (C) 2010 Paul Mundt 7 */ 8#include <linux/init.h> 9#include <linux/platform_device.h> 10#include <linux/io.h> 11#include <linux/regulator/fixed.h> 12#include <linux/regulator/machine.h> 13#include <linux/smsc911x.h> 14#include <linux/i2c.h> 15#include <linux/irq.h> 16#include <linux/clk.h> 17#include <linux/clkdev.h> 18#include <mach/fpga.h> 19#include <mach/irq.h> 20#include <asm/machvec.h> 21#include <asm/heartbeat.h> 22#include <linux/sizes.h> 23#include <asm/clock.h> 24#include <asm/reboot.h> 25#include <asm/smp-ops.h> 26 27static struct resource heartbeat_resource = { 28 .start = 0x07fff8b0, 29 .end = 0x07fff8b0 + sizeof(u16) - 1, 30 .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, 31}; 32 33static struct platform_device heartbeat_device = { 34 .name = "heartbeat", 35 .id = -1, 36 .num_resources = 1, 37 .resource = &heartbeat_resource, 38}; 39 40/* Dummy supplies, where voltage doesn't matter */ 41static struct regulator_consumer_supply dummy_supplies[] = { 42 REGULATOR_SUPPLY("vddvario", "smsc911x"), 43 REGULATOR_SUPPLY("vdd33a", "smsc911x"), 44}; 45 46static struct resource smsc911x_resources[] = { 47 [0] = { 48 .name = "smsc911x-memory", 49 .start = 0x07ffff00, 50 .end = 0x07ffff00 + SZ_256 - 1, 51 .flags = IORESOURCE_MEM, 52 }, 53 [1] = { 54 .name = "smsc911x-irq", 55 .start = evt2irq(0x2c0), 56 .end = evt2irq(0x2c0), 57 .flags = IORESOURCE_IRQ, 58 }, 59}; 60 61static struct smsc911x_platform_config smsc911x_config = { 62 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 63 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, 64 .flags = SMSC911X_USE_32BIT, 65 .phy_interface = PHY_INTERFACE_MODE_MII, 66}; 67 68static struct platform_device smsc911x_device = { 69 .name = "smsc911x", 70 .id = -1, 71 .num_resources = ARRAY_SIZE(smsc911x_resources), 72 .resource = smsc911x_resources, 73 .dev = { 74 .platform_data = &smsc911x_config, 75 }, 76}; 77 78static struct resource smbus_fpga_resource = { 79 .start = 0x07fff9e0, 80 .end = 0x07fff9e0 + SZ_32 - 1, 81 .flags = IORESOURCE_MEM, 82}; 83 84static struct platform_device smbus_fpga_device = { 85 .name = "i2c-sdk7786", 86 .id = 0, 87 .num_resources = 1, 88 .resource = &smbus_fpga_resource, 89}; 90 91static struct resource smbus_pcie_resource = { 92 .start = 0x07fffc30, 93 .end = 0x07fffc30 + SZ_32 - 1, 94 .flags = IORESOURCE_MEM, 95}; 96 97static struct platform_device smbus_pcie_device = { 98 .name = "i2c-sdk7786", 99 .id = 1, 100 .num_resources = 1, 101 .resource = &smbus_pcie_resource, 102}; 103 104static struct i2c_board_info __initdata sdk7786_i2c_devices[] = { 105 { 106 I2C_BOARD_INFO("max6900", 0x68), 107 }, 108}; 109 110static struct platform_device *sh7786_devices[] __initdata = { 111 &heartbeat_device, 112 &smsc911x_device, 113 &smbus_fpga_device, 114 &smbus_pcie_device, 115}; 116 117static int sdk7786_i2c_setup(void) 118{ 119 unsigned int tmp; 120 121 /* 122 * Hand over I2C control to the FPGA. 123 */ 124 tmp = fpga_read_reg(SBCR); 125 tmp &= ~SCBR_I2CCEN; 126 tmp |= SCBR_I2CMEN; 127 fpga_write_reg(tmp, SBCR); 128 129 return i2c_register_board_info(0, sdk7786_i2c_devices, 130 ARRAY_SIZE(sdk7786_i2c_devices)); 131} 132 133static int __init sdk7786_devices_setup(void) 134{ 135 int ret; 136 137 ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices)); 138 if (unlikely(ret != 0)) 139 return ret; 140 141 return sdk7786_i2c_setup(); 142} 143device_initcall(sdk7786_devices_setup); 144 145static int sdk7786_mode_pins(void) 146{ 147 return fpga_read_reg(MODSWR); 148} 149 150/* 151 * FPGA-driven PCIe clocks 152 * 153 * Historically these include the oscillator, clock B (slots 2/3/4) and 154 * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove 155 * everything under a single PCIe clocks enable bit that happens to map 156 * to the same bit position as the oscillator bit for earlier FPGA 157 * versions. 158 * 159 * Given that the legacy clocks have the side-effect of shutting the CPU 160 * off through the FPGA along with the PCI slots, we simply leave them in 161 * their initial state and don't bother registering them with the clock 162 * framework. 163 */ 164static int sdk7786_pcie_clk_enable(struct clk *clk) 165{ 166 fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR); 167 return 0; 168} 169 170static void sdk7786_pcie_clk_disable(struct clk *clk) 171{ 172 fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR); 173} 174 175static struct sh_clk_ops sdk7786_pcie_clk_ops = { 176 .enable = sdk7786_pcie_clk_enable, 177 .disable = sdk7786_pcie_clk_disable, 178}; 179 180static struct clk sdk7786_pcie_clk = { 181 .ops = &sdk7786_pcie_clk_ops, 182}; 183 184static struct clk_lookup sdk7786_pcie_cl = { 185 .con_id = "pcie_plat_clk", 186 .clk = &sdk7786_pcie_clk, 187}; 188 189static int sdk7786_clk_init(void) 190{ 191 struct clk *clk; 192 int ret; 193 194 /* 195 * Only handle the EXTAL case, anyone interfacing a crystal 196 * resonator will need to provide their own input clock. 197 */ 198 if (test_mode_pin(MODE_PIN9)) 199 return -EINVAL; 200 201 clk = clk_get(NULL, "extal"); 202 if (IS_ERR(clk)) 203 return PTR_ERR(clk); 204 ret = clk_set_rate(clk, 33333333); 205 clk_put(clk); 206 207 /* 208 * Setup the FPGA clocks. 209 */ 210 ret = clk_register(&sdk7786_pcie_clk); 211 if (unlikely(ret)) { 212 pr_err("FPGA clock registration failed\n"); 213 return ret; 214 } 215 216 clkdev_add(&sdk7786_pcie_cl); 217 218 return 0; 219} 220 221static void sdk7786_restart(char *cmd) 222{ 223 fpga_write_reg(0xa5a5, SRSTR); 224} 225 226static void sdk7786_power_off(void) 227{ 228 fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR); 229 230 /* 231 * It can take up to 20us for the R8C to do its job, back off and 232 * wait a bit until we've been shut off. Even though newer FPGA 233 * versions don't set the ACK bit, the latency issue remains. 234 */ 235 while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0) 236 cpu_sleep(); 237} 238 239/* Initialize the board */ 240static void __init sdk7786_setup(char **cmdline_p) 241{ 242 pr_info("Renesas Technology Europe SDK7786 support:\n"); 243 244 regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); 245 246 sdk7786_fpga_init(); 247 sdk7786_nmi_init(); 248 249 pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); 250 251 machine_ops.restart = sdk7786_restart; 252 pm_power_off = sdk7786_power_off; 253 254 register_smp_ops(&shx3_smp_ops); 255} 256 257/* 258 * The Machine Vector 259 */ 260static struct sh_machine_vector mv_sdk7786 __initmv = { 261 .mv_name = "SDK7786", 262 .mv_setup = sdk7786_setup, 263 .mv_mode_pins = sdk7786_mode_pins, 264 .mv_clk_init = sdk7786_clk_init, 265 .mv_init_irq = sdk7786_init_irq, 266};