@@ -1320,12 +1320,13 @@ bool atom_parse_data_header(struct atom_context *ctx, int index,
return true;
}
-bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
- uint8_t * crev)
+bool atom_parse_cmd_header_stack(struct atom_context *ctx, int index, uint8_t *frev,
+ uint8_t *crev, uint8_t *ps_size, uint8_t *ws_size)
{
int offset = index * 2 + 4;
int idx = CU16(ctx->cmd_table + offset);
u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
+ u16 table_attrib = CU16(idx + 4);
if (!mct[index])
return false;
@@ -1334,9 +1335,19 @@ bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
*frev = CU8(idx + 2);
if (crev)
*crev = CU8(idx + 3);
+ if (ps_size)
+ *ps_size = (table_attrib & 0xe00) >> 8;
+ if (ws_size)
+ *ws_size = (table_attrib & 0xff);
return true;
}
+bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *rev,
+ uint8_t *crev)
+{
+ return atom_parse_cmd_header_stack(ctx, index, rev, crev, NULL, NULL);
+}
+
int atom_allocate_fb_scratch(struct atom_context *ctx)
{
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
@@ -147,6 +147,8 @@ bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
uint8_t *frev, uint8_t *crev, uint16_t *data_start);
bool atom_parse_cmd_header(struct atom_context *ctx, int index,
uint8_t *frev, uint8_t *crev);
+bool atom_parse_cmd_header_stack(struct atom_context *ctx, int index, uint8_t *rev,
+ uint8_t *crev, uint8_t *ps_size, uint8_t *ws_size);
int atom_allocate_fb_scratch(struct atom_context *ctx);
#include "atom-types.h"
#include "atombios.h"
@@ -1398,12 +1398,19 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
ATOM_DEVICE_CRT_SUPPORT)) {
DAC_LOAD_DETECTION_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
- uint8_t frev, crev;
+ uint8_t frev, crev, ps_size;
memset(&args, 0, sizeof(args));
- if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ if (!atom_parse_cmd_header_stack(rdev->mode_info.atom_context, index, &frev, &crev, &ps_size, NULL))
return false;
+
+ /* r4xx and some early rv5xx probe all DACs, this can cause distrubances in the force,
+ also on other DACs. - we can detect these tables as they have a 0 sized param stack */
+ if (ps_size == 0) {
+ DRM_DEBUG("not executing dac load detection table due to buggy atom table\n");
+ return false;
+ }
args.sDacload.ucMisc = 0;