1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2024, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <drivers/stm32_shared_io.h>
8 #include <io.h>
9 #include <kernel/panic.h>
10 #include <mm/core_memprot.h>
11 #include <stm32_sysconf.h>
12 #include <trace.h>
13 #include <types_ext.h>
14 #include <util.h>
15
16 #define SYSCON_OFFSET(id) ((id) & GENMASK_32(15, 0))
17 #define SYSCON_BANK(id) (((id) & GENMASK_32(31, 16)) >> 16)
18
19 #define SYSCFG_OCTOSPIAMCR SYSCON_ID(SYSCON_SYSCFG, \
20 0x2C00U)
21 #define SYSCFG_OCTOSPIAMCR_OAM_MASK GENMASK_32(2, 0)
22 #define SYSCFG_OCTOSPIAMCR_MM1_256_MM2_0 U(0)
23 #define SYSCFG_OCTOSPIAMCR_MM1_192_MM2_64 U(1)
24 #define SYSCFG_OCTOSPIAMCR_MM1_128_MM2_128 U(2)
25 #define SYSCFG_OCTOSPIAMCR_MM1_64_MM2_192 U(3)
26 #define SYSCFG_OCTOSPIAMCR_MM1_0_MM2_256 U(4)
27
28 #define SZ_64M U(0x04000000)
29 #define SZ_128M U(0x08000000)
30 #define SZ_192M U(0x0C000000)
31 #define SZ_256M U(0x10000000)
32
33 /* Safe Reset register definition */
34 #define SYSCFG_SAFERSTCR SYSCON_ID(SYSCON_SYSCFG, U(0x2018))
35 #define SYSCFG_SAFERSTCR_EN BIT(0)
36
37 struct io_pa_va syscfg_base[SYSCON_NB_BANKS] = {
38 { .pa = SYSCFG_BASE },
39 { .pa = A35SSC_BASE }
40 };
41
stm32mp_syscfg_base(uint32_t id)42 static vaddr_t stm32mp_syscfg_base(uint32_t id)
43 {
44 uint32_t bank = SYSCON_BANK(id);
45
46 assert(bank < SYSCON_NB_BANKS);
47
48 return io_pa_or_va_secure(&syscfg_base[bank], 1);
49 }
50
stm32mp_syscfg_write(uint32_t id,uint32_t value,uint32_t bitmsk)51 void stm32mp_syscfg_write(uint32_t id, uint32_t value, uint32_t bitmsk)
52 {
53 vaddr_t syconf_base = stm32mp_syscfg_base(id);
54
55 io_mask32_stm32shregs(syconf_base + SYSCON_OFFSET(id), value, bitmsk);
56 }
57
stm32mp_syscfg_read(uint32_t id)58 uint32_t stm32mp_syscfg_read(uint32_t id)
59 {
60 return io_read32(stm32mp_syscfg_base(id) + SYSCON_OFFSET(id));
61 }
62
stm32mp25_syscfg_set_safe_reset(bool status)63 void stm32mp25_syscfg_set_safe_reset(bool status)
64 {
65 vaddr_t addr = stm32mp_syscfg_base(SYSCON_SYSCFG) + SYSCFG_SAFERSTCR;
66
67 FMSG("Set safe reset to %d", status);
68
69 if (status)
70 io_setbits32(addr, SYSCFG_SAFERSTCR_EN);
71 else
72 io_clrbits32(addr, SYSCFG_SAFERSTCR_EN);
73 }
74
stm32mp25_syscfg_set_amcr(size_t mm1_size,size_t mm2_size)75 void stm32mp25_syscfg_set_amcr(size_t mm1_size, size_t mm2_size)
76 {
77 vaddr_t amcr_addr = stm32mp_syscfg_base(SYSCON_SYSCFG) +
78 SYSCON_OFFSET(SYSCFG_OCTOSPIAMCR);
79 uint32_t amcr = 0;
80
81 switch (mm1_size) {
82 case 0:
83 if (mm2_size != SZ_256M)
84 panic();
85
86 amcr = SYSCFG_OCTOSPIAMCR_MM1_0_MM2_256;
87 break;
88 case SZ_64M:
89 if (mm2_size != SZ_192M)
90 panic();
91
92 amcr = SYSCFG_OCTOSPIAMCR_MM1_64_MM2_192;
93 break;
94 case SZ_128M:
95 if (mm2_size != SZ_128M)
96 panic();
97
98 amcr = SYSCFG_OCTOSPIAMCR_MM1_128_MM2_128;
99 break;
100 case SZ_192M:
101 if (mm2_size != SZ_64M)
102 panic();
103
104 amcr = SYSCFG_OCTOSPIAMCR_MM1_192_MM2_64;
105 break;
106 case SZ_256M:
107 if (mm2_size != 0)
108 panic();
109
110 amcr = SYSCFG_OCTOSPIAMCR_MM1_256_MM2_0;
111 break;
112 default:
113 panic();
114 }
115
116 io_clrsetbits32(amcr_addr, SYSCFG_OCTOSPIAMCR_OAM_MASK, amcr);
117 }
118