11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2d70e78c4SJerome Forissier /*
3d70e78c4SJerome Forissier * Copyright (c) 2015, Linaro Limited
4d70e78c4SJerome Forissier */
5d70e78c4SJerome Forissier
6d70e78c4SJerome Forissier #include <console.h>
7d70e78c4SJerome Forissier #include <drivers/pl011.h>
871c1078aSVictor Chong #ifdef CFG_SPI
971c1078aSVictor Chong #include <drivers/pl022_spi.h>
1071c1078aSVictor Chong #include <drivers/pl061_gpio.h>
1171c1078aSVictor Chong #endif
1266df8a2cSVictor Chong #if defined(PLATFORM_FLAVOR_hikey)
1371c1078aSVictor Chong #include <hikey_peripherals.h>
1466df8a2cSVictor Chong #endif
1571c1078aSVictor Chong #include <initcall.h>
1671c1078aSVictor Chong #include <io.h>
17d70e78c4SJerome Forissier #include <kernel/panic.h>
18d70e78c4SJerome Forissier #include <mm/tee_pager.h>
19ebbef0caSJens Wiklander #include <mm/core_memprot.h>
20d70e78c4SJerome Forissier #include <platform_config.h>
21d70e78c4SJerome Forissier #include <stdint.h>
22d70e78c4SJerome Forissier
23cf1879b1SRenê de Souza Pinto static struct pl011_data console_data __nex_bss;
24f182814bSJerome Forissier
25a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, PL011_REG_SIZE);
2666df8a2cSVictor Chong #if defined(PLATFORM_FLAVOR_hikey)
27a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, PMUSSI_BASE, PMUSSI_REG_SIZE);
2866df8a2cSVictor Chong #endif
2966df8a2cSVictor Chong #if defined(CFG_SPI) && defined(PLATFORM_FLAVOR_hikey)
30a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, PERI_BASE, PERI_BASE_REG_SIZE);
31a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, PMX0_BASE, PMX0_REG_SIZE);
32a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, PMX1_BASE, PMX1_REG_SIZE);
33a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, GPIO6_BASE, PL061_REG_SIZE);
34a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, SPI_BASE, PL022_REG_SIZE);
3571c1078aSVictor Chong #endif
3657ad0090SWen Bin register_ddr(DRAM0_BASE, DRAM0_SIZE_NSEC);
378d91fe09SVictor Chong #ifdef DRAM1_SIZE_NSEC
3857ad0090SWen Bin register_ddr(DRAM1_BASE, DRAM1_SIZE_NSEC);
398d91fe09SVictor Chong #endif
40db2e28d5SJerome Forissier #ifdef DRAM2_SIZE_NSEC
4157ad0090SWen Bin register_ddr(DRAM2_BASE, DRAM2_SIZE_NSEC);
42db2e28d5SJerome Forissier #endif
436d7ecad5SJens Wiklander
plat_console_init(void)44*55ab8f06SAlvin Chang void plat_console_init(void)
456ef34537SSY Chiu {
46f182814bSJerome Forissier pl011_init(&console_data, CONSOLE_UART_BASE, CONSOLE_UART_CLK_IN_HZ,
47f182814bSJerome Forissier CONSOLE_BAUDRATE);
48756aea59SJerome Forissier register_serial_console(&console_data.chip);
49d70e78c4SJerome Forissier }
5071c1078aSVictor Chong
5166df8a2cSVictor Chong #if defined(PLATFORM_FLAVOR_hikey)
5271c1078aSVictor Chong #ifdef CFG_SPI
spi_init(void)5371c1078aSVictor Chong void spi_init(void)
5471c1078aSVictor Chong {
5571c1078aSVictor Chong uint32_t shifted_val, read_val;
56c2e4eb43SAnton Rybakov vaddr_t peri_base = core_mmu_get_va(PERI_BASE, MEM_AREA_IO_NSEC,
57c2e4eb43SAnton Rybakov PERI_BASE_REG_SIZE);
58c2e4eb43SAnton Rybakov vaddr_t pmx0_base = core_mmu_get_va(PMX0_BASE, MEM_AREA_IO_NSEC,
59c2e4eb43SAnton Rybakov PMX0_REG_SIZE);
60c2e4eb43SAnton Rybakov vaddr_t pmx1_base = core_mmu_get_va(PMX1_BASE, MEM_AREA_IO_NSEC,
61c2e4eb43SAnton Rybakov PMX1_REG_SIZE);
6271c1078aSVictor Chong
63bce2f88aSVincent Mailhol DMSG("take SPI0 out of reset");
6471c1078aSVictor Chong shifted_val = PERI_RST3_SSP;
6571c1078aSVictor Chong /*
6671c1078aSVictor Chong * no need to read PERI_SC_PERIPH_RSTDIS3 first
6771c1078aSVictor Chong * as all the bits are processed and cleared after writing
6871c1078aSVictor Chong */
691c3ba0d4SEtienne Carriere io_write32(peri_base + PERI_SC_PERIPH_RSTDIS3, shifted_val);
70bce2f88aSVincent Mailhol DMSG("PERI_SC_PERIPH_RSTDIS3: 0x%x",
711c3ba0d4SEtienne Carriere io_read32(peri_base + PERI_SC_PERIPH_RSTDIS3));
7271c1078aSVictor Chong
7371c1078aSVictor Chong /*
7471c1078aSVictor Chong * wait until the requested device is out of reset
7571c1078aSVictor Chong * and ready to be used
7671c1078aSVictor Chong */
7771c1078aSVictor Chong do {
781c3ba0d4SEtienne Carriere read_val = io_read32(peri_base + PERI_SC_PERIPH_RSTSTAT3);
7971c1078aSVictor Chong } while (read_val & shifted_val);
80bce2f88aSVincent Mailhol DMSG("PERI_SC_PERIPH_RSTSTAT3: 0x%x", read_val);
8171c1078aSVictor Chong
82bce2f88aSVincent Mailhol DMSG("enable SPI clock");
8371c1078aSVictor Chong /*
8471c1078aSVictor Chong * no need to read PERI_SC_PERIPH_CLKEN3 first
8571c1078aSVictor Chong * as all the bits are processed and cleared after writing
8671c1078aSVictor Chong */
8771c1078aSVictor Chong shifted_val = PERI_CLK3_SSP;
881c3ba0d4SEtienne Carriere io_write32(peri_base + PERI_SC_PERIPH_CLKEN3, shifted_val);
89bce2f88aSVincent Mailhol DMSG("PERI_SC_PERIPH_CLKEN3: 0x%x",
901c3ba0d4SEtienne Carriere io_read32(peri_base + PERI_SC_PERIPH_CLKEN3));
9171c1078aSVictor Chong
92bce2f88aSVincent Mailhol DMSG("PERI_SC_PERIPH_CLKSTAT3: 0x%x",
931c3ba0d4SEtienne Carriere io_read32(peri_base + PERI_SC_PERIPH_CLKSTAT3));
9471c1078aSVictor Chong
9571c1078aSVictor Chong /*
9686a9d40dSVictor Chong * GPIO6_2 can be configured as PINMUX_GPIO, but as PINMUX_SPI, HW IP
9786a9d40dSVictor Chong * will control the chip select pin so we don't have to manually do it.
9886a9d40dSVictor Chong * The only concern is that the IP will pulse it between each packet,
9986a9d40dSVictor Chong * which might not work with certain clients. There seems to be no
10086a9d40dSVictor Chong * option to configure it to stay enabled for the total duration of the
10186a9d40dSVictor Chong * transfer.
10271c1078aSVictor Chong * ref: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/CJACFAFG.html
10371c1078aSVictor Chong */
104bce2f88aSVincent Mailhol DMSG("configure gpio6 pins 0-3 as SPI");
1051c3ba0d4SEtienne Carriere io_write32(pmx0_base + PMX0_IOMG104, PINMUX_SPI);
1061c3ba0d4SEtienne Carriere io_write32(pmx0_base + PMX0_IOMG105, PINMUX_SPI);
1071c3ba0d4SEtienne Carriere io_write32(pmx0_base + PMX0_IOMG106, PINMUX_SPI);
1081c3ba0d4SEtienne Carriere io_write32(pmx0_base + PMX0_IOMG107, PINMUX_SPI);
10971c1078aSVictor Chong
110bce2f88aSVincent Mailhol DMSG("configure gpio6 pins 0-3 as nopull");
1111c3ba0d4SEtienne Carriere io_write32(pmx1_base + PMX1_IOCG104, PINCFG_NOPULL);
1121c3ba0d4SEtienne Carriere io_write32(pmx1_base + PMX1_IOCG105, PINCFG_NOPULL);
1131c3ba0d4SEtienne Carriere io_write32(pmx1_base + PMX1_IOCG106, PINCFG_NOPULL);
1141c3ba0d4SEtienne Carriere io_write32(pmx1_base + PMX1_IOCG107, PINCFG_NOPULL);
11571c1078aSVictor Chong
11671c1078aSVictor Chong #ifdef CFG_SPI_TEST
11771c1078aSVictor Chong spi_test();
11871c1078aSVictor Chong #endif
11971c1078aSVictor Chong }
12071c1078aSVictor Chong #endif
12171c1078aSVictor Chong
peripherals_init(void)12271c1078aSVictor Chong static TEE_Result peripherals_init(void)
12371c1078aSVictor Chong {
124c2e4eb43SAnton Rybakov vaddr_t pmussi_base = core_mmu_get_va(PMUSSI_BASE, MEM_AREA_IO_NSEC,
125c2e4eb43SAnton Rybakov PMUSSI_REG_SIZE);
12671c1078aSVictor Chong
127bce2f88aSVincent Mailhol DMSG("enable LD021_1V8 source (pin 35) on LS connector");
12871c1078aSVictor Chong /*
12971c1078aSVictor Chong * Mezzanine cards usually use this to source level shifters for
13071c1078aSVictor Chong * UART, GPIO, SPI, I2C, etc so if not enabled, connected
13171c1078aSVictor Chong * peripherals will not work either (during bootloader stage)
13271c1078aSVictor Chong * until linux is booted.
13371c1078aSVictor Chong */
13471c1078aSVictor Chong io_mask8(pmussi_base + PMUSSI_LDO21_REG_ADJ, PMUSSI_LDO21_REG_VL_1V8,
13571c1078aSVictor Chong PMUSSI_LDO21_REG_VL_MASK);
1361c3ba0d4SEtienne Carriere io_write8(pmussi_base + PMUSSI_ENA_LDO17_22, PMUSSI_ENA_LDO21);
13771c1078aSVictor Chong
13871c1078aSVictor Chong #ifdef CFG_SPI
13971c1078aSVictor Chong spi_init();
14071c1078aSVictor Chong #endif
14171c1078aSVictor Chong return TEE_SUCCESS;
14271c1078aSVictor Chong }
14371c1078aSVictor Chong
14471c1078aSVictor Chong driver_init(peripherals_init);
14566df8a2cSVictor Chong #endif /* PLATFORM_FLAVOR_hikey */
146