Merge "Bluetooth: Increased the LE connection supervision timeout" into msm-3.0
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index eca2ffa..ed6a58c 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -266,9 +266,7 @@
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 18e9085..0bb87fb 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -267,9 +267,7 @@
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 02b2c33..e49cd3a 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -463,25 +463,25 @@
static struct acpu_level acpu_freq_tbl_8960_kraitv2_slow[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
{ 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
{ 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
{ 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1237500 },
{ 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1250000 },
{ 0, { 0 } }
@@ -490,25 +490,25 @@
static struct acpu_level acpu_freq_tbl_8960_kraitv2_nom[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1025000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1050000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1075000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 925000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 950000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 950000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 975000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 975000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1125000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
{ 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1150000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1175000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1175000 },
{ 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1175000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
{ 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1187500 },
{ 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1200000 },
{ 0, { 0 } }
@@ -517,25 +517,25 @@
static struct acpu_level acpu_freq_tbl_8960_kraitv2_fast[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 850000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 850000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 975000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1000000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1025000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 875000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 875000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 900000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 925000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 975000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 975000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1075000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
{ 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1100000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1125000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1125000 },
{ 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1125000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1137500 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1137500 },
{ 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1137500 },
{ 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1150000 },
{ 0, { 0 } }
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index a8c5d48..0357c40 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 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 @@
.io_fraction = 100,
},
{
- .gpu_freq = 27000000,
- .bus_freq = 0,
+ .gpu_freq = 192000000,
+ .bus_freq = 2,
+ .io_fraction = 100,
},
},
.init_level = 0,
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index f3eebce..c286c7f 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -97,6 +97,9 @@
};
VREG_CONSUMERS(L23) = {
REGULATOR_SUPPLY("8921_l23", NULL),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.1"),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.2"),
+
};
VREG_CONSUMERS(L24) = {
REGULATOR_SUPPLY("8921_l24", NULL),
@@ -106,6 +109,8 @@
REGULATOR_SUPPLY("8921_l25", NULL),
REGULATOR_SUPPLY("VDDD_CDC_D", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla2x-slim"),
};
VREG_CONSUMERS(L26) = {
REGULATOR_SUPPLY("8921_l26", NULL),
@@ -113,9 +118,11 @@
};
VREG_CONSUMERS(L27) = {
REGULATOR_SUPPLY("8921_l27", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.2"),
};
VREG_CONSUMERS(L28) = {
REGULATOR_SUPPLY("8921_l28", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.1"),
};
VREG_CONSUMERS(S1) = {
REGULATOR_SUPPLY("8921_s1", NULL),
@@ -139,6 +146,10 @@
REGULATOR_SUPPLY("CDC_VDD_CP", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla2x-slim"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
};
VREG_CONSUMERS(S5) = {
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 8212e15..e0bc723 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -499,8 +499,8 @@
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
};
static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 618d757..90cc3c5 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -40,6 +40,7 @@
#include <linux/ks8851.h>
#include <linux/i2c/isa1200.h>
#include <linux/gpio_keys.h>
+#include <linux/memory.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -429,12 +430,9 @@
if (high - low <= bank_size)
return;
- msm8930_reserve_info.low_unstable_address = low + bank_size;
- /* To avoid overflow of u32 compute max_unstable_size
- * by first subtracting low from mb->start)
- * */
- msm8930_reserve_info.max_unstable_size = (mb->start - low) +
- mb->size - bank_size;
+ msm8930_reserve_info.low_unstable_address = mb->start -
+ MIN_MEMORY_BLOCK_SIZE + mb->size;
+ msm8930_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
msm8930_reserve_info.bank_size = bank_size;
pr_info("low unstable address %lx max size %lx bank size %lx\n",
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index fb78ce7..c5169a8 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -81,6 +81,8 @@
}
};
+static void set_mdp_clocks_for_liquid_wuxga(void);
+
static int msm_fb_detect_panel(const char *name)
{
if (machine_is_msm8960_liquid()) {
@@ -88,8 +90,10 @@
if (SOCINFO_VERSION_MAJOR(ver) == 3) {
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
- PANEL_NAME_MAX_LEN)))
+ PANEL_NAME_MAX_LEN))) {
+ set_mdp_clocks_for_liquid_wuxga();
return 0;
+ }
} else {
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
@@ -643,6 +647,24 @@
#endif
};
+/**
+ * Set MDP clocks to high frequency to avoid DSI underflow
+ * when using high resolution 1200x1920 WUXGA panel.
+ */
+static void set_mdp_clocks_for_liquid_wuxga(void)
+{
+ int i;
+
+ mdp_ui_vectors[0].ab = 2000000000;
+ mdp_ui_vectors[0].ib = 2000000000;
+
+ mdp_pdata.mdp_core_clk_rate = 200000000;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+ mdp_core_clk_rate_table[i] = 200000000;
+
+}
+
void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
{
mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 786ec01..49539ef 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1022,12 +1022,54 @@
0x23, 0x83,/* set source impedance sdjusment */
-1};
+#ifdef CONFIG_MSM_BUS_SCALING
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 60000000, /* At least 480Mbps on bus. */
+ .ib = 960000000, /* MAX bursts rate */
+ },
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(usb_init_vectors),
+ usb_init_vectors,
+ },
+ {
+ ARRAY_SIZE(usb_max_vectors),
+ usb_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+ usb_bus_scale_usecases,
+ ARRAY_SIZE(usb_bus_scale_usecases),
+ .name = "usb",
+};
+#endif
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
.pmic_id_irq = PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
.power_budget = 750,
+#ifdef CONFIG_MSM_BUS_SCALING
+ .bus_scale_table = &usb_bus_scale_pdata,
+#endif
};
#endif
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index cb63395..f179bdf 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -381,6 +381,7 @@
#define LPASS_SLIMBUS_PHYS 0x28080000
#define LPASS_SLIMBUS_BAM_PHYS 0x28084000
+#define LPASS_SLIMBUS_SLEW (MSM8960_TLMM_PHYS + 0x207C)
/* Board info for the slimbus slave device */
static struct resource slimbus_res[] = {
{
@@ -396,6 +397,12 @@
.name = "slimbus_bam_physical",
},
{
+ .start = LPASS_SLIMBUS_SLEW,
+ .end = LPASS_SLIMBUS_SLEW + 4 - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "slimbus_slew_reg",
+ },
+ {
.start = SLIMBUS0_CORE_EE1_IRQ,
.end = SLIMBUS0_CORE_EE1_IRQ,
.flags = IORESOURCE_IRQ,
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 600a2e9..c856455 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -43,123 +43,10 @@
char *name;
int domain;
} msm_iommu_ctx_names[] = {
- /* Camera */
- {
- .name = "vpe_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vpe_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_imgwr",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_misc",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_vg1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_vg2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_rgb1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_rgb2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_mm1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_b_mm2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_stream",
- .domain = GLOBAL_DOMAIN,
- },
-};
-
-static struct mem_pool global_pools[] = {
- [VIDEO_FIRMWARE_POOL] =
- /* Low addresses, intended for video firmware */
- {
- .paddr = SZ_128K,
- .size = SZ_16M - SZ_128K,
- },
- [LOW_256MB_POOL] =
- /*
- * Video can only access first 256MB of memory
- * dedicated pool for such allocations
- */
- {
- .paddr = SZ_16M,
- .size = SZ_256M - SZ_16M,
- },
- [HIGH_POOL] =
- /* Remaining address space up to 2G */
- {
- .paddr = SZ_256M,
- .size = SZ_2G - SZ_256M,
- }
};
static struct msm_iommu_domain msm_iommu_domains[] = {
- [GLOBAL_DOMAIN] = {
- .iova_pools = global_pools,
- .npools = ARRAY_SIZE(global_pools),
- }
};
int msm_iommu_map_extra(struct iommu_domain *domain,
@@ -281,10 +168,8 @@
int msm_use_iommu()
{
- /*
- * For now, just detect if the iommu is attached.
- */
- return iommu_found();
+ /* Kill use of the iommu by these clients for now. */
+ return 0;
}
static int __init msm_subsystem_iommu_init(void)
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7ceae89..07322cd 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -124,7 +124,8 @@
*/
int chk_apps_master(void)
{
- if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615())
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_apq8064() || cpu_is_msm8627())
return 1;
else
return 0;
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index fc1cfb6..a6b0cf6 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -27,9 +27,11 @@
#include <linux/memory_alloc.h>
#include <linux/seq_file.h>
#include <linux/fmem.h>
+#include <linux/iommu.h>
#include <mach/msm_memtypes.h>
#include <mach/scm.h>
-#include "ion_priv.h"
+#include <mach/iommu_domains.h>
+ #include "ion_priv.h"
#include <asm/mach/map.h>
@@ -566,6 +568,103 @@
return ret_value;
}
+static int ion_cp_heap_map_iommu(struct ion_buffer *buffer,
+ struct ion_iommu_map *data,
+ unsigned int domain_num,
+ unsigned int partition_num,
+ unsigned long align,
+ unsigned long iova_length,
+ unsigned long flags)
+{
+ unsigned long temp_phys, temp_iova;
+ struct iommu_domain *domain;
+ int i, ret = 0;
+ unsigned long extra;
+
+ data->mapped_size = iova_length;
+
+ if (!msm_use_iommu()) {
+ data->iova_addr = buffer->priv_phys;
+ return 0;
+ }
+
+ extra = iova_length - buffer->size;
+
+ data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+ data->mapped_size, align);
+
+ if (!data->iova_addr) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ temp_iova = data->iova_addr;
+ temp_phys = buffer->priv_phys;
+ for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+ temp_phys += SZ_4K) {
+ ret = iommu_map(domain, temp_iova, temp_phys,
+ get_order(SZ_4K),
+ ION_IS_CACHED(flags) ? 1 : 0);
+
+ if (ret) {
+ pr_err("%s: could not map %lx to %lx in domain %p\n",
+ __func__, temp_iova, temp_phys, domain);
+ goto out2;
+ }
+ }
+
+ if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+ goto out2;
+
+ return 0;
+
+out2:
+ for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+ iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+out1:
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+out:
+ return ret;
+}
+
+static void ion_cp_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+ int i;
+ unsigned long temp_iova;
+ unsigned int domain_num;
+ unsigned int partition_num;
+ struct iommu_domain *domain;
+
+ if (!msm_use_iommu())
+ return;
+
+ domain_num = iommu_map_domain(data);
+ partition_num = iommu_map_partition(data);
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+ return;
+ }
+
+ temp_iova = data->iova_addr;
+ for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+ iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+
+ return;
+}
static struct ion_heap_ops cp_heap_ops = {
.allocate = ion_cp_heap_allocate,
@@ -581,6 +680,8 @@
.print_debug = ion_cp_print_debug,
.secure_heap = ion_cp_secure_heap,
.unsecure_heap = ion_cp_unsecure_heap,
+ .map_iommu = ion_cp_heap_map_iommu,
+ .unmap_iommu = ion_cp_heap_unmap_iommu,
};
struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *heap_data)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 805e2b6..9cbebbe 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -131,31 +131,35 @@
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)
@@ -248,6 +252,16 @@
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
* writes For CFF dump we must idle and use the registers so that it is
@@ -442,6 +456,7 @@
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 9c2d704..9498b80 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 @@
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 e31b76b..f2b1278 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -164,7 +164,8 @@
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 1bad811..f68bc41 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -34,7 +34,7 @@
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 @@
#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 @@
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 @@
virt2gpu(cmd, &drawctxt->gpustate);
cmd++;
+ start = cmd;
+
*cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
*cmd++ = 0;
@@ -1313,7 +1310,8 @@
_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 @@
/* 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 @@
_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 @@
*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_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 @@
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 @@
#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 @@
(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 @@
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 @@
{
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 @@
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 aade50c..c8c7c44 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -80,7 +80,7 @@
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 @@
*/
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 @@
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 @@
* 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 @@
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 c1b9e4c..b53ca8f 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -143,7 +143,8 @@
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 9bf85cf..aeb89b3 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -86,7 +86,7 @@
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 fb88a72..cc3f3e7 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -86,7 +86,7 @@
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 36248ef..671479e 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/iommu.h>
+#include <mach/socinfo.h>
#include "kgsl.h"
#include "kgsl_mmu.h"
@@ -534,9 +535,16 @@
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 @@
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))
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index af61bd2..86d62c9 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -73,43 +73,54 @@
static struct ispif_device *ispif;
+atomic_t ispif_irq_cnt;
+spinlock_t ispif_tasklet_lock;
+struct list_head ispif_tasklet_q;
static uint32_t global_intf_cmd_mask = 0xFFFFFFFF;
-static int msm_ispif_intf_reset(uint8_t intftype)
+
+static int msm_ispif_intf_reset(uint8_t intfmask)
{
int rc = 0;
- uint32_t data;
+ uint32_t data = 0x1;
+ uint8_t intfnum = 0, mask = intfmask;
+ while (mask != 0) {
+ if (!(intfmask & (0x1 << intfnum))) {
+ mask >>= 1;
+ intfnum++;
+ continue;
+ }
+ switch (intfnum) {
+ case PIX0:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << PIX_VFE_RST_STB) +
+ (0x1 << PIX_CSID_RST_STB);
+ break;
- switch (intftype) {
- case PIX0:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << PIX_VFE_RST_STB) +
- (0x1 << PIX_CSID_RST_STB);
+ case RDI0:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << RDI_VFE_RST_STB) +
+ (0x1 << RDI_CSID_RST_STB);
+ break;
+
+ case RDI1:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << RDI_1_VFE_RST_STB) +
+ (0x1 << RDI_1_CSID_RST_STB);
+ break;
+
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ mask >>= 1;
+ intfnum++;
+ } /*end while */
+ if (rc >= 0) {
msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- case RDI0:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << RDI_VFE_RST_STB) +
- (0x1 << RDI_CSID_RST_STB);
- msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- case RDI1:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << RDI_1_VFE_RST_STB) +
- (0x1 << RDI_1_CSID_RST_STB);
- msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- default:
- rc = -EINVAL;
- break;
+ rc = wait_for_completion_interruptible(&ispif->reset_complete);
}
- if (rc >= 0)
- rc = wait_for_completion_interruptible(
- &ispif->reset_complete);
return rc;
}
@@ -244,97 +255,109 @@
}
static void
-msm_ispif_intf_cmd(uint8_t intftype, uint8_t intf_cmd_mask)
+msm_ispif_intf_cmd(uint8_t intfmask, uint8_t intf_cmd_mask)
{
uint8_t vc = 0, val = 0;
- uint32_t cid_mask = msm_ispif_get_cid_mask(intftype);
-
- while (cid_mask != 0) {
- if ((cid_mask & 0xf) != 0x0) {
- val = (intf_cmd_mask>>(vc*2)) & 0x3;
- global_intf_cmd_mask &= ~((0x3 & ~val)
- <<((vc*2)+(intftype*8)));
- CDBG("intf cmd 0x%x\n", global_intf_cmd_mask);
- msm_io_w(global_intf_cmd_mask,
- ispif->base + ISPIF_INTF_CMD_ADDR);
+ uint8_t mask = intfmask, intfnum = 0;
+ uint32_t cid_mask = 0;
+ while (mask != 0) {
+ if (!(intfmask & (0x1 << intfnum))) {
+ mask >>= 1;
+ intfnum++;
+ continue;
}
- vc++;
- cid_mask >>= 4;
+
+ cid_mask = msm_ispif_get_cid_mask(intfnum);
+ vc = 0;
+
+ while (cid_mask != 0) {
+ if ((cid_mask & 0xf) != 0x0) {
+ val = (intf_cmd_mask>>(vc*2)) & 0x3;
+ global_intf_cmd_mask |=
+ (0x3 << ((vc * 2) + (intfnum * 8)));
+ global_intf_cmd_mask &= ~((0x3 & ~val)
+ << ((vc * 2) +
+ (intfnum * 8)));
+ }
+ vc++;
+ cid_mask >>= 4;
+ }
+ mask >>= 1;
+ intfnum++;
}
+ msm_io_w(global_intf_cmd_mask, ispif->base + ISPIF_INTF_CMD_ADDR);
}
-static int msm_ispif_abort_intf_transfer(uint8_t intf)
+static int msm_ispif_abort_intf_transfer(uint8_t intfmask)
{
int rc = 0;
uint8_t intf_cmd_mask = 0xAA;
-
- CDBG("abort stream request\n");
+ uint8_t intfnum = 0, mask = intfmask;
mutex_lock(&ispif->mutex);
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
- rc = msm_ispif_intf_reset(intf);
- global_intf_cmd_mask |= 0xFF<<(intf * 8);
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+ while (mask != 0) {
+ if (intfmask & (0x1 << intfnum))
+ global_intf_cmd_mask |= (0xFF << (intfnum * 8));
+ mask >>= 1;
+ intfnum++;
+ }
mutex_unlock(&ispif->mutex);
return rc;
}
-static int msm_ispif_start_intf_transfer(uint8_t intf)
+static int msm_ispif_start_intf_transfer(uint8_t intfmask)
{
- uint32_t data;
uint8_t intf_cmd_mask = 0x55;
int rc = 0;
-
- CDBG("start stream request\n");
mutex_lock(&ispif->mutex);
- switch (intf) {
- case PIX0:
- data = msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR);
- if ((data & 0xf) != 0xf) {
- CDBG("interface is busy\n");
- mutex_unlock(&ispif->mutex);
- return -EBUSY;
- }
- break;
-
- case RDI0:
- data = msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR);
- ispif->start_ack_pending = 1;
- break;
-
- case RDI1:
- data = msm_io_r(ispif->base + ISPIF_RDI_1_STATUS_ADDR);
- ispif->start_ack_pending = 1;
- break;
- }
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
+ rc = msm_ispif_intf_reset(intfmask);
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
mutex_unlock(&ispif->mutex);
return rc;
}
-static int msm_ispif_stop_intf_transfer(uint8_t intf)
+static int msm_ispif_stop_intf_transfer(uint8_t intfmask)
{
int rc = 0;
uint8_t intf_cmd_mask = 0x00;
- CDBG("stop stream request\n");
+ uint8_t intfnum = 0, mask = intfmask;
mutex_lock(&ispif->mutex);
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
- switch (intf) {
- case PIX0:
- while ((msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR)
- & 0xf) != 0xf) {
- CDBG("Wait for Idle\n");
- }
- break;
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+ while (mask != 0) {
+ if (intfmask & (0x1 << intfnum)) {
+ switch (intfnum) {
+ case PIX0:
+ while ((msm_io_r(ispif->base +
+ ISPIF_PIX_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for pix0 Idle\n");
+ }
+ break;
- case RDI0:
- while ((msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR)
- & 0xf) != 0xf) {
- CDBG("Wait for Idle\n");
+ case RDI0:
+ while ((msm_io_r(ispif->base +
+ ISPIF_RDI_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for rdi0 Idle\n");
+ }
+ break;
+
+ case RDI1:
+ while ((msm_io_r(ispif->base +
+ ISPIF_RDI_1_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for rdi1 Idle\n");
+ }
+ break;
+
+ default:
+ break;
+ }
+ global_intf_cmd_mask |= (0xFF << (intfnum * 8));
}
- break;
- default:
- break;
+ mask >>= 1;
+ intfnum++;
}
- global_intf_cmd_mask |= 0xFF<<(intf * 8);
mutex_unlock(&ispif->mutex);
return rc;
}
@@ -364,10 +387,77 @@
return rc;
}
+static void ispif_do_tasklet(unsigned long data)
+{
+ unsigned long flags;
+
+ struct ispif_isr_queue_cmd *qcmd = NULL;
+ CDBG("=== ispif_do_tasklet start ===\n");
+
+ while (atomic_read(&ispif_irq_cnt)) {
+ spin_lock_irqsave(&ispif_tasklet_lock, flags);
+ qcmd = list_first_entry(&ispif_tasklet_q,
+ struct ispif_isr_queue_cmd, list);
+ atomic_sub(1, &ispif_irq_cnt);
+
+ if (!qcmd) {
+ spin_unlock_irqrestore(&ispif_tasklet_lock,
+ flags);
+ return;
+ }
+ list_del(&qcmd->list);
+ spin_unlock_irqrestore(&ispif_tasklet_lock,
+ flags);
+ if (qcmd->ispifInterruptStatus0 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+ CDBG("ispif rdi irq status\n");
+ }
+ if (qcmd->ispifInterruptStatus1 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+ CDBG("ispif rdi1 irq status\n");
+ }
+ kfree(qcmd);
+ }
+ CDBG("=== ispif_do_tasklet end ===\n");
+}
+
+DECLARE_TASKLET(ispif_tasklet, ispif_do_tasklet, 0);
+
+static void ispif_process_irq(struct ispif_irq_status *out)
+{
+ unsigned long flags;
+ struct ispif_isr_queue_cmd *qcmd;
+
+ CDBG("ispif_process_irq\n");
+ qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
+ GFP_ATOMIC);
+ if (!qcmd) {
+ pr_err("ispif_process_irq: qcmd malloc failed!\n");
+ return;
+ }
+ qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
+ qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
+
+ spin_lock_irqsave(&ispif_tasklet_lock, flags);
+ list_add_tail(&qcmd->list, &ispif_tasklet_q);
+
+ atomic_add(1, &ispif_irq_cnt);
+ spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
+ tasklet_schedule(&ispif_tasklet);
+ return;
+}
+
static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out)
{
out->ispifIrqStatus0 = msm_io_r(ispif->base +
- ISPIF_IRQ_STATUS_ADDR);
+ ISPIF_IRQ_STATUS_ADDR);
+ out->ispifIrqStatus1 = msm_io_r(ispif->base +
+ ISPIF_IRQ_STATUS_1_ADDR);
+ msm_io_w(out->ispifIrqStatus0,
+ ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+ msm_io_w(out->ispifIrqStatus1,
+ ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+
CDBG("ispif->irq: Irq_status0 = 0x%x\n",
out->ispifIrqStatus0);
if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
@@ -377,23 +467,14 @@
pr_err("%s: pix intf 0 overflow.\n", __func__);
if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
pr_err("%s: rdi intf 0 overflow.\n", __func__);
- if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
- if (ispif->start_ack_pending) {
- v4l2_subdev_notify(&ispif->subdev,
- NOTIFY_ISP_MSG_EVT,
- (void *)MSG_ID_START_ACK);
- ispif->start_ack_pending = 0;
- /* stop stream at frame boundary */
- msm_ispif_stop_intf_transfer(RDI0);
- }
- v4l2_subdev_notify(&ispif->subdev, NOTIFY_ISP_MSG_EVT,
- (void *)MSG_ID_SOF_ACK);
+ if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) ||
+ (out->ispifIrqStatus1 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK)) {
+ ispif_process_irq(out);
}
}
- msm_io_w(out->ispifIrqStatus0,
- ispif->base + ISPIF_IRQ_CLEAR_ADDR);
msm_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
- ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+ ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
}
static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
@@ -414,6 +495,8 @@
static int msm_ispif_init(const uint32_t *csid_version)
{
int rc = 0;
+ spin_lock_init(&ispif_tasklet_lock);
+ INIT_LIST_HEAD(&ispif_tasklet_q);
rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
IRQF_TRIGGER_RISING, "ispif", 0);
@@ -451,6 +534,7 @@
CDBG("%s, free_irq\n", __func__);
free_irq(ispif->irq->start, 0);
+ tasklet_kill(&ispif_tasklet);
}
void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num)
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index deadc28..8f1dd12 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -36,6 +36,12 @@
struct clk *ispif_clk[5];
};
+struct ispif_isr_queue_cmd {
+ struct list_head list;
+ uint32_t ispifInterruptStatus0;
+ uint32_t ispifInterruptStatus1;
+};
+
#define VIDIOC_MSM_ISPIF_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_ispif_params)
@@ -51,6 +57,12 @@
#define ISPIF_OFF_IMMEDIATELY (0x01 << 2)
#define ISPIF_S_STREAM_SHIFT 4
+
+#define PIX_0 (0x01 << 0)
+#define RDI_0 (0x01 << 1)
+#define PIX_1 (0x01 << 2)
+#define RDI_1 (0x01 << 3)
+
void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num);
#endif
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 0ae247e..207f8be 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -40,29 +40,42 @@
goto cam_clk_set_err;
}
}
+ rc = clk_prepare(clk_ptr[i]);
+ if (rc < 0) {
+ pr_err("%s prepare failed\n",
+ clk_info[i].clk_name);
+ goto cam_clk_prepare_err;
+ }
+
rc = clk_enable(clk_ptr[i]);
if (rc < 0) {
pr_err("%s enable failed\n",
clk_info[i].clk_name);
- goto cam_clk_set_err;
+ goto cam_clk_enable_err;
}
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
- if (clk_ptr[i] != NULL)
+ if (clk_ptr[i] != NULL) {
clk_disable(clk_ptr[i]);
+ clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ }
}
}
return rc;
+cam_clk_enable_err:
+ clk_unprepare(clk_ptr[i]);
+cam_clk_prepare_err:
cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
clk_disable(clk_ptr[i]);
+ clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
}
}
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 22322b8..7cab16e 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -116,6 +116,7 @@
NOTIFY_ISP_MSG_EVT, /* arg = enum ISP_MESSAGE_ID */
NOTIFY_VFE_MSG_OUT, /* arg = struct isp_msg_output */
NOTIFY_VFE_MSG_STATS, /* arg = struct isp_msg_stats */
+ NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
NOTIFY_VPE_MSG_EVT,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 6b3aef7..0cffbbf 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -307,6 +307,36 @@
}
}
break;
+ case NOTIFY_VFE_MSG_COMP_STATS: {
+ struct msm_stats_buf *stats = (struct msm_stats_buf *)arg;
+ struct msm_stats_buf *stats_buf = NULL;
+
+ isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
+ stats->aec.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->aec.buff, &(stats->aec.fd));
+ stats->awb.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->awb.buff, &(stats->awb.fd));
+ stats->af.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->af.buff, &(stats->af.fd));
+ stats->ihist.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->ihist.buff, &(stats->ihist.fd));
+ stats->rs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->rs.buff, &(stats->rs.fd));
+ stats->cs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->cs.buff, &(stats->cs.fd));
+
+ stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
+ if (!stats_buf) {
+ pr_err("%s: out of memory.\n", __func__);
+ rc = -ENOMEM;
+ } else {
+ *stats_buf = *stats;
+ isp_event->isp_data.isp_msg.len =
+ sizeof(struct msm_stats_buf);
+ isp_event->isp_data.isp_msg.data = stats_buf;
+ }
+ }
+ break;
case NOTIFY_VFE_MSG_STATS: {
struct msm_stats_buf stats;
struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 2c4fbe4..13d1daf 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -241,6 +241,7 @@
case NOTIFY_ISP_MSG_EVT:
case NOTIFY_VFE_MSG_OUT:
case NOTIFY_VFE_MSG_STATS:
+ case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
case NOTIFY_VFE_BUF_FREE_EVT:
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_notify) {
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 4b86bd8..e1a36a8 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -589,6 +589,7 @@
vfe32_ctrl->operation_mode = *p;
vfe32_ctrl->stats_comp = *(++p);
+ vfe32_ctrl->hfr_mode = *(++p);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CFG);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_MODULE_CFG);
@@ -684,10 +685,16 @@
static void vfe32_start_common(void)
{
+ uint32_t irq_mask = 0x00E00021;
vfe32_ctrl->start_ack_pending = TRUE;
CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
- msm_io_w(0x00EFE021, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+ if (vfe32_ctrl->stats_comp)
+ irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+ else
+ irq_mask |= 0x000FE000;
+
+ msm_io_w(irq_mask, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
@@ -2389,47 +2396,73 @@
static void vfe32_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->af_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->af_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->afStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->awb_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->awb_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->awbStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->aec_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->aec_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->aecStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->ihist_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->ihistStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->rs_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->rsStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->cs_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->csStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
-
static inline void vfe32_read_irq_status(struct vfe32_irq_status *out)
{
uint32_t *temp;
@@ -2654,6 +2687,13 @@
msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
}
+ } /* if raw snapshot mode. */
+ if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+ (vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+ (vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+ vfe32_ctrl->vfeFrameId++;
+ CDBG("Skip the SOF notification when HFR enabled\n");
+ return;
}
vfe32_ctrl->vfeFrameId++;
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_SOF_ACK);
@@ -2907,11 +2947,6 @@
}
}
-static void vfe32_process_stats_comb_irq(uint32_t *irqstatus)
-{
- return;
-}
-
static uint32_t vfe32_process_stats_irq_common(uint32_t statsNum,
uint32_t newAddr) {
@@ -2971,17 +3006,23 @@
case statsIhistNum: {
msgStats.id = MSG_ID_STATS_IHIST;
+ spin_lock_irqsave(&vfe32_ctrl->ihist_ack_lock, flags);
vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->ihist_ack_lock, flags);
}
break;
case statsRsNum: {
msgStats.id = MSG_ID_STATS_RS;
+ spin_lock_irqsave(&vfe32_ctrl->rs_ack_lock, flags);
vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->rs_ack_lock, flags);
}
break;
case statsCsNum: {
msgStats.id = MSG_ID_STATS_CS;
+ spin_lock_irqsave(&vfe32_ctrl->cs_ack_lock, flags);
vfe32_ctrl->csStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->cs_ack_lock, flags);
}
break;
@@ -2997,6 +3038,30 @@
return;
}
+static void vfe_send_comp_stats_msg(uint32_t status_bits)
+{
+ struct msm_stats_buf msgStats;
+ uint32_t temp;
+
+ msgStats.frame_id = vfe32_ctrl->vfeFrameId;
+ msgStats.status_bits = status_bits;
+
+ msgStats.aec.buff = vfe32_ctrl->aecStatsControl.bufToRender;
+ msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
+ msgStats.af.buff = vfe32_ctrl->afStatsControl.bufToRender;
+
+ msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
+ msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
+ msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
+
+ temp = msm_io_r(vfe32_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+ msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+ v4l2_subdev_notify(&vfe32_ctrl->subdev,
+ NOTIFY_VFE_MSG_COMP_STATS,
+ &msgStats);
+}
+
static void vfe32_process_stats_ae_irq(void)
{
unsigned long flags;
@@ -3105,6 +3170,126 @@
}
}
+static void vfe32_process_stats(uint32_t status_bits)
+{
+ unsigned long flags;
+ int32_t process_stats = false;
+ CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+
+ spin_lock_irqsave(&vfe32_ctrl->comp_stats_ack_lock, flags);
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+ if (!vfe32_ctrl->aecStatsControl.ackPending) {
+ vfe32_ctrl->aecStatsControl.ackPending = TRUE;
+ vfe32_ctrl->aecStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAeNum,
+ vfe32_ctrl->aecStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else{
+ vfe32_ctrl->aecStatsControl.bufToRender = 0;
+ vfe32_ctrl->aecStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe32_ctrl->aecStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+ if (!vfe32_ctrl->awbStatsControl.ackPending) {
+ vfe32_ctrl->awbStatsControl.ackPending = TRUE;
+ vfe32_ctrl->awbStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAwbNum,
+ vfe32_ctrl->awbStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else{
+ vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->awbStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->awbStatsControl.bufToRender = 0;
+ }
+
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+ if (!vfe32_ctrl->afStatsControl.ackPending) {
+ vfe32_ctrl->afStatsControl.ackPending = TRUE;
+ vfe32_ctrl->afStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAfNum,
+ vfe32_ctrl->afStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->afStatsControl.bufToRender = 0;
+ vfe32_ctrl->afStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe32_ctrl->afStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+ if (!vfe32_ctrl->ihistStatsControl.ackPending) {
+ vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+ vfe32_ctrl->ihistStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsIhistNum,
+ vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+ if (!vfe32_ctrl->rsStatsControl.ackPending) {
+ vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+ vfe32_ctrl->rsStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsRsNum,
+ vfe32_ctrl->rsStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->rsStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->rsStatsControl.bufToRender = 0;
+ }
+
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+ if (!vfe32_ctrl->csStatsControl.ackPending) {
+ vfe32_ctrl->csStatsControl.ackPending = TRUE;
+ vfe32_ctrl->csStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsCsNum,
+ vfe32_ctrl->csStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->csStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->csStatsControl.bufToRender = 0;
+ }
+
+ spin_unlock_irqrestore(&vfe32_ctrl->comp_stats_ack_lock, flags);
+ if (process_stats)
+ vfe_send_comp_stats_msg(status_bits);
+
+ return;
+}
+
+static void vfe32_process_stats_irq(uint32_t *irqstatus)
+{
+ uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
+
+ if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+ (vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+ CDBG("Skip the stats when HFR enabled\n");
+ return;
+ }
+
+ vfe32_process_stats(status_bits);
+ return;
+}
+
static void vfe32_do_tasklet(unsigned long data)
{
unsigned long flags;
@@ -3191,7 +3376,7 @@
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
CDBG("Stats composite irq occured.\n");
- vfe32_process_stats_comb_irq(
+ vfe32_process_stats_irq(
&qcmd->vfeInterruptStatus0);
}
} else {
@@ -3618,6 +3803,10 @@
spin_lock_init(&vfe32_ctrl->aec_ack_lock);
spin_lock_init(&vfe32_ctrl->awb_ack_lock);
spin_lock_init(&vfe32_ctrl->af_ack_lock);
+ spin_lock_init(&vfe32_ctrl->ihist_ack_lock);
+ spin_lock_init(&vfe32_ctrl->rs_ack_lock);
+ spin_lock_init(&vfe32_ctrl->cs_ack_lock);
+ spin_lock_init(&vfe32_ctrl->comp_stats_ack_lock);
spin_lock_init(&vfe32_ctrl->sd_notify_lock);
INIT_LIST_HEAD(&vfe32_ctrl->tasklet_q);
@@ -3625,6 +3814,7 @@
vfe32_ctrl->update_rolloff = false;
vfe32_ctrl->update_la = false;
vfe32_ctrl->update_gamma = false;
+ vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
enable_irq(vfe32_ctrl->vfeirq->start);
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 1adfffd..c511b69 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -168,6 +168,8 @@
#define VFE_AF_PINGPONG_STATUS_BIT 0x100
#define VFE_AWB_PINGPONG_STATUS_BIT 0x200
+#define HFR_MODE_OFF 1
+
enum VFE32_DMI_RAM_SEL {
NO_MEM_SELECTED = 0,
BLACK_LUT_RAM_BANK0 = 0x1,
@@ -220,7 +222,7 @@
#define V32_OUT_CLAMP_OFF 0x00000524
#define V32_OUT_CLAMP_LEN 8
-#define V32_OPERATION_CFG_LEN 32
+#define V32_OPERATION_CFG_LEN 36
#define V32_AXI_OUT_OFF 0x00000038
#define V32_AXI_OUT_LEN 216
@@ -778,6 +780,8 @@
#define VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
#define VFE32_IMASK_AXI_ERROR (0x00000001<<22)
+#define VFE_COM_STATUS 0x000FE000
+
struct vfe32_output_path {
uint16_t output_mode; /* bitmask */
@@ -864,6 +868,7 @@
#define VFE_CLAMP_MIN 0x00000528
#define VFE_REALIGN_BUF 0x0000052C
#define VFE_STATS_CFG 0x00000530
+#define VFE_STATS_AWB_SGW_CFG 0x00000554
#define VFE_DMI_CFG 0x00000598
#define VFE_DMI_ADDR 0x0000059C
#define VFE_DMI_DATA_LO 0x000005A4
@@ -906,6 +911,10 @@
spinlock_t aec_ack_lock;
spinlock_t awb_ack_lock;
spinlock_t af_ack_lock;
+ spinlock_t ihist_ack_lock;
+ spinlock_t rs_ack_lock;
+ spinlock_t cs_ack_lock;
+ spinlock_t comp_stats_ack_lock;
uint32_t extlen;
void *extdata;
@@ -958,6 +967,7 @@
struct platform_device *pdev;
struct clk *vfe_clk[3];
spinlock_t sd_notify_lock;
+ uint32_t hfr_mode;
};
#define statsAeNum 0
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 1b57350..d0b4f1f 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -215,7 +215,7 @@
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
- PIX0, ISPIF_OFF_IMMEDIATELY));
+ PIX_0, ISPIF_OFF_IMMEDIATELY));
s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msleep(30);
if (update_type == MSM_SENSOR_REG_INIT) {
@@ -244,7 +244,7 @@
output_settings[res].op_pixel_clk);
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
- PIX0, ISPIF_ON_FRAME_BOUNDARY));
+ PIX_0, ISPIF_ON_FRAME_BOUNDARY));
s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
msleep(30);
}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 00e4fda..6dd65e8 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -42,6 +42,7 @@
#include <mach/clk.h>
#include <mach/msm_xo.h>
+#include <mach/msm_bus.h>
#define MSM_USB_BASE (motg->regs)
#define DRIVER_NAME "msm_otg"
@@ -1122,6 +1123,7 @@
static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on)
{
+ int ret;
struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
struct msm_otg_platform_data *pdata = motg->pdata;
@@ -1142,11 +1144,27 @@
* power collapse(pc) while running in peripheral mode.
*/
otg_pm_qos_update_latency(motg, 1);
+ /* Configure BUS performance parameters for MAX bandwidth */
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 1);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to vote for "
+ "bus bandwidth %d\n", __func__, ret);
+ }
usb_gadget_vbus_connect(otg->gadget);
} else {
dev_dbg(otg->dev, "gadget off\n");
usb_gadget_vbus_disconnect(otg->gadget);
otg_pm_qos_update_latency(motg, 0);
+ /* Configure BUS performance parameters to default */
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 0);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to devote "
+ "for bus bw %d\n", __func__, ret);
+ }
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_UNDEFINED);
}
@@ -2601,6 +2619,14 @@
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
+ if (motg->pdata->bus_scale_table) {
+ motg->bus_perf_client =
+ msm_bus_scale_register_client(motg->pdata->bus_scale_table);
+ if (!motg->bus_perf_client)
+ dev_err(motg->otg.dev, "%s: Failed to register BUS "
+ "scaling client!!\n", __func__);
+ }
+
return 0;
remove_otg:
@@ -2702,6 +2728,9 @@
if (motg->pdata->swfi_latency)
pm_qos_remove_request(&motg->pm_qos_req_dma);
+ if (motg->bus_perf_client)
+ msm_bus_scale_unregister_client(motg->bus_perf_client);
+
kfree(motg);
return 0;
}
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index c7759c4..b590c41 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -309,6 +309,15 @@
The panel is connected to the host
via Toshiba DSI-to-LVDS bridge.
+config FB_MSM_MIPI_CHIMEI_WUXGA
+ bool "LVDS Chimei WUXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
+ select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+ ---help---
+ Support for Chimei WUXGA (1920x1200) panel.
+ The panel is using a serial LVDS input.
+ The panel is connected to the host
+ via Toshiba DSI-to-LVDS bridge.
+
config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
bool
select FB_MSM_MIPI_DSI_TRULY
@@ -446,6 +455,7 @@
select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
select FB_MSM_MIPI_SIMULATOR_VIDEO
select FB_MSM_MIPI_CHIMEI_WXGA
+ select FB_MSM_MIPI_CHIMEI_WUXGA
---help---
Support for MIPI panel auto detect
@@ -543,6 +553,10 @@
bool "MIPI Chimei WXGA PT Panel"
select FB_MSM_MIPI_CHIMEI_WXGA
+config FB_MSM_MIPI_CHIMEI_WUXGA_PANEL
+ bool "MIPI Chimei WUXGA Panel"
+ select FB_MSM_MIPI_CHIMEI_WUXGA
+
config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT_PANEL
bool "MIPI Truly Video WVGA PT Panel"
select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index 93205bc..bd7628d 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -119,6 +119,7 @@
obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
obj-y += mipi_chimei_wxga_pt.o
+obj-y += mipi_chimei_wuxga.o
obj-y += mipi_truly_video_wvga_pt.o
else
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
@@ -133,6 +134,7 @@
obj-$(CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT) += mipi_NT35510_video_wvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA) += mipi_chimei_wuxga.o
endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
new file mode 100644
index 0000000..c63df46
--- /dev/null
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -0,0 +1,196 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+ * Chimei WUXGA LVDS Panel driver.
+ * The panel model is N101JSF-L21.
+ *
+ * The panel interface includes:
+ * 1. LVDS input for video (clock & data).
+ * 2. few configuration pins to control 3D module: Enable, Mode (2D/3D).
+ * 3. Backlight LED control (PWM 200 HZ).
+ *
+ * This panel is controled via the Toshiba DSI-to-LVDS bridge.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+#include "msm_fb.h"
+#include "msm_fb_panel.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+#define MHZ (1000*1000)
+
+/**
+ * Panel info parameters.
+ * The panel info is passed to the mipi framebuffer driver.
+ */
+static struct msm_panel_info chimei_wuxga_pinfo;
+
+/**
+ * The mipi_dsi_phy_ctrl is calculated according to the
+ * "dsi_timing_program.xlsm" excel sheet.
+ * Output is based on: 1200x1920, RGB565, 4 lanes , 58 frames
+ * per second.
+ */
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+ /* DSIPHY_REGULATOR_CTRL */
+ .regulator = {0x03, 0x0a, 0x04, 0x00, 0x20}, /* common 8960 */
+ /* DSIPHY_CTRL */
+ .ctrl = {0x5f, 0x00, 0x00, 0x10}, /* common 8960 */
+ /* DSIPHY_STRENGTH_CTRL */
+ .strength = {0xff, 0x00, 0x06, 0x00}, /* common 8960 */
+ /* DSIPHY_TIMING_CTRL */
+ .timing = { 0xC9, 0x92, 0x29, /* panel specific */
+ 0, /* DSIPHY_TIMING_CTRL_3 = 0 */
+ 0x2E, 0x9B, 0x2C, 0x94, 0x2E, 0x03, 0x04}, /* panel specific */
+
+ /* DSIPHY_PLL_CTRL */
+ .pll = { 0x00, /* common 8960 */
+ /* VCO */
+ 0x32, (0x01 | 0x30) , (0x19 | 0xC0), /* panel specific */
+ 0x00, 0x50, 0x48, 0x63,
+ 0x77, 0x88, 0x99, /* Auto update by dsi-mipi driver */
+ 0x00, 0x14, 0x03, 0x00, 0x02, /* common 8960 */
+ 0x00, 0x20, 0x00, 0x01 }, /* common 8960 */
+};
+
+/**
+ * Module init.
+ *
+ * Register the panel-info.
+ *
+ * Some parameters are from the panel datasheet
+ * and other are *calculated* by the "dsi_timing_program.xlsm"
+ * excel file
+ *
+ * @return int
+ */
+static int __init mipi_chimei_wuxga_init(void)
+{
+ int ret;
+ struct msm_panel_info *pinfo = &chimei_wuxga_pinfo;
+
+ if (msm_fb_detect_client("mipi_video_chimei_wuxga"))
+ return 0;
+
+ pr_info("mipi-dsi chimei wuxga (1200x1920) driver ver 1.0.\n");
+
+ /* Portrait */
+ pinfo->xres = 1200;
+ pinfo->yres = 1920;
+ pinfo->type = MIPI_VIDEO_PANEL;
+ pinfo->pdest = DISPLAY_1; /* Primary Display */
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = 24; /* RGB565 requires 24 bits-per-pixel :-O */
+ pinfo->fb_num = 2; /* using two frame buffers */
+
+ /*
+ * The CMI panel requires 80 MHZ LVDS-CLK.
+ * The D2L bridge drives the LVDS-CLK from the DSI-CLK.
+ * The DSI-CLK = bitclk/2, 640 MHZ/2= 320 MHZ.
+ * LVDS-CLK = DSI-CLK/4 , 320 MHZ/4= 80 MHZ.
+ */
+
+ pinfo->clk_rate = 640 * MHZ ; /* bitclk Calculated */
+
+ /*
+ * this panel is operated by DE,
+ * vsycn and hsync are ignored
+ */
+
+ pinfo->lcdc.h_front_porch = 16; /* thfp */
+ pinfo->lcdc.h_back_porch = 160; /* thb */
+ pinfo->lcdc.h_pulse_width = 32; /* thpw */
+
+ pinfo->lcdc.v_front_porch = 0; /* tvfp */
+ pinfo->lcdc.v_back_porch = 26; /* tvb */
+ pinfo->lcdc.v_pulse_width = 6; /* tvpw */
+
+ pinfo->lcdc.border_clr = 0; /* black */
+ pinfo->lcdc.underflow_clr = 0xff; /* blue */
+
+ pinfo->lcdc.hsync_skew = 0;
+
+ /* Backlight levels - controled via PMIC pwm gpio */
+ pinfo->bl_max = 15;
+ pinfo->bl_min = 1;
+
+ /* mipi - general */
+ pinfo->mipi.vc = 0; /* virtual channel */
+ pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+ pinfo->mipi.tx_eot_append = true;
+ pinfo->mipi.t_clk_post = 34; /* Calculated */
+ pinfo->mipi.t_clk_pre = 69; /* Calculated */
+
+ pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+ /* Four lanes are recomended for 1920x1200 at 60 frames per second */
+ pinfo->mipi.frame_rate = 45; /* 45 frames per second */
+ pinfo->mipi.data_lane0 = true;
+ pinfo->mipi.data_lane1 = true;
+ pinfo->mipi.data_lane2 = true;
+ pinfo->mipi.data_lane3 = true;
+
+ pinfo->mipi.mode = DSI_VIDEO_MODE;
+ /*
+ * Note: The CMI panel input is RGB888,
+ * thus the DSI-to-LVDS bridge output is RGB888.
+ * This parameter selects the DSI-Core output to the bridge.
+ */
+ pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB565;
+
+ /* mipi - video mode */
+ pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+ pinfo->mipi.pulse_mode_hsa_he = false; /* sync mode */
+
+ pinfo->mipi.hfp_power_stop = false;
+ pinfo->mipi.hbp_power_stop = false;
+ pinfo->mipi.hsa_power_stop = false;
+ pinfo->mipi.eof_bllp_power_stop = false;
+ pinfo->mipi.bllp_power_stop = false;
+
+ /* mipi - command mode */
+ pinfo->mipi.te_sel = 1; /* TE from vsycn gpio */
+ pinfo->mipi.interleave_max = 1;
+ /* The bridge supports only Generic Read/Write commands */
+ pinfo->mipi.insert_dcs_cmd = false;
+ pinfo->mipi.wr_mem_continue = 0;
+ pinfo->mipi.wr_mem_start = 0;
+ pinfo->mipi.stream = false; /* dma_p */
+ pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+ pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+ /*
+ * toshiba d2l chip does not need max_pkt_size dcs cmd
+ * client reply len is directly configure through
+ * RDPKTLN register (0x0404)
+ */
+ pinfo->mipi.no_max_pkt_size = 1;
+ pinfo->mipi.force_clk_lane_hs = 1;
+
+ pinfo->is_3d_panel = FB_TYPE_3D_PANEL;
+
+ ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM, 1);
+ if (ret)
+ pr_err("%s: failed to register device!\n", __func__);
+
+ return ret;
+}
+
+module_init(mipi_chimei_wuxga_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Chimei WUXGA LVDS Panel driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 42fa2ba..489e6d2 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1520,8 +1520,8 @@
pdata->set_backlight(mfd);
bl_level_old = unset_bl_level;
up(&mfd->sem);
+ bl_updated = 1;
}
- bl_updated = 1;
}
++mfd->panel_info.frame_count;
@@ -2624,8 +2624,8 @@
pdata->set_backlight(mfd);
bl_level_old = unset_bl_level;
up(&mfd->sem);
+ bl_updated = 1;
}
- bl_updated = 1;
}
return ret;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 2cbe6ce..037cfe7 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -164,6 +164,7 @@
* @enable_dcd: Enable Data Contact Detection circuit. if not set
* wait for 600msec before proceeding to primary
* detection.
+ * @bus_scale_table: parameters for bus bandwidth requirements
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -179,6 +180,7 @@
bool disable_reset_on_disconnect;
u32 swfi_latency;
bool enable_dcd;
+ struct msm_bus_scale_pdata *bus_scale_table;
};
/**
@@ -211,6 +213,7 @@
collapse when cable is connected.
* @id_timer: The timer used for polling ID line to detect ACA states.
* @xo_handle: TCXO buffer handle
+ * @bus_perf_client: Bus performance client handle to request BUS bandwidth
*/
struct msm_otg {
struct otg_transceiver otg;
@@ -241,6 +244,7 @@
struct timer_list id_timer;
unsigned long caps;
struct clk *xo_handle;
+ uint32_t bus_perf_client;
/*
* Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
* analog regulators while going to low power mode.
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 7caafb6..5dd1445 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -58,6 +58,7 @@
#define MSG_ID_STATS_AWB_AEC 39
#define MSG_ID_OUTPUT_PRIMARY 40
#define MSG_ID_OUTPUT_SECONDARY 41
+#define MSG_ID_STATS_COMPOSITE 42
/* ISP command IDs */
#define VFE_CMD_DUMMY_0 0
diff --git a/sound/soc/msm/msm7201.c b/sound/soc/msm/msm7201.c
index 9e041c7..6408cef 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -1,6 +1,6 @@
/* linux/sound/soc/msm/msm7201.c
*
- * Copyright (c) 2008-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, 2012 Code Aurora Forum. All rights reserved.
*
* All source code in this file is licensed under the following license except
* where indicated.
@@ -40,6 +40,8 @@
#include <mach/msm_rpcrouter.h>
static struct msm_rpc_endpoint *snd_ep;
+static uint32_t snd_mute_ear_mute;
+static uint32_t snd_mute_mic_mute;
struct msm_snd_rpc_ids {
unsigned long prog;
@@ -99,7 +101,7 @@
* The number of devices supported is 26 (0 to 25)
*/
uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 25;
+ uinfo->value.integer.max = 36;
return 0;
}
@@ -107,6 +109,8 @@
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = (uint32_t)snd_rpc_ids.device;
+ ucontrol->value.integer.value[1] = snd_mute_ear_mute;
+ ucontrol->value.integer.value[2] = snd_mute_mic_mute;
return 0;
}
@@ -213,8 +217,11 @@
if (rc < 0) {
printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
__func__, rc);
- } else
- printk(KERN_INFO "snd device connected \n");
+ } else {
+ printk(KERN_INFO "snd device connected\n");
+ snd_mute_ear_mute = ucontrol->value.integer.value[1];
+ snd_mute_mic_mute = ucontrol->value.integer.value[2];
+ }
return rc;
}