Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1962 → Rev 1963

/drivers/video/drm/radeon/atom.c
24,6 → 24,7
 
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
 
#define ATOM_DEBUG
31,6 → 32,7
#include "atom.h"
#include "atom-names.h"
#include "atom-bits.h"
#include "radeon.h"
 
#define ATOM_COND_ABOVE 0
#define ATOM_COND_ABOVEOREQUAL 1
52,15 → 54,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,
98,7 → 102,9
static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
uint32_t index, uint32_t data)
{
struct radeon_device *rdev = ctx->card->dev->dev_private;
uint32_t temp = 0xCDCDCDCD;
 
while (1)
switch (CU8(base)) {
case ATOM_IIO_NOP:
105,12 → 111,13
base++;
break;
case ATOM_IIO_READ:
temp = ctx->card->reg_read(ctx->card, CU16(base + 1));
temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1));
base += 3;
break;
case ATOM_IIO_WRITE:
(void)ctx->card->reg_read(ctx->card, CU16(base + 1));
ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
if (rdev->family == CHIP_RV515)
(void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
base += 3;
break;
case ATOM_IIO_CLEAR:
128,7 → 135,7
case ATOM_IIO_MOVE_INDEX:
temp &=
~((0xFFFFFFFF >> (32 - CU8(base + 1))) <<
CU8(base + 2));
CU8(base + 3));
temp |=
((index >> CU8(base + 2)) &
(0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base +
138,7 → 145,7
case ATOM_IIO_MOVE_DATA:
temp &=
~((0xFFFFFFFF >> (32 - CU8(base + 1))) <<
CU8(base + 2));
CU8(base + 3));
temp |=
((data >> CU8(base + 2)) &
(0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base +
148,7 → 155,7
case ATOM_IIO_MOVE_ATTR:
temp &=
~((0xFFFFFFFF >> (32 - CU8(base + 1))) <<
CU8(base + 2));
CU8(base + 3));
temp |=
((ctx->
io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 -
604,13 → 611,18
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)
{
640,12 → 652,12
 
static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
{
uint8_t count = U8((*ptr)++);
unsigned count = U8((*ptr)++);
SDEBUG(" count: %d\n", count);
if (arg == ATOM_UNIT_MICROSEC)
udelay(count);
else
mdelay(count);
msleep(count);
}
 
static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg)
673,6 → 685,8
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:
707,16 → 721,16
static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
{
uint8_t attr = U8((*ptr)++);
uint32_t dst, src1, src2, saved;
uint32_t dst, mask, src, saved;
int dptr = *ptr;
SDEBUG(" dst: ");
dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
SDEBUG(" src1: ");
src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr);
SDEBUG(" src2: ");
src2 = atom_get_src(ctx, attr, ptr);
dst &= src1;
dst |= src2;
mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr);
SDEBUG(" mask: 0x%08x", mask);
SDEBUG(" src: ");
src = atom_get_src(ctx, attr, ptr);
dst &= mask;
dst |= src;
SDEBUG(" dst: ");
atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
}
881,11 → 895,16
uint8_t attr = U8((*ptr)++), shift;
uint32_t saved, dst;
int dptr = *ptr;
uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
SDEBUG(" dst: ");
dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
/* op needs to full dst value */
dst = saved;
shift = atom_get_src(ctx, attr, ptr);
SDEBUG(" shift: %d\n", shift);
dst <<= shift;
dst &= atom_arg_mask[dst_align];
dst >>= atom_arg_shift[dst_align];
SDEBUG(" dst: ");
atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
}
895,11 → 914,16
uint8_t attr = U8((*ptr)++), shift;
uint32_t saved, dst;
int dptr = *ptr;
uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
SDEBUG(" dst: ");
dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
/* op needs to full dst value */
dst = saved;
shift = atom_get_src(ctx, attr, ptr);
SDEBUG(" shift: %d\n", shift);
dst >>= shift;
dst &= atom_arg_mask[dst_align];
dst >>= atom_arg_shift[dst_align];
SDEBUG(" dst: ");
atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
}
1104,15 → 1128,16
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;
int ret = 0;
 
if (!base)
return;
return -EINVAL;
 
len = CU16(base + ATOM_CT_SIZE_PTR);
ws = CU8(base + ATOM_CT_WS_PTR);
1125,6 → 1150,8
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
1137,6 → 1164,12
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);
ret = -EINVAL;
goto free;
}
 
if (op < ATOM_OP_CNT && op > 0)
opcode_table[op].func(&ectx, &ptr,
1150,12 → 1183,16
debug_depth--;
SDEBUG("<<\n");
 
free:
if (ws)
kfree(ectx.ws);
return ret;
}
 
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;
1163,8 → 1200,9
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 };
1248,9 → 1286,7
 
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)
1260,13 → 1296,17
kfree(ctx);
}
 
void atom_parse_data_header(struct atom_context *ctx, int index,
bool atom_parse_data_header(struct atom_context *ctx, int index,
uint16_t * size, uint8_t * frev, uint8_t * crev,
uint16_t * data_start)
{
int offset = index * 2 + 4;
int idx = CU16(ctx->data_table + offset);
u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
 
if (!mdt[index])
return false;
 
if (size)
*size = CU16(idx);
if (frev)
1274,20 → 1314,24
if (crev)
*crev = CU8(idx + 3);
*data_start = idx;
return;
return true;
}
 
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
uint8_t * crev)
{
int offset = index * 2 + 4;
int idx = CU16(ctx->cmd_table + offset);
u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
 
if (!mct[index])
return false;
 
if (frev)
*frev = CU8(idx + 2);
if (crev)
*crev = CU8(idx + 3);
return;
return true;
}
 
int atom_allocate_fb_scratch(struct atom_context *ctx)
1294,11 → 1338,10
{
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
uint16_t data_offset;
int usage_bytes;
int usage_bytes = 0;
struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
 
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
 
if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
 
DRM_DEBUG("atom firmware requested %08x %dkb\n",
1306,6 → 1349,7
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
 
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
}
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */