diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atom.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 102 |
1 files changed, 85 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 388140a7e651..e3b44562d265 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -246,6 +246,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
246 | case ATOM_WS_ATTRIBUTES: | 246 | case ATOM_WS_ATTRIBUTES: |
247 | val = gctx->io_attr; | 247 | val = gctx->io_attr; |
248 | break; | 248 | break; |
249 | case ATOM_WS_REGPTR: | ||
250 | val = gctx->reg_block; | ||
251 | break; | ||
249 | default: | 252 | default: |
250 | val = ctx->ws[idx]; | 253 | val = ctx->ws[idx]; |
251 | } | 254 | } |
@@ -385,6 +388,32 @@ static uint32_t atom_get_src(atom_exec_context *ctx, uint8_t attr, int *ptr) | |||
385 | return atom_get_src_int(ctx, attr, ptr, NULL, 1); | 388 | return atom_get_src_int(ctx, attr, ptr, NULL, 1); |
386 | } | 389 | } |
387 | 390 | ||
391 | static uint32_t atom_get_src_direct(atom_exec_context *ctx, uint8_t align, int *ptr) | ||
392 | { | ||
393 | uint32_t val = 0xCDCDCDCD; | ||
394 | |||
395 | switch (align) { | ||
396 | case ATOM_SRC_DWORD: | ||
397 | val = U32(*ptr); | ||
398 | (*ptr) += 4; | ||
399 | break; | ||
400 | case ATOM_SRC_WORD0: | ||
401 | case ATOM_SRC_WORD8: | ||
402 | case ATOM_SRC_WORD16: | ||
403 | val = U16(*ptr); | ||
404 | (*ptr) += 2; | ||
405 | break; | ||
406 | case ATOM_SRC_BYTE0: | ||
407 | case ATOM_SRC_BYTE8: | ||
408 | case ATOM_SRC_BYTE16: | ||
409 | case ATOM_SRC_BYTE24: | ||
410 | val = U8(*ptr); | ||
411 | (*ptr)++; | ||
412 | break; | ||
413 | } | ||
414 | return val; | ||
415 | } | ||
416 | |||
388 | static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, | 417 | static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, |
389 | int *ptr, uint32_t *saved, int print) | 418 | int *ptr, uint32_t *saved, int print) |
390 | { | 419 | { |
@@ -482,6 +511,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
482 | case ATOM_WS_ATTRIBUTES: | 511 | case ATOM_WS_ATTRIBUTES: |
483 | gctx->io_attr = val; | 512 | gctx->io_attr = val; |
484 | break; | 513 | break; |
514 | case ATOM_WS_REGPTR: | ||
515 | gctx->reg_block = val; | ||
516 | break; | ||
485 | default: | 517 | default: |
486 | ctx->ws[idx] = val; | 518 | ctx->ws[idx] = val; |
487 | } | 519 | } |
@@ -677,7 +709,7 @@ static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) | |||
677 | SDEBUG(" dst: "); | 709 | SDEBUG(" dst: "); |
678 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 710 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
679 | SDEBUG(" src1: "); | 711 | SDEBUG(" src1: "); |
680 | src1 = atom_get_src(ctx, attr, ptr); | 712 | src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); |
681 | SDEBUG(" src2: "); | 713 | SDEBUG(" src2: "); |
682 | src2 = atom_get_src(ctx, attr, ptr); | 714 | src2 = atom_get_src(ctx, attr, ptr); |
683 | dst &= src1; | 715 | dst &= src1; |
@@ -809,6 +841,38 @@ static void atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg) | |||
809 | SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); | 841 | SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); |
810 | } | 842 | } |
811 | 843 | ||
844 | static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg) | ||
845 | { | ||
846 | uint8_t attr = U8((*ptr)++), shift; | ||
847 | uint32_t saved, dst; | ||
848 | int dptr = *ptr; | ||
849 | attr &= 0x38; | ||
850 | attr |= atom_def_dst[attr >> 3] << 6; | ||
851 | SDEBUG(" dst: "); | ||
852 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
853 | shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); | ||
854 | SDEBUG(" shift: %d\n", shift); | ||
855 | dst <<= shift; | ||
856 | SDEBUG(" dst: "); | ||
857 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | ||
858 | } | ||
859 | |||
860 | static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg) | ||
861 | { | ||
862 | uint8_t attr = U8((*ptr)++), shift; | ||
863 | uint32_t saved, dst; | ||
864 | int dptr = *ptr; | ||
865 | attr &= 0x38; | ||
866 | attr |= atom_def_dst[attr >> 3] << 6; | ||
867 | SDEBUG(" dst: "); | ||
868 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | ||
869 | shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); | ||
870 | SDEBUG(" shift: %d\n", shift); | ||
871 | dst >>= shift; | ||
872 | SDEBUG(" dst: "); | ||
873 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | ||
874 | } | ||
875 | |||
812 | static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | 876 | static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) |
813 | { | 877 | { |
814 | uint8_t attr = U8((*ptr)++), shift; | 878 | uint8_t attr = U8((*ptr)++), shift; |
@@ -818,7 +882,7 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | |||
818 | attr |= atom_def_dst[attr >> 3] << 6; | 882 | attr |= atom_def_dst[attr >> 3] << 6; |
819 | SDEBUG(" dst: "); | 883 | SDEBUG(" dst: "); |
820 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 884 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
821 | shift = U8((*ptr)++); | 885 | shift = atom_get_src(ctx, attr, ptr); |
822 | SDEBUG(" shift: %d\n", shift); | 886 | SDEBUG(" shift: %d\n", shift); |
823 | dst <<= shift; | 887 | dst <<= shift; |
824 | SDEBUG(" dst: "); | 888 | SDEBUG(" dst: "); |
@@ -834,7 +898,7 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) | |||
834 | attr |= atom_def_dst[attr >> 3] << 6; | 898 | attr |= atom_def_dst[attr >> 3] << 6; |
835 | SDEBUG(" dst: "); | 899 | SDEBUG(" dst: "); |
836 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 900 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
837 | shift = U8((*ptr)++); | 901 | shift = atom_get_src(ctx, attr, ptr); |
838 | SDEBUG(" shift: %d\n", shift); | 902 | SDEBUG(" shift: %d\n", shift); |
839 | dst >>= shift; | 903 | dst >>= shift; |
840 | SDEBUG(" dst: "); | 904 | SDEBUG(" dst: "); |
@@ -937,18 +1001,18 @@ static struct { | |||
937 | atom_op_or, ATOM_ARG_FB}, { | 1001 | atom_op_or, ATOM_ARG_FB}, { |
938 | atom_op_or, ATOM_ARG_PLL}, { | 1002 | atom_op_or, ATOM_ARG_PLL}, { |
939 | atom_op_or, ATOM_ARG_MC}, { | 1003 | atom_op_or, ATOM_ARG_MC}, { |
940 | atom_op_shl, ATOM_ARG_REG}, { | 1004 | atom_op_shift_left, ATOM_ARG_REG}, { |
941 | atom_op_shl, ATOM_ARG_PS}, { | 1005 | atom_op_shift_left, ATOM_ARG_PS}, { |
942 | atom_op_shl, ATOM_ARG_WS}, { | 1006 | atom_op_shift_left, ATOM_ARG_WS}, { |
943 | atom_op_shl, ATOM_ARG_FB}, { | 1007 | atom_op_shift_left, ATOM_ARG_FB}, { |
944 | atom_op_shl, ATOM_ARG_PLL}, { | 1008 | atom_op_shift_left, ATOM_ARG_PLL}, { |
945 | atom_op_shl, ATOM_ARG_MC}, { | 1009 | atom_op_shift_left, ATOM_ARG_MC}, { |
946 | atom_op_shr, ATOM_ARG_REG}, { | 1010 | atom_op_shift_right, ATOM_ARG_REG}, { |
947 | atom_op_shr, ATOM_ARG_PS}, { | 1011 | atom_op_shift_right, ATOM_ARG_PS}, { |
948 | atom_op_shr, ATOM_ARG_WS}, { | 1012 | atom_op_shift_right, ATOM_ARG_WS}, { |
949 | atom_op_shr, ATOM_ARG_FB}, { | 1013 | atom_op_shift_right, ATOM_ARG_FB}, { |
950 | atom_op_shr, ATOM_ARG_PLL}, { | 1014 | atom_op_shift_right, ATOM_ARG_PLL}, { |
951 | atom_op_shr, ATOM_ARG_MC}, { | 1015 | atom_op_shift_right, ATOM_ARG_MC}, { |
952 | atom_op_mul, ATOM_ARG_REG}, { | 1016 | atom_op_mul, ATOM_ARG_REG}, { |
953 | atom_op_mul, ATOM_ARG_PS}, { | 1017 | atom_op_mul, ATOM_ARG_PS}, { |
954 | atom_op_mul, ATOM_ARG_WS}, { | 1018 | atom_op_mul, ATOM_ARG_WS}, { |
@@ -1058,8 +1122,6 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 | |||
1058 | 1122 | ||
1059 | SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); | 1123 | SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); |
1060 | 1124 | ||
1061 | /* reset reg block */ | ||
1062 | ctx->reg_block = 0; | ||
1063 | ectx.ctx = ctx; | 1125 | ectx.ctx = ctx; |
1064 | ectx.ps_shift = ps / 4; | 1126 | ectx.ps_shift = ps / 4; |
1065 | ectx.start = base; | 1127 | ectx.start = base; |
@@ -1096,6 +1158,12 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 | |||
1096 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1158 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) |
1097 | { | 1159 | { |
1098 | mutex_lock(&ctx->mutex); | 1160 | mutex_lock(&ctx->mutex); |
1161 | /* reset reg block */ | ||
1162 | ctx->reg_block = 0; | ||
1163 | /* reset fb window */ | ||
1164 | ctx->fb_base = 0; | ||
1165 | /* reset io mode */ | ||
1166 | ctx->io_mode = ATOM_IO_MM; | ||
1099 | atom_execute_table_locked(ctx, index, params); | 1167 | atom_execute_table_locked(ctx, index, params); |
1100 | mutex_unlock(&ctx->mutex); | 1168 | mutex_unlock(&ctx->mutex); |
1101 | } | 1169 | } |