|
28 | 28 | #define DDADR(n) (0x0200 + ((n) << 4)) |
29 | 29 | #define DSADR(n) (0x0204 + ((n) << 4)) |
30 | 30 | #define DTADR(n) (0x0208 + ((n) << 4)) |
| 31 | +#define DDADRH(n) (0x0300 + ((n) << 4)) |
| 32 | +#define DSADRH(n) (0x0304 + ((n) << 4)) |
| 33 | +#define DTADRH(n) (0x0308 + ((n) << 4)) |
31 | 34 | #define DCMD 0x020c |
32 | 35 |
|
33 | 36 | #define DCSR_RUN BIT(31) /* Run Bit (read / write) */ |
|
44 | 47 | #define DCSR_EORSTOPEN BIT(26) /* STOP on an EOR */ |
45 | 48 | #define DCSR_SETCMPST BIT(25) /* Set Descriptor Compare Status */ |
46 | 49 | #define DCSR_CLRCMPST BIT(24) /* Clear Descriptor Compare Status */ |
| 50 | +#define DCSR_LPAEEN BIT(21) /* Long Physical Address Extension Enable */ |
47 | 51 | #define DCSR_CMPST BIT(10) /* The Descriptor Compare Status */ |
48 | 52 | #define DCSR_EORINTR BIT(9) /* The end of Receive */ |
49 | 53 |
|
@@ -76,6 +80,16 @@ struct mmp_pdma_desc_hw { |
76 | 80 | u32 dsadr; /* DSADR value for the current transfer */ |
77 | 81 | u32 dtadr; /* DTADR value for the current transfer */ |
78 | 82 | u32 dcmd; /* DCMD value for the current transfer */ |
| 83 | + /* |
| 84 | + * The following 32-bit words are only used in the 64-bit, ie. |
| 85 | + * LPAE (Long Physical Address Extension) mode. |
| 86 | + * They are used to specify the high 32 bits of the descriptor's |
| 87 | + * addresses. |
| 88 | + */ |
| 89 | + u32 ddadrh; /* High 32-bit of DDADR */ |
| 90 | + u32 dsadrh; /* High 32-bit of DSADR */ |
| 91 | + u32 dtadrh; /* High 32-bit of DTADR */ |
| 92 | + u32 rsvd; /* reserved */ |
79 | 93 | } __aligned(32); |
80 | 94 |
|
81 | 95 | struct mmp_pdma_desc_sw { |
@@ -222,6 +236,57 @@ static u64 get_desc_dst_addr_32(const struct mmp_pdma_desc_hw *desc) |
222 | 236 | return desc->dtadr; |
223 | 237 | } |
224 | 238 |
|
| 239 | +/* For 64-bit PDMA */ |
| 240 | +static void write_next_addr_64(struct mmp_pdma_phy *phy, dma_addr_t addr) |
| 241 | +{ |
| 242 | + writel(lower_32_bits(addr), phy->base + DDADR(phy->idx)); |
| 243 | + writel(upper_32_bits(addr), phy->base + DDADRH(phy->idx)); |
| 244 | +} |
| 245 | + |
| 246 | +static u64 read_src_addr_64(struct mmp_pdma_phy *phy) |
| 247 | +{ |
| 248 | + u32 low = readl(phy->base + DSADR(phy->idx)); |
| 249 | + u32 high = readl(phy->base + DSADRH(phy->idx)); |
| 250 | + |
| 251 | + return ((u64)high << 32) | low; |
| 252 | +} |
| 253 | + |
| 254 | +static u64 read_dst_addr_64(struct mmp_pdma_phy *phy) |
| 255 | +{ |
| 256 | + u32 low = readl(phy->base + DTADR(phy->idx)); |
| 257 | + u32 high = readl(phy->base + DTADRH(phy->idx)); |
| 258 | + |
| 259 | + return ((u64)high << 32) | low; |
| 260 | +} |
| 261 | + |
| 262 | +static void set_desc_next_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) |
| 263 | +{ |
| 264 | + desc->ddadr = lower_32_bits(addr); |
| 265 | + desc->ddadrh = upper_32_bits(addr); |
| 266 | +} |
| 267 | + |
| 268 | +static void set_desc_src_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) |
| 269 | +{ |
| 270 | + desc->dsadr = lower_32_bits(addr); |
| 271 | + desc->dsadrh = upper_32_bits(addr); |
| 272 | +} |
| 273 | + |
| 274 | +static void set_desc_dst_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) |
| 275 | +{ |
| 276 | + desc->dtadr = lower_32_bits(addr); |
| 277 | + desc->dtadrh = upper_32_bits(addr); |
| 278 | +} |
| 279 | + |
| 280 | +static u64 get_desc_src_addr_64(const struct mmp_pdma_desc_hw *desc) |
| 281 | +{ |
| 282 | + return ((u64)desc->dsadrh << 32) | desc->dsadr; |
| 283 | +} |
| 284 | + |
| 285 | +static u64 get_desc_dst_addr_64(const struct mmp_pdma_desc_hw *desc) |
| 286 | +{ |
| 287 | + return ((u64)desc->dtadrh << 32) | desc->dtadr; |
| 288 | +} |
| 289 | + |
225 | 290 | static int mmp_pdma_config_write(struct dma_chan *dchan, |
226 | 291 | struct dma_slave_config *cfg, |
227 | 292 | enum dma_transfer_direction direction); |
@@ -1110,10 +1175,26 @@ static const struct mmp_pdma_ops marvell_pdma_v1_ops = { |
1110 | 1175 | .dma_mask = 0, /* let OF/platform set DMA mask */ |
1111 | 1176 | }; |
1112 | 1177 |
|
| 1178 | +static const struct mmp_pdma_ops spacemit_k1_pdma_ops = { |
| 1179 | + .write_next_addr = write_next_addr_64, |
| 1180 | + .read_src_addr = read_src_addr_64, |
| 1181 | + .read_dst_addr = read_dst_addr_64, |
| 1182 | + .set_desc_next_addr = set_desc_next_addr_64, |
| 1183 | + .set_desc_src_addr = set_desc_src_addr_64, |
| 1184 | + .set_desc_dst_addr = set_desc_dst_addr_64, |
| 1185 | + .get_desc_src_addr = get_desc_src_addr_64, |
| 1186 | + .get_desc_dst_addr = get_desc_dst_addr_64, |
| 1187 | + .run_bits = (DCSR_RUN | DCSR_LPAEEN), |
| 1188 | + .dma_mask = DMA_BIT_MASK(64), /* force 64-bit DMA addr capability */ |
| 1189 | +}; |
| 1190 | + |
1113 | 1191 | static const struct of_device_id mmp_pdma_dt_ids[] = { |
1114 | 1192 | { |
1115 | 1193 | .compatible = "marvell,pdma-1.0", |
1116 | 1194 | .data = &marvell_pdma_v1_ops |
| 1195 | + }, { |
| 1196 | + .compatible = "spacemit,k1-pdma", |
| 1197 | + .data = &spacemit_k1_pdma_ops |
1117 | 1198 | }, { |
1118 | 1199 | /* sentinel */ |
1119 | 1200 | } |
|
0 commit comments