blob: 3c3c9a38cfda912a3439b348d081c142a3884530 [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>
23
Paul Mundt2267c782010-01-15 12:11:30 +090024static struct resource heartbeat_resource = {
25 .start = 0x07fff8b0,
26 .end = 0x07fff8b0 + sizeof(u16) - 1,
27 .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
28};
29
30static struct platform_device heartbeat_device = {
31 .name = "heartbeat",
32 .id = -1,
33 .num_resources = 1,
34 .resource = &heartbeat_resource,
35};
36
Paul Mundt02bf6cc2010-01-14 20:58:58 +090037static struct resource smsc911x_resources[] = {
38 [0] = {
39 .name = "smsc911x-memory",
40 .start = 0x07ffff00,
41 .end = 0x07ffff00 + SZ_256 - 1,
42 .flags = IORESOURCE_MEM,
43 },
44 [1] = {
45 .name = "smsc911x-irq",
46 .start = evt2irq(0x2c0),
47 .end = evt2irq(0x2c0),
48 .flags = IORESOURCE_IRQ,
49 },
50};
51
52static struct smsc911x_platform_config smsc911x_config = {
53 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
54 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
55 .flags = SMSC911X_USE_32BIT,
56 .phy_interface = PHY_INTERFACE_MODE_MII,
57};
58
59static struct platform_device smsc911x_device = {
60 .name = "smsc911x",
61 .id = -1,
62 .num_resources = ARRAY_SIZE(smsc911x_resources),
63 .resource = smsc911x_resources,
64 .dev = {
65 .platform_data = &smsc911x_config,
66 },
67};
68
69static struct resource smbus_fpga_resource = {
70 .start = 0x07fff9e0,
71 .end = 0x07fff9e0 + SZ_32 - 1,
72 .flags = IORESOURCE_MEM,
73};
74
75static struct platform_device smbus_fpga_device = {
76 .name = "i2c-sdk7786",
77 .id = 0,
78 .num_resources = 1,
79 .resource = &smbus_fpga_resource,
80};
81
82static struct resource smbus_pcie_resource = {
83 .start = 0x07fffc30,
84 .end = 0x07fffc30 + SZ_32 - 1,
85 .flags = IORESOURCE_MEM,
86};
87
88static struct platform_device smbus_pcie_device = {
89 .name = "i2c-sdk7786",
90 .id = 1,
91 .num_resources = 1,
92 .resource = &smbus_pcie_resource,
93};
94
95static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
96 {
97 I2C_BOARD_INFO("max6900", 0x68),
98 },
99};
100
101static struct platform_device *sh7786_devices[] __initdata = {
Paul Mundt2267c782010-01-15 12:11:30 +0900102 &heartbeat_device,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900103 &smsc911x_device,
104 &smbus_fpga_device,
105 &smbus_pcie_device,
106};
107
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900108static int sdk7786_i2c_setup(void)
109{
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900110 unsigned int tmp;
111
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900112 /*
113 * Hand over I2C control to the FPGA.
114 */
Paul Mundtefd590d2010-01-20 15:08:36 +0900115 tmp = fpga_read_reg(SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900116 tmp &= ~SCBR_I2CCEN;
117 tmp |= SCBR_I2CMEN;
Paul Mundtefd590d2010-01-20 15:08:36 +0900118 fpga_write_reg(tmp, SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900119
120 return i2c_register_board_info(0, sdk7786_i2c_devices,
121 ARRAY_SIZE(sdk7786_i2c_devices));
122}
123
124static int __init sdk7786_devices_setup(void)
125{
126 int ret;
127
128 ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
129 if (unlikely(ret != 0))
130 return ret;
131
132 return sdk7786_i2c_setup();
133}
134__initcall(sdk7786_devices_setup);
135
Paul Mundt6f832e82010-01-15 16:31:04 +0900136static int sdk7786_mode_pins(void)
137{
Paul Mundtefd590d2010-01-20 15:08:36 +0900138 return fpga_read_reg(MODSWR);
Paul Mundt6f832e82010-01-15 16:31:04 +0900139}
140
Paul Mundtc8098212010-01-19 19:38:36 +0900141static int sdk7786_clk_init(void)
142{
143 struct clk *clk;
144 int ret;
145
146 /*
147 * Only handle the EXTAL case, anyone interfacing a crystal
148 * resonator will need to provide their own input clock.
149 */
150 if (test_mode_pin(MODE_PIN9))
151 return -EINVAL;
152
153 clk = clk_get(NULL, "extal");
154 if (!clk || IS_ERR(clk))
155 return PTR_ERR(clk);
156 ret = clk_set_rate(clk, 33333333);
157 clk_put(clk);
158
159 return ret;
160}
161
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900162/* Initialize the board */
163static void __init sdk7786_setup(char **cmdline_p)
164{
Paul Mundtefd590d2010-01-20 15:08:36 +0900165 pr_info("Renesas Technology Europe SDK7786 support:\n");
166
167 sdk7786_fpga_init();
168
169 pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900170}
171
172/*
173 * The Machine Vector
174 */
175static struct sh_machine_vector mv_sdk7786 __initmv = {
176 .mv_name = "SDK7786",
177 .mv_setup = sdk7786_setup,
Paul Mundt6f832e82010-01-15 16:31:04 +0900178 .mv_mode_pins = sdk7786_mode_pins,
Paul Mundtc8098212010-01-19 19:38:36 +0900179 .mv_clk_init = sdk7786_clk_init,
Paul Mundt5f240712010-01-20 15:23:54 +0900180 .mv_init_irq = sdk7786_init_irq,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900181};