diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 145 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 129 |
16 files changed, 294 insertions, 105 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index c78c9224ab..7785908a66 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -78,6 +78,12 @@ struct dmub_srv_dcn31_regs; struct dmcub_trace_buf_entry; +/* enum dmub_window_memory_type - memory location type specification for windows */ +enum dmub_window_memory_type { + DMUB_WINDOW_MEMORY_TYPE_FB = 0, + DMUB_WINDOW_MEMORY_TYPE_GART +}; + /* enum dmub_status - return code for dmcub functions */ enum dmub_status { DMUB_STATUS_OK = 0, @@ -106,6 +112,7 @@ enum dmub_asic { DMUB_ASIC_DCN32, DMUB_ASIC_DCN321, DMUB_ASIC_DCN35, + DMUB_ASIC_DCN351, DMUB_ASIC_MAX, }; @@ -119,6 +126,7 @@ enum dmub_window_id { DMUB_WINDOW_5_TRACEBUFF, DMUB_WINDOW_6_FW_STATE, DMUB_WINDOW_7_SCRATCH_MEM, + DMUB_WINDOW_SHARED_STATE, DMUB_WINDOW_TOTAL, }; @@ -203,7 +211,7 @@ struct dmub_srv_region_params { uint32_t vbios_size; const uint8_t *fw_inst_const; const uint8_t *fw_bss_data; - bool is_mailbox_in_inbox; + const enum dmub_window_memory_type *window_memory_type; }; /** @@ -223,7 +231,7 @@ struct dmub_srv_region_params { */ struct dmub_srv_region_info { uint32_t fb_size; - uint32_t inbox_size; + uint32_t gart_size; uint8_t num_regions; struct dmub_region regions[DMUB_WINDOW_TOTAL]; }; @@ -239,9 +247,10 @@ struct dmub_srv_region_info { struct dmub_srv_memory_params { const struct dmub_srv_region_info *region_info; void *cpu_fb_addr; - void *cpu_inbox_addr; + void *cpu_gart_addr; uint64_t gpu_fb_addr; - uint64_t gpu_inbox_addr; + uint64_t gpu_gart_addr; + const enum dmub_window_memory_type *window_memory_type; }; /** @@ -361,7 +370,8 @@ struct dmub_srv_hw_funcs { const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void (*setup_mailbox)(struct dmub_srv *dmub, const struct dmub_region *inbox1); @@ -443,7 +453,6 @@ struct dmub_srv_create_params { struct dmub_srv_base_funcs funcs; struct dmub_srv_hw_funcs *hw_funcs; void *user_ctx; - struct dc_context *dc_ctx; enum dmub_asic asic; uint32_t fw_version; bool is_virtual; @@ -455,6 +464,7 @@ struct dmub_srv_create_params { * @user_ctx: user provided context for the dmub_srv * @fw_version: the current firmware version, if any * @is_virtual: false if hardware support only + * @shared_state: dmub shared state between firmware and driver * @fw_state: dmub firmware state pointer */ struct dmub_srv { @@ -463,6 +473,7 @@ struct dmub_srv { uint32_t fw_version; bool is_virtual; struct dmub_fb scratch_mem_fb; + volatile struct dmub_shared_state_feature_block *shared_state; volatile const struct dmub_fw_state *fw_state; /* private: internal use only */ diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index bb1f69a54c..af3fe8bb07 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -26,15 +26,6 @@ #ifndef DMUB_CMD_H #define DMUB_CMD_H -#if defined(_TEST_HARNESS) || defined(FPGA_USB4) -#include "dmub_fw_types.h" -#include "include_legacy/atomfirmware.h" - -#if defined(_TEST_HARNESS) -#include <string.h> -#endif -#else - #include <asm/byteorder.h> #include <linux/types.h> #include <linux/string.h> @@ -42,8 +33,6 @@ #include "atomfirmware.h" -#endif // defined(_TEST_HARNESS) || defined(FPGA_USB4) - //<DMUB_TYPES>================================================================== /* Basic type definitions. */ @@ -403,15 +392,16 @@ union replay_debug_flags { /** * 0x400 (bit 10) - * @force_disable_ips1: Force disable IPS1 state + * @enable_ips_visual_confirm: Enable IPS visual confirm when entering IPS + * If we enter IPS2, the Visual confirm bar will change to yellow */ - uint32_t force_disable_ips1 : 1; + uint32_t enable_ips_visual_confirm : 1; /** * 0x800 (bit 11) - * @force_disable_ips2: Force disable IPS2 state + * @enable_ips_residency_profiling: Enable IPS residency profiling */ - uint32_t force_disable_ips2 : 1; + uint32_t enable_ips_residency_profiling : 1; uint32_t reserved : 20; } bitfields; @@ -518,6 +508,8 @@ struct dmub_visual_confirm_color { * @trace_buffer_size: size of the tracebuffer region * @fw_version: the firmware version information * @dal_fw: 1 if the firmware is DAL + * @shared_state_size: size of the shared state region in bytes + * @shared_state_features: number of shared state features */ struct dmub_fw_meta_info { uint32_t magic_value; /**< magic value identifying DMUB firmware meta info */ @@ -526,6 +518,9 @@ struct dmub_fw_meta_info { uint32_t fw_version; /**< the firmware version information */ uint8_t dal_fw; /**< 1 if the firmware is DAL */ uint8_t reserved[3]; /**< padding bits */ + uint32_t shared_state_size; /**< size of the shared state region in bytes */ + uint16_t shared_state_features; /**< number of shared state features */ + uint16_t reserved2; /**< padding bytes */ }; /** @@ -670,6 +665,116 @@ enum dmub_fw_boot_options_bit { }; //============================================================================== +//< DMUB_SHARED_STATE>========================================================== +//============================================================================== + +/** + * Shared firmware state between driver and firmware for lockless communication + * in situations where the inbox/outbox may be unavailable. + * + * Each structure *must* be at most 256-bytes in size. The layout allocation is + * described below: + * + * [Header (256 Bytes)][Feature 1 (256 Bytes)][Feature 2 (256 Bytes)]... + */ + +/** + * enum dmub_shared_state_feature_id - List of shared state features. + */ +enum dmub_shared_state_feature_id { + DMUB_SHARED_SHARE_FEATURE__INVALID = 0, + DMUB_SHARED_SHARE_FEATURE__IPS_FW = 1, + DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER = 2, + DMUB_SHARED_STATE_FEATURE__LAST, /* Total number of features. */ +}; + +/** + * struct dmub_shared_state_ips_fw - Firmware signals for IPS. + */ +union dmub_shared_state_ips_fw_signals { + struct { + uint32_t ips1_commit : 1; /**< 1 if in IPS1 */ + uint32_t ips2_commit : 1; /**< 1 if in IPS2 */ + uint32_t reserved_bits : 30; /**< Reversed */ + } bits; + uint32_t all; +}; + +/** + * struct dmub_shared_state_ips_signals - Firmware signals for IPS. + */ +union dmub_shared_state_ips_driver_signals { + struct { + uint32_t allow_pg : 1; /**< 1 if PG is allowed */ + uint32_t allow_ips1 : 1; /**< 1 is IPS1 is allowed */ + uint32_t allow_ips2 : 1; /**< 1 is IPS1 is allowed */ + uint32_t allow_z10 : 1; /**< 1 if Z10 is allowed */ + uint32_t reserved_bits : 28; /**< Reversed bits */ + } bits; + uint32_t all; +}; + +/** + * IPS FW Version + */ +#define DMUB_SHARED_STATE__IPS_FW_VERSION 1 + +/** + * struct dmub_shared_state_ips_fw - Firmware state for IPS. + */ +struct dmub_shared_state_ips_fw { + union dmub_shared_state_ips_fw_signals signals; /**< 4 bytes, IPS signal bits */ + uint32_t reserved[61]; /**< Reversed, to be updated when adding new fields. */ +}; /* 248-bytes, fixed */ + +/** + * IPS Driver Version + */ +#define DMUB_SHARED_STATE__IPS_DRIVER_VERSION 1 + +/** + * struct dmub_shared_state_ips_driver - Driver state for IPS. + */ +struct dmub_shared_state_ips_driver { + union dmub_shared_state_ips_driver_signals signals; /**< 4 bytes, IPS signal bits */ + uint32_t reserved[61]; /**< Reversed, to be updated when adding new fields. */ +}; /* 248-bytes, fixed */ + +/** + * enum dmub_shared_state_feature_common - Generic payload. + */ +struct dmub_shared_state_feature_common { + uint32_t padding[62]; +}; /* 248-bytes, fixed */ + +/** + * enum dmub_shared_state_feature_header - Feature description. + */ +struct dmub_shared_state_feature_header { + uint16_t id; /**< Feature ID */ + uint16_t version; /**< Feature version */ + uint32_t reserved; /**< Reserved bytes. */ +}; /* 8 bytes, fixed */ + +/** + * struct dmub_shared_state_feature_block - Feature block. + */ +struct dmub_shared_state_feature_block { + struct dmub_shared_state_feature_header header; /**< Shared state header. */ + union dmub_shared_feature_state_union { + struct dmub_shared_state_feature_common common; /**< Generic data */ + struct dmub_shared_state_ips_fw ips_fw; /**< IPS firmware state */ + struct dmub_shared_state_ips_driver ips_driver; /**< IPS driver state */ + } data; /**< Shared state data. */ +}; /* 256-bytes, fixed */ + +/** + * Shared state size in bytes. + */ +#define DMUB_FW_HEADER_SHARED_STATE_SIZE \ + ((DMUB_SHARED_STATE_FEATURE__LAST + 1) * sizeof(struct dmub_shared_state_feature_block)) + +//============================================================================== //</DMUB_STATUS>================================================================ //============================================================================== //< DMUB_VBIOS>================================================================= @@ -1270,11 +1375,11 @@ struct dmub_cmd_PLAT_54186_wa { uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; /**< reg value */ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; /**< reg value */ struct { - uint8_t hubp_inst : 4; /**< HUBP instance */ - uint8_t tmz_surface : 1; /**< TMZ enable or disable */ - uint8_t immediate :1; /**< Immediate flip */ - uint8_t vmid : 4; /**< VMID */ - uint8_t grph_stereo : 1; /**< 1 if stereo */ + uint32_t hubp_inst : 4; /**< HUBP instance */ + uint32_t tmz_surface : 1; /**< TMZ enable or disable */ + uint32_t immediate :1; /**< Immediate flip */ + uint32_t vmid : 4; /**< VMID */ + uint32_t grph_stereo : 1; /**< 1 if stereo */ uint32_t reserved : 21; /**< Reserved */ } flip_params; /**< Pageflip parameters */ uint32_t reserved[9]; /**< Reserved bits */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/Makefile b/drivers/gpu/drm/amd/display/dmub/src/Makefile index 08aaf84aff..50a98448e2 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/Makefile +++ b/drivers/gpu/drm/amd/display/dmub/src/Makefile @@ -25,6 +25,7 @@ DMUB += dmub_dcn30.o dmub_dcn301.o dmub_dcn302.o dmub_dcn303.o DMUB += dmub_dcn31.o dmub_dcn314.o dmub_dcn315.o dmub_dcn316.o DMUB += dmub_dcn32.o DMUB += dmub_dcn35.o +DMUB += dmub_dcn351.o AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB)) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index 98dad0d47e..cae96fba63 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -191,7 +191,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; uint64_t fb_base, fb_offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index 1df128e57e..de287b1018 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -197,7 +197,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c index 81dae75e9f..a4abe951c8 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c @@ -124,7 +124,8 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h index 9a3afffd9b..066f35a500 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h @@ -43,7 +43,8 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); #endif /* _DMUB_DCN30_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 094e9f8645..2bcf5fb87d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -187,7 +187,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index 4d520a893c..eccdab4986 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -199,7 +199,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index 2daa1e0c80..0d521eeda0 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -32,8 +32,6 @@ #include "dcn/dcn_3_2_0_offset.h" #include "dcn/dcn_3_2_0_sh_mask.h" -#define DCN_BASE__INST0_SEG2 0x000034C0 - #define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] #define CTX dmub #define REGS dmub->regs_dcn32 @@ -218,7 +216,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h index b0cd8d2940..29c1132951 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h @@ -206,7 +206,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c index 6d1fbea0f6..53f359f3fa 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -229,7 +229,8 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; @@ -275,6 +276,15 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, DMCUB_REGION3_CW6_ENABLE, 1); + + offset = region6->offset; + + REG_WRITE(DMCUB_REGION6_OFFSET, offset.u.low_part); + REG_WRITE(DMCUB_REGION6_OFFSET_HIGH, offset.u.high_part); + REG_SET_2(DMCUB_REGION6_TOP_ADDRESS, 0, + DMCUB_REGION6_TOP_ADDRESS, + region6->region.top - region6->region.base - 1, + DMCUB_REGION6_ENABLE, 1); } void dmub_dcn35_setup_mailbox(struct dmub_srv *dmub, @@ -545,8 +555,14 @@ uint32_t dmub_dcn35_read_inbox0_ack_register(struct dmub_srv *dmub) bool dmub_dcn35_is_hw_powered_up(struct dmub_srv *dmub) { union dmub_fw_boot_status status; + uint32_t is_enable; + + REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enable); + if (is_enable == 0) + return false; status.all = REG_READ(DMCUB_SCRATCH0); - return status.bits.hw_power_init_done; + return (status.bits.dal_fw && status.bits.hw_power_init_done && status.bits.mailbox_rdy) || + (!status.bits.dal_fw && status.bits.mailbox_rdy); } diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h index 129a7031d2..686e97c00c 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h @@ -89,6 +89,9 @@ struct dmub_srv; DMUB_SR(DMCUB_REGION5_OFFSET) \ DMUB_SR(DMCUB_REGION5_OFFSET_HIGH) \ DMUB_SR(DMCUB_REGION5_TOP_ADDRESS) \ + DMUB_SR(DMCUB_REGION6_OFFSET) \ + DMUB_SR(DMCUB_REGION6_OFFSET_HIGH) \ + DMUB_SR(DMCUB_REGION6_TOP_ADDRESS) \ DMUB_SR(DMCUB_SCRATCH0) \ DMUB_SR(DMCUB_SCRATCH1) \ DMUB_SR(DMCUB_SCRATCH2) \ @@ -154,6 +157,8 @@ struct dmub_srv; DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \ + DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_TOP_ADDRESS) \ + DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_ENABLE) \ DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \ DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \ DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \ @@ -214,7 +219,8 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn35_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.c new file mode 100644 index 0000000000..8f40b9f670 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2024 Advanced Micro Devices, Inc. */ + +#include "../dmub_srv.h" +#include "dmub_reg.h" +#include "dmub_dcn351.h" + +#include "dcn/dcn_3_5_1_offset.h" +#include "dcn/dcn_3_5_1_sh_mask.h" + +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] +#define CTX dmub +#define REGS dmub->regs_dcn35 +#define REG_OFFSET_EXP(reg_name) BASE(reg##reg_name##_BASE_IDX) + reg##reg_name + +void dmub_srv_dcn351_regs_init(struct dmub_srv *dmub, struct dc_context *ctx) +{ + struct dmub_srv_dcn35_regs *regs = dmub->regs_dcn35; +#define REG_STRUCT regs + +#define DMUB_SR(reg) REG_STRUCT->offset.reg = REG_OFFSET_EXP(reg); + DMUB_DCN35_REGS() + DMCUB_INTERNAL_REGS() +#undef DMUB_SR + +#define DMUB_SF(reg, field) REG_STRUCT->mask.reg##__##field = FD_MASK(reg, field); + DMUB_DCN35_FIELDS() +#undef DMUB_SF + +#define DMUB_SF(reg, field) REG_STRUCT->shift.reg##__##field = FD_SHIFT(reg, field); + DMUB_DCN35_FIELDS() +#undef DMUB_SF +#undef REG_STRUCT +} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.h new file mode 100644 index 0000000000..4121fa1b30 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn351.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2024 Advanced Micro Devices, Inc. */ + +#ifndef _DMUB_DCN351_H_ +#define _DMUB_DCN351_H_ + +#include "dmub_dcn35.h" + +struct dmub_srv; + +void dmub_srv_dcn351_regs_init(struct dmub_srv *dmub, struct dc_context *ctx); + +#endif /* _DMUB_DCN351_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 9ad7388053..90e878195d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -37,6 +37,7 @@ #include "dmub_dcn316.h" #include "dmub_dcn32.h" #include "dmub_dcn35.h" +#include "dmub_dcn351.h" #include "os_types.h" /* * Note: the DMUB service is standalone. No additional headers should be @@ -78,6 +79,7 @@ #define DMUB_CW6_BASE (0x66000000) #define DMUB_REGION5_BASE (0xA0000000) +#define DMUB_REGION6_BASE (0xC0000000) static struct dmub_srv_dcn32_regs dmub_srv_dcn32_regs; static struct dmub_srv_dcn35_regs dmub_srv_dcn35_regs; @@ -314,6 +316,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) break; case DMUB_ASIC_DCN35: + case DMUB_ASIC_DCN351: dmub->regs_dcn35 = &dmub_srv_dcn35_regs; funcs->configure_dmub_in_system_memory = dmub_dcn35_configure_dmub_in_system_memory; funcs->send_inbox0_cmd = dmub_dcn35_send_inbox0_cmd; @@ -350,6 +353,8 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->get_diagnostic_data = dmub_dcn35_get_diagnostic_data; funcs->init_reg_offsets = dmub_srv_dcn35_regs_init; + if (asic == DMUB_ASIC_DCN351) + funcs->init_reg_offsets = dmub_srv_dcn351_regs_init; funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up; funcs->should_detect = dmub_dcn35_should_detect; @@ -417,58 +422,44 @@ void dmub_srv_destroy(struct dmub_srv *dmub) dmub_memset(dmub, 0, sizeof(*dmub)); } +static uint32_t dmub_srv_calc_regions_for_memory_type(const struct dmub_srv_region_params *params, + struct dmub_srv_region_info *out, + const uint32_t *window_sizes, + enum dmub_window_memory_type memory_type) +{ + uint32_t i, top = 0; + + for (i = 0; i < DMUB_WINDOW_TOTAL; ++i) { + if (params->window_memory_type[i] == memory_type) { + struct dmub_region *region = &out->regions[i]; + + region->base = dmub_align(top, 256); + region->top = region->base + dmub_align(window_sizes[i], 64); + top = region->top; + } + } + + return dmub_align(top, 4096); +} + enum dmub_status -dmub_srv_calc_region_info(struct dmub_srv *dmub, - const struct dmub_srv_region_params *params, - struct dmub_srv_region_info *out) + dmub_srv_calc_region_info(struct dmub_srv *dmub, + const struct dmub_srv_region_params *params, + struct dmub_srv_region_info *out) { - struct dmub_region *inst = &out->regions[DMUB_WINDOW_0_INST_CONST]; - struct dmub_region *stack = &out->regions[DMUB_WINDOW_1_STACK]; - struct dmub_region *data = &out->regions[DMUB_WINDOW_2_BSS_DATA]; - struct dmub_region *bios = &out->regions[DMUB_WINDOW_3_VBIOS]; - struct dmub_region *mail = &out->regions[DMUB_WINDOW_4_MAILBOX]; - struct dmub_region *trace_buff = &out->regions[DMUB_WINDOW_5_TRACEBUFF]; - struct dmub_region *fw_state = &out->regions[DMUB_WINDOW_6_FW_STATE]; - struct dmub_region *scratch_mem = &out->regions[DMUB_WINDOW_7_SCRATCH_MEM]; const struct dmub_fw_meta_info *fw_info; uint32_t fw_state_size = DMUB_FW_STATE_SIZE; uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE; - uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE; - uint32_t previous_top = 0; + uint32_t window_sizes[DMUB_WINDOW_TOTAL] = { 0 }; + if (!dmub->sw_init) return DMUB_STATUS_INVALID; memset(out, 0, sizeof(*out)); + memset(window_sizes, 0, sizeof(window_sizes)); out->num_regions = DMUB_NUM_WINDOWS; - inst->base = 0x0; - inst->top = inst->base + params->inst_const_size; - - data->base = dmub_align(inst->top, 256); - data->top = data->base + params->bss_data_size; - - /* - * All cache windows below should be aligned to the size - * of the DMCUB cache line, 64 bytes. - */ - - stack->base = dmub_align(data->top, 256); - stack->top = stack->base + DMUB_STACK_SIZE + DMUB_CONTEXT_SIZE; - - bios->base = dmub_align(stack->top, 256); - bios->top = bios->base + params->vbios_size; - - if (params->is_mailbox_in_inbox) { - mail->base = 0; - mail->top = mail->base + DMUB_MAILBOX_SIZE; - previous_top = bios->top; - } else { - mail->base = dmub_align(bios->top, 256); - mail->top = mail->base + DMUB_MAILBOX_SIZE; - previous_top = mail->top; - } - fw_info = dmub_get_fw_meta_info(params); if (fw_info) { @@ -486,19 +477,21 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, dmub->fw_version = fw_info->fw_version; } - trace_buff->base = dmub_align(previous_top, 256); - trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64); - - fw_state->base = dmub_align(trace_buff->top, 256); - fw_state->top = fw_state->base + dmub_align(fw_state_size, 64); + window_sizes[DMUB_WINDOW_0_INST_CONST] = params->inst_const_size; + window_sizes[DMUB_WINDOW_1_STACK] = DMUB_STACK_SIZE + DMUB_CONTEXT_SIZE; + window_sizes[DMUB_WINDOW_2_BSS_DATA] = params->bss_data_size; + window_sizes[DMUB_WINDOW_3_VBIOS] = params->vbios_size; + window_sizes[DMUB_WINDOW_4_MAILBOX] = DMUB_MAILBOX_SIZE; + window_sizes[DMUB_WINDOW_5_TRACEBUFF] = trace_buffer_size; + window_sizes[DMUB_WINDOW_6_FW_STATE] = fw_state_size; + window_sizes[DMUB_WINDOW_7_SCRATCH_MEM] = DMUB_SCRATCH_MEM_SIZE; + window_sizes[DMUB_WINDOW_SHARED_STATE] = DMUB_FW_HEADER_SHARED_STATE_SIZE; - scratch_mem->base = dmub_align(fw_state->top, 256); - scratch_mem->top = scratch_mem->base + dmub_align(scratch_mem_size, 64); + out->fb_size = + dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_FB); - out->fb_size = dmub_align(scratch_mem->top, 4096); - - if (params->is_mailbox_in_inbox) - out->inbox_size = dmub_align(mail->top, 4096); + out->gart_size = + dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_GART); return DMUB_STATUS_OK; } @@ -507,8 +500,6 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, const struct dmub_srv_memory_params *params, struct dmub_srv_fb_info *out) { - uint8_t *cpu_base; - uint64_t gpu_base; uint32_t i; if (!dmub->sw_init) @@ -519,19 +510,16 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, if (params->region_info->num_regions != DMUB_NUM_WINDOWS) return DMUB_STATUS_INVALID; - cpu_base = (uint8_t *)params->cpu_fb_addr; - gpu_base = params->gpu_fb_addr; - for (i = 0; i < DMUB_NUM_WINDOWS; ++i) { const struct dmub_region *reg = ¶ms->region_info->regions[i]; - out->fb[i].cpu_addr = cpu_base + reg->base; - out->fb[i].gpu_addr = gpu_base + reg->base; - - if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) { - out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base; - out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base; + if (params->window_memory_type[i] == DMUB_WINDOW_MEMORY_TYPE_GART) { + out->fb[i].cpu_addr = (uint8_t *)params->cpu_gart_addr + reg->base; + out->fb[i].gpu_addr = params->gpu_gart_addr + reg->base; + } else { + out->fb[i].cpu_addr = (uint8_t *)params->cpu_fb_addr + reg->base; + out->fb[i].gpu_addr = params->gpu_fb_addr + reg->base; } out->fb[i].size = reg->top - reg->base; @@ -583,9 +571,10 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, struct dmub_fb *tracebuff_fb = params->fb[DMUB_WINDOW_5_TRACEBUFF]; struct dmub_fb *fw_state_fb = params->fb[DMUB_WINDOW_6_FW_STATE]; struct dmub_fb *scratch_mem_fb = params->fb[DMUB_WINDOW_7_SCRATCH_MEM]; + struct dmub_fb *shared_state_fb = params->fb[DMUB_WINDOW_SHARED_STATE]; struct dmub_rb_init_params rb_params, outbox0_rb_params; - struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6; + struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6, region6; struct dmub_region inbox1, outbox1, outbox0; if (!dmub->sw_init) @@ -670,10 +659,16 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, dmub->fw_state = fw_state_fb->cpu_addr; + region6.offset.quad_part = shared_state_fb->gpu_addr; + region6.region.base = DMUB_CW6_BASE; + region6.region.top = region6.region.base + shared_state_fb->size; + + dmub->shared_state = shared_state_fb->cpu_addr; + dmub->scratch_mem_fb = *scratch_mem_fb; if (dmub->hw_funcs.setup_windows) - dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5, &cw6); + dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5, &cw6, ®ion6); if (dmub->hw_funcs.setup_outbox0) dmub->hw_funcs.setup_outbox0(dmub, &outbox0); @@ -812,8 +807,10 @@ bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub) if (!dmub->hw_funcs.is_hw_powered_up) return true; - return dmub->hw_funcs.is_hw_powered_up(dmub) && - dmub->hw_funcs.is_hw_init(dmub); + if (!dmub->hw_funcs.is_hw_powered_up(dmub)) + return false; + + return true; } enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub, |