blob: 589ae2435cbebcced7c7332b40b0c9b7b0054b6d [file] [log] [blame]
Manuel Lauss27dd65a2009-10-04 14:55:28 +02001/*
Manuel Lauss7c4b24d2011-11-10 12:06:21 +00002 * DBAu1000/1500/1100 board support
Manuel Lauss27dd65a2009-10-04 14:55:28 +02003 *
Manuel Lauss7c4b24d2011-11-10 12:06:21 +00004 * Copyright 2000, 2008 MontaVista Software Inc.
5 * Author: MontaVista Software, Inc. <source@mvista.com>
Manuel Lauss27dd65a2009-10-04 14:55:28 +02006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000022#include <linux/dma-mapping.h>
23#include <linux/gpio.h>
Manuel Lauss27dd65a2009-10-04 14:55:28 +020024#include <linux/init.h>
Manuel Laussb2ce3052011-07-25 13:44:46 +020025#include <linux/interrupt.h>
Manuel Lauss27dd65a2009-10-04 14:55:28 +020026#include <linux/platform_device.h>
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000027#include <linux/pm.h>
Manuel Laussb2ce3052011-07-25 13:44:46 +020028#include <asm/mach-au1x00/au1000.h>
29#include <asm/mach-au1x00/au1000_dma.h>
Manuel Lauss206aa6c2009-10-19 12:53:37 +020030#include <asm/mach-db1x00/bcsr.h>
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000031#include <asm/reboot.h>
32#include <prom.h>
33#include "platform.h"
Manuel Lauss27dd65a2009-10-04 14:55:28 +020034
Manuel Lauss7517de32011-08-12 11:39:44 +020035struct pci_dev;
36
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000037const char *get_system_type(void)
38{
39 return "Alchemy Db1x00";
40}
41
42void __init board_setup(void)
43{
44#ifdef CONFIG_MIPS_DB1000
45 printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
46#endif
47#ifdef CONFIG_MIPS_DB1500
48 printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
49#endif
50#ifdef CONFIG_MIPS_DB1100
51 printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
52#endif
53 /* initialize board register space */
54 bcsr_init(DB1000_BCSR_PHYS_ADDR,
55 DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
56
57#if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR)
58 {
59 u32 pin_func;
60
61 /* Set IRFIRSEL instead of GPIO15 */
62 pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
63 au_writel(pin_func, SYS_PINFUNC);
64 /* Power off until the driver is in use */
65 bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
66 BCSR_RESETS_IRDA_MODE_OFF);
67 }
68#endif
69 bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
70
71 /* Enable GPIO[31:0] inputs */
72 alchemy_gpio1_input_enable();
73}
74
Manuel Lauss27dd65a2009-10-04 14:55:28 +020075/* DB1xxx PCMCIA interrupt sources:
Manuel Lauss7c4b24d2011-11-10 12:06:21 +000076 * CD0/1 GPIO0/3
Manuel Lauss27dd65a2009-10-04 14:55:28 +020077 * STSCHG0/1 GPIO1/4
78 * CARD0/1 GPIO2/5
Manuel Lauss27dd65a2009-10-04 14:55:28 +020079 */
Manuel Lauss78814462009-10-07 20:15:15 +020080
Manuel Lauss206aa6c2009-10-19 12:53:37 +020081#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
Manuel Lauss78814462009-10-07 20:15:15 +020082
83#if defined(CONFIG_MIPS_DB1000)
84#define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT
85#define DB1XXX_PCMCIA_STSCHG0 AU1000_GPIO1_INT
86#define DB1XXX_PCMCIA_CARD0 AU1000_GPIO2_INT
87#define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT
88#define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT
89#define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT
90#elif defined(CONFIG_MIPS_DB1100)
91#define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT
92#define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT
93#define DB1XXX_PCMCIA_CARD0 AU1100_GPIO2_INT
94#define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT
95#define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT
96#define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT
97#elif defined(CONFIG_MIPS_DB1500)
98#define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT
99#define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT
100#define DB1XXX_PCMCIA_CARD0 AU1500_GPIO2_INT
101#define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT
102#define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT
103#define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT
Manuel Lauss27dd65a2009-10-04 14:55:28 +0200104
Manuel Laussf869d422011-11-10 12:06:16 +0000105static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
Manuel Lauss7517de32011-08-12 11:39:44 +0200106{
107 if ((slot < 12) || (slot > 13) || pin == 0)
108 return -1;
109 if (slot == 12)
110 return (pin == 1) ? AU1500_PCI_INTA : 0xff;
111 if (slot == 13) {
112 switch (pin) {
113 case 1: return AU1500_PCI_INTA;
114 case 2: return AU1500_PCI_INTB;
115 case 3: return AU1500_PCI_INTC;
116 case 4: return AU1500_PCI_INTD;
117 }
118 }
119 return -1;
120}
Manuel Lauss7517de32011-08-12 11:39:44 +0200121
Manuel Lauss7517de32011-08-12 11:39:44 +0200122static struct resource alchemy_pci_host_res[] = {
123 [0] = {
124 .start = AU1500_PCI_PHYS_ADDR,
125 .end = AU1500_PCI_PHYS_ADDR + 0xfff,
126 .flags = IORESOURCE_MEM,
127 },
128};
129
Manuel Laussf869d422011-11-10 12:06:16 +0000130static struct alchemy_pci_platdata db1500_pci_pd = {
131 .board_map_irq = db1500_map_pci_irq,
Manuel Lauss7517de32011-08-12 11:39:44 +0200132};
133
Manuel Laussf869d422011-11-10 12:06:16 +0000134static struct platform_device db1500_pci_host_dev = {
135 .dev.platform_data = &db1500_pci_pd,
Manuel Lauss7517de32011-08-12 11:39:44 +0200136 .name = "alchemy-pci",
137 .id = 0,
138 .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
139 .resource = alchemy_pci_host_res,
140};
141
Manuel Laussf869d422011-11-10 12:06:16 +0000142static int __init db1500_pci_init(void)
Manuel Lauss7517de32011-08-12 11:39:44 +0200143{
Manuel Laussf869d422011-11-10 12:06:16 +0000144 return platform_device_register(&db1500_pci_host_dev);
Manuel Lauss7517de32011-08-12 11:39:44 +0200145}
146/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
Manuel Laussf869d422011-11-10 12:06:16 +0000147arch_initcall(db1500_pci_init);
Manuel Lauss7517de32011-08-12 11:39:44 +0200148#endif
149
Manuel Lauss37663862011-08-12 11:39:45 +0200150#ifdef CONFIG_MIPS_DB1100
151static struct resource au1100_lcd_resources[] = {
152 [0] = {
153 .start = AU1100_LCD_PHYS_ADDR,
154 .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
155 .flags = IORESOURCE_MEM,
156 },
157 [1] = {
158 .start = AU1100_LCD_INT,
159 .end = AU1100_LCD_INT,
160 .flags = IORESOURCE_IRQ,
161 }
162};
163
164static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
165
166static struct platform_device au1100_lcd_device = {
167 .name = "au1100-lcd",
168 .id = 0,
169 .dev = {
170 .dma_mask = &au1100_lcd_dmamask,
171 .coherent_dma_mask = DMA_BIT_MASK(32),
172 },
173 .num_resources = ARRAY_SIZE(au1100_lcd_resources),
174 .resource = au1100_lcd_resources,
175};
176#endif
177
Manuel Laussb2ce3052011-07-25 13:44:46 +0200178static struct resource alchemy_ac97c_res[] = {
179 [0] = {
180 .start = AU1000_AC97_PHYS_ADDR,
181 .end = AU1000_AC97_PHYS_ADDR + 0xfff,
182 .flags = IORESOURCE_MEM,
183 },
184 [1] = {
185 .start = DMA_ID_AC97C_TX,
186 .end = DMA_ID_AC97C_TX,
187 .flags = IORESOURCE_DMA,
188 },
189 [2] = {
190 .start = DMA_ID_AC97C_RX,
191 .end = DMA_ID_AC97C_RX,
192 .flags = IORESOURCE_DMA,
193 },
194};
195
196static struct platform_device alchemy_ac97c_dev = {
197 .name = "alchemy-ac97c",
198 .id = -1,
199 .resource = alchemy_ac97c_res,
200 .num_resources = ARRAY_SIZE(alchemy_ac97c_res),
201};
202
203static struct platform_device alchemy_ac97c_dma_dev = {
204 .name = "alchemy-pcm-dma",
205 .id = 0,
206};
207
208static struct platform_device db1x00_codec_dev = {
209 .name = "ac97-codec",
210 .id = -1,
211};
212
213static struct platform_device db1x00_audio_dev = {
214 .name = "db1000-audio",
215};
216
Manuel Lauss27dd65a2009-10-04 14:55:28 +0200217static int __init db1xxx_dev_init(void)
218{
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000219 irq_set_irq_type(DB1XXX_PCMCIA_CD0, IRQ_TYPE_EDGE_BOTH);
220 irq_set_irq_type(DB1XXX_PCMCIA_CD1, IRQ_TYPE_EDGE_BOTH);
221 irq_set_irq_type(DB1XXX_PCMCIA_CARD0, IRQ_TYPE_LEVEL_LOW);
222 irq_set_irq_type(DB1XXX_PCMCIA_CARD1, IRQ_TYPE_LEVEL_LOW);
223 irq_set_irq_type(DB1XXX_PCMCIA_STSCHG0, IRQ_TYPE_LEVEL_LOW);
224 irq_set_irq_type(DB1XXX_PCMCIA_STSCHG1, IRQ_TYPE_LEVEL_LOW);
225
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200226 db1x_register_pcmcia_socket(
227 AU1000_PCMCIA_ATTR_PHYS_ADDR,
228 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
229 AU1000_PCMCIA_MEM_PHYS_ADDR,
230 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
231 AU1000_PCMCIA_IO_PHYS_ADDR,
232 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
233 DB1XXX_PCMCIA_CARD0, DB1XXX_PCMCIA_CD0,
234 /*DB1XXX_PCMCIA_STSCHG0*/0, 0, 0);
Manuel Lauss27dd65a2009-10-04 14:55:28 +0200235
Manuel Lauss7cc2e272011-08-12 11:39:40 +0200236 db1x_register_pcmcia_socket(
237 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
238 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
239 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
240 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
241 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
242 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
243 DB1XXX_PCMCIA_CARD1, DB1XXX_PCMCIA_CD1,
244 /*DB1XXX_PCMCIA_STSCHG1*/0, 0, 1);
Manuel Lauss37663862011-08-12 11:39:45 +0200245#ifdef CONFIG_MIPS_DB1100
246 platform_device_register(&au1100_lcd_device);
Manuel Lauss27dd65a2009-10-04 14:55:28 +0200247#endif
Manuel Laussb2ce3052011-07-25 13:44:46 +0200248 platform_device_register(&db1x00_codec_dev);
249 platform_device_register(&alchemy_ac97c_dma_dev);
250 platform_device_register(&alchemy_ac97c_dev);
251 platform_device_register(&db1x00_audio_dev);
252
Manuel Lauss7c4b24d2011-11-10 12:06:21 +0000253 db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED);
Manuel Lauss27dd65a2009-10-04 14:55:28 +0200254 return 0;
255}
256device_initcall(db1xxx_dev_init);