blob: 8dbbdea9c983ae459310ea704ceea48abde7a244 [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 Mundt02bf6cc2010-01-14 20:58:58 +090018#include <asm/machvec.h>
Paul Mundt2267c782010-01-15 12:11:30 +090019#include <asm/heartbeat.h>
Paul Mundt02bf6cc2010-01-14 20:58:58 +090020#include <asm/sizes.h>
Paul Mundtefd590d2010-01-20 15:08:36 +090021#include <mach/fpga.h>
Paul Mundt02bf6cc2010-01-14 20:58:58 +090022
Paul Mundt2267c782010-01-15 12:11:30 +090023static struct resource heartbeat_resource = {
24 .start = 0x07fff8b0,
25 .end = 0x07fff8b0 + sizeof(u16) - 1,
26 .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
27};
28
29static struct platform_device heartbeat_device = {
30 .name = "heartbeat",
31 .id = -1,
32 .num_resources = 1,
33 .resource = &heartbeat_resource,
34};
35
Paul Mundt02bf6cc2010-01-14 20:58:58 +090036static struct resource smsc911x_resources[] = {
37 [0] = {
38 .name = "smsc911x-memory",
39 .start = 0x07ffff00,
40 .end = 0x07ffff00 + SZ_256 - 1,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .name = "smsc911x-irq",
45 .start = evt2irq(0x2c0),
46 .end = evt2irq(0x2c0),
47 .flags = IORESOURCE_IRQ,
48 },
49};
50
51static struct smsc911x_platform_config smsc911x_config = {
52 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
53 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
54 .flags = SMSC911X_USE_32BIT,
55 .phy_interface = PHY_INTERFACE_MODE_MII,
56};
57
58static struct platform_device smsc911x_device = {
59 .name = "smsc911x",
60 .id = -1,
61 .num_resources = ARRAY_SIZE(smsc911x_resources),
62 .resource = smsc911x_resources,
63 .dev = {
64 .platform_data = &smsc911x_config,
65 },
66};
67
68static struct resource smbus_fpga_resource = {
69 .start = 0x07fff9e0,
70 .end = 0x07fff9e0 + SZ_32 - 1,
71 .flags = IORESOURCE_MEM,
72};
73
74static struct platform_device smbus_fpga_device = {
75 .name = "i2c-sdk7786",
76 .id = 0,
77 .num_resources = 1,
78 .resource = &smbus_fpga_resource,
79};
80
81static struct resource smbus_pcie_resource = {
82 .start = 0x07fffc30,
83 .end = 0x07fffc30 + SZ_32 - 1,
84 .flags = IORESOURCE_MEM,
85};
86
87static struct platform_device smbus_pcie_device = {
88 .name = "i2c-sdk7786",
89 .id = 1,
90 .num_resources = 1,
91 .resource = &smbus_pcie_resource,
92};
93
94static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
95 {
96 I2C_BOARD_INFO("max6900", 0x68),
97 },
98};
99
100static struct platform_device *sh7786_devices[] __initdata = {
Paul Mundt2267c782010-01-15 12:11:30 +0900101 &heartbeat_device,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900102 &smsc911x_device,
103 &smbus_fpga_device,
104 &smbus_pcie_device,
105};
106
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900107static int sdk7786_i2c_setup(void)
108{
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900109 unsigned int tmp;
110
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900111 /*
112 * Hand over I2C control to the FPGA.
113 */
Paul Mundtefd590d2010-01-20 15:08:36 +0900114 tmp = fpga_read_reg(SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900115 tmp &= ~SCBR_I2CCEN;
116 tmp |= SCBR_I2CMEN;
Paul Mundtefd590d2010-01-20 15:08:36 +0900117 fpga_write_reg(tmp, SBCR);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900118
119 return i2c_register_board_info(0, sdk7786_i2c_devices,
120 ARRAY_SIZE(sdk7786_i2c_devices));
121}
122
123static int __init sdk7786_devices_setup(void)
124{
125 int ret;
126
127 ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
128 if (unlikely(ret != 0))
129 return ret;
130
131 return sdk7786_i2c_setup();
132}
133__initcall(sdk7786_devices_setup);
134
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900135enum {
136 ATA_IRQ_BIT = 1,
137 SPI_BUSY_BIT = 2,
138 LIRQ5_BIT = 3,
139 LIRQ6_BIT = 4,
140 LIRQ7_BIT = 5,
141 LIRQ8_BIT = 6,
142 KEY_IRQ_BIT = 7,
143 PEN_IRQ_BIT = 8,
144 ETH_IRQ_BIT = 9,
145 RTC_ALARM_BIT = 10,
146 CRYSTAL_FAIL_BIT = 12,
147 ETH_PME_BIT = 14,
148};
149
150static void __init init_sdk7786_IRQ(void)
151{
152 unsigned int tmp;
153
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900154 /* Enable priority encoding for all IRLs */
155 fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR);
156
157 /* Clear FPGA interrupt status registers */
158 fpga_write_reg(0x0000, INTASR);
159 fpga_write_reg(0x0000, INTBSR);
160
161 /* Unmask FPGA interrupts */
162 tmp = fpga_read_reg(INTAMR);
163 tmp &= ~(1 << ETH_IRQ_BIT);
164 fpga_write_reg(tmp, INTAMR);
165
166 plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK);
167 plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
168}
169
Paul Mundt6f832e82010-01-15 16:31:04 +0900170static int sdk7786_mode_pins(void)
171{
Paul Mundtefd590d2010-01-20 15:08:36 +0900172 return fpga_read_reg(MODSWR);
Paul Mundt6f832e82010-01-15 16:31:04 +0900173}
174
Paul Mundtc8098212010-01-19 19:38:36 +0900175static int sdk7786_clk_init(void)
176{
177 struct clk *clk;
178 int ret;
179
180 /*
181 * Only handle the EXTAL case, anyone interfacing a crystal
182 * resonator will need to provide their own input clock.
183 */
184 if (test_mode_pin(MODE_PIN9))
185 return -EINVAL;
186
187 clk = clk_get(NULL, "extal");
188 if (!clk || IS_ERR(clk))
189 return PTR_ERR(clk);
190 ret = clk_set_rate(clk, 33333333);
191 clk_put(clk);
192
193 return ret;
194}
195
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900196/* Initialize the board */
197static void __init sdk7786_setup(char **cmdline_p)
198{
Paul Mundtefd590d2010-01-20 15:08:36 +0900199 pr_info("Renesas Technology Europe SDK7786 support:\n");
200
201 sdk7786_fpga_init();
202
203 pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900204}
205
206/*
207 * The Machine Vector
208 */
209static struct sh_machine_vector mv_sdk7786 __initmv = {
210 .mv_name = "SDK7786",
211 .mv_setup = sdk7786_setup,
Paul Mundt6f832e82010-01-15 16:31:04 +0900212 .mv_mode_pins = sdk7786_mode_pins,
Paul Mundtc8098212010-01-19 19:38:36 +0900213 .mv_clk_init = sdk7786_clk_init,
Paul Mundt02bf6cc2010-01-14 20:58:58 +0900214 .mv_init_irq = init_sdk7786_IRQ,
215};