hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/** @file
 *
 *  Copyright (c) 2017, Andrei Warkentin <andrey.warkentin@gmail.com>
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent
 *
 **/
 
#include "RockchipSdhci.h"
#include <Library/PcdLib.h>
 
#define GRF_BASE            0xFDC60000
#define NS_CRU_BASE         0xFDD20000
#define CRU_CLKSEL_CON28    0x0170
 
#define EMMC_CLOCK_BASE     (NS_CRU_BASE + CRU_CLKSEL_CON28)
#define EMMC_CLOCK_SEL(a)   (((7 << 12) << 16) | (a << 12))
 
#define EMMCPHY_BASE        PcdGet32 (PcdSdhciDxeBaseAddress)
#define DWCMSHC_HOST_CTRL3    (EMMC_BASE + 0x508)
#define EMMC_DLL_CTRL        (EMMC_BASE + 0x800)
#define EMMC_DLL_RXCLK        (EMMC_BASE + 0x804)
#define EMMC_DLL_TXCLK        (EMMC_BASE + 0x808)
#define EMMC_DLL_STRBIN        (EMMC_BASE + 0x80C)
#define EMMC_DLL_STATUS0    (EMMC_BASE + 0x840)
#define EMMC_DLL_STATUS1    (EMMC_BASE + 0x844)
 
EFI_STATUS SdhciSetPHY(
  IN UINTN Clock
  )
{
  UINT32 Tmp;
 
  /* Disable cmd conflict check */
  Tmp = MmioRead32(DWCMSHC_HOST_CTRL3);
  Tmp &= ~BIT0;
  MmioWrite32(EMMCPHY_BASE + DWCMSHC_HOST_CTRL3, Tmp);
 
  if (Clock < 100000000) {
    MmioWrite32(EMMC_DLL_CTRL, 0);
    MmioWrite32(EMMC_DLL_RXCLK, 1<<29); /* PIO mode need set bit 29*/
    MmioWrite32(EMMC_DLL_TXCLK, 0);
    MmioWrite32(EMMC_DLL_STRBIN, 0);
    return EFI_SUCCESS;
  }
  else {
    return RETURN_UNSUPPORTED;
  }
 
  return EFI_SUCCESS;
}
 
EFI_STATUS
EFIAPI
SdhciGetClockRate(
  IN UINTN TargetFreq,
  OUT UINTN *BaseFreq
  )
{
  UINT32 CClkEmmcSel;
 
  if (TargetFreq == 0 || BaseFreq == NULL)
    return -1;
  
  if (TargetFreq >= 200000000) {
    CClkEmmcSel = 1;
  } else if (TargetFreq >= 150000000) {
    CClkEmmcSel = 2;
  } else if (TargetFreq >= 100000000) {
    CClkEmmcSel = 3;
  } else if (TargetFreq >= 50000000) {
    CClkEmmcSel = 4;
  } else if (TargetFreq >= 24000000) {
    CClkEmmcSel = 0;
  } else {
    CClkEmmcSel = 5; /* 375KHZ */
  }
  
  SdhciSetPHY(TargetFreq);
  *BaseFreq= TargetFreq;
 
  DEBUG ((DEBUG_BLKIO, "MMCHost: Clock: %d\n", TargetFreq));
  MmioWrite32(EMMC_CLOCK_BASE, EMMC_CLOCK_SEL(CClkEmmcSel));
  DEBUG ((DEBUG_BLKIO, "EMMC_CLOCK 0x%x: 0x%x:\n", EMMC_CLOCK_BASE, MmioRead32(EMMC_CLOCK_BASE)));
  //DEBUG ((DEBUG_BLKIO, "GPIO1B_IOMUX_H: 0x%x:\n", MmioRead32(GRF_BASE+0x0C)));
  //DEBUG ((DEBUG_BLKIO, "GPIO1C_IOMUX_L: 0x%x:\n", MmioRead32(GRF_BASE+0x10)));
  //DEBUG ((DEBUG_BLKIO, "GPIO1C_IOMUX_H: 0x%x:\n", MmioRead32(GRF_BASE+0x14)));
 
  //DEBUG ((DEBUG_BLKIO, "EMMC_DLL_CTRL: 0x%x:\n", MmioRead32(EMMC_DLL_CTRL)));
  //DEBUG ((DEBUG_BLKIO, "EMMC_DLL_RXCLK: 0x%x:\n", MmioRead32(EMMC_DLL_RXCLK)));
  //DEBUG ((DEBUG_BLKIO, "EMMC_DLL_TXCLK: 0x%x:\n", MmioRead32(EMMC_DLL_TXCLK)));
 
  return EFI_SUCCESS;
}