1 /* 2 * This program is free software; you can redistribute it and/or modify it 3 * under the terms of the GNU General Public License version 2 as published 4 * by the Free Software Foundation. 5 * 6 * This program is distributed in the hope that it will be useful, 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * GNU General Public License for more details. 10 * 11 * You should have received a copy of the GNU General Public License 12 * along with this program; if not, write to the Free Software 13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 14 * 15 * Copyright (C) 2011 John Crispin <blogic@openwrt.org> 16 */ 17 18 #include <linux/init.h> 19 #include <linux/platform_device.h> 20 #include <linux/io.h> 21 #include <linux/dma-mapping.h> 22 #include <linux/export.h> 23 24 #include <lantiq_soc.h> 25 #include <xway_dma.h> 26 27 #define LTQ_DMA_CTRL 0x10 28 #define LTQ_DMA_CPOLL 0x14 29 #define LTQ_DMA_CS 0x18 30 #define LTQ_DMA_CCTRL 0x1C 31 #define LTQ_DMA_CDBA 0x20 32 #define LTQ_DMA_CDLEN 0x24 33 #define LTQ_DMA_CIS 0x28 34 #define LTQ_DMA_CIE 0x2C 35 #define LTQ_DMA_PS 0x40 36 #define LTQ_DMA_PCTRL 0x44 37 #define LTQ_DMA_IRNEN 0xf4 38 39 #define DMA_DESCPT BIT(3) /* descriptor complete irq */ 40 #define DMA_TX BIT(8) /* TX channel direction */ 41 #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ 42 #define DMA_PDEN BIT(6) /* enable packet drop */ 43 #define DMA_CHAN_RST BIT(1) /* channel on / off bit */ 44 #define DMA_RESET BIT(0) /* channel on / off bit */ 45 #define DMA_IRQ_ACK 0x7e /* IRQ status register */ 46 #define DMA_POLL BIT(31) /* turn on channel polling */ 47 #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ 48 #define DMA_2W_BURST BIT(1) /* 2 word burst length */ 49 #define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ 50 #define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */ 51 #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ 52 53 #define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x)) 54 #define ltq_dma_w32(x, y) ltq_w32(x, ltq_dma_membase + (y)) 55 #define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ 56 ltq_dma_membase + (z)) 57 58 static struct resource ltq_dma_resource = { 59 .name = "dma", 60 .start = LTQ_DMA_BASE_ADDR, 61 .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1, 62 .flags = IORESOURCE_MEM, 63 }; 64 65 static void __iomem *ltq_dma_membase; 66 67 void 68 ltq_dma_enable_irq(struct ltq_dma_channel *ch) 69 { 70 unsigned long flags; 71 72 local_irq_save(flags); 73 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 74 ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); 75 local_irq_restore(flags); 76 } 77 EXPORT_SYMBOL_GPL(ltq_dma_enable_irq); 78 79 void 80 ltq_dma_disable_irq(struct ltq_dma_channel *ch) 81 { 82 unsigned long flags; 83 84 local_irq_save(flags); 85 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 86 ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN); 87 local_irq_restore(flags); 88 } 89 EXPORT_SYMBOL_GPL(ltq_dma_disable_irq); 90 91 void 92 ltq_dma_ack_irq(struct ltq_dma_channel *ch) 93 { 94 unsigned long flags; 95 96 local_irq_save(flags); 97 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 98 ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS); 99 local_irq_restore(flags); 100 } 101 EXPORT_SYMBOL_GPL(ltq_dma_ack_irq); 102 103 void 104 ltq_dma_open(struct ltq_dma_channel *ch) 105 { 106 unsigned long flag; 107 108 local_irq_save(flag); 109 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 110 ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL); 111 ltq_dma_enable_irq(ch); 112 local_irq_restore(flag); 113 } 114 EXPORT_SYMBOL_GPL(ltq_dma_open); 115 116 void 117 ltq_dma_close(struct ltq_dma_channel *ch) 118 { 119 unsigned long flag; 120 121 local_irq_save(flag); 122 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 123 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 124 ltq_dma_disable_irq(ch); 125 local_irq_restore(flag); 126 } 127 EXPORT_SYMBOL_GPL(ltq_dma_close); 128 129 static void 130 ltq_dma_alloc(struct ltq_dma_channel *ch) 131 { 132 unsigned long flags; 133 134 ch->desc = 0; 135 ch->desc_base = dma_alloc_coherent(NULL, 136 LTQ_DESC_NUM * LTQ_DESC_SIZE, 137 &ch->phys, GFP_ATOMIC); 138 memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE); 139 140 local_irq_save(flags); 141 ltq_dma_w32(ch->nr, LTQ_DMA_CS); 142 ltq_dma_w32(ch->phys, LTQ_DMA_CDBA); 143 ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN); 144 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 145 wmb(); 146 ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL); 147 while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST) 148 ; 149 local_irq_restore(flags); 150 } 151 152 void 153 ltq_dma_alloc_tx(struct ltq_dma_channel *ch) 154 { 155 unsigned long flags; 156 157 ltq_dma_alloc(ch); 158 159 local_irq_save(flags); 160 ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE); 161 ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); 162 ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL); 163 local_irq_restore(flags); 164 } 165 EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx); 166 167 void 168 ltq_dma_alloc_rx(struct ltq_dma_channel *ch) 169 { 170 unsigned long flags; 171 172 ltq_dma_alloc(ch); 173 174 local_irq_save(flags); 175 ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE); 176 ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN); 177 ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL); 178 local_irq_restore(flags); 179 } 180 EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx); 181 182 void 183 ltq_dma_free(struct ltq_dma_channel *ch) 184 { 185 if (!ch->desc_base) 186 return; 187 ltq_dma_close(ch); 188 dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE, 189 ch->desc_base, ch->phys); 190 } 191 EXPORT_SYMBOL_GPL(ltq_dma_free); 192 193 void 194 ltq_dma_init_port(int p) 195 { 196 ltq_dma_w32(p, LTQ_DMA_PS); 197 switch (p) { 198 case DMA_PORT_ETOP: 199 /* 200 * Tell the DMA engine to swap the endianess of data frames and 201 * drop packets if the channel arbitration fails. 202 */ 203 ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN, 204 LTQ_DMA_PCTRL); 205 break; 206 207 case DMA_PORT_DEU: 208 ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), 209 LTQ_DMA_PCTRL); 210 break; 211 212 default: 213 break; 214 } 215 } 216 EXPORT_SYMBOL_GPL(ltq_dma_init_port); 217 218 int __init 219 ltq_dma_init(void) 220 { 221 int i; 222 223 /* insert and request the memory region */ 224 if (insert_resource(&iomem_resource, <q_dma_resource) < 0) 225 panic("Failed to insert dma memory"); 226 227 if (request_mem_region(ltq_dma_resource.start, 228 resource_size(<q_dma_resource), "dma") < 0) 229 panic("Failed to request dma memory"); 230 231 /* remap dma register range */ 232 ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, 233 resource_size(<q_dma_resource)); 234 if (!ltq_dma_membase) 235 panic("Failed to remap dma memory"); 236 237 /* power up and reset the dma engine */ 238 ltq_pmu_enable(PMU_DMA); 239 ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); 240 241 /* disable all interrupts */ 242 ltq_dma_w32(0, LTQ_DMA_IRNEN); 243 244 /* reset/configure each channel */ 245 for (i = 0; i < DMA_MAX_CHANNEL; i++) { 246 ltq_dma_w32(i, LTQ_DMA_CS); 247 ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); 248 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); 249 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 250 } 251 return 0; 252 } 253 254 postcore_initcall(ltq_dma_init); 255