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

📄 sdhc_s3c2450_ch1.cpp

📁 smdk2450 ce6 bsp,需要的朋友可以参考以下.
💻 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 "SDHC_s3c2450_ch1.h"

#include <cebuscfg.h>

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
#define _DBG_ 0
// 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;
#endif  // !(BSP_TYPE == BSP_SMDK2443)

BOOL 
CSDHController::Init(
    LPCTSTR pszActiveKey
    )
{
#if (BSP_TYPE == BSP_SMDK2443)
  S3C2450_CLKPWR_REG *pCLKPWR;
  S3C2450_HSMMC_REG *pHSMMC;
  S3C2450_IOPORT_REG *pIOPreg;

  RETAILMSG(0,(TEXT("CSDHController::Init\n")));

  //GPIO Setting
  //----- 1. Map the GPIO registers needed to enable the SDI controller -----
  pIOPreg = (S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pIOPreg == NULL) 
  {
    RETAILMSG (1,(TEXT("GPIO registers not allocated\r\n")));
    return FALSE;
  }
  if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("GPIO registers not mapped\r\n")));

    return FALSE;
  }

  pCLKPWR = (S3C2450_CLKPWR_REG *)VirtualAlloc(0, sizeof(S3C2450_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pCLKPWR == NULL) 
  {
    RETAILMSG (1,(TEXT("Clock & Power Management Special Register not allocated\n\r")));
    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 (1,(TEXT("Clock & Power Management Special Register not mapped\n\r")));
    return FALSE;
  }

  pHSMMC = (S3C2450_HSMMC_REG *)VirtualAlloc(0, sizeof(S3C2450_HSMMC_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pHSMMC == NULL) 
  {
    RETAILMSG (1,(TEXT("HSMMC Special Register not allocated\n\r")));
    return FALSE;
  }
  if (!VirtualCopy((PVOID)pHSMMC, (PVOID)(S3C2450_BASE_REG_PA_HSMMC >> 8), sizeof(S3C2450_HSMMC_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("HSMMC Special Register not mapped\n\r")));
    return FALSE;
  }	

  //	pIOPreg->GPFCON &= ~(0x3<<14);
  //	pIOPreg->GPFCON |= (0x1<<14);	

  pIOPreg->GPLCON &= ~(0xFFFFF);
  pIOPreg->GPLCON |= (0xAAAAA);
  //	pIOPreg->GPLUDP &= ~(0xFFFFF);
  //	pIOPreg->GPLUDP |= (0xAAAAA);

  pIOPreg->GPJCON &= ~(0x3F << 26);
  pIOPreg->GPJCON |= (0x2A << 26);

  //	pIOPreg->GPJUDP &= ~(0x3F << 26);
  //	pIOPreg->GPJUDP |= (0x2A << 26);

  pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x2/*EPLL*/<<4);
  pHSMMC->CONTROL3 = (0<<31) | (1<<23) | (0<<15) | (1<<7);
  RETAILMSG(0,(TEXT("pHSMMC->CONTROL2 = 0x%X\n"),pHSMMC->CONTROL2));
  pCLKPWR->HCLKCON |= (0x1<<16);
  pCLKPWR->SCLKCON |= (0x1<<13);	
  pCLKPWR->SCLKCON |= (0x1<<12);
  //	pCLKPWR->CLKDIV1 |= (0x3<<6);

  VirtualFree((PVOID) pIOPreg, 0, MEM_RELEASE);
  VirtualFree((PVOID) pCLKPWR, 0, MEM_RELEASE);
  VirtualFree((PVOID) pHSMMC, 0, MEM_RELEASE);

#elif (BSP_TYPE == BSP_SMDK2450)
  RETAILMSG(1, (TEXT("[HSMMC1] Initializing the HSMMC Host Controller\n")));
  g_initialInsertion = 1;
  // 08.03.13 by KYS
  // HSMMC Ch1 initialization
  if (!InitCh()) return FALSE;
#endif  // !(BSP_TYPE == BSP_SMDK2443)
  return CSDHCBase::Init(pszActiveKey);
}

  void
CSDHController::PowerUp()
{
#if (BSP_TYPE == BSP_SMDK2443)
  S3C2450_CLKPWR_REG *pCLKPWR;
  S3C2450_HSMMC_REG *pHSMMC;
  S3C2450_IOPORT_REG *pIOPreg;
  S3C2450_INTR_REG *pINTreg;

  //GPIO Setting
  //----- 1. Map the GPIO registers needed to enable the SDI controller -----
  pIOPreg = (S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pIOPreg == NULL) 
  {
    RETAILMSG (1,(TEXT("GPIO registers not allocated\r\n")));
    return;
  }
  if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("GPIO registers not mapped\r\n")));

    return;
  }

  pCLKPWR = (S3C2450_CLKPWR_REG *)VirtualAlloc(0, sizeof(S3C2450_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pCLKPWR == NULL) 
  {
    RETAILMSG (1,(TEXT("Clock & Power Management Special Register not allocated\n\r")));
    return;
  }
  if (!VirtualCopy((PVOID)pCLKPWR, (PVOID)(S3C2450_BASE_REG_PA_CLOCK_POWER >> 8), sizeof(S3C2450_CLKPWR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("Clock & Power Management Special Register not mapped\n\r")));
    return;
  }

  pHSMMC = (S3C2450_HSMMC_REG *)VirtualAlloc(0, sizeof(S3C2450_HSMMC_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pHSMMC == NULL) 
  {
    RETAILMSG (1,(TEXT("HSMMC Special Register not allocated\n\r")));
    return;
  }
  if (!VirtualCopy((PVOID)pHSMMC, (PVOID)(S3C2450_BASE_REG_PA_HSMMC >> 8), sizeof(S3C2450_HSMMC_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("HSMMC Special Register not mapped\n\r")));
    return;
  }	

  pINTreg = (S3C2450_INTR_REG *)VirtualAlloc(0, sizeof(S3C2450_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pINTreg == NULL) 
  {
    RETAILMSG (1,(TEXT("HSMMC Special Register not allocated\n\r")));
    return;
  }
  if (!VirtualCopy((PVOID)pINTreg, (PVOID)(S3C2450_BASE_REG_PA_INTR >> 8), sizeof(S3C2450_INTR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
    RETAILMSG (1,(TEXT("HSMMC Special Register not mapped\n\r")));
    return;
  }    

  //	pIOPreg->GPFCON &= ~(0x3<<14);
  //	pIOPreg->GPFCON |= (0x1<<14);	

  pIOPreg->GPLCON &= ~(0xFFFFF);
  pIOPreg->GPLCON |= (0xAAAAA);
  //	pIOPreg->GPLUDP &= ~(0xFFFFF);
  //	pIOPreg->GPLUDP |= (0x55555);

  pIOPreg->GPJCON &= ~(0x3F << 26);
  pIOPreg->GPJCON |= (0x2A << 26);
  //	pIOPreg->GPJUDP &= ~(0x3F << 26);
  //	pIOPreg->GPJUDP |= (0x15 << 26);

  pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x2/*EPLL*/<<4);
  pHSMMC->CONTROL3 = (0<<31) | (1<<23) | (0<<15) | (1<<7);

  pCLKPWR->HCLKCON |= (0x1<<16);
  pCLKPWR->SCLKCON |= (0x1<<13);	
  pCLKPWR->SCLKCON |= (0x1<<12);	

  RETAILMSG(0,(TEXT("HSMMC!!!!!!!!!!! pINTreg->INTMSK = 0x%08X\n"),pINTreg->INTMSK));
  RETAILMSG(0,(TEXT("HSMMC!!!!!!!!!!! pHSMMC->NORINTSTSEN = 0x%08X\n"),pHSMMC->NORINTSTSEN));


  VirtualFree((PVOID) pINTreg, 0, MEM_RELEASE);
  VirtualFree((PVOID) pIOPreg, 0, MEM_RELEASE);
  VirtualFree((PVOID) pCLKPWR, 0, MEM_RELEASE);
  VirtualFree((PVOID) pHSMMC, 0, MEM_RELEASE);	

#elif (BSP_TYPE == BSP_SMDK2450)
  RETAILMSG(1, (TEXT("[HSMMC1] Power Up the HSMMC Host Controller\n")));
  g_initialInsertion = 1;
  // 08.03.13 by KYS
  // HSMMC Ch1 initialization for "WakeUp"
  if (!InitCh()) return;
#endif  // !(BSP_TYPE == BSP_SMDK2443)
  CSDHCBase::PowerUp();
}

extern "C"
PCSDHCBase
CreateHSMMCHCObject(
    )
{
  return new CSDHController;
}


VOID 
CSDHController::DestroyHSMMCHCObject(
    PCSDHCBase pSDHC
    )
{
  DEBUGCHK(pSDHC);
  delete pSDHC;
}

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
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(1,(TEXT("[HSMMC1] Clock & Power Management Special Register is *NOT* allocated.\n")));
    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(1,(TEXT("[HSMMC1] Clock & Power Management Special Register is *NOT* mapped.\n")));
    return FALSE;
  }

  RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the EPLL (for SDCLK) : SYSCon.\n")));
  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)
  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(1,(TEXT("[HSMMC1] GPIO registers is *NOT* allocated.\n")));
    return FALSE;
  }
  if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),
        sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
    RETAILMSG(1,(TEXT("[HSMMC1] GPIO registers is *NOT* mapped.\n")));
    return FALSE;
  }

  RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the GPIO.\n")));
#ifdef _SMDK2450_CH1_8BIT_
  //pIOPreg->GPLSEL &= ~(0xF);      // GPLSEL[3:0]: 4'b0000 is to enable the SD1_DAT[7:4].
  pIOPreg->GPLCON &= ~(0xFFFFF);
  pIOPreg->GPLCON |=  (0xAAAAA);
  pIOPreg->GPLUDP &= ~(0xFFFFF);	// pull-up/down disable
#else // DAT 4-Bit
  pIOPreg->GPLCON &= ~(0xF<<16);
  pIOPreg->GPLCON |=  (0xA<<16);	// SD1_CLK, SD0_CMD
  pIOPreg->GPLUDP &= ~(0xF<<16);	// pull-up/down disable
  pIOPreg->GPLCON &= ~(0xFF);
  pIOPreg->GPLCON |=  (0xAA);     	// SD1_DAT[3:0]
  pIOPreg->GPLUDP &= ~(0xFF);		// pull-up/down disable
#endif

  pIOPreg->GPJCON &= ~(0x3F << 26);
#ifdef _SMDK2450_CH1_WP_
  pIOPreg->GPJCON |=  (0xA << 26);	// nSD1_WP(input in case of SMDK2450), SD1_CD(func), SD1_LED(func)
#else
  pIOPreg->GPJCON |=  (0x2A << 26);	// nSD1_WP(func), SD1_CD(func), SD1_LED(func)
#endif
  pIOPreg->GPJUDP &= ~(0x3F << 26);	// pull-up/down disable

  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("[HSMMC1] HSMMC Special Register is *NOT* allocated.\n")));
    return FALSE;
  }
  if (!VirtualCopy((PVOID)pHSMMC, (PVOID)(S3C2450_BASE_REG_PA_HSMMC1 >> 8),
        sizeof(S3C2450_HSMMC_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
    RETAILMSG(_DBG_,(TEXT("[HSMMC1] HSMMC Special Register is *NOT* mapped.\n")));
    return FALSE;
  }

  RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the EPLL : HSMMCCon.\n")));
  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)
  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;
}
#endif  // !(BSP_TYPE == BSP_SMDK2443)

⌨️ 快捷键说明

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