main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. main.c
  5. Abstract:
  6. This module implements the entry point for the UEFI firmware running on top
  7. of the RK3288 Veyron.
  8. Author:
  9. Evan Green 10-Jul-2015
  10. Environment:
  11. Firmware
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <uefifw.h>
  17. #include "veyronfw.h"
  18. //
  19. // ---------------------------------------------------------------- Definitions
  20. //
  21. #define FIRMWARE_IMAGE_NAME "veyronfw.elf"
  22. //
  23. // The I2C PMU defaults to run at 400KHz.
  24. //
  25. #define RK32_I2C_PMU_FREQUENCY 400000
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. //
  30. // ----------------------------------------------- Internal Function Prototypes
  31. //
  32. VOID
  33. EfipVeyronConfigureArmPll (
  34. VOID
  35. );
  36. EFI_STATUS
  37. EfipVeyronConfigureI2cClock (
  38. VOID
  39. );
  40. VOID
  41. EfipVeyronConfigureMmcClocks (
  42. VOID
  43. );
  44. //
  45. // -------------------------------------------------------------------- Globals
  46. //
  47. //
  48. // Variables defined in the linker script that mark the start and end of the
  49. // image.
  50. //
  51. extern INT8 _end;
  52. extern INT8 __executable_start;
  53. //
  54. // Disable the RK3288 watchdog by default. Once it is started, it cannot be
  55. // stopped. So, it is essentially useless unless a keep-alive method is
  56. // implemented.
  57. //
  58. BOOLEAN EfiDisableWatchdog = TRUE;
  59. //
  60. // Define a boolean indicating whether the firmware was loaded via SD or eMMC.
  61. //
  62. BOOLEAN EfiBootedViaSd;
  63. //
  64. // ------------------------------------------------------------------ Functions
  65. //
  66. VOID
  67. EfiVeyronMain (
  68. VOID *TopOfStack,
  69. UINTN StackSize
  70. )
  71. /*++
  72. Routine Description:
  73. This routine is the C entry point for the firmware.
  74. Arguments:
  75. TopOfStack - Supplies the top of the stack that has been set up for the
  76. loader.
  77. StackSize - Supplies the total size of the stack set up for the loader, in
  78. bytes.
  79. Return Value:
  80. This routine does not return.
  81. --*/
  82. {
  83. UINTN FirmwareSize;
  84. //
  85. // Initialize UEFI enough to get into the debugger.
  86. //
  87. FirmwareSize = (UINTN)&_end - (UINTN)&__executable_start;
  88. EfiCoreMain((VOID *)-1,
  89. &__executable_start,
  90. FirmwareSize,
  91. FIRMWARE_IMAGE_NAME,
  92. TopOfStack - StackSize,
  93. StackSize);
  94. return;
  95. }
  96. EFI_STATUS
  97. EfiPlatformInitialize (
  98. UINT32 Phase
  99. )
  100. /*++
  101. Routine Description:
  102. This routine performs platform-specific firmware initialization.
  103. Arguments:
  104. Phase - Supplies the iteration number this routine is being called on.
  105. Phase zero occurs very early, just after the debugger comes up.
  106. Phase one occurs a bit later, after timer and interrupt services are
  107. initialized. Phase two happens right before boot, after all platform
  108. devices have been enumerated.
  109. Return Value:
  110. EFI status code.
  111. --*/
  112. {
  113. EFI_STATUS Status;
  114. if (Phase == 0) {
  115. if (EfiDisableWatchdog != FALSE) {
  116. EfiPlatformSetWatchdogTimer(0, 0, 0, NULL);
  117. }
  118. EfipVeyronConfigureArmPll();
  119. EfipVeyronConfigureMmcClocks();
  120. //
  121. // Initialize the I2C clock so that the clock frequency querying code
  122. // does not need to be present in the runtime core.
  123. //
  124. Status = EfipVeyronConfigureI2cClock();
  125. if (EFI_ERROR(Status)) {
  126. return Status;
  127. }
  128. } else if (Phase == 1) {
  129. EfipVeyronUsbInitialize();
  130. Status = EfipSmpInitialize();
  131. if (EFI_ERROR(Status)) {
  132. return Status;
  133. }
  134. Status = EfipVeyronCreateSmbiosTables();
  135. if (EFI_ERROR(Status)) {
  136. return Status;
  137. }
  138. }
  139. return EFI_SUCCESS;
  140. }
  141. EFI_STATUS
  142. EfiPlatformEnumerateDevices (
  143. VOID
  144. )
  145. /*++
  146. Routine Description:
  147. This routine enumerates and connects any builtin devices the platform
  148. contains.
  149. Arguments:
  150. None.
  151. Return Value:
  152. EFI status code.
  153. --*/
  154. {
  155. EFI_STATUS Status;
  156. Status = EfipVeyronEnumerateVideo();
  157. if (EFI_ERROR(Status)) {
  158. return Status;
  159. }
  160. Status = EfipVeyronEnumerateSd();
  161. if (EFI_ERROR(Status)) {
  162. return Status;
  163. }
  164. Status = EfipVeyronEnumerateSerial();
  165. if (EFI_ERROR(Status)) {
  166. return Status;
  167. }
  168. Status = EfipEnumerateRamDisks();
  169. if (EFI_ERROR(Status)) {
  170. return Status;
  171. }
  172. return EFI_SUCCESS;
  173. }
  174. EFI_STATUS
  175. EfipRk32GetPllClockFrequency (
  176. RK32_PLL_TYPE PllType,
  177. UINT32 *Frequency
  178. )
  179. /*++
  180. Routine Description:
  181. This routine returns the base PLL clock frequency of the given type.
  182. Arguments:
  183. PllType - Supplies the type of the PLL clock whose frequency is being
  184. queried.
  185. Frequency - Supplies a pointer that receives the PLL clock's frequency in
  186. Hertz.
  187. Return Value:
  188. Status code.
  189. --*/
  190. {
  191. RK32_CRU_REGISTER Configuration0;
  192. RK32_CRU_REGISTER Configuration1;
  193. VOID *CruBase;
  194. UINT32 Mode;
  195. UINT32 Nf;
  196. UINT32 No;
  197. UINT32 Nr;
  198. UINT32 Value;
  199. CruBase = (VOID *)RK32_CRU_BASE;
  200. *Frequency = 0;
  201. //
  202. // The CRU mode control register encodes the clock mode for each of the PLL
  203. // clocks.
  204. //
  205. Mode = EfiReadRegister32(CruBase + Rk32CruModeControl);
  206. switch (PllType) {
  207. case Rk32PllNew:
  208. Mode = (Mode & RK32_CRU_MODE_CONTROL_NEW_PLL_MODE_MASK) >>
  209. RK32_CRU_MODE_CONTROL_NEW_PLL_MODE_SHIFT;
  210. Configuration0 = Rk32CruNewPllConfiguration0;
  211. Configuration1 = Rk32CruNewPllConfiguration1;
  212. break;
  213. case Rk32PllCodec:
  214. Mode = (Mode & RK32_CRU_MODE_CONTROL_CODEC_PLL_MODE_MASK) >>
  215. RK32_CRU_MODE_CONTROL_CODEC_PLL_MODE_SHIFT;
  216. Configuration0 = Rk32CruCodecPllConfiguration0;
  217. Configuration1 = Rk32CruCodecPllConfiguration1;
  218. break;
  219. case Rk32PllGeneral:
  220. Mode = (Mode & RK32_CRU_MODE_CONTROL_GENERAL_PLL_MODE_MASK) >>
  221. RK32_CRU_MODE_CONTROL_GENERAL_PLL_MODE_SHIFT;
  222. Configuration0 = Rk32CruGeneralPllConfiguration0;
  223. Configuration1 = Rk32CruGeneralPllConfiguration1;
  224. break;
  225. case Rk32PllDdr:
  226. Mode = (Mode & RK32_CRU_MODE_CONTROL_DDR_PLL_MODE_MASK) >>
  227. RK32_CRU_MODE_CONTROL_DDR_PLL_MODE_SHIFT;
  228. Configuration0 = Rk32CruDdrPllConfiguration0;
  229. Configuration1 = Rk32CruDdrPllConfiguration1;
  230. break;
  231. case Rk32PllArm:
  232. Mode = (Mode & RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_MASK) >>
  233. RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_SHIFT;
  234. Configuration0 = Rk32CruArmPllConfiguration0;
  235. Configuration1 = Rk32CruArmPllConfiguration1;
  236. break;
  237. default:
  238. return EFI_UNSUPPORTED;
  239. }
  240. //
  241. // Calculate the frequency based on the mode.
  242. //
  243. if (Mode == RK32_CRU_MODE_CONTROL_SLOW_MODE) {
  244. *Frequency = RK32_CRU_PLL_SLOW_MODE_FREQUENCY;
  245. } else if (Mode == RK32_CRU_MODE_CONTROL_NORMAL_MODE) {
  246. //
  247. // Calculate the clock speed based on the formula described in
  248. // section 3.9 of the RK3288 TRM.
  249. //
  250. Value = EfiReadRegister32(CruBase + Configuration0);
  251. No = (Value & RK32_PLL_CONFIGURATION0_OD_MASK) >>
  252. RK32_PLL_CONFIGURATION0_OD_SHIFT;
  253. No += 1;
  254. Nr = (Value & RK32_PLL_CONFIGURATION0_NR_MASK) >>
  255. RK32_PLL_CONFIGURATION0_NR_SHIFT;
  256. Nr += 1;
  257. Value = EfiReadRegister32(CruBase + Configuration1);
  258. Nf = (Value & RK32_PLL_CONFIGURATION1_NF_MASK) >>
  259. RK32_PLL_CONFIGURATION1_NF_SHIFT;
  260. Nf += 1;
  261. *Frequency = RK32_CRU_PLL_COMPUTE_CLOCK_FREQUENCY(Nf, Nr, No);
  262. } else if (Mode == RK32_CRU_MODE_CONTROL_DEEP_SLOW_MODE) {
  263. *Frequency = RK32_CRU_PLL_DEEP_SLOW_MODE_FREQUENCY;
  264. } else {
  265. return EFI_DEVICE_ERROR;
  266. }
  267. return EFI_SUCCESS;
  268. }
  269. //
  270. // --------------------------------------------------------- Internal Functions
  271. //
  272. VOID
  273. EfipVeyronConfigureArmPll (
  274. VOID
  275. )
  276. /*++
  277. Routine Description:
  278. This routine configures the ARM PLL, since the 1800MHz set by the firmware
  279. actually seems to be too fast to run correctly.
  280. Arguments:
  281. None.
  282. Return Value:
  283. None.
  284. --*/
  285. {
  286. UINT32 Frequency;
  287. UINT32 Nf;
  288. UINT32 No;
  289. UINT32 Nr;
  290. UINT32 Value;
  291. //
  292. // Put the PLL in slow mode to bypass the PLL while it's being configured.
  293. //
  294. Value = (RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_MASK << 16) |
  295. RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_SLOW;
  296. RK32_WRITE_CRU(Rk32CruModeControl, Value);
  297. Frequency = VEYRON_ARM_CPU_HERTZ;
  298. Nr = 1;
  299. No = 1;
  300. Nf = (UINT32)((UINT64)Frequency * Nr * No / VEYRON_OSC_HERTZ);
  301. //
  302. // Reset the PLL.
  303. //
  304. Value = (RK32_PLL_CONFIGURATION3_RESET << 16) |
  305. RK32_PLL_CONFIGURATION3_RESET;
  306. RK32_WRITE_CRU(Rk32CruArmPllConfiguration3, Value);
  307. //
  308. // Configure the PLL.
  309. //
  310. Value = ((RK32_PLL_CONFIGURATION0_NR_MASK |
  311. RK32_PLL_CONFIGURATION0_OD_MASK) << 16) |
  312. ((Nr - 1) << RK32_PLL_CONFIGURATION0_NR_SHIFT) | (No - 1);
  313. RK32_WRITE_CRU(Rk32CruArmPllConfiguration0, Value);
  314. Value = (RK32_PLL_CONFIGURATION1_NF_MASK << 16) | (Nf - 1);
  315. RK32_WRITE_CRU(Rk32CruArmPllConfiguration1, Value);
  316. Value = (RK32_PLL_CONFIGURATION2_BWADJ_MASK << 16) | ((Nf >> 1) - 1);
  317. RK32_WRITE_CRU(Rk32CruArmPllConfiguration2, Value);
  318. EfiStall(10);
  319. //
  320. // Clear reset.
  321. //
  322. Value = RK32_PLL_CONFIGURATION3_RESET << 16;
  323. RK32_WRITE_CRU(Rk32CruArmPllConfiguration3, Value);
  324. //
  325. // Wait for the PLL to lock itself.
  326. //
  327. do {
  328. Value = RK32_READ_GRF(Rk32GrfSocStatus1);
  329. } while ((Value & RK32_GRF_SOC_STATUS1_ARM_PLL_LOCK) == 0);
  330. //
  331. // Enter normal mode on the PLL.
  332. //
  333. Value = (RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_MASK << 16) |
  334. RK32_CRU_MODE_CONTROL_ARM_PLL_MODE_NORMAL;
  335. RK32_WRITE_CRU(Rk32CruModeControl, Value);
  336. return;
  337. }
  338. EFI_STATUS
  339. EfipVeyronConfigureI2cClock (
  340. VOID
  341. )
  342. /*++
  343. Routine Description:
  344. This routine configures the I2C clock to 400Khz. This is done outside the
  345. runtime core to avoid pulling in the clock querying code and divide
  346. intrinsics.
  347. Arguments:
  348. None.
  349. Return Value:
  350. Status code.
  351. --*/
  352. {
  353. UINT32 AclkPllFrequency;
  354. UINT32 BusAclkDivider;
  355. UINT32 BusAclkDivider1;
  356. UINT32 BusAclkFrequency;
  357. UINT32 BusPclkDivider;
  358. UINT32 BusPclkFrequency;
  359. UINT32 Divisor;
  360. UINT32 DivisorHigh;
  361. UINT32 DivisorLow;
  362. VOID *I2cPmuBase;
  363. RK32_PLL_TYPE PllType;
  364. VOID *PmuBase;
  365. EFI_STATUS Status;
  366. UINT32 Value;
  367. I2cPmuBase = (VOID *)RK32_I2C_PMU_BASE;
  368. PmuBase = (VOID *)RK32_PMU_BASE;
  369. EfiWriteRegister32(PmuBase + Rk32PmuIomuxI2c0Sda,
  370. RK32_PMU_IOMUX_I2C0_SDA_DEFAULT);
  371. EfiWriteRegister32(PmuBase + Rk32PmuIomuxI2c0Scl,
  372. RK32_PMU_IOMUX_I2C0_SCL_DEFAULT);
  373. //
  374. // Get the frequency of the bus PCLK. The bus's ACLK must first be
  375. // calculated.
  376. //
  377. PllType = Rk32PllCodec;
  378. Value = EfiReadRegister32((VOID *)RK32_CRU_BASE + Rk32CruClockSelect1);
  379. if ((Value & RK32_CRU_CLOCK_SELECT1_GENERAL_PLL) != 0) {
  380. PllType = Rk32PllGeneral;
  381. }
  382. Status = EfipRk32GetPllClockFrequency(PllType, &AclkPllFrequency);
  383. if (EFI_ERROR(Status)) {
  384. return Status;
  385. }
  386. BusAclkDivider = (Value & RK32_CRU_CLOCK_SELECT1_ACLK_DIVIDER_MASK) >>
  387. RK32_CRU_CLOCK_SELECT1_ACLK_DIVIDER_SHIFT;
  388. BusAclkDivider += 1;
  389. BusAclkDivider1 = (Value & RK32_CRU_CLOCK_SELECT1_ACLK_DIVIDER1_MASK) >>
  390. RK32_CRU_CLOCK_SELECT1_ACLK_DIVIDER1_SHIFT;
  391. BusAclkDivider1 += 1;
  392. BusAclkFrequency = AclkPllFrequency / (BusAclkDivider * BusAclkDivider1);
  393. //
  394. // Now divide the ACLK by the PCLK's divider to get the PCLK frequency.
  395. //
  396. BusPclkDivider = (Value & RK32_CRU_CLOCK_SELECT1_PCLK_DIVIDER_MASK) >>
  397. RK32_CRU_CLOCK_SELECT1_PCLK_DIVIDER_SHIFT;
  398. BusPclkDivider += 1;
  399. BusPclkFrequency = BusAclkFrequency / BusPclkDivider;
  400. //
  401. // Set the clock divisor to run at 400Mhz.
  402. //
  403. Divisor = (BusPclkFrequency + (8 * RK32_I2C_PMU_FREQUENCY - 1)) /
  404. (8 * RK32_I2C_PMU_FREQUENCY);
  405. DivisorHigh = ((Divisor * 3) / 7) - 1;
  406. DivisorLow = Divisor - DivisorHigh - 2;
  407. Value = (DivisorHigh << RK32_I2C_CLOCK_DIVISOR_HIGH_SHIFT) &
  408. RK32_I2C_CLOCK_DIVISOR_HIGH_MASK;
  409. Value |= (DivisorLow << RK32_I2C_CLOCK_DIVISOR_LOW_SHIFT) &
  410. RK32_I2C_CLOCK_DIVISOR_LOW_MASK;
  411. EfiWriteRegister32(I2cPmuBase + Rk32I2cClockDivisor, Value);
  412. return EFI_SUCCESS;
  413. }
  414. VOID
  415. EfipVeyronConfigureMmcClocks (
  416. VOID
  417. )
  418. /*++
  419. Routine Description:
  420. This routine configures the MMC clock.
  421. Arguments:
  422. None.
  423. Return Value:
  424. Status code.
  425. --*/
  426. {
  427. UINT32 Mask;
  428. UINT32 Mmc;
  429. UINT32 Value;
  430. //
  431. // To figure out if the firmware was loaded from SD or eMMC, check to see
  432. // which clock was configured. If SD was configured for high speed, assume
  433. // boot came from there.
  434. //
  435. Mmc = EfiReadRegister32((VOID *)RK32_CRU_BASE + Rk32CruClockSelect11);
  436. if ((Mmc & RK32_CRU_CLOCK_SELECT11_MMC0_CLOCK_MASK) !=
  437. (RK32_CRU_CLOCK_SELECT11_MMC0_24MHZ <<
  438. RK32_CRU_CLOCK_SELECT11_MMC0_CLOCK_SHIFT)) {
  439. EfiBootedViaSd = TRUE;
  440. }
  441. //
  442. // Set up MMC0 to clock off of the general PLL / 6, which comes out to
  443. // 99MHz.
  444. //
  445. Mmc = (RK32_CRU_CLOCK_SELECT11_MMC0_GENERAL_PLL <<
  446. RK32_CRU_CLOCK_SELECT11_MMC0_CLOCK_SHIFT) |
  447. (5 << RK32_CRU_CLOCK_SELECT11_MMC0_DIVIDER_SHIFT);
  448. Mask = RK32_CRU_CLOCK_SELECT11_MMC0_CLOCK_MASK |
  449. RK32_CRU_CLOCK_SELECT11_MMC0_DIVIDER_MASK;
  450. Mmc |= Mask << RK32_CRU_CLOCK_SELECT11_PROTECT_SHIFT;
  451. EfiWriteRegister32((VOID *)RK32_CRU_BASE + Rk32CruClockSelect11, Mmc);
  452. //
  453. // Set up eMMC like the MMC0.
  454. //
  455. Mmc = (RK32_CRU_CLOCK_SELECT12_EMMC_GENERAL_PLL <<
  456. RK32_CRU_CLOCK_SELECT12_EMMC_CLOCK_SHIFT) |
  457. (5 << RK32_CRU_CLOCK_SELECT12_EMMC_DIVIDER_SHIFT);
  458. Mask = RK32_CRU_CLOCK_SELECT12_EMMC_CLOCK_MASK |
  459. RK32_CRU_CLOCK_SELECT12_EMMC_DIVIDER_MASK;
  460. Mmc |= Mask << RK32_CRU_CLOCK_SELECT12_PROTECT_SHIFT;
  461. EfiWriteRegister32((VOID *)RK32_CRU_BASE + Rk32CruClockSelect12, Mmc);
  462. //
  463. // Reset the SD/MMC.
  464. //
  465. Value = RK32_CRU_SOFT_RESET8_MMC0 << RK32_CRU_SOFT_RESET8_PROTECT_SHIFT;
  466. Value |= RK32_CRU_SOFT_RESET8_MMC0;
  467. EfiWriteRegister32((VOID *)RK32_CRU_BASE + Rk32CruSoftReset8, Value);
  468. EfiStall(100);
  469. Value &= ~RK32_CRU_SOFT_RESET8_MMC0;
  470. EfiWriteRegister32((VOID *)RK32_CRU_BASE + Rk32CruSoftReset8, Value);
  471. //
  472. // Reset the IOMUX to the correct value for SD/MMC.
  473. //
  474. Value = RK32_GRF_GPIO6C_IOMUX_VALUE;
  475. EfiWriteRegister32((VOID *)RK32_GRF_BASE + Rk32GrfGpio6cIomux, Value);
  476. return;
  477. }