diff mbox series

[v4,2/3] dmaengine: dw-axi-dmac: Add support for StarFive JH7110 DMA

Message ID 20230306140430.28951-3-walker.chen@starfivetech.com (mailing list archive)
State Superseded
Headers show
Series Add DMA driver for StarFive JH7110 SoC | expand

Commit Message

Walker Chen March 6, 2023, 2:04 p.m. UTC
Add dma reset operation in device probe and use different configuration
on CH_CFG registers according to match data. Update all uses of
of_device_is_compatible with of_device_get_match_data.

Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 67 ++++++++++++++++---
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  2 +
 2 files changed, 61 insertions(+), 8 deletions(-)

Comments

Emil Renner Berthing March 6, 2023, 2:39 p.m. UTC | #1
On Mon, 6 Mar 2023 at 15:04, Walker Chen <walker.chen@starfivetech.com> wrote:
>
> Add dma reset operation in device probe and use different configuration
> on CH_CFG registers according to match data. Update all uses of
> of_device_is_compatible with of_device_get_match_data.
>
> Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>

Hi Walker,

Again please remove my Reviewed-by when you're adding a bunch of new
code as you're doing here.

> Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
> ---
>  .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 67 ++++++++++++++++---
>  drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  2 +
>  2 files changed, 61 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index bf85aa0979ec..d1148f6fbcf9 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -21,10 +21,12 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/of_dma.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/property.h>
> +#include <linux/reset.h>
>  #include <linux/slab.h>
>  #include <linux/types.h>
>
> @@ -46,6 +48,12 @@
>         DMA_SLAVE_BUSWIDTH_32_BYTES     | \
>         DMA_SLAVE_BUSWIDTH_64_BYTES)
>
> +struct axi_dma_chip_config {
> +       int (*apb_setup)(struct platform_device *pdev, struct axi_dma_chip *chip);
> +       int (*reset_init)(struct platform_device *pdev);
> +       bool use_cfg2;
> +};
> +
>  static inline void
>  axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
>  {
> @@ -86,7 +94,8 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
>
>         cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
>                   config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
> -       if (chan->chip->dw->hdata->reg_map_8_channels) {
> +       if (chan->chip->dw->hdata->reg_map_8_channels &&
> +           !chan->chip->dw->hdata->use_cfg2) {
>                 cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
>                          config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
>                          config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
> @@ -1142,7 +1151,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
>         axi_chan_disable(chan);
>
>         ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
> -                                       !(val & chan_active), 1000, 10000);
> +                                       !(val & chan_active), 1000, DMAC_TIMEOUT_US);
>         if (ret == -ETIMEDOUT)
>                 dev_warn(dchan2dev(dchan),
>                          "%s failed to stop\n", axi_chan_name(chan));
> @@ -1367,13 +1376,33 @@ static int parse_device_properties(struct axi_dma_chip *chip)
>         return 0;
>  }
>
> +static int intel_apb_setup(struct platform_device *pdev, struct axi_dma_chip *chip)
> +{
> +       chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
> +       if (IS_ERR(chip->apb_regs))
> +               return PTR_ERR(chip->apb_regs);
> +       else
> +               return 0;
> +}
> +
> +static int jh7110_reset_init(struct platform_device *pdev)
> +{
> +       struct reset_control *resets;
> +
> +       resets = devm_reset_control_array_get_exclusive(&pdev->dev);
> +       if (IS_ERR(resets))
> +               return PTR_ERR(resets);
> +
> +       return reset_control_deassert(resets);
> +}
> +
>  static int dw_probe(struct platform_device *pdev)
>  {
> -       struct device_node *node = pdev->dev.of_node;
>         struct axi_dma_chip *chip;
>         struct resource *mem;
>         struct dw_axi_dma *dw;
>         struct dw_axi_dma_hcfg *hdata;
> +       const struct axi_dma_chip_config *ccfg;
>         u32 i;
>         int ret;
>
> @@ -1402,10 +1431,21 @@ static int dw_probe(struct platform_device *pdev)
>         if (IS_ERR(chip->regs))
>                 return PTR_ERR(chip->regs);
>
> -       if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
> -               chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
> -               if (IS_ERR(chip->apb_regs))
> -                       return PTR_ERR(chip->apb_regs);
> +       ccfg = of_device_get_match_data(&pdev->dev);
> +       if (ccfg) {
> +               if (ccfg->apb_setup) {
> +                       ret = ccfg->apb_setup(pdev, chip);
> +                       if (ret)
> +                               return ret;
> +               }
> +
> +               if (ccfg->reset_init) {
> +                       ret = ccfg->reset_init(pdev);
> +                       if (ret)
> +                               return ret;
> +               }
> +
> +               chip->dw->hdata->use_cfg2 = ccfg->use_cfg2;

This claims and deasserts the resets before the clocks, whereas your
previous versions did it after turning the clocks on. Which is the
correct order?

Also this certainly gets rid of of_device_is_compatible calls, but
seems like a lot of code to do that. Did you consider something like

+#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
+#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
+#define AXI_DMA_FLAG_USE_CFG2 BIT(2)

+unsigned int flags = (uintptr_t)device_get_match_data(&pdev->dev);

-if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
+if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {

-if (of_device_is_compatible(node, "starfive,jh7110-axi-dma)) {
+if (flags & AXI_DMA_FLAG_HAS_RESETS) {

+chip->dw->hwdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);

-{ .compatible = "intel,kmb-axi-dma" },
+{ .compatible = "intel,kmb-axi-dma", .data = (void
*)AXI_DMA_FLAG_HAS_APB_REGS },
+{ .compatible = "starive,jh7110-axi-dma", .data = (void
*)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2) },

>         }
>
>         chip->core_clk = devm_clk_get(chip->dev, "core-clk");
> @@ -1557,9 +1597,20 @@ static const struct dev_pm_ops dw_axi_dma_pm_ops = {
>         SET_RUNTIME_PM_OPS(axi_dma_runtime_suspend, axi_dma_runtime_resume, NULL)
>  };
>
> +static const struct axi_dma_chip_config intel_chip_config = {
> +       .apb_setup = intel_apb_setup,
> +       .use_cfg2 = false,
> +};
> +
> +static const struct axi_dma_chip_config jh7110_chip_config = {
> +       .reset_init = jh7110_reset_init,
> +       .use_cfg2 = true,
> +};
> +
>  static const struct of_device_id dw_dma_of_id_table[] = {
>         { .compatible = "snps,axi-dma-1.01a" },
> -       { .compatible = "intel,kmb-axi-dma" },
> +       { .compatible = "intel,kmb-axi-dma", .data = &intel_chip_config },
> +       { .compatible = "starfive,jh7110-axi-dma", .data = &jh7110_chip_config },
>         {}
>  };
>  MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> index e9d5eb0fd594..b906d5884efe 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> @@ -21,6 +21,7 @@
>  #define DMAC_MAX_CHANNELS      16
>  #define DMAC_MAX_MASTERS       2
>  #define DMAC_MAX_BLK_SIZE      0x200000
> +#define DMAC_TIMEOUT_US                200000
>
>  struct dw_axi_dma_hcfg {
>         u32     nr_channels;
> @@ -33,6 +34,7 @@ struct dw_axi_dma_hcfg {
>         /* Register map for DMAX_NUM_CHANNELS <= 8 */
>         bool    reg_map_8_channels;
>         bool    restrict_axi_burst_len;
> +       bool    use_cfg2;
>  };
>
>  struct axi_dma_chan {
> --
> 2.17.1
>
Walker Chen March 7, 2023, 1:38 a.m. UTC | #2
On 2023/3/6 22:39, Emil Renner Berthing wrote:
> On Mon, 6 Mar 2023 at 15:04, Walker Chen <walker.chen@starfivetech.com> wrote:
>>
>> Add dma reset operation in device probe and use different configuration
>> on CH_CFG registers according to match data. Update all uses of
>> of_device_is_compatible with of_device_get_match_data.
>>
>> Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
> 
> Hi Walker,
> 
> Again please remove my Reviewed-by when you're adding a bunch of new
> code as you're doing here.

Sorry, I made another simple mistake.

> 
>> Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
>> ---
>>  .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 67 ++++++++++++++++---
>>  drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  2 +
>>  2 files changed, 61 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
>> index bf85aa0979ec..d1148f6fbcf9 100644
>> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
>> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
>> @@ -21,10 +21,12 @@
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>> +#include <linux/of_device.h>
>>  #include <linux/of_dma.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/property.h>
>> +#include <linux/reset.h>
>>  #include <linux/slab.h>
>>  #include <linux/types.h>
>>
>> @@ -46,6 +48,12 @@
>>         DMA_SLAVE_BUSWIDTH_32_BYTES     | \
>>         DMA_SLAVE_BUSWIDTH_64_BYTES)
>>
>> +struct axi_dma_chip_config {
>> +       int (*apb_setup)(struct platform_device *pdev, struct axi_dma_chip *chip);
>> +       int (*reset_init)(struct platform_device *pdev);
>> +       bool use_cfg2;
>> +};
>> +
>>  static inline void
>>  axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
>>  {
>> @@ -86,7 +94,8 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
>>
>>         cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
>>                   config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
>> -       if (chan->chip->dw->hdata->reg_map_8_channels) {
>> +       if (chan->chip->dw->hdata->reg_map_8_channels &&
>> +           !chan->chip->dw->hdata->use_cfg2) {
>>                 cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
>>                          config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
>>                          config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
>> @@ -1142,7 +1151,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
>>         axi_chan_disable(chan);
>>
>>         ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
>> -                                       !(val & chan_active), 1000, 10000);
>> +                                       !(val & chan_active), 1000, DMAC_TIMEOUT_US);
>>         if (ret == -ETIMEDOUT)
>>                 dev_warn(dchan2dev(dchan),
>>                          "%s failed to stop\n", axi_chan_name(chan));
>> @@ -1367,13 +1376,33 @@ static int parse_device_properties(struct axi_dma_chip *chip)
>>         return 0;
>>  }
>>
>> +static int intel_apb_setup(struct platform_device *pdev, struct axi_dma_chip *chip)
>> +{
>> +       chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
>> +       if (IS_ERR(chip->apb_regs))
>> +               return PTR_ERR(chip->apb_regs);
>> +       else
>> +               return 0;
>> +}
>> +
>> +static int jh7110_reset_init(struct platform_device *pdev)
>> +{
>> +       struct reset_control *resets;
>> +
>> +       resets = devm_reset_control_array_get_exclusive(&pdev->dev);
>> +       if (IS_ERR(resets))
>> +               return PTR_ERR(resets);
>> +
>> +       return reset_control_deassert(resets);
>> +}
>> +
>>  static int dw_probe(struct platform_device *pdev)
>>  {
>> -       struct device_node *node = pdev->dev.of_node;
>>         struct axi_dma_chip *chip;
>>         struct resource *mem;
>>         struct dw_axi_dma *dw;
>>         struct dw_axi_dma_hcfg *hdata;
>> +       const struct axi_dma_chip_config *ccfg;
>>         u32 i;
>>         int ret;
>>
>> @@ -1402,10 +1431,21 @@ static int dw_probe(struct platform_device *pdev)
>>         if (IS_ERR(chip->regs))
>>                 return PTR_ERR(chip->regs);
>>
>> -       if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
>> -               chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
>> -               if (IS_ERR(chip->apb_regs))
>> -                       return PTR_ERR(chip->apb_regs);
>> +       ccfg = of_device_get_match_data(&pdev->dev);
>> +       if (ccfg) {
>> +               if (ccfg->apb_setup) {
>> +                       ret = ccfg->apb_setup(pdev, chip);
>> +                       if (ret)
>> +                               return ret;
>> +               }
>> +
>> +               if (ccfg->reset_init) {
>> +                       ret = ccfg->reset_init(pdev);
>> +                       if (ret)
>> +                               return ret;
>> +               }
>> +
>> +               chip->dw->hdata->use_cfg2 = ccfg->use_cfg2;
> 
> This claims and deasserts the resets before the clocks, whereas your
> previous versions did it after turning the clocks on. Which is the
> correct order?

The order has no problem, I have tested it with audio pwmdac on VisionFive2 board.

> 
> Also this certainly gets rid of of_device_is_compatible calls, but
> seems like a lot of code to do that. Did you consider something like
> 
> +#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
> +#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
> +#define AXI_DMA_FLAG_USE_CFG2 BIT(2)
> 
> +unsigned int flags = (uintptr_t)device_get_match_data(&pdev->dev);
> 
> -if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
> +if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {
> 
> -if (of_device_is_compatible(node, "starfive,jh7110-axi-dma)) {
> +if (flags & AXI_DMA_FLAG_HAS_RESETS) {
> 
> +chip->dw->hwdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);
> 
> -{ .compatible = "intel,kmb-axi-dma" },
> +{ .compatible = "intel,kmb-axi-dma", .data = (void
> *)AXI_DMA_FLAG_HAS_APB_REGS },
> +{ .compatible = "starive,jh7110-axi-dma", .data = (void
> *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2) },

Of course, it's better to have less code. I will try your method.

Thank you for taking the time to review and comment.

Best regards,
Walker
diff mbox series

Patch

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index bf85aa0979ec..d1148f6fbcf9 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -21,10 +21,12 @@ 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_dma.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 
@@ -46,6 +48,12 @@ 
 	DMA_SLAVE_BUSWIDTH_32_BYTES	| \
 	DMA_SLAVE_BUSWIDTH_64_BYTES)
 
+struct axi_dma_chip_config {
+	int (*apb_setup)(struct platform_device *pdev, struct axi_dma_chip *chip);
+	int (*reset_init)(struct platform_device *pdev);
+	bool use_cfg2;
+};
+
 static inline void
 axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
 {
@@ -86,7 +94,8 @@  static inline void axi_chan_config_write(struct axi_dma_chan *chan,
 
 	cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
 		  config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
-	if (chan->chip->dw->hdata->reg_map_8_channels) {
+	if (chan->chip->dw->hdata->reg_map_8_channels &&
+	    !chan->chip->dw->hdata->use_cfg2) {
 		cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
 			 config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
 			 config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
@@ -1142,7 +1151,7 @@  static int dma_chan_terminate_all(struct dma_chan *dchan)
 	axi_chan_disable(chan);
 
 	ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
-					!(val & chan_active), 1000, 10000);
+					!(val & chan_active), 1000, DMAC_TIMEOUT_US);
 	if (ret == -ETIMEDOUT)
 		dev_warn(dchan2dev(dchan),
 			 "%s failed to stop\n", axi_chan_name(chan));
@@ -1367,13 +1376,33 @@  static int parse_device_properties(struct axi_dma_chip *chip)
 	return 0;
 }
 
+static int intel_apb_setup(struct platform_device *pdev, struct axi_dma_chip *chip)
+{
+	chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(chip->apb_regs))
+		return PTR_ERR(chip->apb_regs);
+	else
+		return 0;
+}
+
+static int jh7110_reset_init(struct platform_device *pdev)
+{
+	struct reset_control *resets;
+
+	resets = devm_reset_control_array_get_exclusive(&pdev->dev);
+	if (IS_ERR(resets))
+		return PTR_ERR(resets);
+
+	return reset_control_deassert(resets);
+}
+
 static int dw_probe(struct platform_device *pdev)
 {
-	struct device_node *node = pdev->dev.of_node;
 	struct axi_dma_chip *chip;
 	struct resource *mem;
 	struct dw_axi_dma *dw;
 	struct dw_axi_dma_hcfg *hdata;
+	const struct axi_dma_chip_config *ccfg;
 	u32 i;
 	int ret;
 
@@ -1402,10 +1431,21 @@  static int dw_probe(struct platform_device *pdev)
 	if (IS_ERR(chip->regs))
 		return PTR_ERR(chip->regs);
 
-	if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
-		chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
-		if (IS_ERR(chip->apb_regs))
-			return PTR_ERR(chip->apb_regs);
+	ccfg = of_device_get_match_data(&pdev->dev);
+	if (ccfg) {
+		if (ccfg->apb_setup) {
+			ret = ccfg->apb_setup(pdev, chip);
+			if (ret)
+				return ret;
+		}
+
+		if (ccfg->reset_init) {
+			ret = ccfg->reset_init(pdev);
+			if (ret)
+				return ret;
+		}
+
+		chip->dw->hdata->use_cfg2 = ccfg->use_cfg2;
 	}
 
 	chip->core_clk = devm_clk_get(chip->dev, "core-clk");
@@ -1557,9 +1597,20 @@  static const struct dev_pm_ops dw_axi_dma_pm_ops = {
 	SET_RUNTIME_PM_OPS(axi_dma_runtime_suspend, axi_dma_runtime_resume, NULL)
 };
 
+static const struct axi_dma_chip_config intel_chip_config = {
+	.apb_setup = intel_apb_setup,
+	.use_cfg2 = false,
+};
+
+static const struct axi_dma_chip_config jh7110_chip_config = {
+	.reset_init = jh7110_reset_init,
+	.use_cfg2 = true,
+};
+
 static const struct of_device_id dw_dma_of_id_table[] = {
 	{ .compatible = "snps,axi-dma-1.01a" },
-	{ .compatible = "intel,kmb-axi-dma" },
+	{ .compatible = "intel,kmb-axi-dma", .data = &intel_chip_config },
+	{ .compatible = "starfive,jh7110-axi-dma", .data = &jh7110_chip_config },
 	{}
 };
 MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index e9d5eb0fd594..b906d5884efe 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -21,6 +21,7 @@ 
 #define DMAC_MAX_CHANNELS	16
 #define DMAC_MAX_MASTERS	2
 #define DMAC_MAX_BLK_SIZE	0x200000
+#define DMAC_TIMEOUT_US		200000
 
 struct dw_axi_dma_hcfg {
 	u32	nr_channels;
@@ -33,6 +34,7 @@  struct dw_axi_dma_hcfg {
 	/* Register map for DMAX_NUM_CHANNELS <= 8 */
 	bool	reg_map_8_channels;
 	bool	restrict_axi_burst_len;
+	bool	use_cfg2;
 };
 
 struct axi_dma_chan {