📄 s3c2450_hsmmc.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 <s3c2450.h>
#include "s3c2450_hsmmc.h"
#include <bsp_cfg.h>
#include <cebuscfg.h>
//#define _SRCCLK_48MHZ_
#define _DBG_ 1
// 08.03.13 by KYS
// The variable that gets the Channel number; The number of hsmmc channels on SMDK2450 is originally 2(Ch0, Ch1).
// and, this driver source is a code for channel 1.
static const g_ChNumber = 1;
// 2007.07.21 By D.Baek
// To support the "Sleep/Wakeup" function
extern DWORD g_initialInsertion;
BOOL
CSDHController::Init(
LPCTSTR pszActiveKey
)
{
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] Initializing the HSMMC Host Controller\n"), g_ChNumber));
g_initialInsertion = 1;
// 08.03.13 by KYS
// HSMMC Ch1 initialization
if (!InitCh()) return FALSE;
return CSDHCBase::Init(pszActiveKey);
}
VOID
CSDHController::PowerUp()
{
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] Power Up the HSMMC Host Controller\n"), g_ChNumber));
g_initialInsertion = 1;
// 08.03.13 by KYS
// HSMMC Ch1 initialization for "WakeUp"
if (!InitCh()) return;
CSDHCBase::PowerUp();
}
extern "C"
PCSDHCBase
CreateHSMMCHCObject(
)
{
return new CSDHController;
}
VOID
CSDHController::DestroyHSMMCHCObject(
PCSDHCBase pSDHC
)
{
DEBUGCHK(pSDHC);
delete pSDHC;
}
BOOL CSDHController::InitClkPwr() {
volatile S3C2450_CLKPWR_REG *pCLKPWR = NULL;
pCLKPWR = (volatile S3C2450_CLKPWR_REG *)VirtualAlloc(0, sizeof(S3C2450_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pCLKPWR == NULL) {
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] Clock & Power Management Special Register is *NOT* allocated.\n"), g_ChNumber));
return FALSE;
}
if (!VirtualCopy((PVOID)pCLKPWR, (PVOID)(S3C2450_BASE_REG_PA_CLOCK_POWER >> 8),
sizeof(S3C2450_CLKPWR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] Clock & Power Management Special Register is *NOT* mapped.\n"), g_ChNumber));
return FALSE;
}
#if (BSP_TYPE == BSP_SMDK2443)
pCLKPWR->HCLKCON |= (0x1<<16);
pCLKPWR->SCLKCON |= (0x1<<13);
pCLKPWR->SCLKCON |= (0x1<<12);
if (fSuccess) {
// enable it
WriteWord(SDHC_CLOCK_CONTROL, m_wRegClockControl | CLOCK_ENABLE);
fSuccess = WaitForReg<WORD>(ReadWord, SDHC_CLOCK_CONTROL, CLOCK_EXTERNAL_STABLE, CLOCK_EXTERNAL_STABLE); // KYS
}
else {
DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for CLOCK_STABLE\r\n"),
pszFname));
}
#elif (BSP_TYPE == BSP_SMDK2450)
#ifdef _SRCCLK_48MHZ_
RETAILMSG(_DBG_, (TEXT("[HSMMC%d] Setting registers for the USB48MHz (EXTCLK for SDCLK) : SYSCon.\n"), g_ChNumber));
pCLKPWR->CLKSRC |= (0x1<<17); // HSMMC1 clock: 0 = EPLL, 1 = USB 48MHz
pCLKPWR->HCLKCON |= (0x1<<16); // Enable HCLK into the HSMMC1
// pCLKPWR->SCLKCON |= (0x1<<13); // Enable HSMMC_EXT clock for HSMMC 0,1 (EXTCLK)
pCLKPWR->SCLKCON |= (0x1<<12); // Enable HSMMC_1 clock for (EPLL/USB48M)
#else
RETAILMSG(_DBG_, (TEXT("[HSMMC%d] Setting registers for the EPLL (for SDCLK) : SYSCon.\n"), g_ChNumber));
pCLKPWR->CLKSRC |= (0x0<<17); // HSMMC1 clock: 0 = EPLL, 1 = USB 48MHz
pCLKPWR->HCLKCON |= (0x1<<16); // Enable HCLK into the HSMMC1
pCLKPWR->SCLKCON |= (0x0<<13); // Disable HSMMC_EXT clock for HSMMC 0,1 (EXTCLK)
pCLKPWR->SCLKCON |= (0x1<<12); // Enable HSMMC_1 clock for (EPLL/USB48M)
#endif
#endif // !(BSP_TYPE == BSP_SMDK2443)
VirtualFree((PVOID) pCLKPWR, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitGPIO() {
volatile S3C2450_IOPORT_REG *pIOPreg = NULL;
pIOPreg = (volatile S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pIOPreg == NULL) {
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] GPIO registers is *NOT* allocated.\n"), g_ChNumber));
return FALSE;
}
if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),
sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] GPIO registers is *NOT* mapped.\n"), g_ChNumber));
return FALSE;
}
RETAILMSG(_DBG_, (TEXT("[HSMMC%d] Setting registers for the GPIO.\n"), g_ChNumber));
pIOPreg->GPLCON &= ~(0xFFFFF);
pIOPreg->GPLCON |= (0xAAAAA);
pIOPreg->GPJCON &= ~(0x3F << 26);
pIOPreg->GPJCON |= (0x2A << 26);
VirtualFree((PVOID) pIOPreg, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitHSMMC() {
volatile S3C2450_HSMMC_REG *pHSMMC = NULL;
pHSMMC = (volatile S3C2450_HSMMC_REG *)VirtualAlloc(0, sizeof(S3C2450_HSMMC_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pHSMMC == NULL)
{
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] HSMMC Special Register is *NOT* allocated.\n"), g_ChNumber));
return FALSE;
}
if (!VirtualCopy((PVOID)pHSMMC, (PVOID)(S3C2450_BASE_REG_PA_HSMMC >> 8),
sizeof(S3C2450_HSMMC_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC%d] HSMMC Special Register is *NOT* mapped.\n"), g_ChNumber));
return FALSE;
}
#if (BSP_TYPE == BSP_SMDK2443)
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x2/*EPLL*/<<4);
#elif (BSP_TYPE == BSP_SMDK2450)
#ifdef _SRCCLK_48MHZ_
RETAILMSG(_DBG_, (TEXT("[HSMMC%d] Setting registers for the USB48MHz(EXTCLK) : HSMMCCon.\n"), g_ChNumber));
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | // clear all
(0x1<<15) | // enable Feedback clock for Tx Data/Command Clock
(0x1<<14) | // enable Feedback clock for Rx Data/Command Clock
(0x3<<9) | // Debounce Filter Count 0x3=64 iSDCLK
(0x1<<8) | // SDCLK Hold Enable
(0x3<<4); // Base Clock Source = USB PHY 48MHz (from SYSCON block)
#else
RETAILMSG(_DBG_, (TEXT("[HSMMC%d] Setting registers for the EPLL : HSMMCCon.\n"), g_ChNumber));
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | // clear all
(0x1<<15) | // enable Feedback clock for Tx Data/Command Clock
(0x1<<14) | // enable Feedback clock for Rx Data/Command Clock
(0x3<<9) | // Debounce Filter Count 0x3=64 iSDCLK
(0x1<<8) | // SDCLK Hold Enable
(0x2<<4); // Base Clock Source = EPLL (from SYSCON block)
#endif
#endif // !(BSP_TYPE == BSP_SMDK2443)
pHSMMC->CONTROL3 = (0<<31) | (1<<23) | (0<<15) | (1<<7); // controlling the Feedback Clock
VirtualFree((PVOID) pHSMMC, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitCh() {
if (!InitClkPwr()) return FALSE;
if (!InitGPIO()) return FALSE;
if (!InitHSMMC()) return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -