diff options
author | Andy Hu <andy.hu@starfivetech.com> | 2023-08-31 05:06:00 +0300 |
---|---|---|
committer | Andy Hu <andy.hu@starfivetech.com> | 2023-08-31 05:06:00 +0300 |
commit | c698aee1b2dc0772f4a8ea5f2777b9e5710630d2 (patch) | |
tree | 076e91dc5144cc79f24696064026ac844e1449c9 | |
parent | 05533e9c31d6f0da20efc2d436a3b0f6d516ed4b (diff) | |
parent | 45c6eeaad9c30b4b558b1ad8380332eb257b4884 (diff) | |
download | linux-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.dtsi | 23 | ||||
-rw-r--r-- | drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 390 | ||||
-rw-r--r-- | drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 105 | ||||
-rw-r--r-- | drivers/media/platform/chips-media/wave5/wave5-hw.c | 24 | ||||
-rw-r--r-- | drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 193 | ||||
-rw-r--r-- | drivers/media/platform/chips-media/wave5/wave5-vpuapi.h | 1 | ||||
-rw-r--r-- | drivers/net/can/ipms_canfd.c | 2 | ||||
-rw-r--r-- | sound/soc/starfive/starfive_pwmdac.c | 52 | ||||
-rw-r--r-- | sound/soc/starfive/starfive_tdm.c | 46 |
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, |