1 /*
2 * Copyright (c) 2019-2025, ARM Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef GIC600_MULTICHIP_PRIVATE_H
8 #define GIC600_MULTICHIP_PRIVATE_H
9
10 #include <drivers/arm/gic600_multichip.h>
11
12 #include "gicv3_private.h"
13
14 /* GIC600 GICD multichip related offsets */
15 #define GICD_CHIPSR U(0xC000)
16 #define GICD_DCHIPR U(0xC004)
17 #define GICD_CHIPR U(0xC008)
18 #define GICD_CFGID U(0xF000)
19
20 /* GIC600 GICD multichip related masks */
21 #define GICD_CHIPRx_PUP_BIT BIT_64(1)
22 #define GICD_CHIPRx_SOCKET_STATE BIT_64(0)
23 #define GICD_DCHIPR_PUP_BIT BIT_32(0)
24 #define GICD_CHIPSR_RTS_MASK (BIT_32(4) | BIT_32(5))
25 #define GICD_CFGID_LCA_BIT BIT_64(21)
26
27 /* GIC600 GICD multichip related shifts */
28 #define GICD_CHIPRx_ADDR_SHIFT 16
29 #define GICD_CHIPSR_RTS_SHIFT 4
30 #define GICD_DCHIPR_RT_OWNER_SHIFT 4
31
32 /* Other shifts and masks remain the same between GIC-600 and GIC-700. */
33 #define GIC_700_SPI_BLOCK_MIN_SHIFT 9
34 #define GIC_700_SPI_BLOCKS_SHIFT 3
35 #define GIC_600_SPI_BLOCK_MIN_SHIFT 10
36 #define GIC_600_SPI_BLOCKS_SHIFT 5
37
38 #define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0)
39 #define GICD_CHIPSR_RTS_STATE_UPDATING U(1)
40 #define GICD_CHIPSR_RTS_STATE_CONSISTENT U(2)
41
42 /* SPI interrupt id minimum and maximum range */
43 #define GIC600_SPI_ID_MIN 32
44 #define GIC600_SPI_ID_MAX 991
45
46 #define GIC700_SPI_ID_MIN 32
47 #define GIC700_SPI_ID_MAX 991
48 #define GIC700_ESPI_ID_MIN 4096
49 #define GIC700_ESPI_ID_MAX 5119
50
51 /* Number of retries for PUP update */
52 #define GICD_PUP_UPDATE_RETRIES 10000
53
54 #define SPI_BLOCK_MIN_VALUE(spi_id_min) \
55 (((spi_id_min) - GIC600_SPI_ID_MIN) / \
56 GIC600_SPI_ID_MIN)
57 #define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
58 (((spi_id_max) - (spi_id_min) + 1) / \
59 GIC600_SPI_ID_MIN)
60 #define ESPI_BLOCK_MIN_VALUE(spi_id_min) \
61 (((spi_id_min) - GIC700_ESPI_ID_MIN + 1) / \
62 GIC700_SPI_ID_MIN)
63 #define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
64 (((uint64_t)(chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
65 ((uint64_t)(spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
66 ((uint64_t)(spi_blocks) << GIC_700_SPI_BLOCKS_SHIFT))
67 #define GICD_CHIPR_VALUE_GIC_600(chip_addr, spi_block_min, spi_blocks) \
68 (((uint64_t)(chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
69 ((uint64_t)(spi_block_min) << GIC_600_SPI_BLOCK_MIN_SHIFT) | \
70 ((uint64_t)(spi_blocks) << GIC_600_SPI_BLOCKS_SHIFT))
71
72 /*
73 * Multichip data assertion macros
74 */
75 /* Set bits from 0 to ((spi_id_max + 1) / 32) */
76 #define SPI_BLOCKS_TILL_MAX(spi_id_max) \
77 ((1ULL << (((spi_id_max) + 1) >> 5)) - 1)
78 /* Set bits from 0 to (spi_id_min / 32) */
79 #define SPI_BLOCKS_TILL_MIN(spi_id_min) ((1 << ((spi_id_min) >> 5)) - 1)
80 /* Set bits from (spi_id_min / 32) to ((spi_id_max + 1) / 32) */
81 #define BLOCKS_OF_32(spi_id_min, spi_id_max) \
82 SPI_BLOCKS_TILL_MAX(spi_id_max) ^ \
83 SPI_BLOCKS_TILL_MIN(spi_id_min)
84
85 /*******************************************************************************
86 * GIC-600 multichip operation related helper functions
87 ******************************************************************************/
read_gicd_dchipr(uintptr_t base)88 static inline uint32_t read_gicd_dchipr(uintptr_t base)
89 {
90 return mmio_read_32(base + GICD_DCHIPR);
91 }
92
read_gicd_chipr_n(uintptr_t base,uint8_t n)93 static inline uint64_t read_gicd_chipr_n(uintptr_t base, uint8_t n)
94 {
95 return mmio_read_64(base + (GICD_CHIPR + (8U * n)));
96 }
97
read_gicd_chipsr(uintptr_t base)98 static inline uint32_t read_gicd_chipsr(uintptr_t base)
99 {
100 return mmio_read_32(base + GICD_CHIPSR);
101 }
102
read_gicd_cfgid(uintptr_t base)103 static inline uint64_t read_gicd_cfgid(uintptr_t base)
104 {
105 return mmio_read_64(base + GICD_CFGID);
106 }
107
write_gicd_dchipr(uintptr_t base,uint32_t val)108 static inline void write_gicd_dchipr(uintptr_t base, uint32_t val)
109 {
110 mmio_write_32(base + GICD_DCHIPR, val);
111 }
112
write_gicd_chipr_n(uintptr_t base,uint8_t n,uint64_t val)113 static inline void write_gicd_chipr_n(uintptr_t base, uint8_t n, uint64_t val)
114 {
115 mmio_write_64(base + (GICD_CHIPR + (8U * n)), val);
116 }
117
118 #endif /* GIC600_MULTICHIP_PRIVATE_H */
119