Merge "ASoC: msm: Add VSS_IVOCPROC_CMD_SET_MUTE case in cvp callback" into msm-3.0
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 0a23a17..5cb44b8 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1277,6 +1277,83 @@
.id = -1,
};
+#ifdef CONFIG_QSEECOM
+/* qseecom bus scaling */
+static struct msm_bus_vectors qseecom_clks_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_dfab_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
+static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(qseecom_clks_init_vectors),
+ qseecom_clks_init_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_sfpb_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+ qseecom_hw_bus_scale_usecases,
+ ARRAY_SIZE(qseecom_hw_bus_scale_usecases),
+ .name = "qsee",
+};
+
+static struct platform_device qseecom_device = {
+ .name = "qseecom",
+ .id = 0,
+ .dev = {
+ .platform_data = &qseecom_bus_pdata,
+ },
+};
+#endif
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -1809,6 +1886,10 @@
&msm8064_device_saw_regulator_core1,
&msm8064_device_saw_regulator_core2,
&msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_QSEECOM)
+ &qseecom_device,
+#endif
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
&qcrypto_device,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 173ec95..6859b9f 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -654,6 +654,83 @@
.dev = {.platform_data = &qcom_wcnss_pdata},
};
+#ifdef CONFIG_QSEECOM
+/* qseecom bus scaling */
+static struct msm_bus_vectors qseecom_clks_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_dfab_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
+static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(qseecom_clks_init_vectors),
+ qseecom_clks_init_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_sfpb_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+ qseecom_hw_bus_scale_usecases,
+ ARRAY_SIZE(qseecom_hw_bus_scale_usecases),
+ .name = "qsee",
+};
+
+static struct platform_device qseecom_device = {
+ .name = "qseecom",
+ .id = 0,
+ .dev = {
+ .platform_data = &qseecom_bus_pdata,
+ },
+};
+#endif
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -1646,6 +1723,10 @@
&msm8960_device_qup_i2c_gsbi12,
&msm_slim_ctrl,
&msm_device_wcnss_wlan,
+#if defined(CONFIG_QSEECOM)
+ &qseecom_device,
+#endif
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
&qcrypto_device,
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a21788b..1ca25cc 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -41,6 +41,7 @@
#include <linux/ks8851.h>
#include <linux/i2c/isa1200.h>
#include <linux/memory.h>
+#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -159,6 +160,12 @@
#define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
#define MSM_LIQUID_ION_SF_SIZE MSM_LIQUID_PMEM_SIZE
#define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SIZE
+
+#define MSM8960_FIXED_AREA_START 0xa0000000
+#define MAX_FIXED_AREA_SIZE 0x10000000
+#define MSM_MM_FW_SIZE 0x200000
+#define MSM8960_FW_START (MSM8960_FIXED_AREA_START - MSM_MM_FW_SIZE)
+
static unsigned msm_ion_sf_size = MSM_ION_SF_SIZE;
#else
#define MSM_PMEM_KERNEL_EBI1_SIZE 0x110C000
@@ -367,6 +374,7 @@
.align = PAGE_SIZE,
.reusable = FMEM_ENABLED,
.mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_MIDDLE,
};
static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
@@ -374,6 +382,7 @@
.align = PAGE_SIZE,
.reusable = 0,
.mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_HIGH,
};
static struct ion_co_heap_pdata co_ion_pdata = {
@@ -386,6 +395,7 @@
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
.mem_is_fmem = FMEM_ENABLED,
+ .fixed_position = FIXED_LOW,
};
#endif
@@ -513,6 +523,24 @@
msm8960_reserve_table[mem_type].size += size;
}
+static void __init msm8960_reserve_fixed_area(unsigned long fixed_area_size)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+ int ret;
+
+ if (fixed_area_size > MAX_FIXED_AREA_SIZE)
+ panic("fixed area size is larger than %dM\n",
+ MAX_FIXED_AREA_SIZE >> 20);
+
+ reserve_info->fixed_area_size = fixed_area_size;
+ reserve_info->fixed_area_start = MSM8960_FW_START;
+
+ ret = memblock_remove(reserve_info->fixed_area_start,
+ reserve_info->fixed_area_size);
+ BUG_ON(ret);
+#endif
+}
+
/**
* Reserve memory for ION and calculate amount of reusable memory for fmem.
* We only reserve memory for heaps that are not reusable. However, we only
@@ -530,11 +558,17 @@
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
unsigned int i;
unsigned int reusable_count = 0;
+ unsigned int fixed_size = 0;
+ unsigned int fixed_low_size, fixed_middle_size, fixed_high_size;
+ unsigned long fixed_low_start, fixed_middle_start, fixed_high_start;
adjust_mem_for_liquid();
fmem_pdata.size = 0;
fmem_pdata.reserved_size_low = 0;
fmem_pdata.reserved_size_high = 0;
+ fixed_low_size = 0;
+ fixed_middle_size = 0;
+ fixed_high_size = 0;
/* We only support 1 reusable heap. Check if more than one heap
* is specified as reusable and set as non-reusable if found.
@@ -557,40 +591,98 @@
}
for (i = 0; i < ion_pdata.nr; ++i) {
- int reusable = 0;
- int adjacent_heap_id = INVALID_HEAP_ID;
- int mem_is_fmem = 0;
const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
if (heap->extra_data) {
+ int fixed_position = NOT_FIXED;
+ int mem_is_fmem = 0;
+
switch (heap->type) {
case ION_HEAP_TYPE_CP:
- reusable = ((struct ion_cp_heap_pdata *)
- heap->extra_data)->reusable;
mem_is_fmem = ((struct ion_cp_heap_pdata *)
- heap->extra_data)->mem_is_fmem;
+ heap->extra_data)->mem_is_fmem;
+ fixed_position = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->fixed_position;
break;
case ION_HEAP_TYPE_CARVEOUT:
- adjacent_heap_id = ((struct ion_co_heap_pdata *)
- heap->extra_data)->adjacent_mem_id;
mem_is_fmem = ((struct ion_co_heap_pdata *)
- heap->extra_data)->mem_is_fmem;
+ heap->extra_data)->mem_is_fmem;
+ fixed_position = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ default:
+ break;
+ }
+
+ if (fixed_position != NOT_FIXED)
+ fixed_size += heap->size;
+ else
+ reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
+
+ if (fixed_position == FIXED_LOW)
+ fixed_low_size += heap->size;
+ else if (fixed_position == FIXED_MIDDLE)
+ fixed_middle_size += heap->size;
+ else if (fixed_position == FIXED_HIGH)
+ fixed_high_size += heap->size;
+
+ if (mem_is_fmem)
+ fmem_pdata.size += heap->size;
+ }
+ }
+
+ if (!fixed_size)
+ return;
+
+ if (fmem_pdata.size) {
+ fmem_pdata.reserved_size_low = fixed_low_size;
+ fmem_pdata.reserved_size_high = fixed_high_size;
+ }
+
+ /* Since the fixed area may be carved out of lowmem,
+ * make sure the length is a multiple of 1M.
+ */
+ fixed_size = (fixed_size + MSM_MM_FW_SIZE + SECTION_SIZE - 1)
+ & SECTION_MASK;
+ msm8960_reserve_fixed_area(fixed_size);
+
+ fixed_low_start = MSM8960_FIXED_AREA_START;
+ fixed_middle_start = fixed_low_start + fixed_low_size;
+ fixed_high_start = fixed_middle_start + fixed_middle_size;
+
+ for (i = 0; i < ion_pdata.nr; ++i) {
+ struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+
+ if (heap->extra_data) {
+ int fixed_position = NOT_FIXED;
+
+ switch (heap->type) {
+ case ION_HEAP_TYPE_CP:
+ fixed_position = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ case ION_HEAP_TYPE_CARVEOUT:
+ fixed_position = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->fixed_position;
+ break;
+ default:
+ break;
+ }
+
+ switch (fixed_position) {
+ case FIXED_LOW:
+ heap->base = fixed_low_start;
+ break;
+ case FIXED_MIDDLE:
+ heap->base = fixed_middle_start;
+ break;
+ case FIXED_HIGH:
+ heap->base = fixed_high_start;
break;
default:
break;
}
}
-
- if (mem_is_fmem && !reusable) {
- if (adjacent_heap_id != INVALID_HEAP_ID)
- fmem_pdata.reserved_size_low += heap->size;
- else
- fmem_pdata.reserved_size_high += heap->size;
- }
- if (mem_is_fmem)
- fmem_pdata.size += heap->size;
- else
- reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
}
#endif
}
@@ -659,6 +751,7 @@
static struct reserve_info msm8960_reserve_info __initdata = {
.memtype_reserve_table = msm8960_reserve_table,
.calculate_reserve_sizes = msm8960_calculate_reserve_sizes,
+ .reserve_fixed_area = msm8960_reserve_fixed_area,
.paddr_to_memtype = msm8960_paddr_to_memtype,
};
@@ -674,6 +767,8 @@
unsigned long low, high;
bank_size = msm8960_memory_bank_size();
+ msm8960_reserve_info.bank_size = bank_size;
+
low = meminfo.bank[0].start;
high = mb->start + mb->size;
@@ -681,12 +776,14 @@
if (high < mb->start)
high = ~0UL;
+ if (high < MAX_FIXED_AREA_SIZE + MSM8960_FIXED_AREA_START)
+ panic("fixed area extends beyond end of memory\n");
+
low &= ~(bank_size - 1);
if (high - low <= bank_size)
- return;
+ goto no_dmm;
- msm8960_reserve_info.bank_size = bank_size;
#ifdef CONFIG_ENABLE_DMM
msm8960_reserve_info.low_unstable_address = mb->start -
MIN_MEMORY_BLOCK_SIZE + mb->size;
@@ -695,10 +792,11 @@
msm8960_reserve_info.low_unstable_address,
msm8960_reserve_info.max_unstable_size,
msm8960_reserve_info.bank_size);
-#else
- msm8960_reserve_info.low_unstable_address = 0;
- msm8960_reserve_info.max_unstable_size = 0;
+ return;
#endif
+no_dmm:
+ msm8960_reserve_info.low_unstable_address = high;
+ msm8960_reserve_info.max_unstable_size = 0;
}
static void __init place_movable_zone(void)
@@ -740,7 +838,18 @@
{
msm8960_set_display_params(prim_panel_name, ext_panel_name);
msm_reserve();
- fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
+ if (fmem_pdata.size) {
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+ fmem_pdata.phys = reserve_info->fixed_area_start +
+ MSM_MM_FW_SIZE;
+ pr_info("mm fw at %lx (fixed) size %x\n",
+ reserve_info->fixed_area_start, MSM_MM_FW_SIZE);
+ pr_info("fmem start %lx (fixed) size %lx\n",
+ fmem_pdata.phys, fmem_pdata.size);
+#else
+ fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
+#endif
+ }
}
static int msm8960_change_memory_power(u64 start, u64 size,
@@ -958,6 +1067,83 @@
.dev = {.platform_data = &qcom_wcnss_pdata},
};
+#ifdef CONFIG_QSEECOM
+/* qseecom bus scaling */
+static struct msm_bus_vectors qseecom_clks_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_dfab_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
+static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(qseecom_clks_init_vectors),
+ qseecom_clks_init_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_sfpb_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+ qseecom_hw_bus_scale_usecases,
+ ARRAY_SIZE(qseecom_hw_bus_scale_usecases),
+ .name = "qsee",
+};
+
+static struct platform_device qseecom_device = {
+ .name = "qseecom",
+ .id = 0,
+ .dev = {
+ .platform_data = &qseecom_bus_pdata,
+ },
+};
+#endif
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -2268,6 +2454,9 @@
#endif
&msm_slim_ctrl,
&msm_device_wcnss_wlan,
+#if defined(CONFIG_QSEECOM)
+ &qseecom_device,
+#endif
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
&qcrypto_device,
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index d5a1d3f..c92c049 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -483,12 +483,18 @@
{ 0 }
};
-static struct clk_data gfx3d_clks[] = {
+static struct clk_data gfx3d_8660_clks[] = {
{ .name = "core_clk", .reset_rate = 27000000 },
{ .name = "iface_clk" },
{ 0 }
};
+static struct clk_data gfx3d_8064_clks[] = {
+ { .name = "core_clk", .reset_rate = 27000000 },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
static struct clk_data ijpeg_clks[] = {
{ .name = "core_clk" },
@@ -579,7 +585,7 @@
GFX2D1_GFS_CTL_REG, 31, gfx2d1_clks,
MSM_BUS_MASTER_GRAPHICS_2D_CORE1, 0),
FOOTSWITCH(FS_GFX3D, "fs_gfx3d", &standard_fs_ops,
- GFX3D_GFS_CTL_REG, 31, gfx3d_clks,
+ GFX3D_GFS_CTL_REG, 31, gfx3d_8660_clks,
MSM_BUS_MASTER_GRAPHICS_3D, 0),
FOOTSWITCH(FS_IJPEG, "fs_ijpeg", &standard_fs_ops,
GEMINI_GFS_CTL_REG, 31, ijpeg_clks,
@@ -625,10 +631,13 @@
if (pdev->id == FS_MDP) {
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_apq8064())
fs->clk_data = mdp_8960_clks;
- else if (cpu_is_msm8x60())
- fs->clk_data = mdp_8660_clks;
else
- BUG();
+ fs->clk_data = mdp_8660_clks;
+ } else if (pdev->id == FS_GFX3D) {
+ if (cpu_is_msm8930() || cpu_is_apq8064())
+ fs->clk_data = gfx3d_8064_clks;
+ else
+ fs->clk_data = gfx3d_8660_clks;
}
for (clock = fs->clk_data; clock->name; clock++) {
diff --git a/arch/arm/mach-msm/include/mach/msm_memtypes.h b/arch/arm/mach-msm/include/mach/msm_memtypes.h
index 29a9d4a..6f9bed1 100644
--- a/arch/arm/mach-msm/include/mach/msm_memtypes.h
+++ b/arch/arm/mach-msm/include/mach/msm_memtypes.h
@@ -55,10 +55,13 @@
struct reserve_info {
struct memtype_reserve *memtype_reserve_table;
void (*calculate_reserve_sizes)(void);
+ void (*reserve_fixed_area)(unsigned long);
int (*paddr_to_memtype)(unsigned int);
unsigned long low_unstable_address;
unsigned long max_unstable_size;
unsigned long bank_size;
+ unsigned long fixed_area_start;
+ unsigned long fixed_area_size;
};
extern struct reserve_info *reserve_info;
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 8dbf304..0db160e 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -317,6 +317,8 @@
if (size >= mt->size) {
size = stable_size(mb,
reserve_info->low_unstable_address);
+ if (!size)
+ continue;
/* mt->size may be larger than size, all this
* means is that we are carving the memory pool
* out of multiple contiguous memory banks.
@@ -370,10 +372,24 @@
}
}
+#define MAX_FIXED_AREA_SIZE 0x11000000
+
void __init msm_reserve(void)
{
+ unsigned long msm_fixed_area_size;
+ unsigned long msm_fixed_area_start;
+
memory_pool_init();
reserve_info->calculate_reserve_sizes();
+
+ msm_fixed_area_size = reserve_info->fixed_area_size;
+ msm_fixed_area_start = reserve_info->fixed_area_start;
+ if (msm_fixed_area_size)
+ if (msm_fixed_area_start > reserve_info->low_unstable_address
+ - MAX_FIXED_AREA_SIZE)
+ reserve_info->low_unstable_address =
+ msm_fixed_area_start;
+
calculate_reserve_limits();
adjust_reserve_sizes();
reserve_memory_for_mempools();
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 42befd1..8a46a2e 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -248,13 +248,16 @@
*/
if (action == MEM_ONLINE) {
for (i = 0; i < nr_pages; i++) {
- if (PageReserved(first_page+i))
- continue;
-
- printk(KERN_WARNING "section number %ld page number %d "
- "not reserved, was it already online?\n",
- phys_index, i);
- return -EBUSY;
+ if (page_is_ram(page_to_pfn(first_page+i))) {
+ if (PageReserved(first_page+i))
+ continue;
+ printk(KERN_WARNING
+ "section number %ld page number"
+ " %d not reserved, was it "
+ " already online?\n",
+ phys_index, i);
+ return -EBUSY;
+ }
}
}
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 6aed95c..2d33096 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -412,9 +412,12 @@
{
int input = 0;
int bypass = 0;
- int ret, cpu, reenable_timer;
+ int ret, cpu, reenable_timer, j;
struct cpu_dbs_info_s *dbs_info;
+ struct cpumask cpus_timer_done;
+ cpumask_clear(&cpus_timer_done);
+
ret = sscanf(buf, "%d", &input);
if (ret != 1)
@@ -447,10 +450,23 @@
continue;
dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+
+ for_each_cpu(j, &cpus_timer_done) {
+ if (!dbs_info->cur_policy) {
+ pr_err("Dbs policy is NULL\n");
+ goto skip_this_cpu;
+ }
+ if (cpumask_test_cpu(j, dbs_info->
+ cur_policy->cpus))
+ goto skip_this_cpu;
+ }
+
+ cpumask_set_cpu(cpu, &cpus_timer_done);
if (dbs_info->cur_policy) {
/* restart dbs timer */
dbs_timer_init(dbs_info);
}
+skip_this_cpu:
unlock_policy_rwsem_write(cpu);
}
}
@@ -463,6 +479,19 @@
continue;
dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+
+ for_each_cpu(j, &cpus_timer_done) {
+ if (!dbs_info->cur_policy) {
+ pr_err("Dbs policy is NULL\n");
+ goto skip_this_cpu_bypass;
+ }
+ if (cpumask_test_cpu(j, dbs_info->
+ cur_policy->cpus))
+ goto skip_this_cpu_bypass;
+ }
+
+ cpumask_set_cpu(cpu, &cpus_timer_done);
+
if (dbs_info->cur_policy) {
/* cpu using ondemand, cancel dbs timer */
mutex_lock(&dbs_info->timer_mutex);
@@ -475,6 +504,7 @@
mutex_unlock(&dbs_info->timer_mutex);
}
+skip_this_cpu_bypass:
unlock_policy_rwsem_write(cpu);
}
}
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 203b41a..15c0ec5 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -81,12 +81,44 @@
return 0;
}
+static void ion_set_base_address(struct ion_platform_heap *heap,
+ struct ion_platform_heap *shared_heap,
+ struct ion_co_heap_pdata *co_heap_data,
+ struct ion_cp_heap_pdata *cp_data)
+{
+ if (cp_data->reusable) {
+ const struct fmem_data *fmem_info = fmem_get_info();
+
+ if (!fmem_info) {
+ pr_err("fmem info pointer NULL!\n");
+ BUG();
+ }
+
+ heap->base = fmem_info->phys - fmem_info->reserved_size_low;
+ cp_data->virt_addr = fmem_info->virt;
+ pr_info("ION heap %s using FMEM\n", shared_heap->name);
+ } else {
+ heap->base = msm_ion_get_base(heap->size + shared_heap->size,
+ shared_heap->memory_type,
+ co_heap_data->align);
+ }
+ if (heap->base) {
+ shared_heap->base = heap->base + heap->size;
+ cp_data->secure_base = heap->base;
+ cp_data->secure_size = heap->size + shared_heap->size;
+ } else {
+ pr_err("%s: could not get memory for heap %s (id %x)\n",
+ __func__, heap->name, heap->id);
+ }
+}
+
static void allocate_co_memory(struct ion_platform_heap *heap,
struct ion_platform_heap heap_data[],
unsigned int nr_heaps)
{
struct ion_co_heap_pdata *co_heap_data =
(struct ion_co_heap_pdata *) heap->extra_data;
+
if (co_heap_data->adjacent_mem_id != INVALID_HEAP_ID) {
struct ion_platform_heap *shared_heap =
find_heap(heap_data, nr_heaps,
@@ -94,30 +126,23 @@
if (shared_heap) {
struct ion_cp_heap_pdata *cp_data =
(struct ion_cp_heap_pdata *) shared_heap->extra_data;
- if (cp_data->reusable) {
+ if (cp_data->fixed_position == FIXED_MIDDLE) {
const struct fmem_data *fmem_info =
fmem_get_info();
- heap->base = fmem_info->phys -
- fmem_info->reserved_size_low;
+
+ if (!fmem_info) {
+ pr_err("fmem info pointer NULL!\n");
+ BUG();
+ }
+
cp_data->virt_addr = fmem_info->virt;
- pr_info("ION heap %s using FMEM\n",
- shared_heap->name);
- } else {
- heap->base = msm_ion_get_base(
- heap->size + shared_heap->size,
- shared_heap->memory_type,
- co_heap_data->align);
- }
- if (heap->base) {
- shared_heap->base = heap->base + heap->size;
cp_data->secure_base = heap->base;
cp_data->secure_size =
heap->size + shared_heap->size;
- } else {
- pr_err("%s: could not get memory for heap %s "
- "(id %x)\n", __func__, heap->name, heap->id);
+ } else if (!heap->base) {
+ ion_set_base_address(heap, shared_heap,
+ co_heap_data, cp_data);
}
-
}
}
}
@@ -138,7 +163,7 @@
for (i = 0; i < nr_heaps; i++) {
struct ion_platform_heap *heap = &heap_data[i];
- if (!heap->base && heap->type == ION_HEAP_TYPE_CARVEOUT) {
+ if (heap->type == ION_HEAP_TYPE_CARVEOUT) {
if (heap->extra_data)
allocate_co_memory(heap, heap_data, nr_heaps);
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 83f402b..87f259d 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -106,10 +106,8 @@
},
#endif
},
- .gmemspace = {
- .gpu_base = 0,
- .sizebytes = SZ_256K,
- },
+ .gmem_base = 0,
+ .gmem_size = SZ_256K,
.pfp_fw = NULL,
.pm4_fw = NULL,
.wait_timeout = 10000, /* in milliseconds */
@@ -472,7 +470,7 @@
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;
- adreno_dev->gmemspace.sizebytes = adreno_gpulist[i].gmem_size;
+ adreno_dev->gmem_size = adreno_gpulist[i].gmem_size;
}
static int __devinit
@@ -792,10 +790,8 @@
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;
+ devinfo.gmem_gpubaseaddr = adreno_dev->gmem_base;
+ devinfo.gmem_sizebytes = adreno_dev->gmem_size;
if (copy_to_user(value, &devinfo, sizeof(devinfo)) !=
0) {
@@ -869,6 +865,48 @@
return status;
}
+static int adreno_setproperty(struct kgsl_device *device,
+ enum kgsl_property_type type,
+ void *value,
+ unsigned int sizebytes)
+{
+ int status = -EINVAL;
+
+ switch (type) {
+ case KGSL_PROP_PWRCTRL: {
+ unsigned int enable;
+ struct kgsl_device_platform_data *pdata =
+ kgsl_device_get_drvdata(device);
+
+ if (sizebytes != sizeof(enable))
+ break;
+
+ if (copy_from_user(&enable, (void __user *) value,
+ sizeof(enable))) {
+ status = -EFAULT;
+ break;
+ }
+
+ if (enable) {
+ if (pdata->nap_allowed)
+ device->pwrctrl.nap_allowed = true;
+
+ kgsl_pwrscale_enable(device);
+ } else {
+ device->pwrctrl.nap_allowed = false;
+ kgsl_pwrscale_disable(device);
+ }
+
+ status = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
static inline void adreno_poke(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
@@ -1065,9 +1103,8 @@
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));
+ BUG_ON(offsetwords*sizeof(uint32_t) >= device->reg_len);
+ reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
if (!in_interrupt())
kgsl_pre_hwaccess(device);
@@ -1083,14 +1120,13 @@
{
unsigned int *reg;
- BUG_ON(offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes);
+ BUG_ON(offsetwords*sizeof(uint32_t) >= device->reg_len);
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));
+ reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
/*ensure previous writes post before this one,
* i.e. act like normal writel() */
@@ -1280,12 +1316,23 @@
unsigned int timestamp = 0;
unsigned int context_id = _get_context_id(context);
- if (type == KGSL_TIMESTAMP_CONSUMED)
+ switch (type) {
+ case KGSL_TIMESTAMP_QUEUED: {
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+
+ timestamp = rb->timestamp[context_id];
+ break;
+ }
+ case KGSL_TIMESTAMP_CONSUMED:
adreno_regread(device, REG_CP_TIMESTAMP, ×tamp);
- else if (type == KGSL_TIMESTAMP_RETIRED)
+ break;
+ case KGSL_TIMESTAMP_RETIRED:
kgsl_sharedmem_readl(&device->memstore, ×tamp,
- KGSL_MEMSTORE_OFFSET(context_id,
- eoptimestamp));
+ KGSL_MEMSTORE_OFFSET(context_id, eoptimestamp));
+ break;
+ }
+
rmb();
return timestamp;
@@ -1401,6 +1448,7 @@
.setstate = adreno_setstate,
.drawctxt_create = adreno_drawctxt_create,
.drawctxt_destroy = adreno_drawctxt_destroy,
+ .setproperty = adreno_setproperty,
};
static struct platform_device_id adreno_id_table[] = {
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 48e70c8..491cf62 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -62,7 +62,8 @@
struct kgsl_device dev; /* Must be first field in this struct */
unsigned int chip_id;
enum adreno_gpurev gpurev;
- struct kgsl_memregion gmemspace;
+ unsigned long gmem_base;
+ unsigned int gmem_size;
struct adreno_context *drawctxt_active;
const char *pfp_fwfile;
unsigned int *pfp_fw;
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 18d0e83..6fa053b 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1325,9 +1325,8 @@
{
int result;
- calc_gmemsize(&drawctxt->context_gmem_shadow,
- adreno_dev->gmemspace.sizebytes);
- tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
+ calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_base);
+ tmp_ctx.gmem_base = adreno_dev->gmem_base;
result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
@@ -1849,12 +1848,8 @@
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);
+ gmem_size = (adreno_dev->gmem_size >> 14);
while (gmem_size >>= 1)
edram_value++;
@@ -1864,7 +1859,7 @@
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);
+ rb_edram_info.f.edram_range = (adreno_dev->gmem_base >> 14);
adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
}
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 32603bd..6b58545 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2138,9 +2138,8 @@
{
int result;
- calc_gmemsize(&drawctxt->context_gmem_shadow,
- adreno_dev->gmemspace.sizebytes);
- tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
+ calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_size);
+ tmp_ctx.gmem_base = adreno_dev->gmem_base;
result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index a93529a..9e9bbf2 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2426,7 +2426,6 @@
{
int result;
int status = -EINVAL;
- struct kgsl_memregion *regspace = NULL;
struct resource *res;
struct platform_device *pdev =
container_of(device->parentdev, struct platform_device, dev);
@@ -2447,26 +2446,25 @@
goto error_pwrctrl_close;
}
if (res->start == 0 || resource_size(res) == 0) {
- KGSL_DRV_ERR(device, "dev %d invalid regspace\n", device->id);
+ KGSL_DRV_ERR(device, "dev %d invalid register region\n",
+ device->id);
status = -EINVAL;
goto error_pwrctrl_close;
}
- regspace = &device->regspace;
- regspace->mmio_phys_base = res->start;
- regspace->sizebytes = resource_size(res);
+ device->reg_phys = res->start;
+ device->reg_len = resource_size(res);
- if (!request_mem_region(regspace->mmio_phys_base,
- regspace->sizebytes, device->name)) {
+ if (!request_mem_region(device->reg_phys, device->reg_len,
+ device->name)) {
KGSL_DRV_ERR(device, "request_mem_region failed\n");
status = -ENODEV;
goto error_pwrctrl_close;
}
- regspace->mmio_virt_base = ioremap(regspace->mmio_phys_base,
- regspace->sizebytes);
+ device->reg_virt = ioremap(device->reg_phys, device->reg_len);
- if (regspace->mmio_virt_base == NULL) {
+ if (device->reg_virt == NULL) {
KGSL_DRV_ERR(device, "ioremap failed\n");
status = -ENODEV;
goto error_release_mem;
@@ -2483,9 +2481,9 @@
disable_irq(device->pwrctrl.interrupt_num);
KGSL_DRV_INFO(device,
- "dev_id %d regs phys 0x%08x size 0x%08x virt %p\n",
- device->id, regspace->mmio_phys_base,
- regspace->sizebytes, regspace->mmio_virt_base);
+ "dev_id %d regs phys 0x%08lx size 0x%08x virt %p\n",
+ device->id, device->reg_phys, device->reg_len,
+ device->reg_virt);
result = kgsl_drm_init(pdev);
if (result)
@@ -2498,10 +2496,10 @@
free_irq(device->pwrctrl.interrupt_num, NULL);
device->pwrctrl.have_irq = 0;
error_iounmap:
- iounmap(regspace->mmio_virt_base);
- regspace->mmio_virt_base = NULL;
+ iounmap(device->reg_virt);
+ device->reg_virt = NULL;
error_release_mem:
- release_mem_region(regspace->mmio_phys_base, regspace->sizebytes);
+ release_mem_region(device->reg_phys, device->reg_len);
error_pwrctrl_close:
kgsl_pwrctrl_close(device);
error:
@@ -2511,15 +2509,12 @@
void kgsl_device_platform_remove(struct kgsl_device *device)
{
- struct kgsl_memregion *regspace = &device->regspace;
-
kgsl_unregister_device(device);
- if (regspace->mmio_virt_base != NULL) {
- iounmap(regspace->mmio_virt_base);
- regspace->mmio_virt_base = NULL;
- release_mem_region(regspace->mmio_phys_base,
- regspace->sizebytes);
+ if (device->reg_virt != NULL) {
+ iounmap(device->reg_virt);
+ device->reg_virt = NULL;
+ release_mem_region(device->reg_phys, device->reg_len);
}
kgsl_pwrctrl_close(device);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index fece715..7d3cfca 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -110,13 +110,6 @@
unsigned int sizebytes);
};
-struct kgsl_memregion {
- unsigned char *mmio_virt_base;
- unsigned int mmio_phys_base;
- uint32_t gpu_base;
- unsigned int sizebytes;
-};
-
/* MH register values */
struct kgsl_mh {
unsigned int mharb;
@@ -143,7 +136,9 @@
unsigned int ver_minor;
uint32_t flags;
enum kgsl_deviceid id;
- struct kgsl_memregion regspace;
+ unsigned long reg_phys;
+ void *reg_virt;
+ unsigned int reg_len;
struct kgsl_memdesc memstore;
const char *iomemname;
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 3efafee..c8db702 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -63,7 +63,8 @@
* return the global timestamp for all contexts
*/
- header->timestamp_queued = -1;
+ header->timestamp_queued = device->ftbl->readtimestamp(device,
+ context, KGSL_TIMESTAMP_QUEUED);
header->timestamp_retired = device->ftbl->readtimestamp(device,
context, KGSL_TIMESTAMP_RETIRED);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index bc5c960..cff7fec 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -700,10 +700,9 @@
{
unsigned int *reg;
- BUG_ON(offsetwords * sizeof(uint32_t) >= device->regspace.sizebytes);
+ BUG_ON(offsetwords * sizeof(uint32_t) >= device->reg_len);
- reg = (unsigned int *)(device->regspace.mmio_virt_base
- + (offsetwords << 2));
+ reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
/*ensure this read finishes before the next one.
* i.e. act like normal readl() */
@@ -718,10 +717,9 @@
{
unsigned int *reg;
- BUG_ON(offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes);
+ BUG_ON(offsetwords*sizeof(uint32_t) >= device->reg_len);
- reg = (unsigned int *)(device->regspace.mmio_virt_base
- + (offsetwords << 2));
+ reg = (unsigned int *)(device->reg_virt + (offsetwords << 2));
kgsl_cffdump_regwrite(device->id, offsetwords << 2, value);
/*ensure previous writes post before this one,
* i.e. act like normal writel() */
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 6026fda..2c42bc7 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -33,6 +33,7 @@
#include <linux/clk.h>
#include <linux/qseecom.h>
#include <linux/freezer.h>
+#include <mach/board.h>
#include <mach/msm_bus.h>
#include <mach/msm_bus_board.h>
#include <mach/scm.h>
@@ -68,6 +69,11 @@
QSEOS_RESULT_FAILURE = 0xFFFFFFFF
};
+enum qseecom_clk_definitions {
+ CLK_DFAB = 0,
+ CLK_SFPB,
+};
+
__packed struct qseecom_check_app_ireq {
uint32_t qsee_cmd_id;
char app_name[MAX_APP_NAME_SIZE];
@@ -137,9 +143,11 @@
static DEFINE_MUTEX(send_msg_lock);
static DEFINE_MUTEX(qsee_bw_mutex);
+static DEFINE_MUTEX(qsee_sfpb_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
static int qsee_bw_count;
+static int qsee_sfpb_bw_count;
static struct clk *qseecom_bus_clk;
static uint32_t qsee_perf_client;
@@ -203,6 +211,10 @@
atomic_t ioctl_count;
};
+/* Function proto types */
+static int qsee_vote_for_clock(int32_t);
+static void qsee_disable_clock_vote(int32_t);
+
static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
struct qseecom_register_listener_req *svc)
{
@@ -601,6 +613,10 @@
pr_err("copy_from_user failed\n");
return -EFAULT;
}
+ /* Vote for the SFPB clock */
+ ret = qsee_vote_for_clock(CLK_SFPB);
+ if (ret)
+ pr_warning("Unable to vote for SFPB clock");
req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
@@ -642,6 +658,7 @@
load_img_req.ifd_data_fd);
if (IS_ERR_OR_NULL(ihandle)) {
pr_err("Ion client could not retrieve the handle\n");
+ qsee_disable_clock_vote(CLK_SFPB);
return -ENOMEM;
}
@@ -667,6 +684,7 @@
pr_err("scm_call rsp.result is QSEOS_RESULT_FAILURE\n");
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
+ qsee_disable_clock_vote(CLK_SFPB);
return -EFAULT;
}
@@ -677,6 +695,7 @@
ret);
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
+ qsee_disable_clock_vote(CLK_SFPB);
return ret;
}
}
@@ -685,6 +704,7 @@
resp.result);
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
+ qsee_disable_clock_vote(CLK_SFPB);
return -EFAULT;
}
@@ -693,6 +713,7 @@
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
pr_err("kmalloc failed\n");
+ qsee_disable_clock_vote(CLK_SFPB);
return -ENOMEM;
}
entry->app_id = app_id;
@@ -715,8 +736,10 @@
if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
pr_err("copy_to_user failed\n");
kzfree(entry);
+ qsee_disable_clock_vote(CLK_SFPB);
return -EFAULT;
}
+ qsee_disable_clock_vote(CLK_SFPB);
return 0;
}
@@ -1151,61 +1174,96 @@
return 0;
}
-static int qsee_vote_for_clock(void)
+static int qsee_vote_for_clock(int32_t clk_type)
{
int ret = 0;
if (!qsee_perf_client)
return ret;
- /* Check if the clk is valid */
- if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
- pr_warn("qseecom bus clock is null or error");
- return -EINVAL;
- }
-
- mutex_lock(&qsee_bw_mutex);
- if (!qsee_bw_count) {
- ret = msm_bus_scale_client_update_request(
- qsee_perf_client, 1);
- if (ret) {
- pr_err("Bandwidth request failed (%d)\n", ret);
- } else {
- ret = clk_enable(qseecom_bus_clk);
- if (ret)
- pr_err("Clock enable failed\n");
+ switch (clk_type) {
+ case CLK_DFAB:
+ /* Check if the clk is valid */
+ if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
+ pr_warn("qseecom bus clock is null or error");
+ return -EINVAL;
}
+ mutex_lock(&qsee_bw_mutex);
+ if (!qsee_bw_count) {
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 1);
+ if (ret)
+ pr_err("DFAB Bandwidth req failed (%d)\n",
+ ret);
+ else
+ qsee_bw_count++;
+ }
+ mutex_unlock(&qsee_bw_mutex);
+ break;
+ case CLK_SFPB:
+ mutex_lock(&qsee_sfpb_bw_mutex);
+ if (!qsee_sfpb_bw_count) {
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 2);
+ if (ret)
+ pr_err("SFPB Bandwidth req failed (%d)\n",
+ ret);
+ else
+ qsee_sfpb_bw_count++;
+ }
+ mutex_unlock(&qsee_sfpb_bw_mutex);
+ break;
+ default:
+ pr_err("Clock type not defined\n");
+ break;
}
- if (ret)
- msm_bus_scale_client_update_request(qsee_perf_client, 0);
- else
- qsee_bw_count++;
-
- mutex_unlock(&qsee_bw_mutex);
return ret;
}
-static void qsee_disable_clock_vote(void)
+static void qsee_disable_clock_vote(int32_t clk_type)
{
+ int32_t ret = 0;
if (!qsee_perf_client)
return;
- /* Check if the clk is valid */
- if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
- pr_warn("qseecom bus clock is null or error");
- return;
+ switch (clk_type) {
+ case CLK_DFAB:
+ /* Check if the DFAB clk is valid */
+ if (IS_ERR_OR_NULL(qseecom_bus_clk)) {
+ pr_warn("qseecom bus clock is null or error");
+ return;
+ }
+ mutex_lock(&qsee_bw_mutex);
+ if (qsee_bw_count > 0) {
+ if (qsee_bw_count-- == 1) {
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 0);
+ if (ret)
+ pr_err("SFPB Bandwidth req fail (%d)\n",
+ ret);
+ }
+ }
+ mutex_unlock(&qsee_bw_mutex);
+ break;
+ case CLK_SFPB:
+ mutex_lock(&qsee_sfpb_bw_mutex);
+ if (qsee_sfpb_bw_count > 0) {
+ if (qsee_sfpb_bw_count-- == 1) {
+ ret = msm_bus_scale_client_update_request(
+ qsee_perf_client, 0);
+ if (ret)
+ pr_err("SFPB Bandwidth req fail (%d)\n",
+ ret);
+ }
+ }
+ mutex_unlock(&qsee_sfpb_bw_mutex);
+ break;
+ default:
+ pr_err("Clock type not defined\n");
+ break;
}
- mutex_lock(&qsee_bw_mutex);
- if (qsee_bw_count > 0) {
- if (qsee_bw_count-- == 1) {
- msm_bus_scale_client_update_request(qsee_perf_client,
- 0);
- clk_disable(qseecom_bus_clk);
- }
- }
- mutex_unlock(&qsee_bw_mutex);
}
static int qseecom_load_external_elf(struct qseecom_dev_handle *data,
@@ -1417,15 +1475,15 @@
}
case QSEECOM_IOCTL_PERF_ENABLE_REQ:{
atomic_inc(&data->ioctl_count);
- ret = qsee_vote_for_clock();
+ ret = qsee_vote_for_clock(CLK_DFAB);
if (ret)
- pr_err("Failed to vote for clock%d\n", ret);
+ pr_err("Failed to vote for DFAB clock%d\n", ret);
atomic_dec(&data->ioctl_count);
break;
}
case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
atomic_inc(&data->ioctl_count);
- qsee_disable_clock_vote();
+ qsee_disable_clock_vote(CLK_DFAB);
atomic_dec(&data->ioctl_count);
break;
}
@@ -1527,41 +1585,11 @@
mutex_unlock(&pil_access_lock);
}
kfree(data);
- qsee_disable_clock_vote();
+ qsee_disable_clock_vote(CLK_DFAB);
return ret;
}
-/* qseecom bus scaling */
-static struct msm_bus_paths qsee_bw_table[] = {
- {
- .vectors = (struct msm_bus_vectors[]){
- {
- .src = MSM_BUS_MASTER_SPS,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- },
- },
- .num_paths = 1,
- },
- {
- .vectors = (struct msm_bus_vectors[]){
- {
- .src = MSM_BUS_MASTER_SPS,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ib = (492 * 8) * 1000000UL,
- .ab = (492 * 8) * 100000UL,
- },
- },
- .num_paths = 1,
- },
-};
-
-static struct msm_bus_scale_pdata qsee_bus_pdata = {
- .usecase = qsee_bw_table,
- .num_usecases = ARRAY_SIZE(qsee_bw_table),
- .name = "qsee",
-};
-
static const struct file_operations qseecom_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = qseecom_ioctl,
@@ -1569,11 +1597,12 @@
.release = qseecom_release
};
-static int __init qseecom_init(void)
+static int __devinit qseecom_probe(struct platform_device *pdev)
{
int rc;
struct device *class_dev;
char qsee_not_legacy = 0;
+ struct msm_bus_scale_pdata *qseecom_platform_support;
uint32_t system_call_id = QSEOS_CHECK_VERSION_CMD;
qsee_bw_count = 0;
@@ -1639,8 +1668,10 @@
}
/* register client for bus scaling */
+ qseecom_platform_support = (struct msm_bus_scale_pdata *)
+ pdev->dev.platform_data;
qsee_perf_client = msm_bus_scale_register_client(
- &qsee_bus_pdata);
+ qseecom_platform_support);
if (!qsee_perf_client) {
pr_err("Unable to register bus client\n");
} else {
@@ -1663,7 +1694,28 @@
return rc;
}
-static void __exit qseecom_exit(void)
+static int __devinit qseecom_remove(struct platform_device *pdev)
+{
+ if (pdev->dev.platform_data != NULL)
+ msm_bus_scale_unregister_client(qsee_perf_client);
+ return 0;
+};
+
+static struct platform_driver qseecom_plat_driver = {
+ .probe = qseecom_probe,
+ .remove = qseecom_remove,
+ .driver = {
+ .name = "qseecom",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __devinit qseecom_init(void)
+{
+ return platform_driver_register(&qseecom_plat_driver);
+}
+
+static void __devexit qseecom_exit(void)
{
clk_put(qseecom_bus_clk);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index d761e1e..ae49bce 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -79,6 +79,13 @@
ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */
};
+enum ion_fixed_position {
+ NOT_FIXED,
+ FIXED_LOW,
+ FIXED_MIDDLE,
+ FIXED_HIGH,
+};
+
/**
* Flag to use when allocating to indicate that a heap is secure.
*/
@@ -168,6 +175,7 @@
* (see FMEM)
* @mem_is_fmem Flag indicating whether this memory is coming from fmem
* or not.
+ * @fixed_position If nonzero, position in the fixed area.
* @virt_addr: Virtual address used when using fmem.
* @request_region: function to be called when the number of allocations
* goes from 0 -> 1
@@ -183,6 +191,7 @@
size_t secure_size; /* Size used for securing heap when heap is shared*/
int reusable;
int mem_is_fmem;
+ enum ion_fixed_position fixed_position;
ion_virt_addr_t *virt_addr;
int (*request_region)(void *);
int (*release_region)(void *);
@@ -195,6 +204,7 @@
* @align: Alignment requirement for the memory
* @mem_is_fmem Flag indicating whether this memory is coming from fmem
* or not.
+ * @fixed_position If nonzero, position in the fixed area.
* @request_region: function to be called when the number of allocations
* goes from 0 -> 1
* @release_region: function to be called when the number of allocations
@@ -206,6 +216,7 @@
int adjacent_mem_id;
unsigned int align;
int mem_is_fmem;
+ enum ion_fixed_position fixed_position;
int (*request_region)(void *);
int (*release_region)(void *);
void *(*setup_region)(void);
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index ee1a22e..244b957 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -2,7 +2,7 @@
#define _MSM_KGSL_H
#define KGSL_VERSION_MAJOR 3
-#define KGSL_VERSION_MINOR 10
+#define KGSL_VERSION_MINOR 11
/*context flags */
#define KGSL_CONTEXT_SAVE_GMEM 0x00000001
@@ -112,7 +112,7 @@
enum kgsl_timestamp_type {
KGSL_TIMESTAMP_CONSUMED = 0x00000001, /* start-of-pipeline timestamp */
KGSL_TIMESTAMP_RETIRED = 0x00000002, /* end-of-pipeline timestamp*/
- KGSL_TIMESTAMP_MAX = 0x00000002,
+ KGSL_TIMESTAMP_QUEUED = 0x00000003,
};
/* property types - used with kgsl_device_getproperty */
@@ -125,7 +125,8 @@
KGSL_PROP_MMU_ENABLE = 0x00000006,
KGSL_PROP_INTERRUPT_WAITS = 0x00000007,
KGSL_PROP_VERSION = 0x00000008,
- KGSL_PROP_GPU_RESET_STAT = 0x00000009
+ KGSL_PROP_GPU_RESET_STAT = 0x00000009,
+ KGSL_PROP_PWRCTRL = 0x0000000E,
};
struct kgsl_shadowprop {
diff --git a/kernel/resource.c b/kernel/resource.c
index fdd3939..ef4beab 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -357,12 +357,18 @@
while ((res.start < res.end) &&
(find_next_system_ram(&res, "System RAM") >= 0)) {
pfn = (res.start + PAGE_SIZE - 1) >> PAGE_SHIFT;
- end_pfn = (res.end + 1) >> PAGE_SHIFT;
+ if (res.end + 1 <= 0)
+ end_pfn = res.end >> PAGE_SHIFT;
+ else
+ end_pfn = (res.end + 1) >> PAGE_SHIFT;
if (end_pfn > pfn)
ret = (*func)(pfn, end_pfn - pfn, arg);
if (ret)
break;
- res.start = res.end + 1;
+ if (res.end + 1 > res.start)
+ res.start = res.end + 1;
+ else
+ res.start = res.end;
res.end = orig_end;
}
return ret;