From c6b3a994e82fd6cc423a4122fa8dcb2b2d553611 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:51 -0700 Subject: [PATCH 01/11] msm: kgsl: Update the GMEM and istore size for A320 Set the correct GMEM and istore sizes for A320 on APQ8064. The more GMEM we have the happier we are, so the code will work with 256K, but it will be better with 512K. For the instruction store the size is important during GPU snapshot and postmortem dump. Also, the size of each instruction is different on A3XX so remove the hard coded constants and add a GPU specific size variable. Change-Id: Ic0dedbad01d5a9dc4211a666bc0a065189938841 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno.c | 18 +++++++++++------- drivers/gpu/msm/adreno.h | 8 ++------ drivers/gpu/msm/adreno_a2xx.c | 3 ++- drivers/gpu/msm/adreno_a3xx.c | 3 +++ drivers/gpu/msm/adreno_debugfs.c | 3 ++- drivers/gpu/msm/adreno_snapshot.c | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 805e2b687e2..608adf763a9 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -131,31 +131,35 @@ static const struct { struct adreno_gpudev *gpudev; unsigned int istore_size; unsigned int pix_shader_start; + unsigned int instruction_size; /* Size of an instruction in dwords */ } adreno_gpulist[] = { { ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID, "yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev, - 512, 384}, + 512, 384, 3}, { ADRENO_REV_A205, 0, 1, 0, ANY_ID, "yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev, - 512, 384}, + 512, 384, 3}, { ADRENO_REV_A220, 2, 1, ANY_ID, ANY_ID, "leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev, - 512, 384}, + 512, 384, 3}, /* * 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, - 1536, 768 }, + 1536, 768, 3 }, { ADRENO_REV_A225, 2, 2, 0, 6, "a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev, - 1536, 768 }, + 1536, 768, 3 }, { ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID, "a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev, - 1536, 768 }, + 1536, 768, 3 }, + /* A3XX doesn't use the pix_shader_start */ { ADRENO_REV_A320, 3, 1, ANY_ID, ANY_ID, - "a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev }, + "a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev, + 512, 0, 2 }, + }; static irqreturn_t adreno_isr(int irq, void *data) diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 9c2d7045a94..9498b80e4ee 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -39,12 +39,7 @@ #define ADRENO_DEFAULT_PWRSCALE_POLICY NULL #endif -/* - * constants for the size of shader instructions - */ -#define ADRENO_ISTORE_BYTES 12 -#define ADRENO_ISTORE_WORDS 3 -#define ADRENO_ISTORE_START 0x5000 +#define ADRENO_ISTORE_START 0x5000 /* Istore offset */ enum adreno_gpurev { ADRENO_REV_UNKNOWN = 0, @@ -75,6 +70,7 @@ struct adreno_device { unsigned int wait_timeout; unsigned int istore_size; unsigned int pix_shader_start; + unsigned int instruction_size; }; struct adreno_gpudev { diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c index e31b76b0175..f2b127857d6 100644 --- a/drivers/gpu/msm/adreno_a2xx.c +++ b/drivers/gpu/msm/adreno_a2xx.c @@ -164,7 +164,8 @@ const unsigned int a220_registers_count = ARRAY_SIZE(a220_registers) / 2; static inline int _shader_shadow_size(struct adreno_device *adreno_dev) { - return adreno_dev->istore_size*ADRENO_ISTORE_BYTES; + return adreno_dev->istore_size * + (adreno_dev->instruction_size * sizeof(unsigned int)); } static inline int _context_size(struct adreno_device *adreno_dev) diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 1bad8113844..9bd5a0ee444 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -2547,6 +2547,9 @@ static void a3xx_start(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; + /* GMEM size on A320 is 512K */ + adreno_dev->gmemspace.sizebytes = SZ_512K; + /* Reset the core */ adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD, 0x00000001); diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index c1b9e4ce24b..b53ca8f848a 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -143,7 +143,8 @@ static ssize_t kgsl_istore_read( return 0; adreno_dev = ADRENO_DEVICE(device); - count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS; + count = adreno_dev->istore_size * adreno_dev->instruction_size; + remaining = count; for (i = 0; i < count; i += rowc) { unsigned int vals[rowc]; diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index fb88a72bd65..cc3f3e781cd 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -86,7 +86,7 @@ static int snapshot_istore(struct kgsl_device *device, void *snapshot, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int count, i; - count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS; + count = adreno_dev->istore_size * adreno_dev->instruction_size; if (remain < (count * 4) + sizeof(*header)) { KGSL_DRV_ERR(device, From 55d98fd5ce644b096d32daaf11bd68c27b32bb0a Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:51 -0700 Subject: [PATCH 02/11] msm: kgsl: Correct the microcode sizes in the GPU snapshot The stored sizes for the PM4 and PFP microcode in the adreno device structure were already dword sized, so just store those numbers directly in the snapshot header. The stored size include an additional version dword that isn't actually saved as part of the firmware, so decrement the stored sizes by one when we read the data back from the GPU. Change-Id: Ic0dedbad6d4c5612903c7b6d1b626ccd6246f61c Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno.c | 1 + drivers/gpu/msm/adreno_a3xx.c | 2 +- drivers/gpu/msm/adreno_a3xx_snapshot.c | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 608adf763a9..69934221427 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -446,6 +446,7 @@ adreno_identify_gpu(struct adreno_device *adreno_dev) 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; + adreno_dev->instruction_size = adreno_gpulist[i].instruction_size; } static int __devinit diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 9bd5a0ee444..14d4e0aa437 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -34,7 +34,7 @@ const unsigned int a3xx_registers[] = { 0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff, 0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f, 0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f, - 0x0579, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e, + 0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e, 0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f, 0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7, 0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05, diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c index aade50cd753..e76db298117 100644 --- a/drivers/gpu/msm/adreno_a3xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c @@ -80,7 +80,7 @@ static int a3xx_snapshot_cp_pm4_ram(struct kgsl_device *device, void *snapshot, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_snapshot_debug *header = snapshot; unsigned int *data = snapshot + sizeof(*header); - int i, size = adreno_dev->pm4_fw_size >> 2; + int i, size = adreno_dev->pm4_fw_size - 1; if (remain < DEBUG_SECTION_SZ(size)) { SNAPSHOT_ERR_NOMEM(device, "CP PM4 RAM DEBUG"); @@ -98,7 +98,7 @@ static int a3xx_snapshot_cp_pm4_ram(struct kgsl_device *device, void *snapshot, */ adreno_regwrite(device, REG_CP_ME_RAM_RADDR, 0x0); - for (i = 0; i < adreno_dev->pm4_fw_size >> 2; i++) + for (i = 0; i < size; i++) adreno_regread(device, REG_CP_ME_RAM_DATA, &data[i]); return DEBUG_SECTION_SZ(size); @@ -110,7 +110,7 @@ static int a3xx_snapshot_cp_pfp_ram(struct kgsl_device *device, void *snapshot, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_snapshot_debug *header = snapshot; unsigned int *data = snapshot + sizeof(*header); - int i, size = adreno_dev->pfp_fw_size >> 2; + int i, size = adreno_dev->pfp_fw_size - 1; if (remain < DEBUG_SECTION_SZ(size)) { SNAPSHOT_ERR_NOMEM(device, "CP PFP RAM DEBUG"); @@ -127,7 +127,7 @@ static int a3xx_snapshot_cp_pfp_ram(struct kgsl_device *device, void *snapshot, * maintain always changing hardcoded constants */ kgsl_regwrite(device, A3XX_CP_PFP_UCODE_ADDR, 0x0); - for (i = 0; i < adreno_dev->pfp_fw_size >> 2; i++) + for (i = 0; i < size; i++) adreno_regread(device, A3XX_CP_PFP_UCODE_DATA, &data[i]); return DEBUG_SECTION_SZ(size); From a7ec42196a6e1aa4e0a6aeabfee8bf6f79654bd9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:52 -0700 Subject: [PATCH 03/11] msm: kgsl: A3XX GMEM save/restore was never executed GMEM save/restore was never being executed for A3XX due to an if() statement checking a flag that never gets set. Remove said if statement and set the flag so that GMEM save/restore gets run during a context switch if requested from user space. Additionally, fix a few minor issues with the gmem save/restore sequence so when the application requests it, it will actually work. Change-Id: Ic0dedbad3f8e86b23bbd26051b771514e6518831 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_a3xx.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 14d4e0aa437..51008ae443e 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -258,7 +258,7 @@ static void build_regconstantsave_cmds(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { unsigned int *cmd = tmp_ctx.cmd; - unsigned int *start = cmd; + unsigned int *start; unsigned int i; drawctxt->constant_save_commands[0].hostptr = cmd; @@ -266,6 +266,8 @@ static void build_regconstantsave_cmds(struct adreno_device *adreno_dev, virt2gpu(cmd, &drawctxt->gpustate); cmd++; + start = cmd; + *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1); *cmd++ = 0; @@ -1329,7 +1331,7 @@ static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev, /* SP_FS_OUT_REG */ *cmds++ = _SET(SP_FSOUTREG_PAD0, SP_PIXEL_BASED); - *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2); + *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5); *cmds++ = CP_REG(A3XX_SP_FS_MRT_REG_0); /* SP_FS_MRT_REG0 */ *cmds++ = _SET(SP_FSMRTREG_REGID, 4); @@ -1426,7 +1428,7 @@ static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev, _SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) | _SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2); - *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 11); + *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2); *cmds++ = CP_REG(A3XX_SP_SP_CTRL_REG); /* SP_SP_CTRL_REG */ *cmds++ = _SET(SP_SPCTRLREG_SLEEPMODE, 1); @@ -2130,24 +2132,17 @@ static int a3xx_create_gpustate_shadow(struct adreno_device *adreno_dev, static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev, struct adreno_context *drawctxt) { + int result; + calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmemspace.sizebytes); tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base; - if (drawctxt->flags & CTXT_FLAGS_GMEM_SHADOW) { - int result = - kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow, - drawctxt->pagetable, - drawctxt->context_gmem_shadow.size); + result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow, + drawctxt->pagetable, drawctxt->context_gmem_shadow.size); - if (result) - return result; - } else { - memset(&drawctxt->context_gmem_shadow.gmemshadow, 0, - sizeof(drawctxt->context_gmem_shadow.gmemshadow)); - - return 0; - } + if (result) + return result; build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow, &tmp_ctx.cmd); @@ -2163,6 +2158,8 @@ static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev, kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow, KGSL_CACHE_OP_FLUSH); + drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW; + return 0; } From b6ebffe18fa745e2f5ca5e6ba27a7e71fadc4ff2 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:53 -0700 Subject: [PATCH 04/11] msm: kgsl: Enable A3XX GPU hang detection A3XX GPU hang detection can figure out if the core is hung and interrupt us if it has. However, the interrupt seems to be a little unreliable so that isn't of use to us, but the hang detection has a beneficial side effect of spewing lots of useful information to debug registers that can be used on a hang. Enable the hang detection but disable the hang interrupt. Change-Id: Ic0dedbadc8492d388729c2eea9b9e1bdc8ac1013 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_a3xx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 51008ae443e..cde170e8812 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -2441,7 +2441,6 @@ static void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq) (1 << A3XX_INT_CP_RB_INT) | \ (1 << A3XX_INT_CP_REG_PROTECT_FAULT) | \ (1 << A3XX_INT_CP_AHB_ERROR_HALT) | \ - (1 << A3XX_INT_MISC_HANG_DETECT) | \ (1 << A3XX_INT_UCHE_OOB_ACCESS)) static struct { @@ -2471,7 +2470,7 @@ static struct { A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 21 - CP_AHB_ERROR_FAULT */ A3XX_IRQ_CALLBACK(NULL), /* 22 - Unused */ A3XX_IRQ_CALLBACK(NULL), /* 23 - Unused */ - A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 24 - MISC_HANG_DETECT */ + A3XX_IRQ_CALLBACK(NULL), /* 24 - MISC_HANG_DETECT */ A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 25 - UCHE_OOB_ACCESS */ /* 26 to 31 - Unused */ }; @@ -2574,6 +2573,13 @@ static void a3xx_start(struct adreno_device *adreno_dev) /* Turn on the power counters */ adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00003000); + + /* Turn on hang detection - this spews a lot of useful information + * into the RBBM registers on a hang */ + + adreno_regwrite(device, A3XX_RBBM_INTERFACE_HANG_INT_CTL, + (1 << 16) | 0xFFF); + } /* Defined in adreno_a3xx_snapshot.c */ From 662a67c42f0804b5e2420a07691e99fb4b7c8948 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:53 -0700 Subject: [PATCH 05/11] msm: kgsl: Fix the A3XX debugbus snapshot code The code that dumped the A3XX debug bus wasn't using the right bitshift for debug bus ID resulting in completely incorrect data in the snapshot output. Set the ID correctly and the debug data is full and complete. Change-Id: Ic0dedbad41ec7267517f4fa16de2c5884ae0d82c Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_a3xx_snapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c index e76db298117..c8c7c441add 100644 --- a/drivers/gpu/msm/adreno_a3xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c @@ -175,7 +175,7 @@ static int a3xx_snapshot_debugbus_block(struct kgsl_device *device, return 0; } - val = (id << 0x06) | (1 << 0x10); + val = (id << 8) | (1 << 16); header->id = id; header->count = DEBUGFS_BLOCK_SIZE; From 817e0b90575cb8cf6c82ce99bed6db25ac633ce9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 10:23:53 -0700 Subject: [PATCH 06/11] msm: kgsl: Set the default MMU to 'none' for APQ8064 A3XX targets (8064 and greater) have no GPU MMU, so default to no MMU when the IOMMU isn't available or configured. Change-Id: Ic0dedbad90e2762663349ad055d818416290a164 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/kgsl_mmu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 36248ef2f75..2836a3ec559 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "kgsl.h" #include "kgsl_mmu.h" @@ -712,7 +713,14 @@ EXPORT_SYMBOL(kgsl_mmu_get_mmutype); void kgsl_mmu_set_mmutype(char *mmutype) { - kgsl_mmu_type = iommu_found() ? KGSL_MMU_TYPE_IOMMU : KGSL_MMU_TYPE_GPU; + /* Set the default MMU - GPU on <=8960 and nothing on >= 8064 */ + kgsl_mmu_type = + cpu_is_apq8064() ? KGSL_MMU_TYPE_NONE : KGSL_MMU_TYPE_GPU; + + /* Use the IOMMU if it is found */ + if (iommu_found()) + kgsl_mmu_type = KGSL_MMU_TYPE_IOMMU; + if (mmutype && !strncmp(mmutype, "gpummu", 6)) kgsl_mmu_type = KGSL_MMU_TYPE_GPU; if (iommu_found() && mmutype && !strncmp(mmutype, "iommu", 5)) From e3f80eaff7d8a7f00223627531ff5ecb75104899 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Sat, 4 Feb 2012 14:22:36 -0700 Subject: [PATCH 07/11] msm: kgsl: Only use the setstate slowpath for A3XX The setstate fastpath only works on A2XX, so completely skip it for A3XX. Change-Id: Ic0dedbad9c0dac16ea28b6f615f5d07fb5059980 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 69934221427..9cbebbe1691 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -251,6 +251,16 @@ static void adreno_setstate(struct kgsl_device *device, int sizedwords = 0; unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */ + /* + * A3XX doesn't support the fast path (the registers don't even exist) + * so just bail out early + */ + + if (adreno_is_a3xx(adreno_dev)) { + kgsl_mmu_device_setstate(device, flags); + return; + } + /* * If possible, then set the state via the command stream to avoid * a CPU idle. Otherwise, use the default setstate which uses register From 40861a40bbd2e14152d66eecc29093a8da6f5e3c Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 6 Feb 2012 10:18:23 -0700 Subject: [PATCH 08/11] msm: kgsl: Use the right physical addresses in NOMMU mode In NOMMU mode the gpuaddr was set to the physaddr for the memdesc which worked great until the memory wasn't allocated by KGSL, at which point it blew up. We already went through the due dilligence to turn all memdescs into sglists, so use the sglist to get the physaddr (and thus the gpuaddr). Check to make sure that we're not trying to map a real sglist (more than one entry) and if we are, then loudly fail. Change-Id: Ic0dedbad5d401c505949c92d9a7795f3260dbabb Signed-off-by: Jordan Crouse --- drivers/gpu/msm/kgsl_mmu.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 2836a3ec559..671479ea9c0 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -535,9 +535,16 @@ kgsl_mmu_map(struct kgsl_pagetable *pagetable, int ret; if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) { - memdesc->gpuaddr = memdesc->physaddr; - return 0; + if (memdesc->sglen == 1) { + memdesc->gpuaddr = sg_phys(memdesc->sg); + return 0; + } else { + KGSL_CORE_ERR("Memory is not contigious " + "(sglen = %d)\n", memdesc->sglen); + return -EINVAL; + } } + memdesc->gpuaddr = gen_pool_alloc_aligned(pagetable->pool, memdesc->size, KGSL_MMU_ALIGN_SHIFT); From 0e43cd39ecc42c4a956229682be128ad3a1b89b5 Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Wed, 8 Feb 2012 21:03:50 -0800 Subject: [PATCH 09/11] msm: board-8064: Fix 8064 GPU clk at 192 Mhz Disable GPU 3d clock scaling by making all the clock frequencies 192 Mhz. we will re-enable GPU clock scaling when system is more stable and GPU clock is verified at higher frequencies. Change-Id: I00b0b40b976798a7cfa66b30aa5dbe42dc855343 Signed-off-by: Tarun Karra --- arch/arm/mach-msm/board-8064-gpu.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c index a8c5d48c099..0357c4061e1 100644 --- a/arch/arm/mach-msm/board-8064-gpu.c +++ b/arch/arm/mach-msm/board-8064-gpu.c @@ -125,14 +125,14 @@ static struct resource kgsl_3d0_resources[] = { static struct kgsl_device_platform_data kgsl_3d0_pdata = { .pwrlevel = { { - .gpu_freq = 400000000, - .bus_freq = 4, - .io_fraction = 0, + .gpu_freq = 192000000, + .bus_freq = 2, + .io_fraction = 100, }, { - .gpu_freq = 320000000, - .bus_freq = 3, - .io_fraction = 33, + .gpu_freq = 192000000, + .bus_freq = 2, + .io_fraction = 100, }, { .gpu_freq = 1920000000, @@ -140,8 +140,9 @@ static struct kgsl_device_platform_data kgsl_3d0_pdata = { .io_fraction = 100, }, { - .gpu_freq = 27000000, - .bus_freq = 0, + .gpu_freq = 192000000, + .bus_freq = 2, + .io_fraction = 100, }, }, .init_level = 0, From 7e8e1cf4033e383143bfaf3c9786f6eb0ace19bf Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Mon, 6 Feb 2012 18:23:19 -0800 Subject: [PATCH 10/11] msm: kgsl: Context switch fixes for A3XX In A3xx GPU state during context switching is saved from shadow RAM. Changed to use correct shadow ram base address by default. Gmem quad restore height and width is fixed to right values. Fixed A3XX_GRAS_SC_CONTROL to right value. Change-Id: I8589545183d2c4f5081c290bf453a86693542c79 Signed-off-by: Tarun Karra --- drivers/gpu/msm/adreno_a3xx.c | 14 ++++++-------- drivers/gpu/msm/adreno_drawctxt.c | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index cde170e8812..9d9e09e13fa 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -127,13 +127,8 @@ const unsigned int a3xx_registers_count = ARRAY_SIZE(a3xx_registers) / 2; #define HLSQ_MEMOBJ_OFFSET 0x400 #define HLSQ_MIPMAP_OFFSET 0x800 -#ifdef GSL_USE_A3XX_HLSQ_SHADOW_RAM /* Use shadow RAM */ #define HLSQ_SHADOW_BASE (0x10000+SSIZE*2) -#else -/* Use working RAM */ -#define HLSQ_SHADOW_BASE 0x10000 -#endif #define REG_TO_MEM_LOOP_COUNT_SHIFT 15 @@ -1315,7 +1310,8 @@ static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev, _SET(SP_FSCTRLREG1_FSINITIALOUTSTANDING, 2) | _SET(SP_FSCTRLREG1_HALFPRECVAROFFSET, 63); /* SP_FS_OBJ_OFFSET_REG */ - *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128); + *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128) | + _SET(SP_OBJOFFSETREG_SHADEROBJOFFSETINIC, 1); /* SP_FS_OBJ_START_REG */ *cmds++ = 0x00000000; @@ -1654,7 +1650,9 @@ static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev, *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2); *cmds++ = CP_REG(A3XX_GRAS_SC_CONTROL); /* GRAS_SC_CONTROL */ - *cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1); + /*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1); + *cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1) |*/ + *cmds++ = 0x04001000; *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2); *cmds++ = CP_REG(A3XX_GRAS_SU_MODE_CONTROL); @@ -2569,7 +2567,7 @@ static void a3xx_start(struct adreno_device *adreno_dev) adreno_regwrite(device, A3XX_RBBM_AHB_CTL0, 0x00000001); /* Enable AHB error reporting */ - adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0xA6FFFFFF); + adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0x86FFFFFF); /* Turn on the power counters */ adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00003000); diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c index 9bf85cfa927..aeb89b3a8fe 100644 --- a/drivers/gpu/msm/adreno_drawctxt.c +++ b/drivers/gpu/msm/adreno_drawctxt.c @@ -86,7 +86,7 @@ static void set_gmem_copy_quad(struct gmem_shadow_t *shadow) gmem_restore_quad[7] = uint2float(shadow->width); memcpy(shadow->quad_vertices.hostptr, gmem_copy_quad, QUAD_LEN << 2); - memcpy(shadow->quad_vertices_restore.hostptr, gmem_copy_quad, + memcpy(shadow->quad_vertices_restore.hostptr, gmem_restore_quad, QUAD_RESTORE_LEN << 2); memcpy(shadow->quad_texcoords.hostptr, gmem_copy_texcoord, From 375feb228e1e8b582969328ff8d89fd9ca227791 Mon Sep 17 00:00:00 2001 From: Tarun Karra Date: Wed, 8 Feb 2012 20:42:38 -0800 Subject: [PATCH 11/11] msm: kgsl: Disable ME, PFP split timeout and VFD interrupts. The ME and PFP split timeout interrupts are fired when a wait for idle does not get a response within the specified time limit, which happens to be far too low for this revision of the hardware. The VFD interrupt is harmless since we aways set the VFD range to the maximum addressible size. All these interrupts can be safely removed. Change-Id: I32e714782a3c5a042b64360c1f6bcb7f8a9750db Signed-off-by: Tarun Karra --- drivers/gpu/msm/adreno_a3xx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 9d9e09e13fa..f68bc419836 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -2426,10 +2426,7 @@ static void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq) #define A3XX_INT_MASK \ ((1 << A3XX_INT_RBBM_AHB_ERROR) | \ (1 << A3XX_INT_RBBM_REG_TIMEOUT) | \ - (1 << A3XX_INT_RBBM_ME_MS_TIMEOUT) | \ - (1 << A3XX_INT_RBBM_PFP_MS_TIMEOUT) | \ (1 << A3XX_INT_RBBM_ATB_BUS_OVERFLOW) | \ - (1 << A3XX_INT_VFD_ERROR) | \ (1 << A3XX_INT_CP_T0_PACKET_IN_IB) | \ (1 << A3XX_INT_CP_OPCODE_ERROR) | \ (1 << A3XX_INT_CP_RESERVED_BIT_ERROR) | \