quark.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <mmc.h>
  8. #include <netdev.h>
  9. #include <phy.h>
  10. #include <asm/io.h>
  11. #include <asm/pci.h>
  12. #include <asm/post.h>
  13. #include <asm/processor.h>
  14. #include <asm/arch/device.h>
  15. #include <asm/arch/msg_port.h>
  16. #include <asm/arch/quark.h>
  17. static struct pci_device_id mmc_supported[] = {
  18. { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO },
  19. };
  20. /*
  21. * TODO:
  22. *
  23. * This whole routine should be removed until we fully convert the ICH SPI
  24. * driver to DM and make use of DT to pass the bios control register offset
  25. */
  26. static void unprotect_spi_flash(void)
  27. {
  28. u32 bc;
  29. bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
  30. bc |= 0x1; /* unprotect the flash */
  31. x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
  32. }
  33. static void quark_setup_bars(void)
  34. {
  35. /* GPIO - D31:F0:R44h */
  36. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA,
  37. CONFIG_GPIO_BASE | IO_BAR_EN);
  38. /* ACPI PM1 Block - D31:F0:R48h */
  39. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK,
  40. CONFIG_ACPI_PM1_BASE | IO_BAR_EN);
  41. /* GPE0 - D31:F0:R4Ch */
  42. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK,
  43. CONFIG_ACPI_GPE0_BASE | IO_BAR_EN);
  44. /* WDT - D31:F0:R84h */
  45. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA,
  46. CONFIG_WDT_BASE | IO_BAR_EN);
  47. /* RCBA - D31:F0:RF0h */
  48. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA,
  49. CONFIG_RCBA_BASE | MEM_BAR_EN);
  50. /* ACPI P Block - Msg Port 04:R70h */
  51. msg_port_write(MSG_PORT_RMU, PBLK_BA,
  52. CONFIG_ACPI_PBLK_BASE | IO_BAR_EN);
  53. /* SPI DMA - Msg Port 04:R7Ah */
  54. msg_port_write(MSG_PORT_RMU, SPI_DMA_BA,
  55. CONFIG_SPI_DMA_BASE | IO_BAR_EN);
  56. /* PCIe ECAM */
  57. msg_port_write(MSG_PORT_MEM_ARBITER, AEC_CTRL,
  58. CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN);
  59. msg_port_write(MSG_PORT_HOST_BRIDGE, HEC_REG,
  60. CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN);
  61. }
  62. static void quark_enable_legacy_seg(void)
  63. {
  64. u32 hmisc2;
  65. hmisc2 = msg_port_read(MSG_PORT_HOST_BRIDGE, HMISC2);
  66. hmisc2 |= (HMISC2_SEGE | HMISC2_SEGF | HMISC2_SEGAB);
  67. msg_port_write(MSG_PORT_HOST_BRIDGE, HMISC2, hmisc2);
  68. }
  69. int arch_cpu_init(void)
  70. {
  71. struct pci_controller *hose;
  72. int ret;
  73. post_code(POST_CPU_INIT);
  74. #ifdef CONFIG_SYS_X86_TSC_TIMER
  75. timer_set_base(rdtsc());
  76. #endif
  77. ret = x86_cpu_init_f();
  78. if (ret)
  79. return ret;
  80. ret = pci_early_init_hose(&hose);
  81. if (ret)
  82. return ret;
  83. /*
  84. * Quark SoC has some non-standard BARs (excluding PCI standard BARs)
  85. * which need be initialized with suggested values
  86. */
  87. quark_setup_bars();
  88. /* Turn on legacy segments (A/B/E/F) decode to system RAM */
  89. quark_enable_legacy_seg();
  90. unprotect_spi_flash();
  91. return 0;
  92. }
  93. int print_cpuinfo(void)
  94. {
  95. post_code(POST_CPU_INFO);
  96. return default_print_cpuinfo();
  97. }
  98. void reset_cpu(ulong addr)
  99. {
  100. /* cold reset */
  101. outb(0x08, PORT_RESET);
  102. }
  103. int cpu_mmc_init(bd_t *bis)
  104. {
  105. return pci_mmc_init("Quark SDHCI", mmc_supported,
  106. ARRAY_SIZE(mmc_supported));
  107. }
  108. int cpu_eth_init(bd_t *bis)
  109. {
  110. u32 base;
  111. int ret0, ret1;
  112. pci_read_config_dword(QUARK_EMAC0, PCI_BASE_ADDRESS_0, &base);
  113. ret0 = designware_initialize(base, PHY_INTERFACE_MODE_RMII);
  114. pci_read_config_dword(QUARK_EMAC1, PCI_BASE_ADDRESS_0, &base);
  115. ret1 = designware_initialize(base, PHY_INTERFACE_MODE_RMII);
  116. if (ret0 < 0 && ret1 < 0)
  117. return -1;
  118. else
  119. return 0;
  120. }