224 lines
7.0 KiB
C
224 lines
7.0 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: fsata_intr.c
|
||
* Date: 2022-02-10 14:55:11
|
||
* LastEditTime: 2022-02-18 09:03:57
|
||
* Description: This files is for intrrupt function of Sata ctrl
|
||
*
|
||
* Modify History:
|
||
* Ver Who Date Changes
|
||
* ----- ------ -------- --------------------------------------
|
||
*/
|
||
|
||
#include "fassert.h"
|
||
#include "fdebug.h"
|
||
#include "fsata.h"
|
||
#include "fsata_hw.h"
|
||
#include "finterrupt.h"
|
||
|
||
/************************** Constant Definitions *****************************/
|
||
|
||
/**************************** Type Definitions *******************************/
|
||
|
||
/***************** Macros (Inline Functions) Definitions *********************/
|
||
|
||
/************************** Function Prototypes ******************************/
|
||
|
||
/************************** Variable Definitions *****************************/
|
||
|
||
#define FSATA_DEBUG_TAG "FSATA_INTR"
|
||
#define FSATA_ERROR(format, ...) FT_DEBUG_PRINT_E(FSATA_DEBUG_TAG, format, ##__VA_ARGS__)
|
||
#define FSATA_WARN(format, ...) FT_DEBUG_PRINT_W(FSATA_DEBUG_TAG, format, ##__VA_ARGS__)
|
||
#define FSATA_INFO(format, ...) FT_DEBUG_PRINT_I(FSATA_DEBUG_TAG, format, ##__VA_ARGS__)
|
||
#define FSATA_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSATA_DEBUG_TAG, format, ##__VA_ARGS__)
|
||
|
||
/**
|
||
* @name: FSataIrqEnable
|
||
* @msg: enable sata interrupt mask
|
||
* @param {FSataCtrl} *instance_p, pointer to the FSataCtrl instance
|
||
* @param {u32} int_mask, interrupt enable mask
|
||
* @return {void}
|
||
*/
|
||
void FSataIrqEnable(FSataCtrl *instance_p, u32 int_mask)
|
||
{
|
||
u32 reg_value;
|
||
FASSERT(instance_p != NULL);
|
||
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
||
u32 port = instance_p->private_data;
|
||
u32 i;
|
||
for (i = 0; i < instance_p->n_ports; i++)
|
||
{
|
||
if (!(port & BIT(i)))
|
||
continue;
|
||
|
||
uintptr port_base_addr = instance_p->port[i].port_base_addr;
|
||
FSATA_SETBIT(port_base_addr, FSATA_PORT_IRQ_MASK, int_mask);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @name: FSataIrqDisable
|
||
* @msg: disable sata interrupt mask
|
||
* @param {FSataCtrl} *instance_p, pointer to the FSataCtrl instance
|
||
* @param {u32} int_mask, interrupt disable mask
|
||
* @return {void}
|
||
*/
|
||
void FSataIrqDisable(FSataCtrl *instance_p, u32 int_mask)
|
||
{
|
||
u32 reg_value;
|
||
FASSERT(instance_p != NULL);
|
||
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
||
u32 port = instance_p->private_data;
|
||
u32 i;
|
||
for (i = 0; i < instance_p->n_ports; i++)
|
||
{
|
||
if (!(port & BIT(i)))
|
||
continue;
|
||
|
||
uintptr port_base_addr = instance_p->port[i].port_base_addr;
|
||
|
||
FSATA_CLEARBIT(port_base_addr, FSATA_PORT_IRQ_MASK, int_mask);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @name: FSataSetHandler
|
||
* @msg: set sata interrupt handler function
|
||
* @param {FSataCtrl} *instance_p, pointer to the FSataCtrl instance
|
||
* @param {u32} irq_type, interrupt type
|
||
* @param {void} *func_pointer, interrupt handler function
|
||
* @param {void} *call_back_ref, interrupt handler function argument
|
||
* @return {FError} return FSATA_SUCCESS if successful, return others if failed
|
||
*/
|
||
FError FSataSetHandler(FSataCtrl *instance_p, u32 irq_type, void *func_pointer, void *call_back_ref)
|
||
{
|
||
FError status = FT_SUCCESS;
|
||
FASSERT(instance_p != NULL);
|
||
FASSERT(func_pointer != NULL);
|
||
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
||
|
||
switch (irq_type)
|
||
{
|
||
case FSATA_PORT_IRQ_D2H_REG_FIS:
|
||
instance_p->fsata_dhrs_cb = ((FSataIrqCallBack)(void *)func_pointer);
|
||
instance_p->dhrs_args = call_back_ref;
|
||
break;
|
||
|
||
case FSATA_PORT_IRQ_SDB_FIS:
|
||
instance_p->fsata_sdbs_cb = ((FSataIrqCallBack)(void *)func_pointer);
|
||
instance_p->sdbs_args = call_back_ref;
|
||
break;
|
||
|
||
case FSATA_PORT_IRQ_CONNECT:
|
||
instance_p->fsata_pcs_cb = ((FSataIrqCallBack)(void *)func_pointer);
|
||
instance_p->pcs_args = call_back_ref;
|
||
break;
|
||
|
||
case FSATA_PORT_IRQ_PIOS_FIS:
|
||
instance_p->fsata_pss_cb = ((FSataIrqCallBack)(void *)func_pointer);
|
||
instance_p->pss_args = call_back_ref;
|
||
break;
|
||
|
||
default:
|
||
status = (FSATA_ERR_OPERATION);
|
||
break;
|
||
}
|
||
return status;
|
||
}
|
||
|
||
/**
|
||
* @name: FSataIrqHandler
|
||
* @msg: sata interrupt handler entry
|
||
* @param {void} *param, function parameters, users can set
|
||
* @return {void}
|
||
*/
|
||
void FSataIrqHandler(s32 vector, void *param)
|
||
{
|
||
FSataCtrl *instance_p = (FSataCtrl *)param;
|
||
FSataConfig *config_p;
|
||
|
||
FASSERT(instance_p != NULL);
|
||
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
|
||
u32 port = instance_p->private_data;
|
||
u32 status;
|
||
u32 mask_status = 0;
|
||
uintptr base_addr = instance_p->config.base_addr;
|
||
u32 irq_state = 0;
|
||
u32 i = 0;
|
||
|
||
uintptr port_base_addr = 0;
|
||
|
||
for (i = 0; i < instance_p->n_ports; i++)
|
||
{
|
||
if (!(port & BIT(i)))
|
||
continue;
|
||
|
||
port_base_addr = instance_p->port[i].port_base_addr;
|
||
irq_state = FSATA_READ_REG32(base_addr, FSATA_HOST_IRQ_STAT);
|
||
status = FSATA_READ_REG32(port_base_addr, FSATA_PORT_IRQ_STAT);
|
||
mask_status = FSATA_READ_REG32(port_base_addr, FSATA_PORT_IRQ_MASK);
|
||
|
||
/* clear port first, host second */
|
||
FSATA_WRITE_REG32(port_base_addr, FSATA_PORT_IRQ_STAT, status);
|
||
FSATA_WRITE_REG32(base_addr, FSATA_HOST_IRQ_STAT, irq_state);
|
||
|
||
if (status & mask_status & FSATA_PORT_IRQ_D2H_REG_FIS)
|
||
{
|
||
if (instance_p->fsata_dhrs_cb)
|
||
{
|
||
instance_p->fsata_dhrs_cb(instance_p->dhrs_args);
|
||
}
|
||
}
|
||
|
||
if (status & mask_status & FSATA_PORT_IRQ_PIOS_FIS)
|
||
{
|
||
if (instance_p->fsata_pss_cb)
|
||
{
|
||
instance_p->fsata_pss_cb(instance_p->pss_args);
|
||
}
|
||
}
|
||
|
||
if (status & mask_status & FSATA_PORT_IRQ_SDB_FIS)
|
||
{
|
||
if (instance_p->fsata_sdbs_cb)
|
||
{
|
||
instance_p->fsata_sdbs_cb(instance_p->sdbs_args);
|
||
}
|
||
}
|
||
|
||
if (status & mask_status & FSATA_PORT_IRQ_DMAS_FIS)
|
||
{
|
||
if (instance_p->fsata_dss_cb)
|
||
{
|
||
instance_p->fsata_dss_cb(instance_p->dss_args);
|
||
}
|
||
}
|
||
|
||
if (status & mask_status & FSATA_PORT_IRQ_CONNECT)
|
||
{
|
||
if (instance_p->fsata_pcs_cb)
|
||
{
|
||
instance_p->fsata_pcs_cb(instance_p->pcs_args);
|
||
}
|
||
|
||
/* reset hba */
|
||
FSATA_WRITE_REG32(base_addr, FSATA_HOST_CTL, FSATA_HOST_RESET);
|
||
FSataAhciInit(instance_p);
|
||
FSataIrqEnable(instance_p, FSATA_PORT_IRQ_FREEZE);
|
||
}
|
||
|
||
}
|
||
}
|
||
|