Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dma-engine: sun4i: Add support for Allwinner suniv F1C100s

DMA of Allwinner suniv F1C100s is similar to sun4i. It has 4 NDMA, 4
DDMA channels and endpoints are different. Also F1C100s has reset bit
for DMA in CCU. Add support for it.

Signed-off-by: Mesih Kilinc <mesihkilinc@gmail.com>
[ csokas.bence: Rebased on current master ]
Signed-off-by: Csókás Bence <csokas.bence@prolan.hu>
Link: https://lore.kernel.org/r/20241122161128.2619172-5-csokas.bence@prolan.hu
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Mesih Kilinc and committed by
Vinod Koul
6faf1cca fdcdcc57

+62 -2
+2 -2
drivers/dma/Kconfig
··· 162 162 163 163 config DMA_SUN4I 164 164 tristate "Allwinner A10 DMA SoCs support" 165 - depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I 166 - default (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I) 165 + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNIV 166 + default (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNIV) 167 167 select DMA_ENGINE 168 168 select DMA_VIRTUAL_CHANNELS 169 169 help
+60
drivers/dma/sun4i-dma.c
··· 33 33 #define SUN4I_DMA_CFG_SRC_ADDR_MODE(mode) ((mode) << 5) 34 34 #define SUN4I_DMA_CFG_SRC_DRQ_TYPE(type) (type) 35 35 36 + #define SUNIV_DMA_CFG_DST_DATA_WIDTH(width) ((width) << 24) 37 + #define SUNIV_DMA_CFG_SRC_DATA_WIDTH(width) ((width) << 8) 38 + 36 39 #define SUN4I_MAX_BURST 8 40 + #define SUNIV_MAX_BURST 4 37 41 38 42 /** Normal DMA register values **/ 39 43 40 44 /* Normal DMA source/destination data request type values */ 41 45 #define SUN4I_NDMA_DRQ_TYPE_SDRAM 0x16 42 46 #define SUN4I_NDMA_DRQ_TYPE_LIMIT (0x1F + 1) 47 + 48 + #define SUNIV_NDMA_DRQ_TYPE_SDRAM 0x11 49 + #define SUNIV_NDMA_DRQ_TYPE_LIMIT (0x17 + 1) 43 50 44 51 /** Normal DMA register layout **/ 45 52 ··· 61 54 #define SUN4I_NDMA_CFG_BYTE_COUNT_MODE_REMAIN BIT(15) 62 55 #define SUN4I_NDMA_CFG_SRC_NON_SECURE BIT(6) 63 56 57 + #define SUNIV_NDMA_CFG_CONT_MODE BIT(29) 58 + #define SUNIV_NDMA_CFG_WAIT_STATE(n) ((n) << 26) 59 + 64 60 /** Dedicated DMA register values **/ 65 61 66 62 /* Dedicated DMA source/destination address mode values */ ··· 75 65 /* Dedicated DMA source/destination data request type values */ 76 66 #define SUN4I_DDMA_DRQ_TYPE_SDRAM 0x1 77 67 #define SUN4I_DDMA_DRQ_TYPE_LIMIT (0x1F + 1) 68 + 69 + #define SUNIV_DDMA_DRQ_TYPE_SDRAM 0x1 70 + #define SUNIV_DDMA_DRQ_TYPE_LIMIT (0x9 + 1) 78 71 79 72 /** Dedicated DMA register layout **/ 80 73 ··· 131 118 #define SUN4I_DDMA_NR_MAX_VCHANS 21 132 119 #define SUN4I_DMA_NR_MAX_VCHANS \ 133 120 (SUN4I_NDMA_NR_MAX_VCHANS + SUN4I_DDMA_NR_MAX_VCHANS) 121 + 122 + #define SUNIV_NDMA_NR_MAX_CHANNELS 4 123 + #define SUNIV_DDMA_NR_MAX_CHANNELS 4 124 + #define SUNIV_NDMA_NR_MAX_VCHANS (24 * 2 - 1) 125 + #define SUNIV_DDMA_NR_MAX_VCHANS 10 134 126 135 127 /* This set of SUN4I_DDMA timing parameters were found experimentally while 136 128 * working with the SPI driver and seem to make it behave correctly */ ··· 261 243 *p_cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(data_width); 262 244 } 263 245 246 + static void set_dst_data_width_f1c100s(u32 *p_cfg, s8 data_width) 247 + { 248 + *p_cfg |= SUNIV_DMA_CFG_DST_DATA_WIDTH(data_width); 249 + } 250 + 251 + static void set_src_data_width_f1c100s(u32 *p_cfg, s8 data_width) 252 + { 253 + *p_cfg |= SUNIV_DMA_CFG_SRC_DATA_WIDTH(data_width); 254 + } 255 + 264 256 static int convert_burst_a10(u32 maxburst) 265 257 { 266 258 if (maxburst > 8) 267 259 return -EINVAL; 268 260 269 261 /* 1 -> 0, 4 -> 1, 8 -> 2 */ 262 + return (maxburst >> 2); 263 + } 264 + 265 + static int convert_burst_f1c100s(u32 maxburst) 266 + { 267 + if (maxburst > 4) 268 + return -EINVAL; 269 + 270 + /* 1 -> 0, 4 -> 1 */ 270 271 return (maxburst >> 2); 271 272 } 272 273 ··· 1405 1368 .has_reset = false, 1406 1369 }; 1407 1370 1371 + static struct sun4i_dma_config suniv_f1c100s_dma_cfg = { 1372 + .ndma_nr_max_channels = SUNIV_NDMA_NR_MAX_CHANNELS, 1373 + .ndma_nr_max_vchans = SUNIV_NDMA_NR_MAX_VCHANS, 1374 + 1375 + .ddma_nr_max_channels = SUNIV_DDMA_NR_MAX_CHANNELS, 1376 + .ddma_nr_max_vchans = SUNIV_DDMA_NR_MAX_VCHANS, 1377 + 1378 + .dma_nr_max_channels = SUNIV_NDMA_NR_MAX_CHANNELS + 1379 + SUNIV_DDMA_NR_MAX_CHANNELS, 1380 + 1381 + .set_dst_data_width = set_dst_data_width_f1c100s, 1382 + .set_src_data_width = set_src_data_width_f1c100s, 1383 + .convert_burst = convert_burst_f1c100s, 1384 + 1385 + .ndma_drq_sdram = SUNIV_NDMA_DRQ_TYPE_SDRAM, 1386 + .ddma_drq_sdram = SUNIV_DDMA_DRQ_TYPE_SDRAM, 1387 + 1388 + .max_burst = SUNIV_MAX_BURST, 1389 + .has_reset = true, 1390 + }; 1391 + 1408 1392 static const struct of_device_id sun4i_dma_match[] = { 1409 1393 { .compatible = "allwinner,sun4i-a10-dma", .data = &sun4i_a10_dma_cfg }, 1394 + { .compatible = "allwinner,suniv-f1c100s-dma", 1395 + .data = &suniv_f1c100s_dma_cfg }, 1410 1396 { /* sentinel */ }, 1411 1397 }; 1412 1398 MODULE_DEVICE_TABLE(of, sun4i_dma_match);