📄 sdhc_s3c6400.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <s3c6400.h>
#include <DrvLib.h>
#include "SDHC_s3c6400.h"
// 2007.07.21 By D.Baek
// To support the "Sleep/Wakeup" function
extern DWORD g_initialInsertion;
#include <cebuscfg.h>
#define SRCCLK_48MHZ // from USB PHY (Keep sync with "sdhcslot.cpp")
BOOL CSDHController::Init(
LPCTSTR pszActiveKey
)
{
S3C6400_SYSCON_REG *pCLKPWR = NULL;
S3C6400_HSMMC_REG *pHSMMC = NULL;
S3C6400_GPIO_REG *pIOPreg = NULL;
RETAILMSG(0,(TEXT("CSDHController::Init\r\n")));
g_initialInsertion = 1;
//GPIO Setting
//----- 1. Map the GPIO registers needed to enable the SDI controller -----
pIOPreg = (S3C6400_GPIO_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_GPIO, sizeof(S3C6400_GPIO_REG), FALSE);
if (pIOPreg == NULL)
{
RETAILMSG (1,(TEXT("GPIO registers not mapped\r\n")));
return FALSE;
}
pCLKPWR = (S3C6400_SYSCON_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_SYSCON, sizeof(S3C6400_SYSCON_REG), FALSE);
if (pCLKPWR == NULL)
{
RETAILMSG (1,(TEXT("SysCon registers not mapped\r\n")));
return FALSE;
}
pHSMMC = (S3C6400_HSMMC_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_HSMMC1, sizeof(S3C6400_HSMMC_REG), FALSE);
if (pHSMMC == NULL)
{
RETAILMSG (1,(TEXT("HSMMC registers not mapped\r\n")));
return FALSE;
}
// For HSMMC0 -> GPGCON
//pIOPreg->GPGCON &=~(0xFFFFFF); // GPGCON[23:0]
//pIOPreg->GPGCON |= (0x222222); // 4'b0010 for the MMC 0
// For HSMMC1 -> GPGCON
pIOPreg->GPHCON0 &=~(0xFFFFFFFF); // GPHCON0[31:0]
pIOPreg->GPHCON0 |= (0x22222222); // 4'b0010 for the MMC 1
pIOPreg->GPHCON1 &=~(0xFF); // GPHCON0[31:0]
pIOPreg->GPHCON1 |= (0x22); // 4'b0010 for the MMC 1
pIOPreg->GPHPUD &= ~(0xFFFFF); // Pull-up/down disabled
// There is no GPIO port for setting the WP (Write Protection), SD0_LED except SD0_CD (Card Detection) in the S3C6400 GPIO
//For MMC CD0 (Card Detection)
//pIOPreg->GPGCON &=~(0xF<<24);
//pIOPreg->GPGCON |= (0x2<<24);
//pIOPreg->GPGPUD &= ~(0x3FFF);
// For MMC CD1 (Card Detection)
pIOPreg->GPGCON &=~(0xF<<24);
pIOPreg->GPGCON |= (0x3<<24);
pIOPreg->GPGPUD &= ~(0x3<<12);
RETAILMSG(0,(TEXT("pHSMMC->CONTROL2 = 0x%X\n"),pHSMMC->CONTROL2));
// Set the division value for CLKMMC0 to 1
//pCLKPWR->CLK_DIV1 &= ~(0xF<<0);
//pCLKPWR->CLK_DIV1 |= (0x1<<0);
// Set the division value for CLKMMC1 to 1
//pCLKPWR->CLK_DIV1 &= ~(0xF<<4);
//pCLKPWR->CLK_DIV1 |= (0x1<<4);
// Set the clock source to EPLL out for CLKMMC0
//pCLKPWR->CLK_SRC &= ~(0x1<<2);
//pCLKPWR->CLK_SRC |= (0x1<<2);
//pCLKPWR->CLK_SRC &= ~(0x3<<18);
#ifdef SRCCLK_48MHZ
// To use the USB clock, must be set the "USB_SIG_MASK" bit in the syscon register.
pCLKPWR->OTHERS |= (0x1<<16);
pCLKPWR->HCLK_GATE |= (0x1<<18);
pCLKPWR->SCLK_GATE |=(0x1<<28);
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x3<<9)|(0x1<<8)|(0x3/*USB_PHY*/<<4);
#else
// Set the clock source to EPLL out for CLKMMC1
pCLKPWR->CLK_SRC &= ~(0x1<<2);
pCLKPWR->CLK_SRC |= (0x1<<2);
pCLKPWR->CLK_SRC &= ~(0x3<<20);
pCLKPWR->HCLK_GATE |= (0x1<<18);
pCLKPWR->SCLK_GATE &= ~(0x3F<<24);
pCLKPWR->SCLK_GATE |= (0x1<<25);
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x3<<9)|(0x1<<8)|(0x2/*EPLL*/<<4);
#endif
#if 0
pHSMMC->CONTROL3 = (0x1<<31) | (0x1<<23) | (0x0<<15) | (0x0<<7);
#endif
// HCLK_GATE[17] = HCLK_HSMMC0
// HCLK_GATE[18] = HCLK_HSMMC1
// HCLK_GATE[19] = HCLK_HSMMC2
//pCLKPWR->HCLK_GATE |= (0x1<<17);
// SCLKCON[24] = HSMMC0
// SCLKCON[25] = HSMMC1
// SCLKCON[26] = HSMMC2
//For HSMMC0
//pCLKPWR->SCLK_GATE &= ~(0x3F<<24);
//pCLKPWR->SCLK_GATE |= (0x1<<24);
//For HSMMC1
DrvLib_UnmapIoSpace((PVOID)pIOPreg);
DrvLib_UnmapIoSpace((PVOID)pCLKPWR);
DrvLib_UnmapIoSpace((PVOID)pHSMMC);
RETAILMSG(1,(TEXT("[HSMMC] Init()\r\n")));
return CSDHCBase::Init(pszActiveKey);
}
void
CSDHController::PowerUp()
{
S3C6400_SYSCON_REG *pCLKPWR;
S3C6400_HSMMC_REG *pHSMMC;
S3C6400_GPIO_REG *pIOPreg;
RETAILMSG(0,(TEXT("CSDHController::Init\r\n")));
g_initialInsertion = 1;
pIOPreg = (S3C6400_GPIO_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_GPIO, sizeof(S3C6400_GPIO_REG), FALSE);
if (pIOPreg == NULL)
{
RETAILMSG (1,(TEXT("GPIO registers not mapped\r\n")));
//return FALSE;
}
pCLKPWR = (S3C6400_SYSCON_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_SYSCON, sizeof(S3C6400_SYSCON_REG), FALSE);
if (pCLKPWR == NULL)
{
RETAILMSG (1,(TEXT("SysCon registers not mapped\r\n")));
//return FALSE;
}
pHSMMC = (S3C6400_HSMMC_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_HSMMC1, sizeof(S3C6400_HSMMC_REG), FALSE);
if (pHSMMC == NULL)
{
RETAILMSG (1,(TEXT("HSMMC registers not mapped\r\n")));
//return FALSE;
}
// For HSMMC0 -> GPGCON
//pIOPreg->GPGCON &=~(0xFFFFFF); // GPGCON[23:0]
//pIOPreg->GPGCON |= (0x222222); // 4'b0010 for the MMC 0
// For HSMMC1 -> GPGCON
pIOPreg->GPHCON0 &=~(0xFFFFFFFF); // GPHCON0[31:0]
pIOPreg->GPHCON0 |= (0x22222222); // 4'b0010 for the MMC 1
pIOPreg->GPHCON1 &=~(0xFF); // GPHCON0[31:0]
pIOPreg->GPHCON1 |= (0x22); // 4'b0010 for the MMC 1
pIOPreg->GPHPUD &= ~(0xFFFFF); // Pull-up/down disabled
// There is no GPIO port for setting the WP (Write Protection), SD0_LED except SD0_CD (Card Detection) in the S3C6400 GPIO
//For MMC CD0 (Card Detection)
//pIOPreg->GPGCON &=~(0xF<<24);
//pIOPreg->GPGCON |= (0x2<<24);
//pIOPreg->GPGPUD &= ~(0x3FFF);
// For MMC CD1 (Card Detection)
pIOPreg->GPGCON &=~(0xF<<24);
pIOPreg->GPGCON |= (0x3<<24);
pIOPreg->GPGPUD &= ~(0x3<<12);
#ifdef SRCCLK_48MHZ
// To use the USB clock, must be set the "USB_SIG_MASK" bit in the syscon register.
pCLKPWR->OTHERS |= (0x1<<16);
pCLKPWR->HCLK_GATE |= (0x1<<18);
pCLKPWR->SCLK_GATE |=(0x1<<28);
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) |(0x3<<9)|(0x1<<8)|(0x3/*USB_PHY*/<<4);
#else
// Set the clock source to EPLL out for CLKMMC1
pCLKPWR->CLK_SRC &= ~(0x1<<2);
pCLKPWR->CLK_SRC |= (0x1<<2);
pCLKPWR->CLK_SRC &= ~(0x3<<20);
pCLKPWR->HCLK_GATE |= (0x1<<18);
pCLKPWR->SCLK_GATE &= ~(0x3F<<24);
pCLKPWR->SCLK_GATE |= (0x1<<25);
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) |(0x3<<9)|(0x1<<8)|(0x2/*EPLL*/<<4);
#endif
#if 0
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x0<<15)|(0x0<<14)|(0x3<<9)|(0x1<<8)|(0x2/*EPLL*/<<4);
#endif
//pHSMMC->CONTROL3 = (0x1<<31) | (0x1<<23) | (0x0<<15) | (0x0<<7);
RETAILMSG(0,(TEXT("pHSMMC->CONTROL2 = 0x%X\n"),pHSMMC->CONTROL2));
// Set the division value for CLKMMC0 to 1
//pCLKPWR->CLK_DIV1 &= ~(0xF<<0);
//pCLKPWR->CLK_DIV1 |= (0x1<<0);
// Set the division value for CLKMMC1 to 1
//pCLKPWR->CLK_DIV1 &= ~(0xF<<4);
//pCLKPWR->CLK_DIV1 |= (0x1<<4);
// Set the clock source to EPLL out for CLKMMC0
//pCLKPWR->CLK_SRC &= ~(0x1<<2);
//pCLKPWR->CLK_SRC |= (0x1<<2);
//pCLKPWR->CLK_SRC &= ~(0x3<<18);
// HCLK_GATE[17] = HCLK_HSMMC0
// HCLK_GATE[18] = HCLK_HSMMC1
// HCLK_GATE[19] = HCLK_HSMMC2
//pCLKPWR->HCLK_GATE |= (0x1<<17);
// SCLKCON[24] = HSMMC0
// SCLKCON[25] = HSMMC1
// SCLKCON[26] = HSMMC2
//For HSMMC0
//pCLKPWR->SCLK_GATE &= ~(0x3F<<24);
//pCLKPWR->SCLK_GATE |= (0x1<<24);
//For HSMMC1
DrvLib_UnmapIoSpace((PVOID)pIOPreg);
DrvLib_UnmapIoSpace((PVOID)pCLKPWR);
DrvLib_UnmapIoSpace((PVOID)pHSMMC);
RETAILMSG(1,(TEXT("[HSMMC] PowerUp()\r\n")));
CSDHCBase::PowerUp();
}
extern "C"
PCSDHCBase
CreateHSMMCHCObject(
)
{
return new CSDHController;
}
VOID
CSDHController::DestroyHSMMCHCObject(
PCSDHCBase pSDHC
)
{
DEBUGCHK(pSDHC);
delete pSDHC;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -