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, diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 805e2b687e2..9cbebbe1691 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) @@ -247,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 @@ -442,6 +456,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.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..f68bc419836 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, @@ -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 @@ -258,7 +253,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 +261,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; @@ -1313,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; @@ -1329,7 +1327,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 +1424,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); @@ -1652,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); @@ -2130,24 +2130,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 +2156,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; } @@ -2431,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) | \ @@ -2444,7 +2436,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 { @@ -2474,7 +2465,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 */ }; @@ -2547,6 +2538,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); @@ -2570,10 +2564,17 @@ 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); + + /* 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 */ diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c index aade50cd753..c8c7c441add 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); @@ -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; 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_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, 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, diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 36248ef2f75..671479ea9c0 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" @@ -534,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); @@ -712,7 +720,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))