Date:2010-04-24 17:35:05 (12 years 5 months ago)
Author:Lars C.
Commit:26e6894325eab6f295ae51a468f5d866a27b2f8c
Message:Add JZ4740 SoC core support

Files: arch/mips/Kconfig (2 diffs)
arch/mips/Makefile (1 diff)
arch/mips/include/asm/bootinfo.h (1 diff)
arch/mips/include/asm/cpu.h (3 diffs)
arch/mips/include/asm/mach-jz4740/base.h (1 diff)
arch/mips/include/asm/mach-jz4740/clock.h (1 diff)
arch/mips/include/asm/mach-jz4740/dma.h (1 diff)
arch/mips/include/asm/mach-jz4740/gpio.h (1 diff)
arch/mips/include/asm/mach-jz4740/irq.h (1 diff)
arch/mips/include/asm/mach-jz4740/platform.h (1 diff)
arch/mips/include/asm/mach-jz4740/serial.h (1 diff)
arch/mips/include/asm/mach-jz4740/timer.h (1 diff)
arch/mips/include/asm/mach-jz4740/war.h (1 diff)
arch/mips/jz4740/Kconfig (1 diff)
arch/mips/jz4740/Makefile (1 diff)
arch/mips/jz4740/clock-debugfs.c (1 diff)
arch/mips/jz4740/clock.c (1 diff)
arch/mips/jz4740/clock.h (1 diff)
arch/mips/jz4740/dma.c (1 diff)
arch/mips/jz4740/gpio.c (1 diff)
arch/mips/jz4740/irq.c (1 diff)
arch/mips/jz4740/irq.h (1 diff)
arch/mips/jz4740/platform.c (1 diff)
arch/mips/jz4740/pm.c (1 diff)
arch/mips/jz4740/prom.c (1 diff)
arch/mips/jz4740/reset.c (1 diff)
arch/mips/jz4740/reset.h (1 diff)
arch/mips/jz4740/setup.c (1 diff)
arch/mips/jz4740/time.c (1 diff)
arch/mips/kernel/cpu-probe.c (3 diffs)
arch/mips/mm/tlbex.c (1 diff)

Change Details

arch/mips/Kconfig
162162     Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
163163     Olivetti M700-10 workstations.
164164
165config MACH_JZ
166    bool "Ingenic JZ4720/JZ4740 based machines"
167
165168config LASAT
166169    bool "LASAT Networks platforms"
167170    select CEVT_R4K
...... 
684687source "arch/mips/alchemy/Kconfig"
685688source "arch/mips/bcm63xx/Kconfig"
686689source "arch/mips/jazz/Kconfig"
690source "arch/mips/jz4740/Kconfig"
687691source "arch/mips/lasat/Kconfig"
688692source "arch/mips/pmc-sierra/Kconfig"
689693source "arch/mips/powertv/Kconfig"
arch/mips/Makefile
646646load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
647647endif
648648
649# Ingenic JZ4740
650#
651core-$(CONFIG_SOC_JZ4740) += arch/mips/jz4740/
652cflags-$(CONFIG_SOC_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
653load-$(CONFIG_SOC_JZ4740) += 0xffffffff80010000
654
649655cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
650656drivers-$(CONFIG_PCI) += arch/mips/pci/
651657
arch/mips/include/asm/bootinfo.h
7171#define MACH_LEMOTE_LL2F 7
7272#define MACH_LOONGSON_END 8
7373
74/*
75 * Valid machtype for group INGENIC
76 */
77#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
78#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
79
7480extern char *system_type;
7581const char *get_system_type(void);
7682
arch/mips/include/asm/cpu.h
3434#define PRID_COMP_LSI 0x080000
3535#define PRID_COMP_LEXRA 0x0b0000
3636#define PRID_COMP_CAVIUM 0x0d0000
37
37#define PRID_COMP_INGENIC 0xd00000
3838
3939/*
4040 * Assigned values for the product ID register. In order to detect a
...... 
133133#define PRID_IMP_CAVIUM_CN52XX 0x0700
134134
135135/*
136 * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
137 */
138
139#define PRID_IMP_JZRISC 0x0200
140
141/*
136142 * Definitions for 7:0 on legacy processors
137143 */
138144
...... 
226232    CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
227233    CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
228234
235    /*
236     * Ingenic class processors
237     */
238    CPU_JZRISC, CPU_XBURST,
239
229240    CPU_LAST
230241};
231242
arch/mips/include/asm/mach-jz4740/base.h
1#ifndef __JZ4740_BASE_ADDR_H__
2#define __JZ4740_BASE_ADDR_H__
3
4#define JZ4740_CPM_BASE_ADDR 0xb0000000
5#define JZ4740_INTC_BASE_ADDR 0xb0001000
6#define JZ4740_TCU_BASE_ADDR 0xb0002000
7#define JZ4740_WDT_BASE_ADDR 0xb0002000
8#define JZ4740_RTC_BASE_ADDR 0xb0003000
9#define JZ4740_GPIO_BASE_ADDR 0xb0010000
10#define JZ4740_AIC_BASE_ADDR 0xb0020000
11#define JZ4740_ICDC_BASE_ADDR 0xb0020000
12#define JZ4740_MSC_BASE_ADDR 0xb0021000
13#define JZ4740_UART0_BASE_ADDR 0xb0030000
14#define JZ4740_UART1_BASE_ADDR 0xb0031000
15#define JZ4740_I2C_BASE_ADDR 0xb0042000
16#define JZ4740_SSI_BASE_ADDR 0xb0043000
17#define JZ4740_SADC_BASE_ADDR 0xb0070000
18#define JZ4740_EMC_BASE_ADDR 0xb3010000
19#define JZ4740_DMAC_BASE_ADDR 0xb3020000
20#define JZ4740_UHC_BASE_ADDR 0xb3030000
21#define JZ4740_UDC_BASE_ADDR 0xb3040000
22#define JZ4740_LCD_BASE_ADDR 0xb3050000
23#define JZ4740_SLCD_BASE_ADDR 0xb3050000
24#define JZ4740_CIM_BASE_ADDR 0xb3060000
25#define JZ4740_IPU_BASE_ADDR 0xb3080000
26#define JZ4740_ETH_BASE_ADDR 0xb3100000
27
28#endif
arch/mips/include/asm/mach-jz4740/clock.h
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * You should have received a copy of the GNU General Public License along
10 * with this program; if not, write to the Free Software Foundation, Inc.,
11 * 675 Mass Ave, Cambridge, MA 02139, USA.
12 *
13 */
14
15#ifndef __ASM_JZ4740_CLOCK_H__
16#define __ASM_JZ4740_CLOCK_H__
17
18enum jz4740_wait_mode {
19    JZ4740_WAIT_MODE_IDLE,
20    JZ4740_WAIT_MODE_SLEEP,
21};
22
23void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
24
25void jz4740_clock_udc_enable_auto_suspend(void);
26void jz4740_clock_udc_disable_auto_suspend(void);
27
28#endif
arch/mips/include/asm/mach-jz4740/dma.h
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ7420/JZ4740 DMA definitions
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __ASM_MACH_JZ4740_DMA_H__
17#define __ASM_MACH_JZ4740_DMA_H__
18
19struct jz4740_dma_chan;
20
21enum jz4740_dma_request_type {
22    JZ4740_DMA_TYPE_AUTO_REQUEST = 8,
23    JZ4740_DMA_TYPE_UART_TRANSMIT = 20,
24    JZ4740_DMA_TYPE_UART_RECEIVE = 21,
25    JZ4740_DMA_TYPE_SPI_TRANSMIT = 22,
26    JZ4740_DMA_TYPE_SPI_RECEIVE = 23,
27    JZ4740_DMA_TYPE_AIC_TRANSMIT = 24,
28    JZ4740_DMA_TYPE_AIC_RECEIVE = 25,
29    JZ4740_DMA_TYPE_MMC_TRANSMIT = 26,
30    JZ4740_DMA_TYPE_MMC_RECEIVE = 27,
31    JZ4740_DMA_TYPE_TCU = 28,
32    JZ4740_DMA_TYPE_SADC = 29,
33    JZ4740_DMA_TYPE_SLCD = 30,
34};
35
36enum jz4740_dma_width {
37    JZ4740_DMA_WIDTH_8BIT,
38    JZ4740_DMA_WIDTH_16BIT,
39    JZ4740_DMA_WIDTH_32BIT,
40};
41
42enum jz4740_dma_transfer_size {
43    JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0,
44    JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1,
45    JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2,
46    JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
47    JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
48};
49
50enum jz4740_dma_flags {
51    JZ4740_DMA_SRC_AUTOINC = 0x2,
52    JZ4740_DMA_DST_AUTOINC = 0x1,
53};
54
55enum jz4740_dma_mode {
56    JZ4740_DMA_MODE_SINGLE = 0,
57    JZ4740_DMA_MODE_BLOCK = 1,
58};
59
60struct jz4740_dma_config {
61    enum jz4740_dma_width src_width;
62    enum jz4740_dma_width dst_width;
63    enum jz4740_dma_transfer_size transfer_size;
64    enum jz4740_dma_request_type request_type;
65    enum jz4740_dma_flags flags;
66    enum jz4740_dma_mode mode;
67};
68
69typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
70
71struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
72void jz4740_dma_free(struct jz4740_dma_chan *dma);
73
74void jz4740_dma_configure(struct jz4740_dma_chan *dma,
75    const struct jz4740_dma_config *config);
76
77
78void jz4740_dma_enable(struct jz4740_dma_chan *dma);
79void jz4740_dma_disable(struct jz4740_dma_chan *dma);
80
81void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
82void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
83void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
84
85uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
86
87void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
88    jz4740_dma_complete_callback_t cb);
89
90#endif /* __ASM_JZ4740_DMA_H__ */
arch/mips/include/asm/mach-jz4740/gpio.h
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ7420/JZ4740 GPIO pin definitions
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef _JZ_GPIO_H
17#define _JZ_GPIO_H
18
19#include <linux/types.h>
20
21enum jz_gpio_function {
22    JZ_GPIO_FUNC_NONE,
23    JZ_GPIO_FUNC1,
24    JZ_GPIO_FUNC2,
25    JZ_GPIO_FUNC3,
26};
27
28
29/*
30 Usually a driver for a SoC component has to request several gpio pins and
31 configure them as funcion pins.
32 jz_gpio_bulk_request can be used to ease this process.
33 Usually one would do something like:
34
35 const static struct jz_gpio_bulk_request i2c_pins[] = {
36    JZ_GPIO_BULK_PIN(I2C_SDA),
37    JZ_GPIO_BULK_PIN(I2C_SCK),
38 };
39
40 inside the probe function:
41
42    ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
43    if (ret) {
44    ...
45
46 inside the remove function:
47
48    jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
49
50
51*/
52struct jz_gpio_bulk_request {
53    int gpio;
54    const char *name;
55    enum jz_gpio_function function;
56};
57
58#define JZ_GPIO_BULK_PIN(pin) { \
59    .gpio = JZ_GPIO_ ## pin, \
60    .name = #pin, \
61    .function = JZ_GPIO_FUNC_ ## pin \
62}
63
64int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
65void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
66void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
67void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
68void jz_gpio_enable_pullup(unsigned gpio);
69void jz_gpio_disable_pullup(unsigned gpio);
70int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
71
72int jz_gpio_port_direction_input(int port, uint32_t mask);
73int jz_gpio_port_direction_output(int port, uint32_t mask);
74void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
75uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
76
77#include <asm/mach-generic/gpio.h>
78
79#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
80#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
81#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
82#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
83
84/* Port A function pins */
85#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0)
86#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1)
87#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2)
88#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3)
89#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4)
90#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5)
91#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6)
92#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7)
93#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8)
94#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9)
95#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10)
96#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11)
97#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12)
98#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13)
99#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14)
100#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15)
101#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16)
102#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17)
103#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18)
104#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19)
105#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20)
106#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21)
107#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22)
108#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23)
109#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24)
110#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25)
111#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26)
112#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27)
113#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28)
114#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29)
115#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30)
116#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31)
117
118#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1
119#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1
120#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1
121#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1
122#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1
123#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1
124#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1
125#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1
126#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1
127#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1
128#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1
129#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1
130#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1
131#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1
132#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1
133#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1
134#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1
135#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1
136#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1
137#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1
138#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1
139#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1
140#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1
141#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1
142#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1
143#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1
144#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1
145#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1
146#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1
147#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1
148#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1
149#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1
150
151/* Port B function pins */
152#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0)
153#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1)
154#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2)
155#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3)
156#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4)
157#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5)
158#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6)
159#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7)
160#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8)
161#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9)
162#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10)
163#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11)
164#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12)
165#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13)
166#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14)
167#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15)
168#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16)
169#define JZ_GPIO_MEM_CLS JZ_GPIO_PORTB(17)
170#define JZ_GPIO_MEM_SPL JZ_GPIO_PORTB(18)
171#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19)
172#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20)
173#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21)
174#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22)
175#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23)
176#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24)
177#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25)
178#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26)
179#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27)
180#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28)
181#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29)
182#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30)
183#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31)
184
185#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1
186#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1
187#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1
188#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1
189#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1
190#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1
191#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1
192#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1
193#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1
194#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1
195#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1
196#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1
197#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1
198#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1
199#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1
200#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1
201#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1
202#define JZ_GPIO_FUNC_MEM_CLS JZ_GPIO_FUNC1
203#define JZ_GPIO_FUNC_MEM_SPL JZ_GPIO_FUNC1
204#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1
205#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1
206#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1
207#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1
208#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1
209#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1
210#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1
211#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1
212#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1
213#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1
214#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1
215#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1
216#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1
217
218
219#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17)
220#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18)
221
222#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2
223#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2
224
225/* Port C function pins */
226#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0)
227#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1)
228#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2)
229#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3)
230#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4)
231#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5)
232#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6)
233#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7)
234#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8)
235#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9)
236#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10)
237#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11)
238#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12)
239#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13)
240#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14)
241#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15)
242#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16)
243#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17)
244#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18)
245#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19)
246#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20)
247#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21)
248#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22)
249#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23)
250#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24)
251#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25)
252#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26)
253#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
254#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
255#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
256
257#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
258#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
259#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1
260#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1
261#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1
262#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1
263#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1
264#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1
265#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1
266#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1
267#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1
268#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1
269#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1
270#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1
271#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1
272#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1
273#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1
274#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1
275#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1
276#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1
277#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1
278#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1
279#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1
280#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1
281#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1
282#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1
283#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1
284#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
285#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
286#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
287
288
289#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
290#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23)
291
292#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2
293#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2
294
295/* Port D function pins */
296#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0)
297#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1)
298#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2)
299#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3)
300#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4)
301#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5)
302#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6)
303#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7)
304#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8)
305#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9)
306#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10)
307#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11)
308#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12)
309#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13)
310#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14)
311#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15)
312#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16)
313#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17)
314#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18)
315#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19)
316#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20)
317#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21)
318#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22)
319#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23)
320#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24)
321#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25)
322#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26)
323#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27)
324#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28)
325#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30)
326#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31)
327
328#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC1
329#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC1
330#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC1
331#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC1
332#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC1
333#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC1
334#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC1
335#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC1
336#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1
337#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1
338#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC1
339#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC1
340#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC1
341#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC1
342#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1
343#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1
344#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1
345#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1
346#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1
347#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1
348#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1
349#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1
350#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1
351#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC1
352#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC1
353#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC1
354#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC1
355#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC1
356#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC1
357#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC1
358
359#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18)
360#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19)
361#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20)
362#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21)
363#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22)
364#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23)
365#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24)
366#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25)
367#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26)
368#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27)
369#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28)
370#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30)
371#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31)
372
373#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2
374#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2
375#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2
376#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2
377#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2
378#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2
379#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2
380#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2
381#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2
382#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2
383#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2
384#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2
385#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2
386
387#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30)
388#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31)
389
390#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3
391#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3
392
393#endif
arch/mips/include/asm/mach-jz4740/irq.h
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ7420/JZ4740 IRQ definitions
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __ASM_MACH_JZ4740_IRQ_H__
17#define __ASM_MACH_JZ4740_IRQ_H__
18
19#define MIPS_CPU_IRQ_BASE 0
20#define JZ4740_IRQ_BASE 8
21
22/* 1st-level interrupts */
23#define JZ4740_IRQ(x) (JZ4740_IRQ_BASE + (x))
24#define JZ4740_IRQ_I2C JZ4740_IRQ(1)
25#define JZ4740_IRQ_UHC JZ4740_IRQ(3)
26#define JZ4740_IRQ_UART1 JZ4740_IRQ(8)
27#define JZ4740_IRQ_UART0 JZ4740_IRQ(9)
28#define JZ4740_IRQ_SADC JZ4740_IRQ(12)
29#define JZ4740_IRQ_MSC JZ4740_IRQ(14)
30#define JZ4740_IRQ_RTC JZ4740_IRQ(15)
31#define JZ4740_IRQ_SSI JZ4740_IRQ(16)
32#define JZ4740_IRQ_CIM JZ4740_IRQ(17)
33#define JZ4740_IRQ_AIC JZ4740_IRQ(18)
34#define JZ4740_IRQ_ETH JZ4740_IRQ(19)
35#define JZ4740_IRQ_DMAC JZ4740_IRQ(20)
36#define JZ4740_IRQ_TCU2 JZ4740_IRQ(21)
37#define JZ4740_IRQ_TCU1 JZ4740_IRQ(22)
38#define JZ4740_IRQ_TCU0 JZ4740_IRQ(23)
39#define JZ4740_IRQ_UDC JZ4740_IRQ(24)
40#define JZ4740_IRQ_GPIO3 JZ4740_IRQ(25)
41#define JZ4740_IRQ_GPIO2 JZ4740_IRQ(26)
42#define JZ4740_IRQ_GPIO1 JZ4740_IRQ(27)
43#define JZ4740_IRQ_GPIO0 JZ4740_IRQ(28)
44#define JZ4740_IRQ_IPU JZ4740_IRQ(29)
45#define JZ4740_IRQ_LCD JZ4740_IRQ(30)
46
47/* 2nd-level interrupts */
48#define JZ4740_IRQ_DMA(x) ((x) + JZ4740_IRQ(32))
49
50#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
51#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x))
52
53#define NR_IRQS (JZ4740_IRQ_GPIO(127) + 1)
54
55#endif
arch/mips/include/asm/mach-jz4740/platform.h
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ7420/JZ4740 platform device definitions
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16
17#ifndef __JZ4740_PLATFORM_H
18#define __JZ4740_PLATFORM_H
19
20#include <linux/platform_device.h>
21
22extern struct platform_device jz4740_usb_ohci_device;
23extern struct platform_device jz4740_usb_gdt_device;
24extern struct platform_device jz4740_mmc_device;
25extern struct platform_device jz4740_rtc_device;
26extern struct platform_device jz4740_i2c_device;
27extern struct platform_device jz4740_nand_device;
28extern struct platform_device jz4740_framebuffer_device;
29extern struct platform_device jz4740_i2s_device;
30extern struct platform_device jz4740_codec_device;
31extern struct platform_device jz4740_adc_device;
32extern struct platform_device jz4740_battery_device;
33
34#endif
arch/mips/include/asm/mach-jz4740/serial.h
1/*
2 * linux/include/asm-mips/mach-jz4740/serial.h
3 *
4 * Ingenic's JZ4740 common include.
5 *
6 * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc.
7 *
8 * Author: <yliu@ingenic.cn>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __ASM_BOARD_SERIAL_H__
16#define __ASM_BOARD_SERIAL_H__
17
18#ifndef CONFIG_SERIAL_MANY_PORTS
19#undef RS_TABLE_SIZE
20#define RS_TABLE_SIZE 1
21#endif
22
23#define JZ_BASE_BAUD (12000000/16)
24
25#define JZ_SERIAL_PORT_DEFNS \
26    { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART0, \
27      .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART0_BASE, \
28      .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM },
29
30#endif /* __ASM_BORAD_SERIAL_H__ */
arch/mips/include/asm/mach-jz4740/timer.h
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform timer support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __ASM_MACH_JZ4740_TIMER
17#define __ASM_MACH_JZ4740_TIMER
18
19void jz4740_timer_enable_watchdog(void);
20void jz4740_timer_disable_watchdog(void);
21
22#endif
arch/mips/include/asm/mach-jz4740/war.h
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
7 */
8#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H
9#define __ASM_MIPS_MACH_JZ4740_WAR_H
10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0
13#define R4600_V2_HIT_CACHEOP_WAR 0
14#define R5432_CP0_INTERRUPT_WAR 0
15#define BCM1250_M3_WAR 0
16#define SIBYTE_1956_WAR 0
17#define MIPS4K_ICACHE_REFILL_WAR 0
18#define MIPS_CACHE_SYNC_WAR 0
19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define RM9000_CDEX_SMP_WAR 0
21#define ICACHE_REFILLS_WORKAROUND_WAR 0
22#define R10000_LLSC_WAR 0
23#define MIPS34K_MISSED_ITLB_WAR 0
24
25#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
arch/mips/jz4740/Kconfig
1choice
2    prompt "Machine type"
3    depends on MACH_JZ
4    default JZ4740_QI_LB60
5
6endchoice
7
8config SOC_JZ4740
9    bool
10    select JZSOC
11    select GENERIC_GPIO
12    select ARCH_REQUIRE_GPIOLIB
13    select SYS_HAS_EARLY_PRINTK
14    select SYS_SUPPORTS_LITTLE_ENDIAN
15    select IRQ_CPU
16
17config JZSOC
18    bool
19    select JZRISC
20    select SYS_HAS_CPU_MIPS32_R1
21    select SYS_SUPPORTS_32BIT_KERNEL
22
23config JZRISC
24    bool
arch/mips/jz4740/Makefile
1#
2# Makefile for the Ingenic JZ4740.
3#
4
5# Object file lists.
6
7obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
8    gpio.o clock.o platform.o
9
10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
11
12# board specific support
13
14# PM support
15
16obj-$(CONFIG_PM) += pm.o
17
arch/mips/jz4740/clock-debugfs.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC clock support debugfs entries
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <linux/debugfs.h>
22#include <linux/uaccess.h>
23
24#include <asm/mach-jz4740/clock.h>
25#include "clock.h"
26
27static struct dentry *jz4740_clock_debugfs;
28
29static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
30{
31    struct clk *clk = data;
32    *value = clk_is_enabled(clk);
33
34    return 0;
35}
36
37static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
38{
39    struct clk *clk = data;
40
41    if (value)
42        return clk_enable(clk);
43    else
44        clk_disable(clk);
45
46    return 0;
47}
48
49DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
50    jz4740_clock_debugfs_show_enabled,
51    jz4740_clock_debugfs_set_enabled,
52    "%llu\n");
53
54static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
55{
56    struct clk *clk = data;
57    *value = clk_get_rate(clk);
58
59    return 0;
60}
61
62DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
63    jz4740_clock_debugfs_show_rate,
64    NULL,
65    "%llu\n");
66
67void jz4740_clock_debugfs_add_clk(struct clk *clk)
68{
69    if (!jz4740_clock_debugfs)
70        return;
71
72    clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
73    debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
74                &jz4740_clock_debugfs_ops_rate);
75    debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
76                &jz4740_clock_debugfs_ops_enabled);
77
78    if (clk->parent) {
79        char parent_path[100];
80        snprintf(parent_path, 100, "../%s", clk->parent->name);
81        clk->debugfs_parent_entry = debugfs_create_symlink("parent",
82                        clk->debugfs_entry,
83                        parent_path);
84    }
85}
86
87/* TODO: Locking */
88void jz4740_clock_debugfs_update_parent(struct clk *clk)
89{
90    if (clk->debugfs_parent_entry)
91        debugfs_remove(clk->debugfs_parent_entry);
92
93    if (clk->parent) {
94        char parent_path[100];
95        snprintf(parent_path, 100, "../%s", clk->parent->name);
96        clk->debugfs_parent_entry = debugfs_create_symlink("parent",
97                        clk->debugfs_entry,
98                        parent_path);
99    } else {
100        clk->debugfs_parent_entry = NULL;
101    }
102}
103
104void jz4740_clock_debugfs_init(void)
105{
106    jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
107    if (IS_ERR(jz4740_clock_debugfs))
108        jz4740_clock_debugfs = NULL;
109}
arch/mips/jz4740/clock.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC clock support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/clk.h>
19#include <linux/spinlock.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/list.h>
23#include <linux/err.h>
24
25#include <asm/mach-jz4740/clock.h>
26#include <asm/mach-jz4740/base.h>
27
28#include "clock.h"
29
30#define JZ_REG_CLOCK_CTRL 0x00
31#define JZ_REG_CLOCK_LOW_POWER 0x04
32#define JZ_REG_CLOCK_PLL 0x10
33#define JZ_REG_CLOCK_GATE 0x20
34#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
35#define JZ_REG_CLOCK_I2S 0x60
36#define JZ_REG_CLOCK_LCD 0x64
37#define JZ_REG_CLOCK_MMC 0x68
38#define JZ_REG_CLOCK_UHC 0x6C
39#define JZ_REG_CLOCK_SPI 0x74
40
41#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
42#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
43#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
44#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
45#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
46#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
47#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
48#define JZ_CLOCK_CTRL_UDIV_OFFSET 23
49#define JZ_CLOCK_CTRL_LDIV_OFFSET 16
50#define JZ_CLOCK_CTRL_MDIV_OFFSET 12
51#define JZ_CLOCK_CTRL_PDIV_OFFSET 8
52#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
53#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
54
55#define JZ_CLOCK_GATE_UART0 BIT(0)
56#define JZ_CLOCK_GATE_TCU BIT(1)
57#define JZ_CLOCK_GATE_RTC BIT(2)
58#define JZ_CLOCK_GATE_I2C BIT(3)
59#define JZ_CLOCK_GATE_SPI BIT(4)
60#define JZ_CLOCK_GATE_AIC BIT(5)
61#define JZ_CLOCK_GATE_I2S BIT(6)
62#define JZ_CLOCK_GATE_MMC BIT(7)
63#define JZ_CLOCK_GATE_ADC BIT(8)
64#define JZ_CLOCK_GATE_CIM BIT(9)
65#define JZ_CLOCK_GATE_LCD BIT(10)
66#define JZ_CLOCK_GATE_UDC BIT(11)
67#define JZ_CLOCK_GATE_DMAC BIT(12)
68#define JZ_CLOCK_GATE_IPU BIT(13)
69#define JZ_CLOCK_GATE_UHC BIT(14)
70#define JZ_CLOCK_GATE_UART1 BIT(15)
71
72#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
73
74#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
75
76#define JZ_CLOCK_MMC_DIV_MASK 0x001f
77
78#define JZ_CLOCK_UHC_DIV_MASK 0x000f
79
80#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
81#define JZ_CLOCK_SPI_DIV_MASK 0x000f
82
83#define JZ_CLOCK_PLL_M_MASK 0x01ff
84#define JZ_CLOCK_PLL_N_MASK 0x001f
85#define JZ_CLOCK_PLL_OD_MASK 0x0003
86#define JZ_CLOCK_PLL_STABLE BIT(10)
87#define JZ_CLOCK_PLL_BYPASS BIT(9)
88#define JZ_CLOCK_PLL_ENABLED BIT(8)
89#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f
90#define JZ_CLOCK_PLL_M_OFFSET 23
91#define JZ_CLOCK_PLL_N_OFFSET 18
92#define JZ_CLOCK_PLL_OD_OFFSET 16
93
94#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
95#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
96
97#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
98#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
99
100static void __iomem *jz_clock_base;
101static spinlock_t jz_clock_lock;
102static LIST_HEAD(jz_clocks);
103
104struct main_clk {
105    struct clk clk;
106    uint32_t div_offset;
107};
108
109struct divided_clk {
110    struct clk clk;
111    uint32_t reg;
112    uint32_t mask;
113};
114
115struct static_clk {
116    struct clk clk;
117    unsigned long rate;
118};
119
120static uint32_t jz_clk_reg_read(int reg)
121{
122    return readl(jz_clock_base + reg);
123}
124
125static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
126{
127    uint32_t val2;
128
129    spin_lock(&jz_clock_lock);
130    val2 = readl(jz_clock_base + reg);
131    val2 &= ~mask;
132    val2 |= val;
133    writel(val2, jz_clock_base + reg);
134    spin_unlock(&jz_clock_lock);
135}
136
137static void jz_clk_reg_set_bits(int reg, uint32_t mask)
138{
139    uint32_t val;
140
141    spin_lock(&jz_clock_lock);
142    val = readl(jz_clock_base + reg);
143    val |= mask;
144    writel(val, jz_clock_base + reg);
145    spin_unlock(&jz_clock_lock);
146}
147
148static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
149{
150    uint32_t val;
151
152    spin_lock(&jz_clock_lock);
153    val = readl(jz_clock_base + reg);
154    val &= ~mask;
155    writel(val, jz_clock_base + reg);
156    spin_unlock(&jz_clock_lock);
157}
158
159static int jz_clk_enable_gating(struct clk *clk)
160{
161    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
162        return -EINVAL;
163
164    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
165    return 0;
166}
167
168static int jz_clk_disable_gating(struct clk *clk)
169{
170    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
171        return -EINVAL;
172
173    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
174    return 0;
175}
176
177static int jz_clk_is_enabled_gating(struct clk *clk)
178{
179    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
180        return 1;
181
182    return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
183}
184
185static unsigned long jz_clk_static_get_rate(struct clk *clk)
186{
187    return ((struct static_clk *)clk)->rate;
188}
189
190static int jz_clk_ko_enable(struct clk *clk)
191{
192    jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
193    return 0;
194}
195
196static int jz_clk_ko_disable(struct clk *clk)
197{
198    jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
199    return 0;
200}
201
202static int jz_clk_ko_is_enabled(struct clk *clk)
203{
204    return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
205}
206
207static const int pllno[] = {1, 2, 2, 4};
208
209static unsigned long jz_clk_pll_get_rate(struct clk *clk)
210{
211    uint32_t val;
212    int m;
213    int n;
214    int od;
215
216    val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
217
218    if (val & JZ_CLOCK_PLL_BYPASS)
219        return clk_get_rate(clk->parent);
220
221    m = ((val >> 23) & 0x1ff) + 2;
222    n = ((val >> 18) & 0x1f) + 2;
223    od = (val >> 16) & 0x3;
224
225    return clk_get_rate(clk->parent) * (m / n) / pllno[od];
226}
227
228static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
229{
230    uint32_t reg;
231
232    reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
233    if (reg & JZ_CLOCK_CTRL_PLL_HALF)
234        return jz_clk_pll_get_rate(clk->parent);
235    return jz_clk_pll_get_rate(clk->parent) >> 1;
236}
237
238static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
239
240static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
241{
242    unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
243    int div;
244
245    div = parent_rate / rate;
246    if (div > 32)
247        return parent_rate / 32;
248    else if (div < 1)
249        return parent_rate;
250
251    div &= (0x3 << (ffs(div) - 1));
252
253    return parent_rate / div;
254}
255
256static unsigned long jz_clk_main_get_rate(struct clk *clk)
257{
258    struct main_clk *mclk = (struct main_clk *)clk;
259    uint32_t div;
260
261    div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
262
263    div >>= mclk->div_offset;
264    div &= 0xf;
265
266    if (div >= ARRAY_SIZE(jz_clk_main_divs))
267        div = ARRAY_SIZE(jz_clk_main_divs) - 1;
268
269    return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
270}
271
272static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
273{
274    struct main_clk *mclk = (struct main_clk *)clk;
275    int i;
276    int div;
277    unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
278
279    rate = jz_clk_main_round_rate(clk, rate);
280
281    div = parent_rate / rate;
282
283    i = (ffs(div) - 1) << 1;
284    if (i > 0 && !(div & BIT(i-1)))
285        i -= 1;
286
287    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
288                0xf << mclk->div_offset);
289
290    return 0;
291}
292
293static struct clk_ops jz_clk_static_ops = {
294    .get_rate = jz_clk_static_get_rate,
295    .enable = jz_clk_enable_gating,
296    .disable = jz_clk_disable_gating,
297    .is_enabled = jz_clk_is_enabled_gating,
298};
299
300static struct static_clk jz_clk_ext = {
301    .clk = {
302        .name = "ext",
303        .gate_bit = JZ4740_CLK_NOT_GATED,
304        .ops = &jz_clk_static_ops,
305    },
306};
307
308static struct clk_ops jz_clk_pll_ops = {
309    .get_rate = jz_clk_static_get_rate,
310};
311
312static struct clk jz_clk_pll = {
313    .name = "pll",
314    .parent = &jz_clk_ext.clk,
315    .ops = &jz_clk_pll_ops,
316};
317
318static struct clk_ops jz_clk_pll_half_ops = {
319    .get_rate = jz_clk_pll_half_get_rate,
320};
321
322static struct clk jz_clk_pll_half = {
323    .name = "pll half",
324    .parent = &jz_clk_pll,
325    .ops = &jz_clk_pll_half_ops,
326};
327
328static const struct clk_ops jz_clk_main_ops = {
329    .get_rate = jz_clk_main_get_rate,
330    .set_rate = jz_clk_main_set_rate,
331    .round_rate = jz_clk_main_round_rate,
332};
333
334static struct main_clk jz_clk_cpu = {
335    .clk = {
336        .name = "cclk",
337        .parent = &jz_clk_pll,
338        .ops = &jz_clk_main_ops,
339    },
340    .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
341};
342
343static struct main_clk jz_clk_memory = {
344    .clk = {
345        .name = "mclk",
346        .parent = &jz_clk_pll,
347        .ops = &jz_clk_main_ops,
348    },
349    .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
350};
351
352static struct main_clk jz_clk_high_speed_peripheral = {
353    .clk = {
354        .name = "hclk",
355        .parent = &jz_clk_pll,
356        .ops = &jz_clk_main_ops,
357    },
358    .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
359};
360
361
362static struct main_clk jz_clk_low_speed_peripheral = {
363    .clk = {
364        .name = "pclk",
365        .parent = &jz_clk_pll,
366        .ops = &jz_clk_main_ops,
367    },
368    .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
369};
370
371static const struct clk_ops jz_clk_ko_ops = {
372    .enable = jz_clk_ko_enable,
373    .disable = jz_clk_ko_disable,
374    .is_enabled = jz_clk_ko_is_enabled,
375};
376
377static struct clk jz_clk_ko = {
378    .name = "cko",
379    .parent = &jz_clk_memory.clk,
380    .ops = &jz_clk_ko_ops,
381};
382
383static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
384{
385    if (parent == &jz_clk_pll)
386        jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
387    else if (parent == &jz_clk_ext.clk)
388        jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
389    else
390        return -EINVAL;
391
392    clk->parent = parent;
393
394    return 0;
395}
396
397static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
398{
399    if (parent == &jz_clk_pll_half)
400        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
401    else if (parent == &jz_clk_ext.clk)
402        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
403    else
404        return -EINVAL;
405
406    clk->parent = parent;
407
408    return 0;
409}
410
411static int jz_clk_udc_enable(struct clk *clk)
412{
413    jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
414            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
415
416    return 0;
417}
418
419static int jz_clk_udc_disable(struct clk *clk)
420{
421    jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
422            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
423
424    return 0;
425}
426
427static int jz_clk_udc_is_enabled(struct clk *clk)
428{
429    return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
430            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
431}
432static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
433{
434    if (parent == &jz_clk_pll_half)
435        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
436    else if (parent == &jz_clk_ext.clk)
437        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
438    else
439        return -EINVAL;
440
441    clk->parent = parent;
442
443    return 0;
444}
445
446static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
447{
448    int div;
449
450    if (clk->parent == &jz_clk_ext.clk)
451        return -EINVAL;
452
453    div = clk_get_rate(clk->parent) / rate - 1;
454
455    if (div < 0)
456        div = 0;
457    else if (div > 63)
458        div = 63;
459
460    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
461                JZ_CLOCK_CTRL_UDIV_MASK);
462    return 0;
463}
464
465static unsigned long jz_clk_udc_get_rate(struct clk *clk)
466{
467    int div;
468
469    if (clk->parent == &jz_clk_ext.clk)
470        return clk_get_rate(clk->parent);
471
472    div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
473    div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
474    div += 1;
475
476    return clk_get_rate(clk->parent) / div;
477}
478
479static unsigned long jz_clk_divided_get_rate(struct clk *clk)
480{
481    struct divided_clk *dclk = (struct divided_clk *)clk;
482    int div;
483
484    if (clk->parent == &jz_clk_ext.clk)
485        return clk_get_rate(clk->parent);
486
487    div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
488
489    return clk_get_rate(clk->parent) / div;
490}
491
492static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
493{
494    struct divided_clk *dclk = (struct divided_clk *)clk;
495    int div;
496
497    if (clk->parent == &jz_clk_ext.clk)
498        return -EINVAL;
499
500    div = clk_get_rate(clk->parent) / rate - 1;
501
502    if (div < 0)
503        div = 0;
504    else if (div > dclk->mask)
505        div = dclk->mask;
506
507    jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
508
509    return 0;
510}
511
512static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
513{
514    int div;
515    unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
516
517    if (rate > 150000000)
518        return 150000000;
519
520    div = parent_rate / rate;
521    if (div < 1)
522        div = 1;
523    else if (div > 32)
524        div = 32;
525
526    return parent_rate / div;
527}
528
529static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
530{
531    int div;
532
533    if (rate > 150000000)
534        return -EINVAL;
535
536    div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
537    if (div < 0)
538        div = 0;
539    else if (div > 31)
540        div = 31;
541
542    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
543                JZ_CLOCK_CTRL_LDIV_MASK);
544
545    return 0;
546}
547
548static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
549{
550    int div;
551
552    div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
553    div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
554
555    return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
556}
557
558static const struct clk_ops jz_clk_ops_ld = {
559    .set_rate = jz_clk_ldclk_set_rate,
560    .get_rate = jz_clk_ldclk_get_rate,
561    .round_rate = jz_clk_ldclk_round_rate,
562    .enable = jz_clk_enable_gating,
563    .disable = jz_clk_disable_gating,
564    .is_enabled = jz_clk_is_enabled_gating,
565};
566
567static struct clk jz_clk_ld = {
568    .name = "lcd",
569    .gate_bit = JZ_CLOCK_GATE_LCD,
570    .parent = &jz_clk_pll_half,
571    .ops = &jz_clk_ops_ld,
572};
573
574/* TODO: ops!!! */
575static struct clk jz_clk_cim_mclk = {
576    .name = "cim_mclk",
577    .parent = &jz_clk_high_speed_peripheral.clk,
578};
579
580static struct static_clk jz_clk_cim_pclk = {
581    .clk = {
582        .name = "cim_pclk",
583        .gate_bit = JZ_CLOCK_GATE_CIM,
584        .ops = &jz_clk_static_ops,
585    },
586};
587
588static const struct clk_ops jz_clk_i2s_ops = {
589    .set_rate = jz_clk_divided_set_rate,
590    .get_rate = jz_clk_divided_get_rate,
591    .enable = jz_clk_enable_gating,
592    .disable = jz_clk_disable_gating,
593    .is_enabled = jz_clk_is_enabled_gating,
594    .set_parent = jz_clk_i2s_set_parent,
595};
596
597static const struct clk_ops jz_clk_spi_ops = {
598    .set_rate = jz_clk_divided_set_rate,
599    .get_rate = jz_clk_divided_get_rate,
600    .enable = jz_clk_enable_gating,
601    .disable = jz_clk_disable_gating,
602    .is_enabled = jz_clk_is_enabled_gating,
603    .set_parent = jz_clk_spi_set_parent,
604};
605
606static const struct clk_ops jz_clk_divided_ops = {
607    .set_rate = jz_clk_divided_set_rate,
608    .get_rate = jz_clk_divided_get_rate,
609    .enable = jz_clk_enable_gating,
610    .disable = jz_clk_disable_gating,
611    .is_enabled = jz_clk_is_enabled_gating,
612};
613
614static struct divided_clk jz4740_clock_divided_clks[] = {
615    {
616        .clk = {
617            .name = "lcd_pclk",
618            .parent = &jz_clk_pll_half,
619            .gate_bit = JZ4740_CLK_NOT_GATED,
620            .ops = &jz_clk_divided_ops,
621        },
622        .reg = JZ_REG_CLOCK_LCD,
623        .mask = JZ_CLOCK_LCD_DIV_MASK,
624    },
625    {
626        .clk = {
627            .name = "i2s",
628            .parent = &jz_clk_ext.clk,
629            .gate_bit = JZ_CLOCK_GATE_I2S,
630            .ops = &jz_clk_i2s_ops,
631        },
632        .reg = JZ_REG_CLOCK_I2S,
633        .mask = JZ_CLOCK_I2S_DIV_MASK,
634    },
635    {
636        .clk = {
637            .name = "spi",
638            .parent = &jz_clk_ext.clk,
639            .gate_bit = JZ_CLOCK_GATE_SPI,
640            .ops = &jz_clk_spi_ops,
641        },
642        .reg = JZ_REG_CLOCK_SPI,
643        .mask = JZ_CLOCK_SPI_DIV_MASK,
644    },
645    {
646        .clk = {
647            .name = "mmc",
648            .parent = &jz_clk_pll_half,
649            .gate_bit = JZ_CLOCK_GATE_MMC,
650            .ops = &jz_clk_divided_ops,
651        },
652        .reg = JZ_REG_CLOCK_MMC,
653        .mask = JZ_CLOCK_MMC_DIV_MASK,
654    },
655    {
656        .clk = {
657            .name = "uhc",
658            .parent = &jz_clk_pll_half,
659            .gate_bit = JZ_CLOCK_GATE_UHC,
660            .ops = &jz_clk_divided_ops,
661        },
662        .reg = JZ_REG_CLOCK_UHC,
663        .mask = JZ_CLOCK_UHC_DIV_MASK,
664    },
665};
666
667static const struct clk_ops jz_clk_udc_ops = {
668    .set_parent = jz_clk_udc_set_parent,
669    .set_rate = jz_clk_udc_set_rate,
670    .get_rate = jz_clk_udc_get_rate,
671    .enable = jz_clk_udc_enable,
672    .disable = jz_clk_udc_disable,
673    .is_enabled = jz_clk_udc_is_enabled,
674};
675
676static const struct clk_ops jz_clk_simple_ops = {
677    .enable = jz_clk_enable_gating,
678    .disable = jz_clk_disable_gating,
679    .is_enabled = jz_clk_is_enabled_gating,
680};
681
682static struct clk jz4740_clock_simple_clks[] = {
683    {
684        .name = "udc",
685        .parent = &jz_clk_ext.clk,
686        .ops = &jz_clk_udc_ops,
687    },
688    {
689        .name = "uart0",
690        .parent = &jz_clk_ext.clk,
691        .gate_bit = JZ_CLOCK_GATE_UART0,
692        .ops = &jz_clk_simple_ops,
693    },
694    {
695        .name = "uart1",
696        .parent = &jz_clk_ext.clk,
697        .gate_bit = JZ_CLOCK_GATE_UART1,
698        .ops = &jz_clk_simple_ops,
699    },
700    {
701        .name = "dma",
702        .parent = &jz_clk_high_speed_peripheral.clk,
703        .gate_bit = JZ_CLOCK_GATE_UART0,
704        .ops = &jz_clk_simple_ops,
705    },
706    {
707        .name = "ipu",
708        .parent = &jz_clk_high_speed_peripheral.clk,
709        .gate_bit = JZ_CLOCK_GATE_IPU,
710        .ops = &jz_clk_simple_ops,
711    },
712    {
713        .name = "adc",
714        .parent = &jz_clk_ext.clk,
715        .gate_bit = JZ_CLOCK_GATE_ADC,
716        .ops = &jz_clk_simple_ops,
717    },
718    {
719        .name = "i2c",
720        .parent = &jz_clk_ext.clk,
721        .gate_bit = JZ_CLOCK_GATE_I2C,
722        .ops = &jz_clk_simple_ops,
723    },
724    {
725        .name = "aic",
726        .parent = &jz_clk_ext.clk,
727        .gate_bit = JZ_CLOCK_GATE_AIC,
728        .ops = &jz_clk_simple_ops,
729    },
730};
731
732static struct static_clk jz_clk_rtc = {
733    .clk = {
734        .name = "rtc",
735        .gate_bit = JZ_CLOCK_GATE_RTC,
736        .ops = &jz_clk_static_ops,
737    },
738    .rate = 32768,
739};
740
741int clk_enable(struct clk *clk)
742{
743    if (!clk->ops->enable)
744        return -EINVAL;
745
746    return clk->ops->enable(clk);
747}
748EXPORT_SYMBOL_GPL(clk_enable);
749
750void clk_disable(struct clk *clk)
751{
752    if (clk->ops->disable)
753        clk->ops->disable(clk);
754}
755EXPORT_SYMBOL_GPL(clk_disable);
756
757int clk_is_enabled(struct clk *clk)
758{
759    if (clk->ops->is_enabled)
760        return clk->ops->is_enabled(clk);
761
762    return 1;
763}
764
765unsigned long clk_get_rate(struct clk *clk)
766{
767    if (clk->ops->get_rate)
768        return clk->ops->get_rate(clk);
769    if (clk->parent)
770        return clk_get_rate(clk->parent);
771
772    return -EINVAL;
773}
774EXPORT_SYMBOL_GPL(clk_get_rate);
775
776int clk_set_rate(struct clk *clk, unsigned long rate)
777{
778    if (!clk->ops->set_rate)
779        return -EINVAL;
780    return clk->ops->set_rate(clk, rate);
781}
782EXPORT_SYMBOL_GPL(clk_set_rate);
783
784long clk_round_rate(struct clk *clk, unsigned long rate)
785{
786    if (clk->ops->round_rate)
787        return clk->ops->round_rate(clk, rate);
788
789    return -EINVAL;
790}
791EXPORT_SYMBOL_GPL(clk_round_rate);
792
793int clk_set_parent(struct clk *clk, struct clk *parent)
794{
795    int ret;
796
797    if (!clk->ops->set_parent)
798        return -EINVAL;
799
800    clk_disable(clk);
801    ret = clk->ops->set_parent(clk, parent);
802    clk_enable(clk);
803
804    jz4740_clock_debugfs_update_parent(clk);
805
806    return ret;
807}
808EXPORT_SYMBOL_GPL(clk_set_parent);
809
810struct clk *clk_get(struct device *dev, const char *name)
811{
812    struct clk *clk;
813
814    list_for_each_entry(clk, &jz_clocks, list) {
815        if (strcmp(clk->name, name) == 0)
816            return clk;
817    }
818    return ERR_PTR(-ENOENT);
819}
820EXPORT_SYMBOL_GPL(clk_get);
821
822void clk_put(struct clk *clk)
823{
824}
825EXPORT_SYMBOL_GPL(clk_put);
826
827
828static inline void clk_add(struct clk *clk)
829{
830    list_add_tail(&clk->list, &jz_clocks);
831
832    jz4740_clock_debugfs_add_clk(clk);
833}
834
835static void clk_register_clks(void)
836{
837    size_t i;
838
839    clk_add(&jz_clk_ext.clk);
840    clk_add(&jz_clk_pll);
841    clk_add(&jz_clk_pll_half);
842    clk_add(&jz_clk_cpu.clk);
843    clk_add(&jz_clk_high_speed_peripheral.clk);
844    clk_add(&jz_clk_low_speed_peripheral.clk);
845    clk_add(&jz_clk_ko);
846    clk_add(&jz_clk_ld);
847    clk_add(&jz_clk_cim_mclk);
848    clk_add(&jz_clk_cim_pclk.clk);
849    clk_add(&jz_clk_rtc.clk);
850
851    for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
852        clk_add(&jz4740_clock_divided_clks[i].clk);
853
854    for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
855        clk_add(&jz4740_clock_simple_clks[i]);
856}
857
858void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
859{
860    switch (mode) {
861    case JZ4740_WAIT_MODE_IDLE:
862        jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
863        break;
864    case JZ4740_WAIT_MODE_SLEEP:
865        jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
866        break;
867    }
868}
869
870void jz4740_clock_udc_disable_auto_suspend(void)
871{
872    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
873}
874EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
875
876void jz4740_clock_udc_enable_auto_suspend(void)
877{
878    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
879}
880EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
881
882void jz4740_clock_suspend(void)
883{
884    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
885        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
886
887    jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
888}
889
890void jz4740_clock_resume(void)
891{
892    uint32_t pll;
893
894    jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
895
896    do {
897        pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
898    } while (!(pll & JZ_CLOCK_PLL_STABLE));
899
900    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
901        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
902}
903
904int jz4740_clock_init(void)
905{
906    uint32_t val;
907
908    jz_clock_base = ioremap(CPHYSADDR(JZ4740_CPM_BASE_ADDR), 0x100);
909    if (!jz_clock_base)
910        return -EBUSY;
911
912    spin_lock_init(&jz_clock_lock);
913
914    jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
915    jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
916
917    val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
918
919    if (val & JZ_CLOCK_SPI_SRC_PLL)
920        jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
921
922    val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
923
924    if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
925        jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
926
927    if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
928        jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
929
930    jz4740_clock_debugfs_init();
931
932    clk_register_clks();
933
934    return 0;
935}
arch/mips/jz4740/clock.h
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC clock support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __JZ4740_CLOCK_H__
17#define __JZ4740_CLOCK_H__
18
19struct jz4740_clock_board_data {
20    unsigned long ext_rate;
21    unsigned long rtc_rate;
22};
23
24extern struct jz4740_clock_board_data jz4740_clock_bdata;
25
26int jz4740_clock_init(void);
27void jz4740_clock_suspend(void);
28void jz4740_clock_resume(void);
29
30struct clk;
31
32struct clk_ops {
33    unsigned long (*get_rate)(struct clk *clk);
34    unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
35    int (*set_rate)(struct clk *clk, unsigned long rate);
36    int (*enable)(struct clk *clk);
37    int (*disable)(struct clk *clk);
38    int (*is_enabled)(struct clk *clk);
39
40    int (*set_parent)(struct clk *clk, struct clk *parent);
41
42};
43
44struct clk {
45    const char *name;
46    struct clk *parent;
47
48    uint32_t gate_bit;
49
50    const struct clk_ops *ops;
51
52    struct list_head list;
53
54#ifdef CONFIG_DEBUG_FS
55    struct dentry *debugfs_entry;
56    struct dentry *debugfs_parent_entry;
57#endif
58
59};
60
61#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
62
63int clk_is_enabled(struct clk *clk);
64
65#ifdef CONFIG_DEBUG_FS
66void jz4740_clock_debugfs_init(void);
67void jz4740_clock_debugfs_add_clk(struct clk *clk);
68void jz4740_clock_debugfs_update_parent(struct clk *clk);
69#else
70static inline void jz4740_clock_debugfs_init(void) {};
71static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
72static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
73#endif
74
75#endif
arch/mips/jz4740/dma.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC DMA support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/spinlock.h>
19#include <linux/interrupt.h>
20
21#include <linux/dma-mapping.h>
22#include <asm/mach-jz4740/dma.h>
23#include <asm/mach-jz4740/base.h>
24
25#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
26#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
27#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
28#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
29#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
30#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
31#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
32
33#define JZ_REG_DMA_CTRL 0x300
34#define JZ_REG_DMA_IRQ 0x304
35#define JZ_REG_DMA_DOORBELL 0x308
36#define JZ_REG_DMA_DOORBELL_SET 0x30C
37
38#define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31)
39#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
40#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
41#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
42#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
43#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
44#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
45
46#define JZ_DMA_CMD_SRC_INC BIT(23)
47#define JZ_DMA_CMD_DST_INC BIT(22)
48#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
49#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
50#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
51#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
52#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
53#define JZ_DMA_CMD_DESC_VALID BIT(4)
54#define JZ_DMA_CMD_DESC_VALID_MODE BIT(3)
55#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2)
56#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1)
57#define JZ_DMA_CMD_LINK_ENABLE BIT(0)
58
59#define JZ_DMA_CMD_FLAGS_OFFSET 22
60#define JZ_DMA_CMD_RDIL_OFFSET 16
61#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
62#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
63#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
64#define JZ_DMA_CMD_MODE_OFFSET 7
65
66#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
67#define JZ_DMA_CTRL_HALT BIT(3)
68#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
69#define JZ_DMA_CTRL_ENABLE BIT(0)
70
71
72static void __iomem *jz4740_dma_base;
73static spinlock_t jz4740_dma_lock;
74
75static inline uint32_t jz4740_dma_read(size_t reg)
76{
77    return readl(jz4740_dma_base + reg);
78}
79
80static inline void jz4740_dma_write(size_t reg, uint32_t val)
81{
82    writel(val, jz4740_dma_base + reg);
83}
84
85static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
86{
87    uint32_t val2;
88    val2 = jz4740_dma_read(reg);
89    val2 &= ~mask;
90    val2 |= val;
91    jz4740_dma_write(reg, val2);
92}
93
94struct jz4740_dma_chan {
95    unsigned int id;
96    void *dev;
97    const char *name;
98
99    enum jz4740_dma_flags flags;
100    uint32_t transfer_shift;
101
102    jz4740_dma_complete_callback_t complete_cb;
103
104    unsigned used:1;
105};
106
107#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
108
109struct jz4740_dma_chan jz4740_dma_channels[] = {
110    JZ4740_DMA_CHANNEL(0),
111    JZ4740_DMA_CHANNEL(1),
112    JZ4740_DMA_CHANNEL(2),
113    JZ4740_DMA_CHANNEL(3),
114    JZ4740_DMA_CHANNEL(4),
115    JZ4740_DMA_CHANNEL(5),
116};
117
118struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
119{
120    unsigned int i;
121    struct jz4740_dma_chan *dma = NULL;
122
123    spin_lock(&jz4740_dma_lock);
124
125    for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
126        if (!jz4740_dma_channels[i].used) {
127            dma = &jz4740_dma_channels[i];
128            dma->used = 1;
129            break;
130        }
131    }
132
133    spin_unlock(&jz4740_dma_lock);
134
135    if (!dma)
136        return NULL;
137
138    dma->dev = dev;
139    dma->name = name;
140
141    return dma;
142}
143EXPORT_SYMBOL_GPL(jz4740_dma_request);
144
145void jz4740_dma_configure(struct jz4740_dma_chan *dma,
146    const struct jz4740_dma_config *config)
147{
148    uint32_t cmd;
149    uint32_t ctrl;
150
151    switch (config->transfer_size) {
152    case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
153        dma->transfer_shift = 1;
154        break;
155    case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
156        dma->transfer_shift = 2;
157        break;
158    case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
159        dma->transfer_shift = 4;
160        break;
161    case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
162        dma->transfer_shift = 5;
163        break;
164    default:
165        dma->transfer_shift = 0;
166        break;
167    }
168
169    cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
170    cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
171    cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
172    cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
173    cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
174    cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
175
176    ctrl = JZ_DMA_STATUS_CTRL_NO_DESC;
177    ctrl |= JZ_DMA_STATUS_CTRL_HALT;
178
179    jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
180    jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), ctrl);
181    jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
182}
183EXPORT_SYMBOL_GPL(jz4740_dma_configure);
184
185void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
186{
187    jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
188}
189EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
190
191void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
192{
193    jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
194}
195EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
196
197void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
198{
199    count >>= dma->transfer_shift;
200    jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
201}
202EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
203
204void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
205    jz4740_dma_complete_callback_t cb)
206{
207    dma->complete_cb = cb;
208}
209EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
210
211void jz4740_dma_free(struct jz4740_dma_chan *dma)
212{
213    dma->dev = NULL;
214    dma->complete_cb = NULL;
215    dma->used = 0;
216}
217EXPORT_SYMBOL_GPL(jz4740_dma_free);
218
219void jz4740_dma_enable(struct jz4740_dma_chan *dma)
220{
221    jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
222            JZ_DMA_STATUS_CTRL_ENABLE,
223            JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_HALT);
224
225    jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
226            JZ_DMA_CTRL_ENABLE,
227            JZ_DMA_CTRL_ENABLE | JZ_DMA_CTRL_HALT);
228}
229EXPORT_SYMBOL_GPL(jz4740_dma_enable);
230
231void jz4740_dma_disable(struct jz4740_dma_chan *dma)
232{
233    jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
234            JZ_DMA_STATUS_CTRL_ENABLE);
235}
236EXPORT_SYMBOL_GPL(jz4740_dma_disable);
237
238uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
239{
240    uint32_t residue;
241    residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
242    return residue << dma->transfer_shift;
243}
244EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
245
246static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
247{
248    uint32_t status;
249
250    status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
251
252    jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
253        JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
254
255    if (dma->complete_cb)
256        dma->complete_cb(dma, 0, dma->dev);
257}
258
259static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
260{
261    uint32_t irq_status;
262    unsigned int i;
263
264    irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
265
266    for (i = 0; i < 6; ++i) {
267        if (irq_status & (1 << i))
268            jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
269    }
270
271    return IRQ_HANDLED;
272}
273
274#if 0
275static struct jz4740_dma_config dma_test_config = {
276    .src_width = JZ4740_DMA_WIDTH_32BIT,
277    .dst_width = JZ4740_DMA_WIDTH_32BIT,
278    .transfer_size = JZ4740_DMA_TRANSFER_SIZE_4BYTE,
279    .request_type = JZ4740_DMA_TYPE_AUTO_REQUEST,
280    .flags = JZ4740_DMA_SRC_AUTOINC | JZ4740_DMA_DST_AUTOINC,
281    .mode = JZ4740_DMA_MODE_BLOCK,
282};
283
284static void jz4740_dma_test(void)
285{
286    uint32_t *buf1, *buf2;
287    dma_addr_t addr1, addr2;
288    struct jz4740_dma_chan *dma = jz4740_dma_request(NULL, "dma test");
289    int i;
290
291    printk("STARTING DMA TEST\n");
292
293    buf1 = dma_alloc_coherent(NULL,
294                        0x1000,
295                        &addr1, GFP_KERNEL);
296    buf2 = dma_alloc_coherent(NULL,
297                        0x1000,
298                        &addr2, GFP_KERNEL);
299
300    for (i = 0; i < 0x400; ++i)
301        buf1[i] = i;
302
303
304    jz4740_dma_configure(dma, &dma_test_config);
305    jz4740_dma_set_src_addr(dma, addr1);
306    jz4740_dma_set_dst_addr(dma, addr2);
307    jz4740_dma_set_transfer_count(dma, 0x1000);
308
309    jz4740_dma_enable(dma);
310    mdelay(2000);
311
312    for (i = 0; i < 0x400; ++i) {
313        if (buf2[i] != i)
314            printk("OH MY GOD: %x %x\n", i, buf2[i]);
315    }
316
317    printk("DMA TEST DONE\n");
318}
319#endif
320
321static int jz4740_dma_init(void)
322{
323    unsigned int ret;
324
325    jz4740_dma_base = ioremap(CPHYSADDR(JZ4740_DMAC_BASE_ADDR), 0x400);
326
327    if (!jz4740_dma_base)
328        return -EBUSY;
329
330    spin_lock_init(&jz4740_dma_lock);
331
332    ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
333
334    if (ret)
335        printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
336
337    return ret;
338}
339arch_initcall(jz4740_dma_init);
arch/mips/jz4740/gpio.c
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform GPIO support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19
20#include <linux/spinlock.h>
21#include <linux/sysdev.h>
22#include <linux/io.h>
23#include <linux/gpio.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/bitops.h>
27
28#include <linux/debugfs.h>
29#include <linux/seq_file.h>
30
31#include <asm/mach-jz4740/base.h>
32
33#define JZ4740_GPIO_BASE_A (32*0)
34#define JZ4740_GPIO_BASE_B (32*1)
35#define JZ4740_GPIO_BASE_C (32*2)
36#define JZ4740_GPIO_BASE_D (32*3)
37
38#define JZ4740_GPIO_NUM_A 32
39#define JZ4740_GPIO_NUM_B 32
40#define JZ4740_GPIO_NUM_C 31
41#define JZ4740_GPIO_NUM_D 32
42
43#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
44#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
45#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
46#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
47
48#define JZ4740_IRQ_GPIO_A(num) (JZ4740_IRQ_GPIO_BASE_A + num)
49#define JZ4740_IRQ_GPIO_B(num) (JZ4740_IRQ_GPIO_BASE_B + num)
50#define JZ4740_IRQ_GPIO_C(num) (JZ4740_IRQ_GPIO_BASE_C + num)
51#define JZ4740_IRQ_GPIO_D(num) (JZ4740_IRQ_GPIO_BASE_D + num)
52
53#define JZ_REG_GPIO_PIN 0x00
54#define JZ_REG_GPIO_DATA 0x10
55#define JZ_REG_GPIO_DATA_SET 0x14
56#define JZ_REG_GPIO_DATA_CLEAR 0x18
57#define JZ_REG_GPIO_MASK 0x20
58#define JZ_REG_GPIO_MASK_SET 0x24
59#define JZ_REG_GPIO_MASK_CLEAR 0x28
60#define JZ_REG_GPIO_PULL 0x30
61#define JZ_REG_GPIO_PULL_SET 0x34
62#define JZ_REG_GPIO_PULL_CLEAR 0x38
63#define JZ_REG_GPIO_FUNC 0x40
64#define JZ_REG_GPIO_FUNC_SET 0x44
65#define JZ_REG_GPIO_FUNC_CLEAR 0x48
66#define JZ_REG_GPIO_SELECT 0x50
67#define JZ_REG_GPIO_SELECT_SET 0x54
68#define JZ_REG_GPIO_SELECT_CLEAR 0x58
69#define JZ_REG_GPIO_DIRECTION 0x60
70#define JZ_REG_GPIO_DIRECTION_SET 0x64
71#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
72#define JZ_REG_GPIO_TRIGGER 0x70
73#define JZ_REG_GPIO_TRIGGER_SET 0x74
74#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
75#define JZ_REG_GPIO_FLAG 0x80
76#define JZ_REG_GPIO_FLAG_CLEAR 0x14
77
78
79#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
80#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
81#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
82
83struct jz_gpio_chip {
84    unsigned int irq;
85    unsigned int irq_base;
86    uint32_t wakeup;
87    uint32_t suspend_mask;
88    uint32_t edge_trigger_both;
89
90    void __iomem *base;
91
92    spinlock_t lock;
93
94    struct gpio_chip gpio_chip;
95    struct irq_chip irq_chip;
96    struct sys_device sysdev;
97};
98
99
100static struct jz_gpio_chip jz4740_gpio_chips[];
101
102static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
103{
104    return &jz4740_gpio_chips[gpio >> 5];
105}
106
107static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
108{
109    return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
110}
111
112static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
113{
114    return get_irq_chip_data(irq);
115}
116
117static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
118{
119    writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
120}
121
122int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
123{
124    if (function == JZ_GPIO_FUNC_NONE) {
125        jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
126        jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
127        jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
128    } else {
129        jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
130        jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
131        switch (function) {
132        case JZ_GPIO_FUNC1:
133            jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
134            break;
135        case JZ_GPIO_FUNC3:
136            jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
137        case JZ_GPIO_FUNC2: /* Falltrough */
138            jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
139            break;
140        default:
141            BUG();
142            break;
143        }
144    }
145
146    return 0;
147}
148EXPORT_SYMBOL_GPL(jz_gpio_set_function);
149
150int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
151{
152    size_t i;
153    int ret;
154
155    for (i = 0; i < num; ++i, ++request) {
156        ret = gpio_request(request->gpio, request->name);
157        if (ret)
158            goto err;
159        jz_gpio_set_function(request->gpio, request->function);
160    }
161
162    return 0;
163
164err:
165    for (--request; i > 0; --i, --request) {
166        gpio_free(request->gpio);
167        jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
168    }
169
170    return ret;
171}
172EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
173
174void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
175{
176    size_t i;
177
178    for (i = 0; i < num; ++i, ++request) {
179        gpio_free(request->gpio);
180        jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
181    }
182
183}
184EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
185
186void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
187{
188    size_t i;
189
190    for (i = 0; i < num; ++i, ++request) {
191        jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
192        jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
193        jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
194    }
195}
196EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
197
198void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
199{
200    size_t i;
201
202    for (i = 0; i < num; ++i, ++request)
203        jz_gpio_set_function(request->gpio, request->function);
204}
205EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
206
207void jz_gpio_enable_pullup(unsigned gpio)
208{
209    jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
210}
211EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
212
213void jz_gpio_disable_pullup(unsigned gpio)
214{
215    jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
216}
217EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
218
219static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
220{
221    return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
222}
223
224static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
225{
226    uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
227    reg += !value;
228    writel(BIT(gpio), reg);
229}
230
231static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
232    int value)
233{
234    writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
235    jz_gpio_set_value(chip, gpio, value);
236
237    return 0;
238}
239
240static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
241{
242    writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
243
244    return 0;
245}
246
247int jz_gpio_port_direction_input(int port, uint32_t mask)
248{
249    writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
250
251    return 0;
252}
253EXPORT_SYMBOL(jz_gpio_port_direction_input);
254
255int jz_gpio_port_direction_output(int port, uint32_t mask)
256{
257    writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
258
259    return 0;
260}
261EXPORT_SYMBOL(jz_gpio_port_direction_output);
262
263void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
264{
265    writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
266    writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
267}
268EXPORT_SYMBOL(jz_gpio_port_set_value);
269
270uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
271{
272    uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
273
274    return value & mask;
275}
276EXPORT_SYMBOL(jz_gpio_port_get_value);
277
278
279#define IRQ_TO_GPIO(irq) (irq - JZ4740_IRQ_GPIO(0))
280#define IRQ_TO_BIT(irq) BIT(IRQ_TO_GPIO(irq) & 0x1f)
281
282#define IRQ_TO_REG(irq, reg) GPIO_TO_REG(IRQ_TO_GPIO(irq), reg)
283
284static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
285{
286    uint32_t flag;
287    unsigned int gpio_irq;
288    unsigned int gpio_bank;
289    struct jz_gpio_chip *chip = get_irq_desc_data(desc);
290
291    gpio_bank = JZ4740_IRQ_GPIO0 - irq;
292
293    flag = readl(chip->base + JZ_REG_GPIO_FLAG);
294
295    gpio_irq = ffs(flag) - 1;
296
297    if (chip->edge_trigger_both & BIT(gpio_irq)) {
298        uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
299        if (value & BIT(gpio_irq)) {
300            writel(BIT(gpio_irq),
301                chip->base + JZ_REG_GPIO_DIRECTION_CLEAR);
302        } else {
303            writel(BIT(gpio_irq),
304                chip->base + JZ_REG_GPIO_DIRECTION_SET);
305        }
306    }
307
308    gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
309
310    generic_handle_irq(gpio_irq);
311};
312
313static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
314{
315    writel(IRQ_TO_BIT(irq), IRQ_TO_REG(irq, reg));
316}
317
318static void jz_gpio_irq_mask(unsigned int irq)
319{
320    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
321};
322
323static void jz_gpio_irq_unmask(unsigned int irq)
324{
325    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
326};
327
328
329/* TODO: Check if function is gpio */
330static unsigned int jz_gpio_irq_startup(unsigned int irq)
331{
332    struct irq_desc *desc = irq_to_desc(irq);
333
334    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
335
336    desc->status &= ~IRQ_MASKED;
337    jz_gpio_irq_unmask(irq);
338
339    return 0;
340}
341
342static void jz_gpio_irq_shutdown(unsigned int irq)
343{
344    struct irq_desc *desc = irq_to_desc(irq);
345
346    jz_gpio_irq_mask(irq);
347    desc->status |= IRQ_MASKED;
348
349    /* Set direction to input */
350    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
351    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
352}
353
354static void jz_gpio_irq_ack(unsigned int irq)
355{
356    jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
357};
358
359static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
360{
361    struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
362    struct irq_desc *desc = irq_to_desc(irq);
363
364    jz_gpio_irq_mask(irq);
365
366    if (flow_type == IRQ_TYPE_EDGE_BOTH) {
367        uint32_t value = readl(IRQ_TO_REG(irq, JZ_REG_GPIO_PIN));
368        if (value & IRQ_TO_BIT(irq))
369            flow_type = IRQ_TYPE_EDGE_FALLING;
370        else
371            flow_type = IRQ_TYPE_EDGE_RISING;
372        chip->edge_trigger_both |= IRQ_TO_BIT(irq);
373    } else {
374        chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
375    }
376
377    switch (flow_type) {
378    case IRQ_TYPE_EDGE_RISING:
379        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
380        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
381        break;
382    case IRQ_TYPE_EDGE_FALLING:
383        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
384        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
385        break;
386    case IRQ_TYPE_LEVEL_HIGH:
387        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
388        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
389        break;
390    case IRQ_TYPE_LEVEL_LOW:
391        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
392        jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
393        break;
394    default:
395        return -EINVAL;
396    }
397
398    if (!(desc->status & IRQ_MASKED))
399        jz_gpio_irq_unmask(irq);
400
401    return 0;
402}
403
404static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
405{
406    struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
407    spin_lock(&chip->lock);
408    if (on)
409        chip->wakeup |= IRQ_TO_BIT(irq);
410    else
411        chip->wakeup &= ~IRQ_TO_BIT(irq);
412    spin_unlock(&chip->lock);
413
414    set_irq_wake(chip->irq, !!(chip->wakeup));
415    return 0;
416}
417
418int gpio_to_irq(unsigned gpio)
419{
420    return JZ4740_IRQ_GPIO(0) + gpio;
421}
422EXPORT_SYMBOL_GPL(gpio_to_irq);
423
424int irq_to_gpio(unsigned gpio)
425{
426    return IRQ_TO_GPIO(gpio);
427}
428EXPORT_SYMBOL_GPL(irq_to_gpio);
429
430#define JZ4740_GPIO_CHIP(_bank) { \
431    .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
432    .gpio_chip = { \
433        .label = "Bank " # _bank, \
434        .owner = THIS_MODULE, \
435        .set = jz_gpio_set_value, \
436        .get = jz_gpio_get_value, \
437        .direction_output = jz_gpio_direction_output, \
438        .direction_input = jz_gpio_direction_input, \
439        .base = JZ4740_GPIO_BASE_ ## _bank, \
440        .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
441    }, \
442    .irq_chip = { \
443        .name = "GPIO Bank " # _bank, \
444        .mask = jz_gpio_irq_mask, \
445        .unmask = jz_gpio_irq_unmask, \
446        .ack = jz_gpio_irq_ack, \
447        .startup = jz_gpio_irq_startup, \
448        .shutdown = jz_gpio_irq_shutdown, \
449        .set_type = jz_gpio_irq_set_type, \
450        .set_wake = jz_gpio_irq_set_wake, \
451    }, \
452}
453
454static struct jz_gpio_chip jz4740_gpio_chips[] = {
455    JZ4740_GPIO_CHIP(A),
456    JZ4740_GPIO_CHIP(B),
457    JZ4740_GPIO_CHIP(C),
458    JZ4740_GPIO_CHIP(D),
459};
460
461static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
462{
463    return container_of(dev, struct jz_gpio_chip, sysdev);
464}
465
466static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
467{
468    struct jz_gpio_chip *chip = sysdev_to_chip(dev);
469
470    chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
471    writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
472    writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
473
474    return 0;
475}
476
477static int jz4740_gpio_resume(struct sys_device *dev)
478{
479    struct jz_gpio_chip *chip = sysdev_to_chip(dev);
480    uint32_t mask = chip->suspend_mask;
481
482    writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
483    writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
484
485    return 0;
486}
487
488static struct sysdev_class jz4740_gpio_sysdev_class = {
489    .name = "gpio",
490    .suspend = jz4740_gpio_suspend,
491    .resume = jz4740_gpio_resume,
492};
493
494static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
495{
496    int ret, irq;
497
498    chip->sysdev.id = id;
499    chip->sysdev.cls = &jz4740_gpio_sysdev_class;
500    ret = sysdev_register(&chip->sysdev);
501
502    if (ret)
503        return ret;
504
505    spin_lock_init(&chip->lock);
506
507    chip->base = ioremap(CPHYSADDR(JZ4740_GPIO_BASE_ADDR) + (id * 0x100), 0x100);
508
509    gpiochip_add(&chip->gpio_chip);
510
511    chip->irq = JZ4740_IRQ_INTC_GPIO(id);
512    set_irq_data(chip->irq, chip);
513    set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
514
515    for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
516        set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
517        set_irq_chip_data(irq, chip);
518    }
519
520    return 0;
521}
522
523int __init jz_gpiolib_init(void)
524{
525    unsigned int i;
526    int ret;
527
528    ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
529    if (ret)
530        return ret;
531
532    for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) {
533        jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
534    }
535
536    printk(KERN_INFO "JZ4740 GPIO initalized\n");
537
538    return 0;
539}
540
541#ifdef CONFIG_DEBUG_FS
542
543static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
544    const char *name, unsigned int reg)
545{
546    seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
547}
548
549
550static int gpio_regs_show(struct seq_file *s, void *unused)
551{
552    struct jz_gpio_chip *chip = jz4740_gpio_chips;
553    int i;
554
555    for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
556        seq_printf(s, "GPIO %d: \n", i);
557        gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
558        gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
559        gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
560        gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
561        gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
562        gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
563        gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
564        gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
565        gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
566    }
567
568    return 0;
569}
570
571static int gpio_regs_open(struct inode *inode, struct file *file)
572{
573    return single_open(file, gpio_regs_show, NULL);
574}
575
576static const struct file_operations gpio_regs_operations = {
577    .open = gpio_regs_open,
578    .read = seq_read,
579    .llseek = seq_lseek,
580    .release = single_release,
581};
582
583static int __init gpio_debugfs_init(void)
584{
585    (void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
586                NULL, NULL, &gpio_regs_operations);
587    return 0;
588}
589subsys_initcall(gpio_debugfs_init);
590
591#endif
arch/mips/jz4740/irq.c
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform IRQ support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/types.h>
19#include <linux/interrupt.h>
20#include <linux/ioport.h>
21#include <linux/timex.h>
22#include <linux/slab.h>
23#include <linux/delay.h>
24
25#include <linux/debugfs.h>
26#include <linux/seq_file.h>
27
28#include <asm/io.h>
29#include <asm/mipsregs.h>
30#include <asm/irq_cpu.h>
31
32#include <asm/mach-jz4740/base.h>
33
34static void __iomem *jz_intc_base;
35static uint32_t jz_intc_wakeup;
36static uint32_t jz_intc_saved;
37
38#define JZ_REG_INTC_STATUS 0x00
39#define JZ_REG_INTC_MASK 0x04
40#define JZ_REG_INTC_SET_MASK 0x08
41#define JZ_REG_INTC_CLEAR_MASK 0x0c
42#define JZ_REG_INTC_PENDING 0x10
43
44#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
45
46static void intc_irq_unmask(unsigned int irq)
47{
48    writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
49}
50
51static void intc_irq_mask(unsigned int irq)
52{
53    writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
54}
55
56static void intc_irq_ack(unsigned int irq)
57{
58    writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_PENDING);
59}
60
61static int intc_irq_set_wake(unsigned int irq, unsigned int on)
62{
63    if (on)
64        jz_intc_wakeup |= IRQ_BIT(irq);
65    else
66        jz_intc_wakeup &= ~IRQ_BIT(irq);
67
68    return 0;
69}
70
71static struct irq_chip intc_irq_type = {
72    .name = "INTC",
73    .mask = intc_irq_mask,
74    .unmask = intc_irq_unmask,
75    .ack = intc_irq_ack,
76    .set_wake = intc_irq_set_wake,
77};
78
79static irqreturn_t jz4740_cascade(int irq, void *data)
80{
81    uint32_t irq_reg;
82
83    irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
84    generic_handle_irq(ffs(irq_reg) - 1 + JZ4740_IRQ_BASE);
85
86    return IRQ_HANDLED;
87}
88
89static struct irqaction jz4740_cascade_action = {
90    .handler = jz4740_cascade,
91    .name = "JZ4740 cascade interrupt",
92    .flags = IRQF_DISABLED,
93};
94
95void __init arch_init_irq(void)
96{
97    int i;
98    mips_cpu_irq_init();
99
100    jz_intc_base = ioremap(CPHYSADDR(JZ4740_INTC_BASE_ADDR), 0x14);
101
102    for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
103        intc_irq_mask(i);
104        set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
105    }
106
107    setup_irq(2, &jz4740_cascade_action);
108}
109
110asmlinkage void plat_irq_dispatch(void)
111{
112    unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
113    if (pending & STATUSF_IP2)
114        do_IRQ(2);
115    else if (pending & STATUSF_IP3)
116        do_IRQ(3);
117    else
118        spurious_interrupt();
119}
120
121void jz4740_intc_suspend(void)
122{
123    jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
124    writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
125    writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
126}
127
128void jz4740_intc_resume(void)
129{
130    writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
131    writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
132}
133
134#ifdef CONFIG_DEBUG_FS
135
136static inline void intc_seq_reg(struct seq_file *s, const char *name,
137    unsigned int reg)
138{
139    seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
140}
141
142static int intc_regs_show(struct seq_file *s, void *unused)
143{
144    intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
145    intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
146    intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
147
148    return 0;
149}
150
151static int intc_regs_open(struct inode *inode, struct file *file)
152{
153    return single_open(file, intc_regs_show, NULL);
154}
155
156static const struct file_operations intc_regs_operations = {
157    .open = intc_regs_open,
158    .read = seq_read,
159    .llseek = seq_lseek,
160    .release = single_release,
161};
162
163static int __init intc_debugfs_init(void)
164{
165    (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
166                NULL, NULL, &intc_regs_operations);
167    return 0;
168}
169subsys_initcall(intc_debugfs_init);
170
171#endif
arch/mips/jz4740/irq.h
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * You should have received a copy of the GNU General Public License along
10 * with this program; if not, write to the Free Software Foundation, Inc.,
11 * 675 Mass Ave, Cambridge, MA 02139, USA.
12 *
13 */
14
15#ifndef __MIPS_JZ4740_IRQ_H__
16#define __MIPS_JZ4740_IRQ_H__
17
18extern void jz4740_intc_suspend(void);
19extern void jz4740_intc_resume(void);
20
21#endif
arch/mips/jz4740/platform.c
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform devices
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/device.h>
17#include <linux/platform_device.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/resource.h>
21
22#include <asm/mach-jz4740/platform.h>
23#include <asm/mach-jz4740/base.h>
24#include <asm/mach-jz4740/irq.h>
25
26/* OHCI (USB full speed host controller) */
27static struct resource jz4740_usb_ohci_resources[] = {
28    [0] = {
29        .start = CPHYSADDR(JZ4740_UHC_BASE_ADDR),
30        .end = CPHYSADDR(JZ4740_UHC_BASE_ADDR) + 0x10000 - 1,
31        .flags = IORESOURCE_MEM,
32    },
33    [1] = {
34        .start = JZ4740_IRQ_UHC,
35        .end = JZ4740_IRQ_UHC,
36        .flags = IORESOURCE_IRQ,
37    },
38};
39
40/* The dmamask must be set for OHCI to work */
41static u64 ohci_dmamask = ~(u32)0;
42
43struct platform_device jz4740_usb_ohci_device = {
44    .name = "jz4740-ohci",
45    .id = -1,
46    .dev = {
47        .dma_mask = &ohci_dmamask,
48        .coherent_dma_mask = 0xffffffff,
49    },
50    .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources),
51    .resource = jz4740_usb_ohci_resources,
52};
53
54/* UDC (USB gadget controller) */
55static struct resource jz4740_usb_gdt_resources[] = {
56    [0] = {
57        .start = CPHYSADDR(JZ4740_UDC_BASE_ADDR),
58        .end = CPHYSADDR(JZ4740_UDC_BASE_ADDR) + 0x10000 - 1,
59        .flags = IORESOURCE_MEM,
60    },
61    [1] = {
62        .start = JZ4740_IRQ_UDC,
63        .end = JZ4740_IRQ_UDC,
64        .flags = IORESOURCE_IRQ,
65    },
66};
67
68static u64 jz4740_udc_dmamask = ~(u32)0;
69
70struct platform_device jz4740_usb_gdt_device = {
71    .name = "jz-udc",
72    .id = -1,
73    .dev = {
74        .dma_mask = &jz4740_udc_dmamask,
75        .coherent_dma_mask = 0xffffffff,
76    },
77    .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources),
78    .resource = jz4740_usb_gdt_resources,
79};
80
81/** MMC/SD controller **/
82static struct resource jz4740_mmc_resources[] = {
83    [0] = {
84        .start = CPHYSADDR(JZ4740_MSC_BASE_ADDR),
85        .end = CPHYSADDR(JZ4740_MSC_BASE_ADDR) + 0x10000 - 1,
86        .flags = IORESOURCE_MEM,
87    },
88    [1] = {
89        .start = JZ4740_IRQ_MSC,
90        .end = JZ4740_IRQ_MSC,
91        .flags = IORESOURCE_IRQ,
92    }
93};
94
95static u64 jz4740_mmc_dmamask = ~(u32)0;
96
97struct platform_device jz4740_mmc_device = {
98    .name = "jz4740-mmc",
99    .id = 0,
100    .dev = {
101        .dma_mask = &jz4740_mmc_dmamask,
102        .coherent_dma_mask = 0xffffffff,
103    },
104    .num_resources = ARRAY_SIZE(jz4740_mmc_resources),
105    .resource = jz4740_mmc_resources,
106};
107
108static struct resource jz4740_rtc_resources[] = {
109    [0] = {
110        .start = CPHYSADDR(JZ4740_RTC_BASE_ADDR),
111        .end = CPHYSADDR(JZ4740_RTC_BASE_ADDR) + 0x38 - 1,
112        .flags = IORESOURCE_MEM,
113    },
114    [1] = {
115        .start = JZ4740_IRQ_RTC,
116        .end = JZ4740_IRQ_RTC,
117        .flags = IORESOURCE_IRQ,
118    },
119};
120
121struct platform_device jz4740_rtc_device = {
122    .name = "jz4740-rtc",
123    .id = -1,
124    .num_resources = ARRAY_SIZE(jz4740_rtc_resources),
125    .resource = jz4740_rtc_resources,
126};
127
128/** I2C controller **/
129static struct resource jz4740_i2c_resources[] = {
130    [0] = {
131        .start = CPHYSADDR(JZ4740_I2C_BASE_ADDR),
132        .end = CPHYSADDR(JZ4740_I2C_BASE_ADDR) + 0x10000 - 1,
133        .flags = IORESOURCE_MEM,
134    },
135    [1] = {
136        .start = JZ4740_IRQ_I2C,
137        .end = JZ4740_IRQ_I2C,
138        .flags = IORESOURCE_IRQ,
139    }
140};
141
142static u64 jz4740_i2c_dmamask = ~(u32)0;
143
144struct platform_device jz4740_i2c_device = {
145    .name = "jz_i2c",
146    .id = 0,
147    .dev = {
148        .dma_mask = &jz4740_i2c_dmamask,
149        .coherent_dma_mask = 0xffffffff,
150    },
151    .num_resources = ARRAY_SIZE(jz4740_i2c_resources),
152    .resource = jz4740_i2c_resources,
153};
154
155static struct resource jz4740_nand_resources[] = {
156    [0] = {
157        .start = CPHYSADDR(JZ4740_EMC_BASE_ADDR),
158        .end = CPHYSADDR(JZ4740_EMC_BASE_ADDR) + 0x10000 - 1,
159        .flags = IORESOURCE_MEM,
160    },
161};
162
163struct platform_device jz4740_nand_device = {
164    .name = "jz4740-nand",
165    .num_resources = ARRAY_SIZE(jz4740_nand_resources),
166    .resource = jz4740_nand_resources,
167};
168
169static struct resource jz4740_framebuffer_resources[] = {
170    [0] = {
171        .start = CPHYSADDR(JZ4740_LCD_BASE_ADDR),
172        .end = CPHYSADDR(JZ4740_LCD_BASE_ADDR) + 0x10000 - 1,
173        .flags = IORESOURCE_MEM,
174    },
175};
176
177static u64 jz4740_fb_dmamask = ~(u32)0;
178
179struct platform_device jz4740_framebuffer_device = {
180    .name = "jz4740-fb",
181    .id = -1,
182    .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
183    .resource = jz4740_framebuffer_resources,
184    .dev = {
185        .dma_mask = &jz4740_fb_dmamask,
186        .coherent_dma_mask = 0xffffffff,
187    },
188};
189
190static struct resource jz4740_i2s_resources[] = {
191    [0] = {
192        .start = CPHYSADDR(JZ4740_AIC_BASE_ADDR),
193        .end = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x38 - 1,
194        .flags = IORESOURCE_MEM,
195    },
196};
197
198struct platform_device jz4740_i2s_device = {
199    .name = "jz4740-i2s",
200    .id = -1,
201    .num_resources = ARRAY_SIZE(jz4740_i2s_resources),
202    .resource = jz4740_i2s_resources,
203};
204
205static struct resource jz4740_codec_resources[] = {
206    [0] = {
207        .start = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x80,
208        .end = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x88 - 1,
209        .flags = IORESOURCE_MEM,
210    },
211};
212
213struct platform_device jz4740_codec_device = {
214    .name = "jz4740-codec",
215    .id = -1,
216    .num_resources = ARRAY_SIZE(jz4740_codec_resources),
217    .resource = jz4740_codec_resources,
218};
219
220static struct resource jz4740_adc_resources[] = {
221    [0] = {
222        .start = CPHYSADDR(JZ4740_SADC_BASE_ADDR),
223        .end = CPHYSADDR(JZ4740_SADC_BASE_ADDR) + 0x30,
224        .flags = IORESOURCE_MEM,
225    },
226    [1] = {
227        .start = JZ4740_IRQ_SADC,
228        .end = JZ4740_IRQ_SADC,
229        .flags = IORESOURCE_IRQ,
230    },
231};
232
233struct platform_device jz4740_adc_device = {
234    .name = "jz4740-adc",
235    .id = -1,
236    .num_resources = ARRAY_SIZE(jz4740_adc_resources),
237    .resource = jz4740_adc_resources,
238};
239
240struct platform_device jz4740_battery_device = {
241    .name = "jz4740-battery",
242    .id = -1,
243    .dev = {
244        .parent = &jz4740_adc_device.dev
245    },
246};
arch/mips/jz4740/pm.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC power management support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/pm.h>
18#include <linux/delay.h>
19#include <linux/suspend.h>
20
21#include <asm/mach-jz4740/clock.h>
22
23#include "clock.h"
24#include "irq.h"
25
26static int jz_pm_enter(suspend_state_t state)
27{
28    jz4740_intc_suspend();
29    jz4740_clock_suspend();
30
31    jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
32
33    __asm__(".set\tmips3\n\t"
34        "wait\n\t"
35        ".set\tmips0");
36
37    jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
38
39    jz4740_clock_resume();
40    jz4740_intc_resume();
41
42    return 0;
43}
44
45static struct platform_suspend_ops jz_pm_ops = {
46    .valid = suspend_valid_only_mem,
47    .enter = jz_pm_enter,
48};
49
50/*
51 * Initialize power interface
52 */
53int __init jz_pm_init(void)
54{
55    suspend_set_ops(&jz_pm_ops);
56    return 0;
57
58}
59late_initcall(jz_pm_init);
arch/mips/jz4740/prom.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC prom code
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/string.h>
21
22#include <linux/serial_reg.h>
23
24#include <asm/bootinfo.h>
25#include <asm/mach-jz4740/base.h>
26
27void jz4740_init_cmdline(int argc, char *argv[])
28{
29    unsigned int count = COMMAND_LINE_SIZE - 1;
30    int i;
31    char *dst = &(arcs_cmdline[0]);
32    char *src;
33
34    for (i = 1; i < argc && count; ++i) {
35        src = argv[i];
36        while (*src && count) {
37            *dst++ = *src++;
38            --count;
39        }
40        *dst++ = ' ';
41    }
42    if (i > 1)
43        --dst;
44
45    *dst = 0;
46}
47
48void __init prom_init(void)
49{
50    jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
51    mips_machtype = MACH_INGENIC_JZ4740;
52}
53
54void __init prom_free_prom_memory(void)
55{
56}
57
58#define UART_REG(offset) ((void __iomem*)(JZ4740_UART0_BASE_ADDR + (offset << 2)))
59
60void prom_putchar(char c)
61{
62    uint8_t lsr;
63
64    do {
65        lsr = readb(UART_REG(UART_LSR));
66    } while ((lsr & UART_LSR_TEMT) == 0);
67
68    writeb(c, UART_REG(UART_TX));
69}
arch/mips/jz4740/reset.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * You should have received a copy of the GNU General Public License along
10 * with this program; if not, write to the Free Software Foundation, Inc.,
11 * 675 Mass Ave, Cambridge, MA 02139, USA.
12 *
13 */
14
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <linux/pm.h>
18
19#include <linux/delay.h>
20
21#include <asm/reboot.h>
22
23#include <asm/mach-jz4740/base.h>
24#include <asm/mach-jz4740/timer.h>
25
26static void jz4740_halt(void)
27{
28    while (1) {
29        __asm__(".set push;\n"
30            ".set mips3;\n"
31            "wait;\n"
32            ".set pop;\n"
33        );
34    }
35}
36
37#define JZ_REG_WDT_DATA 0x00
38#define JZ_REG_WDT_COUNTER_ENABLE 0x04
39#define JZ_REG_WDT_COUNTER 0x08
40#define JZ_REG_WDT_CTRL 0x0c
41
42static void jz4740_restart(char *command)
43{
44    void __iomem *wdt_base = ioremap(CPHYSADDR(JZ4740_WDT_BASE_ADDR), 0x0f);
45
46    jz4740_timer_enable_watchdog();
47
48    writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
49
50    writew(0, wdt_base + JZ_REG_WDT_COUNTER);
51    writew(0, wdt_base + JZ_REG_WDT_DATA);
52    writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL);
53
54    writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
55    jz4740_halt();
56}
57
58#define JZ_REG_RTC_CTRL 0x00
59#define JZ_REG_RTC_HIBERNATE 0x20
60
61#define JZ_RTC_CTRL_WRDY BIT(7)
62
63static void jz4740_power_off(void)
64{
65    void __iomem *rtc_base = ioremap(CPHYSADDR(JZ4740_RTC_BASE_ADDR), 0x24);
66    uint32_t ctrl;
67
68    do {
69        ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
70    } while (!(ctrl & JZ_RTC_CTRL_WRDY));
71
72    writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
73    jz4740_halt();
74}
75
76void jz4740_reset_init(void)
77{
78    _machine_restart = jz4740_restart;
79    _machine_halt = jz4740_halt;
80    pm_power_off = jz4740_power_off;
81}
arch/mips/jz4740/reset.h
1#ifndef __MIPS_JZ4740_RESET_H__
2#define __MIPS_JZ4740_RESET_H__
3
4extern void jz4740_reset_init(void);
5
6#endif
7
arch/mips/jz4740/setup.c
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 setup code
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/serial.h>
20#include <linux/serial_core.h>
21#include <linux/serial_8250.h>
22
23#include <asm/mach-jz4740/base.h>
24#include <asm/mach-jz4740/clock.h>
25#include <asm/mach-jz4740/serial.h>
26
27#include "reset.h"
28#include "clock.h"
29
30static void __init jz4740_serial_setup(void)
31{
32#ifdef CONFIG_SERIAL_8250
33    struct uart_port s;
34    memset(&s, 0, sizeof(s));
35    s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
36    s.iotype = SERIAL_IO_MEM;
37    s.regshift = 2;
38    s.uartclk = jz4740_clock_bdata.ext_rate;
39
40    s.line = 0;
41    s.membase = (u8 *)JZ4740_UART0_BASE_ADDR;
42    s.irq = JZ4740_IRQ_UART0;
43    if (early_serial_setup(&s) != 0) {
44        printk(KERN_ERR "Serial ttyS0 setup failed!\n");
45    }
46
47    s.line = 1;
48    s.membase = (u8 *)JZ4740_UART1_BASE_ADDR;
49    s.irq = JZ4740_IRQ_UART1;
50    if (early_serial_setup(&s) != 0) {
51        printk(KERN_ERR "Serial ttyS1 setup failed!\n");
52    }
53#endif
54}
55void __init plat_mem_setup(void)
56{
57    jz4740_reset_init();
58    jz4740_serial_setup();
59}
60
61const char *get_system_type(void)
62{
63    return "JZ4740";
64}
arch/mips/jz4740/time.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform time support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/interrupt.h>
18#include <linux/time.h>
19#include <linux/clockchips.h>
20#include <linux/clk.h>
21
22#include <asm/mach-jz4740/irq.h>
23#include <asm/mach-jz4740/base.h>
24#include <asm/time.h>
25#include "clock.h"
26
27#define JZ_REG_TIMER_STOP 0x1C
28#define JZ_REG_TIMER_STOP_SET 0x2C
29#define JZ_REG_TIMER_STOP_CLEAR 0x3C
30#define JZ_REG_TIMER_ENABLE 0x10
31#define JZ_REG_TIMER_ENABLE_SET 0x14
32#define JZ_REG_TIMER_ENABLE_CLEAR 0x18
33#define JZ_REG_TIMER_FLAG 0x20
34#define JZ_REG_TIMER_FLAG_SET 0x24
35#define JZ_REG_TIMER_FLAG_CLEAR 0x28
36#define JZ_REG_TIMER_MASK 0x30
37#define JZ_REG_TIMER_MASK_SET 0x34
38#define JZ_REG_TIMER_MASK_CLEAR 0x38
39
40#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x40)
41#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x44)
42#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x48)
43#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x4C)
44
45#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
46#define JZ_TIMER_IRQ_FULL(x) BIT(x)
47
48#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
49#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
50#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
51#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
52#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
53#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
54#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
55#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
56#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
57#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
58
59#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
60#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
61#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
62
63static void __iomem *jz4740_timer_base;
64static uint16_t jz4740_jiffies_per_tick;
65
66void jz4740_timer_enable_watchdog(void)
67{
68    writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
69}
70
71void jz4740_timer_disable_watchdog(void)
72{
73    writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
74}
75
76static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
77{
78    writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
79}
80
81static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
82{
83    writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
84}
85
86static void jz4740_init_timer(void)
87{
88    uint16_t val = 0;
89    val |= JZ_TIMER_CTRL_PRESCALE_16;
90    val |= JZ_TIMER_CTRL_SRC_EXT;
91
92    writew(val, jz4740_timer_base + JZ_REG_TIMER_CTRL(0));
93    writew(0xffff, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
94    writew(val, jz4740_timer_base + JZ_REG_TIMER_CTRL(1));
95    writew(0xffff, jz4740_timer_base + JZ_REG_TIMER_DFR(1));
96}
97
98static void jz4740_timer_enable(unsigned int timer)
99{
100    writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
101    writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
102}
103
104static void jz4740_timer_disable(unsigned int timer)
105{
106    writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
107    writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
108}
109
110static void jz4740_timer_irq_full_enable(unsigned int timer)
111{
112    writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
113    writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
114}
115
116static int jz4740_timer_irq_full_is_enabled(unsigned int timer)
117{
118    return !(readl(jz4740_timer_base + JZ_REG_TIMER_MASK) &
119    JZ_TIMER_IRQ_FULL(timer));
120}
121
122static void jz4740_timer_irq_full_disable(unsigned int timer)
123{
124    writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
125}
126
127static void jz4740_timer_irq_half_enable(unsigned int timer)
128{
129    writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
130    writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
131}
132
133static void jz4740_timer_irq_half_disable(unsigned int timer)
134{
135    writel(JZ_TIMER_IRQ_HALF(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
136}
137
138static cycle_t jz4740_clocksource_read(struct clocksource *cs)
139{
140    uint16_t val;
141    val = readw(jz4740_timer_base + JZ_REG_TIMER_CNT(1));
142    return val;
143}
144
145static struct clocksource jz4740_clocksource = {
146    .name = "jz4740-timer",
147    .rating = 200,
148    .read = jz4740_clocksource_read,
149    .mask = CLOCKSOURCE_MASK(16),
150    .flags = CLOCK_SOURCE_IS_CONTINUOUS,
151};
152
153static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
154{
155    struct clock_event_device *cd = devid;
156
157    writel(JZ_TIMER_IRQ_FULL(0), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
158
159    if (cd->mode != CLOCK_EVT_MODE_PERIODIC) {
160        jz4740_timer_disable(0);
161        cd->event_handler(cd);
162     } else {
163        cd->event_handler(cd);
164    }
165
166    return IRQ_HANDLED;
167}
168
169static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
170    struct clock_event_device *cd)
171{
172    switch (mode) {
173    case CLOCK_EVT_MODE_PERIODIC:
174        writew(0x0, jz4740_timer_base + JZ_REG_TIMER_CNT(0));
175        writew(jz4740_jiffies_per_tick, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
176    case CLOCK_EVT_MODE_RESUME:
177        jz4740_timer_irq_full_enable(0);
178        jz4740_timer_enable(0);
179        break;
180    case CLOCK_EVT_MODE_ONESHOT:
181    case CLOCK_EVT_MODE_SHUTDOWN:
182        jz4740_timer_disable(0);
183        break;
184    default:
185        break;
186    }
187}
188
189static int jz4740_clockevent_set_next(unsigned long evt,
190    struct clock_event_device *cd)
191{
192    writew(0x0, jz4740_timer_base + JZ_REG_TIMER_CNT(0));
193    writew(evt, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
194    jz4740_timer_enable(0);
195
196    return 0;
197}
198
199static struct clock_event_device jz4740_clockevent = {
200    .name = "jz4740-timer",
201    .features = CLOCK_EVT_FEAT_PERIODIC,
202    .set_next_event = jz4740_clockevent_set_next,
203    .set_mode = jz4740_clockevent_set_mode,
204    .rating = 200,
205    .irq = JZ4740_IRQ_TCU0,
206};
207
208static struct irqaction timer_irqaction = {
209    .handler = jz4740_clockevent_irq,
210    .flags = IRQF_PERCPU | IRQF_TIMER | IRQF_DISABLED,
211    .name = "jz4740-timerirq",
212    .dev_id = &jz4740_clockevent,
213};
214
215void __init plat_time_init(void)
216{
217    int ret;
218    uint32_t clk_rate;
219
220    jz4740_timer_base = ioremap(CPHYSADDR(JZ4740_TCU_BASE_ADDR), 0x100);
221
222    if (!jz4740_timer_base) {
223        printk(KERN_ERR "Failed to ioremap timer registers");
224        return;
225    }
226
227    clk_rate = jz4740_clock_bdata.ext_rate >> 4;
228    jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
229
230    clockevent_set_clock(&jz4740_clockevent, clk_rate);
231    jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
232    jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
233    jz4740_clockevent.cpumask = cpumask_of(0);
234
235    clockevents_register_device(&jz4740_clockevent);
236
237    clocksource_set_clock(&jz4740_clocksource, clk_rate);
238    ret = clocksource_register(&jz4740_clocksource);
239
240    if (ret)
241        printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
242
243    setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
244
245    jz4740_init_timer();
246    writew(jz4740_jiffies_per_tick, jz4740_timer_base + JZ_REG_TIMER_DFR(0));
247    jz4740_timer_irq_half_disable(0);
248    jz4740_timer_irq_full_enable(0);
249    jz4740_timer_enable(0);
250
251    jz4740_timer_irq_half_disable(1);
252    jz4740_timer_irq_full_disable(1);
253
254    jz4740_timer_enable(1);
255}
arch/mips/kernel/cpu-probe.c
163163    case CPU_BCM6358:
164164    case CPU_CAVIUM_OCTEON:
165165    case CPU_CAVIUM_OCTEON_PLUS:
166    case CPU_JZRISC:
166167        cpu_wait = r4k_wait;
167168        break;
168169
...... 
932933    }
933934}
934935
936static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
937{
938    decode_configs(c);
939    /* JZRISC does not implement the CP0 counter. */
940    c->options &= ~MIPS_CPU_COUNTER;
941    switch (c->processor_id & 0xff00) {
942    case PRID_IMP_JZRISC:
943        c->cputype = CPU_JZRISC;
944        __cpu_name[cpu] = "Ingenic JZRISC";
945        break;
946    default:
947        panic("Unknown Ingenic Processor ID!");
948        break;
949    }
950}
951
935952const char *__cpu_name[NR_CPUS];
936953const char *__elf_platform;
937954
...... 
970987    case PRID_COMP_CAVIUM:
971988        cpu_probe_cavium(c, cpu);
972989        break;
990    case PRID_COMP_INGENIC:
991        cpu_probe_ingenic(c, cpu);
992        break;
973993    }
974994
975995    BUG_ON(!__cpu_name[cpu]);
arch/mips/mm/tlbex.c
393393        tlbw(p);
394394        break;
395395
396    case CPU_JZRISC:
397        tlbw(p);
398        uasm_i_nop(p);
399        break;
400
396401    default:
397402        panic("No TLB refill handler yet (CPU type: %d)",
398403              current_cpu_data.cputype);

Archive Download the corresponding diff file



interactive