149b49cdaSZbigniew Bodek /*-
249b49cdaSZbigniew Bodek *******************************************************************************
349b49cdaSZbigniew Bodek Copyright (C) 2015 Annapurna Labs Ltd.
449b49cdaSZbigniew Bodek
549b49cdaSZbigniew Bodek This file may be licensed under the terms of the Annapurna Labs Commercial
649b49cdaSZbigniew Bodek License Agreement.
749b49cdaSZbigniew Bodek
849b49cdaSZbigniew Bodek Alternatively, this file can be distributed under the terms of the GNU General
949b49cdaSZbigniew Bodek Public License V2 as published by the Free Software Foundation and can be
1049b49cdaSZbigniew Bodek found at http://www.gnu.org/licenses/gpl-2.0.html
1149b49cdaSZbigniew Bodek
1249b49cdaSZbigniew Bodek Alternatively, redistribution and use in source and binary forms, with or
1349b49cdaSZbigniew Bodek without modification, are permitted provided that the following conditions are
1449b49cdaSZbigniew Bodek met:
1549b49cdaSZbigniew Bodek
1649b49cdaSZbigniew Bodek * Redistributions of source code must retain the above copyright notice,
1749b49cdaSZbigniew Bodek this list of conditions and the following disclaimer.
1849b49cdaSZbigniew Bodek
1949b49cdaSZbigniew Bodek * Redistributions in binary form must reproduce the above copyright
2049b49cdaSZbigniew Bodek notice, this list of conditions and the following disclaimer in
2149b49cdaSZbigniew Bodek the documentation and/or other materials provided with the
2249b49cdaSZbigniew Bodek distribution.
2349b49cdaSZbigniew Bodek
2449b49cdaSZbigniew Bodek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2549b49cdaSZbigniew Bodek ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2649b49cdaSZbigniew Bodek WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2749b49cdaSZbigniew Bodek DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
2849b49cdaSZbigniew Bodek ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2949b49cdaSZbigniew Bodek (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3049b49cdaSZbigniew Bodek LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3149b49cdaSZbigniew Bodek ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3249b49cdaSZbigniew Bodek (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3349b49cdaSZbigniew Bodek SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3449b49cdaSZbigniew Bodek
3549b49cdaSZbigniew Bodek *******************************************************************************/
3649b49cdaSZbigniew Bodek
3749b49cdaSZbigniew Bodek /**
3849b49cdaSZbigniew Bodek * @file al_hal_udma_config.c
3949b49cdaSZbigniew Bodek *
4049b49cdaSZbigniew Bodek * @brief Universal DMA HAL driver for configurations
4149b49cdaSZbigniew Bodek *
4249b49cdaSZbigniew Bodek */
4349b49cdaSZbigniew Bodek
4449b49cdaSZbigniew Bodek #include <al_hal_common.h>
4549b49cdaSZbigniew Bodek #include <al_hal_udma_regs.h>
4649b49cdaSZbigniew Bodek #include <al_hal_udma_config.h>
4749b49cdaSZbigniew Bodek
4849b49cdaSZbigniew Bodek /**************** Misc configurations *********************/
4949b49cdaSZbigniew Bodek /** Configure AXI generic configuration */
al_udma_axi_set(struct udma_gen_axi * axi_regs,struct al_udma_axi_conf * axi)5049b49cdaSZbigniew Bodek int al_udma_axi_set(struct udma_gen_axi *axi_regs,
5149b49cdaSZbigniew Bodek struct al_udma_axi_conf *axi)
5249b49cdaSZbigniew Bodek {
5349b49cdaSZbigniew Bodek uint32_t reg;
5449b49cdaSZbigniew Bodek
5549b49cdaSZbigniew Bodek al_reg_write32(&axi_regs->cfg_1, axi->axi_timeout);
5649b49cdaSZbigniew Bodek
5749b49cdaSZbigniew Bodek reg = al_reg_read32(&axi_regs->cfg_2);
5849b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_CFG_2_ARB_PROMOTION_MASK;
5949b49cdaSZbigniew Bodek reg |= axi->arb_promotion;
6049b49cdaSZbigniew Bodek al_reg_write32(&axi_regs->cfg_2, reg);
6149b49cdaSZbigniew Bodek
6249b49cdaSZbigniew Bodek reg = al_reg_read32(&axi_regs->endian_cfg);
6349b49cdaSZbigniew Bodek if (axi->swap_8_bytes == AL_TRUE)
6449b49cdaSZbigniew Bodek reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN;
6549b49cdaSZbigniew Bodek else
6649b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_64B_EN;
6749b49cdaSZbigniew Bodek
6849b49cdaSZbigniew Bodek if (axi->swap_s2m_data == AL_TRUE)
6949b49cdaSZbigniew Bodek reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA;
7049b49cdaSZbigniew Bodek else
7149b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DATA;
7249b49cdaSZbigniew Bodek
7349b49cdaSZbigniew Bodek if (axi->swap_s2m_desc == AL_TRUE)
7449b49cdaSZbigniew Bodek reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC;
7549b49cdaSZbigniew Bodek else
7649b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_S2M_DESC;
7749b49cdaSZbigniew Bodek
7849b49cdaSZbigniew Bodek if (axi->swap_m2s_data == AL_TRUE)
7949b49cdaSZbigniew Bodek reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA;
8049b49cdaSZbigniew Bodek else
8149b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DATA;
8249b49cdaSZbigniew Bodek
8349b49cdaSZbigniew Bodek if (axi->swap_m2s_desc == AL_TRUE)
8449b49cdaSZbigniew Bodek reg |= UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC;
8549b49cdaSZbigniew Bodek else
8649b49cdaSZbigniew Bodek reg &= ~UDMA_GEN_AXI_ENDIAN_CFG_SWAP_M2S_DESC;
8749b49cdaSZbigniew Bodek
8849b49cdaSZbigniew Bodek al_reg_write32(&axi_regs->endian_cfg, reg);
8949b49cdaSZbigniew Bodek return 0;
9049b49cdaSZbigniew Bodek }
9149b49cdaSZbigniew Bodek
9249b49cdaSZbigniew Bodek /* Configure UDMA AXI M2S configuration */
9349b49cdaSZbigniew Bodek /** Configure AXI M2S submaster */
al_udma_m2s_axi_sm_set(struct al_udma_axi_submaster * m2s_sm,uint32_t * cfg_1,uint32_t * cfg_2,uint32_t * cfg_max_beats)9449b49cdaSZbigniew Bodek static int al_udma_m2s_axi_sm_set(struct al_udma_axi_submaster *m2s_sm,
9549b49cdaSZbigniew Bodek uint32_t *cfg_1, uint32_t *cfg_2,
9649b49cdaSZbigniew Bodek uint32_t *cfg_max_beats)
9749b49cdaSZbigniew Bodek {
9849b49cdaSZbigniew Bodek uint32_t reg;
9949b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_1);
10049b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK;
10149b49cdaSZbigniew Bodek reg |= m2s_sm->id & UDMA_AXI_M2S_COMP_WR_CFG_1_AWID_MASK;
10249b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK;
10349b49cdaSZbigniew Bodek reg |= (m2s_sm->cache_type <<
10449b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_SHIFT) &
10549b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_1_AWCACHE_MASK;
10649b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK;
10749b49cdaSZbigniew Bodek reg |= (m2s_sm->burst << UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_SHIFT) &
10849b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_1_AWBURST_MASK;
10949b49cdaSZbigniew Bodek al_reg_write32(cfg_1, reg);
11049b49cdaSZbigniew Bodek
11149b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_2);
11249b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK;
11349b49cdaSZbigniew Bodek reg |= m2s_sm->used_ext & UDMA_AXI_M2S_COMP_WR_CFG_2_AWUSER_MASK;
11449b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK;
11549b49cdaSZbigniew Bodek reg |= (m2s_sm->bus_size <<
11649b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_SHIFT) &
11749b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_2_AWSIZE_MASK;
11849b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK;
11949b49cdaSZbigniew Bodek reg |= (m2s_sm->qos << UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_SHIFT) &
12049b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_2_AWQOS_MASK;
12149b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK;
12249b49cdaSZbigniew Bodek reg |= (m2s_sm->prot << UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_SHIFT) &
12349b49cdaSZbigniew Bodek UDMA_AXI_M2S_COMP_WR_CFG_2_AWPROT_MASK;
12449b49cdaSZbigniew Bodek al_reg_write32(cfg_2, reg);
12549b49cdaSZbigniew Bodek
12649b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_max_beats);
12749b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
12849b49cdaSZbigniew Bodek reg |= m2s_sm->max_beats &
12949b49cdaSZbigniew Bodek UDMA_AXI_M2S_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
13049b49cdaSZbigniew Bodek al_reg_write32(cfg_max_beats, reg);
13149b49cdaSZbigniew Bodek
13249b49cdaSZbigniew Bodek return 0;
13349b49cdaSZbigniew Bodek }
13449b49cdaSZbigniew Bodek
13549b49cdaSZbigniew Bodek /** Configure UDMA AXI M2S configuration */
al_udma_m2s_axi_set(struct al_udma * udma,struct al_udma_m2s_axi_conf * axi_m2s)13649b49cdaSZbigniew Bodek int al_udma_m2s_axi_set(struct al_udma *udma,
13749b49cdaSZbigniew Bodek struct al_udma_m2s_axi_conf *axi_m2s)
13849b49cdaSZbigniew Bodek {
13949b49cdaSZbigniew Bodek uint32_t reg;
14049b49cdaSZbigniew Bodek
14149b49cdaSZbigniew Bodek al_udma_m2s_axi_sm_set(&axi_m2s->comp_write,
14249b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_1,
14349b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.comp_wr_cfg_2,
14449b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
14549b49cdaSZbigniew Bodek
14649b49cdaSZbigniew Bodek al_udma_m2s_axi_sm_set(&axi_m2s->data_read,
14749b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_1,
14849b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.data_rd_cfg_2,
14949b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.data_rd_cfg);
15049b49cdaSZbigniew Bodek
15149b49cdaSZbigniew Bodek al_udma_m2s_axi_sm_set(&axi_m2s->desc_read,
15249b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_1,
15349b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_2,
15449b49cdaSZbigniew Bodek &udma->udma_regs->m2s.axi_m2s.desc_rd_cfg_3);
15549b49cdaSZbigniew Bodek
15649b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg);
15749b49cdaSZbigniew Bodek if (axi_m2s->break_on_max_boundary == AL_TRUE)
15849b49cdaSZbigniew Bodek reg |= UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY;
15949b49cdaSZbigniew Bodek else
16049b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_DATA_RD_CFG_ALWAYS_BREAK_ON_MAX_BOUDRY;
16149b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.axi_m2s.data_rd_cfg, reg);
16249b49cdaSZbigniew Bodek
16349b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1);
16449b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
16549b49cdaSZbigniew Bodek reg |= (axi_m2s->min_axi_beats <<
16649b49cdaSZbigniew Bodek UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) &
16749b49cdaSZbigniew Bodek UDMA_AXI_M2S_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
16849b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.axi_m2s.desc_wr_cfg_1, reg);
16949b49cdaSZbigniew Bodek
17049b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg);
17149b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK;
17249b49cdaSZbigniew Bodek reg |= axi_m2s->ostand_max_data_read &
17349b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_DATA_RD_MASK;
17449b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK;
17549b49cdaSZbigniew Bodek reg |= (axi_m2s->ostand_max_desc_read <<
17649b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_SHIFT) &
17749b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_DESC_RD_MASK;
17849b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK;
17949b49cdaSZbigniew Bodek reg |= (axi_m2s->ostand_max_comp_req <<
18049b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_SHIFT) &
18149b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_REQ_MASK;
18249b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK;
18349b49cdaSZbigniew Bodek reg |= (axi_m2s->ostand_max_comp_write <<
18449b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_SHIFT) &
18549b49cdaSZbigniew Bodek UDMA_AXI_M2S_OSTAND_CFG_MAX_COMP_DATA_WR_MASK;
18649b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.axi_m2s.ostand_cfg, reg);
18749b49cdaSZbigniew Bodek return 0;
18849b49cdaSZbigniew Bodek }
18949b49cdaSZbigniew Bodek
19049b49cdaSZbigniew Bodek /** Configure AXI S2M submaster */
al_udma_s2m_axi_sm_set(struct al_udma_axi_submaster * s2m_sm,uint32_t * cfg_1,uint32_t * cfg_2,uint32_t * cfg_max_beats)19149b49cdaSZbigniew Bodek static int al_udma_s2m_axi_sm_set(struct al_udma_axi_submaster *s2m_sm,
19249b49cdaSZbigniew Bodek uint32_t *cfg_1, uint32_t *cfg_2,
19349b49cdaSZbigniew Bodek uint32_t *cfg_max_beats)
19449b49cdaSZbigniew Bodek {
19549b49cdaSZbigniew Bodek uint32_t reg;
19649b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_1);
19749b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK;
19849b49cdaSZbigniew Bodek reg |= s2m_sm->id & UDMA_AXI_S2M_COMP_WR_CFG_1_AWID_MASK;
19949b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK;
20049b49cdaSZbigniew Bodek reg |= (s2m_sm->cache_type <<
20149b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_SHIFT) &
20249b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_1_AWCACHE_MASK;
20349b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK;
20449b49cdaSZbigniew Bodek reg |= (s2m_sm->burst << UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_SHIFT) &
20549b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_1_AWBURST_MASK;
20649b49cdaSZbigniew Bodek al_reg_write32(cfg_1, reg);
20749b49cdaSZbigniew Bodek
20849b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_2);
20949b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK;
21049b49cdaSZbigniew Bodek reg |= s2m_sm->used_ext & UDMA_AXI_S2M_COMP_WR_CFG_2_AWUSER_MASK;
21149b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK;
21249b49cdaSZbigniew Bodek reg |= (s2m_sm->bus_size << UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_SHIFT) &
21349b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_2_AWSIZE_MASK;
21449b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK;
21549b49cdaSZbigniew Bodek reg |= (s2m_sm->qos << UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_SHIFT) &
21649b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_2_AWQOS_MASK;
21749b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK;
21849b49cdaSZbigniew Bodek reg |= (s2m_sm->prot << UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_SHIFT) &
21949b49cdaSZbigniew Bodek UDMA_AXI_S2M_COMP_WR_CFG_2_AWPROT_MASK;
22049b49cdaSZbigniew Bodek al_reg_write32(cfg_2, reg);
22149b49cdaSZbigniew Bodek
22249b49cdaSZbigniew Bodek reg = al_reg_read32(cfg_max_beats);
22349b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
22449b49cdaSZbigniew Bodek reg |= s2m_sm->max_beats &
22549b49cdaSZbigniew Bodek UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK;
22649b49cdaSZbigniew Bodek al_reg_write32(cfg_max_beats, reg);
22749b49cdaSZbigniew Bodek
22849b49cdaSZbigniew Bodek return 0;
22949b49cdaSZbigniew Bodek }
23049b49cdaSZbigniew Bodek
23149b49cdaSZbigniew Bodek /** Configure UDMA AXI S2M configuration */
al_udma_s2m_axi_set(struct al_udma * udma,struct al_udma_s2m_axi_conf * axi_s2m)23249b49cdaSZbigniew Bodek int al_udma_s2m_axi_set(struct al_udma *udma,
23349b49cdaSZbigniew Bodek struct al_udma_s2m_axi_conf *axi_s2m)
23449b49cdaSZbigniew Bodek {
23549b49cdaSZbigniew Bodek
23649b49cdaSZbigniew Bodek uint32_t reg;
23749b49cdaSZbigniew Bodek
23849b49cdaSZbigniew Bodek al_udma_s2m_axi_sm_set(&axi_s2m->data_write,
23949b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_1,
24049b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.data_wr_cfg_2,
24149b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.data_wr_cfg);
24249b49cdaSZbigniew Bodek
24349b49cdaSZbigniew Bodek al_udma_s2m_axi_sm_set(&axi_s2m->desc_read,
24449b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_4,
24549b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_5,
24649b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3);
24749b49cdaSZbigniew Bodek
24849b49cdaSZbigniew Bodek al_udma_s2m_axi_sm_set(&axi_s2m->comp_write,
24949b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_1,
25049b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.comp_wr_cfg_2,
25149b49cdaSZbigniew Bodek &udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1);
25249b49cdaSZbigniew Bodek
25349b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3);
25449b49cdaSZbigniew Bodek if (axi_s2m->break_on_max_boundary == AL_TRUE)
25549b49cdaSZbigniew Bodek reg |= UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY;
25649b49cdaSZbigniew Bodek else
25749b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_DESC_RD_CFG_3_ALWAYS_BREAK_ON_MAX_BOUDRY;
25849b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_rd_cfg_3, reg);
25949b49cdaSZbigniew Bodek
26049b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1);
26149b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
26249b49cdaSZbigniew Bodek reg |= (axi_s2m->min_axi_beats <<
26349b49cdaSZbigniew Bodek UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT) &
26449b49cdaSZbigniew Bodek UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK;
26549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1, reg);
26649b49cdaSZbigniew Bodek
26749b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd);
26849b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK;
26949b49cdaSZbigniew Bodek reg |= axi_s2m->ostand_max_desc_read &
27049b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_DESC_RD_OSTAND_MASK;
27149b49cdaSZbigniew Bodek
27249b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK;
27349b49cdaSZbigniew Bodek reg |= (axi_s2m->ack_fifo_depth <<
27449b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_SHIFT) &
27549b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_RD_MAX_STREAM_ACK_MASK;
27649b49cdaSZbigniew Bodek
27749b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_rd, reg);
27849b49cdaSZbigniew Bodek
27949b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr);
28049b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK;
28149b49cdaSZbigniew Bodek reg |= axi_s2m->ostand_max_data_req &
28249b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_WR_OSTAND_MASK;
28349b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK;
28449b49cdaSZbigniew Bodek reg |= (axi_s2m->ostand_max_data_write <<
28549b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_SHIFT) &
28649b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_DATA_BEATS_WR_OSTAND_MASK;
28749b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK;
28849b49cdaSZbigniew Bodek reg |= (axi_s2m->ostand_max_comp_req <<
28949b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_SHIFT) &
29049b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_REQ_MASK;
29149b49cdaSZbigniew Bodek reg &= ~UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK;
29249b49cdaSZbigniew Bodek reg |= (axi_s2m->ostand_max_comp_write <<
29349b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_SHIFT) &
29449b49cdaSZbigniew Bodek UDMA_AXI_S2M_OSTAND_CFG_WR_MAX_COMP_DATA_WR_OSTAND_MASK;
29549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.axi_s2m.ostand_cfg_wr, reg);
29649b49cdaSZbigniew Bodek return 0;
29749b49cdaSZbigniew Bodek }
29849b49cdaSZbigniew Bodek
29949b49cdaSZbigniew Bodek /** M2S packet len configuration */
al_udma_m2s_packet_size_cfg_set(struct al_udma * udma,struct al_udma_m2s_pkt_len_conf * conf)30049b49cdaSZbigniew Bodek int al_udma_m2s_packet_size_cfg_set(struct al_udma *udma,
30149b49cdaSZbigniew Bodek struct al_udma_m2s_pkt_len_conf *conf)
30249b49cdaSZbigniew Bodek {
30349b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s.cfg_len);
30449b49cdaSZbigniew Bodek uint32_t max_supported_size = UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK;
30549b49cdaSZbigniew Bodek
30649b49cdaSZbigniew Bodek al_assert(udma->type == UDMA_TX);
30749b49cdaSZbigniew Bodek
30849b49cdaSZbigniew Bodek if (conf->encode_64k_as_zero == AL_TRUE)
30949b49cdaSZbigniew Bodek max_supported_size += 1; /* 64K */
31049b49cdaSZbigniew Bodek
31149b49cdaSZbigniew Bodek if (conf->max_pkt_size > max_supported_size) {
31249b49cdaSZbigniew Bodek al_err("udma [%s]: requested max_pkt_size (0x%x) exceeds the"
31349b49cdaSZbigniew Bodek "supported limit (0x%x)\n", udma->name,
31449b49cdaSZbigniew Bodek conf->max_pkt_size, max_supported_size);
31549b49cdaSZbigniew Bodek return -EINVAL;
31649b49cdaSZbigniew Bodek }
31749b49cdaSZbigniew Bodek
31849b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K;
31949b49cdaSZbigniew Bodek if (conf->encode_64k_as_zero == AL_TRUE)
32049b49cdaSZbigniew Bodek reg |= UDMA_M2S_CFG_LEN_ENCODE_64K;
32149b49cdaSZbigniew Bodek else
32249b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_CFG_LEN_ENCODE_64K;
32349b49cdaSZbigniew Bodek
32449b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_CFG_LEN_MAX_PKT_SIZE_MASK;
32549b49cdaSZbigniew Bodek reg |= conf->max_pkt_size;
32649b49cdaSZbigniew Bodek
32749b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s.cfg_len, reg);
32849b49cdaSZbigniew Bodek return 0;
32949b49cdaSZbigniew Bodek }
33049b49cdaSZbigniew Bodek
33149b49cdaSZbigniew Bodek /** Report Error - to be used for abort */
al_udma_err_report(struct al_udma * udma)33249b49cdaSZbigniew Bodek void al_udma_err_report(struct al_udma *udma __attribute__((__unused__)))
33349b49cdaSZbigniew Bodek {
33449b49cdaSZbigniew Bodek return;
33549b49cdaSZbigniew Bodek }
33649b49cdaSZbigniew Bodek
33749b49cdaSZbigniew Bodek /** Statistics - TBD */
al_udma_stats_get(struct al_udma * udma)33849b49cdaSZbigniew Bodek void al_udma_stats_get(struct al_udma *udma __attribute__((__unused__)))
33949b49cdaSZbigniew Bodek {
34049b49cdaSZbigniew Bodek return;
34149b49cdaSZbigniew Bodek }
34249b49cdaSZbigniew Bodek
34349b49cdaSZbigniew Bodek /** Configure UDMA M2S descriptor prefetch */
al_udma_m2s_pref_set(struct al_udma * udma,struct al_udma_m2s_desc_pref_conf * conf)34449b49cdaSZbigniew Bodek int al_udma_m2s_pref_set(struct al_udma *udma,
34549b49cdaSZbigniew Bodek struct al_udma_m2s_desc_pref_conf *conf)
34649b49cdaSZbigniew Bodek {
34749b49cdaSZbigniew Bodek uint32_t reg;
34849b49cdaSZbigniew Bodek
34949b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1);
35049b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK;
35149b49cdaSZbigniew Bodek reg |= conf->desc_fifo_depth;
35249b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1, reg);
35349b49cdaSZbigniew Bodek
35449b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2);
35549b49cdaSZbigniew Bodek
35649b49cdaSZbigniew Bodek if (conf->sch_mode == SRR)
35749b49cdaSZbigniew Bodek reg |= UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
35849b49cdaSZbigniew Bodek else if (conf->sch_mode == STRICT)
35949b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
36049b49cdaSZbigniew Bodek else {
36149b49cdaSZbigniew Bodek al_err("udma [%s]: requested descriptor preferch arbiter "
36249b49cdaSZbigniew Bodek "mode (%d) is invalid\n", udma->name, conf->sch_mode);
36349b49cdaSZbigniew Bodek return -EINVAL;
36449b49cdaSZbigniew Bodek }
36549b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK;
36649b49cdaSZbigniew Bodek reg |= conf->max_desc_per_packet &
36749b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK;
36849b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2, reg);
36949b49cdaSZbigniew Bodek
37049b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3);
37149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
37249b49cdaSZbigniew Bodek reg |= conf->min_burst_below_thr &
37349b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
37449b49cdaSZbigniew Bodek
37549b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
37649b49cdaSZbigniew Bodek reg |=(conf->min_burst_above_thr <<
37749b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) &
37849b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
37949b49cdaSZbigniew Bodek
38049b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
38149b49cdaSZbigniew Bodek reg |= (conf->pref_thr <<
38249b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) &
38349b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
38449b49cdaSZbigniew Bodek
38549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3, reg);
38649b49cdaSZbigniew Bodek
38749b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.data_cfg);
38849b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK;
38949b49cdaSZbigniew Bodek reg |= conf->data_fifo_depth &
39049b49cdaSZbigniew Bodek UDMA_M2S_RD_DATA_CFG_DATA_FIFO_DEPTH_MASK;
39149b49cdaSZbigniew Bodek
39249b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK;
39349b49cdaSZbigniew Bodek reg |= (conf->max_pkt_limit
39449b49cdaSZbigniew Bodek << UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_SHIFT) &
39549b49cdaSZbigniew Bodek UDMA_M2S_RD_DATA_CFG_MAX_PKT_LIMIT_MASK;
39649b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rd.data_cfg, reg);
39749b49cdaSZbigniew Bodek
39849b49cdaSZbigniew Bodek return 0;
39949b49cdaSZbigniew Bodek }
40049b49cdaSZbigniew Bodek
40149b49cdaSZbigniew Bodek /** Ger the M2S UDMA descriptor prefetch */
al_udma_m2s_pref_get(struct al_udma * udma,struct al_udma_m2s_desc_pref_conf * conf)40249b49cdaSZbigniew Bodek int al_udma_m2s_pref_get(struct al_udma *udma,
40349b49cdaSZbigniew Bodek struct al_udma_m2s_desc_pref_conf *conf)
40449b49cdaSZbigniew Bodek {
40549b49cdaSZbigniew Bodek uint32_t reg;
40649b49cdaSZbigniew Bodek
40749b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_1);
40849b49cdaSZbigniew Bodek conf->desc_fifo_depth =
40949b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg, UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK,
41049b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_1_FIFO_DEPTH_SHIFT);
41149b49cdaSZbigniew Bodek
41249b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2);
41349b49cdaSZbigniew Bodek if (reg & UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK)
41449b49cdaSZbigniew Bodek conf->sch_mode = SRR;
41549b49cdaSZbigniew Bodek else
41649b49cdaSZbigniew Bodek conf->sch_mode = STRICT;
41749b49cdaSZbigniew Bodek conf->max_desc_per_packet =
41849b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
41949b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK,
42049b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT);
42149b49cdaSZbigniew Bodek
42249b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3);
42349b49cdaSZbigniew Bodek
42449b49cdaSZbigniew Bodek conf->min_burst_below_thr =
42549b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
42649b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK,
42749b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_SHIFT);
42849b49cdaSZbigniew Bodek
42949b49cdaSZbigniew Bodek conf->min_burst_above_thr =
43049b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
43149b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
43249b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT);
43349b49cdaSZbigniew Bodek
43449b49cdaSZbigniew Bodek conf->pref_thr = AL_REG_FIELD_GET(reg,
43549b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK,
43649b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT);
43749b49cdaSZbigniew Bodek return 0;
43849b49cdaSZbigniew Bodek }
43949b49cdaSZbigniew Bodek
44049b49cdaSZbigniew Bodek /* set max descriptors */
al_udma_m2s_max_descs_set(struct al_udma * udma,uint8_t max_descs)44149b49cdaSZbigniew Bodek int al_udma_m2s_max_descs_set(struct al_udma *udma, uint8_t max_descs)
44249b49cdaSZbigniew Bodek {
44349b49cdaSZbigniew Bodek uint32_t pref_thr = max_descs;
44449b49cdaSZbigniew Bodek uint32_t min_burst_above_thr = 4;
44549b49cdaSZbigniew Bodek al_assert(max_descs <= AL_UDMA_M2S_MAX_ALLOWED_DESCS_PER_PACKET);
44649b49cdaSZbigniew Bodek al_assert(max_descs > 0);
44749b49cdaSZbigniew Bodek
44849b49cdaSZbigniew Bodek /* increase min_burst_above_thr so larger burst can be used to fetch
44949b49cdaSZbigniew Bodek * descriptors */
45049b49cdaSZbigniew Bodek if (pref_thr >= 8)
45149b49cdaSZbigniew Bodek min_burst_above_thr = 8;
45249b49cdaSZbigniew Bodek else {
45349b49cdaSZbigniew Bodek /* don't set prefetch threshold too low so we can have the
45449b49cdaSZbigniew Bodek * min_burst_above_thr >= 4 */
45549b49cdaSZbigniew Bodek pref_thr = 4;
45649b49cdaSZbigniew Bodek }
45749b49cdaSZbigniew Bodek
45849b49cdaSZbigniew Bodek al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_2,
45949b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_MASK,
46049b49cdaSZbigniew Bodek max_descs << UDMA_M2S_RD_DESC_PREF_CFG_2_MAX_DESC_PER_PKT_SHIFT);
46149b49cdaSZbigniew Bodek
46249b49cdaSZbigniew Bodek al_reg_write32_masked(&udma->udma_regs->m2s.m2s_rd.desc_pref_cfg_3,
46349b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_MASK |
46449b49cdaSZbigniew Bodek UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
46549b49cdaSZbigniew Bodek (pref_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) |
46649b49cdaSZbigniew Bodek (min_burst_above_thr << UDMA_M2S_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT));
46749b49cdaSZbigniew Bodek
46849b49cdaSZbigniew Bodek return 0;
46949b49cdaSZbigniew Bodek }
47049b49cdaSZbigniew Bodek
47149b49cdaSZbigniew Bodek /* set s2m max descriptors */
al_udma_s2m_max_descs_set(struct al_udma * udma,uint8_t max_descs)47249b49cdaSZbigniew Bodek int al_udma_s2m_max_descs_set(struct al_udma *udma, uint8_t max_descs)
47349b49cdaSZbigniew Bodek {
47449b49cdaSZbigniew Bodek uint32_t pref_thr = max_descs;
47549b49cdaSZbigniew Bodek uint32_t min_burst_above_thr = 4;
47649b49cdaSZbigniew Bodek al_assert(max_descs <= AL_UDMA_S2M_MAX_ALLOWED_DESCS_PER_PACKET);
47749b49cdaSZbigniew Bodek al_assert(max_descs > 0);
47849b49cdaSZbigniew Bodek
47949b49cdaSZbigniew Bodek /* increase min_burst_above_thr so larger burst can be used to fetch
48049b49cdaSZbigniew Bodek * descriptors */
48149b49cdaSZbigniew Bodek if (pref_thr >= 8)
48249b49cdaSZbigniew Bodek min_burst_above_thr = 8;
48349b49cdaSZbigniew Bodek else
48449b49cdaSZbigniew Bodek /* don't set prefetch threshold too low so we can have the
48549b49cdaSZbigniew Bodek * min_burst_above_thr >= 4 */
48649b49cdaSZbigniew Bodek pref_thr = 4;
48749b49cdaSZbigniew Bodek
48849b49cdaSZbigniew Bodek al_reg_write32_masked(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3,
48949b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK |
49049b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK,
49149b49cdaSZbigniew Bodek (pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) |
49249b49cdaSZbigniew Bodek (min_burst_above_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT));
49349b49cdaSZbigniew Bodek
49449b49cdaSZbigniew Bodek return 0;
49549b49cdaSZbigniew Bodek }
49649b49cdaSZbigniew Bodek
al_udma_s2m_full_line_write_set(struct al_udma * udma,al_bool enable)49749b49cdaSZbigniew Bodek int al_udma_s2m_full_line_write_set(struct al_udma *udma, al_bool enable)
49849b49cdaSZbigniew Bodek {
49949b49cdaSZbigniew Bodek uint32_t val = 0;
50049b49cdaSZbigniew Bodek
50149b49cdaSZbigniew Bodek if (enable == AL_TRUE) {
50249b49cdaSZbigniew Bodek val = UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE;
50349b49cdaSZbigniew Bodek al_info("udma [%s]: full line write enabled\n", udma->name);
50449b49cdaSZbigniew Bodek }
50549b49cdaSZbigniew Bodek
50649b49cdaSZbigniew Bodek al_reg_write32_masked(&udma->udma_regs->s2m.s2m_wr.data_cfg_2,
50749b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE,
50849b49cdaSZbigniew Bodek val);
50949b49cdaSZbigniew Bodek return 0;
51049b49cdaSZbigniew Bodek }
51149b49cdaSZbigniew Bodek
51249b49cdaSZbigniew Bodek /** Configure S2M UDMA descriptor prefetch */
al_udma_s2m_pref_set(struct al_udma * udma,struct al_udma_s2m_desc_pref_conf * conf)51349b49cdaSZbigniew Bodek int al_udma_s2m_pref_set(struct al_udma *udma,
51449b49cdaSZbigniew Bodek struct al_udma_s2m_desc_pref_conf *conf)
51549b49cdaSZbigniew Bodek {
51649b49cdaSZbigniew Bodek uint32_t reg;
51749b49cdaSZbigniew Bodek
51849b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1);
51949b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_1_FIFO_DEPTH_MASK;
52049b49cdaSZbigniew Bodek reg |= conf->desc_fifo_depth;
52149b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_1, reg);
52249b49cdaSZbigniew Bodek
52349b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2);
52449b49cdaSZbigniew Bodek
52549b49cdaSZbigniew Bodek if (conf->sch_mode == SRR)
52649b49cdaSZbigniew Bodek reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
52749b49cdaSZbigniew Bodek else if (conf->sch_mode == STRICT)
52849b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PREF_FORCE_RR;
52949b49cdaSZbigniew Bodek else {
53049b49cdaSZbigniew Bodek al_err("udma [%s]: requested descriptor preferch arbiter "
53149b49cdaSZbigniew Bodek "mode (%d) is invalid\n", udma->name, conf->sch_mode);
53249b49cdaSZbigniew Bodek return -EINVAL;
53349b49cdaSZbigniew Bodek }
53449b49cdaSZbigniew Bodek if (conf->q_promotion == AL_TRUE)
53549b49cdaSZbigniew Bodek reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION;
53649b49cdaSZbigniew Bodek else
53749b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_Q_PROMOTION;
53849b49cdaSZbigniew Bodek
53949b49cdaSZbigniew Bodek if (conf->force_promotion == AL_TRUE)
54049b49cdaSZbigniew Bodek reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION;
54149b49cdaSZbigniew Bodek else
54249b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_FORCE_PROMOTION;
54349b49cdaSZbigniew Bodek
54449b49cdaSZbigniew Bodek if (conf->en_pref_prediction == AL_TRUE)
54549b49cdaSZbigniew Bodek reg |= UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION;
54649b49cdaSZbigniew Bodek else
54749b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_EN_PREF_PREDICTION;
54849b49cdaSZbigniew Bodek
54949b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK;
55049b49cdaSZbigniew Bodek reg |= (conf->promotion_th
55149b49cdaSZbigniew Bodek << UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_SHIFT) &
55249b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_2_PROMOTION_TH_MASK;
55349b49cdaSZbigniew Bodek
55449b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_2, reg);
55549b49cdaSZbigniew Bodek
55649b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3);
55749b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
55849b49cdaSZbigniew Bodek reg |= (conf->pref_thr << UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_SHIFT) &
55949b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_PREF_THR_MASK;
56049b49cdaSZbigniew Bodek
56149b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
56249b49cdaSZbigniew Bodek reg |= conf->min_burst_below_thr &
56349b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_BELOW_THR_MASK;
56449b49cdaSZbigniew Bodek
56549b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
56649b49cdaSZbigniew Bodek reg |=(conf->min_burst_above_thr <<
56749b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_SHIFT) &
56849b49cdaSZbigniew Bodek UDMA_S2M_RD_DESC_PREF_CFG_3_MIN_BURST_ABOVE_THR_MASK;
56949b49cdaSZbigniew Bodek
57049b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_3, reg);
57149b49cdaSZbigniew Bodek
57249b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4);
57349b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK;
57449b49cdaSZbigniew Bodek reg |= conf->a_full_thr & UDMA_S2M_RD_DESC_PREF_CFG_4_A_FULL_THR_MASK;
57549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_rd.desc_pref_cfg_4, reg);
57649b49cdaSZbigniew Bodek
57749b49cdaSZbigniew Bodek
57849b49cdaSZbigniew Bodek return 0;
57949b49cdaSZbigniew Bodek }
58049b49cdaSZbigniew Bodek
58149b49cdaSZbigniew Bodek /* Configure S2M UDMA data write */
al_udma_s2m_data_write_set(struct al_udma * udma,struct al_udma_s2m_data_write_conf * conf)58249b49cdaSZbigniew Bodek int al_udma_s2m_data_write_set(struct al_udma *udma,
58349b49cdaSZbigniew Bodek struct al_udma_s2m_data_write_conf *conf)
58449b49cdaSZbigniew Bodek {
58549b49cdaSZbigniew Bodek uint32_t reg;
58649b49cdaSZbigniew Bodek
58749b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1);
58849b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK;
58949b49cdaSZbigniew Bodek reg |= conf->data_fifo_depth &
59049b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_1_DATA_FIFO_DEPTH_MASK;
59149b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK;
59249b49cdaSZbigniew Bodek reg |= (conf->max_pkt_limit <<
59349b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_SHIFT) &
59449b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_1_MAX_PKT_LIMIT_MASK;
59549b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK;
59649b49cdaSZbigniew Bodek reg |= (conf->fifo_margin <<
59749b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_SHIFT) &
59849b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_1_FIFO_MARGIN_MASK;
59949b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_1, reg);
60049b49cdaSZbigniew Bodek
60149b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2);
60249b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK;
60349b49cdaSZbigniew Bodek reg |= conf->desc_wait_timer &
60449b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK;
60549b49cdaSZbigniew Bodek reg &= ~(UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC |
60649b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC |
60749b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF |
60849b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE |
60949b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1);
61049b49cdaSZbigniew Bodek reg |= conf->flags &
61149b49cdaSZbigniew Bodek (UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC |
61249b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC |
61349b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_WAIT_FOR_PREF |
61449b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_FULL_LINE_MODE |
61549b49cdaSZbigniew Bodek UDMA_S2M_WR_DATA_CFG_2_DIRECT_HDR_USE_BUF1);
61649b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg);
61749b49cdaSZbigniew Bodek
61849b49cdaSZbigniew Bodek return 0;
61949b49cdaSZbigniew Bodek }
62049b49cdaSZbigniew Bodek
62149b49cdaSZbigniew Bodek /* Configure S2M UDMA completion */
al_udma_s2m_completion_set(struct al_udma * udma,struct al_udma_s2m_completion_conf * conf)62249b49cdaSZbigniew Bodek int al_udma_s2m_completion_set(struct al_udma *udma,
62349b49cdaSZbigniew Bodek struct al_udma_s2m_completion_conf *conf)
62449b49cdaSZbigniew Bodek {
62549b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_1c);
62649b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
62749b49cdaSZbigniew Bodek reg |= conf->desc_size & UDMA_S2M_COMP_CFG_1C_DESC_SIZE_MASK;
62849b49cdaSZbigniew Bodek if (conf->cnt_words == AL_TRUE)
62949b49cdaSZbigniew Bodek reg |= UDMA_S2M_COMP_CFG_1C_CNT_WORDS;
63049b49cdaSZbigniew Bodek else
63149b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_1C_CNT_WORDS;
63249b49cdaSZbigniew Bodek if (conf->q_promotion == AL_TRUE)
63349b49cdaSZbigniew Bodek reg |= UDMA_S2M_COMP_CFG_1C_Q_PROMOTION;
63449b49cdaSZbigniew Bodek else
63549b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_1C_Q_PROMOTION;
63649b49cdaSZbigniew Bodek if (conf->force_rr == AL_TRUE)
63749b49cdaSZbigniew Bodek reg |= UDMA_S2M_COMP_CFG_1C_FORCE_RR;
63849b49cdaSZbigniew Bodek else
63949b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_1C_FORCE_RR;
64049b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK;
64149b49cdaSZbigniew Bodek reg |= (conf->q_free_min << UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_SHIFT) &
64249b49cdaSZbigniew Bodek UDMA_S2M_COMP_CFG_1C_Q_FREE_MIN_MASK;
64349b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_1c, reg);
64449b49cdaSZbigniew Bodek
64549b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_comp.cfg_2c);
64649b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK;
64749b49cdaSZbigniew Bodek reg |= conf->comp_fifo_depth
64849b49cdaSZbigniew Bodek & UDMA_S2M_COMP_CFG_2C_COMP_FIFO_DEPTH_MASK;
64949b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK;
65049b49cdaSZbigniew Bodek reg |= (conf->unack_fifo_depth
65149b49cdaSZbigniew Bodek << UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_SHIFT) &
65249b49cdaSZbigniew Bodek UDMA_S2M_COMP_CFG_2C_UNACK_FIFO_DEPTH_MASK;
65349b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_2c, reg);
65449b49cdaSZbigniew Bodek
65549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_comp.cfg_application_ack,
65649b49cdaSZbigniew Bodek conf->timeout);
65749b49cdaSZbigniew Bodek return 0;
65849b49cdaSZbigniew Bodek }
65949b49cdaSZbigniew Bodek
66049b49cdaSZbigniew Bodek /** Configure the M2S UDMA scheduling mode */
al_udma_m2s_sc_set(struct al_udma * udma,struct al_udma_m2s_dwrr_conf * sched)66149b49cdaSZbigniew Bodek int al_udma_m2s_sc_set(struct al_udma *udma,
66249b49cdaSZbigniew Bodek struct al_udma_m2s_dwrr_conf *sched)
66349b49cdaSZbigniew Bodek {
66449b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched);
66549b49cdaSZbigniew Bodek
66649b49cdaSZbigniew Bodek if (sched->enable_dwrr == AL_TRUE)
66749b49cdaSZbigniew Bodek reg |= UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR;
66849b49cdaSZbigniew Bodek else
66949b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_DWRR_CFG_SCHED_EN_DWRR;
67049b49cdaSZbigniew Bodek
67149b49cdaSZbigniew Bodek if (sched->pkt_mode == AL_TRUE)
67249b49cdaSZbigniew Bodek reg |= UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN;
67349b49cdaSZbigniew Bodek else
67449b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_DWRR_CFG_SCHED_PKT_MODE_EN;
67549b49cdaSZbigniew Bodek
67649b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_MASK;
67749b49cdaSZbigniew Bodek reg |= sched->weight << UDMA_M2S_DWRR_CFG_SCHED_WEIGHT_INC_SHIFT;
67849b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_MASK;
67949b49cdaSZbigniew Bodek reg |= sched->inc_factor << UDMA_M2S_DWRR_CFG_SCHED_INC_FACTOR_SHIFT;
68049b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.cfg_sched, reg);
68149b49cdaSZbigniew Bodek
68249b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt);
68349b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_DWRR_CTRL_DEFICIT_CNT_INIT_MASK;
68449b49cdaSZbigniew Bodek reg |= sched->deficit_init_val;
68549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_dwrr.ctrl_deficit_cnt, reg);
68649b49cdaSZbigniew Bodek
68749b49cdaSZbigniew Bodek return 0;
68849b49cdaSZbigniew Bodek }
68949b49cdaSZbigniew Bodek
69049b49cdaSZbigniew Bodek /** Configure the M2S UDMA rate limitation */
al_udma_m2s_rlimit_set(struct al_udma * udma,struct al_udma_m2s_rlimit_mode * mode)69149b49cdaSZbigniew Bodek int al_udma_m2s_rlimit_set(struct al_udma *udma,
69249b49cdaSZbigniew Bodek struct al_udma_m2s_rlimit_mode *mode)
69349b49cdaSZbigniew Bodek {
69449b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(
69549b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg);
69649b49cdaSZbigniew Bodek
69749b49cdaSZbigniew Bodek if (mode->pkt_mode_en == AL_TRUE)
69849b49cdaSZbigniew Bodek reg |= UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN;
69949b49cdaSZbigniew Bodek else
70049b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_PKT_MODE_EN;
70149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK;
70249b49cdaSZbigniew Bodek reg |= mode->short_cycle_sz &
70349b49cdaSZbigniew Bodek UDMA_M2S_RATE_LIMITER_GEN_CFG_SHORT_CYCLE_SIZE_MASK;
70449b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.gen_cfg, reg);
70549b49cdaSZbigniew Bodek
70649b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token);
70749b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK;
70849b49cdaSZbigniew Bodek reg |= mode->token_init_val &
70949b49cdaSZbigniew Bodek UDMA_M2S_RATE_LIMITER_CTRL_TOKEN_RST_MASK;
71049b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_token, reg);
71149b49cdaSZbigniew Bodek
71249b49cdaSZbigniew Bodek return 0;
71349b49cdaSZbigniew Bodek }
71449b49cdaSZbigniew Bodek
al_udma_m2s_rlimit_reset(struct al_udma * udma)71549b49cdaSZbigniew Bodek int al_udma_m2s_rlimit_reset(struct al_udma *udma)
71649b49cdaSZbigniew Bodek {
71749b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(
71849b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt);
71949b49cdaSZbigniew Bodek reg |= UDMA_M2S_RATE_LIMITER_CTRL_CYCLE_CNT_RST;
72049b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_rate_limiter.ctrl_cycle_cnt,
72149b49cdaSZbigniew Bodek reg);
72249b49cdaSZbigniew Bodek return 0;
72349b49cdaSZbigniew Bodek }
72449b49cdaSZbigniew Bodek
72549b49cdaSZbigniew Bodek /** Configure the Stream/Q rate limitation */
al_udma_common_rlimit_set(struct udma_rlimit_common * regs,struct al_udma_m2s_rlimit_cfg * conf)72649b49cdaSZbigniew Bodek static int al_udma_common_rlimit_set(struct udma_rlimit_common *regs,
72749b49cdaSZbigniew Bodek struct al_udma_m2s_rlimit_cfg *conf)
72849b49cdaSZbigniew Bodek {
72949b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(®s->cfg_1s);
73049b49cdaSZbigniew Bodek /* mask max burst size, and enable/pause control bits */
73149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK;
73249b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN;
73349b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE;
73449b49cdaSZbigniew Bodek reg |= conf->max_burst_sz &
73549b49cdaSZbigniew Bodek UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_MAX_BURST_SIZE_MASK;
73649b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_1s, reg);
73749b49cdaSZbigniew Bodek
73849b49cdaSZbigniew Bodek reg = al_reg_read32(®s->cfg_cycle);
73949b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK;
74049b49cdaSZbigniew Bodek reg |= conf->long_cycle_sz &
74149b49cdaSZbigniew Bodek UDMA_M2S_STREAM_RATE_LIMITER_CFG_CYCLE_LONG_CYCLE_SIZE_MASK;
74249b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_cycle, reg);
74349b49cdaSZbigniew Bodek
74449b49cdaSZbigniew Bodek reg = al_reg_read32(®s->cfg_token_size_1);
74549b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK;
74649b49cdaSZbigniew Bodek reg |= conf->long_cycle &
74749b49cdaSZbigniew Bodek UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_1_LONG_CYCLE_MASK;
74849b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_token_size_1, reg);
74949b49cdaSZbigniew Bodek
75049b49cdaSZbigniew Bodek reg = al_reg_read32(®s->cfg_token_size_2);
75149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK;
75249b49cdaSZbigniew Bodek reg |= conf->short_cycle &
75349b49cdaSZbigniew Bodek UDMA_M2S_STREAM_RATE_LIMITER_CFG_TOKEN_SIZE_2_SHORT_CYCLE_MASK;
75449b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_token_size_2, reg);
75549b49cdaSZbigniew Bodek
75649b49cdaSZbigniew Bodek reg = al_reg_read32(®s->mask);
75749b49cdaSZbigniew Bodek reg &= ~0xf; /* only bits 0-3 defined */
75849b49cdaSZbigniew Bodek reg |= conf->mask & 0xf;
75949b49cdaSZbigniew Bodek al_reg_write32(®s->mask, reg);
76049b49cdaSZbigniew Bodek
76149b49cdaSZbigniew Bodek return 0;
76249b49cdaSZbigniew Bodek }
76349b49cdaSZbigniew Bodek
al_udma_common_rlimit_act(struct udma_rlimit_common * regs,enum al_udma_m2s_rlimit_action act)76449b49cdaSZbigniew Bodek static int al_udma_common_rlimit_act(struct udma_rlimit_common *regs,
76549b49cdaSZbigniew Bodek enum al_udma_m2s_rlimit_action act)
76649b49cdaSZbigniew Bodek {
76749b49cdaSZbigniew Bodek uint32_t reg;
76849b49cdaSZbigniew Bodek
76949b49cdaSZbigniew Bodek switch (act) {
77049b49cdaSZbigniew Bodek case AL_UDMA_STRM_RLIMIT_ENABLE:
77149b49cdaSZbigniew Bodek reg = al_reg_read32(®s->cfg_1s);
77249b49cdaSZbigniew Bodek reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_EN;
77349b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_1s, reg);
77449b49cdaSZbigniew Bodek break;
77549b49cdaSZbigniew Bodek case AL_UDMA_STRM_RLIMIT_PAUSE:
77649b49cdaSZbigniew Bodek reg = al_reg_read32(®s->cfg_1s);
77749b49cdaSZbigniew Bodek reg |= UDMA_M2S_STREAM_RATE_LIMITER_CFG_1S_PAUSE;
77849b49cdaSZbigniew Bodek al_reg_write32(®s->cfg_1s, reg);
77949b49cdaSZbigniew Bodek break;
78049b49cdaSZbigniew Bodek case AL_UDMA_STRM_RLIMIT_RESET:
78149b49cdaSZbigniew Bodek reg = al_reg_read32(®s->sw_ctrl);
78249b49cdaSZbigniew Bodek reg |= UDMA_M2S_STREAM_RATE_LIMITER_SW_CTRL_RST_TOKEN_CNT;
78349b49cdaSZbigniew Bodek al_reg_write32(®s->sw_ctrl, reg);
78449b49cdaSZbigniew Bodek break;
78549b49cdaSZbigniew Bodek default:
78649b49cdaSZbigniew Bodek return -EINVAL;
78749b49cdaSZbigniew Bodek }
78849b49cdaSZbigniew Bodek return 0;
78949b49cdaSZbigniew Bodek }
79049b49cdaSZbigniew Bodek
79149b49cdaSZbigniew Bodek /** Configure the M2S Stream rate limitation */
al_udma_m2s_strm_rlimit_set(struct al_udma * udma,struct al_udma_m2s_rlimit_cfg * conf)79249b49cdaSZbigniew Bodek int al_udma_m2s_strm_rlimit_set(struct al_udma *udma,
79349b49cdaSZbigniew Bodek struct al_udma_m2s_rlimit_cfg *conf)
79449b49cdaSZbigniew Bodek {
79549b49cdaSZbigniew Bodek struct udma_rlimit_common *rlimit_regs =
79649b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit;
79749b49cdaSZbigniew Bodek
79849b49cdaSZbigniew Bodek return al_udma_common_rlimit_set(rlimit_regs, conf);
79949b49cdaSZbigniew Bodek }
80049b49cdaSZbigniew Bodek
al_udma_m2s_strm_rlimit_act(struct al_udma * udma,enum al_udma_m2s_rlimit_action act)80149b49cdaSZbigniew Bodek int al_udma_m2s_strm_rlimit_act(struct al_udma *udma,
80249b49cdaSZbigniew Bodek enum al_udma_m2s_rlimit_action act)
80349b49cdaSZbigniew Bodek {
80449b49cdaSZbigniew Bodek struct udma_rlimit_common *rlimit_regs =
80549b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_stream_rate_limiter.rlimit;
80649b49cdaSZbigniew Bodek
80749b49cdaSZbigniew Bodek if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) {
80849b49cdaSZbigniew Bodek al_err("udma [%s]: udma stream rate limit invalid action "
80949b49cdaSZbigniew Bodek "(%d)\n", udma->name, act);
81049b49cdaSZbigniew Bodek return -EINVAL;
81149b49cdaSZbigniew Bodek }
81249b49cdaSZbigniew Bodek return 0;
81349b49cdaSZbigniew Bodek }
81449b49cdaSZbigniew Bodek
81549b49cdaSZbigniew Bodek /** Configure the M2S UDMA Q rate limitation */
al_udma_m2s_q_rlimit_set(struct al_udma_q * udma_q,struct al_udma_m2s_rlimit_cfg * conf)81649b49cdaSZbigniew Bodek int al_udma_m2s_q_rlimit_set(struct al_udma_q *udma_q,
81749b49cdaSZbigniew Bodek struct al_udma_m2s_rlimit_cfg *conf)
81849b49cdaSZbigniew Bodek {
81949b49cdaSZbigniew Bodek struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit;
82049b49cdaSZbigniew Bodek
82149b49cdaSZbigniew Bodek return al_udma_common_rlimit_set(rlimit_regs, conf);
82249b49cdaSZbigniew Bodek }
82349b49cdaSZbigniew Bodek
al_udma_m2s_q_rlimit_act(struct al_udma_q * udma_q,enum al_udma_m2s_rlimit_action act)82449b49cdaSZbigniew Bodek int al_udma_m2s_q_rlimit_act(struct al_udma_q *udma_q,
82549b49cdaSZbigniew Bodek enum al_udma_m2s_rlimit_action act)
82649b49cdaSZbigniew Bodek {
82749b49cdaSZbigniew Bodek struct udma_rlimit_common *rlimit_regs = &udma_q->q_regs->m2s_q.rlimit;
82849b49cdaSZbigniew Bodek
82949b49cdaSZbigniew Bodek if (al_udma_common_rlimit_act(rlimit_regs, act) == -EINVAL) {
83049b49cdaSZbigniew Bodek al_err("udma [%s %d]: udma stream rate limit invalid action "
83149b49cdaSZbigniew Bodek "(%d)\n",
83249b49cdaSZbigniew Bodek udma_q->udma->name, udma_q->qid, act);
83349b49cdaSZbigniew Bodek return -EINVAL;
83449b49cdaSZbigniew Bodek }
83549b49cdaSZbigniew Bodek return 0;
83649b49cdaSZbigniew Bodek }
83749b49cdaSZbigniew Bodek
83849b49cdaSZbigniew Bodek /** Configure the M2S UDMA Q scheduling mode */
al_udma_m2s_q_sc_set(struct al_udma_q * udma_q,struct al_udma_m2s_q_dwrr_conf * conf)83949b49cdaSZbigniew Bodek int al_udma_m2s_q_sc_set(struct al_udma_q *udma_q,
84049b49cdaSZbigniew Bodek struct al_udma_m2s_q_dwrr_conf *conf)
84149b49cdaSZbigniew Bodek {
84249b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1);
84349b49cdaSZbigniew Bodek
84449b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK;
84549b49cdaSZbigniew Bodek reg |= conf->max_deficit_cnt_sz &
84649b49cdaSZbigniew Bodek UDMA_M2S_Q_DWRR_CFG_1_MAX_DEFICIT_CNT_SIZE_MASK;
84749b49cdaSZbigniew Bodek if (conf->strict == AL_TRUE)
84849b49cdaSZbigniew Bodek reg |= UDMA_M2S_Q_DWRR_CFG_1_STRICT;
84949b49cdaSZbigniew Bodek else
85049b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_1_STRICT;
85149b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg);
85249b49cdaSZbigniew Bodek
85349b49cdaSZbigniew Bodek reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_2);
85449b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
85549b49cdaSZbigniew Bodek reg |= (conf->axi_qos << UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_SHIFT) &
85649b49cdaSZbigniew Bodek UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
85749b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
85849b49cdaSZbigniew Bodek reg |= conf->q_qos & UDMA_M2S_Q_DWRR_CFG_2_Q_QOS_MASK;
85949b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_2, reg);
86049b49cdaSZbigniew Bodek
86149b49cdaSZbigniew Bodek reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_3);
86249b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK;
86349b49cdaSZbigniew Bodek reg |= conf->weight & UDMA_M2S_Q_DWRR_CFG_3_WEIGHT_MASK;
86449b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_3, reg);
86549b49cdaSZbigniew Bodek
86649b49cdaSZbigniew Bodek return 0;
86749b49cdaSZbigniew Bodek }
86849b49cdaSZbigniew Bodek
al_udma_m2s_q_sc_pause(struct al_udma_q * udma_q,al_bool set)86949b49cdaSZbigniew Bodek int al_udma_m2s_q_sc_pause(struct al_udma_q *udma_q, al_bool set)
87049b49cdaSZbigniew Bodek {
87149b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_cfg_1);
87249b49cdaSZbigniew Bodek
87349b49cdaSZbigniew Bodek if (set == AL_TRUE)
87449b49cdaSZbigniew Bodek reg |= UDMA_M2S_Q_DWRR_CFG_1_PAUSE;
87549b49cdaSZbigniew Bodek else
87649b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_Q_DWRR_CFG_1_PAUSE;
87749b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_cfg_1, reg);
87849b49cdaSZbigniew Bodek
87949b49cdaSZbigniew Bodek return 0;
88049b49cdaSZbigniew Bodek }
88149b49cdaSZbigniew Bodek
al_udma_m2s_q_sc_reset(struct al_udma_q * udma_q)88249b49cdaSZbigniew Bodek int al_udma_m2s_q_sc_reset(struct al_udma_q *udma_q)
88349b49cdaSZbigniew Bodek {
88449b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl);
88549b49cdaSZbigniew Bodek
88649b49cdaSZbigniew Bodek reg |= UDMA_M2S_Q_DWRR_SW_CTRL_RST_CNT;
88749b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->m2s_q.dwrr_sw_ctrl, reg);
88849b49cdaSZbigniew Bodek
88949b49cdaSZbigniew Bodek return 0;
89049b49cdaSZbigniew Bodek }
89149b49cdaSZbigniew Bodek
89249b49cdaSZbigniew Bodek /** M2S UDMA completion and application timeouts */
al_udma_m2s_comp_timeouts_set(struct al_udma * udma,struct al_udma_m2s_comp_timeouts * conf)89349b49cdaSZbigniew Bodek int al_udma_m2s_comp_timeouts_set(struct al_udma *udma,
89449b49cdaSZbigniew Bodek struct al_udma_m2s_comp_timeouts *conf)
89549b49cdaSZbigniew Bodek {
89649b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c);
89749b49cdaSZbigniew Bodek
89849b49cdaSZbigniew Bodek if (conf->sch_mode == SRR)
89949b49cdaSZbigniew Bodek reg |= UDMA_M2S_COMP_CFG_1C_FORCE_RR;
90049b49cdaSZbigniew Bodek else if (conf->sch_mode == STRICT)
90149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_COMP_CFG_1C_FORCE_RR;
90249b49cdaSZbigniew Bodek else {
90349b49cdaSZbigniew Bodek al_err("udma [%s]: requested completion descriptor preferch "
90449b49cdaSZbigniew Bodek "arbiter mode (%d) is invalid\n",
90549b49cdaSZbigniew Bodek udma->name, conf->sch_mode);
90649b49cdaSZbigniew Bodek return -EINVAL;
90749b49cdaSZbigniew Bodek }
90849b49cdaSZbigniew Bodek if (conf->enable_q_promotion == AL_TRUE)
90949b49cdaSZbigniew Bodek reg |= UDMA_M2S_COMP_CFG_1C_Q_PROMOTION;
91049b49cdaSZbigniew Bodek else
91149b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_COMP_CFG_1C_Q_PROMOTION;
91249b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK;
91349b49cdaSZbigniew Bodek reg |=
91449b49cdaSZbigniew Bodek conf->comp_fifo_depth << UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT;
91549b49cdaSZbigniew Bodek
91649b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK;
91749b49cdaSZbigniew Bodek reg |= conf->unack_fifo_depth
91849b49cdaSZbigniew Bodek << UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT;
91949b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_1c, reg);
92049b49cdaSZbigniew Bodek
92149b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_coal
92249b49cdaSZbigniew Bodek , conf->coal_timeout);
92349b49cdaSZbigniew Bodek
92449b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack);
92549b49cdaSZbigniew Bodek reg &= ~UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK;
92649b49cdaSZbigniew Bodek reg |= conf->app_timeout << UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT;
92749b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->m2s.m2s_comp.cfg_application_ack, reg);
92849b49cdaSZbigniew Bodek return 0;
92949b49cdaSZbigniew Bodek }
93049b49cdaSZbigniew Bodek
al_udma_m2s_comp_timeouts_get(struct al_udma * udma,struct al_udma_m2s_comp_timeouts * conf)93149b49cdaSZbigniew Bodek int al_udma_m2s_comp_timeouts_get(struct al_udma *udma,
93249b49cdaSZbigniew Bodek struct al_udma_m2s_comp_timeouts *conf)
93349b49cdaSZbigniew Bodek {
93449b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma->udma_regs->m2s.m2s_comp.cfg_1c);
93549b49cdaSZbigniew Bodek
93649b49cdaSZbigniew Bodek if (reg & UDMA_M2S_COMP_CFG_1C_FORCE_RR)
93749b49cdaSZbigniew Bodek conf->sch_mode = SRR;
93849b49cdaSZbigniew Bodek else
93949b49cdaSZbigniew Bodek conf->sch_mode = STRICT;
94049b49cdaSZbigniew Bodek
94149b49cdaSZbigniew Bodek if (reg & UDMA_M2S_COMP_CFG_1C_Q_PROMOTION)
94249b49cdaSZbigniew Bodek conf->enable_q_promotion = AL_TRUE;
94349b49cdaSZbigniew Bodek else
94449b49cdaSZbigniew Bodek conf->enable_q_promotion = AL_FALSE;
94549b49cdaSZbigniew Bodek
94649b49cdaSZbigniew Bodek conf->comp_fifo_depth =
94749b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
94849b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_MASK,
94949b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_1C_COMP_FIFO_DEPTH_SHIFT);
95049b49cdaSZbigniew Bodek conf->unack_fifo_depth =
95149b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
95249b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_MASK,
95349b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_1C_UNACK_FIFO_DEPTH_SHIFT);
95449b49cdaSZbigniew Bodek
95549b49cdaSZbigniew Bodek conf->coal_timeout = al_reg_read32(
95649b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_comp.cfg_coal);
95749b49cdaSZbigniew Bodek
95849b49cdaSZbigniew Bodek reg = al_reg_read32(
95949b49cdaSZbigniew Bodek &udma->udma_regs->m2s.m2s_comp.cfg_application_ack);
96049b49cdaSZbigniew Bodek
96149b49cdaSZbigniew Bodek conf->app_timeout =
96249b49cdaSZbigniew Bodek AL_REG_FIELD_GET(reg,
96349b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_MASK,
96449b49cdaSZbigniew Bodek UDMA_M2S_COMP_CFG_APPLICATION_ACK_TOUT_SHIFT);
96549b49cdaSZbigniew Bodek
96649b49cdaSZbigniew Bodek return 0;
96749b49cdaSZbigniew Bodek }
96849b49cdaSZbigniew Bodek
96949b49cdaSZbigniew Bodek /**
97049b49cdaSZbigniew Bodek * S2M UDMA configure no descriptors behaviour
97149b49cdaSZbigniew Bodek */
al_udma_s2m_no_desc_cfg_set(struct al_udma * udma,al_bool drop_packet,al_bool gen_interrupt,uint32_t wait_for_desc_timeout)97249b49cdaSZbigniew Bodek int al_udma_s2m_no_desc_cfg_set(struct al_udma *udma, al_bool drop_packet, al_bool gen_interrupt, uint32_t wait_for_desc_timeout)
97349b49cdaSZbigniew Bodek {
97449b49cdaSZbigniew Bodek uint32_t reg;
97549b49cdaSZbigniew Bodek
97649b49cdaSZbigniew Bodek reg = al_reg_read32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2);
97749b49cdaSZbigniew Bodek
97849b49cdaSZbigniew Bodek if ((drop_packet == AL_TRUE) && (wait_for_desc_timeout == 0)) {
97949b49cdaSZbigniew Bodek al_err("udam [%s]: setting timeout to 0 will cause the udma to wait forever instead of dropping the packet", udma->name);
98049b49cdaSZbigniew Bodek return -EINVAL;
98149b49cdaSZbigniew Bodek }
98249b49cdaSZbigniew Bodek
98349b49cdaSZbigniew Bodek if (drop_packet == AL_TRUE)
98449b49cdaSZbigniew Bodek reg |= UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC;
98549b49cdaSZbigniew Bodek else
98649b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_2_DROP_IF_NO_DESC;
98749b49cdaSZbigniew Bodek
98849b49cdaSZbigniew Bodek if (gen_interrupt == AL_TRUE)
98949b49cdaSZbigniew Bodek reg |= UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC;
99049b49cdaSZbigniew Bodek else
99149b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_WR_DATA_CFG_2_HINT_IF_NO_DESC;
99249b49cdaSZbigniew Bodek
99349b49cdaSZbigniew Bodek AL_REG_FIELD_SET(reg, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_MASK, UDMA_S2M_WR_DATA_CFG_2_DESC_WAIT_TIMER_SHIFT, wait_for_desc_timeout);
99449b49cdaSZbigniew Bodek
99549b49cdaSZbigniew Bodek al_reg_write32(&udma->udma_regs->s2m.s2m_wr.data_cfg_2, reg);
99649b49cdaSZbigniew Bodek
99749b49cdaSZbigniew Bodek return 0;
99849b49cdaSZbigniew Bodek }
99949b49cdaSZbigniew Bodek
100049b49cdaSZbigniew Bodek /* S2M UDMA configure a queue's completion update */
al_udma_s2m_q_compl_updade_config(struct al_udma_q * udma_q,al_bool enable)100149b49cdaSZbigniew Bodek int al_udma_s2m_q_compl_updade_config(struct al_udma_q *udma_q, al_bool enable)
100249b49cdaSZbigniew Bodek {
100349b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
100449b49cdaSZbigniew Bodek
100549b49cdaSZbigniew Bodek if (enable == AL_TRUE)
100649b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
100749b49cdaSZbigniew Bodek else
100849b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
100949b49cdaSZbigniew Bodek
101049b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
101149b49cdaSZbigniew Bodek
101249b49cdaSZbigniew Bodek return 0;
101349b49cdaSZbigniew Bodek }
101449b49cdaSZbigniew Bodek
101549b49cdaSZbigniew Bodek /* S2M UDMA configure a queue's completion descriptors coalescing */
al_udma_s2m_q_compl_coal_config(struct al_udma_q * udma_q,al_bool enable,uint32_t coal_timeout)101649b49cdaSZbigniew Bodek int al_udma_s2m_q_compl_coal_config(struct al_udma_q *udma_q, al_bool enable, uint32_t
101749b49cdaSZbigniew Bodek coal_timeout)
101849b49cdaSZbigniew Bodek {
101949b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
102049b49cdaSZbigniew Bodek
102149b49cdaSZbigniew Bodek if (enable == AL_TRUE)
102249b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
102349b49cdaSZbigniew Bodek else
102449b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
102549b49cdaSZbigniew Bodek
102649b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
102749b49cdaSZbigniew Bodek
102849b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, coal_timeout);
102949b49cdaSZbigniew Bodek return 0;
103049b49cdaSZbigniew Bodek }
103149b49cdaSZbigniew Bodek
103249b49cdaSZbigniew Bodek /* S2M UDMA configure completion descriptors write burst parameters */
al_udma_s2m_compl_desc_burst_config(struct al_udma * udma,uint16_t burst_size)103349b49cdaSZbigniew Bodek int al_udma_s2m_compl_desc_burst_config(struct al_udma *udma, uint16_t
103449b49cdaSZbigniew Bodek burst_size)
103549b49cdaSZbigniew Bodek {
103649b49cdaSZbigniew Bodek if ((burst_size != 64) && (burst_size != 128) && (burst_size != 256)) {
103749b49cdaSZbigniew Bodek al_err("%s: invalid burst_size value (%d)\n", __func__,
103849b49cdaSZbigniew Bodek burst_size);
103949b49cdaSZbigniew Bodek return -EINVAL;
104049b49cdaSZbigniew Bodek }
104149b49cdaSZbigniew Bodek
104249b49cdaSZbigniew Bodek /* convert burst size from bytes to beats (16 byte) */
104349b49cdaSZbigniew Bodek burst_size = burst_size / 16;
104449b49cdaSZbigniew Bodek al_reg_write32_masked(&udma->udma_regs->s2m.axi_s2m.desc_wr_cfg_1,
104549b49cdaSZbigniew Bodek UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_MASK |
104649b49cdaSZbigniew Bodek UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_MASK,
104749b49cdaSZbigniew Bodek burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MIN_AXI_BEATS_SHIFT |
104849b49cdaSZbigniew Bodek burst_size << UDMA_AXI_S2M_DESC_WR_CFG_1_MAX_AXI_BEATS_SHIFT);
104949b49cdaSZbigniew Bodek return 0;
105049b49cdaSZbigniew Bodek }
105149b49cdaSZbigniew Bodek
105249b49cdaSZbigniew Bodek /* S2M UDMA configure a queue's completion descriptors header split */
al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q * udma_q,al_bool enable,al_bool force_hdr_split,uint32_t hdr_len)105349b49cdaSZbigniew Bodek int al_udma_s2m_q_compl_hdr_split_config(struct al_udma_q *udma_q, al_bool enable,
105449b49cdaSZbigniew Bodek al_bool force_hdr_split, uint32_t hdr_len)
105549b49cdaSZbigniew Bodek {
105649b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg);
105749b49cdaSZbigniew Bodek
105849b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
105949b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
106049b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
106149b49cdaSZbigniew Bodek
106249b49cdaSZbigniew Bodek if (enable == AL_TRUE) {
106349b49cdaSZbigniew Bodek reg |= hdr_len & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
106449b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
106549b49cdaSZbigniew Bodek
106649b49cdaSZbigniew Bodek if (force_hdr_split == AL_TRUE)
106749b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
106849b49cdaSZbigniew Bodek }
106949b49cdaSZbigniew Bodek
107049b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg);
107149b49cdaSZbigniew Bodek
107249b49cdaSZbigniew Bodek return 0;
107349b49cdaSZbigniew Bodek }
107449b49cdaSZbigniew Bodek
107549b49cdaSZbigniew Bodek /* S2M UDMA per queue completion configuration */
al_udma_s2m_q_comp_set(struct al_udma_q * udma_q,struct al_udma_s2m_q_comp_conf * conf)107649b49cdaSZbigniew Bodek int al_udma_s2m_q_comp_set(struct al_udma_q *udma_q,
107749b49cdaSZbigniew Bodek struct al_udma_s2m_q_comp_conf *conf)
107849b49cdaSZbigniew Bodek {
107949b49cdaSZbigniew Bodek uint32_t reg = al_reg_read32(&udma_q->q_regs->s2m_q.comp_cfg);
108049b49cdaSZbigniew Bodek if (conf->en_comp_ring_update == AL_TRUE)
108149b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
108249b49cdaSZbigniew Bodek else
108349b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_COMP_CFG_EN_COMP_RING_UPDATE;
108449b49cdaSZbigniew Bodek
108549b49cdaSZbigniew Bodek if (conf->dis_comp_coal == AL_TRUE)
108649b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
108749b49cdaSZbigniew Bodek else
108849b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_COMP_CFG_DIS_COMP_COAL;
108949b49cdaSZbigniew Bodek
109049b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg, reg);
109149b49cdaSZbigniew Bodek
109249b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.comp_cfg_2, conf->comp_timer);
109349b49cdaSZbigniew Bodek
109449b49cdaSZbigniew Bodek reg = al_reg_read32(&udma_q->q_regs->s2m_q.pkt_cfg);
109549b49cdaSZbigniew Bodek
109649b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
109749b49cdaSZbigniew Bodek reg |= conf->hdr_split_size & UDMA_S2M_Q_PKT_CFG_HDR_SPLIT_SIZE_MASK;
109849b49cdaSZbigniew Bodek if (conf->force_hdr_split == AL_TRUE)
109949b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
110049b49cdaSZbigniew Bodek else
110149b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_FORCE_HDR_SPLIT;
110249b49cdaSZbigniew Bodek if (conf->en_hdr_split == AL_TRUE)
110349b49cdaSZbigniew Bodek reg |= UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
110449b49cdaSZbigniew Bodek else
110549b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_Q_PKT_CFG_EN_HDR_SPLIT;
110649b49cdaSZbigniew Bodek
110749b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.pkt_cfg, reg);
110849b49cdaSZbigniew Bodek
110949b49cdaSZbigniew Bodek reg = al_reg_read32(&udma_q->q_regs->s2m_q.qos_cfg);
111049b49cdaSZbigniew Bodek reg &= ~UDMA_S2M_QOS_CFG_Q_QOS_MASK;
111149b49cdaSZbigniew Bodek reg |= conf->q_qos & UDMA_S2M_QOS_CFG_Q_QOS_MASK;
111249b49cdaSZbigniew Bodek al_reg_write32(&udma_q->q_regs->s2m_q.qos_cfg, reg);
111349b49cdaSZbigniew Bodek
111449b49cdaSZbigniew Bodek return 0;
111549b49cdaSZbigniew Bodek }
111649b49cdaSZbigniew Bodek
111749b49cdaSZbigniew Bodek /* UDMA Target-ID control configuration per queue */
al_udma_gen_tgtid_conf_queue_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_conf * conf,uint32_t qid)111849b49cdaSZbigniew Bodek void al_udma_gen_tgtid_conf_queue_set(
111949b49cdaSZbigniew Bodek struct unit_regs *unit_regs,
112049b49cdaSZbigniew Bodek struct al_udma_gen_tgtid_conf *conf,
112149b49cdaSZbigniew Bodek uint32_t qid)
112249b49cdaSZbigniew Bodek {
112349b49cdaSZbigniew Bodek uint32_t *tx_tgtid_reg, *rx_tgtid_reg, *tx_tgtaddr_reg, *rx_tgtaddr_reg;
112449b49cdaSZbigniew Bodek unsigned int rev_id;
112549b49cdaSZbigniew Bodek
112649b49cdaSZbigniew Bodek al_assert(qid < DMA_MAX_Q);
112749b49cdaSZbigniew Bodek rev_id = al_udma_get_revision(unit_regs);
112849b49cdaSZbigniew Bodek
112949b49cdaSZbigniew Bodek /* Target-ID TX DESC EN */
113049b49cdaSZbigniew Bodek al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
113149b49cdaSZbigniew Bodek (conf->tx_q_conf[qid].desc_en << qid) <<
113249b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT,
113349b49cdaSZbigniew Bodek (conf->tx_q_conf[qid].desc_en << qid) <<
113449b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_DESC_EN_SHIFT);
113549b49cdaSZbigniew Bodek
113649b49cdaSZbigniew Bodek /* Target-ID TX QUEUE EN */
113749b49cdaSZbigniew Bodek al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
113849b49cdaSZbigniew Bodek (conf->tx_q_conf[qid].queue_en << qid) <<
113949b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT,
114049b49cdaSZbigniew Bodek (conf->tx_q_conf[qid].queue_en << qid) <<
114149b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_TX_Q_TGTID_QUEUE_EN_SHIFT);
114249b49cdaSZbigniew Bodek
114349b49cdaSZbigniew Bodek /* Target-ID RX DESC EN */
114449b49cdaSZbigniew Bodek al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
114549b49cdaSZbigniew Bodek (conf->rx_q_conf[qid].desc_en << qid) <<
114649b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT,
114749b49cdaSZbigniew Bodek (conf->rx_q_conf[qid].desc_en << qid) <<
114849b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_DESC_EN_SHIFT);
114949b49cdaSZbigniew Bodek
115049b49cdaSZbigniew Bodek /* Target-ID RX QUEUE EN */
115149b49cdaSZbigniew Bodek al_reg_write32_masked(&unit_regs->gen.tgtid.cfg_tgtid_0,
115249b49cdaSZbigniew Bodek (conf->rx_q_conf[qid].queue_en << qid) <<
115349b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT,
115449b49cdaSZbigniew Bodek (conf->rx_q_conf[qid].queue_en << qid) <<
115549b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_RX_Q_TGTID_QUEUE_EN_SHIFT);
115649b49cdaSZbigniew Bodek
115749b49cdaSZbigniew Bodek switch (qid) {
115849b49cdaSZbigniew Bodek case 0:
115949b49cdaSZbigniew Bodek case 1:
116049b49cdaSZbigniew Bodek tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_1;
116149b49cdaSZbigniew Bodek rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_3;
116249b49cdaSZbigniew Bodek tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_0;
116349b49cdaSZbigniew Bodek rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_2;
116449b49cdaSZbigniew Bodek break;
116549b49cdaSZbigniew Bodek case 2:
116649b49cdaSZbigniew Bodek case 3:
116749b49cdaSZbigniew Bodek tx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_2;
116849b49cdaSZbigniew Bodek rx_tgtid_reg = &unit_regs->gen.tgtid.cfg_tgtid_4;
116949b49cdaSZbigniew Bodek tx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_1;
117049b49cdaSZbigniew Bodek rx_tgtaddr_reg = &unit_regs->gen.tgtaddr.cfg_tgtaddr_3;
117149b49cdaSZbigniew Bodek break;
117249b49cdaSZbigniew Bodek default:
117349b49cdaSZbigniew Bodek al_assert(AL_FALSE);
117449b49cdaSZbigniew Bodek return;
117549b49cdaSZbigniew Bodek }
117649b49cdaSZbigniew Bodek
117749b49cdaSZbigniew Bodek al_reg_write32_masked(tx_tgtid_reg,
117849b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
117949b49cdaSZbigniew Bodek conf->tx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
118049b49cdaSZbigniew Bodek
118149b49cdaSZbigniew Bodek al_reg_write32_masked(rx_tgtid_reg,
118249b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_MASK(qid),
118349b49cdaSZbigniew Bodek conf->rx_q_conf[qid].tgtid << UDMA_GEN_TGTID_CFG_TGTID_SHIFT(qid));
118449b49cdaSZbigniew Bodek
118549b49cdaSZbigniew Bodek if (rev_id >= AL_UDMA_REV_ID_REV2) {
118649b49cdaSZbigniew Bodek al_reg_write32_masked(tx_tgtaddr_reg,
118749b49cdaSZbigniew Bodek UDMA_GEN_TGTADDR_CFG_MASK(qid),
118849b49cdaSZbigniew Bodek conf->tx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
118949b49cdaSZbigniew Bodek
119049b49cdaSZbigniew Bodek al_reg_write32_masked(rx_tgtaddr_reg,
119149b49cdaSZbigniew Bodek UDMA_GEN_TGTADDR_CFG_MASK(qid),
119249b49cdaSZbigniew Bodek conf->rx_q_conf[qid].tgtaddr << UDMA_GEN_TGTADDR_CFG_SHIFT(qid));
119349b49cdaSZbigniew Bodek }
119449b49cdaSZbigniew Bodek }
119549b49cdaSZbigniew Bodek
119649b49cdaSZbigniew Bodek /* UDMA Target-ID control configuration */
al_udma_gen_tgtid_conf_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_conf * conf)119749b49cdaSZbigniew Bodek void al_udma_gen_tgtid_conf_set(
119849b49cdaSZbigniew Bodek struct unit_regs *unit_regs,
119949b49cdaSZbigniew Bodek struct al_udma_gen_tgtid_conf *conf)
120049b49cdaSZbigniew Bodek {
120149b49cdaSZbigniew Bodek int i;
120249b49cdaSZbigniew Bodek
120349b49cdaSZbigniew Bodek for (i = 0; i < DMA_MAX_Q; i++)
120449b49cdaSZbigniew Bodek al_udma_gen_tgtid_conf_queue_set(unit_regs, conf, i);
120549b49cdaSZbigniew Bodek }
120649b49cdaSZbigniew Bodek
120749b49cdaSZbigniew Bodek /* UDMA Target-ID MSIX control configuration */
al_udma_gen_tgtid_msix_conf_set(struct unit_regs * unit_regs,struct al_udma_gen_tgtid_msix_conf * conf)120849b49cdaSZbigniew Bodek void al_udma_gen_tgtid_msix_conf_set(
120949b49cdaSZbigniew Bodek struct unit_regs *unit_regs,
121049b49cdaSZbigniew Bodek struct al_udma_gen_tgtid_msix_conf *conf)
121149b49cdaSZbigniew Bodek {
121249b49cdaSZbigniew Bodek al_reg_write32_masked(
121349b49cdaSZbigniew Bodek &unit_regs->gen.tgtid.cfg_tgtid_0,
121449b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN |
121549b49cdaSZbigniew Bodek UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL,
121649b49cdaSZbigniew Bodek (conf->access_en ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_ACCESS_EN : 0) |
121749b49cdaSZbigniew Bodek (conf->sel ? UDMA_GEN_TGTID_CFG_TGTID_0_MSIX_TGTID_SEL : 0));
121849b49cdaSZbigniew Bodek }
121949b49cdaSZbigniew Bodek