setup.c 7.4 KB
Newer Older
1 2 3
/*
 * arch/sh/boards/renesas/r7780rp/setup.c
 *
4 5
 * Renesas Solutions Highlander Support.
 *
6
 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
7
 * Copyright (C) 2005 - 2008 Paul Mundt
8
 *
9 10
 * This contains support for the R7780RP-1, R7780MP, and R7785RP
 * Highlander modules.
11 12 13 14 15 16 17
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/platform_device.h>
18
#include <linux/ata_platform.h>
19
#include <linux/types.h>
20
#include <linux/i2c.h>
21
#include <net/ax88796.h>
22
#include <asm/machvec.h>
23
#include <mach/highlander.h>
24
#include <asm/clock.h>
P
Paul Mundt 已提交
25
#include <asm/heartbeat.h>
26
#include <asm/io.h>
27
#include <asm/io_trapped.h>
28

29 30 31 32 33 34 35 36 37
static struct resource r8a66597_usb_host_resources[] = {
	[0] = {
		.name	= "r8a66597_hcd",
		.start	= 0xA4200000,
		.end	= 0xA42000FF,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.name	= "r8a66597_hcd",
38 39
		.start	= IRQ_EXT1,		/* irq number */
		.end	= IRQ_EXT1,
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device r8a66597_usb_host_device = {
	.name		= "r8a66597_hcd",
	.id		= -1,
	.dev = {
		.dma_mask		= NULL,		/* don't use dma */
		.coherent_dma_mask	= 0xffffffff,
	},
	.num_resources	= ARRAY_SIZE(r8a66597_usb_host_resources),
	.resource	= r8a66597_usb_host_resources,
};

static struct resource m66592_usb_peripheral_resources[] = {
	[0] = {
		.name	= "m66592_udc",
		.start	= 0xb0000000,
		.end	= 0xb00000FF,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.name	= "m66592_udc",
64 65
		.start	= IRQ_EXT4,		/* irq number */
		.end	= IRQ_EXT4,
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device m66592_usb_peripheral_device = {
	.name		= "m66592_udc",
	.id		= -1,
	.dev = {
		.dma_mask		= NULL,		/* don't use dma */
		.coherent_dma_mask	= 0xffffffff,
	},
	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
	.resource	= m66592_usb_peripheral_resources,
};

P
Paul Mundt 已提交
81 82
static struct resource cf_ide_resources[] = {
	[0] = {
83 84 85
		.start	= PA_AREA5_IO + 0x1000,
		.end	= PA_AREA5_IO + 0x1000 + 0x08 - 1,
		.flags	= IORESOURCE_MEM,
P
Paul Mundt 已提交
86 87
	},
	[1] = {
88 89 90
		.start	= PA_AREA5_IO + 0x80c,
		.end	= PA_AREA5_IO + 0x80c + 0x16 - 1,
		.flags	= IORESOURCE_MEM,
P
Paul Mundt 已提交
91 92
	},
	[2] = {
93
		.start	= IRQ_CF,
P
Paul Mundt 已提交
94 95 96 97
		.flags	= IORESOURCE_IRQ,
	},
};

98 99 100 101
static struct pata_platform_info pata_info = {
	.ioport_shift	= 1,
};

P
Paul Mundt 已提交
102 103 104 105 106
static struct platform_device cf_ide_device  = {
	.name		= "pata_platform",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(cf_ide_resources),
	.resource	= cf_ide_resources,
107 108 109
	.dev	= {
		.platform_data	= &pata_info,
	},
P
Paul Mundt 已提交
110 111
};

112 113 114
static struct resource heartbeat_resources[] = {
	[0] = {
		.start	= PA_OBLED,
115
		.end	= PA_OBLED,
116 117 118 119
		.flags	= IORESOURCE_MEM,
	},
};

P
Paul Mundt 已提交
120 121 122 123 124 125 126 127 128
#ifndef CONFIG_SH_R7785RP
static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 };

static struct heartbeat_data heartbeat_data = {
	.bit_pos	= heartbeat_bit_pos,
	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
};
#endif

129 130 131
static struct platform_device heartbeat_device = {
	.name		= "heartbeat",
	.id		= -1,
132 133 134

	/* R7785RP has a slightly more sensible FPGA.. */
#ifndef CONFIG_SH_R7785RP
135
	.dev	= {
136
		.platform_data	= &heartbeat_data,
137
	},
138
#endif
139 140 141 142
	.num_resources	= ARRAY_SIZE(heartbeat_resources),
	.resource	= heartbeat_resources,
};

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
static struct ax_plat_data ax88796_platdata = {
	.flags          = AXFLG_HAS_93CX6,
	.wordlength     = 2,
	.dcr_val        = 0x1,
	.rcr_val        = 0x40,
};

static struct resource ax88796_resources[] = {
	{
#ifdef CONFIG_SH_R7780RP
		.start  = 0xa5800400,
		.end    = 0xa5800400 + (0x20 * 0x2) - 1,
#else
		.start  = 0xa4100400,
		.end    = 0xa4100400 + (0x20 * 0x2) - 1,
#endif
		.flags  = IORESOURCE_MEM,
	},
	{
		.start  = IRQ_AX88796,
		.end    = IRQ_AX88796,
		.flags  = IORESOURCE_IRQ,
	},
};

static struct platform_device ax88796_device = {
	.name           = "ax88796",
	.id             = 0,

	.dev    = {
		.platform_data = &ax88796_platdata,
	},

	.num_resources  = ARRAY_SIZE(ax88796_resources),
	.resource       = ax88796_resources,
};

180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
static struct resource smbus_resources[] = {
	[0] = {
		.start	= PA_SMCR,
		.end	= PA_SMCR + 0x100 - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= IRQ_SMBUS,
		.end	= IRQ_SMBUS,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device smbus_device = {
	.name		= "i2c-highlander",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(smbus_resources),
	.resource	= smbus_resources,
};

static struct i2c_board_info __initdata highlander_i2c_devices[] = {
	{
202
		I2C_BOARD_INFO("r2025sd", 0x32),
203 204
	},
};
205

206
static struct platform_device *r7780rp_devices[] __initdata = {
207 208
	&r8a66597_usb_host_device,
	&m66592_usb_peripheral_device,
209
	&heartbeat_device,
210
	&smbus_device,
M
Magnus Damm 已提交
211
#ifndef CONFIG_SH_R7780RP
212
	&ax88796_device,
M
Magnus Damm 已提交
213
#endif
214 215
};

216 217 218 219 220 221 222 223 224 225 226
/*
 * The CF is connected using a 16-bit bus where 8-bit operations are
 * unsupported. The linux ata driver is however using 8-bit operations, so
 * insert a trapped io filter to convert 8-bit operations into 16-bit.
 */
static struct trapped_io cf_trapped_io = {
	.resource		= cf_ide_resources,
	.num_resources		= 2,
	.minimum_bus_width	= 16,
};

227 228
static int __init r7780rp_devices_setup(void)
{
229 230
	int ret = 0;

231 232
#ifndef CONFIG_SH_R7780RP
	if (register_trapped_io(&cf_trapped_io) == 0)
233
		ret |= platform_device_register(&cf_ide_device);
234
#endif
235 236

	ret |= platform_add_devices(r7780rp_devices,
237
				    ARRAY_SIZE(r7780rp_devices));
238 239 240 241 242

	ret |= i2c_register_board_info(0, highlander_i2c_devices,
				       ARRAY_SIZE(highlander_i2c_devices));

	return ret;
243
}
244
device_initcall(r7780rp_devices_setup);
245 246 247 248 249 250

/*
 * Platform specific clocks
 */
static void ivdr_clk_enable(struct clk *clk)
{
R
Ryusuke Sakato 已提交
251
	ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
252 253 254 255
}

static void ivdr_clk_disable(struct clk *clk)
{
R
Ryusuke Sakato 已提交
256
	ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
}

static struct clk_ops ivdr_clk_ops = {
	.enable		= ivdr_clk_enable,
	.disable	= ivdr_clk_disable,
};

static struct clk ivdr_clk = {
	.name		= "ivdr_clk",
	.ops		= &ivdr_clk_ops,
};

static struct clk *r7780rp_clocks[] = {
	&ivdr_clk,
};

static void r7780rp_power_off(void)
{
275 276
	if (mach_is_r7780mp() || mach_is_r7785rp())
		ctrl_outw(0x0001, PA_POFF);
277 278 279 280 281
}

/*
 * Initialize the board
 */
282
static void __init highlander_setup(char **cmdline_p)
283 284 285 286
{
	u16 ver = ctrl_inw(PA_VERREG);
	int i;

287 288 289 290
	printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
			 mach_is_r7780rp() ? "R7780RP-1" :
			 mach_is_r7780mp() ? "R7780MP"	 :
					     "R7785RP");
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307

	printk(KERN_INFO "Board version: %d (revision %d), "
			 "FPGA version: %d (revision %d)\n",
			 (ver >> 12) & 0xf, (ver >> 8) & 0xf,
			 (ver >>  4) & 0xf, ver & 0xf);

	/*
	 * Enable the important clocks right away..
	 */
	for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) {
		struct clk *clk = r7780rp_clocks[i];

		clk_register(clk);
		clk_enable(clk);
	}

	ctrl_outw(0x0000, PA_OBLED);	/* Clear LED. */
308 309 310 311

	if (mach_is_r7780rp())
		ctrl_outw(0x0001, PA_SDPOW);	/* SD Power ON */

312
	ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL);	/* Si13112 */
313 314 315

	pm_power_off = r7780rp_power_off;
}
P
Paul Mundt 已提交
316

317 318
static unsigned char irl2irq[HL_NR_IRL];

319
static int highlander_irq_demux(int irq)
320 321 322 323 324 325 326
{
	if (irq >= HL_NR_IRL || !irl2irq[irq])
		return irq;

	return irl2irq[irq];
}

327
static void __init highlander_init_irq(void)
328
{
329
	unsigned char *ucp = highlander_plat_irq_setup();
330 331 332 333 334 335 336

	if (ucp) {
		plat_irq_setup_pins(IRQ_MODE_IRL3210);
		memcpy(irl2irq, ucp, HL_NR_IRL);
	}
}

P
Paul Mundt 已提交
337 338 339
/*
 * The Machine Vector
 */
P
Paul Mundt 已提交
340
static struct sh_machine_vector mv_highlander __initmv = {
341 342 343
	.mv_name		= "Highlander",
	.mv_setup		= highlander_setup,
	.mv_init_irq		= highlander_init_irq,
344
	.mv_irq_demux		= highlander_irq_demux,
P
Paul Mundt 已提交
345
};