204 lines
6.4 KiB
C
204 lines
6.4 KiB
C
|
/*
|
|||
|
* 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_intr.c
|
|||
|
* Date: 2022-02-10 14:53:42
|
|||
|
* LastEditTime: 2022-02-18 08:56:46
|
|||
|
* Description: This files is for
|
|||
|
*
|
|||
|
* Modify History:
|
|||
|
* Ver Who Date Changes
|
|||
|
* ----- ------ -------- --------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
#include "fnand.h"
|
|||
|
#include "fnand_hw.h"
|
|||
|
#include "fassert.h"
|
|||
|
#include "ferror_code.h"
|
|||
|
|
|||
|
#include "fdebug.h"
|
|||
|
#define FNAND_INTR_DEBUG_TAG "FNAND_INTR"
|
|||
|
#define FNAND_INTR_ERROR(format, ...) FT_DEBUG_PRINT_E(FNAND_INTR_DEBUG_TAG, format, ##__VA_ARGS__)
|
|||
|
#define FNAND_INTR_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FNAND_INTR_DEBUG_TAG, format, ##__VA_ARGS__)
|
|||
|
#define FNAND_INTR_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FNAND_INTR_DEBUG_TAG, format, ##__VA_ARGS__)
|
|||
|
#define FNAND_INTR_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FNAND_INTR_DEBUG_TAG, format, ##__VA_ARGS__)
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FNandIsrEnable
|
|||
|
* @msg: Enable the corresponding interrupt based on the interrupt mask
|
|||
|
* @return {*}
|
|||
|
* @note:
|
|||
|
* @param {FNand} *instance_p is the pointer to the FNand instance
|
|||
|
* @param {u32} int_mask is interrupt mask
|
|||
|
*/
|
|||
|
void FNandIsrEnable(FNand *instance_p, u32 int_mask)
|
|||
|
{
|
|||
|
u32 reg_value;
|
|||
|
FASSERT(instance_p != NULL);
|
|||
|
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
|||
|
FNandConfig *config_p;
|
|||
|
config_p = &instance_p->config;
|
|||
|
|
|||
|
FNAND_CLEARBIT(config_p->base_address, FNAND_INTRMASK_OFFSET, int_mask);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FNandIrqDisable
|
|||
|
* @msg: Disable the corresponding interrupt based on the interrupt mask
|
|||
|
* @note:
|
|||
|
* @param {FNand} *instance_p is the pointer to the FNand instance
|
|||
|
* @param {u32} int_mask is interrupt mask
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
void FNandIrqDisable(FNand *instance_p, u32 int_mask)
|
|||
|
{
|
|||
|
u32 reg_value;
|
|||
|
FASSERT(instance_p != NULL);
|
|||
|
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
|||
|
FNandConfig *config_p;
|
|||
|
config_p = &instance_p->config;
|
|||
|
|
|||
|
FNAND_SETBIT(config_p->base_address, FNAND_INTRMASK_OFFSET, int_mask);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FNandSetIsrHandler
|
|||
|
* @msg: Initializes isr event callback function
|
|||
|
* @note:
|
|||
|
* @param {FNand} *instance_p is the pointer to the FNand instance.
|
|||
|
* @param {FnandIrqEventHandler} event_p is callback function used to respond to the interrupt event
|
|||
|
* @param {void} *irq_args is the arguments of event callback
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
void FNandSetIsrHandler(FNand *instance_p, FnandIrqEventHandler event_p, void *irq_args)
|
|||
|
{
|
|||
|
FASSERT(instance_p != NULL);
|
|||
|
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
|||
|
instance_p->irq_event_fun_p = event_p;
|
|||
|
instance_p->irq_args = irq_args;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FNandIrqHandler
|
|||
|
* @msg: Nand driver isr handler
|
|||
|
* @note:
|
|||
|
* @param {s32} vector is interrupt number
|
|||
|
* @param {void} *param is argument
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
void FNandIrqHandler(s32 vector, void *param)
|
|||
|
{
|
|||
|
FNand *instance_p = (FNand *)param;
|
|||
|
FNandConfig *config_p;
|
|||
|
u32 status;
|
|||
|
u32 en_irq;
|
|||
|
(void)vector;
|
|||
|
FASSERT(instance_p != NULL);
|
|||
|
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
|||
|
config_p = &instance_p->config;
|
|||
|
|
|||
|
status = FNAND_READREG(config_p->base_address, FNAND_INTR_OFFSET);
|
|||
|
en_irq = (~FNAND_READREG(config_p->base_address, FNAND_INTRMASK_OFFSET)) & FNAND_INTRMASK_ALL_INT_MASK;
|
|||
|
|
|||
|
if ((status & en_irq) == 0)
|
|||
|
{
|
|||
|
FNAND_INTR_DEBUG_E("No irq exit");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
FNandIrqDisable(instance_p, status & FNAND_INTRMASK_ALL_INT_MASK);
|
|||
|
FNAND_WRITEREG(config_p->base_address, 0xfd0, 0);
|
|||
|
FNAND_WRITEREG(config_p->base_address, FNAND_INTR_OFFSET, status);
|
|||
|
|
|||
|
if (instance_p->irq_event_fun_p)
|
|||
|
{
|
|||
|
if (status & FNAND_INTR_BUSY_MASK)
|
|||
|
{
|
|||
|
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_BUSY_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_DMA_BUSY_MASK)
|
|||
|
{
|
|||
|
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_DMA_BUSY_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_DMA_PGFINISH_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_DMA_PGFINISH_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_DMA_FINISH_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_DMA_FINISH_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_FIFO_EMP_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_FIFO_EMP_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_FIFO_FULL_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_FIFO_FULL_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_FIFO_TIMEOUT_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_FIFO_TIMEOUT_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_CMD_FINISH_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_CMD_FINISH_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_PGFINISH_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_PGFINISH_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_RE_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_RE_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_DQS_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_DQS_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_RB_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_RB_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_ECC_FINISH_MASK)
|
|||
|
{
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_ECC_FINISH_EVENT);
|
|||
|
}
|
|||
|
|
|||
|
if (status & FNAND_INTR_ECC_ERR_MASK)
|
|||
|
{
|
|||
|
FNAND_WRITEREG(config_p->base_address, FNAND_ERROR_CLEAR_OFFSET, FNAND_ERROR_CLEAR_ECC_ERR_CLR_MASK);
|
|||
|
FNAND_WRITEREG(config_p->base_address, FNAND_FIFO_FREE_OFFSET, FNAND_FIFO_FREE_MASK);
|
|||
|
instance_p->irq_event_fun_p(instance_p->irq_args, FNAND_IRQ_ECC_ERR_EVENT);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|