blob: 2ec1ea5cf8efcbb0b23306ca32b0202e4343fc0c [file] [log] [blame]
Paul Mundt02bf6cc2010-01-14 20:58:58 +09001/*
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>
Paul Mundtc8098212010-01-19 19:38:36 +090017#include <linux/clk.h>
Paul Mundt5f240712010-01-20 15:23:54 +090018#include <mach/fpga.h>
19#include <mach/irq.h>
Paul Mundt02bf6cc2010-01-14 20:58:58 +090020#include <asm/machvec.h>
Paul Mundt2267c782010-01-15 12:11:30 +090021#include <asm/heartbeat.h>
Paul Mundt02bf6cc2010-01-14 20:58:58 +090022#include <asm/sizes.h>
Paul Mundtb51989b2010-01-20 16:53:11 +090023#include <asm/reboot.h>
Paul Mundt3366e352010-03-30 12:38:01 +090024#include <asm/smp-ops.h>
Paul Mundt02bf6cc2010-01-14 20:58:58 +090025
Paul Mundt2267c782010-01-15 12:11:30 +090026static 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
Paul Mundt02bf6cc2010-01-14 20:58:58 +090039static 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 = {
Paul Mundt2267c782010-01-15 12:11:30 +0900104 &heartbeat_device,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900105 &smsc911x_device,
106 &smbus_fpga_device,
107 &smbus_pcie_device,
108};
109
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900110static int sdk7786_i2c_setup(void)
111{
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900112 unsigned int tmp;
113
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900114 /*
115 * Hand over I2C control to the FPGA.
116 */
Paul Mundtefd590d2010-01-20 15:08:36 +0900117 tmp = fpga_read_reg(SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900118 tmp &= ~SCBR_I2CCEN;
119 tmp |= SCBR_I2CMEN;
Paul Mundtefd590d2010-01-20 15:08:36 +0900120 fpga_write_reg(tmp, SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900121
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
Paul Mundt6f832e82010-01-15 16:31:04 +0900138static int sdk7786_mode_pins(void)
139{
Paul Mundtefd590d2010-01-20 15:08:36 +0900140 return fpga_read_reg(MODSWR);
Paul Mundt6f832e82010-01-15 16:31:04 +0900141}
142
Paul Mundtc8098212010-01-19 19:38:36 +0900143static 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
Paul Mundtb51989b2010-01-20 16:53:11 +0900164static void sdk7786_restart(char *cmd)
165{
166 fpga_write_reg(0xa5a5, SRSTR);
167}
168
Paul Mundtd9c94442010-04-19 16:27:47 +0900169static 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
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900182/* Initialize the board */
183static void __init sdk7786_setup(char **cmdline_p)
184{
Paul Mundtefd590d2010-01-20 15:08:36 +0900185 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);
Paul Mundtb51989b2010-01-20 16:53:11 +0900190
191 machine_ops.restart = sdk7786_restart;
Paul Mundtd9c94442010-04-19 16:27:47 +0900192 pm_power_off = sdk7786_power_off;
Paul Mundt3366e352010-03-30 12:38:01 +0900193
194 register_smp_ops(&shx3_smp_ops);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900195}
196
197/*
198 * The Machine Vector
199 */
200static struct sh_machine_vector mv_sdk7786 __initmv = {
201 .mv_name = "SDK7786",
202 .mv_setup = sdk7786_setup,
Paul Mundt6f832e82010-01-15 16:31:04 +0900203 .mv_mode_pins = sdk7786_mode_pins,
Paul Mundtc8098212010-01-19 19:38:36 +0900204 .mv_clk_init = sdk7786_clk_init,
Paul Mundt5f240712010-01-20 15:23:54 +0900205 .mv_init_irq = sdk7786_init_irq,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900206};