1 From 7efb2cae3df49ba749860a0df04933dc522da224 Mon Sep 17 00:00:00 2001
2 From: Lars-Peter Clausen <lars@metafoo.de>
3 Date: Sat, 24 Apr 2010 17:35:05 +0200
4 Subject: [PATCH] Add JZ4740 SoC core support
7 arch/mips/Kconfig | 4 +
8 arch/mips/Makefile | 6 +
9 arch/mips/include/asm/bootinfo.h | 6 +
10 arch/mips/include/asm/cpu.h | 13 +-
11 arch/mips/include/asm/mach-jz4740/base.h | 28 +
12 arch/mips/include/asm/mach-jz4740/clock.h | 28 +
13 arch/mips/include/asm/mach-jz4740/dma.h | 90 +++
14 arch/mips/include/asm/mach-jz4740/gpio.h | 398 +++++++++++
15 arch/mips/include/asm/mach-jz4740/irq.h | 55 ++
16 arch/mips/include/asm/mach-jz4740/platform.h | 34 +
17 arch/mips/include/asm/mach-jz4740/serial.h | 30 +
18 arch/mips/include/asm/mach-jz4740/timer.h | 22 +
19 arch/mips/include/asm/mach-jz4740/war.h | 25 +
20 arch/mips/jz4740/Kconfig | 29 +
21 arch/mips/jz4740/Makefile | 17 +
22 arch/mips/jz4740/clock-debugfs.c | 109 +++
23 arch/mips/jz4740/clock.c | 935 ++++++++++++++++++++++++++
24 arch/mips/jz4740/clock.h | 75 ++
25 arch/mips/jz4740/dma.c | 339 ++++++++++
26 arch/mips/jz4740/gpio.c | 598 ++++++++++++++++
27 arch/mips/jz4740/irq.c | 174 +++++
28 arch/mips/jz4740/irq.h | 21 +
29 arch/mips/jz4740/platform.c | 246 +++++++
30 arch/mips/jz4740/pm.c | 59 ++
31 arch/mips/jz4740/prom.c | 69 ++
32 arch/mips/jz4740/pwm.c | 167 +++++
33 arch/mips/jz4740/reset.c | 81 +++
34 arch/mips/jz4740/reset.h | 7 +
35 arch/mips/jz4740/setup.c | 64 ++
36 arch/mips/jz4740/time.c | 145 ++++
37 arch/mips/jz4740/timer.c | 45 ++
38 arch/mips/jz4740/timer.h | 130 ++++
39 arch/mips/kernel/cpu-probe.c | 20 +
40 arch/mips/mm/tlbex.c | 5 +
41 34 files changed, 4073 insertions(+), 1 deletions(-)
42 create mode 100644 arch/mips/include/asm/mach-jz4740/base.h
43 create mode 100644 arch/mips/include/asm/mach-jz4740/clock.h
44 create mode 100644 arch/mips/include/asm/mach-jz4740/dma.h
45 create mode 100644 arch/mips/include/asm/mach-jz4740/gpio.h
46 create mode 100644 arch/mips/include/asm/mach-jz4740/irq.h
47 create mode 100644 arch/mips/include/asm/mach-jz4740/platform.h
48 create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
49 create mode 100644 arch/mips/include/asm/mach-jz4740/timer.h
50 create mode 100644 arch/mips/include/asm/mach-jz4740/war.h
51 create mode 100644 arch/mips/jz4740/Kconfig
52 create mode 100644 arch/mips/jz4740/Makefile
53 create mode 100644 arch/mips/jz4740/clock-debugfs.c
54 create mode 100644 arch/mips/jz4740/clock.c
55 create mode 100644 arch/mips/jz4740/clock.h
56 create mode 100644 arch/mips/jz4740/dma.c
57 create mode 100644 arch/mips/jz4740/gpio.c
58 create mode 100644 arch/mips/jz4740/irq.c
59 create mode 100644 arch/mips/jz4740/irq.h
60 create mode 100644 arch/mips/jz4740/platform.c
61 create mode 100644 arch/mips/jz4740/pm.c
62 create mode 100644 arch/mips/jz4740/prom.c
63 create mode 100644 arch/mips/jz4740/pwm.c
64 create mode 100644 arch/mips/jz4740/reset.c
65 create mode 100644 arch/mips/jz4740/reset.h
66 create mode 100644 arch/mips/jz4740/setup.c
67 create mode 100644 arch/mips/jz4740/time.c
68 create mode 100644 arch/mips/jz4740/timer.c
69 create mode 100644 arch/mips/jz4740/timer.h
71 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
72 index 7e6fd1c..e902f02 100644
73 --- a/arch/mips/Kconfig
74 +++ b/arch/mips/Kconfig
75 @@ -162,6 +162,9 @@ config MACH_JAZZ
76 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
77 Olivetti M700-10 workstations.
80 + bool "Ingenic JZ4720/JZ4740 based machines"
83 bool "LASAT Networks platforms"
85 @@ -686,6 +689,7 @@ endchoice
86 source "arch/mips/alchemy/Kconfig"
87 source "arch/mips/bcm63xx/Kconfig"
88 source "arch/mips/jazz/Kconfig"
89 +source "arch/mips/jz4740/Kconfig"
90 source "arch/mips/lasat/Kconfig"
91 source "arch/mips/pmc-sierra/Kconfig"
92 source "arch/mips/powertv/Kconfig"
93 diff --git a/arch/mips/Makefile b/arch/mips/Makefile
94 index 0b9c01a..007a82e 100644
95 --- a/arch/mips/Makefile
96 +++ b/arch/mips/Makefile
97 @@ -659,6 +659,12 @@ else
98 load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
103 +core-$(CONFIG_SOC_JZ4740) += arch/mips/jz4740/
104 +cflags-$(CONFIG_SOC_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
105 +load-$(CONFIG_SOC_JZ4740) += 0xffffffff80010000
107 cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
108 drivers-$(CONFIG_PCI) += arch/mips/pci/
110 diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
111 index 09eee09..15a8ef0 100644
112 --- a/arch/mips/include/asm/bootinfo.h
113 +++ b/arch/mips/include/asm/bootinfo.h
115 #define MACH_LEMOTE_LL2F 7
116 #define MACH_LOONGSON_END 8
119 + * Valid machtype for group INGENIC
121 +#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
122 +#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
124 extern char *system_type;
125 const char *get_system_type(void);
127 diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
128 index a5acda4..e67aebb 100644
129 --- a/arch/mips/include/asm/cpu.h
130 +++ b/arch/mips/include/asm/cpu.h
132 #define PRID_COMP_LSI 0x080000
133 #define PRID_COMP_LEXRA 0x0b0000
134 #define PRID_COMP_CAVIUM 0x0d0000
136 +#define PRID_COMP_INGENIC 0xd00000
139 * Assigned values for the product ID register. In order to detect a
141 #define PRID_IMP_CAVIUM_CN52XX 0x0700
144 + * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
147 +#define PRID_IMP_JZRISC 0x0200
150 * Definitions for 7:0 on legacy processors
153 @@ -226,6 +232,11 @@ enum cpu_type_enum {
154 CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
155 CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
158 + * Ingenic class processors
160 + CPU_JZRISC, CPU_XBURST,
165 diff --git a/arch/mips/include/asm/mach-jz4740/base.h b/arch/mips/include/asm/mach-jz4740/base.h
167 index 0000000..a281972
169 +++ b/arch/mips/include/asm/mach-jz4740/base.h
171 +#ifndef __JZ4740_BASE_ADDR_H__
172 +#define __JZ4740_BASE_ADDR_H__
174 +#define JZ4740_CPM_BASE_ADDR 0xb0000000
175 +#define JZ4740_INTC_BASE_ADDR 0xb0001000
176 +#define JZ4740_TCU_BASE_ADDR 0xb0002000
177 +#define JZ4740_WDT_BASE_ADDR 0xb0002000
178 +#define JZ4740_RTC_BASE_ADDR 0xb0003000
179 +#define JZ4740_GPIO_BASE_ADDR 0xb0010000
180 +#define JZ4740_AIC_BASE_ADDR 0xb0020000
181 +#define JZ4740_ICDC_BASE_ADDR 0xb0020000
182 +#define JZ4740_MSC_BASE_ADDR 0xb0021000
183 +#define JZ4740_UART0_BASE_ADDR 0xb0030000
184 +#define JZ4740_UART1_BASE_ADDR 0xb0031000
185 +#define JZ4740_I2C_BASE_ADDR 0xb0042000
186 +#define JZ4740_SSI_BASE_ADDR 0xb0043000
187 +#define JZ4740_SADC_BASE_ADDR 0xb0070000
188 +#define JZ4740_EMC_BASE_ADDR 0xb3010000
189 +#define JZ4740_DMAC_BASE_ADDR 0xb3020000
190 +#define JZ4740_UHC_BASE_ADDR 0xb3030000
191 +#define JZ4740_UDC_BASE_ADDR 0xb3040000
192 +#define JZ4740_LCD_BASE_ADDR 0xb3050000
193 +#define JZ4740_SLCD_BASE_ADDR 0xb3050000
194 +#define JZ4740_CIM_BASE_ADDR 0xb3060000
195 +#define JZ4740_IPU_BASE_ADDR 0xb3080000
196 +#define JZ4740_ETH_BASE_ADDR 0xb3100000
199 diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
201 index 0000000..9069727
203 +++ b/arch/mips/include/asm/mach-jz4740/clock.h
206 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
208 + * This program is free software; you can redistribute it and/or modify it
209 + * under the terms of the GNU General Public License as published by the
210 + * Free Software Foundation; either version 2 of the License, or (at your
211 + * option) any later version.
213 + * You should have received a copy of the GNU General Public License along
214 + * with this program; if not, write to the Free Software Foundation, Inc.,
215 + * 675 Mass Ave, Cambridge, MA 02139, USA.
219 +#ifndef __ASM_JZ4740_CLOCK_H__
220 +#define __ASM_JZ4740_CLOCK_H__
222 +enum jz4740_wait_mode {
223 + JZ4740_WAIT_MODE_IDLE,
224 + JZ4740_WAIT_MODE_SLEEP,
227 +void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
229 +void jz4740_clock_udc_enable_auto_suspend(void);
230 +void jz4740_clock_udc_disable_auto_suspend(void);
233 diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h
235 index 0000000..d31d4e0
237 +++ b/arch/mips/include/asm/mach-jz4740/dma.h
240 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
241 + * JZ7420/JZ4740 DMA definitions
243 + * This program is free software; you can redistribute it and/or modify it
244 + * under the terms of the GNU General Public License as published by the
245 + * Free Software Foundation; either version 2 of the License, or (at your
246 + * option) any later version.
248 + * You should have received a copy of the GNU General Public License along
249 + * with this program; if not, write to the Free Software Foundation, Inc.,
250 + * 675 Mass Ave, Cambridge, MA 02139, USA.
254 +#ifndef __ASM_MACH_JZ4740_DMA_H__
255 +#define __ASM_MACH_JZ4740_DMA_H__
257 +struct jz4740_dma_chan;
259 +enum jz4740_dma_request_type {
260 + JZ4740_DMA_TYPE_AUTO_REQUEST = 8,
261 + JZ4740_DMA_TYPE_UART_TRANSMIT = 20,
262 + JZ4740_DMA_TYPE_UART_RECEIVE = 21,
263 + JZ4740_DMA_TYPE_SPI_TRANSMIT = 22,
264 + JZ4740_DMA_TYPE_SPI_RECEIVE = 23,
265 + JZ4740_DMA_TYPE_AIC_TRANSMIT = 24,
266 + JZ4740_DMA_TYPE_AIC_RECEIVE = 25,
267 + JZ4740_DMA_TYPE_MMC_TRANSMIT = 26,
268 + JZ4740_DMA_TYPE_MMC_RECEIVE = 27,
269 + JZ4740_DMA_TYPE_TCU = 28,
270 + JZ4740_DMA_TYPE_SADC = 29,
271 + JZ4740_DMA_TYPE_SLCD = 30,
274 +enum jz4740_dma_width {
275 + JZ4740_DMA_WIDTH_8BIT,
276 + JZ4740_DMA_WIDTH_16BIT,
277 + JZ4740_DMA_WIDTH_32BIT,
280 +enum jz4740_dma_transfer_size {
281 + JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0,
282 + JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1,
283 + JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2,
284 + JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
285 + JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
288 +enum jz4740_dma_flags {
289 + JZ4740_DMA_SRC_AUTOINC = 0x2,
290 + JZ4740_DMA_DST_AUTOINC = 0x1,
293 +enum jz4740_dma_mode {
294 + JZ4740_DMA_MODE_SINGLE = 0,
295 + JZ4740_DMA_MODE_BLOCK = 1,
298 +struct jz4740_dma_config {
299 + enum jz4740_dma_width src_width;
300 + enum jz4740_dma_width dst_width;
301 + enum jz4740_dma_transfer_size transfer_size;
302 + enum jz4740_dma_request_type request_type;
303 + enum jz4740_dma_flags flags;
304 + enum jz4740_dma_mode mode;
307 +typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
309 +struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
310 +void jz4740_dma_free(struct jz4740_dma_chan *dma);
312 +void jz4740_dma_configure(struct jz4740_dma_chan *dma,
313 + const struct jz4740_dma_config *config);
316 +void jz4740_dma_enable(struct jz4740_dma_chan *dma);
317 +void jz4740_dma_disable(struct jz4740_dma_chan *dma);
319 +void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
320 +void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
321 +void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
323 +uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
325 +void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
326 + jz4740_dma_complete_callback_t cb);
328 +#endif /* __ASM_JZ4740_DMA_H__ */
329 diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h
331 index 0000000..5f175d7
333 +++ b/arch/mips/include/asm/mach-jz4740/gpio.h
336 + * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
337 + * JZ7420/JZ4740 GPIO pin definitions
339 + * This program is free software; you can redistribute it and/or modify it
340 + * under the terms of the GNU General Public License as published by the
341 + * Free Software Foundation; either version 2 of the License, or (at your
342 + * option) any later version.
344 + * You should have received a copy of the GNU General Public License along
345 + * with this program; if not, write to the Free Software Foundation, Inc.,
346 + * 675 Mass Ave, Cambridge, MA 02139, USA.
353 +#include <linux/types.h>
355 +enum jz_gpio_function {
364 + Usually a driver for a SoC component has to request several gpio pins and
365 + configure them as funcion pins.
366 + jz_gpio_bulk_request can be used to ease this process.
367 + Usually one would do something like:
369 + const static struct jz_gpio_bulk_request i2c_pins[] = {
370 + JZ_GPIO_BULK_PIN(I2C_SDA),
371 + JZ_GPIO_BULK_PIN(I2C_SCK),
374 + inside the probe function:
376 + ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
380 + inside the remove function:
382 + jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
386 +struct jz_gpio_bulk_request {
389 + enum jz_gpio_function function;
392 +#define JZ_GPIO_BULK_PIN(pin) { \
393 + .gpio = JZ_GPIO_ ## pin, \
395 + .function = JZ_GPIO_FUNC_ ## pin \
398 +int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
399 +void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
400 +void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
401 +void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
402 +void jz_gpio_enable_pullup(unsigned gpio);
403 +void jz_gpio_disable_pullup(unsigned gpio);
404 +int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
406 +int jz_gpio_port_direction_input(int port, uint32_t mask);
407 +int jz_gpio_port_direction_output(int port, uint32_t mask);
408 +void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
409 +uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
411 +#include <asm/mach-generic/gpio.h>
413 +#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
414 +#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
415 +#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
416 +#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
418 +/* Port A function pins */
419 +#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0)
420 +#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1)
421 +#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2)
422 +#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3)
423 +#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4)
424 +#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5)
425 +#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6)
426 +#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7)
427 +#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8)
428 +#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9)
429 +#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10)
430 +#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11)
431 +#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12)
432 +#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13)
433 +#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14)
434 +#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15)
435 +#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16)
436 +#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17)
437 +#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18)
438 +#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19)
439 +#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20)
440 +#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21)
441 +#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22)
442 +#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23)
443 +#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24)
444 +#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25)
445 +#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26)
446 +#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27)
447 +#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28)
448 +#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29)
449 +#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30)
450 +#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31)
452 +#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1
453 +#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1
454 +#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1
455 +#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1
456 +#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1
457 +#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1
458 +#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1
459 +#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1
460 +#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1
461 +#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1
462 +#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1
463 +#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1
464 +#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1
465 +#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1
466 +#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1
467 +#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1
468 +#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1
469 +#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1
470 +#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1
471 +#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1
472 +#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1
473 +#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1
474 +#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1
475 +#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1
476 +#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1
477 +#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1
478 +#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1
479 +#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1
480 +#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1
481 +#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1
482 +#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1
483 +#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1
485 +/* Port B function pins */
486 +#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0)
487 +#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1)
488 +#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2)
489 +#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3)
490 +#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4)
491 +#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5)
492 +#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6)
493 +#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7)
494 +#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8)
495 +#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9)
496 +#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10)
497 +#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11)
498 +#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12)
499 +#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13)
500 +#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14)
501 +#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15)
502 +#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16)
503 +#define JZ_GPIO_MEM_CLS JZ_GPIO_PORTB(17)
504 +#define JZ_GPIO_MEM_SPL JZ_GPIO_PORTB(18)
505 +#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19)
506 +#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20)
507 +#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21)
508 +#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22)
509 +#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23)
510 +#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24)
511 +#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25)
512 +#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26)
513 +#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27)
514 +#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28)
515 +#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29)
516 +#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30)
517 +#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31)
519 +#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1
520 +#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1
521 +#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1
522 +#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1
523 +#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1
524 +#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1
525 +#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1
526 +#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1
527 +#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1
528 +#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1
529 +#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1
530 +#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1
531 +#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1
532 +#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1
533 +#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1
534 +#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1
535 +#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1
536 +#define JZ_GPIO_FUNC_MEM_CLS JZ_GPIO_FUNC1
537 +#define JZ_GPIO_FUNC_MEM_SPL JZ_GPIO_FUNC1
538 +#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1
539 +#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1
540 +#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1
541 +#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1
542 +#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1
543 +#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1
544 +#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1
545 +#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1
546 +#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1
547 +#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1
548 +#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1
549 +#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1
550 +#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1
553 +#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17)
554 +#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18)
556 +#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2
557 +#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2
559 +/* Port C function pins */
560 +#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0)
561 +#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1)
562 +#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2)
563 +#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3)
564 +#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4)
565 +#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5)
566 +#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6)
567 +#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7)
568 +#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8)
569 +#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9)
570 +#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10)
571 +#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11)
572 +#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12)
573 +#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13)
574 +#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14)
575 +#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15)
576 +#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16)
577 +#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17)
578 +#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18)
579 +#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19)
580 +#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20)
581 +#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21)
582 +#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22)
583 +#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23)
584 +#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24)
585 +#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25)
586 +#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26)
587 +#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
588 +#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
589 +#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
591 +#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
592 +#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
593 +#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1
594 +#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1
595 +#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1
596 +#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1
597 +#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1
598 +#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1
599 +#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1
600 +#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1
601 +#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1
602 +#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1
603 +#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1
604 +#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1
605 +#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1
606 +#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1
607 +#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1
608 +#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1
609 +#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1
610 +#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1
611 +#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1
612 +#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1
613 +#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1
614 +#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1
615 +#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1
616 +#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1
617 +#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1
618 +#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
619 +#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
620 +#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
623 +#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
624 +#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23)
626 +#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2
627 +#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2
629 +/* Port D function pins */
630 +#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0)
631 +#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1)
632 +#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2)
633 +#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3)
634 +#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4)
635 +#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5)
636 +#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6)
637 +#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7)
638 +#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8)
639 +#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9)
640 +#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10)
641 +#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11)
642 +#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12)
643 +#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13)
644 +#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14)
645 +#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15)
646 +#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16)
647 +#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17)
648 +#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18)
649 +#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19)
650 +#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20)
651 +#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21)
652 +#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22)
653 +#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23)
654 +#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24)
655 +#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25)
656 +#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26)
657 +#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27)
658 +#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28)
659 +#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30)
660 +#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31)
662 +#define JZ_GPIO_FUNC_CIM_DATA JZ_GPIO_FUNC1
663 +#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC_CIM_DATA
664 +#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC_CIM_DATA
665 +#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC_CIM_DATA
666 +#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC_CIM_DATA
667 +#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC_CIM_DATA
668 +#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC_CIM_DATA
669 +#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC_CIM_DATA
670 +#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC_CIM_DATA
671 +#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1
672 +#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1
673 +#define JZ_GPIO_FUNC_MSC_DATA JZ_GPIO_FUNC1
674 +#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC_MSC_DATA
675 +#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC_MSC_DATA
676 +#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC_MSC_DATA
677 +#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC_MSC_DATA
678 +#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1
679 +#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1
680 +#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1
681 +#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1
682 +#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1
683 +#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1
684 +#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1
685 +#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1
686 +#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1
688 +#define JZ_GPIO_FUNC_PWM JZ_GPIO_FUNC1
689 +#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC_PWM
690 +#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC_PWM
691 +#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC_PWM
692 +#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC_PWM
693 +#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC_PWM
694 +#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC_PWM
695 +#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC_PWM
696 +#define JZ_GPIO_FUNC_PWM7 JZ_GPIO_FUNC_PWM
698 +#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18)
699 +#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19)
700 +#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20)
701 +#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21)
702 +#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22)
703 +#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23)
704 +#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24)
705 +#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25)
706 +#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26)
707 +#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27)
708 +#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28)
709 +#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30)
710 +#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31)
712 +#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2
713 +#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2
714 +#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2
715 +#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2
716 +#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2
717 +#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2
718 +#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2
719 +#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2
720 +#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2
721 +#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2
722 +#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2
723 +#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2
724 +#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2
726 +#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30)
727 +#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31)
729 +#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3
730 +#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3
733 diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
735 index 0000000..5e27b78
737 +++ b/arch/mips/include/asm/mach-jz4740/irq.h
740 + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
741 + * JZ7420/JZ4740 IRQ definitions
743 + * This program is free software; you can redistribute it and/or modify it
744 + * under the terms of the GNU General Public License as published by the
745 + * Free Software Foundation; either version 2 of the License, or (at your
746 + * option) any later version.
748 + * You should have received a copy of the GNU General Public License along
749 + * with this program; if not, write to the Free Software Foundation, Inc.,
750 + * 675 Mass Ave, Cambridge, MA 02139, USA.
754 +#ifndef __ASM_MACH_JZ4740_IRQ_H__
755 +#define __ASM_MACH_JZ4740_IRQ_H__
757 +#define MIPS_CPU_IRQ_BASE 0
758 +#define JZ4740_IRQ_BASE 8
760 +/* 1st-level interrupts */
761 +#define JZ4740_IRQ(x) (JZ4740_IRQ_BASE + (x))
762 +#define JZ4740_IRQ_I2C JZ4740_IRQ(1)
763 +#define JZ4740_IRQ_UHC JZ4740_IRQ(3)
764 +#define JZ4740_IRQ_UART1 JZ4740_IRQ(8)
765 +#define JZ4740_IRQ_UART0 JZ4740_IRQ(9)
766 +#define JZ4740_IRQ_SADC JZ4740_IRQ(12)
767 +#define JZ4740_IRQ_MSC JZ4740_IRQ(14)
768 +#define JZ4740_IRQ_RTC JZ4740_IRQ(15)
769 +#define JZ4740_IRQ_SSI JZ4740_IRQ(16)
770 +#define JZ4740_IRQ_CIM JZ4740_IRQ(17)
771 +#define JZ4740_IRQ_AIC JZ4740_IRQ(18)
772 +#define JZ4740_IRQ_ETH JZ4740_IRQ(19)
773 +#define JZ4740_IRQ_DMAC JZ4740_IRQ(20)
774 +#define JZ4740_IRQ_TCU2 JZ4740_IRQ(21)
775 +#define JZ4740_IRQ_TCU1 JZ4740_IRQ(22)
776 +#define JZ4740_IRQ_TCU0 JZ4740_IRQ(23)
777 +#define JZ4740_IRQ_UDC JZ4740_IRQ(24)
778 +#define JZ4740_IRQ_GPIO3 JZ4740_IRQ(25)
779 +#define JZ4740_IRQ_GPIO2 JZ4740_IRQ(26)
780 +#define JZ4740_IRQ_GPIO1 JZ4740_IRQ(27)
781 +#define JZ4740_IRQ_GPIO0 JZ4740_IRQ(28)
782 +#define JZ4740_IRQ_IPU JZ4740_IRQ(29)
783 +#define JZ4740_IRQ_LCD JZ4740_IRQ(30)
785 +/* 2nd-level interrupts */
786 +#define JZ4740_IRQ_DMA(x) ((x) + JZ4740_IRQ(32))
788 +#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
789 +#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x))
791 +#define NR_IRQS (JZ4740_IRQ_GPIO(127) + 1)
794 diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
796 index 0000000..a2e2871
798 +++ b/arch/mips/include/asm/mach-jz4740/platform.h
801 + * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
802 + * JZ7420/JZ4740 platform device definitions
804 + * This program is free software; you can redistribute it and/or modify it
805 + * under the terms of the GNU General Public License as published by the
806 + * Free Software Foundation; either version 2 of the License, or (at your
807 + * option) any later version.
809 + * You should have received a copy of the GNU General Public License along
810 + * with this program; if not, write to the Free Software Foundation, Inc.,
811 + * 675 Mass Ave, Cambridge, MA 02139, USA.
816 +#ifndef __JZ4740_PLATFORM_H
817 +#define __JZ4740_PLATFORM_H
819 +#include <linux/platform_device.h>
821 +extern struct platform_device jz4740_usb_ohci_device;
822 +extern struct platform_device jz4740_usb_gdt_device;
823 +extern struct platform_device jz4740_mmc_device;
824 +extern struct platform_device jz4740_rtc_device;
825 +extern struct platform_device jz4740_i2c_device;
826 +extern struct platform_device jz4740_nand_device;
827 +extern struct platform_device jz4740_framebuffer_device;
828 +extern struct platform_device jz4740_i2s_device;
829 +extern struct platform_device jz4740_codec_device;
830 +extern struct platform_device jz4740_adc_device;
831 +extern struct platform_device jz4740_battery_device;
834 diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
836 index 0000000..c4819b9
838 +++ b/arch/mips/include/asm/mach-jz4740/serial.h
841 + * linux/include/asm-mips/mach-jz4740/serial.h
843 + * Ingenic's JZ4740 common include.
845 + * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc.
847 + * Author: <yliu@ingenic.cn>
849 + * This program is free software; you can redistribute it and/or modify
850 + * it under the terms of the GNU General Public License version 2 as
851 + * published by the Free Software Foundation.
854 +#ifndef __ASM_BOARD_SERIAL_H__
855 +#define __ASM_BOARD_SERIAL_H__
857 +#ifndef CONFIG_SERIAL_MANY_PORTS
858 +#undef RS_TABLE_SIZE
859 +#define RS_TABLE_SIZE 1
862 +#define JZ_BASE_BAUD (12000000/16)
864 +#define JZ_SERIAL_PORT_DEFNS \
865 + { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART0, \
866 + .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART0_BASE, \
867 + .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM },
869 +#endif /* __ASM_BORAD_SERIAL_H__ */
870 diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
872 index 0000000..30153ff
874 +++ b/arch/mips/include/asm/mach-jz4740/timer.h
877 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
878 + * JZ4740 platform timer support
880 + * This program is free software; you can redistribute it and/or modify it
881 + * under the terms of the GNU General Public License as published by the
882 + * Free Software Foundation; either version 2 of the License, or (at your
883 + * option) any later version.
885 + * You should have received a copy of the GNU General Public License along
886 + * with this program; if not, write to the Free Software Foundation, Inc.,
887 + * 675 Mass Ave, Cambridge, MA 02139, USA.
891 +#ifndef __ASM_MACH_JZ4740_TIMER
892 +#define __ASM_MACH_JZ4740_TIMER
894 +void jz4740_timer_enable_watchdog(void);
895 +void jz4740_timer_disable_watchdog(void);
898 diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
900 index 0000000..3a5bc17
902 +++ b/arch/mips/include/asm/mach-jz4740/war.h
905 + * This file is subject to the terms and conditions of the GNU General Public
906 + * License. See the file "COPYING" in the main directory of this archive
907 + * for more details.
909 + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
911 +#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H
912 +#define __ASM_MIPS_MACH_JZ4740_WAR_H
914 +#define R4600_V1_INDEX_ICACHEOP_WAR 0
915 +#define R4600_V1_HIT_CACHEOP_WAR 0
916 +#define R4600_V2_HIT_CACHEOP_WAR 0
917 +#define R5432_CP0_INTERRUPT_WAR 0
918 +#define BCM1250_M3_WAR 0
919 +#define SIBYTE_1956_WAR 0
920 +#define MIPS4K_ICACHE_REFILL_WAR 0
921 +#define MIPS_CACHE_SYNC_WAR 0
922 +#define TX49XX_ICACHE_INDEX_INV_WAR 0
923 +#define RM9000_CDEX_SMP_WAR 0
924 +#define ICACHE_REFILLS_WORKAROUND_WAR 0
925 +#define R10000_LLSC_WAR 0
926 +#define MIPS34K_MISSED_ITLB_WAR 0
928 +#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
929 diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
931 index 0000000..5f6da09
933 +++ b/arch/mips/jz4740/Kconfig
936 + prompt "Machine type"
938 + default JZ4740_QI_LB60
948 + select GENERIC_GPIO
949 + select ARCH_REQUIRE_GPIOLIB
950 + select SYS_HAS_EARLY_PRINTK
951 + select SYS_SUPPORTS_LITTLE_ENDIAN
953 + select DMA_NONCOHERENT
959 + select SYS_HAS_CPU_MIPS32_R1
960 + select SYS_SUPPORTS_32BIT_KERNEL
964 diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
966 index 0000000..e389ddd
968 +++ b/arch/mips/jz4740/Makefile
971 +# Makefile for the Ingenic JZ4740.
974 +# Object file lists.
976 +obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
977 + gpio.o clock.o platform.o timer.o pwm.o
979 +obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
981 +# board specific support
985 +obj-$(CONFIG_PM) += pm.o
987 diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
989 index 0000000..993b91b
991 +++ b/arch/mips/jz4740/clock-debugfs.c
994 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
995 + * JZ4740 SoC clock support debugfs entries
997 + * This program is free software; you can redistribute it and/or modify it
998 + * under the terms of the GNU General Public License as published by the
999 + * Free Software Foundation; either version 2 of the License, or (at your
1000 + * option) any later version.
1002 + * You should have received a copy of the GNU General Public License along
1003 + * with this program; if not, write to the Free Software Foundation, Inc.,
1004 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1008 +#include <linux/kernel.h>
1009 +#include <linux/module.h>
1010 +#include <linux/clk.h>
1011 +#include <linux/err.h>
1013 +#include <linux/debugfs.h>
1014 +#include <linux/uaccess.h>
1016 +#include <asm/mach-jz4740/clock.h>
1019 +static struct dentry *jz4740_clock_debugfs;
1021 +static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
1023 + struct clk *clk = data;
1024 + *value = clk_is_enabled(clk);
1029 +static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
1031 + struct clk *clk = data;
1034 + return clk_enable(clk);
1041 +DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
1042 + jz4740_clock_debugfs_show_enabled,
1043 + jz4740_clock_debugfs_set_enabled,
1046 +static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
1048 + struct clk *clk = data;
1049 + *value = clk_get_rate(clk);
1054 +DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
1055 + jz4740_clock_debugfs_show_rate,
1059 +void jz4740_clock_debugfs_add_clk(struct clk *clk)
1061 + if (!jz4740_clock_debugfs)
1064 + clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
1065 + debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
1066 + &jz4740_clock_debugfs_ops_rate);
1067 + debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
1068 + &jz4740_clock_debugfs_ops_enabled);
1070 + if (clk->parent) {
1071 + char parent_path[100];
1072 + snprintf(parent_path, 100, "../%s", clk->parent->name);
1073 + clk->debugfs_parent_entry = debugfs_create_symlink("parent",
1074 + clk->debugfs_entry,
1079 +/* TODO: Locking */
1080 +void jz4740_clock_debugfs_update_parent(struct clk *clk)
1082 + if (clk->debugfs_parent_entry)
1083 + debugfs_remove(clk->debugfs_parent_entry);
1085 + if (clk->parent) {
1086 + char parent_path[100];
1087 + snprintf(parent_path, 100, "../%s", clk->parent->name);
1088 + clk->debugfs_parent_entry = debugfs_create_symlink("parent",
1089 + clk->debugfs_entry,
1092 + clk->debugfs_parent_entry = NULL;
1096 +void jz4740_clock_debugfs_init(void)
1098 + jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
1099 + if (IS_ERR(jz4740_clock_debugfs))
1100 + jz4740_clock_debugfs = NULL;
1102 diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
1103 new file mode 100644
1104 index 0000000..3954a20
1106 +++ b/arch/mips/jz4740/clock.c
1109 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
1110 + * JZ4740 SoC clock support
1112 + * This program is free software; you can redistribute it and/or modify it
1113 + * under the terms of the GNU General Public License as published by the
1114 + * Free Software Foundation; either version 2 of the License, or (at your
1115 + * option) any later version.
1117 + * You should have received a copy of the GNU General Public License along
1118 + * with this program; if not, write to the Free Software Foundation, Inc.,
1119 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1123 +#include <linux/kernel.h>
1124 +#include <linux/errno.h>
1125 +#include <linux/clk.h>
1126 +#include <linux/spinlock.h>
1127 +#include <linux/io.h>
1128 +#include <linux/module.h>
1129 +#include <linux/list.h>
1130 +#include <linux/err.h>
1132 +#include <asm/mach-jz4740/clock.h>
1133 +#include <asm/mach-jz4740/base.h>
1137 +#define JZ_REG_CLOCK_CTRL 0x00
1138 +#define JZ_REG_CLOCK_LOW_POWER 0x04
1139 +#define JZ_REG_CLOCK_PLL 0x10
1140 +#define JZ_REG_CLOCK_GATE 0x20
1141 +#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
1142 +#define JZ_REG_CLOCK_I2S 0x60
1143 +#define JZ_REG_CLOCK_LCD 0x64
1144 +#define JZ_REG_CLOCK_MMC 0x68
1145 +#define JZ_REG_CLOCK_UHC 0x6C
1146 +#define JZ_REG_CLOCK_SPI 0x74
1148 +#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
1149 +#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
1150 +#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
1151 +#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
1152 +#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
1153 +#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
1154 +#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
1155 +#define JZ_CLOCK_CTRL_UDIV_OFFSET 23
1156 +#define JZ_CLOCK_CTRL_LDIV_OFFSET 16
1157 +#define JZ_CLOCK_CTRL_MDIV_OFFSET 12
1158 +#define JZ_CLOCK_CTRL_PDIV_OFFSET 8
1159 +#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
1160 +#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
1162 +#define JZ_CLOCK_GATE_UART0 BIT(0)
1163 +#define JZ_CLOCK_GATE_TCU BIT(1)
1164 +#define JZ_CLOCK_GATE_RTC BIT(2)
1165 +#define JZ_CLOCK_GATE_I2C BIT(3)
1166 +#define JZ_CLOCK_GATE_SPI BIT(4)
1167 +#define JZ_CLOCK_GATE_AIC BIT(5)
1168 +#define JZ_CLOCK_GATE_I2S BIT(6)
1169 +#define JZ_CLOCK_GATE_MMC BIT(7)
1170 +#define JZ_CLOCK_GATE_ADC BIT(8)
1171 +#define JZ_CLOCK_GATE_CIM BIT(9)
1172 +#define JZ_CLOCK_GATE_LCD BIT(10)
1173 +#define JZ_CLOCK_GATE_UDC BIT(11)
1174 +#define JZ_CLOCK_GATE_DMAC BIT(12)
1175 +#define JZ_CLOCK_GATE_IPU BIT(13)
1176 +#define JZ_CLOCK_GATE_UHC BIT(14)
1177 +#define JZ_CLOCK_GATE_UART1 BIT(15)
1179 +#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
1181 +#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
1183 +#define JZ_CLOCK_MMC_DIV_MASK 0x001f
1185 +#define JZ_CLOCK_UHC_DIV_MASK 0x000f
1187 +#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
1188 +#define JZ_CLOCK_SPI_DIV_MASK 0x000f
1190 +#define JZ_CLOCK_PLL_M_MASK 0x01ff
1191 +#define JZ_CLOCK_PLL_N_MASK 0x001f
1192 +#define JZ_CLOCK_PLL_OD_MASK 0x0003
1193 +#define JZ_CLOCK_PLL_STABLE BIT(10)
1194 +#define JZ_CLOCK_PLL_BYPASS BIT(9)
1195 +#define JZ_CLOCK_PLL_ENABLED BIT(8)
1196 +#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f
1197 +#define JZ_CLOCK_PLL_M_OFFSET 23
1198 +#define JZ_CLOCK_PLL_N_OFFSET 18
1199 +#define JZ_CLOCK_PLL_OD_OFFSET 16
1201 +#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
1202 +#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
1204 +#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
1205 +#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
1207 +static void __iomem *jz_clock_base;
1208 +static spinlock_t jz_clock_lock;
1209 +static LIST_HEAD(jz_clocks);
1213 + uint32_t div_offset;
1216 +struct divided_clk {
1222 +struct static_clk {
1224 + unsigned long rate;
1227 +static uint32_t jz_clk_reg_read(int reg)
1229 + return readl(jz_clock_base + reg);
1232 +static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
1236 + spin_lock(&jz_clock_lock);
1237 + val2 = readl(jz_clock_base + reg);
1240 + writel(val2, jz_clock_base + reg);
1241 + spin_unlock(&jz_clock_lock);
1244 +static void jz_clk_reg_set_bits(int reg, uint32_t mask)
1248 + spin_lock(&jz_clock_lock);
1249 + val = readl(jz_clock_base + reg);
1251 + writel(val, jz_clock_base + reg);
1252 + spin_unlock(&jz_clock_lock);
1255 +static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
1259 + spin_lock(&jz_clock_lock);
1260 + val = readl(jz_clock_base + reg);
1262 + writel(val, jz_clock_base + reg);
1263 + spin_unlock(&jz_clock_lock);
1266 +static int jz_clk_enable_gating(struct clk *clk)
1268 + if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1271 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
1275 +static int jz_clk_disable_gating(struct clk *clk)
1277 + if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1280 + jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
1284 +static int jz_clk_is_enabled_gating(struct clk *clk)
1286 + if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1289 + return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
1292 +static unsigned long jz_clk_static_get_rate(struct clk *clk)
1294 + return ((struct static_clk *)clk)->rate;
1297 +static int jz_clk_ko_enable(struct clk *clk)
1299 + jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
1303 +static int jz_clk_ko_disable(struct clk *clk)
1305 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
1309 +static int jz_clk_ko_is_enabled(struct clk *clk)
1311 + return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
1314 +static const int pllno[] = {1, 2, 2, 4};
1316 +static unsigned long jz_clk_pll_get_rate(struct clk *clk)
1323 + val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
1325 + if (val & JZ_CLOCK_PLL_BYPASS)
1326 + return clk_get_rate(clk->parent);
1328 + m = ((val >> 23) & 0x1ff) + 2;
1329 + n = ((val >> 18) & 0x1f) + 2;
1330 + od = (val >> 16) & 0x3;
1332 + return clk_get_rate(clk->parent) * (m / n) / pllno[od];
1335 +static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
1339 + reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
1340 + if (reg & JZ_CLOCK_CTRL_PLL_HALF)
1341 + return jz_clk_pll_get_rate(clk->parent);
1342 + return jz_clk_pll_get_rate(clk->parent) >> 1;
1345 +static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
1347 +static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
1349 + unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
1352 + div = parent_rate / rate;
1354 + return parent_rate / 32;
1356 + return parent_rate;
1358 + div &= (0x3 << (ffs(div) - 1));
1360 + return parent_rate / div;
1363 +static unsigned long jz_clk_main_get_rate(struct clk *clk)
1365 + struct main_clk *mclk = (struct main_clk *)clk;
1368 + div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
1370 + div >>= mclk->div_offset;
1373 + if (div >= ARRAY_SIZE(jz_clk_main_divs))
1374 + div = ARRAY_SIZE(jz_clk_main_divs) - 1;
1376 + return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
1379 +static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
1381 + struct main_clk *mclk = (struct main_clk *)clk;
1384 + unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
1386 + rate = jz_clk_main_round_rate(clk, rate);
1388 + div = parent_rate / rate;
1390 + i = (ffs(div) - 1) << 1;
1391 + if (i > 0 && !(div & BIT(i-1)))
1394 + jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
1395 + 0xf << mclk->div_offset);
1400 +static struct clk_ops jz_clk_static_ops = {
1401 + .get_rate = jz_clk_static_get_rate,
1402 + .enable = jz_clk_enable_gating,
1403 + .disable = jz_clk_disable_gating,
1404 + .is_enabled = jz_clk_is_enabled_gating,
1407 +static struct static_clk jz_clk_ext = {
1410 + .gate_bit = JZ4740_CLK_NOT_GATED,
1411 + .ops = &jz_clk_static_ops,
1415 +static struct clk_ops jz_clk_pll_ops = {
1416 + .get_rate = jz_clk_static_get_rate,
1419 +static struct clk jz_clk_pll = {
1421 + .parent = &jz_clk_ext.clk,
1422 + .ops = &jz_clk_pll_ops,
1425 +static struct clk_ops jz_clk_pll_half_ops = {
1426 + .get_rate = jz_clk_pll_half_get_rate,
1429 +static struct clk jz_clk_pll_half = {
1430 + .name = "pll half",
1431 + .parent = &jz_clk_pll,
1432 + .ops = &jz_clk_pll_half_ops,
1435 +static const struct clk_ops jz_clk_main_ops = {
1436 + .get_rate = jz_clk_main_get_rate,
1437 + .set_rate = jz_clk_main_set_rate,
1438 + .round_rate = jz_clk_main_round_rate,
1441 +static struct main_clk jz_clk_cpu = {
1444 + .parent = &jz_clk_pll,
1445 + .ops = &jz_clk_main_ops,
1447 + .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
1450 +static struct main_clk jz_clk_memory = {
1453 + .parent = &jz_clk_pll,
1454 + .ops = &jz_clk_main_ops,
1456 + .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
1459 +static struct main_clk jz_clk_high_speed_peripheral = {
1462 + .parent = &jz_clk_pll,
1463 + .ops = &jz_clk_main_ops,
1465 + .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
1469 +static struct main_clk jz_clk_low_speed_peripheral = {
1472 + .parent = &jz_clk_pll,
1473 + .ops = &jz_clk_main_ops,
1475 + .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
1478 +static const struct clk_ops jz_clk_ko_ops = {
1479 + .enable = jz_clk_ko_enable,
1480 + .disable = jz_clk_ko_disable,
1481 + .is_enabled = jz_clk_ko_is_enabled,
1484 +static struct clk jz_clk_ko = {
1486 + .parent = &jz_clk_memory.clk,
1487 + .ops = &jz_clk_ko_ops,
1490 +static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
1492 + if (parent == &jz_clk_pll)
1493 + jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
1494 + else if (parent == &jz_clk_ext.clk)
1495 + jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
1499 + clk->parent = parent;
1504 +static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
1506 + if (parent == &jz_clk_pll_half)
1507 + jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
1508 + else if (parent == &jz_clk_ext.clk)
1509 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
1513 + clk->parent = parent;
1518 +static int jz_clk_udc_enable(struct clk *clk)
1520 + jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
1521 + JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1526 +static int jz_clk_udc_disable(struct clk *clk)
1528 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
1529 + JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1534 +static int jz_clk_udc_is_enabled(struct clk *clk)
1536 + return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
1537 + JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1539 +static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
1541 + if (parent == &jz_clk_pll_half)
1542 + jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
1543 + else if (parent == &jz_clk_ext.clk)
1544 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
1548 + clk->parent = parent;
1553 +static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
1557 + if (clk->parent == &jz_clk_ext.clk)
1560 + div = clk_get_rate(clk->parent) / rate - 1;
1564 + else if (div > 63)
1567 + jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
1568 + JZ_CLOCK_CTRL_UDIV_MASK);
1572 +static unsigned long jz_clk_udc_get_rate(struct clk *clk)
1576 + if (clk->parent == &jz_clk_ext.clk)
1577 + return clk_get_rate(clk->parent);
1579 + div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
1580 + div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
1583 + return clk_get_rate(clk->parent) / div;
1586 +static unsigned long jz_clk_divided_get_rate(struct clk *clk)
1588 + struct divided_clk *dclk = (struct divided_clk *)clk;
1591 + if (clk->parent == &jz_clk_ext.clk)
1592 + return clk_get_rate(clk->parent);
1594 + div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
1596 + return clk_get_rate(clk->parent) / div;
1599 +static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
1601 + struct divided_clk *dclk = (struct divided_clk *)clk;
1604 + if (clk->parent == &jz_clk_ext.clk)
1607 + div = clk_get_rate(clk->parent) / rate - 1;
1611 + else if (div > dclk->mask)
1614 + jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
1619 +static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
1622 + unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
1624 + if (rate > 150000000)
1627 + div = parent_rate / rate;
1630 + else if (div > 32)
1633 + return parent_rate / div;
1636 +static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
1640 + if (rate > 150000000)
1643 + div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
1646 + else if (div > 31)
1649 + jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
1650 + JZ_CLOCK_CTRL_LDIV_MASK);
1655 +static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
1659 + div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
1660 + div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
1662 + return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
1665 +static const struct clk_ops jz_clk_ops_ld = {
1666 + .set_rate = jz_clk_ldclk_set_rate,
1667 + .get_rate = jz_clk_ldclk_get_rate,
1668 + .round_rate = jz_clk_ldclk_round_rate,
1669 + .enable = jz_clk_enable_gating,
1670 + .disable = jz_clk_disable_gating,
1671 + .is_enabled = jz_clk_is_enabled_gating,
1674 +static struct clk jz_clk_ld = {
1676 + .gate_bit = JZ_CLOCK_GATE_LCD,
1677 + .parent = &jz_clk_pll_half,
1678 + .ops = &jz_clk_ops_ld,
1682 +static struct clk jz_clk_cim_mclk = {
1683 + .name = "cim_mclk",
1684 + .parent = &jz_clk_high_speed_peripheral.clk,
1687 +static struct static_clk jz_clk_cim_pclk = {
1689 + .name = "cim_pclk",
1690 + .gate_bit = JZ_CLOCK_GATE_CIM,
1691 + .ops = &jz_clk_static_ops,
1695 +static const struct clk_ops jz_clk_i2s_ops = {
1696 + .set_rate = jz_clk_divided_set_rate,
1697 + .get_rate = jz_clk_divided_get_rate,
1698 + .enable = jz_clk_enable_gating,
1699 + .disable = jz_clk_disable_gating,
1700 + .is_enabled = jz_clk_is_enabled_gating,
1701 + .set_parent = jz_clk_i2s_set_parent,
1704 +static const struct clk_ops jz_clk_spi_ops = {
1705 + .set_rate = jz_clk_divided_set_rate,
1706 + .get_rate = jz_clk_divided_get_rate,
1707 + .enable = jz_clk_enable_gating,
1708 + .disable = jz_clk_disable_gating,
1709 + .is_enabled = jz_clk_is_enabled_gating,
1710 + .set_parent = jz_clk_spi_set_parent,
1713 +static const struct clk_ops jz_clk_divided_ops = {
1714 + .set_rate = jz_clk_divided_set_rate,
1715 + .get_rate = jz_clk_divided_get_rate,
1716 + .enable = jz_clk_enable_gating,
1717 + .disable = jz_clk_disable_gating,
1718 + .is_enabled = jz_clk_is_enabled_gating,
1721 +static struct divided_clk jz4740_clock_divided_clks[] = {
1724 + .name = "lcd_pclk",
1725 + .parent = &jz_clk_pll_half,
1726 + .gate_bit = JZ4740_CLK_NOT_GATED,
1727 + .ops = &jz_clk_divided_ops,
1729 + .reg = JZ_REG_CLOCK_LCD,
1730 + .mask = JZ_CLOCK_LCD_DIV_MASK,
1735 + .parent = &jz_clk_ext.clk,
1736 + .gate_bit = JZ_CLOCK_GATE_I2S,
1737 + .ops = &jz_clk_i2s_ops,
1739 + .reg = JZ_REG_CLOCK_I2S,
1740 + .mask = JZ_CLOCK_I2S_DIV_MASK,
1745 + .parent = &jz_clk_ext.clk,
1746 + .gate_bit = JZ_CLOCK_GATE_SPI,
1747 + .ops = &jz_clk_spi_ops,
1749 + .reg = JZ_REG_CLOCK_SPI,
1750 + .mask = JZ_CLOCK_SPI_DIV_MASK,
1755 + .parent = &jz_clk_pll_half,
1756 + .gate_bit = JZ_CLOCK_GATE_MMC,
1757 + .ops = &jz_clk_divided_ops,
1759 + .reg = JZ_REG_CLOCK_MMC,
1760 + .mask = JZ_CLOCK_MMC_DIV_MASK,
1765 + .parent = &jz_clk_pll_half,
1766 + .gate_bit = JZ_CLOCK_GATE_UHC,
1767 + .ops = &jz_clk_divided_ops,
1769 + .reg = JZ_REG_CLOCK_UHC,
1770 + .mask = JZ_CLOCK_UHC_DIV_MASK,
1774 +static const struct clk_ops jz_clk_udc_ops = {
1775 + .set_parent = jz_clk_udc_set_parent,
1776 + .set_rate = jz_clk_udc_set_rate,
1777 + .get_rate = jz_clk_udc_get_rate,
1778 + .enable = jz_clk_udc_enable,
1779 + .disable = jz_clk_udc_disable,
1780 + .is_enabled = jz_clk_udc_is_enabled,
1783 +static const struct clk_ops jz_clk_simple_ops = {
1784 + .enable = jz_clk_enable_gating,
1785 + .disable = jz_clk_disable_gating,
1786 + .is_enabled = jz_clk_is_enabled_gating,
1789 +static struct clk jz4740_clock_simple_clks[] = {
1792 + .parent = &jz_clk_ext.clk,
1793 + .ops = &jz_clk_udc_ops,
1797 + .parent = &jz_clk_ext.clk,
1798 + .gate_bit = JZ_CLOCK_GATE_UART0,
1799 + .ops = &jz_clk_simple_ops,
1803 + .parent = &jz_clk_ext.clk,
1804 + .gate_bit = JZ_CLOCK_GATE_UART1,
1805 + .ops = &jz_clk_simple_ops,
1809 + .parent = &jz_clk_high_speed_peripheral.clk,
1810 + .gate_bit = JZ_CLOCK_GATE_UART0,
1811 + .ops = &jz_clk_simple_ops,
1815 + .parent = &jz_clk_high_speed_peripheral.clk,
1816 + .gate_bit = JZ_CLOCK_GATE_IPU,
1817 + .ops = &jz_clk_simple_ops,
1821 + .parent = &jz_clk_ext.clk,
1822 + .gate_bit = JZ_CLOCK_GATE_ADC,
1823 + .ops = &jz_clk_simple_ops,
1827 + .parent = &jz_clk_ext.clk,
1828 + .gate_bit = JZ_CLOCK_GATE_I2C,
1829 + .ops = &jz_clk_simple_ops,
1833 + .parent = &jz_clk_ext.clk,
1834 + .gate_bit = JZ_CLOCK_GATE_AIC,
1835 + .ops = &jz_clk_simple_ops,
1839 +static struct static_clk jz_clk_rtc = {
1842 + .gate_bit = JZ_CLOCK_GATE_RTC,
1843 + .ops = &jz_clk_static_ops,
1848 +int clk_enable(struct clk *clk)
1850 + if (!clk->ops->enable)
1853 + return clk->ops->enable(clk);
1855 +EXPORT_SYMBOL_GPL(clk_enable);
1857 +void clk_disable(struct clk *clk)
1859 + if (clk->ops->disable)
1860 + clk->ops->disable(clk);
1862 +EXPORT_SYMBOL_GPL(clk_disable);
1864 +int clk_is_enabled(struct clk *clk)
1866 + if (clk->ops->is_enabled)
1867 + return clk->ops->is_enabled(clk);
1872 +unsigned long clk_get_rate(struct clk *clk)
1874 + if (clk->ops->get_rate)
1875 + return clk->ops->get_rate(clk);
1877 + return clk_get_rate(clk->parent);
1881 +EXPORT_SYMBOL_GPL(clk_get_rate);
1883 +int clk_set_rate(struct clk *clk, unsigned long rate)
1885 + if (!clk->ops->set_rate)
1887 + return clk->ops->set_rate(clk, rate);
1889 +EXPORT_SYMBOL_GPL(clk_set_rate);
1891 +long clk_round_rate(struct clk *clk, unsigned long rate)
1893 + if (clk->ops->round_rate)
1894 + return clk->ops->round_rate(clk, rate);
1898 +EXPORT_SYMBOL_GPL(clk_round_rate);
1900 +int clk_set_parent(struct clk *clk, struct clk *parent)
1904 + if (!clk->ops->set_parent)
1908 + ret = clk->ops->set_parent(clk, parent);
1911 + jz4740_clock_debugfs_update_parent(clk);
1915 +EXPORT_SYMBOL_GPL(clk_set_parent);
1917 +struct clk *clk_get(struct device *dev, const char *name)
1921 + list_for_each_entry(clk, &jz_clocks, list) {
1922 + if (strcmp(clk->name, name) == 0)
1925 + return ERR_PTR(-ENOENT);
1927 +EXPORT_SYMBOL_GPL(clk_get);
1929 +void clk_put(struct clk *clk)
1932 +EXPORT_SYMBOL_GPL(clk_put);
1935 +static inline void clk_add(struct clk *clk)
1937 + list_add_tail(&clk->list, &jz_clocks);
1939 + jz4740_clock_debugfs_add_clk(clk);
1942 +static void clk_register_clks(void)
1946 + clk_add(&jz_clk_ext.clk);
1947 + clk_add(&jz_clk_pll);
1948 + clk_add(&jz_clk_pll_half);
1949 + clk_add(&jz_clk_cpu.clk);
1950 + clk_add(&jz_clk_high_speed_peripheral.clk);
1951 + clk_add(&jz_clk_low_speed_peripheral.clk);
1952 + clk_add(&jz_clk_ko);
1953 + clk_add(&jz_clk_ld);
1954 + clk_add(&jz_clk_cim_mclk);
1955 + clk_add(&jz_clk_cim_pclk.clk);
1956 + clk_add(&jz_clk_rtc.clk);
1958 + for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
1959 + clk_add(&jz4740_clock_divided_clks[i].clk);
1961 + for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
1962 + clk_add(&jz4740_clock_simple_clks[i]);
1965 +void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
1968 + case JZ4740_WAIT_MODE_IDLE:
1969 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
1971 + case JZ4740_WAIT_MODE_SLEEP:
1972 + jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
1977 +void jz4740_clock_udc_disable_auto_suspend(void)
1979 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
1981 +EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
1983 +void jz4740_clock_udc_enable_auto_suspend(void)
1985 + jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
1987 +EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
1989 +void jz4740_clock_suspend(void)
1991 + jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
1992 + JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
1994 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
1997 +void jz4740_clock_resume(void)
2001 + jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
2004 + pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
2005 + } while (!(pll & JZ_CLOCK_PLL_STABLE));
2007 + jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
2008 + JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
2011 +int jz4740_clock_init(void)
2015 + jz_clock_base = ioremap(CPHYSADDR(JZ4740_CPM_BASE_ADDR), 0x100);
2016 + if (!jz_clock_base)
2019 + spin_lock_init(&jz_clock_lock);
2021 + jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
2022 + jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
2024 + val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
2026 + if (val & JZ_CLOCK_SPI_SRC_PLL)
2027 + jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
2029 + val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
2031 + if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
2032 + jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
2034 + if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
2035 + jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
2037 + jz4740_clock_debugfs_init();
2039 + clk_register_clks();
2043 diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
2044 new file mode 100644
2045 index 0000000..96010a4
2047 +++ b/arch/mips/jz4740/clock.h
2050 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
2051 + * JZ4740 SoC clock support
2053 + * This program is free software; you can redistribute it and/or modify it
2054 + * under the terms of the GNU General Public License as published by the
2055 + * Free Software Foundation; either version 2 of the License, or (at your
2056 + * option) any later version.
2058 + * You should have received a copy of the GNU General Public License along
2059 + * with this program; if not, write to the Free Software Foundation, Inc.,
2060 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2064 +#ifndef __JZ4740_CLOCK_H__
2065 +#define __JZ4740_CLOCK_H__
2067 +struct jz4740_clock_board_data {
2068 + unsigned long ext_rate;
2069 + unsigned long rtc_rate;
2072 +extern struct jz4740_clock_board_data jz4740_clock_bdata;
2074 +int jz4740_clock_init(void);
2075 +void jz4740_clock_suspend(void);
2076 +void jz4740_clock_resume(void);
2081 + unsigned long (*get_rate)(struct clk *clk);
2082 + unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
2083 + int (*set_rate)(struct clk *clk, unsigned long rate);
2084 + int (*enable)(struct clk *clk);
2085 + int (*disable)(struct clk *clk);
2086 + int (*is_enabled)(struct clk *clk);
2088 + int (*set_parent)(struct clk *clk, struct clk *parent);
2094 + struct clk *parent;
2096 + uint32_t gate_bit;
2098 + const struct clk_ops *ops;
2100 + struct list_head list;
2102 +#ifdef CONFIG_DEBUG_FS
2103 + struct dentry *debugfs_entry;
2104 + struct dentry *debugfs_parent_entry;
2109 +#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
2111 +int clk_is_enabled(struct clk *clk);
2113 +#ifdef CONFIG_DEBUG_FS
2114 +void jz4740_clock_debugfs_init(void);
2115 +void jz4740_clock_debugfs_add_clk(struct clk *clk);
2116 +void jz4740_clock_debugfs_update_parent(struct clk *clk);
2118 +static inline void jz4740_clock_debugfs_init(void) {};
2119 +static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
2120 +static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
2124 diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c
2125 new file mode 100644
2126 index 0000000..217ddc8
2128 +++ b/arch/mips/jz4740/dma.c
2131 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
2132 + * JZ4740 SoC DMA support
2134 + * This program is free software; you can redistribute it and/or modify it
2135 + * under the terms of the GNU General Public License as published by the
2136 + * Free Software Foundation; either version 2 of the License, or (at your
2137 + * option) any later version.
2139 + * You should have received a copy of the GNU General Public License along
2140 + * with this program; if not, write to the Free Software Foundation, Inc.,
2141 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2145 +#include <linux/kernel.h>
2146 +#include <linux/module.h>
2147 +#include <linux/spinlock.h>
2148 +#include <linux/interrupt.h>
2150 +#include <linux/dma-mapping.h>
2151 +#include <asm/mach-jz4740/dma.h>
2152 +#include <asm/mach-jz4740/base.h>
2154 +#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
2155 +#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
2156 +#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
2157 +#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
2158 +#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
2159 +#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
2160 +#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
2162 +#define JZ_REG_DMA_CTRL 0x300
2163 +#define JZ_REG_DMA_IRQ 0x304
2164 +#define JZ_REG_DMA_DOORBELL 0x308
2165 +#define JZ_REG_DMA_DOORBELL_SET 0x30C
2167 +#define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31)
2168 +#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
2169 +#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
2170 +#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
2171 +#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
2172 +#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
2173 +#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
2175 +#define JZ_DMA_CMD_SRC_INC BIT(23)
2176 +#define JZ_DMA_CMD_DST_INC BIT(22)
2177 +#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
2178 +#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
2179 +#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
2180 +#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
2181 +#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
2182 +#define JZ_DMA_CMD_DESC_VALID BIT(4)
2183 +#define JZ_DMA_CMD_DESC_VALID_MODE BIT(3)
2184 +#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2)
2185 +#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1)
2186 +#define JZ_DMA_CMD_LINK_ENABLE BIT(0)
2188 +#define JZ_DMA_CMD_FLAGS_OFFSET 22
2189 +#define JZ_DMA_CMD_RDIL_OFFSET 16
2190 +#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
2191 +#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
2192 +#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
2193 +#define JZ_DMA_CMD_MODE_OFFSET 7
2195 +#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
2196 +#define JZ_DMA_CTRL_HALT BIT(3)
2197 +#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
2198 +#define JZ_DMA_CTRL_ENABLE BIT(0)
2201 +static void __iomem *jz4740_dma_base;
2202 +static spinlock_t jz4740_dma_lock;
2204 +static inline uint32_t jz4740_dma_read(size_t reg)
2206 + return readl(jz4740_dma_base + reg);
2209 +static inline void jz4740_dma_write(size_t reg, uint32_t val)
2211 + writel(val, jz4740_dma_base + reg);
2214 +static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
2217 + val2 = jz4740_dma_read(reg);
2220 + jz4740_dma_write(reg, val2);
2223 +struct jz4740_dma_chan {
2228 + enum jz4740_dma_flags flags;
2229 + uint32_t transfer_shift;
2231 + jz4740_dma_complete_callback_t complete_cb;
2236 +#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
2238 +struct jz4740_dma_chan jz4740_dma_channels[] = {
2239 + JZ4740_DMA_CHANNEL(0),
2240 + JZ4740_DMA_CHANNEL(1),
2241 + JZ4740_DMA_CHANNEL(2),
2242 + JZ4740_DMA_CHANNEL(3),
2243 + JZ4740_DMA_CHANNEL(4),
2244 + JZ4740_DMA_CHANNEL(5),
2247 +struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
2250 + struct jz4740_dma_chan *dma = NULL;
2252 + spin_lock(&jz4740_dma_lock);
2254 + for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
2255 + if (!jz4740_dma_channels[i].used) {
2256 + dma = &jz4740_dma_channels[i];
2262 + spin_unlock(&jz4740_dma_lock);
2272 +EXPORT_SYMBOL_GPL(jz4740_dma_request);
2274 +void jz4740_dma_configure(struct jz4740_dma_chan *dma,
2275 + const struct jz4740_dma_config *config)
2280 + switch (config->transfer_size) {
2281 + case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
2282 + dma->transfer_shift = 1;
2284 + case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
2285 + dma->transfer_shift = 2;
2287 + case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
2288 + dma->transfer_shift = 4;
2290 + case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
2291 + dma->transfer_shift = 5;
2294 + dma->transfer_shift = 0;
2298 + cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
2299 + cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
2300 + cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
2301 + cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
2302 + cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
2303 + cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
2305 + ctrl = JZ_DMA_STATUS_CTRL_NO_DESC;
2306 + ctrl |= JZ_DMA_STATUS_CTRL_HALT;
2308 + jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
2309 + jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), ctrl);
2310 + jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
2312 +EXPORT_SYMBOL_GPL(jz4740_dma_configure);
2314 +void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
2316 + jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
2318 +EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
2320 +void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
2322 + jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
2324 +EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
2326 +void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
2328 + count >>= dma->transfer_shift;
2329 + jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
2331 +EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
2333 +void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
2334 + jz4740_dma_complete_callback_t cb)
2336 + dma->complete_cb = cb;
2338 +EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
2340 +void jz4740_dma_free(struct jz4740_dma_chan *dma)
2343 + dma->complete_cb = NULL;
2346 +EXPORT_SYMBOL_GPL(jz4740_dma_free);
2348 +void jz4740_dma_enable(struct jz4740_dma_chan *dma)
2350 + jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
2351 + JZ_DMA_STATUS_CTRL_ENABLE,
2352 + JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_HALT);
2354 + jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
2355 + JZ_DMA_CTRL_ENABLE,
2356 + JZ_DMA_CTRL_ENABLE | JZ_DMA_CTRL_HALT);
2358 +EXPORT_SYMBOL_GPL(jz4740_dma_enable);
2360 +void jz4740_dma_disable(struct jz4740_dma_chan *dma)
2362 + jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
2363 + JZ_DMA_STATUS_CTRL_ENABLE);
2365 +EXPORT_SYMBOL_GPL(jz4740_dma_disable);
2367 +uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
2370 + residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
2371 + return residue << dma->transfer_shift;
2373 +EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
2375 +static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
2379 + status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
2381 + jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
2382 + JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
2384 + if (dma->complete_cb)
2385 + dma->complete_cb(dma, 0, dma->dev);
2388 +static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
2390 + uint32_t irq_status;
2393 + irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
2395 + for (i = 0; i < 6; ++i) {
2396 + if (irq_status & (1 << i))
2397 + jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
2400 + return IRQ_HANDLED;
2404 +static struct jz4740_dma_config dma_test_config = {
2405 + .src_width = JZ4740_DMA_WIDTH_32BIT,
2406 + .dst_width = JZ4740_DMA_WIDTH_32BIT,
2407 + .transfer_size = JZ4740_DMA_TRANSFER_SIZE_4BYTE,
2408 + .request_type = JZ4740_DMA_TYPE_AUTO_REQUEST,
2409 + .flags = JZ4740_DMA_SRC_AUTOINC | JZ4740_DMA_DST_AUTOINC,
2410 + .mode = JZ4740_DMA_MODE_BLOCK,
2413 +static void jz4740_dma_test(void)
2415 + uint32_t *buf1, *buf2;
2416 + dma_addr_t addr1, addr2;
2417 + struct jz4740_dma_chan *dma = jz4740_dma_request(NULL, "dma test");
2420 + printk("STARTING DMA TEST\n");
2422 + buf1 = dma_alloc_coherent(NULL,
2424 + &addr1, GFP_KERNEL);
2425 + buf2 = dma_alloc_coherent(NULL,
2427 + &addr2, GFP_KERNEL);
2429 + for (i = 0; i < 0x400; ++i)
2433 + jz4740_dma_configure(dma, &dma_test_config);
2434 + jz4740_dma_set_src_addr(dma, addr1);
2435 + jz4740_dma_set_dst_addr(dma, addr2);
2436 + jz4740_dma_set_transfer_count(dma, 0x1000);
2438 + jz4740_dma_enable(dma);
2441 + for (i = 0; i < 0x400; ++i) {
2443 + printk("OH MY GOD: %x %x\n", i, buf2[i]);
2446 + printk("DMA TEST DONE\n");
2450 +static int jz4740_dma_init(void)
2454 + jz4740_dma_base = ioremap(CPHYSADDR(JZ4740_DMAC_BASE_ADDR), 0x400);
2456 + if (!jz4740_dma_base)
2459 + spin_lock_init(&jz4740_dma_lock);
2461 + ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
2464 + printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
2468 +arch_initcall(jz4740_dma_init);
2469 diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
2470 new file mode 100644
2471 index 0000000..14d8288
2473 +++ b/arch/mips/jz4740/gpio.c
2476 + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
2477 + * JZ4740 platform GPIO support
2479 + * This program is free software; you can redistribute it and/or modify it
2480 + * under the terms of the GNU General Public License as published by the
2481 + * Free Software Foundation; either version 2 of the License, or (at your
2482 + * option) any later version.
2484 + * You should have received a copy of the GNU General Public License along
2485 + * with this program; if not, write to the Free Software Foundation, Inc.,
2486 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2490 +#include <linux/kernel.h>
2491 +#include <linux/module.h>
2492 +#include <linux/init.h>
2494 +#include <linux/spinlock.h>
2495 +#include <linux/sysdev.h>
2496 +#include <linux/io.h>
2497 +#include <linux/gpio.h>
2498 +#include <linux/delay.h>
2499 +#include <linux/interrupt.h>
2500 +#include <linux/bitops.h>
2502 +#include <linux/debugfs.h>
2503 +#include <linux/seq_file.h>
2505 +#include <asm/mach-jz4740/base.h>
2507 +#define JZ4740_GPIO_BASE_A (32*0)
2508 +#define JZ4740_GPIO_BASE_B (32*1)
2509 +#define JZ4740_GPIO_BASE_C (32*2)
2510 +#define JZ4740_GPIO_BASE_D (32*3)
2512 +#define JZ4740_GPIO_NUM_A 32
2513 +#define JZ4740_GPIO_NUM_B 32
2514 +#define JZ4740_GPIO_NUM_C 31
2515 +#define JZ4740_GPIO_NUM_D 32
2517 +#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
2518 +#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
2519 +#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
2520 +#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
2522 +#define JZ4740_IRQ_GPIO_A(num) (JZ4740_IRQ_GPIO_BASE_A + num)
2523 +#define JZ4740_IRQ_GPIO_B(num) (JZ4740_IRQ_GPIO_BASE_B + num)
2524 +#define JZ4740_IRQ_GPIO_C(num) (JZ4740_IRQ_GPIO_BASE_C + num)
2525 +#define JZ4740_IRQ_GPIO_D(num) (JZ4740_IRQ_GPIO_BASE_D + num)
2527 +#define JZ_REG_GPIO_PIN 0x00
2528 +#define JZ_REG_GPIO_DATA 0x10
2529 +#define JZ_REG_GPIO_DATA_SET 0x14
2530 +#define JZ_REG_GPIO_DATA_CLEAR 0x18
2531 +#define JZ_REG_GPIO_MASK 0x20
2532 +#define JZ_REG_GPIO_MASK_SET 0x24
2533 +#define JZ_REG_GPIO_MASK_CLEAR 0x28
2534 +#define JZ_REG_GPIO_PULL 0x30
2535 +#define JZ_REG_GPIO_PULL_SET 0x34
2536 +#define JZ_REG_GPIO_PULL_CLEAR 0x38
2537 +#define JZ_REG_GPIO_FUNC 0x40
2538 +#define JZ_REG_GPIO_FUNC_SET 0x44
2539 +#define JZ_REG_GPIO_FUNC_CLEAR 0x48
2540 +#define JZ_REG_GPIO_SELECT 0x50
2541 +#define JZ_REG_GPIO_SELECT_SET 0x54
2542 +#define JZ_REG_GPIO_SELECT_CLEAR 0x58
2543 +#define JZ_REG_GPIO_DIRECTION 0x60
2544 +#define JZ_REG_GPIO_DIRECTION_SET 0x64
2545 +#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
2546 +#define JZ_REG_GPIO_TRIGGER 0x70
2547 +#define JZ_REG_GPIO_TRIGGER_SET 0x74
2548 +#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
2549 +#define JZ_REG_GPIO_FLAG 0x80
2550 +#define JZ_REG_GPIO_FLAG_CLEAR 0x14
2553 +#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
2554 +#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
2555 +#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
2557 +struct jz_gpio_chip {
2559 + unsigned int irq_base;
2561 + uint32_t suspend_mask;
2562 + uint32_t edge_trigger_both;
2564 + void __iomem *base;
2568 + struct gpio_chip gpio_chip;
2569 + struct irq_chip irq_chip;
2570 + struct sys_device sysdev;
2574 +static struct jz_gpio_chip jz4740_gpio_chips[];
2576 +static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
2578 + return &jz4740_gpio_chips[gpio >> 5];
2581 +static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
2583 + return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
2586 +static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
2588 + return get_irq_chip_data(irq);
2591 +static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
2593 + writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
2596 +int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
2598 + if (function == JZ_GPIO_FUNC_NONE) {
2599 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
2600 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
2601 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
2603 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
2604 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
2605 + switch (function) {
2606 + case JZ_GPIO_FUNC1:
2607 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
2609 + case JZ_GPIO_FUNC3:
2610 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
2611 + case JZ_GPIO_FUNC2: /* Falltrough */
2612 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
2622 +EXPORT_SYMBOL_GPL(jz_gpio_set_function);
2624 +int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
2629 + for (i = 0; i < num; ++i, ++request) {
2630 + ret = gpio_request(request->gpio, request->name);
2633 + jz_gpio_set_function(request->gpio, request->function);
2639 + for (--request; i > 0; --i, --request) {
2640 + gpio_free(request->gpio);
2641 + jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2646 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
2648 +void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
2652 + for (i = 0; i < num; ++i, ++request) {
2653 + gpio_free(request->gpio);
2654 + jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2658 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
2660 +void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
2664 + for (i = 0; i < num; ++i, ++request) {
2665 + jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2666 + jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
2667 + jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
2670 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
2672 +void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
2676 + for (i = 0; i < num; ++i, ++request)
2677 + jz_gpio_set_function(request->gpio, request->function);
2679 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
2681 +void jz_gpio_enable_pullup(unsigned gpio)
2683 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
2685 +EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
2687 +void jz_gpio_disable_pullup(unsigned gpio)
2689 + jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
2691 +EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
2693 +static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
2695 + return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
2698 +static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
2700 + uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
2702 + writel(BIT(gpio), reg);
2705 +static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
2708 + writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
2709 + jz_gpio_set_value(chip, gpio, value);
2714 +static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
2716 + writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
2721 +int jz_gpio_port_direction_input(int port, uint32_t mask)
2723 + writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
2727 +EXPORT_SYMBOL(jz_gpio_port_direction_input);
2729 +int jz_gpio_port_direction_output(int port, uint32_t mask)
2731 + writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
2735 +EXPORT_SYMBOL(jz_gpio_port_direction_output);
2737 +void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
2739 + writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
2740 + writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
2742 +EXPORT_SYMBOL(jz_gpio_port_set_value);
2744 +uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
2746 + uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
2748 + return value & mask;
2750 +EXPORT_SYMBOL(jz_gpio_port_get_value);
2753 +#define IRQ_TO_GPIO(irq) (irq - JZ4740_IRQ_GPIO(0))
2754 +#define IRQ_TO_BIT(irq) BIT(IRQ_TO_GPIO(irq) & 0x1f)
2756 +#define IRQ_TO_REG(irq, reg) GPIO_TO_REG(IRQ_TO_GPIO(irq), reg)
2758 +static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
2761 + unsigned int gpio_irq;
2762 + unsigned int gpio_bank;
2763 + struct jz_gpio_chip *chip = get_irq_desc_data(desc);
2765 + gpio_bank = JZ4740_IRQ_GPIO0 - irq;
2767 + flag = readl(chip->base + JZ_REG_GPIO_FLAG);
2769 + gpio_irq = ffs(flag) - 1;
2771 + if (chip->edge_trigger_both & BIT(gpio_irq)) {
2772 + uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
2773 + if (value & BIT(gpio_irq)) {
2774 + writel(BIT(gpio_irq),
2775 + chip->base + JZ_REG_GPIO_DIRECTION_CLEAR);
2777 + writel(BIT(gpio_irq),
2778 + chip->base + JZ_REG_GPIO_DIRECTION_SET);
2782 + gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
2784 + generic_handle_irq(gpio_irq);
2787 +static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
2789 + writel(IRQ_TO_BIT(irq), IRQ_TO_REG(irq, reg));
2792 +static void jz_gpio_irq_mask(unsigned int irq)
2794 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
2797 +static void jz_gpio_irq_unmask(unsigned int irq)
2799 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
2803 +/* TODO: Check if function is gpio */
2804 +static unsigned int jz_gpio_irq_startup(unsigned int irq)
2806 + struct irq_desc *desc = irq_to_desc(irq);
2808 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
2810 + desc->status &= ~IRQ_MASKED;
2811 + jz_gpio_irq_unmask(irq);
2816 +static void jz_gpio_irq_shutdown(unsigned int irq)
2818 + struct irq_desc *desc = irq_to_desc(irq);
2820 + jz_gpio_irq_mask(irq);
2821 + desc->status |= IRQ_MASKED;
2823 + /* Set direction to input */
2824 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2825 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
2828 +static void jz_gpio_irq_ack(unsigned int irq)
2830 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
2833 +static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
2835 + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
2836 + struct irq_desc *desc = irq_to_desc(irq);
2838 + jz_gpio_irq_mask(irq);
2840 + if (flow_type == IRQ_TYPE_EDGE_BOTH) {
2841 + uint32_t value = readl(IRQ_TO_REG(irq, JZ_REG_GPIO_PIN));
2842 + if (value & IRQ_TO_BIT(irq))
2843 + flow_type = IRQ_TYPE_EDGE_FALLING;
2845 + flow_type = IRQ_TYPE_EDGE_RISING;
2846 + chip->edge_trigger_both |= IRQ_TO_BIT(irq);
2848 + chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
2851 + switch (flow_type) {
2852 + case IRQ_TYPE_EDGE_RISING:
2853 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
2854 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
2856 + case IRQ_TYPE_EDGE_FALLING:
2857 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2858 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
2860 + case IRQ_TYPE_LEVEL_HIGH:
2861 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
2862 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
2864 + case IRQ_TYPE_LEVEL_LOW:
2865 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2866 + jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
2872 + if (!(desc->status & IRQ_MASKED))
2873 + jz_gpio_irq_unmask(irq);
2878 +static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
2880 + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
2881 + spin_lock(&chip->lock);
2883 + chip->wakeup |= IRQ_TO_BIT(irq);
2885 + chip->wakeup &= ~IRQ_TO_BIT(irq);
2886 + spin_unlock(&chip->lock);
2888 + set_irq_wake(chip->irq, on);
2892 +int gpio_to_irq(unsigned gpio)
2894 + return JZ4740_IRQ_GPIO(0) + gpio;
2896 +EXPORT_SYMBOL_GPL(gpio_to_irq);
2898 +int irq_to_gpio(unsigned gpio)
2900 + return IRQ_TO_GPIO(gpio);
2902 +EXPORT_SYMBOL_GPL(irq_to_gpio);
2905 + * This lock class tells lockdep that GPIO irqs are in a different
2906 + * category than their parents, so it won't report false recursion.
2908 +static struct lock_class_key gpio_lock_class;
2910 +#define JZ4740_GPIO_CHIP(_bank) { \
2911 + .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
2913 + .label = "Bank " # _bank, \
2914 + .owner = THIS_MODULE, \
2915 + .set = jz_gpio_set_value, \
2916 + .get = jz_gpio_get_value, \
2917 + .direction_output = jz_gpio_direction_output, \
2918 + .direction_input = jz_gpio_direction_input, \
2919 + .base = JZ4740_GPIO_BASE_ ## _bank, \
2920 + .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
2923 + .name = "GPIO Bank " # _bank, \
2924 + .mask = jz_gpio_irq_mask, \
2925 + .unmask = jz_gpio_irq_unmask, \
2926 + .ack = jz_gpio_irq_ack, \
2927 + .startup = jz_gpio_irq_startup, \
2928 + .shutdown = jz_gpio_irq_shutdown, \
2929 + .set_type = jz_gpio_irq_set_type, \
2930 + .set_wake = jz_gpio_irq_set_wake, \
2934 +static struct jz_gpio_chip jz4740_gpio_chips[] = {
2935 + JZ4740_GPIO_CHIP(A),
2936 + JZ4740_GPIO_CHIP(B),
2937 + JZ4740_GPIO_CHIP(C),
2938 + JZ4740_GPIO_CHIP(D),
2941 +static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
2943 + return container_of(dev, struct jz_gpio_chip, sysdev);
2946 +static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
2948 + struct jz_gpio_chip *chip = sysdev_to_chip(dev);
2950 + chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
2951 + writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
2952 + writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
2957 +static int jz4740_gpio_resume(struct sys_device *dev)
2959 + struct jz_gpio_chip *chip = sysdev_to_chip(dev);
2960 + uint32_t mask = chip->suspend_mask;
2962 + writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
2963 + writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
2968 +static struct sysdev_class jz4740_gpio_sysdev_class = {
2970 + .suspend = jz4740_gpio_suspend,
2971 + .resume = jz4740_gpio_resume,
2974 +static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
2978 + chip->sysdev.id = id;
2979 + chip->sysdev.cls = &jz4740_gpio_sysdev_class;
2980 + ret = sysdev_register(&chip->sysdev);
2985 + spin_lock_init(&chip->lock);
2987 + chip->base = ioremap(CPHYSADDR(JZ4740_GPIO_BASE_ADDR) + (id * 0x100), 0x100);
2989 + gpiochip_add(&chip->gpio_chip);
2991 + chip->irq = JZ4740_IRQ_INTC_GPIO(id);
2992 + set_irq_data(chip->irq, chip);
2993 + set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
2995 + for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
2996 + lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
2997 + set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
2998 + set_irq_chip_data(irq, chip);
3004 +int __init jz_gpiolib_init(void)
3009 + ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
3013 + for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) {
3014 + jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
3017 + printk(KERN_INFO "JZ4740 GPIO initalized\n");
3022 +#ifdef CONFIG_DEBUG_FS
3024 +static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
3025 + const char *name, unsigned int reg)
3027 + seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
3031 +static int gpio_regs_show(struct seq_file *s, void *unused)
3033 + struct jz_gpio_chip *chip = jz4740_gpio_chips;
3036 + for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
3037 + seq_printf(s, "GPIO %d: \n", i);
3038 + gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
3039 + gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
3040 + gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
3041 + gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
3042 + gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
3043 + gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
3044 + gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
3045 + gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
3046 + gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
3052 +static int gpio_regs_open(struct inode *inode, struct file *file)
3054 + return single_open(file, gpio_regs_show, NULL);
3057 +static const struct file_operations gpio_regs_operations = {
3058 + .open = gpio_regs_open,
3060 + .llseek = seq_lseek,
3061 + .release = single_release,
3064 +static int __init gpio_debugfs_init(void)
3066 + (void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
3067 + NULL, NULL, &gpio_regs_operations);
3070 +subsys_initcall(gpio_debugfs_init);
3073 diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
3074 new file mode 100644
3075 index 0000000..a8c76af
3077 +++ b/arch/mips/jz4740/irq.c
3080 + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3081 + * JZ4740 platform IRQ support
3083 + * This program is free software; you can redistribute it and/or modify it
3084 + * under the terms of the GNU General Public License as published by the
3085 + * Free Software Foundation; either version 2 of the License, or (at your
3086 + * option) any later version.
3088 + * You should have received a copy of the GNU General Public License along
3089 + * with this program; if not, write to the Free Software Foundation, Inc.,
3090 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3094 +#include <linux/errno.h>
3095 +#include <linux/init.h>
3096 +#include <linux/types.h>
3097 +#include <linux/interrupt.h>
3098 +#include <linux/ioport.h>
3099 +#include <linux/timex.h>
3100 +#include <linux/slab.h>
3101 +#include <linux/delay.h>
3103 +#include <linux/debugfs.h>
3104 +#include <linux/seq_file.h>
3106 +#include <asm/io.h>
3107 +#include <asm/mipsregs.h>
3108 +#include <asm/irq_cpu.h>
3110 +#include <asm/mach-jz4740/base.h>
3112 +static void __iomem *jz_intc_base;
3113 +static uint32_t jz_intc_wakeup;
3114 +static uint32_t jz_intc_saved;
3116 +#define JZ_REG_INTC_STATUS 0x00
3117 +#define JZ_REG_INTC_MASK 0x04
3118 +#define JZ_REG_INTC_SET_MASK 0x08
3119 +#define JZ_REG_INTC_CLEAR_MASK 0x0c
3120 +#define JZ_REG_INTC_PENDING 0x10
3122 +#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
3124 +static void intc_irq_unmask(unsigned int irq)
3126 + writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3129 +static void intc_irq_mask(unsigned int irq)
3131 + writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
3134 +static void intc_irq_ack(unsigned int irq)
3136 + writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_PENDING);
3139 +static int intc_irq_set_wake(unsigned int irq, unsigned int on)
3142 + jz_intc_wakeup |= IRQ_BIT(irq);
3144 + jz_intc_wakeup &= ~IRQ_BIT(irq);
3149 +static struct irq_chip intc_irq_type = {
3151 + .mask = intc_irq_mask,
3152 + .unmask = intc_irq_unmask,
3153 + .ack = intc_irq_ack,
3154 + .set_wake = intc_irq_set_wake,
3157 +static irqreturn_t jz4740_cascade(int irq, void *data)
3162 + irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
3163 + intc_irq = ffs(irq_reg);
3165 + generic_handle_irq(intc_irq - 1 + JZ4740_IRQ_BASE);
3167 + return IRQ_HANDLED;
3170 +static struct irqaction jz4740_cascade_action = {
3171 + .handler = jz4740_cascade,
3172 + .name = "JZ4740 cascade interrupt",
3173 + .flags = IRQF_DISABLED,
3176 +void __init arch_init_irq(void)
3179 + mips_cpu_irq_init();
3181 + jz_intc_base = ioremap(CPHYSADDR(JZ4740_INTC_BASE_ADDR), 0x14);
3183 + for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
3185 + set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
3188 + setup_irq(2, &jz4740_cascade_action);
3191 +asmlinkage void plat_irq_dispatch(void)
3193 + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
3194 + if (pending & STATUSF_IP2)
3196 + else if (pending & STATUSF_IP3)
3199 + spurious_interrupt();
3202 +void jz4740_intc_suspend(void)
3204 + jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
3205 + writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
3206 + writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3209 +void jz4740_intc_resume(void)
3211 + writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3212 + writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
3215 +#ifdef CONFIG_DEBUG_FS
3217 +static inline void intc_seq_reg(struct seq_file *s, const char *name,
3220 + seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
3223 +static int intc_regs_show(struct seq_file *s, void *unused)
3225 + intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
3226 + intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
3227 + intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
3232 +static int intc_regs_open(struct inode *inode, struct file *file)
3234 + return single_open(file, intc_regs_show, NULL);
3237 +static const struct file_operations intc_regs_operations = {
3238 + .open = intc_regs_open,
3240 + .llseek = seq_lseek,
3241 + .release = single_release,
3244 +static int __init intc_debugfs_init(void)
3246 + (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
3247 + NULL, NULL, &intc_regs_operations);
3250 +subsys_initcall(intc_debugfs_init);
3253 diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h
3254 new file mode 100644
3255 index 0000000..dadbd5f
3257 +++ b/arch/mips/jz4740/irq.h
3260 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3262 + * This program is free software; you can redistribute it and/or modify it
3263 + * under the terms of the GNU General Public License as published by the
3264 + * Free Software Foundation; either version 2 of the License, or (at your
3265 + * option) any later version.
3267 + * You should have received a copy of the GNU General Public License along
3268 + * with this program; if not, write to the Free Software Foundation, Inc.,
3269 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3273 +#ifndef __MIPS_JZ4740_IRQ_H__
3274 +#define __MIPS_JZ4740_IRQ_H__
3276 +extern void jz4740_intc_suspend(void);
3277 +extern void jz4740_intc_resume(void);
3280 diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
3281 new file mode 100644
3282 index 0000000..6bb0778
3284 +++ b/arch/mips/jz4740/platform.c
3287 + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3288 + * JZ4740 platform devices
3290 + * This program is free software; you can redistribute it and/or modify it
3291 + * under the terms of the GNU General Public License as published by the
3292 + * Free Software Foundation; either version 2 of the License, or (at your
3293 + * option) any later version.
3295 + * You should have received a copy of the GNU General Public License along
3296 + * with this program; if not, write to the Free Software Foundation, Inc.,
3297 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3301 +#include <linux/device.h>
3302 +#include <linux/platform_device.h>
3303 +#include <linux/kernel.h>
3304 +#include <linux/init.h>
3305 +#include <linux/resource.h>
3307 +#include <asm/mach-jz4740/platform.h>
3308 +#include <asm/mach-jz4740/base.h>
3309 +#include <asm/mach-jz4740/irq.h>
3311 +/* OHCI (USB full speed host controller) */
3312 +static struct resource jz4740_usb_ohci_resources[] = {
3314 + .start = CPHYSADDR(JZ4740_UHC_BASE_ADDR),
3315 + .end = CPHYSADDR(JZ4740_UHC_BASE_ADDR) + 0x10000 - 1,
3316 + .flags = IORESOURCE_MEM,
3319 + .start = JZ4740_IRQ_UHC,
3320 + .end = JZ4740_IRQ_UHC,
3321 + .flags = IORESOURCE_IRQ,
3325 +/* The dmamask must be set for OHCI to work */
3326 +static u64 ohci_dmamask = ~(u32)0;
3328 +struct platform_device jz4740_usb_ohci_device = {
3329 + .name = "jz4740-ohci",
3332 + .dma_mask = &ohci_dmamask,
3333 + .coherent_dma_mask = 0xffffffff,
3335 + .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources),
3336 + .resource = jz4740_usb_ohci_resources,
3339 +/* UDC (USB gadget controller) */
3340 +static struct resource jz4740_usb_gdt_resources[] = {
3342 + .start = CPHYSADDR(JZ4740_UDC_BASE_ADDR),
3343 + .end = CPHYSADDR(JZ4740_UDC_BASE_ADDR) + 0x10000 - 1,
3344 + .flags = IORESOURCE_MEM,
3347 + .start = JZ4740_IRQ_UDC,
3348 + .end = JZ4740_IRQ_UDC,
3349 + .flags = IORESOURCE_IRQ,
3353 +static u64 jz4740_udc_dmamask = ~(u32)0;
3355 +struct platform_device jz4740_usb_gdt_device = {
3359 + .dma_mask = &jz4740_udc_dmamask,
3360 + .coherent_dma_mask = 0xffffffff,
3362 + .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources),
3363 + .resource = jz4740_usb_gdt_resources,
3366 +/** MMC/SD controller **/
3367 +static struct resource jz4740_mmc_resources[] = {
3369 + .start = CPHYSADDR(JZ4740_MSC_BASE_ADDR),
3370 + .end = CPHYSADDR(JZ4740_MSC_BASE_ADDR) + 0x10000 - 1,
3371 + .flags = IORESOURCE_MEM,
3374 + .start = JZ4740_IRQ_MSC,
3375 + .end = JZ4740_IRQ_MSC,
3376 + .flags = IORESOURCE_IRQ,
3380 +static u64 jz4740_mmc_dmamask = ~(u32)0;
3382 +struct platform_device jz4740_mmc_device = {
3383 + .name = "jz4740-mmc",
3386 + .dma_mask = &jz4740_mmc_dmamask,
3387 + .coherent_dma_mask = 0xffffffff,
3389 + .num_resources = ARRAY_SIZE(jz4740_mmc_resources),
3390 + .resource = jz4740_mmc_resources,
3393 +static struct resource jz4740_rtc_resources[] = {
3395 + .start = CPHYSADDR(JZ4740_RTC_BASE_ADDR),
3396 + .end = CPHYSADDR(JZ4740_RTC_BASE_ADDR) + 0x38 - 1,
3397 + .flags = IORESOURCE_MEM,
3400 + .start = JZ4740_IRQ_RTC,
3401 + .end = JZ4740_IRQ_RTC,
3402 + .flags = IORESOURCE_IRQ,
3406 +struct platform_device jz4740_rtc_device = {
3407 + .name = "jz4740-rtc",
3409 + .num_resources = ARRAY_SIZE(jz4740_rtc_resources),
3410 + .resource = jz4740_rtc_resources,
3413 +/** I2C controller **/
3414 +static struct resource jz4740_i2c_resources[] = {
3416 + .start = CPHYSADDR(JZ4740_I2C_BASE_ADDR),
3417 + .end = CPHYSADDR(JZ4740_I2C_BASE_ADDR) + 0x10000 - 1,
3418 + .flags = IORESOURCE_MEM,
3421 + .start = JZ4740_IRQ_I2C,
3422 + .end = JZ4740_IRQ_I2C,
3423 + .flags = IORESOURCE_IRQ,
3427 +static u64 jz4740_i2c_dmamask = ~(u32)0;
3429 +struct platform_device jz4740_i2c_device = {
3433 + .dma_mask = &jz4740_i2c_dmamask,
3434 + .coherent_dma_mask = 0xffffffff,
3436 + .num_resources = ARRAY_SIZE(jz4740_i2c_resources),
3437 + .resource = jz4740_i2c_resources,
3440 +static struct resource jz4740_nand_resources[] = {
3442 + .start = CPHYSADDR(JZ4740_EMC_BASE_ADDR),
3443 + .end = CPHYSADDR(JZ4740_EMC_BASE_ADDR) + 0x10000 - 1,
3444 + .flags = IORESOURCE_MEM,
3448 +struct platform_device jz4740_nand_device = {
3449 + .name = "jz4740-nand",
3450 + .num_resources = ARRAY_SIZE(jz4740_nand_resources),
3451 + .resource = jz4740_nand_resources,
3454 +static struct resource jz4740_framebuffer_resources[] = {
3456 + .start = CPHYSADDR(JZ4740_LCD_BASE_ADDR),
3457 + .end = CPHYSADDR(JZ4740_LCD_BASE_ADDR) + 0x10000 - 1,
3458 + .flags = IORESOURCE_MEM,
3462 +static u64 jz4740_fb_dmamask = ~(u32)0;
3464 +struct platform_device jz4740_framebuffer_device = {
3465 + .name = "jz4740-fb",
3467 + .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
3468 + .resource = jz4740_framebuffer_resources,
3470 + .dma_mask = &jz4740_fb_dmamask,
3471 + .coherent_dma_mask = 0xffffffff,
3475 +static struct resource jz4740_i2s_resources[] = {
3477 + .start = CPHYSADDR(JZ4740_AIC_BASE_ADDR),
3478 + .end = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x38 - 1,
3479 + .flags = IORESOURCE_MEM,
3483 +struct platform_device jz4740_i2s_device = {
3484 + .name = "jz4740-i2s",
3486 + .num_resources = ARRAY_SIZE(jz4740_i2s_resources),
3487 + .resource = jz4740_i2s_resources,
3490 +static struct resource jz4740_codec_resources[] = {
3492 + .start = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x80,
3493 + .end = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x88 - 1,
3494 + .flags = IORESOURCE_MEM,
3498 +struct platform_device jz4740_codec_device = {
3499 + .name = "jz4740-codec",
3501 + .num_resources = ARRAY_SIZE(jz4740_codec_resources),
3502 + .resource = jz4740_codec_resources,
3505 +static struct resource jz4740_adc_resources[] = {
3507 + .start = CPHYSADDR(JZ4740_SADC_BASE_ADDR),
3508 + .end = CPHYSADDR(JZ4740_SADC_BASE_ADDR) + 0x30,
3509 + .flags = IORESOURCE_MEM,
3512 + .start = JZ4740_IRQ_SADC,
3513 + .end = JZ4740_IRQ_SADC,
3514 + .flags = IORESOURCE_IRQ,
3518 +struct platform_device jz4740_adc_device = {
3519 + .name = "jz4740-adc",
3521 + .num_resources = ARRAY_SIZE(jz4740_adc_resources),
3522 + .resource = jz4740_adc_resources,
3525 +struct platform_device jz4740_battery_device = {
3526 + .name = "jz4740-battery",
3529 + .parent = &jz4740_adc_device.dev
3532 diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
3533 new file mode 100644
3534 index 0000000..4ca3156
3536 +++ b/arch/mips/jz4740/pm.c
3539 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3540 + * JZ4740 SoC power management support
3542 + * This program is free software; you can redistribute it and/or modify it
3543 + * under the terms of the GNU General Public License as published by the
3544 + * Free Software Foundation; either version 2 of the License, or (at your
3545 + * option) any later version.
3547 + * You should have received a copy of the GNU General Public License along
3548 + * with this program; if not, write to the Free Software Foundation, Inc.,
3549 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3553 +#include <linux/init.h>
3554 +#include <linux/pm.h>
3555 +#include <linux/delay.h>
3556 +#include <linux/suspend.h>
3558 +#include <asm/mach-jz4740/clock.h>
3563 +static int jz_pm_enter(suspend_state_t state)
3565 + jz4740_intc_suspend();
3566 + jz4740_clock_suspend();
3568 + jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
3570 + __asm__(".set\tmips3\n\t"
3574 + jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
3576 + jz4740_clock_resume();
3577 + jz4740_intc_resume();
3582 +static struct platform_suspend_ops jz_pm_ops = {
3583 + .valid = suspend_valid_only_mem,
3584 + .enter = jz_pm_enter,
3588 + * Initialize power interface
3590 +int __init jz_pm_init(void)
3592 + suspend_set_ops(&jz_pm_ops);
3596 +late_initcall(jz_pm_init);
3597 diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
3598 new file mode 100644
3599 index 0000000..4f99ea3
3601 +++ b/arch/mips/jz4740/prom.c
3604 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3605 + * JZ4740 SoC prom code
3607 + * This program is free software; you can redistribute it and/or modify it
3608 + * under the terms of the GNU General Public License as published by the
3609 + * Free Software Foundation; either version 2 of the License, or (at your
3610 + * option) any later version.
3612 + * You should have received a copy of the GNU General Public License along
3613 + * with this program; if not, write to the Free Software Foundation, Inc.,
3614 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3619 +#include <linux/module.h>
3620 +#include <linux/kernel.h>
3621 +#include <linux/init.h>
3622 +#include <linux/string.h>
3624 +#include <linux/serial_reg.h>
3626 +#include <asm/bootinfo.h>
3627 +#include <asm/mach-jz4740/base.h>
3629 +void jz4740_init_cmdline(int argc, char *argv[])
3631 + unsigned int count = COMMAND_LINE_SIZE - 1;
3633 + char *dst = &(arcs_cmdline[0]);
3636 + for (i = 1; i < argc && count; ++i) {
3638 + while (*src && count) {
3650 +void __init prom_init(void)
3652 + jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
3653 + mips_machtype = MACH_INGENIC_JZ4740;
3656 +void __init prom_free_prom_memory(void)
3660 +#define UART_REG(offset) ((void __iomem*)(JZ4740_UART0_BASE_ADDR + (offset << 2)))
3662 +void prom_putchar(char c)
3667 + lsr = readb(UART_REG(UART_LSR));
3668 + } while ((lsr & UART_LSR_TEMT) == 0);
3670 + writeb(c, UART_REG(UART_TX));
3672 diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
3673 new file mode 100644
3674 index 0000000..0ff8c1d
3676 +++ b/arch/mips/jz4740/pwm.c
3679 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3680 + * JZ4740 platform PWM support
3682 + * This program is free software; you can redistribute it and/or modify it
3683 + * under the terms of the GNU General Public License as published by the
3684 + * Free Software Foundation; either version 2 of the License, or (at your
3685 + * option) any later version.
3687 + * You should have received a copy of the GNU General Public License along
3688 + * with this program; if not, write to the Free Software Foundation, Inc.,
3689 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3694 +#include <linux/kernel.h>
3696 +#include <linux/clk.h>
3697 +#include <linux/err.h>
3698 +#include <linux/pwm.h>
3699 +#include <linux/gpio.h>
3701 +#include <asm/mach-jz4740/gpio.h>
3704 +static struct clk *jz4740_pwm_clk;
3706 +DEFINE_MUTEX(jz4740_pwm_mutex);
3708 +struct pwm_device {
3710 + unsigned int gpio;
3714 +static struct pwm_device jz4740_pwm_list[] = {
3715 + { 2, JZ_GPIO_PWM2, false },
3716 + { 3, JZ_GPIO_PWM3, false },
3717 + { 4, JZ_GPIO_PWM4, false },
3718 + { 5, JZ_GPIO_PWM5, false },
3719 + { 6, JZ_GPIO_PWM6, false },
3720 + { 7, JZ_GPIO_PWM7, false },
3723 +struct pwm_device *pwm_request(int id, const char *label)
3726 + struct pwm_device *pwm;
3728 + if (!jz4740_pwm_clk) {
3729 + jz4740_pwm_clk = clk_get(NULL, "pclk");
3731 + if (IS_ERR(jz4740_pwm_clk))
3732 + return ERR_PTR(PTR_ERR(jz4740_pwm_clk));
3735 + if (id < 2 || id > 7) {
3736 + return ERR_PTR(-ENOENT);
3739 + mutex_lock(&jz4740_pwm_mutex);
3741 + pwm = &jz4740_pwm_list[id - 2];
3747 + mutex_unlock(&jz4740_pwm_mutex);
3750 + return ERR_PTR(ret);
3753 + ret = gpio_request(pwm->gpio, label);
3756 + printk("Failed to request pwm gpio: %d\n", ret);
3757 + pwm->used = false;
3758 + return ERR_PTR(ret);
3761 + jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
3763 + jz4740_timer_start(id);
3768 +void pwm_free(struct pwm_device *pwm)
3771 + jz4740_timer_set_ctrl(pwm->id, 0);
3773 + jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
3774 + gpio_free(pwm->gpio);
3776 + jz4740_timer_stop(pwm->id);
3778 + pwm->used = false;
3782 +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
3784 + unsigned long long tmp;
3785 + unsigned long period, duty;
3786 + unsigned int prescaler = 0;
3787 + unsigned int id = pwm->id;
3791 + if (duty_ns < 0 || duty_ns > period_ns)
3794 + tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
3796 + do_div(tmp, 1000000000);
3800 + while (period > 0xffff && prescaler < 6) {
3805 + if (prescaler == 6)
3809 + tmp = (unsigned long long)period * duty_ns;
3810 + do_div(tmp, period_ns);
3813 + if (duty >= period)
3814 + duty = period - 1;
3816 + is_enabled = jz4740_timer_is_enabled(id);
3817 + jz4740_timer_disable(id);
3819 + jz4740_timer_set_count(id, 0);
3820 + jz4740_timer_set_duty(id, duty);
3821 + jz4740_timer_set_period(id, period);
3823 + ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_PWM_ENABLE |
3824 + JZ_TIMER_CTRL_SRC_PCLK;
3826 + jz4740_timer_set_ctrl(id, ctrl);
3829 + jz4740_timer_enable(id);
3834 +int pwm_enable(struct pwm_device *pwm)
3836 + jz4740_timer_enable(pwm->id);
3841 +void pwm_disable(struct pwm_device *pwm)
3843 + jz4740_timer_disable(pwm->id);
3845 diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
3846 new file mode 100644
3847 index 0000000..448a7da
3849 +++ b/arch/mips/jz4740/reset.c
3852 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3854 + * This program is free software; you can redistribute it and/or modify it
3855 + * under the terms of the GNU General Public License as published by the
3856 + * Free Software Foundation; either version 2 of the License, or (at your
3857 + * option) any later version.
3859 + * You should have received a copy of the GNU General Public License along
3860 + * with this program; if not, write to the Free Software Foundation, Inc.,
3861 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3865 +#include <linux/io.h>
3866 +#include <linux/kernel.h>
3867 +#include <linux/pm.h>
3869 +#include <linux/delay.h>
3871 +#include <asm/reboot.h>
3873 +#include <asm/mach-jz4740/base.h>
3874 +#include <asm/mach-jz4740/timer.h>
3876 +static void jz4740_halt(void)
3879 + __asm__(".set push;\n"
3887 +#define JZ_REG_WDT_DATA 0x00
3888 +#define JZ_REG_WDT_COUNTER_ENABLE 0x04
3889 +#define JZ_REG_WDT_COUNTER 0x08
3890 +#define JZ_REG_WDT_CTRL 0x0c
3892 +static void jz4740_restart(char *command)
3894 + void __iomem *wdt_base = ioremap(CPHYSADDR(JZ4740_WDT_BASE_ADDR), 0x0f);
3896 + jz4740_timer_enable_watchdog();
3898 + writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
3900 + writew(0, wdt_base + JZ_REG_WDT_COUNTER);
3901 + writew(0, wdt_base + JZ_REG_WDT_DATA);
3902 + writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL);
3904 + writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
3908 +#define JZ_REG_RTC_CTRL 0x00
3909 +#define JZ_REG_RTC_HIBERNATE 0x20
3911 +#define JZ_RTC_CTRL_WRDY BIT(7)
3913 +static void jz4740_power_off(void)
3915 + void __iomem *rtc_base = ioremap(CPHYSADDR(JZ4740_RTC_BASE_ADDR), 0x24);
3919 + ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
3920 + } while (!(ctrl & JZ_RTC_CTRL_WRDY));
3922 + writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
3926 +void jz4740_reset_init(void)
3928 + _machine_restart = jz4740_restart;
3929 + _machine_halt = jz4740_halt;
3930 + pm_power_off = jz4740_power_off;
3932 diff --git a/arch/mips/jz4740/reset.h b/arch/mips/jz4740/reset.h
3933 new file mode 100644
3934 index 0000000..c57a829
3936 +++ b/arch/mips/jz4740/reset.h
3938 +#ifndef __MIPS_JZ4740_RESET_H__
3939 +#define __MIPS_JZ4740_RESET_H__
3941 +extern void jz4740_reset_init(void);
3945 diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
3946 new file mode 100644
3947 index 0000000..a6628f4
3949 +++ b/arch/mips/jz4740/setup.c
3952 + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3953 + * JZ4740 setup code
3955 + * This program is free software; you can redistribute it and/or modify it
3956 + * under the terms of the GNU General Public License as published by the
3957 + * Free Software Foundation; either version 2 of the License, or (at your
3958 + * option) any later version.
3960 + * You should have received a copy of the GNU General Public License along
3961 + * with this program; if not, write to the Free Software Foundation, Inc.,
3962 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3967 +#include <linux/init.h>
3968 +#include <linux/kernel.h>
3969 +#include <linux/serial.h>
3970 +#include <linux/serial_core.h>
3971 +#include <linux/serial_8250.h>
3973 +#include <asm/mach-jz4740/base.h>
3974 +#include <asm/mach-jz4740/clock.h>
3975 +#include <asm/mach-jz4740/serial.h>
3980 +static void __init jz4740_serial_setup(void)
3982 +#ifdef CONFIG_SERIAL_8250
3983 + struct uart_port s;
3984 + memset(&s, 0, sizeof(s));
3985 + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
3986 + s.iotype = SERIAL_IO_MEM;
3988 + s.uartclk = jz4740_clock_bdata.ext_rate;
3991 + s.membase = (u8 *)JZ4740_UART0_BASE_ADDR;
3992 + s.irq = JZ4740_IRQ_UART0;
3993 + if (early_serial_setup(&s) != 0) {
3994 + printk(KERN_ERR "Serial ttyS0 setup failed!\n");
3998 + s.membase = (u8 *)JZ4740_UART1_BASE_ADDR;
3999 + s.irq = JZ4740_IRQ_UART1;
4000 + if (early_serial_setup(&s) != 0) {
4001 + printk(KERN_ERR "Serial ttyS1 setup failed!\n");
4005 +void __init plat_mem_setup(void)
4007 + jz4740_reset_init();
4008 + jz4740_serial_setup();
4011 +const char *get_system_type(void)
4015 diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
4016 new file mode 100644
4017 index 0000000..7721ba7
4019 +++ b/arch/mips/jz4740/time.c
4022 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4023 + * JZ4740 platform time support
4025 + * This program is free software; you can redistribute it and/or modify it
4026 + * under the terms of the GNU General Public License as published by the
4027 + * Free Software Foundation; either version 2 of the License, or (at your
4028 + * option) any later version.
4030 + * You should have received a copy of the GNU General Public License along
4031 + * with this program; if not, write to the Free Software Foundation, Inc.,
4032 + * 675 Mass Ave, Cambridge, MA 02139, USA.
4036 +#include <linux/interrupt.h>
4037 +#include <linux/kernel.h>
4038 +#include <linux/time.h>
4040 +#include <linux/clockchips.h>
4042 +#include <asm/mach-jz4740/irq.h>
4043 +#include <asm/time.h>
4048 +#define TIMER_CLOCKEVENT 0
4049 +#define TIMER_CLOCKSOURCE 1
4051 +static uint16_t jz4740_jiffies_per_tick;
4053 +static cycle_t jz4740_clocksource_read(struct clocksource *cs)
4055 + return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
4058 +static struct clocksource jz4740_clocksource = {
4059 + .name = "jz4740-timer",
4061 + .read = jz4740_clocksource_read,
4062 + .mask = CLOCKSOURCE_MASK(16),
4063 + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
4066 +static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
4068 + struct clock_event_device *cd = devid;
4070 + jz4740_timer_ack_full(TIMER_CLOCKEVENT);
4072 + if (cd->mode != CLOCK_EVT_MODE_PERIODIC)
4073 + jz4740_timer_disable(TIMER_CLOCKEVENT);
4075 + cd->event_handler(cd);
4077 + return IRQ_HANDLED;
4080 +static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
4081 + struct clock_event_device *cd)
4084 + case CLOCK_EVT_MODE_PERIODIC:
4085 + jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
4086 + jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
4087 + case CLOCK_EVT_MODE_RESUME:
4088 + jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
4089 + jz4740_timer_enable(TIMER_CLOCKEVENT);
4091 + case CLOCK_EVT_MODE_ONESHOT:
4092 + case CLOCK_EVT_MODE_SHUTDOWN:
4093 + jz4740_timer_disable(TIMER_CLOCKEVENT);
4100 +static int jz4740_clockevent_set_next(unsigned long evt,
4101 + struct clock_event_device *cd)
4103 + jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
4104 + jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
4105 + jz4740_timer_enable(TIMER_CLOCKEVENT);
4110 +static struct clock_event_device jz4740_clockevent = {
4111 + .name = "jz4740-timer",
4112 + .features = CLOCK_EVT_FEAT_PERIODIC,
4113 + .set_next_event = jz4740_clockevent_set_next,
4114 + .set_mode = jz4740_clockevent_set_mode,
4116 + .irq = JZ4740_IRQ_TCU0,
4119 +static struct irqaction timer_irqaction = {
4120 + .handler = jz4740_clockevent_irq,
4121 + .flags = IRQF_PERCPU | IRQF_TIMER | IRQF_DISABLED,
4122 + .name = "jz4740-timerirq",
4123 + .dev_id = &jz4740_clockevent,
4126 +void __init plat_time_init(void)
4129 + uint32_t clk_rate;
4132 + jz4740_timer_init();
4134 + clk_rate = jz4740_clock_bdata.ext_rate >> 4;
4135 + jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
4137 + clockevent_set_clock(&jz4740_clockevent, clk_rate);
4138 + jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
4139 + jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
4140 + jz4740_clockevent.cpumask = cpumask_of(0);
4142 + clockevents_register_device(&jz4740_clockevent);
4144 + clocksource_set_clock(&jz4740_clocksource, clk_rate);
4145 + ret = clocksource_register(&jz4740_clocksource);
4148 + printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
4150 + setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
4152 + ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
4154 + jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
4155 + jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
4157 + jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
4158 + jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
4160 + jz4740_timer_irq_full_disable(TIMER_CLOCKSOURCE);
4161 + jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
4163 + jz4740_timer_enable(TIMER_CLOCKEVENT);
4164 + jz4740_timer_enable(TIMER_CLOCKSOURCE);
4166 diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
4167 new file mode 100644
4168 index 0000000..208f14c
4170 +++ b/arch/mips/jz4740/timer.c
4173 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4174 + * JZ4740 platform timer support
4176 + * This program is free software; you can redistribute it and/or modify it
4177 + * under the terms of the GNU General Public License as published by the
4178 + * Free Software Foundation; either version 2 of the License, or (at your
4179 + * option) any later version.
4181 + * You should have received a copy of the GNU General Public License along
4182 + * with this program; if not, write to the Free Software Foundation, Inc.,
4183 + * 675 Mass Ave, Cambridge, MA 02139, USA.
4187 +#include <linux/io.h>
4188 +#include <linux/kernel.h>
4189 +#include <linux/module.h>
4193 +#include <asm/mach-jz4740/base.h>
4195 +void __iomem *jz4740_timer_base;
4197 +void jz4740_timer_enable_watchdog(void)
4199 + writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
4202 +void jz4740_timer_disable_watchdog(void)
4204 + writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4207 +void __init jz4740_timer_init(void)
4209 + jz4740_timer_base = ioremap(CPHYSADDR(JZ4740_TCU_BASE_ADDR), 0x100);
4211 + if (!jz4740_timer_base)
4212 + panic("Failed to ioremap timer registers");
4214 + /* Disable all timers except those used as system timers */
4215 + writel(0x100fc, jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4217 diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
4218 new file mode 100644
4219 index 0000000..77d748c
4221 +++ b/arch/mips/jz4740/timer.h
4224 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4225 + * JZ4740 platform timer support
4227 + * This program is free software; you can redistribute it and/or modify it
4228 + * under the terms of the GNU General Public License as published by the
4229 + * Free Software Foundation; either version 2 of the License, or (at your
4230 + * option) any later version.
4232 + * You should have received a copy of the GNU General Public License along
4233 + * with this program; if not, write to the Free Software Foundation, Inc.,
4234 + * 675 Mass Ave, Cambridge, MA 02139, USA.
4238 +#ifndef __MIPS_JZ4740_TIMER_H__
4239 +#define __MIPS_JZ4740_TIMER_H__
4241 +#include <linux/module.h>
4242 +#include <linux/io.h>
4244 +#define JZ_REG_TIMER_STOP 0x1C
4245 +#define JZ_REG_TIMER_STOP_SET 0x2C
4246 +#define JZ_REG_TIMER_STOP_CLEAR 0x3C
4247 +#define JZ_REG_TIMER_ENABLE 0x10
4248 +#define JZ_REG_TIMER_ENABLE_SET 0x14
4249 +#define JZ_REG_TIMER_ENABLE_CLEAR 0x18
4250 +#define JZ_REG_TIMER_FLAG 0x20
4251 +#define JZ_REG_TIMER_FLAG_SET 0x24
4252 +#define JZ_REG_TIMER_FLAG_CLEAR 0x28
4253 +#define JZ_REG_TIMER_MASK 0x30
4254 +#define JZ_REG_TIMER_MASK_SET 0x34
4255 +#define JZ_REG_TIMER_MASK_CLEAR 0x38
4257 +#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x40)
4258 +#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x44)
4259 +#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x48)
4260 +#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x4C)
4262 +#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
4263 +#define JZ_TIMER_IRQ_FULL(x) BIT(x)
4265 +#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
4266 +#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
4267 +#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
4268 +#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
4269 +#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
4270 +#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
4271 +#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
4272 +#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
4273 +#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
4274 +#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
4276 +#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
4278 +#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
4279 +#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
4280 +#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
4282 +extern void __iomem *jz4740_timer_base;
4283 +void __init jz4740_timer_init(void);
4285 +static inline void jz4740_timer_stop(unsigned int timer)
4287 + writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4290 +static inline void jz4740_timer_start(unsigned int timer)
4292 + writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
4295 +static inline bool jz4740_timer_is_enabled(unsigned int timer)
4297 + return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
4300 +static inline void jz4740_timer_enable(unsigned int timer)
4302 + writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
4305 +static inline void jz4740_timer_disable(unsigned int timer)
4307 + writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
4311 +static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
4313 + writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
4316 +static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
4318 + writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
4321 +static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
4323 + writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
4326 +static inline uint16_t jz4740_timer_get_count(unsigned int timer)
4328 + return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
4331 +static inline void jz4740_timer_ack_full(unsigned int timer)
4333 + writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
4336 +static inline void jz4740_timer_irq_full_enable(unsigned int timer)
4338 + writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
4339 + writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
4342 +static inline void jz4740_timer_irq_full_disable(unsigned int timer)
4344 + writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
4347 +static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
4349 + writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
4353 diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
4354 index be5bb16..926c260 100644
4355 --- a/arch/mips/kernel/cpu-probe.c
4356 +++ b/arch/mips/kernel/cpu-probe.c
4357 @@ -163,6 +163,7 @@ void __init check_wait(void)
4359 case CPU_CAVIUM_OCTEON:
4360 case CPU_CAVIUM_OCTEON_PLUS:
4362 cpu_wait = r4k_wait;
4365 @@ -932,6 +933,22 @@ platform:
4369 +static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
4371 + decode_configs(c);
4372 + /* JZRISC does not implement the CP0 counter. */
4373 + c->options &= ~MIPS_CPU_COUNTER;
4374 + switch (c->processor_id & 0xff00) {
4375 + case PRID_IMP_JZRISC:
4376 + c->cputype = CPU_JZRISC;
4377 + __cpu_name[cpu] = "Ingenic JZRISC";
4380 + panic("Unknown Ingenic Processor ID!");
4385 const char *__cpu_name[NR_CPUS];
4386 const char *__elf_platform;
4388 @@ -970,6 +987,9 @@ __cpuinit void cpu_probe(void)
4389 case PRID_COMP_CAVIUM:
4390 cpu_probe_cavium(c, cpu);
4392 + case PRID_COMP_INGENIC:
4393 + cpu_probe_ingenic(c, cpu);
4397 BUG_ON(!__cpu_name[cpu]);
4398 diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
4399 index 86f004d..4510e61 100644
4400 --- a/arch/mips/mm/tlbex.c
4401 +++ b/arch/mips/mm/tlbex.c
4402 @@ -409,6 +409,11 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
4412 panic("No TLB refill handler yet (CPU type: %d)",
4413 current_cpu_data.cputype);