xref: /openbmc/u-boot/drivers/net/ftgmac100.c (revision 1a68faac)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Faraday FTGMAC100 Ethernet
4  *
5  * (C) Copyright 2009 Faraday Technology
6  * Po-Yu Chuang <ratbert@faraday-tech.com>
7  *
8  * (C) Copyright 2010 Andes Technology
9  * Macpaul Lin <macpaul@andestech.com>
10  *
11  * Copyright (C) 2018, IBM Corporation.
12  */
13 
14 #include <clk.h>
15 #include <dm.h>
16 #include <miiphy.h>
17 #include <net.h>
18 #include <wait_bit.h>
19 #include <linux/io.h>
20 #include <linux/iopoll.h>
21 
22 #include "ftgmac100.h"
23 #include "aspeed_mdio.h"
24 
25 /* Min frame ethernet frame size without FCS */
26 #define ETH_ZLEN			60
27 
28 /* Receive Buffer Size Register - HW default is 0x640 */
29 #define FTGMAC100_RBSR_DEFAULT		0x640
30 
31 /* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
32 #define PKTBUFSTX	4	/* must be power of 2 */
33 
34 /* Timeout for transmit */
35 #define FTGMAC100_TX_TIMEOUT_MS		1000
36 
37 /* Timeout for a mdio read/write operation */
38 #define FTGMAC100_MDIO_TIMEOUT_USEC	10000
39 
40 /*
41  * MDC clock cycle threshold
42  *
43  * 20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
44  */
45 #define MDC_CYCTHR			0x34
46 
47 /*
48  * ftgmac100 model variants
49  */
50 enum ftgmac100_model {
51 	FTGMAC100_MODEL_FARADAY,
52 	FTGMAC100_MODEL_ASPEED,
53 	FTGMAC100_MODEL_NEW_ASPEED,
54 };
55 
56 /**
57  * struct ftgmac100_data - private data for the FTGMAC100 driver
58  *
59  * @iobase: The base address of the hardware registers
60  * @txdes: The array of transmit descriptors
61  * @rxdes: The array of receive descriptors
62  * @tx_index: Transmit descriptor index in @txdes
63  * @rx_index: Receive descriptor index in @rxdes
64  * @phy_addr: The PHY interface address to use
65  * @phydev: The PHY device backing the MAC
66  * @bus: The mdio bus
67  * @phy_mode: The mode of the PHY interface (rgmii, rmii, ...)
68  * @max_speed: Maximum speed of Ethernet connection supported by MAC
69  * @clks: The bulk of clocks assigned to the device in the DT
70  * @rxdes0_edorr_mask: The bit number identifying the end of the RX ring buffer
71  * @txdes0_edotr_mask: The bit number identifying the end of the TX ring buffer
72  */
73 struct ftgmac100_data {
74 	struct ftgmac100 *iobase;
75 	fdt_addr_t mdio_addr;	//for aspeed ast2600 new mdio
76 
77 	struct ftgmac100_txdes txdes[PKTBUFSTX];
78 	struct ftgmac100_rxdes rxdes[PKTBUFSRX];
79 	int tx_index;
80 	int rx_index;
81 
82 	u32 phy_addr;
83 	struct phy_device *phydev;
84 	struct mii_dev *bus;
85 	u32 phy_mode;
86 	u32 max_speed;
87 
88 	struct clk_bulk clks;
89 
90 	/* End of RX/TX ring buffer bits. Depend on model */
91 	u32 rxdes0_edorr_mask;
92 	u32 txdes0_edotr_mask;
93 };
94 
95 /*
96  * struct mii_bus functions
97  */
98 static int ftgmac100_mdio_read(struct mii_dev *bus, int phy_addr, int dev_addr,
99 			       int reg_addr)
100 {
101 	struct ftgmac100_data *priv = bus->priv;
102 	struct ftgmac100 *ftgmac100 = priv->iobase;
103 	int phycr;
104 	int data;
105 	int ret;
106 
107 	phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
108 		FTGMAC100_PHYCR_PHYAD(phy_addr) |
109 		FTGMAC100_PHYCR_REGAD(reg_addr) |
110 		FTGMAC100_PHYCR_MIIRD;
111 	writel(phycr, &ftgmac100->phycr);
112 
113 	ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
114 				 !(phycr & FTGMAC100_PHYCR_MIIRD),
115 				 FTGMAC100_MDIO_TIMEOUT_USEC);
116 	if (ret) {
117 		pr_err("%s: mdio read failed (phy:%d reg:%x)\n",
118 		       priv->phydev->dev->name, phy_addr, reg_addr);
119 		return ret;
120 	}
121 
122 	data = readl(&ftgmac100->phydata);
123 
124 	return FTGMAC100_PHYDATA_MIIRDATA(data);
125 }
126 
127 static int ftgmac100_mdio_write(struct mii_dev *bus, int phy_addr, int dev_addr,
128 				int reg_addr, u16 value)
129 {
130 	struct ftgmac100_data *priv = bus->priv;
131 	struct ftgmac100 *ftgmac100 = priv->iobase;
132 	int phycr;
133 	int data;
134 	int ret;
135 
136 	phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
137 		FTGMAC100_PHYCR_PHYAD(phy_addr) |
138 		FTGMAC100_PHYCR_REGAD(reg_addr) |
139 		FTGMAC100_PHYCR_MIIWR;
140 	data = FTGMAC100_PHYDATA_MIIWDATA(value);
141 
142 	writel(data, &ftgmac100->phydata);
143 	writel(phycr, &ftgmac100->phycr);
144 
145 	ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
146 				 !(phycr & FTGMAC100_PHYCR_MIIWR),
147 				 FTGMAC100_MDIO_TIMEOUT_USEC);
148 	if (ret) {
149 		pr_err("%s: mdio write failed (phy:%d reg:%x)\n",
150 		       priv->phydev->dev->name, phy_addr, reg_addr);
151 	}
152 
153 	return ret;
154 }
155 
156 static int ftgmac100_mdio_init(struct udevice *dev)
157 {
158 	struct ftgmac100_data *priv = dev_get_priv(dev);
159 	struct mii_dev *bus;
160 	int ret;
161 
162 	bus = mdio_alloc();
163 	if (!bus)
164 		return -ENOMEM;
165 
166 	if(priv->mdio_addr) {
167 		bus->read  = aspeed_mdio_read;
168 		bus->write = aspeed_mdio_write;
169 		bus->priv  = (void *)priv->mdio_addr;
170 	} else {
171 		bus->read  = ftgmac100_mdio_read;
172 		bus->write = ftgmac100_mdio_write;
173 		bus->priv  = priv;
174 	}
175 
176 	ret = mdio_register_seq(bus, dev->seq);
177 	if (ret) {
178 		free(bus);
179 		return ret;
180 	}
181 
182 	priv->bus = bus;
183 
184 	return 0;
185 }
186 
187 static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv)
188 {
189 	struct ftgmac100 *ftgmac100 = priv->iobase;
190 	struct phy_device *phydev = priv->phydev;
191 	u32 maccr;
192 
193 	if (!phydev->link) {
194 		dev_err(phydev->dev, "No link\n");
195 		return -EREMOTEIO;
196 	}
197 
198 	/* read MAC control register and clear related bits */
199 	maccr = readl(&ftgmac100->maccr) &
200 		~(FTGMAC100_MACCR_GIGA_MODE |
201 		  FTGMAC100_MACCR_FAST_MODE |
202 		  FTGMAC100_MACCR_FULLDUP);
203 
204 	if (phy_interface_is_rgmii(phydev) && phydev->speed == 1000)
205 		maccr |= FTGMAC100_MACCR_GIGA_MODE;
206 
207 	if (phydev->speed == 100)
208 		maccr |= FTGMAC100_MACCR_FAST_MODE;
209 
210 	if (phydev->duplex)
211 		maccr |= FTGMAC100_MACCR_FULLDUP;
212 
213 	/* update MII config into maccr */
214 	writel(maccr, &ftgmac100->maccr);
215 
216 	return 0;
217 }
218 
219 static int ftgmac100_phy_init(struct udevice *dev)
220 {
221 	struct ftgmac100_data *priv = dev_get_priv(dev);
222 	struct phy_device *phydev;
223 	int ret;
224 
225 	phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode);
226 	if (!phydev)
227 		return -ENODEV;
228 
229 	phydev->supported &= PHY_GBIT_FEATURES;
230 	if (priv->max_speed) {
231 		ret = phy_set_supported(phydev, priv->max_speed);
232 		if (ret)
233 			return ret;
234 	}
235 	phydev->advertising = phydev->supported;
236 	priv->phydev = phydev;
237 	phy_config(phydev);
238 
239 	return 0;
240 }
241 
242 /*
243  * Reset MAC
244  */
245 static void ftgmac100_reset(struct ftgmac100_data *priv)
246 {
247 	struct ftgmac100 *ftgmac100 = priv->iobase;
248 
249 	debug("%s()\n", __func__);
250 
251 	setbits_le32(&ftgmac100->maccr, FTGMAC100_MACCR_SW_RST);
252 
253 	while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
254 		;
255 }
256 
257 /*
258  * Set MAC address
259  */
260 static int ftgmac100_set_mac(struct ftgmac100_data *priv,
261 			     const unsigned char *mac)
262 {
263 	struct ftgmac100 *ftgmac100 = priv->iobase;
264 	unsigned int maddr = mac[0] << 8 | mac[1];
265 	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
266 
267 	debug("%s(%x %x)\n", __func__, maddr, laddr);
268 
269 	writel(maddr, &ftgmac100->mac_madr);
270 	writel(laddr, &ftgmac100->mac_ladr);
271 
272 	return 0;
273 }
274 
275 /*
276  * disable transmitter, receiver
277  */
278 static void ftgmac100_stop(struct udevice *dev)
279 {
280 	struct ftgmac100_data *priv = dev_get_priv(dev);
281 	struct ftgmac100 *ftgmac100 = priv->iobase;
282 
283 	debug("%s()\n", __func__);
284 
285 	writel(0, &ftgmac100->maccr);
286 
287 	phy_shutdown(priv->phydev);
288 }
289 
290 static int ftgmac100_start(struct udevice *dev)
291 {
292 	struct eth_pdata *plat = dev_get_platdata(dev);
293 	struct ftgmac100_data *priv = dev_get_priv(dev);
294 	struct ftgmac100 *ftgmac100 = priv->iobase;
295 	struct phy_device *phydev = priv->phydev;
296 	unsigned int maccr;
297 	ulong start, end;
298 	int ret;
299 	int i;
300 
301 	debug("%s()\n", __func__);
302 
303 	ftgmac100_reset(priv);
304 
305 	/* set the ethernet address */
306 	ftgmac100_set_mac(priv, plat->enetaddr);
307 
308 	/* disable all interrupts */
309 	writel(0, &ftgmac100->ier);
310 
311 	/* initialize descriptors */
312 	priv->tx_index = 0;
313 	priv->rx_index = 0;
314 
315 	for (i = 0; i < PKTBUFSTX; i++) {
316 		priv->txdes[i].txdes3 = 0;
317 		priv->txdes[i].txdes0 = 0;
318 	}
319 	priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;
320 
321 	start = (ulong)&priv->txdes[0];
322 	end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN);
323 	flush_dcache_range(start, end);
324 
325 	for (i = 0; i < PKTBUFSRX; i++) {
326 		priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
327 		priv->rxdes[i].rxdes0 = 0;
328 	}
329 	priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;
330 
331 	start = (ulong)&priv->rxdes[0];
332 	end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN);
333 	flush_dcache_range(start, end);
334 
335 	/* transmit ring */
336 	writel((u32)priv->txdes, &ftgmac100->txr_badr);
337 
338 	/* receive ring */
339 	writel((u32)priv->rxdes, &ftgmac100->rxr_badr);
340 
341 	/* poll receive descriptor automatically */
342 	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
343 
344 	/* config receive buffer size register */
345 	writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr);
346 
347 	/* enable transmitter, receiver */
348 	maccr = FTGMAC100_MACCR_TXMAC_EN |
349 		FTGMAC100_MACCR_RXMAC_EN |
350 		FTGMAC100_MACCR_TXDMA_EN |
351 		FTGMAC100_MACCR_RXDMA_EN |
352 		FTGMAC100_MACCR_CRC_APD |
353 		FTGMAC100_MACCR_FULLDUP |
354 		FTGMAC100_MACCR_RX_RUNT |
355 		FTGMAC100_MACCR_RX_BROADPKT;
356 
357 	writel(maccr, &ftgmac100->maccr);
358 
359 	ret = phy_startup(phydev);
360 	if (ret) {
361 		dev_err(phydev->dev, "Could not start PHY\n");
362 		return ret;
363 	}
364 
365 	ret = ftgmac100_phy_adjust_link(priv);
366 	if (ret) {
367 		dev_err(phydev->dev,  "Could not adjust link\n");
368 		return ret;
369 	}
370 
371 	printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name,
372 	       phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr);
373 
374 	return 0;
375 }
376 
377 static int ftgmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
378 {
379 	struct ftgmac100_data *priv = dev_get_priv(dev);
380 	struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
381 	ulong des_start = (ulong)curr_des;
382 	ulong des_end = des_start +
383 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
384 
385 	/* Release buffer to DMA and flush descriptor */
386 	curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
387 	flush_dcache_range(des_start, des_end);
388 
389 	/* Move to next descriptor */
390 	priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
391 
392 	return 0;
393 }
394 
395 /*
396  * Get a data block via Ethernet
397  */
398 static int ftgmac100_recv(struct udevice *dev, int flags, uchar **packetp)
399 {
400 	struct ftgmac100_data *priv = dev_get_priv(dev);
401 	struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
402 	unsigned short rxlen;
403 	ulong des_start = (ulong)curr_des;
404 	ulong des_end = des_start +
405 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
406 	ulong data_start = curr_des->rxdes3;
407 	ulong data_end;
408 
409 	invalidate_dcache_range(des_start, des_end);
410 
411 	if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
412 		return -EAGAIN;
413 
414 	if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
415 				FTGMAC100_RXDES0_CRC_ERR |
416 				FTGMAC100_RXDES0_FTL |
417 				FTGMAC100_RXDES0_RUNT |
418 				FTGMAC100_RXDES0_RX_ODD_NB)) {
419 		return -EAGAIN;
420 	}
421 
422 	rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
423 
424 	debug("%s(): RX buffer %d, %x received\n",
425 	       __func__, priv->rx_index, rxlen);
426 
427 	/* Invalidate received data */
428 	data_end = data_start + roundup(rxlen, ARCH_DMA_MINALIGN);
429 	invalidate_dcache_range(data_start, data_end);
430 	*packetp = (uchar *)data_start;
431 
432 	return rxlen;
433 }
434 
435 static u32 ftgmac100_read_txdesc(const void *desc)
436 {
437 	const struct ftgmac100_txdes *txdes = desc;
438 	ulong des_start = (ulong)txdes;
439 	ulong des_end = des_start + roundup(sizeof(*txdes), ARCH_DMA_MINALIGN);
440 
441 	invalidate_dcache_range(des_start, des_end);
442 
443 	return txdes->txdes0;
444 }
445 
446 BUILD_WAIT_FOR_BIT(ftgmac100_txdone, u32, ftgmac100_read_txdesc)
447 
448 /*
449  * Send a data block via Ethernet
450  */
451 static int ftgmac100_send(struct udevice *dev, void *packet, int length)
452 {
453 	struct ftgmac100_data *priv = dev_get_priv(dev);
454 	struct ftgmac100 *ftgmac100 = priv->iobase;
455 	struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
456 	ulong des_start = (ulong)curr_des;
457 	ulong des_end = des_start +
458 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
459 	ulong data_start;
460 	ulong data_end;
461 	int rc;
462 
463 	invalidate_dcache_range(des_start, des_end);
464 
465 	if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
466 		dev_err(dev, "no TX descriptor available\n");
467 		return -EPERM;
468 	}
469 
470 	debug("%s(%x, %x)\n", __func__, (int)packet, length);
471 
472 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
473 
474 	curr_des->txdes3 = (unsigned int)packet;
475 
476 	/* Flush data to be sent */
477 	data_start = curr_des->txdes3;
478 	data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
479 	flush_dcache_range(data_start, data_end);
480 
481 	/* Only one segment on TXBUF */
482 	curr_des->txdes0 &= priv->txdes0_edotr_mask;
483 	curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
484 			    FTGMAC100_TXDES0_LTS |
485 			    FTGMAC100_TXDES0_TXBUF_SIZE(length) |
486 			    FTGMAC100_TXDES0_TXDMA_OWN ;
487 
488 	/* Flush modified buffer descriptor */
489 	flush_dcache_range(des_start, des_end);
490 
491 	/* Start transmit */
492 	writel(1, &ftgmac100->txpd);
493 
494 	rc = wait_for_bit_ftgmac100_txdone(curr_des,
495 					   FTGMAC100_TXDES0_TXDMA_OWN, false,
496 					   FTGMAC100_TX_TIMEOUT_MS, true);
497 	if (rc)
498 		return rc;
499 
500 	debug("%s(): packet sent\n", __func__);
501 
502 	/* Move to next descriptor */
503 	priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
504 
505 	return 0;
506 }
507 
508 static int ftgmac100_write_hwaddr(struct udevice *dev)
509 {
510 	struct eth_pdata *pdata = dev_get_platdata(dev);
511 	struct ftgmac100_data *priv = dev_get_priv(dev);
512 
513 	return ftgmac100_set_mac(priv, pdata->enetaddr);
514 }
515 
516 static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
517 {
518 	struct eth_pdata *pdata = dev_get_platdata(dev);
519 	struct ftgmac100_data *priv = dev_get_priv(dev);
520 	const char *phy_mode;
521 
522 	pdata->iobase = devfdt_get_addr(dev);
523 	pdata->phy_interface = -1;
524 	phy_mode = dev_read_string(dev, "phy-mode");
525 	if (phy_mode)
526 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
527 	if (pdata->phy_interface == -1) {
528 		dev_err(dev, "Invalid PHY interface '%s'\n", phy_mode);
529 		return -EINVAL;
530 	}
531 
532 	pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
533 
534 	if (dev_get_driver_data(dev) == FTGMAC100_MODEL_NEW_ASPEED) {
535 		priv->mdio_addr =  devfdt_get_addr_index(dev, 1);
536 		debug("priv->mdio_addr %x \n", (u32)priv->mdio_addr);
537 
538 	}
539 	if ((dev_get_driver_data(dev) == FTGMAC100_MODEL_ASPEED) ||
540 		(dev_get_driver_data(dev) == FTGMAC100_MODEL_NEW_ASPEED)){
541 		priv->rxdes0_edorr_mask = BIT(30);
542 		priv->txdes0_edotr_mask = BIT(30);
543 	} else {
544 		priv->rxdes0_edorr_mask = BIT(15);
545 		priv->txdes0_edotr_mask = BIT(15);
546 	}
547 
548 	return clk_get_bulk(dev, &priv->clks);
549 }
550 
551 static int ftgmac100_probe(struct udevice *dev)
552 {
553 	struct eth_pdata *pdata = dev_get_platdata(dev);
554 	struct ftgmac100_data *priv = dev_get_priv(dev);
555 	int ret;
556 
557 	priv->iobase = (struct ftgmac100 *)pdata->iobase;
558 	priv->phy_mode = pdata->phy_interface;
559 	priv->max_speed = pdata->max_speed;
560 	priv->phy_addr = 0;
561 
562 	ret = clk_enable_bulk(&priv->clks);
563 	if (ret)
564 		goto out;
565 
566 	ret = ftgmac100_mdio_init(dev);
567 	if (ret) {
568 		dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
569 		goto out;
570 	}
571 
572 	ret = ftgmac100_phy_init(dev);
573 	if (ret) {
574 		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
575 		goto out;
576 	}
577 
578 out:
579 	if (ret)
580 		clk_release_bulk(&priv->clks);
581 
582 	return ret;
583 }
584 
585 static int ftgmac100_remove(struct udevice *dev)
586 {
587 	struct ftgmac100_data *priv = dev_get_priv(dev);
588 
589 	free(priv->phydev);
590 	mdio_unregister(priv->bus);
591 	mdio_free(priv->bus);
592 	clk_release_bulk(&priv->clks);
593 
594 	return 0;
595 }
596 
597 static const struct eth_ops ftgmac100_ops = {
598 	.start	= ftgmac100_start,
599 	.send	= ftgmac100_send,
600 	.recv	= ftgmac100_recv,
601 	.stop	= ftgmac100_stop,
602 	.free_pkt = ftgmac100_free_pkt,
603 	.write_hwaddr = ftgmac100_write_hwaddr,
604 };
605 
606 static const struct udevice_id ftgmac100_ids[] = {
607 	{ .compatible = "faraday,ftgmac100",  .data = FTGMAC100_MODEL_FARADAY },
608 	{ .compatible = "aspeed,ast2500-mac", .data = FTGMAC100_MODEL_ASPEED  },
609 	{ .compatible = "aspeed,ast2600-mac", .data = FTGMAC100_MODEL_NEW_ASPEED  },
610 	{ }
611 };
612 
613 U_BOOT_DRIVER(ftgmac100) = {
614 	.name	= "ftgmac100",
615 	.id	= UCLASS_ETH,
616 	.of_match = ftgmac100_ids,
617 	.ofdata_to_platdata = ftgmac100_ofdata_to_platdata,
618 	.probe	= ftgmac100_probe,
619 	.remove = ftgmac100_remove,
620 	.ops	= &ftgmac100_ops,
621 	.priv_auto_alloc_size = sizeof(struct ftgmac100_data),
622 	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
623 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
624 };
625