cpu.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  2. /*
  3. * Copyright (c) 2018 Microsemi Corporation
  4. */
  5. #include <common.h>
  6. #include <init.h>
  7. #include <asm/global_data.h>
  8. #include <linux/bitops.h>
  9. #include <asm/io.h>
  10. #include <asm/types.h>
  11. #include <asm/mipsregs.h>
  12. #include <mach/tlb.h>
  13. #include <mach/ddr.h>
  14. DECLARE_GLOBAL_DATA_PTR;
  15. #if CFG_SYS_SDRAM_SIZE <= SZ_64M
  16. #define MSCC_RAM_TLB_SIZE SZ_64M
  17. #define MSCC_ATTRIB2 MMU_REGIO_INVAL
  18. #elif CFG_SYS_SDRAM_SIZE <= SZ_128M
  19. #define MSCC_RAM_TLB_SIZE SZ_64M
  20. #define MSCC_ATTRIB2 MMU_REGIO_RW
  21. #elif CFG_SYS_SDRAM_SIZE <= SZ_256M
  22. #define MSCC_RAM_TLB_SIZE SZ_256M
  23. #define MSCC_ATTRIB2 MMU_REGIO_INVAL
  24. #elif CFG_SYS_SDRAM_SIZE <= SZ_512M
  25. #define MSCC_RAM_TLB_SIZE SZ_256M
  26. #define MSCC_ATTRIB2 MMU_REGIO_RW
  27. #else
  28. #define MSCC_RAM_TLB_SIZE SZ_512M
  29. #define MSCC_ATTRIB2 MMU_REGIO_RW
  30. #endif
  31. /* NOTE: lowlevel_init() function does not have access to the
  32. * stack. Thus, all called functions must be inlined, and (any) local
  33. * variables must be kept in registers.
  34. */
  35. void vcoreiii_tlb_init(void)
  36. {
  37. register int tlbix = 0;
  38. /*
  39. * Unlike most of the MIPS based SoCs, the IO register address
  40. * are not in KSEG0. The mainline linux kernel built in legacy
  41. * mode needs to access some of the registers very early in
  42. * the boot and make the assumption that the bootloader has
  43. * already configured them, so we have to match this
  44. * expectation.
  45. */
  46. create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW,
  47. MMU_REGIO_RW);
  48. #ifdef CONFIG_SOC_LUTON
  49. create_tlb(tlbix++, MSCC_IO_ORIGIN2_OFFSET, SZ_16M, MMU_REGIO_RW,
  50. MMU_REGIO_RW);
  51. #endif
  52. /*
  53. * If U-Boot is located in NOR then we want to be able to use
  54. * the data cache in order to boot in a decent duration
  55. */
  56. create_tlb(tlbix++, MSCC_FLASH_TO, SZ_16M, MMU_REGIO_RO_C,
  57. MMU_REGIO_RO_C);
  58. create_tlb(tlbix++, MSCC_FLASH_TO + SZ_32M, SZ_16M, MMU_REGIO_RO_C,
  59. MMU_REGIO_RO_C);
  60. /*
  61. * Using cache for RAM also helps to improve boot time. Thanks
  62. * to this the time to relocate U-Boot in RAM went from 2.092
  63. * secs to 0.104 secs.
  64. */
  65. create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW,
  66. MSCC_ATTRIB2);
  67. /* Enable mapping (using TLB) kuseg by clearing the bit ERL,
  68. * which is set on reset.
  69. */
  70. write_c0_status(read_c0_status() & ~ST0_ERL);
  71. }
  72. int mach_cpu_init(void)
  73. {
  74. /* Speed up NOR flash access */
  75. #ifdef CONFIG_SOC_LUTON
  76. writel(ICPU_PI_MST_CFG_TRISTATE_CTRL +
  77. ICPU_PI_MST_CFG_CLK_DIV(4), BASE_CFG + ICPU_PI_MST_CFG);
  78. writel(ICPU_SPI_MST_CFG_FAST_READ_ENA +
  79. ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
  80. ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
  81. #else
  82. #if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_SERVAL)
  83. writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
  84. ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG);
  85. #endif
  86. #if defined(CONFIG_SOC_JR2) || defined(CONFIG_SOC_SERVALT)
  87. writel(ICPU_SPI_MST_CFG_FAST_READ_ENA +
  88. ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) +
  89. ICPU_SPI_MST_CFG_CLK_DIV(14), BASE_CFG + ICPU_SPI_MST_CFG);
  90. #endif
  91. /*
  92. * Legacy and mainline linux kernel expect that the
  93. * interruption map was set as it was done by redboot.
  94. */
  95. writel(~0, BASE_CFG + ICPU_DST_INTR_MAP(0));
  96. writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1));
  97. writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2));
  98. writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3));
  99. #endif
  100. return 0;
  101. }