drm/amd/display: Change the DMCUB mailbox memory location from FB to inbox
authorjsg <jsg@openbsd.org>
Thu, 30 Nov 2023 03:07:48 +0000 (03:07 +0000)
committerjsg <jsg@openbsd.org>
Thu, 30 Nov 2023 03:07:48 +0000 (03:07 +0000)
From Lewis Huang
4c55be0855344187d0970874b6e1215b21a68b61 in linux-6.1.y/6.1.64
5911d02cac70d7fb52009fbd37423e63f8f6f9bc in mainline linux

sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c
sys/dev/pci/drm/amd/display/dmub/dmub_srv.h
sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c

index 2d67815..4074c1c 100644 (file)
@@ -2059,7 +2059,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
        struct dmub_srv_create_params create_params;
        struct dmub_srv_region_params region_params;
        struct dmub_srv_region_info region_info;
-       struct dmub_srv_fb_params fb_params;
+       struct dmub_srv_memory_params memory_params;
        struct dmub_srv_fb_info *fb_info;
        struct dmub_srv *dmub_srv;
        const struct dmcub_firmware_header_v1_0 *hdr;
@@ -2190,6 +2190,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
                adev->dm.dmub_fw->data +
                le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
                PSP_HEADER_BYTES;
+       region_params.is_mailbox_in_inbox = false;
 
        status = dmub_srv_calc_region_info(dmub_srv, &region_params,
                                           &region_info);
@@ -2211,10 +2212,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
                return r;
 
        /* Rebase the regions on the framebuffer address. */
-       memset(&fb_params, 0, sizeof(fb_params));
-       fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr;
-       fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr;
-       fb_params.region_info = &region_info;
+       memset(&memory_params, 0, sizeof(memory_params));
+       memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
+       memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
+       memory_params.region_info = &region_info;
 
        adev->dm.dmub_fb_info =
                kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
@@ -2226,7 +2227,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
                return -ENOMEM;
        }
 
-       status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info);
+       status = dmub_srv_calc_mem_info(dmub_srv, &memory_params, fb_info);
        if (status != DMUB_STATUS_OK) {
                DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
                return -EINVAL;
index 5f17b25..a21fe7b 100644 (file)
@@ -174,6 +174,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;
 };
 
 /**
@@ -193,20 +194,25 @@ struct dmub_srv_region_params {
  */
 struct dmub_srv_region_info {
        uint32_t fb_size;
+       uint32_t inbox_size;
        uint8_t num_regions;
        struct dmub_region regions[DMUB_WINDOW_TOTAL];
 };
 
 /**
- * struct dmub_srv_fb_params - parameters used for driver fb setup
+ * struct dmub_srv_memory_params - parameters used for driver fb setup
  * @region_info: region info calculated by dmub service
- * @cpu_addr: base cpu address for the framebuffer
- * @gpu_addr: base gpu virtual address for the framebuffer
+ * @cpu_fb_addr: base cpu address for the framebuffer
+ * @cpu_inbox_addr: base cpu address for the gart
+ * @gpu_fb_addr: base gpu virtual address for the framebuffer
+ * @gpu_inbox_addr: base gpu virtual address for the gart
  */
-struct dmub_srv_fb_params {
+struct dmub_srv_memory_params {
        const struct dmub_srv_region_info *region_info;
-       void *cpu_addr;
-       uint64_t gpu_addr;
+       void *cpu_fb_addr;
+       void *cpu_inbox_addr;
+       uint64_t gpu_fb_addr;
+       uint64_t gpu_inbox_addr;
 };
 
 /**
@@ -524,8 +530,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
  *   DMUB_STATUS_OK - success
  *   DMUB_STATUS_INVALID - unspecified error
  */
-enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
-                                      const struct dmub_srv_fb_params *params,
+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);
 
 /**
index 0dab22d..c332787 100644 (file)
@@ -384,7 +384,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
        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;
        if (!dmub->sw_init)
                return DMUB_STATUS_INVALID;
 
@@ -409,8 +409,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
        bios->base = dmub_align(stack->top, 256);
        bios->top = bios->base + params->vbios_size;
 
-       mail->base = dmub_align(bios->top, 256);
-       mail->top = mail->base + DMUB_MAILBOX_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);
 
@@ -429,7 +436,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
                        dmub->fw_version = fw_info->fw_version;
        }
 
-       trace_buff->base = dmub_align(mail->top, 256);
+       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);
@@ -440,11 +447,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
 
        out->fb_size = dmub_align(scratch_mem->top, 4096);
 
+       if (params->is_mailbox_in_inbox)
+               out->inbox_size = dmub_align(mail->top, 4096);
+
        return DMUB_STATUS_OK;
 }
 
-enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
-                                      const struct dmub_srv_fb_params *params,
+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;
@@ -459,8 +469,8 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
        if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
                return DMUB_STATUS_INVALID;
 
-       cpu_base = (uint8_t *)params->cpu_addr;
-       gpu_base = params->gpu_addr;
+       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 =
@@ -468,6 +478,12 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
 
                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;
+               }
+
                out->fb[i].size = reg->top - reg->base;
        }