diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atom.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d67c42555ab9..388140a7e651 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -58,6 +58,7 @@ typedef struct { | |||
58 | } atom_exec_context; | 58 | } atom_exec_context; |
59 | 59 | ||
60 | int atom_debug = 0; | 60 | int atom_debug = 0; |
61 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); | ||
61 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); | 62 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); |
62 | 63 | ||
63 | static uint32_t atom_arg_mask[8] = | 64 | static uint32_t atom_arg_mask[8] = |
@@ -263,10 +264,10 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
263 | case ATOM_ARG_FB: | 264 | case ATOM_ARG_FB: |
264 | idx = U8(*ptr); | 265 | idx = U8(*ptr); |
265 | (*ptr)++; | 266 | (*ptr)++; |
267 | val = gctx->scratch[((gctx->fb_base + idx) / 4)]; | ||
266 | if (print) | 268 | if (print) |
267 | DEBUG("FB[0x%02X]", idx); | 269 | DEBUG("FB[0x%02X]", idx); |
268 | printk(KERN_INFO "FB access is not implemented.\n"); | 270 | break; |
269 | return 0; | ||
270 | case ATOM_ARG_IMM: | 271 | case ATOM_ARG_IMM: |
271 | switch (align) { | 272 | switch (align) { |
272 | case ATOM_SRC_DWORD: | 273 | case ATOM_SRC_DWORD: |
@@ -488,9 +489,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
488 | case ATOM_ARG_FB: | 489 | case ATOM_ARG_FB: |
489 | idx = U8(*ptr); | 490 | idx = U8(*ptr); |
490 | (*ptr)++; | 491 | (*ptr)++; |
492 | gctx->scratch[((gctx->fb_base + idx) / 4)] = val; | ||
491 | DEBUG("FB[0x%02X]", idx); | 493 | DEBUG("FB[0x%02X]", idx); |
492 | printk(KERN_INFO "FB access is not implemented.\n"); | 494 | break; |
493 | return; | ||
494 | case ATOM_ARG_PLL: | 495 | case ATOM_ARG_PLL: |
495 | idx = U8(*ptr); | 496 | idx = U8(*ptr); |
496 | (*ptr)++; | 497 | (*ptr)++; |
@@ -573,7 +574,7 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) | |||
573 | else | 574 | else |
574 | SDEBUG(" table: %d\n", idx); | 575 | SDEBUG(" table: %d\n", idx); |
575 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) | 576 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) |
576 | atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift); | 577 | atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); |
577 | } | 578 | } |
578 | 579 | ||
579 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) | 580 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) |
@@ -1040,7 +1041,7 @@ static struct { | |||
1040 | atom_op_shr, ATOM_ARG_MC}, { | 1041 | atom_op_shr, ATOM_ARG_MC}, { |
1041 | atom_op_debug, 0},}; | 1042 | atom_op_debug, 0},}; |
1042 | 1043 | ||
1043 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1044 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) |
1044 | { | 1045 | { |
1045 | int base = CU16(ctx->cmd_table + 4 + 2 * index); | 1046 | int base = CU16(ctx->cmd_table + 4 + 2 * index); |
1046 | int len, ws, ps, ptr; | 1047 | int len, ws, ps, ptr; |
@@ -1092,6 +1093,13 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |||
1092 | kfree(ectx.ws); | 1093 | kfree(ectx.ws); |
1093 | } | 1094 | } |
1094 | 1095 | ||
1096 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | ||
1097 | { | ||
1098 | mutex_lock(&ctx->mutex); | ||
1099 | atom_execute_table_locked(ctx, index, params); | ||
1100 | mutex_unlock(&ctx->mutex); | ||
1101 | } | ||
1102 | |||
1095 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; | 1103 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; |
1096 | 1104 | ||
1097 | static void atom_index_iio(struct atom_context *ctx, int base) | 1105 | static void atom_index_iio(struct atom_context *ctx, int base) |
@@ -1214,3 +1222,28 @@ void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | |||
1214 | *crev = CU8(idx + 3); | 1222 | *crev = CU8(idx + 3); |
1215 | return; | 1223 | return; |
1216 | } | 1224 | } |
1225 | |||
1226 | int atom_allocate_fb_scratch(struct atom_context *ctx) | ||
1227 | { | ||
1228 | int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); | ||
1229 | uint16_t data_offset; | ||
1230 | int usage_bytes; | ||
1231 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; | ||
1232 | |||
1233 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | ||
1234 | |||
1235 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); | ||
1236 | |||
1237 | DRM_DEBUG("atom firmware requested %08x %dkb\n", | ||
1238 | firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, | ||
1239 | firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); | ||
1240 | |||
1241 | usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; | ||
1242 | if (usage_bytes == 0) | ||
1243 | usage_bytes = 20 * 1024; | ||
1244 | /* allocate some scratch memory */ | ||
1245 | ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); | ||
1246 | if (!ctx->scratch) | ||
1247 | return -ENOMEM; | ||
1248 | return 0; | ||
1249 | } | ||