summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hu <andy.hu@starfivetech.com>2023-08-31 05:06:00 +0300
committerAndy Hu <andy.hu@starfivetech.com>2023-08-31 05:06:00 +0300
commitc698aee1b2dc0772f4a8ea5f2777b9e5710630d2 (patch)
tree076e91dc5144cc79f24696064026ac844e1449c9
parent05533e9c31d6f0da20efc2d436a3b0f6d516ed4b (diff)
parent45c6eeaad9c30b4b558b1ad8380332eb257b4884 (diff)
downloadlinux-c698aee1b2dc0772f4a8ea5f2777b9e5710630d2.tar.xz
Merge tag 'JH7110_515_SDK_v5.7.0' into vf2-515-devel
-rw-r--r--[-rwxr-xr-x]arch/riscv/boot/dts/starfive/jh7110.dtsi23
-rw-r--r--drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c390
-rw-r--r--drivers/dma/dw-axi-dmac/dw-axi-dmac.h105
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-hw.c24
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c193
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpuapi.h1
-rw-r--r--drivers/net/can/ipms_canfd.c2
-rw-r--r--sound/soc/starfive/starfive_pwmdac.c52
-rw-r--r--sound/soc/starfive/starfive_tdm.c46
9 files changed, 297 insertions, 539 deletions
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 1998e00fe8de..a2831f719bca 100755..100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -629,7 +629,7 @@
};
dma: dma-controller@16050000 {
- compatible = "starfive,jh7110-dma", "snps,axi-dma-1.01a";
+ compatible = "starfive,jh7110-axi-dma";
dma-coherent;
reg = <0x0 0x16050000 0x0 0x10000>;
clocks = <&clkgen JH7110_DMA1P_CLK_AXI>,
@@ -639,13 +639,11 @@
resets = <&rstgen RSTN_U0_DW_DMA1P_AXI>,
<&rstgen RSTN_U0_DW_DMA1P_AHB>,
<&rstgen RSTN_U0_NOC_BUS_STG_AXI_N>;
- reset-names = "rst_axi", "rst_ahb", "rst_stg";
interrupts = <73>;
- #dma-cells = <2>;
+ #dma-cells = <1>;
dma-channels = <4>;
snps,dma-masters = <1>;
snps,data-width = <3>;
- snps,num-hs-if = <56>;
snps,block-size = <65536 65536 65536 65536>;
snps,priority = <0 1 2 3>;
snps,axi-max-burst-len = <15>;
@@ -966,6 +964,7 @@
jpu: jpu@11900000 {
compatible = "starfive,jpu";
+ dma-coherent;
reg = <0x0 0x13090000 0x0 0x300>;
interrupts = <14>;
clocks = <&clkgen JH7110_CODAJ12_CLK_AXI>,
@@ -984,6 +983,7 @@
vpu_dec: vpu_dec@130A0000 {
compatible = "starfive,vdec";
+ dma-coherent;
reg = <0x0 0x130A0000 0x0 0x10000>;
interrupts = <13>;
clocks = <&clkgen JH7110_WAVE511_CLK_AXI>,
@@ -1007,6 +1007,7 @@
vpu_enc: vpu_enc@130B0000 {
compatible = "starfive,venc";
+ dma-coherent;
reg = <0x0 0x130B0000 0x0 0x10000>;
interrupts = <15>;
clocks = <&clkgen JH7110_WAVE420L_CLK_AXI>,
@@ -1208,7 +1209,7 @@
<&rstgen RSTN_U0_TDM16SLOT_APB>,
<&rstgen RSTN_U0_TDM16SLOT_TDM>;
reset-names = "tdm_ahb", "tdm_apb", "tdm_rst";
- dmas = <&dma 20 1>, <&dma 21 1>;
+ dmas = <&dma 20>, <&dma 21>;
dma-names = "rx","tx";
#sound-dai-cells = <0>;
status = "disabled";
@@ -1242,7 +1243,7 @@
clock-names = "apb0", "pwmdac-apb", "pwmdac-core";
resets = <&rstgen RSTN_U0_PWMDAC_APB>;
reset-names = "rst-apb";
- dmas = <&dma 22 1>;
+ dmas = <&dma 22>;
dma-names = "tx";
#sound-dai-cells = <0>;
status = "disabled";
@@ -1253,7 +1254,7 @@
reg = <0x0 0x100c0000 0x0 0x1000>;
interrupt-names = "tx";
#sound-dai-cells = <0>;
- dmas = <&dma 28 1>;
+ dmas = <&dma 28>;
dma-names = "rx";
status = "disabled";
};
@@ -1293,7 +1294,7 @@
resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>,
<&rstgen RSTN_U0_I2SRX_3CH_BCLK>;
reset-names = "rst_apb_rx", "rst_bclk_rx";
- dmas = <&dma 24 1>;
+ dmas = <&dma 24>;
dma-names = "rx";
starfive,sys-syscon = <&sys_syscon 0x18 0x34>;
#sound-dai-cells = <0>;
@@ -1323,7 +1324,7 @@
"bclk-ext", "lrck-ext";
resets = <&rstgen RSTN_U0_I2SRX_3CH_APB>,
<&rstgen RSTN_U0_I2SRX_3CH_BCLK>;
- dmas = <&dma 24 1>;
+ dmas = <&dma 24>;
dma-names = "rx";
starfive,sys-syscon = <&sys_syscon 0x18 0x34>;
#sound-dai-cells = <0>;
@@ -1348,7 +1349,7 @@
resets = <&rstgen RSTN_U0_I2STX_4CH_APB>,
<&rstgen RSTN_U0_I2STX_4CH_BCLK>;
reset-names = "rst_apb", "rst_bclk";
- dmas = <&dma 47 1>;
+ dmas = <&dma 47>;
dma-names = "tx";
#sound-dai-cells = <0>;
status = "disabled";
@@ -1377,7 +1378,7 @@
"mclk_ext", "bclk_ext", "lrck_ext";
resets = <&rstgen RSTN_U1_I2STX_4CH_APB>,
<&rstgen RSTN_U1_I2STX_4CH_BCLK>;
- dmas = <&dma 48 1>;
+ dmas = <&dma 48>;
dma-names = "tx";
#sound-dai-cells = <0>;
status = "disabled";
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 a4e690ecbe1b..0d4d6130c427 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
// (C) 2017-2018 Synopsys, Inc. (www.synopsys.com)
/*
@@ -21,24 +21,23 @@
#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>
-#include <linux/reset.h>
#include "dw-axi-dmac.h"
#include "../dmaengine.h"
#include "../virt-dma.h"
-#include <soc/starfive/vic7100.h>
-
/*
* The set of bus widths supported by the DMA controller. DW AXI DMAC supports
* master data bus width up to 512 bits (for both AXI master interfaces), but
- * it depends on IP block configurarion.
+ * it depends on IP block configuration.
*/
#define AXI_DMA_BUSWIDTHS \
(DMA_SLAVE_BUSWIDTH_1_BYTE | \
@@ -49,6 +48,10 @@
DMA_SLAVE_BUSWIDTH_32_BYTES | \
DMA_SLAVE_BUSWIDTH_64_BYTES)
+#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)
+
static inline void
axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
{
@@ -82,6 +85,36 @@ axi_chan_iowrite64(struct axi_dma_chan *chan, u32 reg, u64 val)
iowrite32(upper_32_bits(val), chan->chan_regs + reg + 4);
}
+static inline void axi_chan_config_write(struct axi_dma_chan *chan,
+ struct axi_dma_chan_config *config)
+{
+ u32 cfg_lo, cfg_hi;
+
+ 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 &&
+ !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 |
+ config->src_per << CH_CFG_H_SRC_PER_POS |
+ config->dst_per << CH_CFG_H_DST_PER_POS |
+ config->prior << CH_CFG_H_PRIORITY_POS;
+ } else {
+ cfg_lo |= config->src_per << CH_CFG2_L_SRC_PER_POS |
+ config->dst_per << CH_CFG2_L_DST_PER_POS;
+ cfg_hi = config->tt_fc << CH_CFG2_H_TT_FC_POS |
+ config->hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS |
+ config->hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS |
+ config->prior << CH_CFG2_H_PRIORITY_POS;
+ }
+
+ cfg_hi |= CH_CFG_H_MAX_OSR_LMT << CH_CFG_H_SRC_OSR_LMT_POS |
+ CH_CFG_H_MAX_OSR_LMT << CH_CFG_H_DST_OSR_LMT_POS;
+ axi_chan_iowrite32(chan, CH_CFG_L, cfg_lo);
+ axi_chan_iowrite32(chan, CH_CFG_H, cfg_hi);
+}
+
static inline void axi_dma_disable(struct axi_dma_chip *chip)
{
u32 val;
@@ -151,89 +184,54 @@ static inline u32 axi_chan_irq_read(struct axi_dma_chan *chan)
return axi_chan_ioread32(chan, CH_INTSTATUS);
}
-static void axi_chan_set_multi_reg(struct axi_dma_chip *chip)
-{
- struct dma_multi *multi = &chip->multi;
-
- /* cfg_2 Exists: (DMAX_NUM_CHANNELS > 8 || DMAX_NUM_HS_IF > 16) */
- if (multi->ch_cfg_2 == true) {
- multi->cfg.ch_cfg_priority_pos = CH_CFG_H_PRIORITY_POS_2;
- multi->cfg.ch_cfg_dst_per_pos = CH_CFG_L_DST_PER_POS_2;
- multi->cfg.ch_cfg_src_per_pos = CH_CFG_L_SRC_PER_POS_2;
- } else {
- multi->cfg.ch_cfg_priority_pos = CH_CFG_H_PRIORITY_POS;
- multi->cfg.ch_cfg_dst_per_pos = CH_CFG_H_DST_PER_POS;
- multi->cfg.ch_cfg_src_per_pos = CH_CFG_H_SRC_PER_POS;
- }
-
- /* en_2 Exists: DMAX_NUM_CHANNELS > 8 */
- if (multi->ch_enreg_2 == true) {
- multi->en.ch_en = DMAC_CHEN_2;
- multi->en.ch_en_shift = DMAC_CHAN_EN_SHIFT_2;
- multi->en.ch_en_we_shift = DMAC_CHAN_EN_WE_SHIFT_2;
-
- multi->en.ch_susp = DMAC_CHSUSP_2;
- multi->en.ch_susp_shift = DMAC_CHAN_SUSP_SHIFT_2;
- multi->en.ch_susp_we_shift = DMAC_CHAN_SUSP_WE_SHIFT_2;
-
- multi->en.ch_abort = DMAC_CHABORT_2;
- multi->en.ch_abort_shift = DMAC_CHAN_ABORT_SHIFT_2;
- multi->en.ch_abort_we_shfit = DMAC_CHAN_ABORT_WE_SHIFT_2;
- } else {
- multi->en.ch_en = DMAC_CHEN;
- multi->en.ch_en_shift = DMAC_CHAN_EN_SHIFT;
- multi->en.ch_en_we_shift = DMAC_CHAN_EN_WE_SHIFT;
-
- multi->en.ch_susp = DMAC_CHSUSP;
- multi->en.ch_susp_shift = DMAC_CHAN_SUSP_SHIFT;
- multi->en.ch_susp_we_shift = DMAC_CHAN_SUSP_WE_SHIFT;
-
- multi->en.ch_abort = DMAC_CHABORT;
- multi->en.ch_abort_shift = DMAC_CHAN_ABORT_SHIFT;
- multi->en.ch_abort_we_shfit = DMAC_CHAN_ABORT_WE_SHIFT;
- }
-}
-
static inline void axi_chan_disable(struct axi_dma_chan *chan)
{
- struct dma_multi *multi = &chan->chip->multi;
u32 val;
- val = axi_dma_ioread32(chan->chip, multi->en.ch_en);
- val &= ~(BIT(chan->id) << multi->en.ch_en_shift);
- val |= BIT(chan->id) << multi->en.ch_en_we_shift;
- axi_dma_iowrite32(chan->chip, multi->en.ch_en, val);
+ val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ val &= ~(BIT(chan->id) << DMAC_CHAN_EN_SHIFT);
+ if (chan->chip->dw->hdata->reg_map_8_channels)
+ val |= BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT;
+ else
+ val |= BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT;
+ axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
}
static inline void axi_chan_enable(struct axi_dma_chan *chan)
{
- struct dma_multi *multi = &chan->chip->multi;
u32 val;
- val = axi_dma_ioread32(chan->chip, multi->en.ch_en);
- val |= BIT(chan->id) << multi->en.ch_en_shift |
- BIT(chan->id) << multi->en.ch_en_we_shift;
- axi_dma_iowrite32(chan->chip, multi->en.ch_en, val);
+ val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ if (chan->chip->dw->hdata->reg_map_8_channels)
+ val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT |
+ BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT;
+ else
+ val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT |
+ BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT;
+ axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
}
static inline bool axi_chan_is_hw_enable(struct axi_dma_chan *chan)
{
- struct dma_multi *multi = &chan->chip->multi;
u32 val;
- val = axi_dma_ioread32(chan->chip, multi->en.ch_en);
+ val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
- return !!(val & (BIT(chan->id) << multi->en.ch_en_shift));
+ return !!(val & (BIT(chan->id) << DMAC_CHAN_EN_SHIFT));
}
static void axi_dma_hw_init(struct axi_dma_chip *chip)
{
+ int ret;
u32 i;
for (i = 0; i < chip->dw->hdata->nr_channels; i++) {
axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
axi_chan_disable(&chip->dw->chan[i]);
}
+ ret = dma_set_mask_and_coherent(chip->dev, DMA_BIT_MASK(64));
+ if (ret)
+ dev_warn(chip->dev, "Unable to set coherent mask\n");
}
static u32 axi_chan_get_xfer_width(struct axi_dma_chan *chan, dma_addr_t src,
@@ -337,12 +335,11 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
len = vd_to_axi_desc(vdesc)->hw_desc[0].len;
completed_length = completed_blocks * len;
bytes = length - completed_length;
- spin_unlock_irqrestore(&chan->vc.lock, flags);
- dma_set_residue(txstate, bytes);
- } else {
- spin_unlock_irqrestore(&chan->vc.lock, flags);
}
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+ dma_set_residue(txstate, bytes);
+
return status;
}
@@ -379,14 +376,13 @@ static void dw_axi_dma_set_byte_halfword(struct axi_dma_chan *chan, bool set)
iowrite32(val, chan->chip->apb_regs + offset);
}
-
/* Called in chan locked context */
static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
struct axi_dma_desc *first)
{
- struct dma_multi *multi = &chan->chip->multi;
u32 priority = chan->chip->dw->hdata->priority[chan->id];
- u32 reg_lo, reg_hi, irq_mask;
+ struct axi_dma_chan_config config = {};
+ u32 irq_mask;
u8 lms = 0; /* Select AXI0 master for LLI fetching */
if (unlikely(axi_chan_is_hw_enable(chan))) {
@@ -398,65 +394,36 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
axi_dma_enable(chan->chip);
- reg_lo = (DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_DST_MULTBLK_TYPE_POS |
- DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
-
- reg_hi = (DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC << CH_CFG_H_TT_FC_POS |
- priority << multi->cfg.ch_cfg_priority_pos |
- DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_DST_POS |
- DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS);
+ config.dst_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
+ config.src_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
+ config.tt_fc = DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC;
+ config.prior = priority;
+ config.hs_sel_dst = DWAXIDMAC_HS_SEL_HW;
+ config.hs_sel_src = DWAXIDMAC_HS_SEL_HW;
switch (chan->direction) {
case DMA_MEM_TO_DEV:
dw_axi_dma_set_byte_halfword(chan, true);
- reg_hi |= (chan->config.device_fc ?
- DWAXIDMAC_TT_FC_MEM_TO_PER_DST :
- DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC)
- << CH_CFG_H_TT_FC_POS;
+ config.tt_fc = chan->config.device_fc ?
+ DWAXIDMAC_TT_FC_MEM_TO_PER_DST :
+ DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC;
if (chan->chip->apb_regs)
- reg_hi |= (chan->id << CH_CFG_H_DST_PER_POS);
+ config.dst_per = chan->id;
+ else
+ config.dst_per = chan->hw_handshake_num;
break;
case DMA_DEV_TO_MEM:
- reg_hi |= (chan->config.device_fc ?
- DWAXIDMAC_TT_FC_PER_TO_MEM_SRC :
- DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC)
- << CH_CFG_H_TT_FC_POS;
+ config.tt_fc = chan->config.device_fc ?
+ DWAXIDMAC_TT_FC_PER_TO_MEM_SRC :
+ DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC;
if (chan->chip->apb_regs)
- reg_hi |= (chan->id << CH_CFG_H_SRC_PER_POS);
+ config.src_per = chan->id;
+ else
+ config.src_per = chan->hw_handshake_num;
break;
default:
break;
}
-
- reg_hi |= CH_CFG_H_MAX_OSR_LMT << CH_CFG_H_SRC_OSR_LMT_POS |
- CH_CFG_H_MAX_OSR_LMT << CH_CFG_H_DST_OSR_LMT_POS;
-
- if (chan->hw_handshake_num) {
- switch (chan->direction) {
- case DMA_MEM_TO_DEV:
- if (multi->ch_cfg_2 == true)
- reg_lo |= chan->hw_handshake_num
- << multi->cfg.ch_cfg_dst_per_pos;
- else
- reg_hi |= chan->hw_handshake_num
- << multi->cfg.ch_cfg_dst_per_pos;
-
- break;
- case DMA_DEV_TO_MEM:
- if (multi->ch_cfg_2 == true)
- reg_lo |= chan->hw_handshake_num
- << multi->cfg.ch_cfg_src_per_pos;
- else
- reg_hi |= chan->hw_handshake_num
- << multi->cfg.ch_cfg_src_per_pos;
-
- break;
- default:
- break;
- }
- }
-
- axi_chan_iowrite32(chan, CH_CFG_L, reg_lo);
- axi_chan_iowrite32(chan, CH_CFG_H, reg_hi);
+ axi_chan_config_write(chan, &config);
write_chan_llp(chan, first->hw_desc[0].llp | lms);
@@ -467,17 +434,6 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
irq_mask |= DWAXIDMAC_IRQ_SUSPENDED;
axi_chan_irq_set(chan, irq_mask);
- /*flush all the desc */
-#ifdef CONFIG_SOC_STARFIVE_VIC7100
- if (chan->chip->multi.need_flush == true) {
- int count = atomic_read(&chan->descs_allocated);
- int i;
-
- for (i = 0; i < count; i++) {
- starfive_flush_dcache(first->hw_desc[i].llp,
- sizeof(*first->hw_desc[i].lli));
- }
-#endif
axi_chan_enable(chan);
}
@@ -593,6 +549,8 @@ static void dw_axi_dma_set_hw_channel(struct axi_dma_chan *chan, bool set)
(chan->id * DMA_APB_HS_SEL_BIT_SIZE));
reg_value |= (val << (chan->id * DMA_APB_HS_SEL_BIT_SIZE));
lo_hi_writeq(reg_value, chip->apb_regs + DMAC_APB_HW_HS_SEL_0);
+
+ return;
}
/*
@@ -657,7 +615,6 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
size_t block_ts;
u32 ctllo, ctlhi;
u32 burst_len;
- u32 burst_trans_len;
axi_block_ts = chan->chip->dw->hdata->block_size[chan->id];
@@ -721,14 +678,8 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
- if (chan->fixed_burst_trans_len == true)
- burst_trans_len = chan->burst_trans_len;
- else
- burst_trans_len = DWAXIDMAC_BURST_TRANS_LEN_4;
-
- ctllo |= burst_trans_len << CH_CTL_L_DST_MSIZE_POS |
- burst_trans_len << CH_CTL_L_SRC_MSIZE_POS;
-
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
set_desc_src_master(hw_desc);
@@ -793,10 +744,6 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr,
num_segments = DIV_ROUND_UP(period_len, axi_block_len);
segment_len = DIV_ROUND_UP(period_len, num_segments);
- if (!IS_ALIGNED(segment_len, 4)) {
- segment_len = ALIGN(segment_len, 4);
- period_len = segment_len * num_segments;
- }
total_segments = num_periods * num_segments;
@@ -1043,6 +990,11 @@ static int dw_axi_dma_chan_slave_config(struct dma_chan *dchan,
static void axi_chan_dump_lli(struct axi_dma_chan *chan,
struct axi_dma_hw_desc *desc)
{
+ if (!desc->lli) {
+ dev_err(dchan2dev(&chan->vc.chan), "NULL LLI\n");
+ return;
+ }
+
dev_err(dchan2dev(&chan->vc.chan),
"SAR: 0x%llx DAR: 0x%llx LLP: 0x%llx BTS 0x%x CTL: 0x%x:%08x",
le64_to_cpu(desc->lli->sar),
@@ -1074,6 +1026,11 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
/* The bad descriptor currently is in the head of vc list */
vd = vchan_next_desc(&chan->vc);
+ if (!vd) {
+ dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
+ axi_chan_name(chan));
+ goto out;
+ }
/* Remove the completed descriptor from issued list */
list_del(&vd->node);
@@ -1088,6 +1045,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
/* Try to restart the controller */
axi_chan_start_first_queued(chan);
+out:
spin_unlock_irqrestore(&chan->vc.lock, flags);
}
@@ -1103,14 +1061,18 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
spin_lock_irqsave(&chan->vc.lock, flags);
if (unlikely(axi_chan_is_hw_enable(chan))) {
- dev_err(chan2dev(chan),
- "BUG: %s caught DWAXIDMAC_IRQ_DMA_TRF, but channel not idle!\n",
+ dev_err(chan2dev(chan), "BUG: %s caught DWAXIDMAC_IRQ_DMA_TRF, but channel not idle!\n",
axi_chan_name(chan));
axi_chan_disable(chan);
}
/* The completed descriptor currently is in the head of vc list */
vd = vchan_next_desc(&chan->vc);
+ if (!vd) {
+ dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
+ axi_chan_name(chan));
+ goto out;
+ }
if (chan->cyclic) {
desc = vd_to_axi_desc(vd);
@@ -1121,9 +1083,6 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
if (hw_desc->llp == llp) {
axi_chan_irq_clear(chan, hw_desc->lli->status_lo);
hw_desc->lli->ctl_hi |= CH_CTL_H_LLI_VALID;
- #ifdef CONFIG_SOC_STARFIVE_VIC7100
- starfive_flush_dcache(hw_desc->llp, sizeof(*hw_desc->lli));
- #endif
desc->completed_blocks = i;
if (((hw_desc->len * (i + 1)) % desc->period_len) == 0)
@@ -1143,6 +1102,7 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
axi_chan_start_first_queued(chan);
}
+out:
spin_unlock_irqrestore(&chan->vc.lock, flags);
}
@@ -1154,10 +1114,10 @@ static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id)
u32 status, i;
- /* Disable DMAC inerrupts. We'll enable them after processing chanels */
+ /* Disable DMAC interrupts. We'll enable them after processing channels */
axi_dma_irq_disable(chip);
- /* Poll, clear and process every chanel interrupt status */
+ /* Poll, clear and process every channel interrupt status */
for (i = 0; i < dw->hdata->nr_channels; i++) {
chan = &dw->chan[i];
status = axi_chan_irq_read(chan);
@@ -1190,7 +1150,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, TIMEOUT_US);
+ !(val & chan_active), 1000, 100000);
if (ret == -ETIMEDOUT)
dev_warn(dchan2dev(dchan),
"%s failed to stop\n", axi_chan_name(chan));
@@ -1217,17 +1177,23 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
static int dma_chan_pause(struct dma_chan *dchan)
{
struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
- struct dma_multi *multi = &chan->chip->multi;
unsigned long flags;
unsigned int timeout = 20; /* timeout iterations */
u32 val;
spin_lock_irqsave(&chan->vc.lock, flags);
- val = axi_dma_ioread32(chan->chip, multi->en.ch_susp);
- val |= BIT(chan->id) << multi->en.ch_susp_shift |
- BIT(chan->id) << multi->en.ch_susp_we_shift;
- axi_dma_iowrite32(chan->chip, multi->en.ch_susp, val);
+ if (chan->chip->dw->hdata->reg_map_8_channels) {
+ val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ val |= BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT |
+ BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT;
+ axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
+ } else {
+ val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
+ val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
+ BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
+ axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
+ }
do {
if (axi_chan_irq_read(chan) & DWAXIDMAC_IRQ_SUSPENDED)
@@ -1248,13 +1214,19 @@ static int dma_chan_pause(struct dma_chan *dchan)
/* Called in chan locked context */
static inline void axi_chan_resume(struct axi_dma_chan *chan)
{
- struct dma_multi *multi = &chan->chip->multi;
u32 val;
- val = axi_dma_ioread32(chan->chip, multi->en.ch_susp);
- val &= ~(BIT(chan->id) << multi->en.ch_susp_shift);
- val |= (BIT(chan->id) << multi->en.ch_susp_we_shift);
- axi_dma_iowrite32(chan->chip, multi->en.ch_susp, val);
+ if (chan->chip->dw->hdata->reg_map_8_channels) {
+ val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT);
+ val |= (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT);
+ axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
+ } else {
+ val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
+ val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT);
+ val |= (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT);
+ axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
+ }
chan->is_paused = false;
}
@@ -1281,7 +1253,7 @@ static int axi_dma_suspend(struct axi_dma_chip *chip)
clk_disable_unprepare(chip->core_clk);
clk_disable_unprepare(chip->cfgr_clk);
- clk_disable_unprepare(chip->axi_clk);
+ clk_disable_unprepare(chip->noc_clk);
return 0;
}
@@ -1290,7 +1262,7 @@ static int axi_dma_resume(struct axi_dma_chip *chip)
{
int ret;
- ret = clk_prepare_enable(chip->axi_clk);
+ ret = clk_prepare_enable(chip->noc_clk);
if (ret < 0)
return ret;
@@ -1308,17 +1280,6 @@ static int axi_dma_resume(struct axi_dma_chip *chip)
return 0;
}
-void axi_dma_cyclic_stop(struct dma_chan *dchan)
-{
- struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
- unsigned long flags;
-
- spin_lock_irqsave(&chan->vc.lock, flags);
- axi_chan_disable(chan);
- spin_unlock_irqrestore(&chan->vc.lock, flags);
-}
-EXPORT_SYMBOL(axi_dma_cyclic_stop);
-
static int __maybe_unused axi_dma_runtime_suspend(struct device *dev)
{
struct axi_dma_chip *chip = dev_get_drvdata(dev);
@@ -1346,13 +1307,6 @@ static struct dma_chan *dw_axi_dma_of_xlate(struct of_phandle_args *dma_spec,
chan = dchan_to_axi_dma_chan(dchan);
chan->hw_handshake_num = dma_spec->args[0];
-
- /*some per may need fixed-burst_trans_len*/
- if (dma_spec->args_count == 2 && dma_spec->args[1] > 0) {
- chan->fixed_burst_trans_len = true;
- chan->burst_trans_len = dma_spec->args[1];
- }
-
return dchan;
}
@@ -1369,6 +1323,8 @@ static int parse_device_properties(struct axi_dma_chip *chip)
return -EINVAL;
chip->dw->hdata->nr_channels = tmp;
+ if (tmp <= DMA_REG_MAP_CH_REF)
+ chip->dw->hdata->reg_map_8_channels = true;
ret = device_property_read_u32(dev, "snps,dma-masters", &tmp);
if (ret)
@@ -1421,34 +1377,16 @@ static int parse_device_properties(struct axi_dma_chip *chip)
chip->dw->hdata->axi_rw_burst_len = tmp;
}
-
- /* get number of handshak interface and configure multi reg */
- ret = device_property_read_u32(dev, "snps,num-hs-if", &tmp);
- if (!ret)
- chip->dw->hdata->nr_hs_if = tmp;
-
- if (chip->dw->hdata->nr_channels > 8) {
-#ifdef CONFIG_SOC_STARFIVE_VIC7100
- chip->multi.need_flush = true;
-#endif
- chip->multi.ch_enreg_2 = true;
- }
-
- if (chip->dw->hdata->nr_channels > 8 || chip->dw->hdata->nr_hs_if > 16)
- chip->multi.ch_cfg_2 = true;
-
- axi_chan_set_multi_reg(chip);
-
return 0;
}
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;
+ struct reset_control *resets;
+ unsigned int flags;
u32 i;
int ret;
@@ -1472,20 +1410,28 @@ static int dw_probe(struct platform_device *pdev)
if (chip->irq < 0)
return chip->irq;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- chip->regs = devm_ioremap_resource(chip->dev, mem);
+ chip->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->regs))
return PTR_ERR(chip->regs);
- if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
+ flags = (uintptr_t)of_device_get_match_data(&pdev->dev);
+ if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {
chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(chip->apb_regs))
return PTR_ERR(chip->apb_regs);
}
- chip->axi_clk = devm_clk_get(chip->dev, "stg_clk");
- if (IS_ERR(chip->axi_clk))
- return PTR_ERR(chip->axi_clk);
+ if (flags & AXI_DMA_FLAG_HAS_RESETS) {
+ resets = devm_reset_control_array_get_exclusive(&pdev->dev);
+ if (IS_ERR(resets))
+ return PTR_ERR(resets);
+
+ ret = reset_control_deassert(resets);
+ if (ret)
+ return ret;
+ }
+
+ chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);
chip->core_clk = devm_clk_get(chip->dev, "core-clk");
if (IS_ERR(chip->core_clk))
@@ -1495,25 +1441,9 @@ static int dw_probe(struct platform_device *pdev)
if (IS_ERR(chip->cfgr_clk))
return PTR_ERR(chip->cfgr_clk);
- chip->rst_axi = devm_reset_control_get_exclusive(&pdev->dev, "rst_stg");
- if (IS_ERR(chip->rst_axi)) {
- dev_err(&pdev->dev, "%s: failed to get rst_stg reset control\n", __func__);
- return PTR_ERR(chip->rst_axi);
- }
- chip->rst_core = devm_reset_control_get_exclusive(&pdev->dev, "rst_axi");
- if (IS_ERR(chip->rst_core)) {
- dev_err(&pdev->dev, "%s: failed to get rst_core reset control\n", __func__);
- return PTR_ERR(chip->rst_core);
- }
- chip->rst_cfgr = devm_reset_control_get_exclusive(&pdev->dev, "rst_ahb");
- if (IS_ERR(chip->rst_cfgr)) {
- dev_err(&pdev->dev, "%s: failed to get rst_cfgr reset control\n", __func__);
- return PTR_ERR(chip->rst_cfgr);
- }
-
- reset_control_deassert(chip->rst_axi);
- reset_control_deassert(chip->rst_core);
- reset_control_deassert(chip->rst_cfgr);
+ chip->noc_clk = devm_clk_get(chip->dev, "noc-clk");
+ if (IS_ERR(chip->noc_clk))
+ return PTR_ERR(chip->noc_clk);
ret = parse_device_properties(chip);
if (ret)
@@ -1627,9 +1557,9 @@ static int dw_remove(struct platform_device *pdev)
u32 i;
/* Enable clk before accessing to registers */
- clk_prepare_enable(chip->axi_clk);
clk_prepare_enable(chip->cfgr_clk);
clk_prepare_enable(chip->core_clk);
+ clk_prepare_enable(chip->noc_clk);
axi_dma_irq_disable(chip);
for (i = 0; i < dw->hdata->nr_channels; i++) {
axi_chan_disable(&chip->dw->chan[i]);
@@ -1658,9 +1588,15 @@ static const struct dev_pm_ops dw_axi_dma_pm_ops = {
};
static const struct of_device_id dw_dma_of_id_table[] = {
- { .compatible = "snps,axi-dma-1.01a" },
- { .compatible = "intel,kmb-axi-dma" },
- { .compatible = "starfive,jh7110-dma" },
+ {
+ .compatible = "snps,axi-dma-1.01a"
+ }, {
+ .compatible = "intel,kmb-axi-dma",
+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
+ }, {
+ .compatible = "starfive,jh7110-axi-dma",
+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+ },
{}
};
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 416cc4b52f13..1e6ce776a32c 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -1,11 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
// (C) 2017-2018 Synopsys, Inc. (www.synopsys.com)
/*
* Synopsys DesignWare AXI DMA Controller driver.
*
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
- * Samin.guo <samin.guo@starfivetech.com>
*/
#ifndef _AXI_DMA_PLATFORM_H
@@ -23,44 +22,18 @@
#define DMAC_MAX_MASTERS 2
#define DMAC_MAX_BLK_SIZE 0x200000
-#define TIMEOUT_US 200000
-
-struct dma_ch_en {
- u8 ch_en;
- u8 ch_en_shift;
- u8 ch_en_we_shift;
- u8 ch_susp;
- u8 ch_susp_shift;
- u8 ch_susp_we_shift;
- u8 ch_abort;
- u8 ch_abort_shift;
- u8 ch_abort_we_shfit;
-};
-
-struct dma_ch_cfg {
- u8 ch_cfg_priority_pos;
- u8 ch_cfg_dst_per_pos;
- u8 ch_cfg_src_per_pos;
-};
-
-struct dma_multi {
- bool ch_cfg_2;
- bool ch_enreg_2;
- struct dma_ch_cfg cfg;
- struct dma_ch_en en;
- bool need_flush;
-};
-
struct dw_axi_dma_hcfg {
u32 nr_channels;
u32 nr_masters;
- u32 nr_hs_if;
u32 m_data_width;
u32 block_size[DMAC_MAX_CHANNELS];
u32 priority[DMAC_MAX_CHANNELS];
/* maximum supported axi burst length */
u32 axi_rw_burst_len;
+ /* Register map for DMAX_NUM_CHANNELS <= 8 */
+ bool reg_map_8_channels;
bool restrict_axi_burst_len;
+ bool use_cfg2;
};
struct axi_dma_chan {
@@ -68,7 +41,6 @@ struct axi_dma_chan {
void __iomem *chan_regs;
u8 id;
u8 hw_handshake_num;
- s8 burst_trans_len;
atomic_t descs_allocated;
struct dma_pool *desc_pool;
@@ -77,7 +49,6 @@ struct axi_dma_chan {
struct axi_dma_desc *desc;
struct dma_slave_config config;
enum dma_transfer_direction direction;
- bool fixed_burst_trans_len;
bool cyclic;
/* these other elements are all protected by vc.lock */
bool is_paused;
@@ -99,12 +70,8 @@ struct axi_dma_chip {
void __iomem *apb_regs;
struct clk *core_clk;
struct clk *cfgr_clk;
- struct clk *axi_clk;
+ struct clk *noc_clk;
struct dw_axi_dma *dw;
- struct dma_multi multi;
- struct reset_control *rst_core;
- struct reset_control *rst_cfgr;
- struct reset_control *rst_axi;
};
/* LLI == Linked List Item */
@@ -133,11 +100,22 @@ struct axi_dma_hw_desc {
struct axi_dma_desc {
struct axi_dma_hw_desc *hw_desc;
- struct virt_dma_desc vd;
- struct axi_dma_chan *chan;
- u32 completed_blocks;
- u32 length;
- u32 period_len;
+ struct virt_dma_desc vd;
+ struct axi_dma_chan *chan;
+ u32 completed_blocks;
+ u32 length;
+ u32 period_len;
+};
+
+struct axi_dma_chan_config {
+ u8 dst_multblk_type;
+ u8 src_multblk_type;
+ u8 dst_per;
+ u8 src_per;
+ u8 tt_fc;
+ u8 prior;
+ u8 hs_sel_dst;
+ u8 hs_sel_src;
};
static inline struct device *dchan2dev(struct dma_chan *dchan)
@@ -176,15 +154,8 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
#define DMAC_CHEN 0x018 /* R/W DMAC Channel Enable */
#define DMAC_CHEN_L 0x018 /* R/W DMAC Channel Enable 00-31 */
#define DMAC_CHEN_H 0x01C /* R/W DMAC Channel Enable 32-63 */
-#define DMAC_CHSUSP 0x018 /* R/W DMAC Channel suspend */
-#define DMAC_CHABORT 0x018 /* R/W DMAC Channel Abort */
-
-#define DMAC_CHEN_2 0x018 /* R/W DMAC Channel Enable */
-#define DMAC_CHEN_L_2 0x018 /* R/W DMAC Channel Enable */
-#define DMAC_CHEN_H_2 0x01C /* R/W DMAC Channel Enable */
-#define DMAC_CHSUSP_2 0x020 /* R/W DMAC Channel Suspend */
-#define DMAC_CHABORT_2 0x028 /* R/W DMAC Channel Abort */
-
+#define DMAC_CHSUSPREG 0x020 /* R/W DMAC Channel Suspend */
+#define DMAC_CHABORTREG 0x028 /* R/W DMAC Channel Abort */
#define DMAC_INTSTATUS 0x030 /* R DMAC Interrupt Status */
#define DMAC_COMMON_INTCLEAR 0x038 /* W DMAC Interrupt Clear */
#define DMAC_COMMON_INTSTATUS_ENA 0x040 /* R DMAC Interrupt Status Enable */
@@ -233,6 +204,7 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
#define DMA_APB_HS_SEL_BIT_SIZE 0x08 /* HW handshake bits per channel */
#define DMA_APB_HS_SEL_MASK 0xFF /* HW handshake select masks */
#define MAX_BLOCK_SIZE 0x1000 /* 1024 blocks * 4 bytes data width */
+#define DMA_REG_MAP_CH_REF 0x08 /* Channel count to choose register map */
/* DMAC_CFG */
#define DMAC_EN_POS 0
@@ -241,23 +213,19 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
#define INT_EN_POS 1
#define INT_EN_MASK BIT(INT_EN_POS)
+/* DMAC_CHEN */
#define DMAC_CHAN_EN_SHIFT 0
#define DMAC_CHAN_EN_WE_SHIFT 8
#define DMAC_CHAN_SUSP_SHIFT 16
#define DMAC_CHAN_SUSP_WE_SHIFT 24
-#define DMAC_CHAN_ABORT_SHIFT 32
-#define DMAC_CHAN_ABORT_WE_SHIFT 40
-
-#define DMAC_CHAN_EN_SHIFT_2 0
-#define DMAC_CHAN_EN_WE_SHIFT_2 16
+/* DMAC_CHEN2 */
+#define DMAC_CHAN_EN2_WE_SHIFT 16
-#define DMAC_CHAN_SUSP_SHIFT_2 0
-#define DMAC_CHAN_SUSP_WE_SHIFT_2 16
-
-#define DMAC_CHAN_ABORT_SHIFT_2 0
-#define DMAC_CHAN_ABORT_WE_SHIFT_2 16
+/* DMAC_CHSUSP */
+#define DMAC_CHAN_SUSP2_SHIFT 0
+#define DMAC_CHAN_SUSP2_WE_SHIFT 16
/* CH_CTL_H */
#define CH_CTL_H_ARLEN_EN BIT(6)
@@ -321,7 +289,6 @@ enum {
#define CH_CFG_H_PRIORITY_POS 17
#define CH_CFG_H_DST_PER_POS 12
#define CH_CFG_H_SRC_PER_POS 7
-#define CH_CFG_H_PRIORITY_POS_2 15
#define CH_CFG_H_HS_SEL_DST_POS 4
#define CH_CFG_H_HS_SEL_SRC_POS 3
enum {
@@ -344,9 +311,6 @@ enum {
/* CH_CFG_L */
#define CH_CFG_L_DST_MULTBLK_TYPE_POS 2
#define CH_CFG_L_SRC_MULTBLK_TYPE_POS 0
-
-#define CH_CFG_L_DST_PER_POS_2 11
-#define CH_CFG_L_SRC_PER_POS_2 4
enum {
DWAXIDMAC_MBLK_TYPE_CONTIGUOUS = 0,
DWAXIDMAC_MBLK_TYPE_RELOAD,
@@ -354,6 +318,15 @@ enum {
DWAXIDMAC_MBLK_TYPE_LL
};
+/* CH_CFG2 */
+#define CH_CFG2_L_SRC_PER_POS 4
+#define CH_CFG2_L_DST_PER_POS 11
+
+#define CH_CFG2_H_TT_FC_POS 0
+#define CH_CFG2_H_HS_SEL_SRC_POS 3
+#define CH_CFG2_H_HS_SEL_DST_POS 4
+#define CH_CFG2_H_PRIORITY_POS 20
+
/**
* DW AXI DMA channel interrupts
*
diff --git a/drivers/media/platform/chips-media/wave5/wave5-hw.c b/drivers/media/platform/chips-media/wave5/wave5-hw.c
index 57bbc3862be2..fdc5c7eeaee1 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-hw.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c
@@ -729,7 +729,6 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b
struct vpu_buf vb_buf;
u32 color_format = 0;
u32 pixel_order = 1;
- u32 scale_en = 0;
u32 bwb_flag = (map_type == LINEAR_FRAME_MAP) ? 1 : 0;
cbcr_interleave = inst->cbcr_interleave;
@@ -831,15 +830,7 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b
p_dec_info->vb_fbc_c_tbl[i] = vb_buf;
}
}
-
- if ((init_info->pic_width - init_info->pic_crop_rect.right != inst->display_fmt.width) ||
- init_info->pic_height - init_info->pic_crop_rect.bottom != inst->display_fmt.height) {
- pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height);
- scale_en = 1;
- } else {
- pic_size = (init_info->pic_width << 16) | (init_info->pic_height);
- scale_en = 0;
- }
+ pic_size = (init_info->pic_width << 16) | (init_info->pic_height);
// allocate task_buffer
vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) +
@@ -855,14 +846,7 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b
p_dec_info->vb_task.daddr);
vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, vb_buf.size);
} else {
- if ((init_info->pic_width - init_info->pic_crop_rect.right != inst->display_fmt.width) ||
- init_info->pic_height - init_info->pic_crop_rect.bottom != inst->display_fmt.height) {
- pic_size = (inst->display_fmt.width << 16) | (inst->display_fmt.height);
- scale_en = 1;
- } else {
- pic_size = (init_info->pic_width << 16) | (init_info->pic_height);
- scale_en = 0;
- }
+ pic_size = (init_info->pic_width << 16) | (init_info->pic_height);
}
dev_dbg(inst->dev->dev, "set pic_size 0x%x\n", pic_size);
endian = wave5_vdi_convert_endian(inst->dev, fb_arr[0].endian);
@@ -872,15 +856,13 @@ int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst, struct frame_b
color_format = 0;
reg_val =
- (scale_en << 29) |
(bwb_flag << 28) |
(pixel_order << 23) | /* PIXEL ORDER in 128bit. first pixel in low address */
(yuv_format << 20) |
(color_format << 19) |
(nv21 << 17) |
(cbcr_interleave << 16) |
- (scale_en ? inst->display_fmt.width : fb_arr[0].stride);
- //inst->display_fmt.width;
+ (fb_arr[0].stride);
dev_dbg(inst->dev->dev, "set W5_COMMON_PIC_INFO 0x%x\n",reg_val);
vpu_write_reg(inst->dev, W5_COMMON_PIC_INFO, reg_val);
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index 5d10f3c7365a..e97b3b022055 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -234,46 +234,6 @@ static void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp, unsigned
}
}
-static void wave5_update_pix_fmt_r8(struct v4l2_pix_format_mplane *pix_mp, unsigned int width,
- unsigned int height)
-{
- switch (pix_mp->pixelformat) {
- case V4L2_PIX_FMT_YUV420:
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- pix_mp->width = round_up(width, 32);
- pix_mp->height = round_up(height, 8);
- pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
- pix_mp->plane_fmt[0].sizeimage = width * height * 3 / 2;
- break;
- case V4L2_PIX_FMT_YUV420M:
- pix_mp->width = round_up(width, 32);
- pix_mp->height = round_up(height, 8);
- pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
- pix_mp->plane_fmt[0].sizeimage = width * height;
- pix_mp->plane_fmt[1].bytesperline = round_up(width, 32) / 2;
- pix_mp->plane_fmt[1].sizeimage = width * height / 4;
- pix_mp->plane_fmt[2].bytesperline = round_up(width, 32) / 2;
- pix_mp->plane_fmt[2].sizeimage = width * height / 4;
- break;
- case V4L2_PIX_FMT_NV12M:
- case V4L2_PIX_FMT_NV21M:
- pix_mp->width = round_up(width, 32);
- pix_mp->height = round_up(height, 8);
- pix_mp->plane_fmt[0].bytesperline = round_up(width, 32);
- pix_mp->plane_fmt[0].sizeimage = width * height;
- pix_mp->plane_fmt[1].bytesperline = round_up(width, 32);
- pix_mp->plane_fmt[1].sizeimage = width * height / 2;
- break;
- default:
- pix_mp->width = width;
- pix_mp->height = height;
- pix_mp->plane_fmt[0].bytesperline = 0;
- pix_mp->plane_fmt[0].sizeimage = width * height;
- break;
- }
-}
-
static void wave5_vpu_dec_start_decode(struct vpu_instance *inst)
{
struct dec_param pic_param;
@@ -301,7 +261,6 @@ static void wave5_vpu_dec_start_decode(struct vpu_instance *inst)
src_buf = v4l2_m2m_src_buf_remove(inst->v4l2_fh.m2m_ctx);
inst->state = VPU_INST_STATE_STOP;
- //printk("%d wave5 state = %d\n",__LINE__, inst->state);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
}
}
@@ -312,7 +271,6 @@ static void wave5_vpu_dec_stop_decode(struct vpu_instance *inst)
int ret;
inst->state = VPU_INST_STATE_STOP;
- //printk("%d wave5 state = %d\n",__LINE__, inst->state);
ret = wave5_vpu_dec_update_bitstream_buffer(inst, 0);
if (ret) {
@@ -337,6 +295,7 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst)
struct dec_output_info dec_output_info;
int ret;
u32 irq_status;
+ u32 stride, height;
if (kfifo_out(&inst->irq_status, &irq_status, sizeof(int)))
wave5_vpu_clear_interrupt_ex(inst, irq_status);
@@ -357,8 +316,14 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst)
v4l2_m2m_dst_buf_remove_by_idx(inst->v4l2_fh.m2m_ctx,
dec_output_info.index_frame_display);
- int stride = inst->display_fmt.width;
- int height =inst->display_fmt.height;
+ if (!dst_buf) {
+ dev_dbg(inst->dev->dev,"find no dst_buf \n");
+ return;
+ }
+
+ stride = dec_output_info.disp_frame.stride;
+ height = dec_output_info.disp_pic_height -
+ dec_output_info.rc_display.bottom;
dev_dbg(inst->dev->dev, "%s %d disp_pic_height %u rc_display.bottom %u\n",
__func__, __LINE__, dec_output_info.disp_pic_height, dec_output_info.rc_display.bottom);
dev_dbg(inst->dev->dev, "%s %d stride %u height %u num %d\n", __func__, __LINE__, stride, height,inst->dst_fmt.num_planes);
@@ -380,11 +345,7 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst)
((stride / 2) * (height / 2)));
}
- if (inst->timestamp) {
- dst_buf->vb2_buf.timestamp = inst->timestamp;
- } else {
- dst_buf->vb2_buf.timestamp = inst->timestamp_cnt++ * inst->codec_info->dec_info.initial_info.ns_per_frame;
- }
+ dst_buf->vb2_buf.timestamp = inst->timestamp_cnt++ * inst->codec_info->dec_info.initial_info.ns_per_frame;
dst_buf->field = V4L2_FIELD_NONE;
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
@@ -425,7 +386,6 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst)
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
inst->eos = TRUE;
- //pr_err("wave5 queue event type: %d id: %d\n",vpu_event_eos.type, vpu_event_eos.id);
v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_eos);
v4l2_m2m_job_finish(inst->v4l2_m2m_dev, inst->v4l2_fh.m2m_ctx);
@@ -498,7 +458,7 @@ static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo
if (!vpu_fmt) {
f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes;
- wave5_update_pix_fmt_r8(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height);
+ wave5_update_pix_fmt(&f->fmt.pix_mp, inst->dst_fmt.width, inst->dst_fmt.height);
} else {
int width = clamp(f->fmt.pix_mp.width, vpu_fmt->min_width, vpu_fmt->max_width);
int height = clamp(f->fmt.pix_mp.height, vpu_fmt->min_height, vpu_fmt->max_height);
@@ -506,7 +466,7 @@ static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo
f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
f->fmt.pix_mp.num_planes = info->mem_planes;
- wave5_update_pix_fmt_r8(&f->fmt.pix_mp, width, height);
+ wave5_update_pix_fmt(&f->fmt.pix_mp, width, height);
}
f->fmt.pix_mp.flags = 0;
@@ -525,7 +485,6 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form
{
struct vpu_instance *inst = wave5_to_vpu_inst(fh);
int i, ret;
- unsigned int scalew, scaleh;
dev_dbg(inst->dev->dev,
"%s: fourcc: %u width: %u height: %u num_planes: %u colorspace: %u field: %u\n",
@@ -533,37 +492,26 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form
f->fmt.pix_mp.num_planes, f->fmt.pix_mp.colorspace, f->fmt.pix_mp.field);
ret = wave5_vpu_dec_try_fmt_cap(file, fh, f);
-
if (ret)
return ret;
- scalew = inst->src_fmt.width / f->fmt.pix_mp.width;
- scaleh = inst->src_fmt.height / f->fmt.pix_mp.height;
-
- //if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) {
- // dev_err(inst->dev->dev,"Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. \n");
- // return -EINVAL;
- //}
-
- inst->display_fmt.width = f->fmt.pix_mp.width;
- inst->display_fmt.height = f->fmt.pix_mp.height;
- inst->display_fmt.pixelformat = f->fmt.pix_mp.pixelformat;
- inst->display_fmt.field = f->fmt.pix_mp.field;
- inst->display_fmt.flags = f->fmt.pix_mp.flags;
- inst->display_fmt.num_planes = f->fmt.pix_mp.num_planes;
+ inst->dst_fmt.width = f->fmt.pix_mp.width;
+ inst->dst_fmt.height = f->fmt.pix_mp.height;
inst->dst_fmt.pixelformat = f->fmt.pix_mp.pixelformat;
+ inst->dst_fmt.field = f->fmt.pix_mp.field;
+ inst->dst_fmt.flags = f->fmt.pix_mp.flags;
inst->dst_fmt.num_planes = f->fmt.pix_mp.num_planes;
- for (i = 0; i < inst->display_fmt.num_planes; i++) {
- inst->display_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline;
- inst->display_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
+ for (i = 0; i < inst->dst_fmt.num_planes; i++) {
+ inst->dst_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline;
+ inst->dst_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
- if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
- inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV12M) {
+ if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
+ inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12M) {
inst->cbcr_interleave = true;
inst->nv21 = false;
- } else if (inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
- inst->display_fmt.pixelformat == V4L2_PIX_FMT_NV21M) {
+ } else if (inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
+ inst->dst_fmt.pixelformat == V4L2_PIX_FMT_NV21M) {
inst->cbcr_interleave = true;
inst->nv21 = true;
} else {
@@ -579,15 +527,15 @@ static int wave5_vpu_dec_g_fmt_cap(struct file *file, void *fh, struct v4l2_form
struct vpu_instance *inst = wave5_to_vpu_inst(fh);
int i;
- f->fmt.pix_mp.width = inst->display_fmt.width;
- f->fmt.pix_mp.height = inst->display_fmt.height;
- f->fmt.pix_mp.pixelformat = inst->display_fmt.pixelformat;
- f->fmt.pix_mp.field = inst->display_fmt.field;
- f->fmt.pix_mp.flags = inst->display_fmt.flags;
- f->fmt.pix_mp.num_planes = inst->display_fmt.num_planes;
+ f->fmt.pix_mp.width = inst->dst_fmt.width;
+ f->fmt.pix_mp.height = inst->dst_fmt.height;
+ f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
+ f->fmt.pix_mp.field = inst->dst_fmt.field;
+ f->fmt.pix_mp.flags = inst->dst_fmt.flags;
+ f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes;
for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
- f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->display_fmt.plane_fmt[i].bytesperline;
- f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->display_fmt.plane_fmt[i].sizeimage;
+ f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->dst_fmt.plane_fmt[i].bytesperline;
+ f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->dst_fmt.plane_fmt[i].sizeimage;
}
f->fmt.pix_mp.colorspace = inst->colorspace;
@@ -660,7 +608,6 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form
__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field);
-
ret = wave5_vpu_dec_try_fmt_out(file, fh, f);
if (ret)
return ret;
@@ -682,9 +629,7 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form
inst->quantization = f->fmt.pix_mp.quantization;
inst->xfer_func = f->fmt.pix_mp.xfer_func;
-
- wave5_update_pix_fmt_r8(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height);
- wave5_update_pix_fmt_r8(&inst->display_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height);
+ wave5_update_pix_fmt(&inst->dst_fmt, f->fmt.pix_mp.width, f->fmt.pix_mp.height);
return 0;
}
@@ -764,7 +709,6 @@ static int wave5_vpu_dec_decoder_cmd(struct file *file, void *fh, struct v4l2_de
wave5_handle_bitstream_buffer(inst);
inst->ops->start_process(inst);
inst->state = VPU_INST_STATE_STOP;
- //printk("%d wave5 state = %d\n",__LINE__, inst->state);
ret = wave5_vpu_dec_update_bitstream_buffer(inst, 0);
if (ret) {
@@ -865,7 +809,7 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff
{
struct vpu_instance *inst = vb2_get_drv_priv(q);
struct v4l2_pix_format_mplane inst_format =
- (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->display_fmt;
+ (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->dst_fmt;
unsigned int i;
int ret;
@@ -936,7 +880,6 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff
}
inst->state = VPU_INST_STATE_OPEN;
- //printk("wave5 state = %d\n",inst->state);
if (inst->thumbnail_mode)
wave5_vpu_dec_give_command(inst, ENABLE_DEC_THUMBNAIL_MODE, NULL);
@@ -950,6 +893,7 @@ static int wave5_vpu_dec_queue_setup(struct vb2_queue *q, unsigned int *num_buff
//if (*num_buffers > inst->min_dst_buf_count &&
// *num_buffers < WAVE5_MAX_FBS)
// inst->dst_buf_count = *num_buffers;
+ inst->dst_buf_count += 2;
*num_buffers = inst->dst_buf_count;
non_linear_num = inst->dst_buf_count;
@@ -1005,7 +949,6 @@ free_bitstream_vbuf:
static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst)
{
struct dec_initial_info initial_info;
- unsigned int scalew, scaleh;
int ret = 0;
memset(&initial_info, 0, sizeof(struct dec_initial_info));
@@ -1036,7 +979,6 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst)
initial_info.profile, initial_info.min_frame_buffer_count);
inst->state = VPU_INST_STATE_INIT_SEQ;
- //printk("wave5 state = %d\n",inst->state);
inst->min_dst_buf_count = initial_info.min_frame_buffer_count + 1;
inst->dst_buf_count = inst->min_dst_buf_count;
@@ -1050,29 +992,15 @@ static int wave5_vpu_dec_start_streaming_open(struct vpu_instance *inst)
if (initial_info.pic_width != inst->src_fmt.width ||
initial_info.pic_height != inst->src_fmt.height) {
- if (inst->std == W_AVC_DEC) {
- wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width,
- initial_info.pic_height);
- wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width,
- initial_info.pic_height);
- } else { //HEVC
- wave5_update_pix_fmt_r8(&inst->src_fmt, initial_info.pic_width,
- initial_info.pic_height);
- wave5_update_pix_fmt_r8(&inst->dst_fmt, initial_info.pic_width,
- initial_info.pic_height);
- }
+ wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width,
+ initial_info.pic_height);
+ wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width,
+ initial_info.pic_height);
}
+
inst->crop_rect.right = initial_info.pic_crop_rect.right;
inst->crop_rect.bottom = initial_info.pic_crop_rect.bottom;
- scalew = inst->dst_fmt.width / inst->display_fmt.width;
- scaleh = inst->dst_fmt.height / inst->display_fmt.height;
-
- if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) {
- wave5_update_pix_fmt(&inst->display_fmt, inst->dst_fmt.width,
- inst->dst_fmt.height);
- }
-
dev_dbg(inst->dev->dev, "wave5 queue event type: %d id: %d\n",vpu_event_src_ch.type, vpu_event_src_ch.id);
v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_src_ch);
@@ -1087,7 +1015,6 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst)
struct dec_initial_info initial_info;
struct dec_param pic_param;
struct dec_output_info dec_output_info;
- unsigned int scalew, scaleh;
int ret = 0;
u32 fail_res = 0;
@@ -1099,7 +1026,6 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst)
src_buf = v4l2_m2m_src_buf_remove(inst->v4l2_fh.m2m_ctx);
inst->state = VPU_INST_STATE_STOP;
- //printk("%d wave5 state = %d\n",__LINE__, inst->state);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
dev_dbg(inst->dev->dev, "%s: wave5_vpu_dec_start_one_frame\n", __func__);
return ret;
@@ -1142,29 +1068,15 @@ static int wave5_vpu_dec_start_streaming_seek(struct vpu_instance *inst)
if (initial_info.pic_width != inst->src_fmt.width ||
initial_info.pic_height != inst->src_fmt.height) {
- if (inst->std == W_AVC_DEC) {
- wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width,
- initial_info.pic_height);
- wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width,
- initial_info.pic_height);
- } else { //HEVC
- wave5_update_pix_fmt_r8(&inst->src_fmt, initial_info.pic_width,
- initial_info.pic_height);
- wave5_update_pix_fmt_r8(&inst->dst_fmt, initial_info.pic_width,
- initial_info.pic_height);
- }
+ wave5_update_pix_fmt(&inst->src_fmt, initial_info.pic_width,
+ initial_info.pic_height);
+ wave5_update_pix_fmt(&inst->dst_fmt, initial_info.pic_width,
+ initial_info.pic_height);
}
+
inst->crop_rect.right = initial_info.pic_crop_rect.right;
inst->crop_rect.bottom = initial_info.pic_crop_rect.bottom;
- scalew = inst->dst_fmt.width / inst->display_fmt.width;
- scaleh = inst->dst_fmt.height / inst->display_fmt.height;
-
- if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1) {
- wave5_update_pix_fmt(&inst->display_fmt, inst->dst_fmt.width,
- inst->dst_fmt.height);
- }
-
v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_src_ch);
wave5_handle_src_buffer(inst);
@@ -1206,22 +1118,22 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
dma_addr_t buf_addr_y = 0, buf_addr_cb = 0, buf_addr_cr = 0;
u32 buf_size = 0;
u32 non_linear_num = inst->dst_buf_count;
- u32 fb_stride = inst->display_fmt.width;
- u32 luma_size = fb_stride * inst->display_fmt.height;
- u32 chroma_size = (fb_stride / 2) * (inst->display_fmt.height / 2);
+ u32 fb_stride = inst->dst_fmt.width;
+ u32 luma_size = fb_stride * inst->dst_fmt.height;
+ u32 chroma_size = (fb_stride / 2) * (inst->dst_fmt.height / 2);
- if (inst->display_fmt.num_planes == 1) {
+ if (inst->dst_fmt.num_planes == 1) {
buf_size = vb2_plane_size(&vbuf->vb2_buf, 0);
buf_addr_y = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
buf_addr_cb = buf_addr_y + luma_size;
buf_addr_cr = buf_addr_cb + chroma_size;
- } else if (inst->display_fmt.num_planes == 2) {
+ } else if (inst->dst_fmt.num_planes == 2) {
buf_size = vb2_plane_size(&vbuf->vb2_buf, 0) +
vb2_plane_size(&vbuf->vb2_buf, 1);
buf_addr_y = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
buf_addr_cb = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 1);
buf_addr_cr = buf_addr_cb + chroma_size;
- } else if (inst->display_fmt.num_planes == 3) {
+ } else if (inst->dst_fmt.num_planes == 3) {
buf_size = vb2_plane_size(&vbuf->vb2_buf, 0) +
vb2_plane_size(&vbuf->vb2_buf, 1) +
vb2_plane_size(&vbuf->vb2_buf, 2);
@@ -1233,7 +1145,7 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
inst->frame_buf[vb->index + non_linear_num].buf_cb = buf_addr_cb;
inst->frame_buf[vb->index + non_linear_num].buf_cr = buf_addr_cr;
inst->frame_buf[vb->index + non_linear_num].size = buf_size;
- inst->frame_buf[vb->index + non_linear_num].width = inst->display_fmt.width;
+ inst->frame_buf[vb->index + non_linear_num].width = inst->src_fmt.width;
inst->frame_buf[vb->index + non_linear_num].stride = fb_stride;
inst->frame_buf[vb->index + non_linear_num].map_type = LINEAR_FRAME_MAP;
inst->frame_buf[vb->index + non_linear_num].update_fb_info = true;
@@ -1369,7 +1281,6 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
if (inst->eos) {
inst->eos = FALSE;
inst->state = VPU_INST_STATE_INIT_SEQ;
- //printk("wave5 state = %d\n",inst->state);
}
inst->queued_dst_buf_num = 0;
}
@@ -1422,7 +1333,6 @@ static void wave5_vpu_dec_device_run(void *priv)
inst->ops->start_process(inst);
inst->state = VPU_INST_STATE_PIC_RUN;
- //printk("wave5 state = %d\n",inst->state);
}
static void wave5_vpu_dec_job_abort(void *priv)
@@ -1487,7 +1397,6 @@ static int wave5_vpu_open_dec(struct file *filp)
v4l2_ctrl_handler_setup(&inst->v4l2_ctrl_hdl);
wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt);
- memcpy((void *)&inst->display_fmt, (void *)&inst->dst_fmt, sizeof(struct v4l2_pix_format_mplane));
inst->colorspace = V4L2_COLORSPACE_REC709;
inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
inst->hsv_enc = 0;
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h
index dcd061b1aa9c..892eff216aea 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h
@@ -1048,7 +1048,6 @@ struct vpu_instance {
struct v4l2_pix_format_mplane src_fmt;
struct v4l2_pix_format_mplane dst_fmt;
- struct v4l2_pix_format_mplane display_fmt;
enum v4l2_colorspace colorspace;
enum v4l2_xfer_func xfer_func;
enum v4l2_ycbcr_encoding ycbcr_enc;
diff --git a/drivers/net/can/ipms_canfd.c b/drivers/net/can/ipms_canfd.c
index b93266b900fc..0a5e906d0a3c 100644
--- a/drivers/net/can/ipms_canfd.c
+++ b/drivers/net/can/ipms_canfd.c
@@ -558,8 +558,6 @@ static netdev_tx_t canfd_driver_start_xmit(struct sk_buff *skb, struct net_devic
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
- netif_stop_queue(ndev);
-
switch (priv->tx_mode) {
case XMIT_FULL:
return NETDEV_TX_BUSY;
diff --git a/sound/soc/starfive/starfive_pwmdac.c b/sound/soc/starfive/starfive_pwmdac.c
index fba58e22d7ef..231bf192590c 100644
--- a/sound/soc/starfive/starfive_pwmdac.c
+++ b/sound/soc/starfive/starfive_pwmdac.c
@@ -495,6 +495,17 @@ static int pwmdac_config(struct sf_pwmdac_dev *dev)
return 0;
}
+static int sf_pwmdac_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ dai_link->stop_dma_first = 1;
+
+ return 0;
+}
+
static int sf_pwmdac_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -565,10 +576,6 @@ static int sf_pwmdac_hw_params(struct snd_pcm_substream *substream,
int ret = 0;
unsigned long mclk_dac_value;
struct sf_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai_link *dai_link = rtd->dai_link;
-
- dai_link->stop_dma_first = 1;
dev->play_dma_data.addr = dev->mapbase + PWMDAC_WDATA;
@@ -829,40 +836,15 @@ static int pwmdac_probe(struct snd_soc_component *component)
}
static const struct snd_soc_dai_ops sf_pwmdac_dai_ops = {
- .hw_params = sf_pwmdac_hw_params,
- .prepare = sf_pwmdac_prepare,
- .trigger = sf_pwmdac_trigger,
+ .startup = sf_pwmdac_startup,
+ .hw_params = sf_pwmdac_hw_params,
+ .prepare = sf_pwmdac_prepare,
+ .trigger = sf_pwmdac_trigger,
};
-static int pwmdac_component_trigger(struct snd_soc_component *component,
- struct snd_pcm_substream *substream, int cmd)
-{
- int ret = 0;
- struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- axi_dma_cyclic_stop(chan);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
static const struct snd_soc_component_driver sf_pwmdac_component = {
- .name = "starfive-pwmdac",
- .probe = pwmdac_probe,
- .trigger = pwmdac_component_trigger,
+ .name = "starfive-pwmdac",
+ .probe = pwmdac_probe,
};
static struct snd_soc_dai_driver pwmdac_dai = {
diff --git a/sound/soc/starfive/starfive_tdm.c b/sound/soc/starfive/starfive_tdm.c
index 375e266046a2..42d369bc3af3 100644
--- a/sound/soc/starfive/starfive_tdm.c
+++ b/sound/soc/starfive/starfive_tdm.c
@@ -255,42 +255,23 @@ static int sf_tdm_resume(struct snd_soc_component *component)
#define sf_tdm_resume NULL
#endif
-/*
- * To stop dma first, we must implement this function, because it is
- * called before stopping the stream.
- */
-static int sf_pcm_trigger(struct snd_soc_component *component,
- struct snd_pcm_substream *substream, int cmd)
-{
- int ret = 0;
- struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- axi_dma_cyclic_stop(chan);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
static const struct snd_soc_component_driver sf_tdm_component = {
.name = "jh7110-tdm",
.suspend = sf_tdm_suspend,
.resume = sf_tdm_resume,
- .trigger = sf_pcm_trigger,
};
+static int sf_tdm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ dai_link->stop_dma_first = 1;
+
+ return 0;
+}
+
static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
@@ -302,10 +283,6 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
int channels;
int ret;
struct snd_dmaengine_dai_dma_data *dma_data = NULL;
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai_link *dai_link = rtd->dai_link;
-
- dai_link->stop_dma_first = 1;
channels = params_channels(params);
data_width = params_width(params);
@@ -490,6 +467,7 @@ static int sf_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
}
static const struct snd_soc_dai_ops sf_tdm_dai_ops = {
+ .startup = sf_tdm_startup,
.hw_params = sf_tdm_hw_params,
.trigger = sf_tdm_trigger,
.set_fmt = sf_tdm_set_fmt,