2022-11-10 22:22:48 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copyright : (C) 2022 Phytium Information Technology, Inc.
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
|
|
|
|
|
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
|
|
|
|
|
* either version 1.0 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
|
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
* See the Phytium Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* FilePath: fnand_dma.c
|
|
|
|
|
* Date: 2022-02-10 14:53:42
|
|
|
|
|
* LastEditTime: 2022-02-18 08:56:22
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* Description: This file is dma descriptor management API.
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*
|
|
|
|
|
* Modify History:
|
|
|
|
|
* Ver Who Date Changes
|
|
|
|
|
* ----- ------ -------- --------------------------------------
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* 1.0 huanghe 2022/05/10 first release
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "fnand_dma.h"
|
|
|
|
|
#include "fnand.h"
|
|
|
|
|
#include "ferror_code.h"
|
|
|
|
|
#include "fdebug.h"
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "fcache.h"
|
|
|
|
|
#include "fnand_toggle.h"
|
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_FNAND_DMA_DEBUG_EN
|
|
|
|
|
#define FNAND_DMA_DEBUG_TAG "FNAND_DMA"
|
|
|
|
|
#define FNAND_DMA_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FNAND_DMA_DEBUG_TAG, format, ##__VA_ARGS__)
|
|
|
|
|
#define FNAND_DMA_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FNAND_DMA_DEBUG_TAG, format, ##__VA_ARGS__)
|
|
|
|
|
#define FNAND_DMA_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FNAND_DMA_DEBUG_TAG, format, ##__VA_ARGS__)
|
|
|
|
|
#else
|
|
|
|
|
#define FNAND_DMA_DEBUG_I(format, ...)
|
|
|
|
|
#define FNAND_DMA_DEBUG_W(format, ...)
|
|
|
|
|
#define FNAND_DMA_DEBUG_E(format, ...)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FNandDmaDump(struct FNandDmaDescriptor *descriptor_p)
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FNAND_DMA_DEBUG_I("Phytium NFC cmd dump: ");
|
|
|
|
|
FNAND_DMA_DEBUG_I("cmd0:%x, cmd1:%x, ctrl:%x, page_cnt:%d ",
|
2022-11-10 22:22:48 +08:00
|
|
|
|
descriptor_p->cmd0, descriptor_p->cmd1, descriptor_p->cmd_ctrl.ctrl, descriptor_p->page_cnt);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FNAND_DMA_DEBUG_I("mem_addr_first:%02x %02x %02x %02x %02x ",
|
2022-11-10 22:22:48 +08:00
|
|
|
|
descriptor_p->mem_addr_first[0], descriptor_p->mem_addr_first[1], descriptor_p->mem_addr_first[2], descriptor_p->mem_addr_first[3], descriptor_p->mem_addr_first[4]);
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FNAND_DMA_DEBUG_I("addr:%02x %02x %02x %02x %02x ",
|
2022-11-10 22:22:48 +08:00
|
|
|
|
descriptor_p->addr[0], descriptor_p->addr[1], descriptor_p->addr[2], descriptor_p->addr[3], descriptor_p->addr[4]);
|
|
|
|
|
|
|
|
|
|
FNAND_DMA_DEBUG_I(" csel : 0x%x ", descriptor_p->cmd_ctrl.nfc_ctrl.csel);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" dbc : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.dbc);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" addr_cyc : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.addr_cyc);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" nc : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.nc);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" cmd_type : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" dc : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.dc);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" auto_rs : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.auto_rs);
|
|
|
|
|
FNAND_DMA_DEBUG_I(" ecc_en : %d ", descriptor_p->cmd_ctrl.nfc_ctrl.ecc_en);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void FNandAddrCorrect(struct FNandDmaDescriptor *descriptor_p,
|
|
|
|
|
u8 *addr_p,
|
|
|
|
|
u32 addr_length)
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
if (addr_length == 0 || addr_p == NULL)
|
|
|
|
|
{
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FNAND_DMA_DEBUG_I("The addr_p is null , Calibration is not required ");
|
2022-11-10 22:22:48 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addr_length >= FNAND_NFC_ADDR_MAX_LEN)
|
|
|
|
|
{
|
|
|
|
|
memcpy(descriptor_p->addr, addr_p, FNAND_NFC_ADDR_MAX_LEN);
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.addr_cyc = FNAND_NFC_ADDR_MAX_LEN;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.addr_cyc = 0;
|
|
|
|
|
for (i = addr_length - 1, j = FNAND_NFC_ADDR_MAX_LEN - 1; i >= 0; i--, j--)
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->addr[j] = addr_p[i]; /* data shift to high array */
|
|
|
|
|
descriptor_p->addr[i] = 0;
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.addr_cyc++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FError FNandDmaPack(FNandCmdFormat *cmd_format,
|
|
|
|
|
struct FNandDmaDescriptor *descriptor_p,
|
|
|
|
|
FNandDmaPackData *pack_data_p
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
u32 i;
|
|
|
|
|
FASSERT(cmd_format != NULL);
|
|
|
|
|
FASSERT(descriptor_p != NULL);
|
|
|
|
|
descriptor_p->cmd_ctrl.ctrl = 0;
|
|
|
|
|
|
|
|
|
|
/* cmd */
|
|
|
|
|
if (cmd_format->end_cmd == TOGGLE_END_CMD_NONE) /* Only one cmd ,need to correct */
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->cmd1 = cmd_format->start_cmd;
|
|
|
|
|
descriptor_p->cmd0 = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->cmd0 = cmd_format->start_cmd;
|
|
|
|
|
descriptor_p->cmd1 = cmd_format->end_cmd;
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.dbc = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* addr */
|
|
|
|
|
FNandAddrCorrect(descriptor_p, pack_data_p->addr_p, pack_data_p->addr_length);
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type = cmd_format->cmd_type; /* cmd type */
|
2023-05-11 10:25:21 +08:00
|
|
|
|
FNAND_DMA_DEBUG_I("cmd_type is %x", descriptor_p->cmd_ctrl.nfc_ctrl.cmd_type);
|
2022-11-10 22:22:48 +08:00
|
|
|
|
if (pack_data_p->contiune_dma)
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.nc = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.csel = (0xf ^ (1 << pack_data_p->chip_addr));
|
|
|
|
|
|
|
|
|
|
if (pack_data_p->phy_address && (pack_data_p->phy_bytes_length > 0))
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.dc = 1;
|
|
|
|
|
for (i = 0; i < FNAND_NFC_ADDR_MAX_LEN; i++)
|
|
|
|
|
{
|
|
|
|
|
descriptor_p->mem_addr_first[i] = pack_data_p->phy_address >> (8 * i) & 0xff;
|
|
|
|
|
}
|
|
|
|
|
descriptor_p->page_cnt = pack_data_p->phy_bytes_length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cmd_format->auto_rs)
|
2023-05-11 10:25:21 +08:00
|
|
|
|
{
|
2022-11-10 22:22:48 +08:00
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.auto_rs = 1;
|
2023-05-11 10:25:21 +08:00
|
|
|
|
}
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
if (cmd_format->ecc_en)
|
2023-05-11 10:25:21 +08:00
|
|
|
|
{
|
2022-11-10 22:22:48 +08:00
|
|
|
|
descriptor_p->cmd_ctrl.nfc_ctrl.ecc_en = 1;
|
2023-05-11 10:25:21 +08:00
|
|
|
|
}
|
2022-11-10 22:22:48 +08:00
|
|
|
|
|
|
|
|
|
/* invalid descriptor and buffer */
|
|
|
|
|
FCacheDCacheInvalidateRange((intptr)descriptor_p, sizeof(struct FNandDmaDescriptor));
|
|
|
|
|
FCacheDCacheInvalidateRange((intptr)pack_data_p->addr_p, pack_data_p->addr_length);
|
|
|
|
|
|
|
|
|
|
FNandDmaDump(descriptor_p);
|
|
|
|
|
|
|
|
|
|
return FT_SUCCESS;
|
|
|
|
|
}
|