1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* Copyright 2021 Alyssa Rosenzweig <alyssa@rosenzweig.io> */ 3 4 #ifndef __APPLE_DCPEP_H__ 5 #define __APPLE_DCPEP_H__ 6 7 #include <linux/types.h> 8 9 #include "version_utils.h" 10 11 /* Fixed size of shared memory between DCP and AP */ 12 #define DCP_SHMEM_SIZE 0x100000 13 14 /* DCP message contexts */ 15 enum dcp_context_id { 16 /* Callback */ 17 DCP_CONTEXT_CB = 0, 18 19 /* Command */ 20 DCP_CONTEXT_CMD = 2, 21 22 /* Asynchronous */ 23 DCP_CONTEXT_ASYNC = 3, 24 25 /* Out-of-band callback */ 26 DCP_CONTEXT_OOBCB = 4, 27 28 /* Out-of-band command */ 29 DCP_CONTEXT_OOBCMD = 6, 30 31 /* Out-of-band Asynchronous */ 32 DCP_CONTEXT_OOBASYNC = 7, 33 34 DCP_NUM_CONTEXTS 35 }; 36 37 /* RTKit endpoint message types */ 38 enum dcpep_type { 39 /* Set shared memory */ 40 IOMFB_MESSAGE_TYPE_SET_SHMEM = 0, 41 42 /* DCP is initialized */ 43 IOMFB_MESSAGE_TYPE_INITIALIZED = 1, 44 45 /* Remote procedure call */ 46 IOMFB_MESSAGE_TYPE_MSG = 2, 47 }; 48 49 #define IOMFB_MESSAGE_TYPE GENMASK_ULL( 3, 0) 50 51 /* Message */ 52 #define IOMFB_MSG_LENGTH GENMASK_ULL(63, 32) 53 #define IOMFB_MSG_OFFSET GENMASK_ULL(31, 16) 54 #define IOMFB_MSG_CONTEXT GENMASK_ULL(11, 8) 55 #define IOMFB_MSG_ACK BIT_ULL(6) 56 57 /* Set shmem */ 58 #define IOMFB_SHMEM_DVA GENMASK_ULL(63, 16) 59 #define IOMFB_SHMEM_FLAG GENMASK_ULL( 7, 4) 60 #define IOMFB_SHMEM_FLAG_VALUE 4 61 62 struct dcp_packet_header { 63 char tag[4]; 64 u32 in_len; 65 u32 out_len; 66 } __packed; 67 68 #define DCP_IS_NULL(ptr) ((ptr) ? 1 : 0) 69 #define DCP_PACKET_ALIGNMENT (0x40) 70 71 enum iomfb_property_id { 72 IOMFB_PROPERTY_NITS = 15, // divide by Brightness_Scale 73 }; 74 75 #define IOMFB_BRIGHTNESS_MIN 0x10000000 76 77 /* Structures used in v12.0 firmware */ 78 79 #define SWAP_SURFACES 4 80 #define MAX_PLANES 3 81 82 enum dcp_colorspace { 83 DCP_COLORSPACE_BG_SRGB = 0, 84 DCP_COLORSPACE_BG_BT2020 = 9, 85 DCP_COLORSPACE_NATIVE = 12, 86 }; 87 88 enum dcp_xfer_func { 89 DCP_XFER_FUNC_SDR = 13, 90 DCP_XFER_FUNC_HDR = 16, 91 }; 92 93 struct dcp_iouserclient { 94 /* Handle for the IOUserClient. macOS sets this to a kernel VA. */ 95 u64 handle; 96 u32 unk; 97 u8 flag1; 98 u8 flag2; 99 u8 padding[2]; 100 } __packed; 101 102 struct dcp_rect { 103 u32 x; 104 u32 y; 105 u32 w; 106 u32 h; 107 } __packed; 108 109 /* 110 * Update background color to struct dcp_swap.bg_color 111 */ 112 #define IOMFB_SET_BACKGROUND BIT(31) 113 114 /* Information describing a plane of a planar compressed surface */ 115 struct dcp_plane_info { 116 u32 width; 117 u32 height; 118 u32 base; 119 u32 offset; 120 u32 stride; 121 u32 size; 122 u16 tile_size; 123 u8 tile_w; 124 u8 tile_h; 125 u32 unk[13]; 126 } __packed; 127 128 struct dcp_component_types { 129 u8 count; 130 u8 types[7]; 131 } __packed; 132 133 struct dcp_allocate_bandwidth_req { 134 u64 unk1; 135 u64 unk2; 136 u64 unk3; 137 u8 unk1_null; 138 u8 unk2_null; 139 u8 padding[8]; 140 } __packed; 141 142 struct dcp_allocate_bandwidth_resp { 143 u64 unk1; 144 u64 unk2; 145 u32 ret; 146 } __packed; 147 148 struct dcp_rt_bandwidth { 149 u64 unk1; 150 u64 reg_scratch; 151 u64 reg_doorbell; 152 u32 unk2; 153 u32 doorbell_bit; 154 u32 padding[7]; 155 } __packed; 156 157 struct frame_sync_props { 158 u8 unk[28]; 159 }; 160 161 struct dcp_set_frame_sync_props_req { 162 struct frame_sync_props props; 163 u8 frame_sync_props_null; 164 u8 padding[3]; 165 } __packed; 166 167 struct dcp_set_frame_sync_props_resp { 168 struct frame_sync_props props; 169 } __packed; 170 171 /* Method calls */ 172 173 enum dcpep_method { 174 dcpep_late_init_signal, 175 dcpep_setup_video_limits, 176 dcpep_set_create_dfb, 177 dcpep_start_signal, 178 dcpep_swap_start, 179 dcpep_swap_submit, 180 dcpep_set_display_device, 181 dcpep_set_digital_out_mode, 182 dcpep_create_default_fb, 183 dcpep_set_display_refresh_properties, 184 dcpep_flush_supports_power, 185 dcpep_set_power_state, 186 dcpep_first_client_open, 187 dcpep_set_parameter_dcp, 188 dcpep_enable_disable_video_power_savings, 189 dcpep_is_main_display, 190 iomfbep_a131_pmu_service_matched, 191 iomfbep_a132_backlight_service_matched, 192 iomfbep_a358_vi_set_temperature_hint, 193 iomfbep_get_color_remap_mode, 194 iomfbep_last_client_close, 195 iomfbep_abort_swaps_dcp, 196 iomfbep_set_matrix, 197 dcpep_num_methods 198 }; 199 200 #define IOMFB_METHOD(tag, name) [name] = { #name, tag } 201 202 struct dcp_method_entry { 203 const char *name; 204 char tag[4]; 205 }; 206 207 #define IOMFB_MAX_CB (1000) 208 struct apple_dcp; 209 210 typedef bool (*iomfb_cb_handler)(struct apple_dcp *, int, void *, void *); 211 212 /* Prototypes */ 213 214 struct dcp_set_digital_out_mode_req { 215 u32 color_mode_id; 216 u32 timing_mode_id; 217 } __packed; 218 219 struct dcp_map_buf_req { 220 u64 buffer; 221 u8 unk; 222 u8 buf_null; 223 u8 vaddr_null; 224 u8 dva_null; 225 } __packed; 226 227 struct dcp_map_buf_resp { 228 u64 vaddr; 229 u64 dva; 230 u32 ret; 231 } __packed; 232 233 struct dcp_unmap_buf_resp { 234 u64 buffer; 235 u64 vaddr; 236 u64 dva; 237 u8 unk; 238 u8 buf_null; 239 } __packed; 240 241 struct dcp_allocate_buffer_req { 242 u32 unk0; 243 u64 size; 244 u32 unk2; 245 u8 paddr_null; 246 u8 dva_null; 247 u8 dva_size_null; 248 u8 padding; 249 } __packed; 250 251 struct dcp_allocate_buffer_resp { 252 u64 paddr; 253 u64 dva; 254 u64 dva_size; 255 u32 mem_desc_id; 256 } __packed; 257 258 struct dcp_map_physical_req { 259 u64 paddr; 260 u64 size; 261 u32 flags; 262 u8 dva_null; 263 u8 dva_size_null; 264 u8 padding[2]; 265 } __packed; 266 267 struct dcp_map_physical_resp { 268 u64 dva; 269 u64 dva_size; 270 u32 mem_desc_id; 271 } __packed; 272 273 struct dcp_swap_start_req { 274 u32 swap_id; 275 struct dcp_iouserclient client; 276 u8 swap_id_null; 277 u8 client_null; 278 u8 padding[2]; 279 } __packed; 280 281 struct dcp_swap_start_resp { 282 u32 swap_id; 283 struct dcp_iouserclient client; 284 u32 ret; 285 } __packed; 286 287 struct dcp_get_uint_prop_req { 288 char obj[4]; 289 char key[0x40]; 290 u64 value; 291 u8 value_null; 292 u8 padding[3]; 293 } __packed; 294 295 struct dcp_get_uint_prop_resp { 296 u64 value; 297 u8 ret; 298 u8 padding[3]; 299 } __packed; 300 301 struct iomfb_sr_set_property_int_req { 302 char obj[4]; 303 char key[0x40]; 304 u64 value; 305 u8 value_null; 306 u8 padding[3]; 307 } __packed; 308 309 struct iomfb_set_fx_prop_req { 310 char obj[4]; 311 char key[0x40]; 312 u32 value; 313 } __packed; 314 315 struct dcp_set_power_state_req { 316 u64 unklong; 317 u8 unkbool; 318 u8 unkint_null; 319 u8 padding[2]; 320 } __packed; 321 322 struct dcp_set_power_state_resp { 323 u32 unkint; 324 u32 ret; 325 } __packed; 326 327 struct dcp_set_dcpav_prop_chunk_req { 328 char data[0x1000]; 329 u32 offset; 330 u32 length; 331 } __packed; 332 333 struct dcp_set_dcpav_prop_end_req { 334 char key[0x40]; 335 } __packed; 336 337 struct dcp_set_parameter_dcp { 338 u32 param; 339 u32 value[8]; 340 u32 count; 341 } __packed; 342 343 struct dcp_swap_complete_intent_gated { 344 u32 swap_id; 345 u8 unkBool; 346 u32 unkInt; 347 u32 width; 348 u32 height; 349 } __packed; 350 351 struct dcp_read_edt_data_req { 352 char key[0x40]; 353 u32 count; 354 u32 value[8]; 355 } __packed; 356 357 struct dcp_read_edt_data_resp { 358 u32 value[8]; 359 u8 ret; 360 } __packed; 361 362 struct iomfb_property { 363 u32 id; 364 u32 value; 365 } __packed; 366 367 struct iomfb_get_color_remap_mode_req { 368 u32 mode; 369 u8 mode_null; 370 u8 padding[3]; 371 } __packed; 372 373 struct iomfb_get_color_remap_mode_resp { 374 u32 mode; 375 u32 ret; 376 } __packed; 377 378 struct iomfb_last_client_close_req { 379 u8 unkint_null; 380 u8 padding[3]; 381 } __packed; 382 383 struct iomfb_last_client_close_resp { 384 u32 unkint; 385 } __packed; 386 387 struct io_user_client { 388 u64 addr; 389 u32 unk; 390 u8 flag1; 391 u8 flag2; 392 u8 pad[2]; 393 } __packed; 394 395 struct iomfb_abort_swaps_dcp_req { 396 struct io_user_client client; 397 u8 client_null; 398 u8 pad[3]; 399 } __packed; 400 401 struct iomfb_abort_swaps_dcp_resp { 402 struct io_user_client client; 403 u32 ret; 404 } __packed; 405 406 struct iomfb_set_matrix_req { 407 u32 unk_u32; // maybe length? 408 u64 r[3]; 409 u64 g[3]; 410 u64 b[3]; 411 u8 matrix_null; 412 u8 padding[3]; 413 } __packed; 414 415 struct iomfb_set_matrix_resp { 416 u32 ret; 417 } __packed; 418 419 struct dcpep_get_tiling_state_req { 420 u32 event; 421 u32 param; 422 u32 value; 423 u8 value_null; 424 u8 padding[3]; 425 } __packed; 426 427 struct dcpep_get_tiling_state_resp { 428 u32 value; 429 u32 ret; 430 } __packed; 431 432 #endif 433