diff options
-rw-r--r-- | arch/xtensa/platforms/s6105/device.c | 91 | ||||
-rw-r--r-- | arch/xtensa/platforms/s6105/setup.c | 9 |
2 files changed, 100 insertions, 0 deletions
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c index 78b08be5a92d..963634a3463d 100644 --- a/arch/xtensa/platforms/s6105/device.c +++ b/arch/xtensa/platforms/s6105/device.c | |||
@@ -5,14 +5,27 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/gpio.h> | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/irq.h> | ||
11 | #include <linux/phy.h> | ||
9 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
10 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
11 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
12 | 15 | ||
13 | #include <variant/hardware.h> | 16 | #include <variant/hardware.h> |
17 | #include <variant/dmac.h> | ||
14 | 18 | ||
19 | #include <platform/gpio.h> | ||
20 | |||
21 | #define GPIO3_INTNUM 3 | ||
15 | #define UART_INTNUM 4 | 22 | #define UART_INTNUM 4 |
23 | #define GMAC_INTNUM 5 | ||
24 | |||
25 | static const signed char gpio3_irq_mappings[] = { | ||
26 | S6_INTC_GPIO(3), | ||
27 | -1 | ||
28 | }; | ||
16 | 29 | ||
17 | static const signed char uart_irq_mappings[] = { | 30 | static const signed char uart_irq_mappings[] = { |
18 | S6_INTC_UART(0), | 31 | S6_INTC_UART(0), |
@@ -20,8 +33,18 @@ static const signed char uart_irq_mappings[] = { | |||
20 | -1, | 33 | -1, |
21 | }; | 34 | }; |
22 | 35 | ||
36 | static const signed char gmac_irq_mappings[] = { | ||
37 | S6_INTC_GMAC_STAT, | ||
38 | S6_INTC_GMAC_ERR, | ||
39 | S6_INTC_DMA_HOSTTERMCNT(0), | ||
40 | S6_INTC_DMA_HOSTTERMCNT(1), | ||
41 | -1 | ||
42 | }; | ||
43 | |||
23 | const signed char *platform_irq_mappings[NR_IRQS] = { | 44 | const signed char *platform_irq_mappings[NR_IRQS] = { |
45 | [GPIO3_INTNUM] = gpio3_irq_mappings, | ||
24 | [UART_INTNUM] = uart_irq_mappings, | 46 | [UART_INTNUM] = uart_irq_mappings, |
47 | [GMAC_INTNUM] = gmac_irq_mappings, | ||
25 | }; | 48 | }; |
26 | 49 | ||
27 | static struct plat_serial8250_port serial_platform_data[] = { | 50 | static struct plat_serial8250_port serial_platform_data[] = { |
@@ -46,6 +69,66 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
46 | { }, | 69 | { }, |
47 | }; | 70 | }; |
48 | 71 | ||
72 | static struct resource s6_gmac_resource[] = { | ||
73 | { | ||
74 | .name = "mem", | ||
75 | .start = (resource_size_t)S6_REG_GMAC, | ||
76 | .end = (resource_size_t)S6_REG_GMAC + 0x10000 - 1, | ||
77 | .flags = IORESOURCE_MEM, | ||
78 | }, | ||
79 | { | ||
80 | .name = "dma", | ||
81 | .start = (resource_size_t) | ||
82 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX), | ||
83 | .end = (resource_size_t) | ||
84 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1, | ||
85 | .flags = IORESOURCE_DMA, | ||
86 | }, | ||
87 | { | ||
88 | .name = "dma", | ||
89 | .start = (resource_size_t) | ||
90 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX), | ||
91 | .end = (resource_size_t) | ||
92 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1, | ||
93 | .flags = IORESOURCE_DMA, | ||
94 | }, | ||
95 | { | ||
96 | .name = "io", | ||
97 | .start = (resource_size_t)S6_MEM_GMAC, | ||
98 | .end = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1, | ||
99 | .flags = IORESOURCE_IO, | ||
100 | }, | ||
101 | { | ||
102 | .name = "irq", | ||
103 | .start = (resource_size_t)GMAC_INTNUM, | ||
104 | .flags = IORESOURCE_IRQ, | ||
105 | }, | ||
106 | { | ||
107 | .name = "irq", | ||
108 | .start = (resource_size_t)PHY_POLL, | ||
109 | .flags = IORESOURCE_IRQ, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | static int __init prepare_phy_irq(int pin) | ||
114 | { | ||
115 | int irq; | ||
116 | if (gpio_request(pin, "s6gmac_phy") < 0) | ||
117 | goto fail; | ||
118 | if (gpio_direction_input(pin) < 0) | ||
119 | goto free; | ||
120 | irq = gpio_to_irq(pin); | ||
121 | if (irq < 0) | ||
122 | goto free; | ||
123 | if (set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0) | ||
124 | goto free; | ||
125 | return irq; | ||
126 | free: | ||
127 | gpio_free(pin); | ||
128 | fail: | ||
129 | return PHY_POLL; | ||
130 | } | ||
131 | |||
49 | static struct platform_device platform_devices[] = { | 132 | static struct platform_device platform_devices[] = { |
50 | { | 133 | { |
51 | .name = "serial8250", | 134 | .name = "serial8250", |
@@ -54,12 +137,20 @@ static struct platform_device platform_devices[] = { | |||
54 | .platform_data = serial_platform_data, | 137 | .platform_data = serial_platform_data, |
55 | }, | 138 | }, |
56 | }, | 139 | }, |
140 | { | ||
141 | .name = "s6gmac", | ||
142 | .id = 0, | ||
143 | .resource = s6_gmac_resource, | ||
144 | .num_resources = ARRAY_SIZE(s6_gmac_resource), | ||
145 | }, | ||
57 | }; | 146 | }; |
58 | 147 | ||
59 | static int __init device_init(void) | 148 | static int __init device_init(void) |
60 | { | 149 | { |
61 | int i; | 150 | int i; |
62 | 151 | ||
152 | s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ); | ||
153 | |||
63 | for (i = 0; i < ARRAY_SIZE(platform_devices); i++) | 154 | for (i = 0; i < ARRAY_SIZE(platform_devices); i++) |
64 | platform_device_register(&platform_devices[i]); | 155 | platform_device_register(&platform_devices[i]); |
65 | return 0; | 156 | return 0; |
diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c index 95fa23c8e632..86ce730f7913 100644 --- a/arch/xtensa/platforms/s6105/setup.c +++ b/arch/xtensa/platforms/s6105/setup.c | |||
@@ -35,12 +35,21 @@ void __init platform_setup(char **cmdline) | |||
35 | { | 35 | { |
36 | unsigned long reg; | 36 | unsigned long reg; |
37 | 37 | ||
38 | reg = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
39 | reg &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC | | ||
40 | S6_GREG1_PLLSEL_GMII_MASK << S6_GREG1_PLLSEL_GMII); | ||
41 | reg |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC | | ||
42 | S6_GREG1_PLLSEL_GMII_125MHZ << S6_GREG1_PLLSEL_GMII; | ||
43 | writel(reg, S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
44 | |||
38 | reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE); | 45 | reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE); |
39 | reg &= ~(1 << S6_GREG1_BLOCK_SB); | 46 | reg &= ~(1 << S6_GREG1_BLOCK_SB); |
47 | reg &= ~(1 << S6_GREG1_BLOCK_GMAC); | ||
40 | writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE); | 48 | writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE); |
41 | 49 | ||
42 | reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA); | 50 | reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA); |
43 | reg |= 1 << S6_GREG1_BLOCK_SB; | 51 | reg |= 1 << S6_GREG1_BLOCK_SB; |
52 | reg |= 1 << S6_GREG1_BLOCK_GMAC; | ||
44 | writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA); | 53 | writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA); |
45 | 54 | ||
46 | printk(KERN_NOTICE "S6105 on Stretch S6000 - " | 55 | printk(KERN_NOTICE "S6105 on Stretch S6000 - " |