quark.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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/irq.h>
  12. #include <asm/pci.h>
  13. #include <asm/post.h>
  14. #include <asm/processor.h>
  15. #include <asm/arch/device.h>
  16. #include <asm/arch/msg_port.h>
  17. #include <asm/arch/quark.h>
  18. static struct pci_device_id mmc_supported[] = {
  19. { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO },
  20. };
  21. /*
  22. * TODO:
  23. *
  24. * This whole routine should be removed until we fully convert the ICH SPI
  25. * driver to DM and make use of DT to pass the bios control register offset
  26. */
  27. static void unprotect_spi_flash(void)
  28. {
  29. u32 bc;
  30. bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
  31. bc |= 0x1; /* unprotect the flash */
  32. x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
  33. }
  34. static void quark_setup_bars(void)
  35. {
  36. /* GPIO - D31:F0:R44h */
  37. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA,
  38. CONFIG_GPIO_BASE | IO_BAR_EN);
  39. /* ACPI PM1 Block - D31:F0:R48h */
  40. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK,
  41. CONFIG_ACPI_PM1_BASE | IO_BAR_EN);
  42. /* GPE0 - D31:F0:R4Ch */
  43. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK,
  44. CONFIG_ACPI_GPE0_BASE | IO_BAR_EN);
  45. /* WDT - D31:F0:R84h */
  46. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA,
  47. CONFIG_WDT_BASE | IO_BAR_EN);
  48. /* RCBA - D31:F0:RF0h */
  49. pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA,
  50. CONFIG_RCBA_BASE | MEM_BAR_EN);
  51. /* ACPI P Block - Msg Port 04:R70h */
  52. msg_port_write(MSG_PORT_RMU, PBLK_BA,
  53. CONFIG_ACPI_PBLK_BASE | IO_BAR_EN);
  54. /* SPI DMA - Msg Port 04:R7Ah */
  55. msg_port_write(MSG_PORT_RMU, SPI_DMA_BA,
  56. CONFIG_SPI_DMA_BASE | IO_BAR_EN);
  57. /* PCIe ECAM */
  58. msg_port_write(MSG_PORT_MEM_ARBITER, AEC_CTRL,
  59. CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN);
  60. msg_port_write(MSG_PORT_HOST_BRIDGE, HEC_REG,
  61. CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN);
  62. }
  63. static void quark_enable_legacy_seg(void)
  64. {
  65. u32 hmisc2;
  66. hmisc2 = msg_port_read(MSG_PORT_HOST_BRIDGE, HMISC2);
  67. hmisc2 |= (HMISC2_SEGE | HMISC2_SEGF | HMISC2_SEGAB);
  68. msg_port_write(MSG_PORT_HOST_BRIDGE, HMISC2, hmisc2);
  69. }
  70. int arch_cpu_init(void)
  71. {
  72. struct pci_controller *hose;
  73. int ret;
  74. post_code(POST_CPU_INIT);
  75. #ifdef CONFIG_SYS_X86_TSC_TIMER
  76. timer_set_base(rdtsc());
  77. #endif
  78. ret = x86_cpu_init_f();
  79. if (ret)
  80. return ret;
  81. ret = pci_early_init_hose(&hose);
  82. if (ret)
  83. return ret;
  84. /*
  85. * Quark SoC has some non-standard BARs (excluding PCI standard BARs)
  86. * which need be initialized with suggested values
  87. */
  88. quark_setup_bars();
  89. /* Turn on legacy segments (A/B/E/F) decode to system RAM */
  90. quark_enable_legacy_seg();
  91. unprotect_spi_flash();
  92. return 0;
  93. }
  94. int print_cpuinfo(void)
  95. {
  96. post_code(POST_CPU_INFO);
  97. return default_print_cpuinfo();
  98. }
  99. void reset_cpu(ulong addr)
  100. {
  101. /* cold reset */
  102. x86_full_reset();
  103. }
  104. int cpu_mmc_init(bd_t *bis)
  105. {
  106. return pci_mmc_init("Quark SDHCI", mmc_supported,
  107. ARRAY_SIZE(mmc_supported));
  108. }
  109. int cpu_eth_init(bd_t *bis)
  110. {
  111. u32 base;
  112. int ret0, ret1;
  113. pci_read_config_dword(QUARK_EMAC0, PCI_BASE_ADDRESS_0, &base);
  114. ret0 = designware_initialize(base, PHY_INTERFACE_MODE_RMII);
  115. pci_read_config_dword(QUARK_EMAC1, PCI_BASE_ADDRESS_0, &base);
  116. ret1 = designware_initialize(base, PHY_INTERFACE_MODE_RMII);
  117. if (ret0 < 0 && ret1 < 0)
  118. return -1;
  119. else
  120. return 0;
  121. }
  122. void cpu_irq_init(void)
  123. {
  124. struct quark_rcba *rcba;
  125. u32 base;
  126. base = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, LB_RCBA);
  127. base &= ~MEM_BAR_EN;
  128. rcba = (struct quark_rcba *)base;
  129. /*
  130. * Route Quark PCI device interrupt pin to PIRQ
  131. *
  132. * Route device#23's INTA/B/C/D to PIRQA/B/C/D
  133. * Route device#20,21's INTA/B/C/D to PIRQE/F/G/H
  134. */
  135. writew(PIRQC, &rcba->rmu_ir);
  136. writew(PIRQA | (PIRQB << 4) | (PIRQC << 8) | (PIRQD << 12),
  137. &rcba->d23_ir);
  138. writew(PIRQD, &rcba->core_ir);
  139. writew(PIRQE | (PIRQF << 4) | (PIRQG << 8) | (PIRQH << 12),
  140. &rcba->d20d21_ir);
  141. }
  142. int arch_misc_init(void)
  143. {
  144. return pirq_init();
  145. }