⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core_sgpio.c

📁 6440linuxDriver的源代码
💻 C
字号:
#include "core_header.h"#include "Spi_hal.h"#include "core_init.h"#ifdef SUPPORT_SGPIO#include "core_exp.h"#include "core_inter.h"#include "core_sgpio.h"#ifdef SUPPORT_ERROR_HANDLINGextern void Core_ReqTimeout (MV_PVOID This, MV_PVOID temp);#endifMV_U32 SGPIO_ReadRegister(PCore_Driver_Extension pCore, MV_U8 regAddress) {	MV_U32 reg;	reg=0;		reg = MV_PCI_READ_DWORD( pCore, regAddress );   	return reg;}void SGPIO_WriteRegister(PCore_Driver_Extension pCore, MV_U8 regAddress, MV_U32 regValue) {	MV_PCI_WRITE_DWORD( pCore, regValue, regAddress );    return;}/** Known Hardware issues for the SGPIO on Odin:* 1. The clock frequency by default is 1 KHz.  Changing clock frequency to 100KHz *    (SGPIO spec uses 100KHz) could cause a phase shift that result in data being written on *    the falling edge instead of rising edge.  *    Possible solution: Write to register of target multiple times until the desired data is*    correctly written into the register.* 2. The SGPIO pins stated on the spec could be wrong.  The following is the correct pin layout.*/voidSGPIO_SendSGPIOFrame(MV_PVOID This, MV_U32 value){	PCore_Driver_Extension pCore=(PCore_Driver_Extension)This;	MV_U32 SGPIO_CtlReg;	MV_U32 SGPIO_DataOut_L;	MV_U32 SGPIO_DataOut_H;	SGPIO_CtlReg = SGPIO_ReadRegister( pCore, SGPIO_Control );	MV_PRINT("*  SGPIO_CtlReg before (start) = 0x%x \n", SGPIO_CtlReg );	SGPIO_DataOut_L = SGPIO_ReadRegister( pCore, SGPIO_Data_Out_L );	SGPIO_DataOut_H = SGPIO_ReadRegister( pCore, SGPIO_Data_Out_H );	MV_PRINT("SGPIO_DataOut_L before write (start) = 0x%x \n", SGPIO_DataOut_L );	MV_PRINT("SGPIO_DataOut_H before write (start) = 0x%x \n", SGPIO_DataOut_H );	SGPIO_WriteRegister( pCore, SGPIO_Data_Out_L, value);	SGPIO_WriteRegister( pCore, SGPIO_Data_Out_H, 0x0);	SGPIO_DataOut_L = SGPIO_ReadRegister( pCore, SGPIO_Data_Out_L );	SGPIO_DataOut_H = SGPIO_ReadRegister( pCore, SGPIO_Data_Out_H );	MV_PRINT("SGPIO_DataOut_L after write (start) = 0x%x \n", SGPIO_DataOut_L );	MV_PRINT("SGPIO_DataOut_H after write (start) = 0x%x \n", SGPIO_DataOut_H );	// Setup the desired SGPIO_Control register value	SGPIO_CtlReg |= SGPIO_TRANSFER_LEN(64)|SGPIO_START_BIT;	MV_PRINT("*  1 SGPIO_CtlReg going to be written into register (start) = 0x%x \n", SGPIO_CtlReg );	// Write to SGPIO_Control register and start data transfer	SGPIO_WriteRegister( pCore, SGPIO_Control, SGPIO_CtlReg);	SGPIO_CtlReg = SGPIO_ReadRegister( pCore, SGPIO_Control );	MV_PRINT("*  SGPIO_CtlReg what is in the register now (start) = 0x%x \n", SGPIO_CtlReg );}voidSGPIO_StopSGPIOFrame(MV_PVOID This, MV_U32 value){	PCore_Driver_Extension pCore=(PCore_Driver_Extension)This;	MV_U32 SGPIO_CtlReg;	MV_PRINT(" \n");	SGPIO_CtlReg = SGPIO_ReadRegister( pCore, SGPIO_Control );	MV_PRINT("*  SGPIO_CtlReg first (stop) = 0x%x \n", SGPIO_CtlReg );	SGPIO_WriteRegister( pCore, SGPIO_Data_Out_L, value);	SGPIO_WriteRegister( pCore, SGPIO_Data_Out_H, value);	SGPIO_CtlReg &= ~SGPIO_START_BIT;	MV_PRINT("*  SGPIO_CtlReg middle (stop) = 0x%x \n", SGPIO_CtlReg );	SGPIO_WriteRegister( pCore, SGPIO_Control, SGPIO_CtlReg);	SGPIO_CtlReg = SGPIO_ReadRegister( pCore, SGPIO_Control );	MV_PRINT("*  SGPIO_CtlReg last (stop) = 0x%x \n", SGPIO_CtlReg );}	 void SGPIO_Initialize( MV_PVOID This ) {	PCore_Driver_Extension pCore=(PCore_Driver_Extension)This;	MV_U32 SGPIO_InitReg=0;  	MV_U32 SGPIO_CtlReg=0;	SGPIO_InitReg = SGPIO_ReadRegister( pCore, SGPIO_Init );	MV_PRINT("*  SGPIO_InitReg before initialization = 0x%x \n", SGPIO_InitReg );	// Set mode to SGPIO mode	SGPIO_InitReg |= SGPIO_Mode;		// The following lines setup the desired clock frequency in SGPIO_Control register 	// before clk is started by SGPIO_Init.  Allowing clk to switch frequency during run-time	// could result in writing on the wrong edge of the clk.	SGPIO_CtlReg |= SGPIO_SELECT_SPEED(SGPIO_100KHz);	MV_PRINT("*  0 SGPIO_CtlReg going to be written into register (start) = 0x%x \n", SGPIO_CtlReg );	SGPIO_WriteRegister( pCore, SGPIO_Control, SGPIO_CtlReg );	// Clock starts once SGPIO mode is set and written to register.	SGPIO_WriteRegister( pCore, SGPIO_Init, SGPIO_InitReg );	SGPIO_InitReg = SGPIO_ReadRegister( pCore, SGPIO_Init );	MV_PRINT("*  SGPIO_InitReg after initialization = 0x%x \n", SGPIO_InitReg );}/* used to send out test signals of the SGPIO. Currently capable of sending data through DataOut */void SGPIOtest(MV_PVOID This){	PCore_Driver_Extension pCore=(PCore_Driver_Extension)This;	SGPIO_Initialize( pCore );	SGPIO_SendSGPIOFrame(This,0x249);	DelayMSec(5000);	SGPIO_StopSGPIOFrame(This,0);}void SGPIO_SMPReq_Callback(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq    ){	MV_U8 portId, TgtId;	struct _Domain_Expander *pTgt;	struct SMPResponse *pSMPResp;	PDomain_Port pPort;	PDomain_SGPIO SGPIO_Result = &pCore->SGPIO_Result;	portId = MapTgtPortId(pCore, pReq->Device_Id);	pPort = &pCore->Ports[MapPortEntry(pCore,portId)];		pSMPResp= (struct SMPResponse *)pReq->Scratch_Buffer;	/*TgtId = (MV_U8)pReq->Device_Id;	pTgt= &pCore->Expanders[MapTgtId(pCore, pReq->Device_Id)];	pSMPResp= (struct SMPResponse *)pReq->Data_Buffer;	MV_PRINT("SMP Function 0x%x Done For Port[0x%x].Target[0x%x] "		 "Result 0x%x\n", 		 pSMPResp->Function, 		 portId, 		 TgtId,		 pSMPResp->FunctionResult);*/	switch(pSMPResp->Function)	{		case READ_GPIO_REGISTER:			MV_PRINT("Read GPIO Register Response: \n");			MV_PRINT("Data In High 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", 				pSMPResp->Response.ReadGPIORegister.Data_In_High[0],				pSMPResp->Response.ReadGPIORegister.Data_In_High[1],				pSMPResp->Response.ReadGPIORegister.Data_In_High[2],				pSMPResp->Response.ReadGPIORegister.Data_In_High[3],				pSMPResp->Response.ReadGPIORegister.Data_In_High[4],				pSMPResp->Response.ReadGPIORegister.Data_In_High[5],				pSMPResp->Response.ReadGPIORegister.Data_In_High[6],				pSMPResp->Response.ReadGPIORegister.Data_In_High[7]);			MV_PRINT("Data In Low 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", 				pSMPResp->Response.ReadGPIORegister.Data_In_Low[0],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[1],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[2],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[3],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[4],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[5],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[6],				pSMPResp->Response.ReadGPIORegister.Data_In_Low[7]);		break;		case WRITE_GPIO_REGISTER:			MV_PRINT("Receive Write GPIO Register Response: \n");		break;	}	MV_CopyMemory(SGPIO_Result, pReq->Scratch_Buffer, sizeof(pReq->Scratch_Buffer) );	if( pReq->Scratch_Buffer )	FreeSMPScratchToPool( pCore, (PSMP_Scratch_Buffer)pReq->Scratch_Buffer );	FreeInternalReqToPool( pCore, pReq );}void SGPIO_SMPRequest_Read(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq	){	PSMP_Scratch_Buffer pSMPSB;	struct SMPRequest *pSMPReq;	PMV_SG_Table pSGTable;	if( pReq == NULL ) 	{		MV_DPRINT(("ERROR: No more free internal requests. Request aborted.\n"));		return;	}	pSMPSB = GetSMPScratchFromPool(pCore);	if( pSMPSB == NULL )	{		MV_DPRINT(("ERROR: No more free SMP scratch buffer. Request aborted.\n"));		return;	}	pSGTable = &pReq->SG_Table;	/* Prepare identify ATA task */	pReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;	pReq->Cdb[1] = CDB_CORE_MODULE;	pReq->Cdb[2] = CDB_CORE_SMP;	pReq->Tag = 0xbb;	pReq->Device_Id = 0xFFFF; // Indicating SGPIO operation	//pReq->Req_Flag;	pReq->Cmd_Initiator = pCore;	pReq->Data_Transfer_Length = sizeof(struct SMPRequest);	pReq->Data_Buffer = &pSMPSB->SMP_Req;	pReq->Scratch_Buffer = pSMPSB;	pSMPReq=(struct SMPRequest *)pReq->Data_Buffer;	pSMPReq->Function=READ_GPIO_REGISTER;	pSMPReq->SMPFrameType=SMP_REQUEST_FRAME;	pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SGPIO_SMPReq_Callback;	/* Make SG table */	SGTable_Init(pSGTable, 0);	/* Send this internal request */	Core_ModuleSendRequest(pCore, pReq);}void SGPIO_SMPRequest_Write(	IN PCore_Driver_Extension pCore	){	PMV_Request pReq = GetInternalReqFromPool(pCore);	PSMP_Scratch_Buffer pSMPSB;	struct SMPRequest *pSMPReq;	PMV_SG_Table pSGTable;	if( pReq == NULL ) 	{		MV_DPRINT(("ERROR: No more free internal requests. Request aborted.\n"));		return;	}	pSMPSB = GetSMPScratchFromPool(pCore);	if( pSMPSB == NULL )	{		MV_DPRINT(("ERROR: No more free SMP scratch buffer. Request aborted.\n"));		return;	}	pSGTable = &pReq->SG_Table;	/* Prepare identify ATA task */	pReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;	pReq->Cdb[1] = CDB_CORE_MODULE;	pReq->Cdb[2] = CDB_CORE_SMP;	pReq->Tag = 0xbb;	pReq->Device_Id = 0xFFFF; // Indicating SGPIO operation	//pReq->Req_Flag;	pReq->Cmd_Initiator = pCore;	pReq->Data_Transfer_Length = sizeof(struct SMPRequest);	pReq->Data_Buffer = &pSMPSB->SMP_Req;	pReq->Scratch_Buffer = pSMPSB;	pSMPReq=(struct SMPRequest *)pReq->Data_Buffer;	pSMPReq->Function=WRITE_GPIO_REGISTER;	pSMPReq->SMPFrameType=SMP_REQUEST_FRAME;	pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SGPIO_SMPReq_Callback;	/* Make SG table */	SGTable_Init(pSGTable, 0);	/* Send this internal request */	Core_ModuleSendRequest(pCore, pReq);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -