Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

kgsl: update based on semc code

Kangd from jerpelea (FreeXperia)
  • Loading branch information...
commit c02c7dfddf7f05ff8e19c0012248507e51d1edee 1 parent 68b2945
@TomGiordano TomGiordano authored
Showing with 13,560 additions and 10,794 deletions.
  1. +14 −2 arch/arm/configs/cyanogen_blade_defconfig
  2. +2 −1  arch/arm/configs/cyanogen_skate_defconfig
  3. +2 −1  arch/arm/configs/cyanogen_v9_defconfig
  4. +47 −53 arch/arm/mach-msm/board-zte-blade.c
  5. +50 −52 arch/arm/mach-msm/board-zte-skate.c
  6. +50 −52 arch/arm/mach-msm/board-zte-turies.c
  7. +47 −53 arch/arm/mach-msm/board-zte-v9.c
  8. +37 −20 drivers/gpu/msm/Kconfig
  9. +26 −16 drivers/gpu/msm/Makefile
  10. +169 −189 drivers/gpu/msm/{yamato_reg.h → a2xx_reg.h}
  11. +1,304 −0 drivers/gpu/msm/adreno.c
  12. +129 −0 drivers/gpu/msm/adreno.h
  13. +1,607 −0 drivers/gpu/msm/adreno_a2xx.c
  14. +73 −128 drivers/gpu/msm/{kgsl_log.c → adreno_debugfs.c}
  15. +40 −0 drivers/gpu/msm/adreno_debugfs.h
  16. +266 −0 drivers/gpu/msm/adreno_drawctxt.c
  17. +151 −0 drivers/gpu/msm/adreno_drawctxt.h
  18. +193 −0 drivers/gpu/msm/adreno_pm4types.h
  19. +878 −0 drivers/gpu/msm/adreno_postmortem.c
  20. +21 −0 drivers/gpu/msm/adreno_postmortem.h
  21. +812 −0 drivers/gpu/msm/adreno_ringbuffer.c
  22. +154 −0 drivers/gpu/msm/adreno_ringbuffer.h
  23. +0 −97 drivers/gpu/msm/g12_reg.h
  24. +1,641 −1,249 drivers/gpu/msm/kgsl.c
  25. +96 −99 drivers/gpu/msm/kgsl.h
  26. +175 −75 drivers/gpu/msm/kgsl_cffdump.c
  27. +20 −24 drivers/gpu/msm/kgsl_cffdump.h
  28. +0 −119 drivers/gpu/msm/kgsl_cmdstream.c
  29. +0 −87 drivers/gpu/msm/kgsl_cmdstream.h
  30. +87 −0 drivers/gpu/msm/kgsl_debugfs.c
  31. +39 −0 drivers/gpu/msm/kgsl_debugfs.h
  32. +184 −107 drivers/gpu/msm/kgsl_device.h
  33. +0 −1,878 drivers/gpu/msm/kgsl_drawctxt.c
  34. +0 −135 drivers/gpu/msm/kgsl_drawctxt.h
  35. +75 −127 drivers/gpu/msm/kgsl_drm.c
  36. +0 −867 drivers/gpu/msm/kgsl_g12.c
  37. +0 −69 drivers/gpu/msm/kgsl_g12.h
  38. +0 −249 drivers/gpu/msm/kgsl_g12_cmdstream.c
  39. +0 −52 drivers/gpu/msm/kgsl_g12_cmdstream.h
  40. +0 −63 drivers/gpu/msm/kgsl_g12_cmdwindow.c
  41. +0 −38 drivers/gpu/msm/kgsl_g12_cmdwindow.h
  42. +0 −50 drivers/gpu/msm/kgsl_g12_drawctxt.c
  43. +0 −77 drivers/gpu/msm/kgsl_g12_drawctxt.h
  44. +0 −40 drivers/gpu/msm/kgsl_g12_vgv3types.h
  45. +767 −0 drivers/gpu/msm/kgsl_gpummu.c
  46. +85 −0 drivers/gpu/msm/kgsl_gpummu.h
  47. +333 −0 drivers/gpu/msm/kgsl_iommu.c
  48. +68 −85 drivers/gpu/msm/kgsl_log.h
  49. +527 −568 drivers/gpu/msm/kgsl_mmu.c
  50. +140 −155 drivers/gpu/msm/kgsl_mmu.h
  51. +0 −193 drivers/gpu/msm/kgsl_pm4types.h
  52. +0 −687 drivers/gpu/msm/kgsl_postmortem.c
  53. +0 −39 drivers/gpu/msm/kgsl_postmortem.h
  54. +550 −177 drivers/gpu/msm/kgsl_pwrctrl.c
  55. +53 −65 drivers/gpu/msm/kgsl_pwrctrl.h
  56. +339 −0 drivers/gpu/msm/kgsl_pwrscale.c
  57. +77 −0 drivers/gpu/msm/kgsl_pwrscale.h
  58. +221 −0 drivers/gpu/msm/kgsl_pwrscale_idlestats.c
  59. +197 −0 drivers/gpu/msm/kgsl_pwrscale_trustzone.c
  60. +0 −795 drivers/gpu/msm/kgsl_ringbuffer.c
  61. +0 −212 drivers/gpu/msm/kgsl_ringbuffer.h
  62. +526 −178 drivers/gpu/msm/kgsl_sharedmem.c
  63. +104 −93 drivers/gpu/msm/kgsl_sharedmem.h
  64. +0 −1,340 drivers/gpu/msm/kgsl_yamato.c
  65. +0 −63 drivers/gpu/msm/kgsl_yamato.h
  66. +0 −39 drivers/gpu/msm/leia_reg.h
  67. +953 −0 drivers/gpu/msm/z180.c
  68. +35 −0 drivers/gpu/msm/z180.h
  69. +49 −0 drivers/gpu/msm/z180_reg.h
  70. +10 −2 fs/anon_inodes.c
  71. +136 −34 include/linux/msm_kgsl.h
  72. +1 −0  lib/memory_alloc.c
View
16 arch/arm/configs/cyanogen_blade_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.35.7
-# Thu Dec 8 03:30:17 2011
+# Tue Jan 17 20:33:52 2012
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -162,10 +162,14 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_CFQ is not set
CONFIG_IOSCHED_BFQ=y
# CONFIG_CGROUP_BFQIO is not set
+# CONFIG_IOSCHED_VR is not set
+# CONFIG_IOSCHED_SIO is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_BFQ=y
# CONFIG_DEFAULT_NOOP is not set
+# CONFIG_DEFAULT_VR is not set
+# CONFIG_DEFAULT_SIO is not set
CONFIG_DEFAULT_IOSCHED="bfq"
# CONFIG_INLINE_SPIN_TRYLOCK is not set
# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
@@ -505,6 +509,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_SMARTASS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_LAGFREE is not set
+# CONFIG_CPU_FREQ_GOV_INTERACTIVEX is not set
+# CONFIG_CPU_FREQ_GOV_SAVAGEDZEN is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -513,6 +520,10 @@ CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SMARTASS=y
CONFIG_CPU_FREQ_GOV_SMARTASS2=y
+# CONFIG_CPU_FREQ_GOV_MINMAX is not set
+CONFIG_CPU_FREQ_MIN_TICKS=10
+CONFIG_CPU_FREQ_SAMPLING_LATENCY_MULTIPLIER=1000
+# CONFIG_CPU_FREQ_GOV_LAGFREE is not set
# CONFIG_CPU_IDLE is not set
CONFIG_CPU_FREQ_MSM=y
@@ -1536,9 +1547,10 @@ CONFIG_MSM_KGSL=y
# CONFIG_MSM_KGSL_PSTMRTMDMP_CP_STAT_NO_DETAIL is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_RB_HEX is not set
-# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_REG_DUMP is not set
+CONFIG_MSM_KGSL_GPUMMU=y
CONFIG_MSM_KGSL_MMU=y
# CONFIG_KGSL_PER_PROCESS_PAGE_TABLE is not set
+CONFIG_MSM_KGSL_PAGE_TABLE_SIZE=0xFFF0000
CONFIG_MSM_KGSL_MMU_PAGE_FAULT=y
# CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES is not set
# CONFIG_VGASTATE is not set
View
3  arch/arm/configs/cyanogen_skate_defconfig
@@ -1536,9 +1536,10 @@ CONFIG_MSM_KGSL=y
# CONFIG_MSM_KGSL_PSTMRTMDMP_CP_STAT_NO_DETAIL is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_RB_HEX is not set
-# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_REG_DUMP is not set
+CONFIG_MSM_KGSL_GPUMMU=y
CONFIG_MSM_KGSL_MMU=y
# CONFIG_KGSL_PER_PROCESS_PAGE_TABLE is not set
+CONFIG_MSM_KGSL_PAGE_TABLE_SIZE=0xFFF0000
CONFIG_MSM_KGSL_MMU_PAGE_FAULT=y
# CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES is not set
# CONFIG_VGASTATE is not set
View
3  arch/arm/configs/cyanogen_v9_defconfig
@@ -1520,9 +1520,10 @@ CONFIG_MSM_KGSL=y
# CONFIG_MSM_KGSL_PSTMRTMDMP_CP_STAT_NO_DETAIL is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_IB_DUMP is not set
# CONFIG_MSM_KGSL_PSTMRTMDMP_RB_HEX is not set
-# CONFIG_MSM_KGSL_PSTMRTMDMP_NO_REG_DUMP is not set
+CONFIG_MSM_KGSL_GPUMMU=y
CONFIG_MSM_KGSL_MMU=y
# CONFIG_KGSL_PER_PROCESS_PAGE_TABLE is not set
+CONFIG_MSM_KGSL_PAGE_TABLE_SIZE=0xFFF0000
CONFIG_MSM_KGSL_MMU_PAGE_FAULT=y
# CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES is not set
# CONFIG_VGASTATE is not set
View
100 arch/arm/mach-msm/board-zte-blade.c
@@ -1070,31 +1070,56 @@ static void __init bt_power_init(void)
#endif
#ifdef CONFIG_ARCH_MSM7X27
-static struct resource kgsl_resources[] = {
- {
- .name = "kgsl_reg_memory",
- .start = 0xA0000000,
- .end = 0xA001ffff,
- .flags = IORESOURCE_MEM,
+
+static struct resource kgsl_3d0_resources[] = {
+ {
+ .name = KGSL_3D0_REG_MEMORY,
+ .start = 0xA0000000,
+ .end = 0xA001ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = KGSL_3D0_IRQ,
+ .start = INT_GRAPHICS,
+ .end = INT_GRAPHICS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+ .pwr_data = {
+ .pwrlevel = {
+ {
+ .gpu_freq = 128000000,
+ .bus_freq = 128000000,
+ },
+ },
+ .init_level = 0,
+ .num_levels = 1,
+ .set_grp_async = NULL,
+ .idle_timeout = HZ/5,
+ .nap_allowed = true,
},
- {
- .name = "kgsl_yamato_irq",
- .start = INT_GRAPHICS,
- .end = INT_GRAPHICS,
- .flags = IORESOURCE_IRQ,
+ .clk = {
+ .name = {
+ .clk = "grp_clk",
+ .pclk = "grp_pclk",
+ },
+ },
+ .imem_clk_name = {
+ .clk = "imem_clk",
+ .pclk = NULL,
},
};
-static struct kgsl_platform_data kgsl_pdata;
-
-static struct platform_device msm_device_kgsl = {
- .name = "kgsl",
- .id = -1,
- .num_resources = ARRAY_SIZE(kgsl_resources),
- .resource = kgsl_resources,
- .dev = {
- .platform_data = &kgsl_pdata,
- },
+struct platform_device msm_kgsl_3d0 = {
+ .name = "kgsl-3d0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+ .resource = kgsl_3d0_resources,
+ .dev = {
+ .platform_data = &kgsl_3d0_pdata,
+ },
};
#endif
@@ -2637,7 +2662,7 @@ static struct platform_device *devices[] __initdata = {
&msm_bluesleep_device,
&msm_bcmsleep_device, //compatible of qualcomm and broadcomm bluetooth chip ZTE_BT_QXX_20101207
#ifdef CONFIG_ARCH_MSM7X27
- &msm_device_kgsl,
+ &msm_kgsl_3d0,
#endif
#ifdef CONFIG_MT9P111
/*
@@ -3373,38 +3398,7 @@ static void __init msm7x2x_init(void)
msm_acpu_clock_init(&msm7x2x_clock_data);
#ifdef CONFIG_ZTE_PLATFORM
init_usb3v3();//USB-HML-001 enable ldo.
- #endif
-#ifdef CONFIG_ARCH_MSM7X27
- // /* Initialize the zero page for barriers and cache ops */
- // map_zero_page_strongly_ordered();
- /* This value has been set to 160000 for power savings. */
- /* OEMs may modify the value at their discretion for performance */
- /* The appropriate maximum replacement for 160000 is: */
- /* clk_get_max_axi_khz() */
- kgsl_pdata.high_axi_3d = 160000;
-
- /* 7x27 doesn't allow graphics clocks to be run asynchronously to */
- /* the AXI bus */
- kgsl_pdata.max_grp2d_freq = 0;
- kgsl_pdata.min_grp2d_freq = 0;
- kgsl_pdata.set_grp2d_async = NULL;
- kgsl_pdata.max_grp3d_freq = 0;
- kgsl_pdata.min_grp3d_freq = 0;
- kgsl_pdata.set_grp3d_async = NULL;
- kgsl_pdata.imem_clk_name = "imem_clk";
- kgsl_pdata.grp3d_clk_name = "grp_clk";
- kgsl_pdata.grp3d_pclk_name = "grp_pclk";
- kgsl_pdata.grp2d0_clk_name = NULL;
- kgsl_pdata.idle_timeout_3d = HZ/5;
- kgsl_pdata.idle_timeout_2d = 0;
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
- kgsl_pdata.pt_va_size = SZ_32M;
-#else
- kgsl_pdata.pt_va_size = SZ_128M;
#endif
-#endif
-
-
#if defined( CONFIG_TOUCHSCREEN_MSM_LEGACY) || defined( CONFIG_TOUCHSCREEN_MSM)
msm_device_tssc.dev.platform_data = &msm_tssc_pdata;
View
102 arch/arm/mach-msm/board-zte-skate.c
@@ -1349,31 +1349,56 @@ static void __init bt_power_init(void)
#endif
#ifdef CONFIG_ARCH_MSM7X27
-static struct resource kgsl_resources[] = {
- {
- .name = "kgsl_reg_memory",
- .start = 0xA0000000,
- .end = 0xA001ffff,
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "kgsl_yamato_irq",
- .start = INT_GRAPHICS,
- .end = INT_GRAPHICS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct kgsl_platform_data kgsl_pdata;
-static struct platform_device msm_device_kgsl = {
- .name = "kgsl",
- .id = -1,
- .num_resources = ARRAY_SIZE(kgsl_resources),
- .resource = kgsl_resources,
- .dev = {
- .platform_data = &kgsl_pdata,
- },
+static struct resource kgsl_3d0_resources[] = {
+ {
+ .name = KGSL_3D0_REG_MEMORY,
+ .start = 0xA0000000,
+ .end = 0xA001ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = KGSL_3D0_IRQ,
+ .start = INT_GRAPHICS,
+ .end = INT_GRAPHICS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+ .pwr_data = {
+ .pwrlevel = {
+ {
+ .gpu_freq = 128000000,
+ .bus_freq = 128000000,
+ },
+ },
+ .init_level = 0,
+ .num_levels = 1,
+ .set_grp_async = NULL,
+ .idle_timeout = HZ/5,
+ .nap_allowed = true,
+ },
+ .clk = {
+ .name = {
+ .clk = "grp_clk",
+ .pclk = "grp_pclk",
+ },
+ },
+ .imem_clk_name = {
+ .clk = "imem_clk",
+ .pclk = NULL,
+ },
+};
+
+struct platform_device msm_kgsl_3d0 = {
+ .name = "kgsl-3d0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+ .resource = kgsl_3d0_resources,
+ .dev = {
+ .platform_data = &kgsl_3d0_pdata,
+ },
};
#endif
@@ -2623,7 +2648,7 @@ static struct platform_device *devices[] __initdata = {
&msm_bluesleep_device,
&msm_bcmsleep_device,
#ifdef CONFIG_ARCH_MSM7X27
- &msm_device_kgsl,
+ &msm_kgsl_3d0,
#endif
#ifdef CONFIG_MT9P111
&msm_camera_sensor_mt9p111,
@@ -3245,33 +3270,6 @@ static void __init msm7x2x_init(void)
msm_acpu_clock_init(&msm7x2x_clock_data);
#ifdef CONFIG_ZTE_PLATFORM
init_usb3v3();
- #endif
-#ifdef CONFIG_ARCH_MSM7X27
- /* This value has been set to 160000 for power savings. */
- /* OEMs may modify the value at their discretion for performance */
- /* The appropriate maximum replacement for 160000 is: */
- /* clk_get_max_axi_khz() */
- kgsl_pdata.high_axi_3d = 160000;
-
- /* 7x27 doesn't allow graphics clocks to be run asynchronously to */
- /* the AXI bus */
- kgsl_pdata.max_grp2d_freq = 0;
- kgsl_pdata.min_grp2d_freq = 0;
- kgsl_pdata.set_grp2d_async = NULL;
- kgsl_pdata.max_grp3d_freq = 0;
- kgsl_pdata.min_grp3d_freq = 0;
- kgsl_pdata.set_grp3d_async = NULL;
- kgsl_pdata.imem_clk_name = "imem_clk";
- kgsl_pdata.grp3d_clk_name = "grp_clk";
- kgsl_pdata.grp3d_pclk_name = "grp_pclk";
- kgsl_pdata.grp2d0_clk_name = NULL;
- kgsl_pdata.idle_timeout_3d = HZ/5;
- kgsl_pdata.idle_timeout_2d = 0;
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
- kgsl_pdata.pt_va_size = SZ_32M;
-#else
- kgsl_pdata.pt_va_size = SZ_128M;
-#endif
#endif
#if defined( CONFIG_TOUCHSCREEN_MSM_LEGACY) || defined( CONFIG_TOUCHSCREEN_MSM)
View
102 arch/arm/mach-msm/board-zte-turies.c
@@ -1362,31 +1362,56 @@ static void __init bt_power_init(void)
#endif
#ifdef CONFIG_ARCH_MSM7X27
-static struct resource kgsl_resources[] = {
- {
- .name = "kgsl_reg_memory",
- .start = 0xA0000000,
- .end = 0xA001ffff,
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "kgsl_yamato_irq",
- .start = INT_GRAPHICS,
- .end = INT_GRAPHICS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct kgsl_platform_data kgsl_pdata;
-static struct platform_device msm_device_kgsl = {
- .name = "kgsl",
- .id = -1,
- .num_resources = ARRAY_SIZE(kgsl_resources),
- .resource = kgsl_resources,
- .dev = {
- .platform_data = &kgsl_pdata,
- },
+static struct resource kgsl_3d0_resources[] = {
+ {
+ .name = KGSL_3D0_REG_MEMORY,
+ .start = 0xA0000000,
+ .end = 0xA001ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = KGSL_3D0_IRQ,
+ .start = INT_GRAPHICS,
+ .end = INT_GRAPHICS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+ .pwr_data = {
+ .pwrlevel = {
+ {
+ .gpu_freq = 128000000,
+ .bus_freq = 128000000,
+ },
+ },
+ .init_level = 0,
+ .num_levels = 1,
+ .set_grp_async = NULL,
+ .idle_timeout = HZ/5,
+ .nap_allowed = true,
+ },
+ .clk = {
+ .name = {
+ .clk = "grp_clk",
+ .pclk = "grp_pclk",
+ },
+ },
+ .imem_clk_name = {
+ .clk = "imem_clk",
+ .pclk = NULL,
+ },
+};
+
+struct platform_device msm_kgsl_3d0 = {
+ .name = "kgsl-3d0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+ .resource = kgsl_3d0_resources,
+ .dev = {
+ .platform_data = &kgsl_3d0_pdata,
+ },
};
#endif
@@ -2805,7 +2830,7 @@ static struct platform_device *devices[] __initdata = {
&msm_bluesleep_device,
&msm_bcmsleep_device, //compatible of qualcomm and broadcomm bluetooth chip
#ifdef CONFIG_ARCH_MSM7X27
- &msm_device_kgsl,
+ &msm_kgsl_3d0,
#endif
#ifdef CONFIG_MT9P111
@@ -3459,33 +3484,6 @@ static void __init msm7x2x_init(void)
msm_acpu_clock_init(&msm7x2x_clock_data);
#ifdef CONFIG_ZTE_PLATFORM
init_usb3v3();
- #endif
-#ifdef CONFIG_ARCH_MSM7X27
- /* This value has been set to 160000 for power savings. */
- /* OEMs may modify the value at their discretion for performance */
- /* The appropriate maximum replacement for 160000 is: */
- /* clk_get_max_axi_khz() */
- kgsl_pdata.high_axi_3d = 160000;
-
- /* 7x27 doesn't allow graphics clocks to be run asynchronously to */
- /* the AXI bus */
- kgsl_pdata.max_grp2d_freq = 0;
- kgsl_pdata.min_grp2d_freq = 0;
- kgsl_pdata.set_grp2d_async = NULL;
- kgsl_pdata.max_grp3d_freq = 0;
- kgsl_pdata.min_grp3d_freq = 0;
- kgsl_pdata.set_grp3d_async = NULL;
- kgsl_pdata.imem_clk_name = "imem_clk";
- kgsl_pdata.grp3d_clk_name = "grp_clk";
- kgsl_pdata.grp3d_pclk_name = "grp_pclk";
- kgsl_pdata.grp2d0_clk_name = NULL;
- kgsl_pdata.idle_timeout_3d = HZ/5;
- kgsl_pdata.idle_timeout_2d = 0;
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
- kgsl_pdata.pt_va_size = SZ_32M;
-#else
- kgsl_pdata.pt_va_size = SZ_128M;
-#endif
#endif
#if defined( CONFIG_TOUCHSCREEN_MSM_LEGACY) || defined( CONFIG_TOUCHSCREEN_MSM)
View
100 arch/arm/mach-msm/board-zte-v9.c
@@ -1092,31 +1092,56 @@ static void __init bt_power_init(void)
#endif
#ifdef CONFIG_ARCH_MSM7X27
-static struct resource kgsl_resources[] = {
- {
- .name = "kgsl_reg_memory",
- .start = 0xA0000000,
- .end = 0xA001ffff,
- .flags = IORESOURCE_MEM,
+
+static struct resource kgsl_3d0_resources[] = {
+ {
+ .name = KGSL_3D0_REG_MEMORY,
+ .start = 0xA0000000,
+ .end = 0xA001ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = KGSL_3D0_IRQ,
+ .start = INT_GRAPHICS,
+ .end = INT_GRAPHICS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+ .pwr_data = {
+ .pwrlevel = {
+ {
+ .gpu_freq = 128000000,
+ .bus_freq = 128000000,
+ },
+ },
+ .init_level = 0,
+ .num_levels = 1,
+ .set_grp_async = NULL,
+ .idle_timeout = HZ/5,
+ .nap_allowed = true,
},
- {
- .name = "kgsl_yamato_irq",
- .start = INT_GRAPHICS,
- .end = INT_GRAPHICS,
- .flags = IORESOURCE_IRQ,
+ .clk = {
+ .name = {
+ .clk = "grp_clk",
+ .pclk = "grp_pclk",
+ },
+ },
+ .imem_clk_name = {
+ .clk = "imem_clk",
+ .pclk = NULL,
},
};
-static struct kgsl_platform_data kgsl_pdata;
-
-static struct platform_device msm_device_kgsl = {
- .name = "kgsl",
- .id = -1,
- .num_resources = ARRAY_SIZE(kgsl_resources),
- .resource = kgsl_resources,
- .dev = {
- .platform_data = &kgsl_pdata,
- },
+struct platform_device msm_kgsl_3d0 = {
+ .name = "kgsl-3d0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+ .resource = kgsl_3d0_resources,
+ .dev = {
+ .platform_data = &kgsl_3d0_pdata,
+ },
};
#endif
@@ -2488,7 +2513,7 @@ static struct platform_device *devices[] __initdata = {
&msm_bluesleep_device,
&msm_bcmsleep_device, //compatible of qualcomm and broadcomm bluetooth chip ZTE_BT_QXX_20101207
#ifdef CONFIG_ARCH_MSM7X27
- &msm_device_kgsl,
+ &msm_kgsl_3d0,
#endif
#ifdef CONFIG_MT9P111
/*
@@ -3143,38 +3168,7 @@ static void __init msm7x2x_init(void)
msm_acpu_clock_init(&msm7x2x_clock_data);
#ifdef CONFIG_ZTE_PLATFORM
init_usb3v3();//USB-HML-001 enable ldo.
- #endif
-#ifdef CONFIG_ARCH_MSM7X27
- // /* Initialize the zero page for barriers and cache ops */
- // map_zero_page_strongly_ordered();
- /* This value has been set to 160000 for power savings. */
- /* OEMs may modify the value at their discretion for performance */
- /* The appropriate maximum replacement for 160000 is: */
- /* clk_get_max_axi_khz() */
- kgsl_pdata.high_axi_3d = 160000;
-
- /* 7x27 doesn't allow graphics clocks to be run asynchronously to */
- /* the AXI bus */
- kgsl_pdata.max_grp2d_freq = 0;
- kgsl_pdata.min_grp2d_freq = 0;
- kgsl_pdata.set_grp2d_async = NULL;
- kgsl_pdata.max_grp3d_freq = 0;
- kgsl_pdata.min_grp3d_freq = 0;
- kgsl_pdata.set_grp3d_async = NULL;
- kgsl_pdata.imem_clk_name = "imem_clk";
- kgsl_pdata.grp3d_clk_name = "grp_clk";
- kgsl_pdata.grp3d_pclk_name = "grp_pclk";
- kgsl_pdata.grp2d0_clk_name = NULL;
- kgsl_pdata.idle_timeout_3d = HZ/5;
- kgsl_pdata.idle_timeout_2d = 0;
-#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
- kgsl_pdata.pt_va_size = SZ_32M;
-#else
- kgsl_pdata.pt_va_size = SZ_128M;
#endif
-#endif
-
-
#if defined( CONFIG_TOUCHSCREEN_MSM_LEGACY) || defined( CONFIG_TOUCHSCREEN_MSM)
msm_device_tssc.dev.platform_data = &msm_tssc_pdata;
View
57 drivers/gpu/msm/Kconfig
@@ -1,10 +1,9 @@
config MSM_KGSL
tristate "MSM 3D Graphics driver"
default n
- depends on FB && ARM && ARCH_MSM && !MSM_HW3D && ANDROID_PMEM
+ depends on ARCH_MSM && !ARCH_MSM7X00A && !ARCH_MSM7X25
select GENERIC_ALLOCATOR
select FW_LOADER
- select RELAY
---help---
3D graphics driver. Required to use hardware accelerated
OpenGL ES 2.0 and 1.1.
@@ -56,39 +55,57 @@ config MSM_KGSL_PSTMRTMDMP_RB_HEX
Use hex version for the ring-buffer in the post-mortem dump, instead
of the human readable version.
-config MSM_KGSL_PSTMRTMDMP_NO_REG_DUMP
- bool "Disable dumping of most registers in post-mortem dump"
- default n
- depends on MSM_KGSL
- ---help---
- For a more compact kernel log the extensive register hex dump
- can be turned off with this option. The register dump takes up
- so much space that vital other information gets cut from the
- post-mortem dump.
-
config MSM_KGSL_2D
- bool "Enable the 2D core. Required for OpenVG"
- default n
- depends on MSM_KGSL && !ARCH_MSM7X27
+ tristate "MSM 2D graphics driver. Required for OpenVG"
+ default y
+ depends on MSM_KGSL && !ARCH_MSM7X27 && !ARCH_MSM7X27A && !(ARCH_QSD8X50 && !MSM_SOC_REV_A)
config MSM_KGSL_DRM
bool "Build a DRM interface for the MSM_KGSL driver"
depends on MSM_KGSL && DRM
-config MSM_KGSL_MMU
+config MSM_KGSL_GPUMMU
bool "Enable the GPU MMU in the MSM_KGSL driver"
- depends on MSM_KGSL && MMU
+ depends on MSM_KGSL && !MSM_KGSL_CFF_DUMP
+ default y
+
+config MSM_KGSL_IOMMU
+ bool "Enable the use of IOMMU in the MSM_KGSL driver"
+ depends on MSM_KGSL && MSM_IOMMU && !MSM_KGSL_GPUMMU && !MSM_KGSL_CFF_DUMP
+
+config MSM_KGSL_MMU
+ bool
+ depends on MSM_KGSL_GPUMMU || MSM_KGSL_IOMMU
default y
config KGSL_PER_PROCESS_PAGE_TABLE
bool "Enable Per Process page tables for the KGSL driver"
default n
- depends on MSM_KGSL_MMU && !MSM_KGSL_DRM
+ depends on MSM_KGSL_GPUMMU && !MSM_KGSL_DRM
+ ---help---
+ The MMU will use per process pagetables when enabled.
+
+config MSM_KGSL_PAGE_TABLE_SIZE
+ hex "Size of pagetables"
+ default 0xFFF0000
+ ---help---
+ Sets the pagetable size used by the MMU. The max value
+ is 0xFFF0000 or (256M - 64K).
+
+config MSM_KGSL_PAGE_TABLE_COUNT
+ int "Minimum of concurrent pagetables to support"
+ default 8
+ depends on KGSL_PER_PROCESS_PAGE_TABLE
+ ---help---
+ Specify the number of pagetables to allocate at init time
+ This is the number of concurrent processes that are guaranteed to
+ to run at any time. Additional processes can be created dynamically
+ assuming there is enough contiguous memory to allocate the pagetable.
config MSM_KGSL_MMU_PAGE_FAULT
bool "Force the GPU MMU to page fault for unmapped regions"
- default n
- depends on MSM_KGSL_MMU
+ default y
+ depends on MSM_KGSL_GPUMMU
config MSM_KGSL_DISABLE_SHADOW_WRITES
bool "Disable register shadow writes for context switches"
View
42 drivers/gpu/msm/Makefile
@@ -1,24 +1,34 @@
ccflags-y := -Iinclude/drm
-msm_kgsl-y = \
- kgsl_drawctxt.o \
- kgsl_cmdstream.o \
+msm_kgsl_core-y = \
kgsl.o \
- kgsl_log.o \
- kgsl_mmu.o \
- kgsl_postmortem.o \
- kgsl_ringbuffer.o \
kgsl_sharedmem.o \
- kgsl_yamato.o \
- kgsl_g12_drawctxt.o \
- kgsl_g12_cmdwindow.o \
- kgsl_g12_cmdstream.o \
kgsl_pwrctrl.o \
- kgsl_g12.o
+ kgsl_pwrscale.o \
+ kgsl_mmu.o \
+ kgsl_gpummu.o
+
+msm_kgsl_core-$(CONFIG_DEBUG_FS) += kgsl_debugfs.o
+msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
+msm_kgsl_core-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
+msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
+msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS) += kgsl_pwrscale_idlestats.o
+
+msm_adreno-y += \
+ adreno_ringbuffer.o \
+ adreno_drawctxt.o \
+ adreno_postmortem.o \
+ adreno_a2xx.o \
+ adreno.o
+
+msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o
-msm_kgsl-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
-msm_kgsl-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
+msm_z180-y += z180.o
-msm_kgsl-objs = $(msm_kgsl-y)
+msm_kgsl_core-objs = $(msm_kgsl_core-y)
+msm_adreno-objs = $(msm_adreno-y)
+msm_z180-objs = $(msm_z180-y)
-obj-$(CONFIG_MSM_KGSL) += msm_kgsl.o
+obj-$(CONFIG_MSM_KGSL) += msm_kgsl_core.o
+obj-$(CONFIG_MSM_KGSL) += msm_adreno.o
+obj-$(CONFIG_MSM_KGSL_2D) += msm_z180.o
View
358 drivers/gpu/msm/yamato_reg.h → drivers/gpu/msm/a2xx_reg.h
@@ -1,139 +1,128 @@
-/* Copyright (c) 2002,2007-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Code Aurora Forum, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * 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
+ * only version 2 as published by the Free Software Foundation.
*
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
*/
-#ifndef _YAMATO_REG_H
-#define _YAMATO_REG_H
+#ifndef __A200_REG_H
+#define __A200_REG_H
enum VGT_EVENT_TYPE {
- VS_DEALLOC = 0,
- PS_DEALLOC = 1,
- VS_DONE_TS = 2,
- PS_DONE_TS = 3,
- CACHE_FLUSH_TS = 4,
- CONTEXT_DONE = 5,
- CACHE_FLUSH = 6,
- VIZQUERY_START = 7,
- VIZQUERY_END = 8,
- SC_WAIT_WC = 9,
- RST_PIX_CNT = 13,
- RST_VTX_CNT = 14,
- TILE_FLUSH = 15,
- CACHE_FLUSH_AND_INV_TS_EVENT = 20,
- ZPASS_DONE = 21,
- CACHE_FLUSH_AND_INV_EVENT = 22,
- PERFCOUNTER_START = 23,
- PERFCOUNTER_STOP = 24,
- VS_FETCH_DONE = 27,
- FACENESS_FLUSH = 28,
+ VS_DEALLOC = 0,
+ PS_DEALLOC = 1,
+ VS_DONE_TS = 2,
+ PS_DONE_TS = 3,
+ CACHE_FLUSH_TS = 4,
+ CONTEXT_DONE = 5,
+ CACHE_FLUSH = 6,
+ VIZQUERY_START = 7,
+ VIZQUERY_END = 8,
+ SC_WAIT_WC = 9,
+ RST_PIX_CNT = 13,
+ RST_VTX_CNT = 14,
+ TILE_FLUSH = 15,
+ CACHE_FLUSH_AND_INV_TS_EVENT = 20,
+ ZPASS_DONE = 21,
+ CACHE_FLUSH_AND_INV_EVENT = 22,
+ PERFCOUNTER_START = 23,
+ PERFCOUNTER_STOP = 24,
+ VS_FETCH_DONE = 27,
+ FACENESS_FLUSH = 28,
};
enum COLORFORMATX {
- COLORX_4_4_4_4 = 0,
- COLORX_1_5_5_5 = 1,
- COLORX_5_6_5 = 2,
- COLORX_8 = 3,
- COLORX_8_8 = 4,
- COLORX_8_8_8_8 = 5,
- COLORX_S8_8_8_8 = 6,
- COLORX_16_FLOAT = 7,
- COLORX_16_16_FLOAT = 8,
- COLORX_16_16_16_16_FLOAT = 9,
- COLORX_32_FLOAT = 10,
- COLORX_32_32_FLOAT = 11,
- COLORX_32_32_32_32_FLOAT = 12,
- COLORX_2_3_3 = 13,
- COLORX_8_8_8 = 14,
+ COLORX_4_4_4_4 = 0,
+ COLORX_1_5_5_5 = 1,
+ COLORX_5_6_5 = 2,
+ COLORX_8 = 3,
+ COLORX_8_8 = 4,
+ COLORX_8_8_8_8 = 5,
+ COLORX_S8_8_8_8 = 6,
+ COLORX_16_FLOAT = 7,
+ COLORX_16_16_FLOAT = 8,
+ COLORX_16_16_16_16_FLOAT = 9,
+ COLORX_32_FLOAT = 10,
+ COLORX_32_32_FLOAT = 11,
+ COLORX_32_32_32_32_FLOAT = 12,
+ COLORX_2_3_3 = 13,
+ COLORX_8_8_8 = 14,
};
enum SURFACEFORMAT {
- FMT_1_REVERSE = 0,
- FMT_1 = 1,
- FMT_8 = 2,
- FMT_1_5_5_5 = 3,
- FMT_5_6_5 = 4,
- FMT_6_5_5 = 5,
- FMT_8_8_8_8 = 6,
- FMT_2_10_10_10 = 7,
- FMT_8_A = 8,
- FMT_8_B = 9,
- FMT_8_8 = 10,
- FMT_Cr_Y1_Cb_Y0 = 11,
- FMT_Y1_Cr_Y0_Cb = 12,
- FMT_5_5_5_1 = 13,
- FMT_8_8_8_8_A = 14,
- FMT_4_4_4_4 = 15,
- FMT_10_11_11 = 16,
- FMT_11_11_10 = 17,
- FMT_DXT1 = 18,
- FMT_DXT2_3 = 19,
- FMT_DXT4_5 = 20,
- FMT_24_8 = 22,
- FMT_24_8_FLOAT = 23,
- FMT_16 = 24,
- FMT_16_16 = 25,
- FMT_16_16_16_16 = 26,
- FMT_16_EXPAND = 27,
- FMT_16_16_EXPAND = 28,
- FMT_16_16_16_16_EXPAND = 29,
- FMT_16_FLOAT = 30,
- FMT_16_16_FLOAT = 31,
- FMT_16_16_16_16_FLOAT = 32,
- FMT_32 = 33,
- FMT_32_32 = 34,
- FMT_32_32_32_32 = 35,
- FMT_32_FLOAT = 36,
- FMT_32_32_FLOAT = 37,
- FMT_32_32_32_32_FLOAT = 38,
- FMT_32_AS_8 = 39,
- FMT_32_AS_8_8 = 40,
- FMT_16_MPEG = 41,
- FMT_16_16_MPEG = 42,
- FMT_8_INTERLACED = 43,
- FMT_32_AS_8_INTERLACED = 44,
- FMT_32_AS_8_8_INTERLACED = 45,
- FMT_16_INTERLACED = 46,
- FMT_16_MPEG_INTERLACED = 47,
- FMT_16_16_MPEG_INTERLACED = 48,
- FMT_DXN = 49,
- FMT_8_8_8_8_AS_16_16_16_16 = 50,
- FMT_DXT1_AS_16_16_16_16 = 51,
- FMT_DXT2_3_AS_16_16_16_16 = 52,
- FMT_DXT4_5_AS_16_16_16_16 = 53,
- FMT_2_10_10_10_AS_16_16_16_16 = 54,
- FMT_10_11_11_AS_16_16_16_16 = 55,
- FMT_11_11_10_AS_16_16_16_16 = 56,
- FMT_32_32_32_FLOAT = 57,
- FMT_DXT3A = 58,
- FMT_DXT5A = 59,
- FMT_CTX1 = 60,
- FMT_DXT3A_AS_1_1_1_1 = 61
+ FMT_1_REVERSE = 0,
+ FMT_1 = 1,
+ FMT_8 = 2,
+ FMT_1_5_5_5 = 3,
+ FMT_5_6_5 = 4,
+ FMT_6_5_5 = 5,
+ FMT_8_8_8_8 = 6,
+ FMT_2_10_10_10 = 7,
+ FMT_8_A = 8,
+ FMT_8_B = 9,
+ FMT_8_8 = 10,
+ FMT_Cr_Y1_Cb_Y0 = 11,
+ FMT_Y1_Cr_Y0_Cb = 12,
+ FMT_5_5_5_1 = 13,
+ FMT_8_8_8_8_A = 14,
+ FMT_4_4_4_4 = 15,
+ FMT_10_11_11 = 16,
+ FMT_11_11_10 = 17,
+ FMT_DXT1 = 18,
+ FMT_DXT2_3 = 19,
+ FMT_DXT4_5 = 20,
+ FMT_24_8 = 22,
+ FMT_24_8_FLOAT = 23,
+ FMT_16 = 24,
+ FMT_16_16 = 25,
+ FMT_16_16_16_16 = 26,
+ FMT_16_EXPAND = 27,
+ FMT_16_16_EXPAND = 28,
+ FMT_16_16_16_16_EXPAND = 29,
+ FMT_16_FLOAT = 30,
+ FMT_16_16_FLOAT = 31,
+ FMT_16_16_16_16_FLOAT = 32,
+ FMT_32 = 33,
+ FMT_32_32 = 34,
+ FMT_32_32_32_32 = 35,
+ FMT_32_FLOAT = 36,
+ FMT_32_32_FLOAT = 37,
+ FMT_32_32_32_32_FLOAT = 38,
+ FMT_32_AS_8 = 39,
+ FMT_32_AS_8_8 = 40,
+ FMT_16_MPEG = 41,
+ FMT_16_16_MPEG = 42,
+ FMT_8_INTERLACED = 43,
+ FMT_32_AS_8_INTERLACED = 44,
+ FMT_32_AS_8_8_INTERLACED = 45,
+ FMT_16_INTERLACED = 46,
+ FMT_16_MPEG_INTERLACED = 47,
+ FMT_16_16_MPEG_INTERLACED = 48,
+ FMT_DXN = 49,
+ FMT_8_8_8_8_AS_16_16_16_16 = 50,
+ FMT_DXT1_AS_16_16_16_16 = 51,
+ FMT_DXT2_3_AS_16_16_16_16 = 52,
+ FMT_DXT4_5_AS_16_16_16_16 = 53,
+ FMT_2_10_10_10_AS_16_16_16_16 = 54,
+ FMT_10_11_11_AS_16_16_16_16 = 55,
+ FMT_11_11_10_AS_16_16_16_16 = 56,
+ FMT_32_32_32_FLOAT = 57,
+ FMT_DXT3A = 58,
+ FMT_DXT5A = 59,
+ FMT_CTX1 = 60,
+ FMT_DXT3A_AS_1_1_1_1 = 61
};
+#define REG_PERF_MODE_CNT 0x0
+#define REG_PERF_STATE_RESET 0x0
+#define REG_PERF_STATE_ENABLE 0x1
+#define REG_PERF_STATE_FREEZE 0x2
+
#define RB_EDRAM_INFO_EDRAM_SIZE_SIZE 4
#define RB_EDRAM_INFO_EDRAM_MAPPING_MODE_SIZE 2
#define RB_EDRAM_INFO_UNUSED0_SIZE 8
@@ -208,10 +197,6 @@ union reg_cp_rb_cntl {
#define SQ_INT_CNTL__PS_WATCHDOG_MASK 0x00000001L
#define SQ_INT_CNTL__VS_WATCHDOG_MASK 0x00000002L
-#define MH_INTERRUPT_MASK__AXI_READ_ERROR 0x00000001L
-#define MH_INTERRUPT_MASK__AXI_WRITE_ERROR 0x00000002L
-#define MH_INTERRUPT_MASK__MMU_PAGE_FAULT 0x00000004L
-
#define RBBM_INT_CNTL__RDERR_INT_MASK 0x00000001L
#define RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK 0x00000002L
#define RBBM_INT_CNTL__GUI_IDLE_INT_MASK 0x00080000L
@@ -255,41 +240,29 @@ union reg_cp_rb_cntl {
#define RB_EDRAM_INFO__EDRAM_SIZE_MASK 0x0000000fL
#define RB_EDRAM_INFO__EDRAM_RANGE_MASK 0xffffc000L
-#define MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT 0x00000006
-#define MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT 0x00000007
-#define MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT 0x00000008
-#define MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT 0x00000009
-#define MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT 0x0000000a
-#define MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT 0x0000000d
-#define MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT 0x0000000e
-#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT 0x0000000f
-#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT 0x00000010
-#define MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT 0x00000016
-#define MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT 0x00000017
-#define MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT 0x00000018
-#define MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT 0x00000019
-#define MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT 0x0000001a
-
-#define MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT 0x00000004
-#define MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT 0x00000006
-#define MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT 0x00000008
-#define MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT 0x0000000a
-#define MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT 0x0000000c
-#define MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT 0x0000000e
-#define MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT 0x00000010
-#define MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT 0x00000012
-#define MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT 0x00000014
-#define MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT 0x00000016
-#define MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT 0x00000018
-
-#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0x00000000
-#define CP_RB_CNTL__RB_BLKSZ__SHIFT 0x00000008
-#define CP_RB_CNTL__RB_POLL_EN__SHIFT 0x00000014
-#define CP_RB_CNTL__RB_NO_UPDATE__SHIFT 0x0000001b
-
-#define RB_COLOR_INFO__COLOR_FORMAT__SHIFT 0x00000000
-#define RB_EDRAM_INFO__EDRAM_MAPPING_MODE__SHIFT 0x00000004
-#define RB_EDRAM_INFO__EDRAM_RANGE__SHIFT 0x0000000e
+#define MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT 0x00000006
+#define MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT 0x00000007
+#define MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT 0x00000008
+#define MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT 0x00000009
+#define MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT 0x0000000a
+#define MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT 0x0000000d
+#define MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT 0x0000000e
+#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT 0x0000000f
+#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT 0x00000010
+#define MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT 0x00000016
+#define MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT 0x00000017
+#define MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT 0x00000018
+#define MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT 0x00000019
+#define MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT 0x0000001a
+
+#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0x00000000
+#define CP_RB_CNTL__RB_BLKSZ__SHIFT 0x00000008
+#define CP_RB_CNTL__RB_POLL_EN__SHIFT 0x00000014
+#define CP_RB_CNTL__RB_NO_UPDATE__SHIFT 0x0000001b
+
+#define RB_COLOR_INFO__COLOR_FORMAT__SHIFT 0x00000000
+#define RB_EDRAM_INFO__EDRAM_MAPPING_MODE__SHIFT 0x00000004
+#define RB_EDRAM_INFO__EDRAM_RANGE__SHIFT 0x0000000e
#define REG_CP_CSQ_IB1_STAT 0x01FE
#define REG_CP_CSQ_IB2_STAT 0x01FF
@@ -323,22 +296,16 @@ union reg_cp_rb_cntl {
#define REG_CP_ST_BASE 0x044D
#define REG_CP_ST_BUFSZ 0x044E
-#define REG_MASTER_INT_SIGNAL 0x03B7
+#define REG_CP_PERFMON_CNTL 0x0444
+#define REG_CP_PERFCOUNTER_SELECT 0x0445
+#define REG_CP_PERFCOUNTER_LO 0x0446
+#define REG_CP_PERFCOUNTER_HI 0x0447
-#define REG_MH_ARBITER_CONFIG 0x0A40
-#define REG_MH_INTERRUPT_CLEAR 0x0A44
-#define REG_MH_INTERRUPT_MASK 0x0A42
-#define REG_MH_INTERRUPT_STATUS 0x0A43
-#define REG_MH_MMU_CONFIG 0x0040
-#define REG_MH_MMU_INVALIDATE 0x0045
-#define REG_MH_MMU_MPU_BASE 0x0046
-#define REG_MH_MMU_MPU_END 0x0047
-#define REG_MH_MMU_PAGE_FAULT 0x0043
-#define REG_MH_MMU_PT_BASE 0x0042
-#define REG_MH_MMU_TRAN_ERROR 0x0044
-#define REG_MH_MMU_VA_RANGE 0x0041
-#define REG_MH_CLNT_INTF_CTRL_CONFIG1 0x0A54
-#define REG_MH_CLNT_INTF_CTRL_CONFIG2 0x0A55
+#define REG_RBBM_PERFCOUNTER1_SELECT 0x0395
+#define REG_RBBM_PERFCOUNTER1_HI 0x0398
+#define REG_RBBM_PERFCOUNTER1_LO 0x0397
+
+#define REG_MASTER_INT_SIGNAL 0x03B7
#define REG_PA_CL_VPORT_XSCALE 0x210F
#define REG_PA_CL_VPORT_ZOFFSET 0x2114
@@ -361,7 +328,7 @@ union reg_cp_rb_cntl {
#define REG_PA_SU_POLY_OFFSET_FRONT_SCALE 0x2380
#define REG_PA_SU_SC_MODE_CNTL 0x2205
-#define REG_PC_INDEX_OFFSET 0x2102
+#define REG_PC_INDEX_OFFSET 0x2102
#define REG_RBBM_CNTL 0x003B
#define REG_RBBM_INT_ACK 0x03B6
@@ -387,7 +354,7 @@ union reg_cp_rb_cntl {
#define REG_RB_EDRAM_INFO 0x0F02
#define REG_RB_MODECONTROL 0x2208
#define REG_RB_SURFACE_INFO 0x2000
-#define REG_RB_SAMPLE_POS 0x220a
+#define REG_RB_SAMPLE_POS 0x220a
#define REG_SCRATCH_ADDR 0x01DD
#define REG_SCRATCH_REG0 0x0578
@@ -397,6 +364,7 @@ union reg_cp_rb_cntl {
#define REG_SQ_CF_BOOLEANS 0x4900
#define REG_SQ_CF_LOOP 0x4908
#define REG_SQ_GPR_MANAGEMENT 0x0D00
+#define REG_SQ_FLOW_CONTROL 0x0D01
#define REG_SQ_INST_STORE_MANAGMENT 0x0D02
#define REG_SQ_INT_ACK 0x0D36
#define REG_SQ_INT_CNTL 0x0D34
@@ -412,9 +380,9 @@ union reg_cp_rb_cntl {
#define REG_VGT_MAX_VTX_INDX 0x2100
#define REG_VGT_MIN_VTX_INDX 0x2101
-#define REG_TP0_CHICKEN 0x0E1E
-#define REG_TC_CNTL_STATUS 0x0E00
-#define REG_PA_SC_AA_CONFIG 0x2301
+#define REG_TP0_CHICKEN 0x0E1E
+#define REG_TC_CNTL_STATUS 0x0E00
+#define REG_PA_SC_AA_CONFIG 0x2301
#define REG_VGT_VERTEX_REUSE_BLOCK_CNTL 0x2316
#define REG_SQ_INTERPOLATOR_CNTL 0x2182
#define REG_RB_DEPTH_INFO 0x2002
@@ -428,11 +396,23 @@ union reg_cp_rb_cntl {
#define REG_SQ_CONSTANT_0 0x4000
#define REG_SQ_FETCH_0 0x4800
-#define REG_MH_AXI_ERROR 0xA45
-#define REG_MH_DEBUG_CTRL 0xA4E
-#define REG_MH_DEBUG_DATA 0xA4F
-#define REG_COHER_BASE_PM4 0xA2A
-#define REG_COHER_STATUS_PM4 0xA2B
-#define REG_COHER_SIZE_PM4 0xA29
-
-#endif /* _YAMATO_REG_H */
+#define REG_COHER_BASE_PM4 0xA2A
+#define REG_COHER_STATUS_PM4 0xA2B
+#define REG_COHER_SIZE_PM4 0xA29
+
+/*registers added in adreno220*/
+#define REG_A220_PC_INDX_OFFSET REG_VGT_INDX_OFFSET
+#define REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL REG_VGT_VERTEX_REUSE_BLOCK_CNTL
+#define REG_A220_PC_MAX_VTX_INDX REG_VGT_MAX_VTX_INDX
+#define REG_A220_RB_LRZ_VSC_CONTROL 0x2209
+#define REG_A220_GRAS_CONTROL 0x2210
+#define REG_A220_VSC_BIN_SIZE 0x0C01
+#define REG_A220_VSC_PIPE_DATA_LENGTH_7 0x0C1D
+
+/*registers added in adreno225*/
+#define REG_A225_RB_COLOR_INFO3 0x2005
+#define REG_A225_PC_MULTI_PRIM_IB_RESET_INDX 0x2103
+#define REG_A225_GRAS_UCP0X 0x2340
+#define REG_A225_GRAS_UCP_ENABLED 0x2360
+
+#endif /* __A200_REG_H */
View
1,304 drivers/gpu/msm/adreno.c
@@ -0,0 +1,1304 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/ioctl.h>
+#include <linux/sched.h>
+
+#include "kgsl.h"
+#include "kgsl_pwrscale.h"
+#include "kgsl_cffdump.h"
+#include "kgsl_sharedmem.h"
+
+#include "adreno.h"
+#include "adreno_pm4types.h"
+#include "adreno_debugfs.h"
+#include "adreno_postmortem.h"
+
+#include "a2xx_reg.h"
+#include "kgsl_mmu.h"
+
+#define cpu_is_msm7x01() 0
+#define cpu_is_msm7x30() 1
+#define cpu_is_qsd8x50() 0
+#define cpu_is_msm8x60() 0
+#define cpu_is_msm8960() 0
+#define cpu_is_msm8930() 0
+
+#define DRIVER_VERSION_MAJOR 3
+#define DRIVER_VERSION_MINOR 1
+
+/* Adreno MH arbiter config*/
+#define ADRENO_CFG_MHARB \
+ (0x10 \
+ | (0 << MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT) \
+ | (0 << MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT) \
+ | (0 << MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT) \
+ | (0x8 << MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT) \
+ | (1 << MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT))
+
+#define ADRENO_MMU_CONFIG \
+ (0x01 \
+ | (MMU_CONFIG << MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT) \
+ | (MMU_CONFIG << MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT))
+
+static const struct kgsl_functable adreno_functable;
+
+static struct adreno_device device_3d0 = {
+ .dev = {
+ .name = DEVICE_3D0_NAME,
+ .id = KGSL_DEVICE_3D0,
+ .ver_major = DRIVER_VERSION_MAJOR,
+ .ver_minor = DRIVER_VERSION_MINOR,
+ .mh = {
+ .mharb = ADRENO_CFG_MHARB,
+ /* Remove 1k boundary check in z470 to avoid a GPU
+ * hang. Notice that this solution won't work if
+ * both EBI and SMI are used
+ */
+ .mh_intf_cfg1 = 0x00032f07,
+ /* turn off memory protection unit by setting
+ acceptable physical address range to include
+ all pages. */
+ .mpu_base = 0x00000000,
+ .mpu_range = 0xFFFFF000,
+ },
+ .mmu = {
+ .config = ADRENO_MMU_CONFIG,
+ },
+ .pwrctrl = {
+ .pwr_rail = PWR_RAIL_GRP_CLK,
+ .regulator_name = "fs_gfx3d",
+ .irq_name = KGSL_3D0_IRQ,
+ .src_clk_name = "grp_src_clk",
+ },
+ .mutex = __MUTEX_INITIALIZER(device_3d0.dev.mutex),
+ .state = KGSL_STATE_INIT,
+ .active_cnt = 0,
+ .iomemname = KGSL_3D0_REG_MEMORY,
+ .ftbl = &adreno_functable,
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ .display_off = {
+ .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING,
+ .suspend = kgsl_early_suspend_driver,
+ .resume = kgsl_late_resume_driver,
+ },
+#endif
+ },
+ .gmemspace = {
+ .gpu_base = 0,
+ .sizebytes = SZ_256K,
+ },
+ .pfp_fw = NULL,
+ .pm4_fw = NULL,
+};
+
+/*
+ * This is the master list of all GPU cores that are supported by this
+ * driver.
+ */
+
+#define ANY_ID (~0)
+
+static const struct {
+ enum adreno_gpurev gpurev;
+ unsigned int core, major, minor, patchid;
+ const char *pm4fw;
+ const char *pfpfw;
+ struct adreno_gpudev *gpudev;
+} adreno_gpulist[] = {
+ { ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
+ "yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev },
+ { ADRENO_REV_A205, 0, 1, 0, ANY_ID,
+ "yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev },
+ { ADRENO_REV_A220, 2, 1, ANY_ID, ANY_ID,
+ "leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev },
+ /*
+ * 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 },
+ { ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID,
+ "a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev },
+};
+
+static void adreno_gmeminit(struct adreno_device *adreno_dev)
+{
+ struct kgsl_device *device = &adreno_dev->dev;
+ union reg_rb_edram_info rb_edram_info;
+ unsigned int gmem_size;
+ unsigned int edram_value = 0;
+
+ /* make sure edram range is aligned to size */
+ BUG_ON(adreno_dev->gmemspace.gpu_base &
+ (adreno_dev->gmemspace.sizebytes - 1));
+
+ /* get edram_size value equivalent */
+ gmem_size = (adreno_dev->gmemspace.sizebytes >> 14);
+ while (gmem_size >>= 1)
+ edram_value++;
+
+ rb_edram_info.val = 0;
+
+ rb_edram_info.f.edram_size = edram_value;
+ rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */
+
+ /* must be aligned to size */
+ rb_edram_info.f.edram_range = (adreno_dev->gmemspace.gpu_base >> 14);
+
+ adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
+}
+
+static irqreturn_t adreno_isr(int irq, void *data)
+{
+ irqreturn_t result;
+ struct kgsl_device *device = data;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ result = adreno_dev->gpudev->irq_handler(adreno_dev);
+
+ if (device->requested_state == KGSL_STATE_NONE) {
+ if (device->pwrctrl.nap_allowed == true) {
+ device->requested_state = KGSL_STATE_NAP;
+ queue_work(device->work_queue, &device->idle_check_ws);
+ } else if (device->pwrscale.policy != NULL) {
+ queue_work(device->work_queue, &device->idle_check_ws);
+ }
+ }
+
+ /* Reset the time-out in our idle timer */
+ mod_timer(&device->idle_timer,
+ jiffies + device->pwrctrl.interval_timeout);
+ return result;
+}
+
+static void adreno_cleanup_pt(struct kgsl_device *device,
+ struct kgsl_pagetable *pagetable)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+
+ kgsl_mmu_unmap(pagetable, &rb->buffer_desc);
+
+ kgsl_mmu_unmap(pagetable, &rb->memptrs_desc);
+
+ kgsl_mmu_unmap(pagetable, &device->memstore);
+
+ kgsl_mmu_unmap(pagetable, &device->mmu.setstate_memory);
+}
+
+static int adreno_setup_pt(struct kgsl_device *device,
+ struct kgsl_pagetable *pagetable)
+{
+ int result = 0;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+
+ result = kgsl_mmu_map_global(pagetable, &rb->buffer_desc,
+ GSL_PT_PAGE_RV);
+ if (result)
+ goto error;
+
+ result = kgsl_mmu_map_global(pagetable, &rb->memptrs_desc,
+ GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ if (result)
+ goto unmap_buffer_desc;
+
+ result = kgsl_mmu_map_global(pagetable, &device->memstore,
+ GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ if (result)
+ goto unmap_memptrs_desc;
+
+ result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory,
+ GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ if (result)
+ goto unmap_memstore_desc;
+
+ return result;
+
+unmap_memstore_desc:
+ kgsl_mmu_unmap(pagetable, &device->memstore);
+
+unmap_memptrs_desc:
+ kgsl_mmu_unmap(pagetable, &rb->memptrs_desc);
+
+unmap_buffer_desc:
+ kgsl_mmu_unmap(pagetable, &rb->buffer_desc);
+
+error:
+ return result;
+}
+
+static void adreno_setstate(struct kgsl_device *device,
+ uint32_t flags)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ unsigned int link[32];
+ unsigned int *cmds = &link[0];
+ int sizedwords = 0;
+ unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
+
+ /* If possible, then set the state via the command stream to avoid
+ a CPU idle. Otherwise, use the default setstate which uses register
+ writes */
+ if (adreno_dev->drawctxt_active) {
+ if (flags & KGSL_MMUFLAGS_PTUPDATE) {
+ /* wait for graphics pipe to be idle */
+ *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
+ *cmds++ = 0x00000000;
+
+ /* set page table base */
+ *cmds++ = cp_type0_packet(MH_MMU_PT_BASE, 1);
+ *cmds++ = kgsl_pt_get_base_addr(
+ device->mmu.hwpagetable);
+ sizedwords += 4;
+ }
+
+ if (flags & KGSL_MMUFLAGS_TLBFLUSH) {
+ if (!(flags & KGSL_MMUFLAGS_PTUPDATE)) {
+ *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE,
+ 1);
+ *cmds++ = 0x00000000;
+ sizedwords += 2;
+ }
+ *cmds++ = cp_type0_packet(MH_MMU_INVALIDATE, 1);
+ *cmds++ = mh_mmu_invalidate;
+ sizedwords += 2;
+ }
+
+ if (flags & KGSL_MMUFLAGS_PTUPDATE &&
+ adreno_is_a20x(adreno_dev)) {
+ /* HW workaround: to resolve MMU page fault interrupts
+ * caused by the VGT.It prevents the CP PFP from filling
+ * the VGT DMA request fifo too early,thereby ensuring
+ * that the VGT will not fetch vertex/bin data until
+ * after the page table base register has been updated.
+ *
+ * Two null DRAW_INDX_BIN packets are inserted right
+ * after the page table base update, followed by a
+ * wait for idle. The null packets will fill up the
+ * VGT DMA request fifo and prevent any further
+ * vertex/bin updates from occurring until the wait
+ * has finished. */
+ *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
+ *cmds++ = (0x4 << 16) |
+ (REG_PA_SU_SC_MODE_CNTL - 0x2000);
+ *cmds++ = 0; /* disable faceness generation */
+ *cmds++ = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
+ *cmds++ = device->mmu.setstate_memory.gpuaddr;
+ *cmds++ = cp_type3_packet(CP_DRAW_INDX_BIN, 6);
+ *cmds++ = 0; /* viz query info */
+ *cmds++ = 0x0003C004; /* draw indicator */
+ *cmds++ = 0; /* bin base */
+ *cmds++ = 3; /* bin size */
+ *cmds++ =
+ device->mmu.setstate_memory.gpuaddr; /* dma base */
+ *cmds++ = 6; /* dma size */
+ *cmds++ = cp_type3_packet(CP_DRAW_INDX_BIN, 6);
+ *cmds++ = 0; /* viz query info */
+ *cmds++ = 0x0003C004; /* draw indicator */
+ *cmds++ = 0; /* bin base */
+ *cmds++ = 3; /* bin size */
+ /* dma base */
+ *cmds++ = device->mmu.setstate_memory.gpuaddr;
+ *cmds++ = 6; /* dma size */
+ *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
+ *cmds++ = 0x00000000;
+ sizedwords += 21;
+ }
+
+
+ if (flags & (KGSL_MMUFLAGS_PTUPDATE | KGSL_MMUFLAGS_TLBFLUSH)) {
+ *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
+ *cmds++ = 0x7fff; /* invalidate all base pointers */
+ sizedwords += 2;
+ }
+
+ adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+ &link[0], sizedwords);
+ } else {
+ kgsl_mmu_device_setstate(device, flags);
+ }
+}
+
+static unsigned int
+adreno_getchipid(struct kgsl_device *device)
+{
+ unsigned int chipid = 0;
+ unsigned int coreid, majorid, minorid, patchid, revid;
+
+ adreno_regread(device, REG_RBBM_PERIPHID1, &coreid);
+ adreno_regread(device, REG_RBBM_PERIPHID2, &majorid);
+ adreno_regread(device, REG_RBBM_PATCH_RELEASE, &revid);
+
+ /*
+ * adreno 22x gpus are indicated by coreid 2,
+ * but REG_RBBM_PERIPHID1 always contains 0 for this field
+ */
+ if (cpu_is_msm8960() || cpu_is_msm8x60() || cpu_is_msm8930())
+ chipid = 2 << 24;
+ else
+ chipid = (coreid & 0xF) << 24;
+
+ chipid |= ((majorid >> 4) & 0xF) << 16;
+
+ minorid = ((revid >> 0) & 0xFF);
+
+ patchid = ((revid >> 16) & 0xFF);
+
+ /* 8x50 returns 0 for patch release, but it should be 1 */
+ if (cpu_is_qsd8x50())
+ patchid = 1;
+
+ chipid |= (minorid << 8) | patchid;
+
+ return chipid;
+}
+
+static inline bool _rev_match(unsigned int id, unsigned int entry)
+{
+ return (entry == ANY_ID || entry == id);
+}
+
+static void
+adreno_identify_gpu(struct adreno_device *adreno_dev)
+{
+ unsigned int i, core, major, minor, patchid;
+
+ adreno_dev->chip_id = adreno_getchipid(&adreno_dev->dev);
+
+ core = (adreno_dev->chip_id >> 24) & 0xff;
+ major = (adreno_dev->chip_id >> 16) & 0xff;
+ minor = (adreno_dev->chip_id >> 8) & 0xff;
+ patchid = (adreno_dev->chip_id & 0xff);
+
+ for (i = 0; i < ARRAY_SIZE(adreno_gpulist); i++) {
+ if (core == adreno_gpulist[i].core &&
+ _rev_match(major, adreno_gpulist[i].major) &&
+ _rev_match(minor, adreno_gpulist[i].minor) &&
+ _rev_match(patchid, adreno_gpulist[i].patchid))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(adreno_gpulist)) {
+ adreno_dev->gpurev = ADRENO_REV_UNKNOWN;
+ return;
+ }
+
+ adreno_dev->gpurev = adreno_gpulist[i].gpurev;
+ adreno_dev->gpudev = adreno_gpulist[i].gpudev;
+ adreno_dev->pfp_fwfile = adreno_gpulist[i].pfpfw;
+ adreno_dev->pm4_fwfile = adreno_gpulist[i].pm4fw;
+}
+
+static int __devinit
+adreno_probe(struct platform_device *pdev)
+{
+ struct kgsl_device *device;
+ struct adreno_device *adreno_dev;
+ int status = -EINVAL;
+
+ device = (struct kgsl_device *)pdev->id_entry->driver_data;
+ adreno_dev = ADRENO_DEVICE(device);
+ device->parentdev = &pdev->dev;
+
+ adreno_dev->wait_timeout = 10000; /* default value in milliseconds */
+
+ init_completion(&device->recovery_gate);
+
+ status = adreno_ringbuffer_init(device);
+ if (status != 0)
+ goto error;
+
+ status = kgsl_device_platform_probe(device, adreno_isr);
+ if (status)
+ goto error_close_rb;
+
+ adreno_debugfs_init(device);
+
+ kgsl_pwrscale_init(device);
+ kgsl_pwrscale_attach_policy(device, ADRENO_DEFAULT_PWRSCALE_POLICY);
+
+ device->flags &= ~KGSL_FLAGS_SOFT_RESET;
+ return 0;
+
+error_close_rb:
+ adreno_ringbuffer_close(&adreno_dev->ringbuffer);
+error:
+ device->parentdev = NULL;
+ return status;
+}
+
+static int __devexit adreno_remove(struct platform_device *pdev)
+{
+ struct kgsl_device *device;
+ struct adreno_device *adreno_dev;
+
+ device = (struct kgsl_device *)pdev->id_entry->driver_data;
+ adreno_dev = ADRENO_DEVICE(device);
+
+ kgsl_pwrscale_detach_policy(device);
+ kgsl_pwrscale_close(device);
+
+ adreno_ringbuffer_close(&adreno_dev->ringbuffer);
+ kgsl_device_platform_remove(device);
+
+ return 0;
+}
+
+static int adreno_start(struct kgsl_device *device, unsigned int init_ram)
+{
+ int status = -EINVAL;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ int init_reftimestamp = 0x7fffffff;
+
+ device->state = KGSL_STATE_INIT;
+ device->requested_state = KGSL_STATE_NONE;
+
+ /* Power up the device */
+ kgsl_pwrctrl_enable(device);
+
+ /* Identify the specific GPU */
+ adreno_identify_gpu(adreno_dev);
+
+ if (adreno_dev->gpurev == ADRENO_REV_UNKNOWN) {
+ KGSL_DRV_ERR(device, "Unknown chip ID %x\n",
+ adreno_dev->chip_id);
+ goto error_clk_off;
+ }
+
+ if (adreno_is_a20x(adreno_dev)) {
+ /*
+ * the MH_CLNT_INTF_CTRL_CONFIG registers aren't present
+ * on older gpus
+ */
+ device->mh.mh_intf_cfg1 = 0;
+ device->mh.mh_intf_cfg2 = 0;
+ }
+
+ kgsl_mh_start(device);
+
+ if (kgsl_mmu_start(device))
+ goto error_clk_off;
+
+ /*We need to make sure all blocks are powered up and clocked before
+ *issuing a soft reset. The overrides will then be turned off (set to 0)
+ */
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe);
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff);
+
+ /* Only reset CP block if all blocks have previously been reset */
+ if (!(device->flags & KGSL_FLAGS_SOFT_RESET) ||
+ !adreno_is_a22x(adreno_dev)) {
+ adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0xFFFFFFFF);
+ device->flags |= KGSL_FLAGS_SOFT_RESET;
+ } else
+ adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000001);
+
+ /* The core is in an indeterminate state until the reset completes
+ * after 30ms.
+ */
+ msleep(30);
+
+ adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000);
+
+ adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
+
+ if (adreno_is_a225(adreno_dev)) {
+ /* Enable large instruction store for A225 */
+ adreno_regwrite(device, REG_SQ_FLOW_CONTROL, 0x18000000);
+ }
+
+ adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
+ adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
+
+ if (cpu_is_msm8960() || cpu_is_msm8930())
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
+ else
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
+
+ if (!adreno_is_a22x(adreno_dev))
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0);
+ else
+ adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
+
+ kgsl_sharedmem_set(&device->memstore, 0, 0, device->memstore.size);
+
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ init_reftimestamp);
+
+ adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
+
+ /* Make sure interrupts are disabled */
+
+ adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
+ adreno_regwrite(device, REG_CP_INT_CNTL, 0);
+ adreno_regwrite(device, REG_SQ_INT_CNTL, 0);
+
+ if (adreno_is_a22x(adreno_dev))
+ adreno_dev->gmemspace.sizebytes = SZ_512K;
+ else
+ adreno_dev->gmemspace.sizebytes = SZ_256K;
+ adreno_gmeminit(adreno_dev);
+
+ kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
+
+ status = adreno_ringbuffer_start(&adreno_dev->ringbuffer, init_ram);
+ if (status != 0)
+ goto error_irq_off;
+
+ mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
+ return status;
+
+error_irq_off:
+ kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+ kgsl_mmu_stop(device);
+error_clk_off:
+ kgsl_pwrctrl_disable(device);
+
+ return status;
+}
+
+static int adreno_stop(struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ adreno_dev->drawctxt_active = NULL;
+
+ adreno_ringbuffer_stop(&adreno_dev->ringbuffer);
+
+ kgsl_mmu_stop(device);
+
+ kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+ del_timer_sync(&device->idle_timer);
+
+ /* Power down the device */
+ kgsl_pwrctrl_disable(device);
+
+ return 0;
+}
+
+static int
+adreno_recover_hang(struct kgsl_device *device)
+{
+ int ret;
+ unsigned int *rb_buffer;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+ unsigned int timestamp;
+ unsigned int num_rb_contents;
+ unsigned int bad_context;
+ unsigned int reftimestamp;
+ unsigned int enable_ts;
+ unsigned int soptimestamp;
+ unsigned int eoptimestamp;
+ struct adreno_context *drawctxt;
+
+ KGSL_DRV_ERR(device, "Starting recovery from 3D GPU hang....\n");
+ rb_buffer = vmalloc(rb->buffer_desc.size);
+ if (!rb_buffer) {
+ KGSL_MEM_ERR(device,
+ "Failed to allocate memory for recovery: %x\n",
+ rb->buffer_desc.size);
+ return -ENOMEM;
+ }
+ /* Extract valid contents from rb which can stil be executed after
+ * hang */
+ ret = adreno_ringbuffer_extract(rb, rb_buffer, &num_rb_contents);
+ if (ret)
+ goto done;
+ timestamp = rb->timestamp;
+ KGSL_DRV_ERR(device, "Last issued timestamp: %x\n", timestamp);
+ kgsl_sharedmem_readl(&device->memstore, &bad_context,
+ KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
+ kgsl_sharedmem_readl(&device->memstore, &reftimestamp,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
+ kgsl_sharedmem_readl(&device->memstore, &enable_ts,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
+ kgsl_sharedmem_readl(&device->memstore, &soptimestamp,
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
+ kgsl_sharedmem_readl(&device->memstore, &eoptimestamp,
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
+ /* Make sure memory is synchronized before restarting the GPU */
+ mb();
+ KGSL_CTXT_ERR(device,
+ "Context that caused a GPU hang: %x\n", bad_context);
+ /* restart device */
+ ret = adreno_stop(device);
+ if (ret)
+ goto done;
+ ret = adreno_start(device, true);
+ if (ret)
+ goto done;
+ KGSL_DRV_ERR(device, "Device has been restarted after hang\n");
+ /* Restore timestamp states */
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
+ soptimestamp);
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp),
+ eoptimestamp);
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
+ soptimestamp);
+ if (num_rb_contents) {
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ reftimestamp);
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
+ enable_ts);
+ }
+ /* Make sure all writes are posted before the GPU reads them */
+ wmb();
+ /* Mark the invalid context so no more commands are accepted from
+ * that context */
+
+ drawctxt = (struct adreno_context *) bad_context;
+
+ KGSL_CTXT_ERR(device,
+ "Context that caused a GPU hang: %x\n", bad_context);
+
+ drawctxt->flags |= CTXT_FLAGS_GPU_HANG;
+
+ /* Restore valid commands in ringbuffer */
+ adreno_ringbuffer_restore(rb, rb_buffer, num_rb_contents);
+ rb->timestamp = timestamp;
+done:
+ vfree(rb_buffer);
+ return ret;
+}
+
+static int
+adreno_dump_and_recover(struct kgsl_device *device)
+{
+ static int recovery;
+ int result = -ETIMEDOUT;
+
+ if (device->state == KGSL_STATE_HUNG)
+ goto done;
+ if (device->state == KGSL_STATE_DUMP_AND_RECOVER && !recovery) {
+ mutex_unlock(&device->mutex);
+ wait_for_completion(&device->recovery_gate);
+ mutex_lock(&device->mutex);
+ if (!(device->state & KGSL_STATE_HUNG))
+ /* recovery success */
+ result = 0;
+ } else {
+ INIT_COMPLETION(device->recovery_gate);
+ /* Detected a hang - trigger an automatic dump */
+ adreno_postmortem_dump(device, 0);
+ if (!recovery) {
+ recovery = 1;
+ result = adreno_recover_hang(device);
+ if (result)
+ device->state = KGSL_STATE_HUNG;
+ recovery = 0;
+ complete_all(&device->recovery_gate);
+ } else
+ KGSL_DRV_ERR(device,
+ "Cannot recover from another hang while "
+ "recovering from a hang\n");
+ }
+done:
+ return result;
+}
+
+static int adreno_getproperty(struct kgsl_device *device,
+ enum kgsl_property_type type,
+ void *value,
+ unsigned int sizebytes)
+{
+ int status = -EINVAL;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ switch (type) {
+ case KGSL_PROP_DEVICE_INFO:
+ {
+ struct kgsl_devinfo devinfo;
+
+ if (sizebytes != sizeof(devinfo)) {
+ status = -EINVAL;
+ break;
+ }
+
+ memset(&devinfo, 0, sizeof(devinfo));
+ devinfo.device_id = device->id+1;
+ devinfo.chip_id = adreno_dev->chip_id;
+ devinfo.mmu_enabled = kgsl_mmu_enabled();
+ devinfo.gpu_id = adreno_dev->gpurev;
+ devinfo.gmem_gpubaseaddr = adreno_dev->gmemspace.
+ gpu_base;
+ devinfo.gmem_sizebytes = adreno_dev->gmemspace.
+ sizebytes;
+
+ if (copy_to_user(value, &devinfo, sizeof(devinfo)) !=
+ 0) {
+ status = -EFAULT;
+ break;
+ }
+ status = 0;
+ }
+ break;
+ case KGSL_PROP_DEVICE_SHADOW:
+ {
+ struct kgsl_shadowprop shadowprop;
+
+ if (sizebytes != sizeof(shadowprop)) {
+ status = -EINVAL;
+ break;
+ }
+ memset(&shadowprop, 0, sizeof(shadowprop));
+ if (device->memstore.hostptr) {
+ /*NOTE: with mmu enabled, gpuaddr doesn't mean
+ * anything to mmap().
+ */
+ shadowprop.gpuaddr = device->memstore.physaddr;
+ shadowprop.size = device->memstore.size;
+ /* GSL needs this to be set, even if it
+ appears to be meaningless */
+ shadowprop.flags = KGSL_FLAGS_INITIALIZED;
+ }
+ if (copy_to_user(value, &shadowprop,
+ sizeof(shadowprop))) {
+ status = -EFAULT;
+ break;
+ }
+ status = 0;
+ }
+ break;
+ case KGSL_PROP_MMU_ENABLE:
+ {
+ int mmu_prop = kgsl_mmu_enabled();
+
+ if (sizebytes != sizeof(int)) {
+ status = -EINVAL;
+ break;
+ }
+ if (copy_to_user(value, &mmu_prop, sizeof(mmu_prop))) {
+ status = -EFAULT;
+ break;
+ }
+ status = 0;
+ }
+ break;
+ case KGSL_PROP_INTERRUPT_WAITS:
+ {
+ int int_waits = 1;
+ if (sizebytes != sizeof(int)) {
+ status = -EINVAL;
+ break;
+ }
+ if (copy_to_user(value, &int_waits, sizeof(int))) {
+ status = -EFAULT;
+ break;
+ }
+ status = 0;
+ }
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+/* Caller must hold the device mutex. */
+int adreno_idle(struct kgsl_device *device, unsigned int timeout)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+ unsigned int rbbm_status;
+ unsigned long wait_timeout =
+ msecs_to_jiffies(adreno_dev->wait_timeout);
+ unsigned long wait_time = jiffies + wait_timeout;
+
+ kgsl_cffdump_regpoll(device->id, REG_RBBM_STATUS << 2,
+ 0x00000000, 0x80000000);
+ /* first, wait until the CP has consumed all the commands in
+ * the ring buffer
+ */
+retry:
+ if (rb->flags & KGSL_FLAGS_STARTED) {
+ do {
+ GSL_RB_GET_READPTR(rb, &rb->rptr);
+ if (time_after(jiffies, wait_time)) {
+ KGSL_DRV_ERR(device, "rptr: %x, wptr: %x\n",
+ rb->rptr, rb->wptr);
+ goto err;
+ }
+ } while (rb->rptr != rb->wptr);
+ }
+
+ /* now, wait for the GPU to finish its operations */
+ wait_time = jiffies + wait_timeout;
+ while (time_before(jiffies, wait_time)) {
+ adreno_regread(device, REG_RBBM_STATUS, &rbbm_status);
+ if (rbbm_status == 0x110)
+ return 0;
+ }
+
+err:
+ KGSL_DRV_ERR(device, "spun too long waiting for RB to idle\n");
+ if (!adreno_dump_and_recover(device)) {
+ wait_time = jiffies + wait_timeout;
+ goto retry;
+ }
+ return -ETIMEDOUT;
+}
+
+static unsigned int adreno_isidle(struct kgsl_device *device)
+{
+ int status = false;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+ unsigned int rbbm_status;
+
+ if (rb->flags & KGSL_FLAGS_STARTED) {
+ /* Is the ring buffer is empty? */
+ GSL_RB_GET_READPTR(rb, &rb->rptr);
+ if (!device->active_cnt && (rb->rptr == rb->wptr)) {
+ /* Is the core idle? */
+ adreno_regread(device, REG_RBBM_STATUS,
+ &rbbm_status);
+ if (rbbm_status == 0x110)
+ status = true;
+ }
+ } else {
+ KGSL_DRV_ERR(device, "ringbuffer not started\n");
+ BUG();
+ }
+ return status;
+}
+
+/* Caller must hold the device mutex. */
+static int adreno_suspend_context(struct kgsl_device *device)
+{
+ int status = 0;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ /* switch to NULL ctxt */
+ if (adreno_dev->drawctxt_active != NULL) {
+ adreno_drawctxt_switch(adreno_dev, NULL, 0);
+ status = adreno_idle(device, KGSL_TIMEOUT_DEFAULT);
+ }
+
+ return status;
+}
+
+uint8_t *kgsl_sharedmem_convertaddr(struct kgsl_device *device,
+ unsigned int pt_base, unsigned int gpuaddr, unsigned int *size)
+{
+ uint8_t *result = NULL;
+ struct kgsl_mem_entry *entry;
+ struct kgsl_process_private *priv;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *ringbuffer = &adreno_dev->ringbuffer;
+
+ if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr)) {
+ return kgsl_gpuaddr_to_vaddr(&ringbuffer->buffer_desc,
+ gpuaddr, size);
+ }
+
+ if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr)) {
+ return kgsl_gpuaddr_to_vaddr(&ringbuffer->memptrs_desc,
+ gpuaddr, size);
+ }
+
+ if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr)) {
+ return kgsl_gpuaddr_to_vaddr(&device->memstore,
+ gpuaddr, size);
+ }
+
+ mutex_lock(&kgsl_driver.process_mutex);
+ list_for_each_entry(priv, &kgsl_driver.process_list, list) {
+ if (!kgsl_mmu_pt_equal(priv->pagetable, pt_base))
+ continue;
+ spin_lock(&priv->mem_lock);
+ entry = kgsl_sharedmem_find_region(priv, gpuaddr,
+ sizeof(unsigned int));
+ if (entry) {
+ result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
+ gpuaddr, size);
+ spin_unlock(&priv->mem_lock);
+ mutex_unlock(&kgsl_driver.process_mutex);
+ return result;
+ }
+ spin_unlock(&priv->mem_lock);
+ }
+ mutex_unlock(&kgsl_driver.process_mutex);
+
+ BUG_ON(!mutex_is_locked(&device->mutex));
+ list_for_each_entry(entry, &device->memqueue, list) {
+ if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr)) {
+ result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
+ gpuaddr, size);
+ break;
+ }
+
+ }
+ return result;
+}
+
+void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
+ unsigned int *value)
+{
+ unsigned int *reg;
+ BUG_ON(offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes);
+ reg = (unsigned int *)(device->regspace.mmio_virt_base
+ + (offsetwords << 2));
+
+ if (!in_interrupt())
+ kgsl_pre_hwaccess(device);
+
+ /*ensure this read finishes before the next one.
+ * i.e. act like normal readl() */
+ *value = __raw_readl(reg);
+ rmb();
+}
+
+void adreno_regwrite(struct kgsl_device *device, unsigned int offsetwords,
+ unsigned int value)
+{
+ unsigned int *reg;
+
+ BUG_ON(offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes);
+
+ if (!in_interrupt())
+ kgsl_pre_hwaccess(device);
+
+ kgsl_cffdump_regwrite(device->id, offsetwords << 2, value);
+ reg = (unsigned int *)(device->regspace.mmio_virt_base
+ + (offsetwords << 2));
+
+ /*ensure previous writes post before this one,
+ * i.e. act like normal writel() */
+ wmb();
+ __raw_writel(value, reg);
+}
+
+static int kgsl_check_interrupt_timestamp(struct kgsl_device *device,
+ unsigned int timestamp)
+{
+ int status;
+ unsigned int ref_ts, enableflag;
+
+ status = kgsl_check_timestamp(device, timestamp);
+ if (!status) {
+ mutex_lock(&device->mutex);
+ kgsl_sharedmem_readl(&device->memstore, &enableflag,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
+ mb();
+
+ if (enableflag) {
+ kgsl_sharedmem_readl(&device->memstore, &ref_ts,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
+ mb();
+ if (timestamp_cmp(ref_ts, timestamp)) {
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ timestamp);
+ wmb();
+ }
+ } else {
+ unsigned int cmds[2];
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
+ timestamp);
+ enableflag = 1;
+ kgsl_sharedmem_writel(&device->memstore,
+ KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
+ enableflag);
+ wmb();
+ /* submit a dummy packet so that even if all
+ * commands upto timestamp get executed we will still
+ * get an interrupt */
+ cmds[0] = cp_type3_packet(CP_NOP, 1);
+ cmds[1] = 0;
+ adreno_ringbuffer_issuecmds(device, 0, &cmds[0], 2);
+ }
+ mutex_unlock(&device->mutex);
+ }
+
+ return status;
+}
+
+/*
+ wait_event_interruptible_timeout checks for the exit condition before
+ placing a process in wait q. For conditional interrupts we expect the
+ process to already be in its wait q when its exit condition checking
+ function is called.
+*/
+#define kgsl_wait_event_interruptible_timeout(wq, condition, timeout, io)\
+({ \
+ long __ret = timeout; \
+ if (io) \
+ __wait_io_event_interruptible_timeout(wq, condition, __ret);\
+ else \
+ __wait_event_interruptible_timeout(wq, condition, __ret);\
+ __ret; \
+})
+
+/* MUST be called with the device mutex held */
+static int adreno_waittimestamp(struct kgsl_device *device,
+ unsigned int timestamp,
+ unsigned int msecs)
+{
+ long status = 0;
+ uint io = 1;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+
+ /* Don't wait forever, set a max value for now */
+ if (msecs == -1)
+ msecs = adreno_dev->wait_timeout;
+
+ if (timestamp != adreno_dev->ringbuffer.timestamp &&
+ timestamp_cmp(timestamp,
+ adreno_dev->ringbuffer.timestamp)) {
+ KGSL_DRV_ERR(device, "Cannot wait for invalid ts: %x, "
+ "rb->timestamp: %x\n",
+ timestamp, adreno_dev->ringbuffer.timestamp);
+ status = -EINVAL;
+ goto done;
+ }
+ if (!kgsl_check_timestamp(device, timestamp)) {
+ if (pwr->active_pwrlevel) {
+ int low_pwrlevel = pwr->num_pwrlevels -
+ KGSL_PWRLEVEL_LOW_OFFSET;
+ if (pwr->active_pwrlevel == low_pwrlevel)
+ io = 0;
+ }
+ mutex_unlock(&device->mutex);
+ /* We need to make sure that the process is placed in wait-q
+ * before its condition is called */
+ status = kgsl_wait_event_interruptible_timeout(
+ device->wait_queue,
+ kgsl_check_interrupt_timestamp(device,
+ timestamp),
+ msecs_to_jiffies(msecs), io);
+ mutex_lock(&device->mutex);
+
+ if (status > 0)
+ status = 0;
+ else if (status == 0) {
+ if (!kgsl_check_timestamp(device, timestamp)) {
+ status = -ETIMEDOUT;
+ KGSL_DRV_ERR(device,
+ "Device hang detected while waiting "
+ "for timestamp: %x, last "
+ "submitted(rb->timestamp): %x, wptr: "
+ "%x\n", timestamp,
+ adreno_dev->ringbuffer.timestamp,
+ adreno_dev->ringbuffer.wptr);
+ if (!adreno_dump_and_recover(device)) {
+ /* wait for idle after recovery as the
+ * timestamp that this process wanted
+ * to wait on may be invalid */
+ if (!adreno_idle(device,
+ KGSL_TIMEOUT_DEFAULT))
+ status = 0;
+ }
+ }
+ }
+ }
+
+done:
+ return (int)status;
+}
+
+static unsigned int adreno_readtimestamp(struct kgsl_device *device,
+ enum kgsl_timestamp_type type)
+{
+ unsigned int timestamp = 0;
+
+ if (type == KGSL_TIMESTAMP_CONSUMED)
+ adreno_regread(device, REG_CP_TIMESTAMP, &timestamp);
+ else if (type == KGSL_TIMESTAMP_RETIRED)
+ kgsl_sharedmem_readl(&device->memstore, &timestamp,
+ KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
+ rmb();
+
+ return timestamp;
+}
+
+static long adreno_ioctl(struct kgsl_device_private *dev_priv,
+ unsigned int cmd, void *data)
+{
+ int result = 0;
+ struct kgsl_drawctxt_set_bin_base_offset *binbase;
+ struct kgsl_context *context;
+
+ switch (cmd) {
+ case IOCTL_KGSL_DRAWCTXT_SET_BIN_BASE_OFFSET:
+ binbase = data;
+
+ context = kgsl_find_context(dev_priv, binbase->drawctxt_id);
+ if (context) {
+ adreno_drawctxt_set_bin_base_offset(
+ dev_priv->device, context, binbase->offset);
+ } else {
+ result = -EINVAL;
+ KGSL_DRV_ERR(dev_priv->device,
+ "invalid drawctxt drawctxt_