msm: kgsl: handle larger instruction store for adreno225

This GPU has a larger instruction store, so more memory
needs to be reserved for saving shader state when context
switching.

The initial vertex and pixel partitioning of the
instruction store also needs to be different.
This commit is contained in:
SecureCRT 2012-07-24 23:30:19 +08:00
parent ee339b2bcb
commit be4c38e2f5
5 changed files with 79 additions and 27 deletions

View File

@ -137,21 +137,28 @@ static const struct {
const char *pm4fw;
const char *pfpfw;
struct adreno_gpudev *gpudev;
unsigned int istore_size;
unsigned int pix_shader_start;
} adreno_gpulist[] = {
{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev },
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
512, 384},
{ ADRENO_REV_A205, 0, 1, 0, ANY_ID,
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev },
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
512, 384},
{ ADRENO_REV_A220, 2, 1, ANY_ID, ANY_ID,
"leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev },
"leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev,
512, 384},
/*
* patchlevel 5 (8960v2) needs special pm4 firmware to work around
* a hardware problem.
*/
{ ADRENO_REV_A225, 2, 2, 0, 5,
"a225p5_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev },
"a225p5_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
1536, 768 },
{ ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID,
"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev },
"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
1536, 768 },
};
static void adreno_gmeminit(struct adreno_device *adreno_dev)
@ -424,6 +431,8 @@ adreno_identify_gpu(struct adreno_device *adreno_dev)
adreno_dev->gpudev = adreno_gpulist[i].gpudev;
adreno_dev->pfp_fwfile = adreno_gpulist[i].pfpfw;
adreno_dev->pm4_fwfile = adreno_gpulist[i].pm4fw;
adreno_dev->istore_size = adreno_gpulist[i].istore_size;
adreno_dev->pix_shader_start = adreno_gpulist[i].pix_shader_start;
}
static int __devinit

View File

@ -39,6 +39,12 @@
#define ADRENO_DEFAULT_PWRSCALE_POLICY NULL
#endif
/*
* constants for the size of shader instructions
*/
#define ADRENO_ISTORE_BYTES 12
#define ADRENO_ISTORE_WORDS 3
enum adreno_gpurev {
ADRENO_REV_UNKNOWN = 0,
ADRENO_REV_A200 = 200,
@ -65,6 +71,8 @@ struct adreno_device {
unsigned int mharb;
struct adreno_gpudev *gpudev;
unsigned int wait_timeout;
unsigned int istore_size;
unsigned int pix_shader_start;
};
struct adreno_gpudev {
@ -128,5 +136,28 @@ static inline int adreno_is_a2xx(struct adreno_device *adreno_dev)
return (adreno_dev->gpurev <= ADRENO_REV_A225);
}
/**
* adreno_encode_istore_size - encode istore size in CP format
* @adreno_dev - The 3D device.
*
* Encode the istore size into the format expected that the
* CP_SET_SHADER_BASES and CP_ME_INIT commands:
* bits 31:29 - istore size as encoded by this function
* bits 27:16 - vertex shader start offset in instructions
* bits 11:0 - pixel shader start offset in instructions.
*/
static inline int adreno_encode_istore_size(struct adreno_device *adreno_dev)
{
unsigned int size;
/* in a225 the CP microcode multiplies the encoded
* value by 3 while decoding.
*/
if (adreno_is_a225(adreno_dev))
size = adreno_dev->istore_size/3;
else
size = adreno_dev->istore_size;
return (ilog2(size) - 5) << 29;
}
#endif /*__ADRENO_H */

View File

@ -72,10 +72,6 @@
#define TEX_CONSTANTS (32*6) /* DWORDS */
#define BOOL_CONSTANTS 8 /* DWORDS */
#define LOOP_CONSTANTS 56 /* DWORDS */
#define SHADER_INSTRUCT_LOG2 9U /* 2^n == SHADER_INSTRUCTIONS */
/* 96-bit instructions */
#define SHADER_INSTRUCT (1<<SHADER_INSTRUCT_LOG2)
/* LOAD_CONSTANT_CONTEXT shadow size */
#define LCC_SHADOW_SIZE 0x2000 /* 8KB */
@ -88,14 +84,21 @@
#define CMD_BUFFER_SIZE 0x3000 /* 12KB */
#endif
#define TEX_SHADOW_SIZE (TEX_CONSTANTS*4) /* 768 bytes */
#define SHADER_SHADOW_SIZE (SHADER_INSTRUCT*12) /* 6KB */
#define REG_OFFSET LCC_SHADOW_SIZE
#define CMD_OFFSET (REG_OFFSET + REG_SHADOW_SIZE)
#define TEX_OFFSET (CMD_OFFSET + CMD_BUFFER_SIZE)
#define SHADER_OFFSET ((TEX_OFFSET + TEX_SHADOW_SIZE + 32) & ~31)
#define CONTEXT_SIZE (SHADER_OFFSET + 3 * SHADER_SHADOW_SIZE)
static inline int _shader_shadow_size(struct adreno_device *adreno_dev)
{
return adreno_dev->istore_size*ADRENO_ISTORE_BYTES;
}
static inline int _context_size(struct adreno_device *adreno_dev)
{
return SHADER_OFFSET + 3*_shader_shadow_size(adreno_dev);
}
/* A scratchpad used to build commands during context create */
@ -603,7 +606,8 @@ static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
*cmds++ = 0x00003F00;
*cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
*cmds++ = (0x80000000) | 0x180;
*cmds++ = adreno_encode_istore_size(adreno_dev)
| adreno_dev->pix_shader_start;
/* load the patched vertex shader stream */
cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN);
@ -806,7 +810,8 @@ static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
*cmds++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
*cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
*cmds++ = (0x80000000) | 0x180;
*cmds++ = adreno_encode_istore_size(adreno_dev)
| adreno_dev->pix_shader_start;
/* Load the patched fragment shader stream */
cmds =
@ -1104,8 +1109,10 @@ build_shader_save_restore_cmds(struct adreno_device *adreno_dev,
/* compute vertex, pixel and shared instruction shadow GPU addresses */
tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET;
tmp_ctx.shader_pixel = tmp_ctx.shader_vertex + SHADER_SHADOW_SIZE;
tmp_ctx.shader_shared = tmp_ctx.shader_pixel + SHADER_SHADOW_SIZE;
tmp_ctx.shader_pixel = tmp_ctx.shader_vertex
+ _shader_shadow_size(adreno_dev);
tmp_ctx.shader_shared = tmp_ctx.shader_pixel
+ _shader_shadow_size(adreno_dev);
/* restore shader partitioning and instructions */
@ -1161,8 +1168,8 @@ build_shader_save_restore_cmds(struct adreno_device *adreno_dev,
*cmd++ = REG_SCRATCH_REG2;
/* AND off invalid bits. */
*cmd++ = 0x0FFF0FFF;
/* OR in instruction memory size */
*cmd++ = (unsigned int)((SHADER_INSTRUCT_LOG2 - 5U) << 29);
/* OR in instruction memory size. */
*cmd++ = adreno_encode_istore_size(adreno_dev);
/* write the computed value to the SET_SHADER_BASES data field */
*cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
@ -1305,13 +1312,13 @@ static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
*/
ret = kgsl_allocate(&drawctxt->gpustate,
drawctxt->pagetable, CONTEXT_SIZE);
drawctxt->pagetable, _context_size(adreno_dev));
if (ret)
return ret;
kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0,
CONTEXT_SIZE);
_context_size(adreno_dev));
tmp_ctx.cmd = tmp_ctx.start
= (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);

11
drivers/gpu/msm/adreno_debugfs.c Normal file → Executable file
View File

@ -223,21 +223,23 @@ static int kgsl_regread_nolock(struct kgsl_device *device,
return 0;
}
#define KGSL_ISTORE_START 0x5000
#define KGSL_ISTORE_LENGTH 0x600
#define ADRENO_ISTORE_START 0x5000
static ssize_t kgsl_istore_read(
struct file *file,
char __user *buff,
size_t buff_count,
loff_t *ppos)
{
int i, count = KGSL_ISTORE_LENGTH, remaining, pos = 0, tot = 0;
int i, count, remaining, pos = 0, tot = 0;
struct kgsl_device *device = file->private_data;
const int rowc = 8;
struct adreno_device *adreno_dev;
if (!ppos || !device)
return 0;
adreno_dev = ADRENO_DEVICE(device);
count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS;
remaining = count;
for (i = 0; i < count; i += rowc) {
unsigned int vals[rowc];
@ -248,7 +250,8 @@ static ssize_t kgsl_istore_read(
if (pos >= *ppos) {
for (j = 0; j < linec; ++j)
kgsl_regread_nolock(device,
KGSL_ISTORE_START+i+j, vals+j);
ADRENO_ISTORE_START + i + j,
vals + j);
} else
memset(vals, 0, sizeof(vals));

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -246,6 +246,7 @@ int adreno_ringbuffer_start(struct adreno_ringbuffer *rb, unsigned int init_ram)
union reg_cp_rb_cntl cp_rb_cntl;
unsigned int *cmds, rb_cntl;
struct kgsl_device *device = rb->device;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
uint cmds_gpu;
if (rb->flags & KGSL_FLAGS_STARTED)
@ -362,9 +363,10 @@ int adreno_ringbuffer_start(struct adreno_ringbuffer *rb, unsigned int init_ram)
GSL_RB_WRITE(cmds, cmds_gpu,
SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
/* Vertex and Pixel Shader Start Addresses in instructions
* (3 DWORDS per instruction) */
GSL_RB_WRITE(cmds, cmds_gpu, 0x80000180);
/* Instruction memory size: */
GSL_RB_WRITE(cmds, cmds_gpu,
(adreno_encode_istore_size(adreno_dev)
| adreno_dev->pix_shader_start));
/* Maximum Contexts */
GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
/* Write Confirm Interval and The CP will wait the