xref: /freebsd/sys/dev/amdsmu/amdsmu.h (revision 9c77fb6aaa366cbabc80ee1b834bcfe4df135491)
1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2025 The FreeBSD Foundation
5  *
6  * This software was developed by Aymeric Wibo <obiwac@freebsd.org>
7  * under sponsorship from the FreeBSD Foundation.
8  */
9 
10 #ifndef _AMDSMU_H_
11 #define	_AMDSMU_H_
12 
13 #include <sys/param.h>
14 #include <sys/bus.h>
15 #include <sys/eventhandler.h>
16 #include <sys/kernel.h>
17 
18 #include <machine/cpu.h>
19 #include <machine/md_var.h>
20 #include <machine/cputypes.h>
21 #include <machine/specialreg.h>
22 #include <x86/cputypes.h>
23 
24 #include <dev/amdsmu/amdsmu_reg.h>
25 
26 #define SMU_RES_READ_PERIOD_US	50
27 #define SMU_RES_READ_MAX	20000
28 
29 static const char *amdsmu_ip_blocks_names[] = {
30     "DISPLAY",
31     "CPU",
32     "GFX",
33     "VDD",
34     "ACP",
35     "VCN",
36     "ISP",
37     "NBIO",
38     "DF",
39     "USB3_0",
40     "USB3_1",
41     "LAPIC",
42     "USB3_2",
43     "USB3_3",
44     "USB3_4",
45     "USB4_0",
46     "USB4_1",
47     "MPM",
48     "JPEG",
49     "IPU",
50     "UMSCH",
51     "VPE",
52 };
53 
54 static const char *amdsmu_ip_blocks_names_v2[] = {
55     "DISPLAY",
56     "CPU",
57     "GFX",
58     "VDD",
59     "VDD_CCX",
60     "ACP",
61     "VCN_0",
62     "VCN_1",
63     "ISP",
64     "NBIO",
65     "DF",
66     "USB3_0",
67     "USB3_1",
68     "LAPIC",
69     "USB3_2",
70     "USB4_RT0",
71     "USB4_RT1",
72     "USB4_0",
73     "USB4_1",
74     "MPM",
75     "JPEG_0",
76     "JPEG_1",
77     "IPU",
78     "UMSCH",
79     "VPE",
80 };
81 
82 #define IP_MAX_BLOCK_NAMES	32
83 
84 CTASSERT(nitems(amdsmu_ip_blocks_names) <= IP_MAX_BLOCK_NAMES);
85 CTASSERT(nitems(amdsmu_ip_blocks_names_v2) <= IP_MAX_BLOCK_NAMES);
86 
87 static const struct amdsmu_product {
88 	uint16_t	amdsmu_vendorid;
89 	uint16_t	amdsmu_deviceid;
90 	uint32_t	model;
91 	int16_t		idlemask_reg;
92 	size_t		ip_block_count;
93 	const char 	**ip_blocks_names;
94 	uint32_t	amdsmu_msg;
95 } amdsmu_products[] = {
96 	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_CEZANNE_ROOT, 0x00,
97 	    SMU_REG_IDLEMASK_CEZANNE,	12 , amdsmu_ip_blocks_names,
98 	    SMU_REG_MSG_CEZANNE},
99 	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_REMBRANDT_ROOT, 0x00,
100 	    SMU_REG_IDLEMASK_PHOENIX,	12 , amdsmu_ip_blocks_names,
101 	    SMU_REG_MSG_CEZANNE},
102 	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_PHOENIX_ROOT, 0x00,
103 	    SMU_REG_IDLEMASK_PHOENIX,	21 , amdsmu_ip_blocks_names,
104 	    SMU_REG_MSG_CEZANNE},
105 	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_KRACKAN_POINT_ROOT, 0x00,
106 	    SMU_REG_IDLEMASK_KRACKAN,	22, amdsmu_ip_blocks_names,
107 	    SMU_REG_MSG_KRACKAN },
108 	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_KRACKAN_POINT_ROOT, 0x70,
109 	    SMU_REG_IDLEMASK_KRACKAN,	25, amdsmu_ip_blocks_names_v2,
110 	    SMU_REG_MSG_KRACKAN },
111 	/*
112 	 * XXX Strix Point (PCI_DEVICEID_AMD_STRIX_POINT_ROOT) doesn't support
113 	 * S0i3 and thus doesn't have an idlemask.  Since our driver doesn't
114 	 * yet understand this, don't attach to Strix Point for the time being.
115 	 */
116 };
117 
118 struct amdsmu_softc {
119 	const struct amdsmu_product	*product;
120 
121 	struct sysctl_ctx_list	*sysctlctx;
122 	struct sysctl_oid	*sysctlnode;
123 
124 	struct eventhandler_entry	*eh_suspend;
125 	struct eventhandler_entry	*eh_resume;
126 
127 	struct resource		*res;
128 	bus_space_tag_t 	bus_tag;
129 
130 	bus_space_handle_t	smu_space;
131 	bus_space_handle_t	reg_space;
132 
133 	uint8_t			smu_program;
134 	uint8_t			smu_maj, smu_min, smu_rev;
135 
136 	uint32_t		active_ip_blocks;
137 	struct sysctl_oid	*ip_blocks_sysctlnode;
138 	struct sysctl_oid	*ip_block_sysctlnodes[IP_MAX_BLOCK_NAMES];
139 	bool			ip_blocks_active[IP_MAX_BLOCK_NAMES];
140 
141 	bus_space_handle_t	metrics_space;
142 	struct amdsmu_metrics	metrics;
143 	uint32_t		idlemask;
144 	uint32_t		smu_msg;
145 };
146 
147 static inline uint32_t
amdsmu_read4(const struct amdsmu_softc * sc,bus_size_t reg)148 amdsmu_read4(const struct amdsmu_softc *sc, bus_size_t reg)
149 {
150 	return (bus_space_read_4(sc->bus_tag, sc->reg_space, reg));
151 }
152 
153 static inline void
amdsmu_write4(const struct amdsmu_softc * sc,bus_size_t reg,uint32_t val)154 amdsmu_write4(const struct amdsmu_softc *sc, bus_size_t reg, uint32_t val)
155 {
156 	bus_space_write_4(sc->bus_tag, sc->reg_space, reg, val);
157 }
158 
159 #endif /* _AMDSMU_H_ */
160