From be4c38e2f5c165dffdaf76a1a573bf3ad1faff5f Mon Sep 17 00:00:00 2001 From: SecureCRT Date: Tue, 24 Jul 2012 23:30:19 +0800 Subject: [PATCH] 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. --- drivers/gpu/msm/adreno.c | 19 +++++++++++----- drivers/gpu/msm/adreno.h | 31 +++++++++++++++++++++++++ drivers/gpu/msm/adreno_a2xx.c | 35 +++++++++++++++++------------ drivers/gpu/msm/adreno_debugfs.c | 11 +++++---- drivers/gpu/msm/adreno_ringbuffer.c | 10 +++++---- 5 files changed, 79 insertions(+), 27 deletions(-) mode change 100644 => 100755 drivers/gpu/msm/adreno_debugfs.c diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index c536fb89..ad164fee 100755 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -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 diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 088511af..b54699ad 100755 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -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 */ diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c index 9e167c65..499d0b4f 100755 --- a/drivers/gpu/msm/adreno_a2xx.c +++ b/drivers/gpu/msm/adreno_a2xx.c @@ -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<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); diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c old mode 100644 new mode 100755 index c878a2c2..419ce9d2 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -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)); diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 57af5563..e5c28d71 100755 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -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