Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2889549imm; Wed, 16 May 2018 23:03:05 -0700 (PDT) X-Google-Smtp-Source: AB8JxZogpalRCi8V40oWx9dhF3dilrdOO+msrtsuOWZY2YVRim6kyVTeqjsZPEjeudJZJr4AP43L X-Received: by 2002:a17:902:6f16:: with SMTP id w22-v6mr3879307plk.216.1526536985448; Wed, 16 May 2018 23:03:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526536985; cv=none; d=google.com; s=arc-20160816; b=FSv4E1/4wkAJ7WshKb6ub5GkNdZ/I4W6yGA861WhGkJnhFLX7NYd+X56ggIIYl4kD9 +ZFZybr044QZGJiDI9cTBpfW95w4U2Y+BmhtCqlPlV7yFd69RMwyPtZrNFNyd5dTFVpC t5LLQ9egx4ANrqlfS33Cm9nvOYWDP/I+jGNSpG0f19DEqFB6uCkkcblkphPE3Wi/ZV3+ gLX2ge2RsHLALXEWcHUGwUgoLIIFTmRt8baMEdjvZUqO8G1bX5ieTG6nKwP43QZh89jw Vh6IO6Ck5dvTN7aM4Ml6SNuz0422gbEEN45mzWqSWTAO2wUgGoFFgljbokvARtHe0XPz Gcmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=DDbAefvUeZITg/sIomZ+5e9ZnxZPdee7YcuP1wnWqxM=; b=UwkI6JgXCVGXzWJCa4/bB3OQcheLk4aoghRyX7q7JyW0NG0PohGw+tJA8EYsGCIdvn NKJTJ3j2++zieQHFC7KRA8/WNmYRQLLOo7N0veNWQ+OMMU8oJIAszO/VWbbvMwE5V9aJ 1bGVkELL7sM62ZtWg0Hdz7Ii6Jp7ytVrVUpbbVjkTuBS40w3UBUs9Xcy2o10sQqQhsQN pEpgvdDSNcAGsQnjLJHIPBuA0ntA238ev3svzaRuZ4uKRz8kdzBw9nYaS+wa1pjyIcht 2DuOYgk8VSmgCRM+L5v8am2XO3JgNmmPxPXHJ2YpdpFMuHa3pcLY+p7BwOPX11XpgXj3 wRig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=F87WIlGP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k90-v6si4619930pfh.50.2018.05.16.23.02.50; Wed, 16 May 2018 23:03:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=F87WIlGP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751334AbeEQGCZ (ORCPT + 99 others); Thu, 17 May 2018 02:02:25 -0400 Received: from mail-ot0-f194.google.com ([74.125.82.194]:34484 "EHLO mail-ot0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750865AbeEQGCY (ORCPT ); Thu, 17 May 2018 02:02:24 -0400 Received: by mail-ot0-f194.google.com with SMTP id i5-v6so3770730otf.1 for ; Wed, 16 May 2018 23:02:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=DDbAefvUeZITg/sIomZ+5e9ZnxZPdee7YcuP1wnWqxM=; b=F87WIlGPVb2OsamyXetNhofL5LZ5eolcw4X5txYclnVNy7O+hjAUGIzGmIYBQkXLj1 oSyaP1Y+kwWdy5Nd8MAPrd3ht6YO+kUitRxSpztRM3P9bG72DyPZ+baOUcr8MU3rfOWO PJN/ey1kYpUAAIAIZbKhGCB+bFS5CzVWxGwBc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=DDbAefvUeZITg/sIomZ+5e9ZnxZPdee7YcuP1wnWqxM=; b=gduAiHoNm4VczNukEbZAUJ6N/gEoNhZ5eOPBOw7PG/uqb4sp22qrF0lz98mBsn5ngQ VnegfGhiY8zqDtrGIvNrlJwCXjFgBldW2cnxsvSR0czqycZNnyf3AC3aDbeg86Bv8nZ3 upQyfdNkcJDLcba+zpe115EwVJm/tsITeX41/wnLcW4knw93HjcEIJg4zaGL+halaEqi ZXJpxv8MLFerHLIfT6PRX1w+QBpXBZAyJ2fAxG9XFfwitDaE18gZXOk+FD/jU3ZQeG64 xxxZpcgM1A2SPuDicvD81EX9q0TTiwzOVVa/HkQ1sxykY6XNWop/gonxJxo3VHcXCwd3 M+WQ== X-Gm-Message-State: ALKqPwdo9OGwWoxMK5WgQea4ctTY4l9slKUN++vTN2cMVXH0ES6kFjYb l4YRLKevpeOcIOkLCALOkislI7fUFNgf8ZHYBdPcQQ== X-Received: by 2002:a9d:2302:: with SMTP id j2-v6mr2929519otb.141.1526536943242; Wed, 16 May 2018 23:02:23 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a9d:2d77:0:0:0:0:0 with HTTP; Wed, 16 May 2018 23:02:22 -0700 (PDT) In-Reply-To: <20180517051447.GS13271@vkoul-mobl> References: <08819489e52add194fecf2b4b234fff9deecdb4c.1526043689.git.baolin.wang@linaro.org> <85413038c111c58747194dd5736834be9adb0f20.1526043689.git.baolin.wang@linaro.org> <20180517051447.GS13271@vkoul-mobl> From: Baolin Wang Date: Thu, 17 May 2018 14:02:22 +0800 Message-ID: Subject: Re: [PATCH v3 2/2] dmaengine: sprd: Add Spreadtrum DMA configuration To: Vinod Cc: Dan Williams , Eric Long , Mark Brown , dmaengine@vger.kernel.org, LKML Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Vinod, On 17 May 2018 at 13:14, Vinod wrote: > On 11-05-18, 21:06, Baolin Wang wrote: >> +struct sprd_dma_config { >> + struct dma_slave_config cfg; >> + u32 block_len; >> + u32 transcation_len; > > /s/transcation/transaction OK. > > now in code I see block_len and this filled by len which is sg_dma_len()? > So why two varibales when you are using only one. Like I explained before, we have transaction transfer, block transfer and fragment transfer, and we should set the length for each transfer. In future, we we will use these two variables in cyclic mode, but for prep_sg, we just make them equal to > > Second, you are storing parameters programmed thru _prep call into > _dma_config. That is not correct. > > We use these to store channel parameters and NOT transaction parameters which > would differ with each txn. No wonder you can only support only 1 txn :) Fine, we can remove block_len/transcation_len from 'struct sprd_dma_config'. Any other issues for the 'struct sprd_dma_config'? > > Lastly, if these are same values why not use src/dstn_max_burst? The fragment length will be filled by src/dstn_max_burst,so we can not use it again. > >> +static enum sprd_dma_datawidth >> +sprd_dma_get_datawidth(enum dma_slave_buswidth buswidth) >> +{ >> + switch (buswidth) { >> + case DMA_SLAVE_BUSWIDTH_1_BYTE: >> + case DMA_SLAVE_BUSWIDTH_2_BYTES: >> + case DMA_SLAVE_BUSWIDTH_4_BYTES: >> + case DMA_SLAVE_BUSWIDTH_8_BYTES: >> + return ffs(buswidth) - 1; >> + default: >> + return SPRD_DMA_DATAWIDTH_4_BYTES; > > Does default make sense, should we error out? Not one error, maybe we can give some warning information. > >> +static u32 sprd_dma_get_step(enum dma_slave_buswidth buswidth) >> +{ >> + switch (buswidth) { >> + case DMA_SLAVE_BUSWIDTH_1_BYTE: >> + case DMA_SLAVE_BUSWIDTH_2_BYTES: >> + case DMA_SLAVE_BUSWIDTH_4_BYTES: >> + case DMA_SLAVE_BUSWIDTH_8_BYTES: >> + return buswidth; >> + >> + default: >> + return SPRD_DMA_DWORD_STEP; > > Does default make sense, should we error out? Ditto. > >> +static int sprd_dma_config(struct dma_chan *chan, struct sprd_dma_desc *sdesc, >> + dma_addr_t src, dma_addr_t dst, >> + struct sprd_dma_config *slave_cfg) >> +{ >> + struct sprd_dma_dev *sdev = to_sprd_dma_dev(chan); >> + struct sprd_dma_chn *schan = to_sprd_dma_chan(chan); >> + struct sprd_dma_chn_hw *hw = &sdesc->chn_hw; >> + u32 fix_mode = 0, fix_en = 0, wrap_en = 0, wrap_mode = 0; >> + u32 src_datawidth, dst_datawidth, temp; >> + >> + if (slave_cfg->cfg.slave_id) >> + schan->dev_id = slave_cfg->cfg.slave_id; >> + >> + hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET; >> + >> + temp = slave_cfg->wrap_ptr & SPRD_DMA_LOW_ADDR_MASK; >> + temp |= (src >> SPRD_DMA_HIGH_ADDR_OFFSET) & SPRD_DMA_HIGH_ADDR_MASK; >> + hw->wrap_ptr = temp; >> + >> + temp = slave_cfg->wrap_to & SPRD_DMA_LOW_ADDR_MASK; >> + temp |= (dst >> SPRD_DMA_HIGH_ADDR_OFFSET) & SPRD_DMA_HIGH_ADDR_MASK; >> + hw->wrap_to = temp; >> + >> + hw->src_addr = src & SPRD_DMA_LOW_ADDR_MASK; >> + hw->des_addr = dst & SPRD_DMA_LOW_ADDR_MASK; >> + >> + if ((slave_cfg->src_step != 0 && slave_cfg->dst_step != 0) >> + || (slave_cfg->src_step | slave_cfg->dst_step) == 0) { > > this check doesnt seem right to me, what are you trying here? This is SPRD DMA internal feature: address-fix transfer. If the src step and dst step both are 0 or both are not 0, that means we can not enable the fix mode. If one is 0 and another one is not, we can enable the fix mode. > >> + fix_en = 0; >> + } else { >> + fix_en = 1; >> + if (slave_cfg->src_step) >> + fix_mode = 1; >> + else >> + fix_mode = 0; >> + } >> + >> + if (slave_cfg->wrap_ptr && slave_cfg->wrap_to) { >> + wrap_en = 1; >> + if (slave_cfg->wrap_to == src) { >> + wrap_mode = 0; >> + } else if (slave_cfg->wrap_to == dst) { >> + wrap_mode = 1; >> + } else { >> + dev_err(sdev->dma_dev.dev, "invalid wrap mode\n"); >> + return -EINVAL; >> + } >> + } >> + >> + hw->intc = slave_cfg->int_mode | SPRD_DMA_CFG_ERR_INT_EN; >> + >> + src_datawidth = sprd_dma_get_datawidth(slave_cfg->cfg.src_addr_width); >> + dst_datawidth = sprd_dma_get_datawidth(slave_cfg->cfg.dst_addr_width); >> + >> + temp = src_datawidth << SPRD_DMA_SRC_DATAWIDTH_OFFSET; >> + temp |= dst_datawidth << SPRD_DMA_DES_DATAWIDTH_OFFSET; >> + temp |= slave_cfg->req_mode << SPRD_DMA_REQ_MODE_OFFSET; >> + temp |= wrap_mode << SPRD_DMA_WRAP_SEL_OFFSET; >> + temp |= wrap_en << SPRD_DMA_WRAP_EN_OFFSET; >> + temp |= fix_mode << SPRD_DMA_FIX_SEL_OFFSET; >> + temp |= fix_en << SPRD_DMA_FIX_EN_OFFSET; >> + temp |= slave_cfg->cfg.src_maxburst & SPRD_DMA_FRG_LEN_MASK; >> + hw->frg_len = temp; >> + >> + hw->blk_len = slave_cfg->block_len & SPRD_DMA_BLK_LEN_MASK; >> + hw->trsc_len = slave_cfg->transcation_len & SPRD_DMA_TRSC_LEN_MASK; >> + >> + temp = (slave_cfg->dst_step & SPRD_DMA_TRSF_STEP_MASK) << >> + SPRD_DMA_DEST_TRSF_STEP_OFFSET; >> + temp |= (slave_cfg->src_step & SPRD_DMA_TRSF_STEP_MASK) << >> + SPRD_DMA_SRC_TRSF_STEP_OFFSET; >> + hw->trsf_step = temp; >> + >> + hw->frg_step = 0; >> + hw->src_blk_step = 0; >> + hw->des_blk_step = 0; >> + return 0; >> +} >> +static struct dma_async_tx_descriptor * >> +sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, >> + unsigned int sglen, enum dma_transfer_direction dir, >> + unsigned long flags, void *context) >> +{ >> + struct sprd_dma_chn *schan = to_sprd_dma_chan(chan); >> + struct sprd_dma_config *slave_cfg = &schan->slave_cfg; >> + u32 src_step = 0, dst_step = 0, len = 0; >> + dma_addr_t src = 0, dst = 0; >> + struct sprd_dma_desc *sdesc; >> + struct scatterlist *sg; >> + int ret, i; >> + >> + /* TODO: now we only support one sg for each DMA configuration. */ >> + if (!is_slave_direction(dir) || sglen > 1) >> + return NULL; >> + >> + sdesc = kzalloc(sizeof(*sdesc), GFP_NOWAIT); >> + if (!sdesc) >> + return NULL; >> + >> + for_each_sg(sgl, sg, sglen, i) { >> + len = sg_dma_len(sg); >> + >> + if (dir == DMA_MEM_TO_DEV) { >> + src = sg_dma_address(sg); >> + dst = slave_cfg->cfg.dst_addr; >> + src_step = sprd_dma_get_step(slave_cfg->cfg.src_addr_width); >> + dst_step = SPRD_DMA_NONE_STEP; >> + } else { >> + src = slave_cfg->cfg.src_addr; >> + dst = sg_dma_address(sg); >> + src_step = SPRD_DMA_NONE_STEP; >> + dst_step = sprd_dma_get_step(slave_cfg->cfg.dst_addr_width); >> + } >> + } >> + >> + sprd_dma_fill_config(slave_cfg, src_step, dst_step, len, flags); >> + >> + ret = sprd_dma_config(chan, sdesc, src, dst, slave_cfg); >> + if (ret) { >> + kfree(sdesc); >> + return NULL; >> + } > > Am more intrigued here, the above call fills you config struct but you do not > use it.. so what is the use of that. I did not get you here. We have passed the slave_cfg to sprd_dma_config() to configure DMA hardware channel. Thanks. -- Baolin.wang Best Regards