Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 189314
b: refs/heads/master
c: c21b0fe
h: refs/heads/master
v: v3
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Mar 14, 2010
1 parent df8d252 commit d5dfe2a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 338e2b1d571e4873908b199c90d6a31f65137fe3
refs/heads/master: c21b0fe6de3912f53087b4f3991942529f03eef6
59 changes: 47 additions & 12 deletions trunk/drivers/gpu/drm/radeon/atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@

typedef struct {
struct atom_context *ctx;

uint32_t *ps, *ws;
int ps_shift;
uint16_t start;
unsigned last_jump;
unsigned long last_jump_jiffies;
bool abort;
} atom_exec_context;

int atom_debug = 0;
static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);

static uint32_t atom_arg_mask[8] =
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
Expand Down Expand Up @@ -604,12 +606,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
{
int idx = U8((*ptr)++);
int r = 0;

if (idx < ATOM_TABLE_NAMES_CNT)
SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]);
else
SDEBUG(" table: %d\n", idx);
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
if (r) {
ctx->abort = true;
}
}

static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
Expand Down Expand Up @@ -673,6 +680,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
{
int execute = 0, target = U16(*ptr);
unsigned long cjiffies;

(*ptr) += 2;
switch (arg) {
case ATOM_COND_ABOVE:
Expand Down Expand Up @@ -700,8 +709,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
if (arg != ATOM_COND_ALWAYS)
SDEBUG(" taken: %s\n", execute ? "yes" : "no");
SDEBUG(" target: 0x%04X\n", target);
if (execute)
if (execute) {
if (ctx->last_jump == (ctx->start + target)) {
cjiffies = jiffies;
if (time_after(cjiffies, ctx->last_jump_jiffies)) {
cjiffies -= ctx->last_jump_jiffies;
if ((jiffies_to_msecs(cjiffies) > 1000)) {
DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
ctx->abort = true;
}
} else {
/* jiffies wrap around we will just wait a little longer */
ctx->last_jump_jiffies = jiffies;
}
} else {
ctx->last_jump = ctx->start + target;
ctx->last_jump_jiffies = jiffies;
}
*ptr = ctx->start + target;
}
}

static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
Expand Down Expand Up @@ -1104,15 +1130,15 @@ static struct {
atom_op_shr, ATOM_ARG_MC}, {
atom_op_debug, 0},};

static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
{
int base = CU16(ctx->cmd_table + 4 + 2 * index);
int len, ws, ps, ptr;
unsigned char op;
atom_exec_context ectx;

if (!base)
return;
return -EINVAL;

len = CU16(base + ATOM_CT_SIZE_PTR);
ws = CU8(base + ATOM_CT_WS_PTR);
Expand All @@ -1125,6 +1151,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
ectx.ps_shift = ps / 4;
ectx.start = base;
ectx.ps = params;
ectx.abort = false;
ectx.last_jump = 0;
if (ws)
ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
else
Expand All @@ -1137,6 +1165,11 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
else
SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
if (ectx.abort) {
DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
base, len, ws, ps, ptr - 1);
return -EINVAL;
}

if (op < ATOM_OP_CNT && op > 0)
opcode_table[op].func(&ectx, &ptr,
Expand All @@ -1152,19 +1185,23 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3

if (ws)
kfree(ectx.ws);
return 0;
}

void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
{
int r;

mutex_lock(&ctx->mutex);
/* reset reg block */
ctx->reg_block = 0;
/* reset fb window */
ctx->fb_base = 0;
/* reset io mode */
ctx->io_mode = ATOM_IO_MM;
atom_execute_table_locked(ctx, index, params);
r = atom_execute_table_locked(ctx, index, params);
mutex_unlock(&ctx->mutex);
return r;
}

static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
Expand Down Expand Up @@ -1248,9 +1285,7 @@ int atom_asic_init(struct atom_context *ctx)

if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
return 1;
atom_execute_table(ctx, ATOM_CMD_INIT, ps);

return 0;
return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
}

void atom_destroy(struct atom_context *ctx)
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/radeon/atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ struct atom_context {
extern int atom_debug;

struct atom_context *atom_parse(struct card_info *, void *);
void atom_execute_table(struct atom_context *, int, uint32_t *);
int atom_execute_table(struct atom_context *, int, uint32_t *);
int atom_asic_init(struct atom_context *);
void atom_destroy(struct atom_context *);
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
Expand Down

0 comments on commit d5dfe2a

Please sign in to comment.