diff mbox

[v3,02/10] dmaengine: sun6i: Correct burst length field offsets for H3

Message ID 8ffbdd23-6bf0-4da0-8ce0-4b0e8dc1281d@rwthex-w2-a.rwth-ad.de (mailing list archive)
State Superseded
Headers show

Commit Message

Stefan Brüns Sept. 25, 2017, 12:02 a.m. UTC
For the H3, the burst lengths field offsets in the channel configuration
register differs from earlier SoC generations.

Using the A31 register macros actually configured the H3 controller
do to bursts of length 1 always, which although working leads to higher
bus utilisation.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

---

Changes in v3: None
Changes in v2:
- Use controller specific callback for burst length setting

 drivers/dma/sun6i-dma.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

Comments

kernel test robot Sept. 26, 2017, 9:08 p.m. UTC | #1
Hi Stefan,

[auto build test WARNING on next-20170926]
[also build test WARNING on v4.14-rc2]
[cannot apply to linus/master robh/for-next v4.14-rc2 v4.14-rc1 v4.13]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stefan-Br-ns/dmaengine-sun6i-Correct-setting-of-clock-autogating-register-for-A83T-H3/20170927-021533
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All warnings (new ones prefixed by >>):

   drivers/dma/sun6i-dma.c:119:2: error: function declaration isn't a prototype [-Werror=strict-prototypes]
     void (*clock_autogate_enable)();
     ^
   drivers/dma/sun6i-dma.c: In function 'sun6i_dma_prep_dma_memcpy':
>> drivers/dma/sun6i-dma.c:627:2: warning: passing argument 1 of 'sdev->cfg->set_burst_length' makes pointer from integer without a cast
     sdev->cfg->set_burst_length(v_lli->cfg, burst, burst);
     ^
   drivers/dma/sun6i-dma.c:627:2: note: expected 'u32 *' but argument is of type 'u32'
   drivers/dma/sun6i-dma.c: At top level:
   drivers/dma/sun6i-dma.c:1040:48: error: expected '}' before ';' token
     .set_burst_length = sun6i_set_burst_length_a31;
                                                   ^
   drivers/dma/sun6i-dma.c:1052:58: error: expected '}' before ';' token
     .clock_autogate_enable = sun6i_enable_clock_autogate_a23;
                                                             ^
   drivers/dma/sun6i-dma.c:1060:58: error: expected '}' before ';' token
     .clock_autogate_enable = sun6i_enable_clock_autogate_a23;
                                                             ^
   drivers/dma/sun6i-dma.c:1073:57: error: expected '}' before ';' token
     .clock_autogate_enable = sun6i_enable_clock_autogate_h3;
                                                            ^
   drivers/dma/sun6i-dma.c:1086:58: error: expected '}' before ';' token
     .clock_autogate_enable = sun6i_enable_clock_autogate_a23;
                                                             ^
   drivers/dma/sun6i-dma.c:292:13: warning: 'sun6i_set_burst_length_h3' defined but not used [-Wunused-function]
    static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst)
                ^
   cc1: some warnings being treated as errors

vim +627 drivers/dma/sun6i-dma.c

   584	
   585	static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
   586			struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
   587			size_t len, unsigned long flags)
   588	{
   589		struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
   590		struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
   591		struct sun6i_dma_lli *v_lli;
   592		struct sun6i_desc *txd;
   593		dma_addr_t p_lli;
   594		s8 burst, width;
   595	
   596		dev_dbg(chan2dev(chan),
   597			"%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n",
   598			__func__, vchan->vc.chan.chan_id, &dest, &src, len, flags);
   599	
   600		if (!len)
   601			return NULL;
   602	
   603		txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
   604		if (!txd)
   605			return NULL;
   606	
   607		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
   608		if (!v_lli) {
   609			dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
   610			goto err_txd_free;
   611		}
   612	
   613		v_lli->src = src;
   614		v_lli->dst = dest;
   615		v_lli->len = len;
   616		v_lli->para = NORMAL_WAIT;
   617	
   618		burst = convert_burst(8);
   619		width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
   620		v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
   621			DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
   622			DMA_CHAN_CFG_DST_LINEAR_MODE |
   623			DMA_CHAN_CFG_SRC_LINEAR_MODE |
   624			DMA_CHAN_CFG_SRC_WIDTH(width) |
   625			DMA_CHAN_CFG_DST_WIDTH(width);
   626	
 > 627		sdev->cfg->set_burst_length(v_lli->cfg, burst, burst);
   628	
   629		sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
   630	
   631		sun6i_dma_dump_lli(vchan, v_lli);
   632	
   633		return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
   634	
   635	err_txd_free:
   636		kfree(txd);
   637		return NULL;
   638	}
   639	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index b4a29d1a100d..269d4ea194e8 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -68,13 +68,15 @@ 
 #define DMA_CHAN_CFG_SRC_DRQ(x)		((x) & 0x1f)
 #define DMA_CHAN_CFG_SRC_IO_MODE	BIT(5)
 #define DMA_CHAN_CFG_SRC_LINEAR_MODE	(0 << 5)
-#define DMA_CHAN_CFG_SRC_BURST(x)	(((x) & 0x3) << 7)
+#define DMA_CHAN_CFG_SRC_BURST_A31(x)	(((x) & 0x3) << 7)
+#define DMA_CHAN_CFG_SRC_BURST_H3(x)	(((x) & 0x3) << 6)
 #define DMA_CHAN_CFG_SRC_WIDTH(x)	(((x) & 0x3) << 9)
 
 #define DMA_CHAN_CFG_DST_DRQ(x)		(DMA_CHAN_CFG_SRC_DRQ(x) << 16)
 #define DMA_CHAN_CFG_DST_IO_MODE	(DMA_CHAN_CFG_SRC_IO_MODE << 16)
 #define DMA_CHAN_CFG_DST_LINEAR_MODE	(DMA_CHAN_CFG_SRC_LINEAR_MODE << 16)
-#define DMA_CHAN_CFG_DST_BURST(x)	(DMA_CHAN_CFG_SRC_BURST(x) << 16)
+#define DMA_CHAN_CFG_DST_BURST_A31(x)	(DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
+#define DMA_CHAN_CFG_DST_BURST_H3(x)	(DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
 #define DMA_CHAN_CFG_DST_WIDTH(x)	(DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
 
 #define DMA_CHAN_CUR_SRC	0x10
@@ -115,6 +117,7 @@  struct sun6i_dma_config {
 	 * BSP kernel source code.
 	 */
 	void (*clock_autogate_enable)();
+	void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
 };
 
 /*
@@ -280,6 +283,18 @@  static void sun6i_enable_clock_autogate_h3(struct sun6i_dma_dev *sdev)
 	writel(SUNXI_H3_DMA_GATE_ENABLE, sdev->base + SUNXI_H3_DMA_GATE);
 }
 
+static void sun6i_set_burst_length_a31(u32 *p_cfg, s8 src_burst, s8 dst_burst)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_BURST_A31(src_burst) |
+		  DMA_CHAN_CFG_DST_BURST_A31(dst_burst);
+}
+
+static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_BURST_H3(src_burst) |
+		  DMA_CHAN_CFG_DST_BURST_H3(dst_burst);
+}
+
 static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
 {
 	struct sun6i_desc *txd = pchan->desc;
@@ -559,11 +574,11 @@  static int set_config(struct sun6i_dma_dev *sdev,
 	if (dst_width < 0)
 		return dst_width;
 
-	*p_cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) |
-		DMA_CHAN_CFG_SRC_WIDTH(src_width) |
-		DMA_CHAN_CFG_DST_BURST(dst_burst) |
+	*p_cfg = DMA_CHAN_CFG_SRC_WIDTH(src_width) |
 		DMA_CHAN_CFG_DST_WIDTH(dst_width);
 
+	sdev->cfg->set_burst_length(p_cfg, src_burst, dst_burst);
+
 	return 0;
 }
 
@@ -606,11 +621,11 @@  static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 		DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
 		DMA_CHAN_CFG_DST_LINEAR_MODE |
 		DMA_CHAN_CFG_SRC_LINEAR_MODE |
-		DMA_CHAN_CFG_SRC_BURST(burst) |
 		DMA_CHAN_CFG_SRC_WIDTH(width) |
-		DMA_CHAN_CFG_DST_BURST(burst) |
 		DMA_CHAN_CFG_DST_WIDTH(width);
 
+	sdev->cfg->set_burst_length(v_lli->cfg, burst, burst);
+
 	sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
 	sun6i_dma_dump_lli(vchan, v_lli);
@@ -1022,6 +1037,7 @@  static struct sun6i_dma_config sun6i_a31_dma_cfg = {
 	.nr_max_channels = 16,
 	.nr_max_requests = 30,
 	.nr_max_vchans   = 53,
+	.set_burst_length = sun6i_set_burst_length_a31;
 };
 
 /*
@@ -1034,6 +1050,7 @@  static struct sun6i_dma_config sun8i_a23_dma_cfg = {
 	.nr_max_requests = 24,
 	.nr_max_vchans   = 37,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23;
+	.set_burst_length = sun6i_set_burst_length_a31;
 };
 
 static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
@@ -1041,13 +1058,12 @@  static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
 	.nr_max_requests = 28,
 	.nr_max_vchans   = 39,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23;
+	.set_burst_length = sun6i_set_burst_length_a31;
 };
 
 /*
  * The H3 has 12 physical channels, a maximum DRQ port id of 27,
  * and a total of 34 usable source and destination endpoints.
- * It also supports additional burst lengths and bus widths,
- * and the burst length fields have different offsets.
  */
 
 static struct sun6i_dma_config sun8i_h3_dma_cfg = {
@@ -1055,6 +1071,7 @@  static struct sun6i_dma_config sun8i_h3_dma_cfg = {
 	.nr_max_requests = 27,
 	.nr_max_vchans   = 34,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_h3;
+	.set_burst_length = sun6i_set_burst_length_h3;
 };
 
 /*
@@ -1067,6 +1084,7 @@  static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
 	.nr_max_requests = 23,
 	.nr_max_vchans   = 24,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23;
+	.set_burst_length = sun6i_set_burst_length_a31;
 };
 
 static const struct of_device_id sun6i_dma_match[] = {