183 lines
7.3 KiB
C
183 lines
7.3 KiB
C
/*******************************************************************************
|
|
* DISCLAIMER
|
|
* This software is supplied by Renesas Electronics Corporation and is only
|
|
* intended for use with Renesas products. No other uses are authorized. This
|
|
* software is owned by Renesas Electronics Corporation and is protected under
|
|
* all applicable laws, including copyright laws.
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
|
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
|
|
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
|
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
|
|
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
|
|
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
|
|
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
|
|
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
* Renesas reserves the right, without notice, to make changes to this software
|
|
* and to discontinue the availability of this software. By using this software,
|
|
* you agree to the additional terms and conditions found by accessing the
|
|
* following link:
|
|
* http://www.renesas.com/disclaimer
|
|
* Copyright 2021-2022 Renesas Electronics Corporation All rights reserved.
|
|
*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* DESCRIPTION : DMA driver
|
|
******************************************************************************/
|
|
/******************************************************************************
|
|
* @file dma.c
|
|
* - Version : 0.07
|
|
* @brief DMA driver.
|
|
* .
|
|
*****************************************************************************/
|
|
/******************************************************************************
|
|
* History : DD.MM.YYYY Version Description
|
|
* : 28.07.2021 0.01 First Release
|
|
* : 30.09.2021 0.02 Change function name load_start and
|
|
* load_end function.
|
|
* : 15.10.2021 0.03 modified to not use CHCLR.
|
|
* : 06.01.2022 0.04 Add exception handling for ICUMX_WDTA.
|
|
* : 02.02.2022 0.05 Add MFIS Lock/Unlock.
|
|
* : 22.06.2022 0.06 Replace address align check to function.
|
|
* : Remove some defines.
|
|
* : 20.12.2022 0.07 Add mask when writing to TCR register.
|
|
*****************************************************************************/
|
|
|
|
#include <stdint.h>
|
|
#include <mem_io.h>
|
|
#include <dma.h>
|
|
#include <rpc.h>
|
|
#include <log.h>
|
|
#include <wdt.h>
|
|
#include <mfis.h>
|
|
|
|
#define DMOR_INIT (uint16_t)(0x0301U)
|
|
#define DMOR_HW_INIT (uint16_t)(0x0000U)
|
|
#define TCR_CNT_SHIFT (6U)
|
|
#define TCR_UPPER8BIT_MASK (0x00FFFFFFU)
|
|
#define CHCR_TRN_MODE (0x00105409U)
|
|
#define CHCR_TE_BIT (0x00000002U)
|
|
#define TE_FLAG (0x00000000U)
|
|
#define CHCR_CAE_BIT (0x80000000U)
|
|
#define CHCR_CAE_BIT_NOERROR (0x00000000U)
|
|
#define CHCR_CAIE_BIT (0x40000000U)
|
|
#define CHCR_DPM_BIT (0x30000000U)
|
|
#define CHCR_RPT_BIT (0x0F000000U)
|
|
#define CHCR_WAIT_BIT (0x00800000U)
|
|
#define CHCR_DPB_BIT (0x00400000U)
|
|
#define CHCR_DSE_BIT (0x00080000U)
|
|
#define CHCR_DSIE_BIT (0x00040000U)
|
|
#define CHCR_DM_BIT (0x0000C000U)
|
|
#define CHCR_SM_BIT (0x00003000U)
|
|
#define CHCR_RS_BIT (0x00000F00U)
|
|
#define CHCR_TS_BIT (0x00300018U)
|
|
#define CHCR_IE_BIT (0x00000004U)
|
|
#define CHCR_TE_BIT (0x00000002U)
|
|
#define CHCR_DE_BIT (0x00000001U)
|
|
#define CHCR_CONF_MASK (CHCR_TS_BIT | CHCR_DM_BIT | CHCR_SM_BIT | CHCR_RS_BIT | CHCR_DE_BIT)
|
|
#define CHCR_DESCRIPTOR_CONF_MASK (CHCR_DPM_BIT | CHCR_RPT_BIT | CHCR_WAIT_BIT | CHCR_DPB_BIT)
|
|
#define CHCR_INTERRUPT_MASK (CHCR_CAIE_BIT | CHCR_DSIE_BIT | CHCR_IE_BIT)
|
|
#define CHCR_FLAG_MASK (CHCR_CAE_BIT | CHCR_DSE_BIT | CHCR_TE_BIT)
|
|
#define CHCR_ALL_BIT_MASK (CHCR_CONF_MASK | CHCR_DESCRIPTOR_CONF_MASK | CHCR_INTERRUPT_MASK | CHCR_FLAG_MASK)
|
|
#define DAR_HW_INIT (0x00000000U)
|
|
#define SAR_HW_INIT (0x00000000U)
|
|
#define TCR_HW_INIT (0x00000000U)
|
|
|
|
/* fraction mask for 256-byte units */
|
|
#define FRACTION_MASK_256_BYTE (0x000000FFU)
|
|
|
|
void dma_init(void)
|
|
{
|
|
uint32_t reg;
|
|
|
|
/* DMA operation */
|
|
mem_write16(RTDMA_DMOR, DMOR_INIT);
|
|
/* DMA secure control register */
|
|
reg = mem_read32(RTDMA_DMSEC);
|
|
reg |= ((uint32_t)1U << DMACH);
|
|
mem_write32(RTDMA_DMSEC, reg);
|
|
|
|
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
|
|
reg &= ~(CHCR_ALL_BIT_MASK);
|
|
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
|
|
}
|
|
/* End of function dma_init(void) */
|
|
|
|
void dma_trans_start(uint32_t dst, uint32_t src, uint32_t len)
|
|
{
|
|
uint32_t reg;
|
|
|
|
/* dst and src must be 64-byte boundary. */
|
|
dma_address_align_check(dst, src);
|
|
|
|
/* round up 256 byte alignment */
|
|
len += FRACTION_MASK_256_BYTE;
|
|
len &= (~(uint32_t)(FRACTION_MASK_256_BYTE));
|
|
|
|
/* DMA destination address */
|
|
mem_write32(dma_get_rtdma_dar_addr(DMACH), dst);
|
|
/* DMA source address */
|
|
mem_write32(dma_get_rtdma_sar_addr(DMACH), src);
|
|
/* DMA 64bytes-unit transfer count */
|
|
mem_write32(dma_get_rtdma_tcr_addr(DMACH), ((len >> TCR_CNT_SHIFT) & TCR_UPPER8BIT_MASK));
|
|
/* Lock to avoid conflict with RPC */
|
|
mfis_lock();
|
|
/* DMA channel control */
|
|
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
|
|
reg |= CHCR_TRN_MODE;
|
|
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
|
|
}
|
|
/* End of function dma_trans_start(uint32_t dst, uint32_t src, uint32_t len) */
|
|
|
|
void dma_trans_end_check(void)
|
|
{
|
|
uint32_t reg;
|
|
|
|
/* Check end of DMA transfer. */
|
|
do
|
|
{
|
|
wdt_restart();
|
|
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
|
|
/* Check error of DMA transfer */
|
|
if ((reg & CHCR_CAE_BIT) != CHCR_CAE_BIT_NOERROR)
|
|
{
|
|
ERROR("DMA - Channel Address Error\n");
|
|
panic;
|
|
}
|
|
} while ((reg & CHCR_TE_BIT) == TE_FLAG);
|
|
|
|
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
|
|
reg &= ~(CHCR_ALL_BIT_MASK);
|
|
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
|
|
|
|
rpc_end_state_check();
|
|
/* Unlock to avoid conflict with RPC */
|
|
mfis_unlock();
|
|
}
|
|
/* End of function dma_trans_end_check(void) */
|
|
|
|
void dma_release(void)
|
|
{
|
|
uint32_t reg;
|
|
|
|
/* DMA channel control */
|
|
reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH));
|
|
reg &= ~(CHCR_ALL_BIT_MASK);
|
|
mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg);
|
|
|
|
/* DMA destination address */
|
|
mem_write32(dma_get_rtdma_dar_addr(DMACH), DAR_HW_INIT);
|
|
/* DMA source address */
|
|
mem_write32(dma_get_rtdma_sar_addr(DMACH), SAR_HW_INIT);
|
|
/* DMA 64bytes-unit transfer count */
|
|
mem_write32(dma_get_rtdma_tcr_addr(DMACH), TCR_HW_INIT);
|
|
|
|
reg = mem_read32(RTDMA_DMSEC);
|
|
reg &= (~((uint32_t)1U << DMACH));
|
|
mem_write32(RTDMA_DMSEC, reg);
|
|
|
|
/* DMA operation */
|
|
mem_write16(RTDMA_DMOR, DMOR_HW_INIT);
|
|
}
|
|
/* End of function dma_release(void) */
|