Merge "clk: qcom: gcc-sdm845: Update the PCIe pipe clock structures"
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
index 8a3e704..c3c8212 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
@@ -9,7 +9,7 @@
- compatible
Usage: required
Value type: <string>
- Definition: must be "qcom,clk-cpu-osm".
+ Definition: must be "qcom,clk-cpu-osm" or "qcom,clk-cpu-osm-v2".
- reg
Usage: required
@@ -85,24 +85,6 @@
by the OSM hardware for each supported DCVS setpoint
of the Performance cluster.
-- qcom,l3-min-cpr-vc-binX
- Usage: required
- Value type: <u32>
- Definition: First virtual corner which does not use PLL post-divider
- for the L3 clock domain.
-
-- qcom,pwrcl-min-cpr-vc-binX
- Usage: required
- Value type: <u32>
- Definition: First virtual corner which does not use PLL post-divider
- for the power cluster.
-
-- qcom,perfcl-min-cpr-vc-binX
- Usage: required
- Value type: <u32>
- Definition: First virtual corner which does not use PLL post-divider
- for the performance cluster.
-
- qcom,osm-no-tz
Usage: optional
Value type: <empty>
@@ -501,10 +483,6 @@
< 1881600000 0x404c1462 0x00004e4e 0x2 21 >,
< 1958400000 0x404c1566 0x00005252 0x3 22 >;
- qcom,l3-min-cpr-vc-bin0 = <7>;
- qcom,pwrcl-min-cpr-vc-bin0 = <6>;
- qcom,perfcl-min-cpr-vc-bin0 = <7>;
-
qcom,up-timer =
<1000 1000 1000>;
qcom,down-timer =
diff --git a/Documentation/devicetree/bindings/arm/msm/rdbg-smp2p.txt b/Documentation/devicetree/bindings/arm/msm/rdbg-smp2p.txt
index ce2d8bd..1114308 100644
--- a/Documentation/devicetree/bindings/arm/msm/rdbg-smp2p.txt
+++ b/Documentation/devicetree/bindings/arm/msm/rdbg-smp2p.txt
@@ -2,12 +2,15 @@
Required properties:
-compatible : Should be one of
- To communicate with modem
+ To communicate with adsp
qcom,smp2pgpio_client_rdbg_2_in (inbound)
qcom,smp2pgpio_client_rdbg_2_out (outbound)
To communicate with modem
qcom,smp2pgpio_client_rdbg_1_in (inbound)
qcom,smp2pgpio_client_rdbg_1_out (outbound)
+ To communicate with cdsp
+ qcom,smp2pgpio_client_rdbg_5_in (inbound)
+ qcom,smp2pgpio_client_rdbg_5_out (outbound)
-gpios : the relevant gpio pins of the entry.
Example:
diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt
index d3222fb..dd668cb 100644
--- a/Documentation/devicetree/bindings/display/msm/sde.txt
+++ b/Documentation/devicetree/bindings/display/msm/sde.txt
@@ -52,6 +52,9 @@
The number of offsets defined should reflect the
amount of mixers that can drive data to a panel
interface.
+- qcom,sde-dspp-top-off: Offset address for the dspp top block.
+ The offset is calculated from register "mdp_phys"
+ defined in reg property.
- qcom,sde-dspp-off: Array of offset addresses for the available dspp
blocks. These offsets are calculated from
register "mdp_phys" defined in reg property.
@@ -207,6 +210,7 @@
e.g. qcom,sde-dspp-blocks
-- qcom,sde-dspp-pcc: offset and version of PCC hardware
-- qcom,sde-dspp-gc: offset and version of GC hardware
+ -- qcom,sde-dspp-igc: offset and version of IGC hardware
-- qcom,sde-dspp-hsic: offset and version of global PA adjustment
-- qcom,sde-dspp-memcolor: offset and version of PA memcolor hardware
-- qcom,sde-dspp-sixzone: offset and version of PA sixzone hardware
@@ -424,6 +428,7 @@
0x00002600 0x00002800>;
qcom,sde-mixer-off = <0x00045000 0x00046000
0x00047000 0x0004a000>;
+ qcom,sde-dspp-top-off = <0x1300>;
qcom,sde-dspp-off = <0x00055000 0x00057000>;
qcom,sde-dspp-ad-off = <0x24000 0x22800>;
qcom,sde-dspp-ad-version = <0x00030000>;
@@ -481,6 +486,7 @@
qcom,sde-sspp-src-size = <0x100>;
qcom,sde-mixer-size = <0x100>;
qcom,sde-ctl-size = <0x100>;
+ qcom,sde-dspp-top-size = <0xc>;
qcom,sde-dspp-size = <0x100>;
qcom,sde-intf-size = <0x100>;
qcom,sde-dsc-size = <0x100>;
@@ -599,6 +605,7 @@
};
qcom,sde-dspp-blocks {
+ qcom,sde-dspp-igc = <0x0 0x00010000>;
qcom,sde-dspp-pcc = <0x1700 0x00010000>;
qcom,sde-dspp-gc = <0x17c0 0x00010000>;
qcom,sde-dspp-hsic = <0x0 0x00010000>;
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 375eaf2..196f6f7 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -91,6 +91,11 @@
a four level page table configuration. Set to use a three
level page table instead.
+- qcom,no-asid-retention:
+ Some hardware may lose internal state for asid after
+ retention. No cache invalidation operations involving asid
+ may be used.
+
- clocks : List of clocks to be used during SMMU register access. See
Documentation/devicetree/bindings/clock/clock-bindings.txt
for information about the format. For each clock specified
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
index da9a632..536507c 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
@@ -77,6 +77,11 @@
register dumps on CRC errors and also downgrade bus speed mode to
SDR50/DDR50 in case of continuous CRC errors. Set this flag to enable
this workaround.
+ - qcom,restore-after-cx-collapse - specifies whether the SDCC registers contents need
+ to be saved and restored by software when the CX Power Collapse feature is enabled.
+ On certain chipsets, coming out of the CX Power Collapse event, the SDCC registers
+ contents will not be retained. It is software responsibility to restore the
+ SDCC registers before resuming to normal operation.
In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltage).
- qcom,<supply>-always-on - specifies whether supply should be kept "on" always.
diff --git a/Documentation/misc-devices/qcom_invoke_driver.txt b/Documentation/misc-devices/qcom_invoke_driver.txt
new file mode 100644
index 0000000..38c976a
--- /dev/null
+++ b/Documentation/misc-devices/qcom_invoke_driver.txt
@@ -0,0 +1,54 @@
+Introduction:
+=============
+Invoke driver is a misc driver which helps communication between non secure
+and secure world. Invoke driver communicates with secure side using SCM
+driver. To use invoke driver, open must be called on invoke device i.e.
+/dev/invoke. Invoke driver exposes only one IOCTL invoke which passes
+userspace request to TZ.
+
+SW Architecture
+===============
+Following is SW stack for Invoke driver.
+
++++++++++++++++++++++++++++++++++++++++++
++ Applications +
++++++++++++++++++++++++++++++++++++++++++
++ System Layer +
++++++++++++++++++++++++++++++++++++++++++
++ Kernel +
++ +++++++++++++++++++ +
++ + Invoke driver + +
++ +++++++++++++++++++ +
++ + SCM Driver + +
++++++++++++++++++++++++++++++++++++++++++
+ ||
+ ||
+ \/
++++++++++++++++++++++++++++++++++++++++++
++ Trust Zone +
++ +++++++++++ +++++++++++ +
++ + TZ App1 + + TZ App2 + +
++++++++++++++++++++++++++++++++++++++++++
+
+
+Interfaces
+==========
+Invoke driver exposes INVOKE_IOCTL_INVOKE_REQ IOCTL for userspace to
+communicate with driver. More details of IOCTL are avilable in
+corresponding header file.
+
+
+Driver Parameters
+=================
+This driver is built and statically linked into the kernel; therefore,
+there are no module parameters supported by this driver.
+
+There are no kernel command line parameters supported by this driver.
+
+Power Management
+================
+TBD
+
+Dependencies
+============
+Invoke driver depends on SCM driver to communicate with TZ.
diff --git a/Makefile b/Makefile
index 88cab97..9839cf4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
-SUBLEVEL = 36
+SUBLEVEL = 37
EXTRAVERSION =
NAME = Roaring Lionus
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e06ecbb..21c66eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -117,7 +117,7 @@
config ARM_DMA_IOMMU_ALIGNMENT
int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers"
range 4 9
- default 8
+ default 9
help
DMA mapping framework by default aligns all buffers to the smallest
PAGE_SIZE order which is greater than or equal to the requested buffer
@@ -1764,6 +1764,29 @@
source "mm/Kconfig"
+choice
+ prompt "Virtual Memory Reclaim"
+ default NO_VM_RECLAIM
+ help
+ Select the method of reclaiming virtual memory
+
+config ENABLE_VMALLOC_SAVING
+ bool "Reclaim memory for each subsystem"
+ help
+ Enable this config to reclaim the virtual space belonging
+ to any subsystem which is expected to have a lifetime of
+ the entire system. This feature allows lowmem to be non-
+ contiguous.
+
+config NO_VM_RECLAIM
+ bool "Do not reclaim memory"
+ help
+ Do not reclaim any memory. This might result in less lowmem
+ and wasting virtual memory space which could otherwise be
+ reclaimed by using any of the other two config options.
+
+endchoice
+
config FORCE_MAX_ZONEORDER
int "Maximum zone order"
default "12" if SOC_AM33XX
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 370581a..483d126 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -469,6 +469,54 @@
#endif
}
+#define MLK(b, t) (b), (t), (((t) - (b)) >> 10)
+#define MLM(b, t) (b), (t), (((t) - (b)) >> 20)
+#define MLK_ROUNDUP(b, t) (b), (t), (DIV_ROUND_UP(((t) - (b)), SZ_1K))
+
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+static void print_vmalloc_lowmem_info(void)
+{
+ struct memblock_region *reg, *prev_reg = NULL;
+
+ pr_notice(
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)high_memory, VMALLOC_END));
+
+ for_each_memblock_rev(memory, reg) {
+ phys_addr_t start_phys = reg->base;
+ phys_addr_t end_phys = reg->base + reg->size;
+
+ if (start_phys > arm_lowmem_limit)
+ continue;
+
+ if (end_phys > arm_lowmem_limit)
+ end_phys = arm_lowmem_limit;
+
+ if (prev_reg == NULL) {
+ prev_reg = reg;
+
+ pr_notice(
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)__va(start_phys),
+ (unsigned long)__va(end_phys)));
+
+ continue;
+ }
+
+ pr_notice(
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)__va(end_phys),
+ (unsigned long)__va(prev_reg->base)));
+
+
+ pr_notice(
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)__va(start_phys),
+ (unsigned long)__va(end_phys)));
+ }
+}
+#endif
+
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -497,9 +545,6 @@
mem_init_print_info(NULL);
-#define MLK(b, t) b, t, ((t) - (b)) >> 10
-#define MLM(b, t) b, t, ((t) - (b)) >> 20
-#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
pr_notice("Virtual kernel memory layout:\n"
" vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
@@ -507,29 +552,34 @@
" DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
" ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
#endif
- " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
- " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
- " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#ifdef CONFIG_HIGHMEM
- " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#endif
-#ifdef CONFIG_MODULES
- " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#endif
- " .text : 0x%p" " - 0x%p" " (%4td kB)\n"
- " .init : 0x%p" " - 0x%p" " (%4td kB)\n"
- " .data : 0x%p" " - 0x%p" " (%4td kB)\n"
- " .bss : 0x%p" " - 0x%p" " (%4td kB)\n",
-
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n",
MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
(PAGE_SIZE)),
#ifdef CONFIG_HAVE_TCM
MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
MLK(ITCM_OFFSET, (unsigned long) itcm_end),
#endif
- MLK(FIXADDR_START, FIXADDR_END),
+ MLK(FIXADDR_START, FIXADDR_END));
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ print_vmalloc_lowmem_info();
+#else
+ printk(KERN_NOTICE
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n",
MLM(VMALLOC_START, VMALLOC_END),
- MLM(PAGE_OFFSET, (unsigned long)high_memory),
+ MLM(PAGE_OFFSET, (unsigned long)high_memory));
+#endif
+ printk(KERN_NOTICE
+#ifdef CONFIG_HIGHMEM
+ " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+#ifdef CONFIG_MODULES
+ " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+ " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
#ifdef CONFIG_HIGHMEM
MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
(PAGE_SIZE)),
@@ -543,10 +593,6 @@
MLK_ROUNDUP(_sdata, _edata),
MLK_ROUNDUP(__bss_start, __bss_stop));
-#undef MLK
-#undef MLM
-#undef MLK_ROUNDUP
-
/*
* Check boundaries twice: Some fundamental inconsistencies can
* be detected at build time already.
@@ -573,6 +619,11 @@
}
#ifdef CONFIG_DEBUG_RODATA
+#undef MLK
+#undef MLM
+#undef MLK_ROUNDUP
+
+#ifdef CONFIG_ARM_KERNMEM_PERMS
struct section_perm {
const char *name;
unsigned long start;
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ff0eed2..203728d 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -92,7 +92,8 @@
void *vaddr;
vm = &svm->vm;
- vm_area_add_early(vm);
+ if (!vm_area_check_early(vm))
+ vm_area_add_early(vm);
vaddr = vm->addr;
list_for_each_entry(curr_svm, &static_vmlist, list) {
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f7c7413..ddc72dc 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1168,6 +1168,19 @@
*/
vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ struct memblock_region *prev_reg = NULL;
+
+ for_each_memblock(memory, reg) {
+ if (prev_reg == NULL) {
+ prev_reg = reg;
+ continue;
+ }
+ vmalloc_limit += reg->base - (prev_reg->base + prev_reg->size);
+ prev_reg = reg;
+ }
+#endif
+
for_each_memblock(memory, reg) {
phys_addr_t block_start = reg->base;
phys_addr_t block_end = reg->base + reg->size;
@@ -1428,12 +1441,21 @@
phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
#endif
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
+ struct static_vm *svm;
+ phys_addr_t start;
+ phys_addr_t end;
+ unsigned long vaddr;
+ unsigned long pfn;
+ unsigned long length;
+ unsigned int type;
+ int nr = 0;
/* Map all the lowmem memory banks. */
for_each_memblock(memory, reg) {
- phys_addr_t start = reg->base;
- phys_addr_t end = start + reg->size;
struct map_desc map;
+ start = reg->base;
+ end = start + reg->size;
+ nr++;
if (memblock_is_nomap(reg))
continue;
@@ -1485,6 +1507,34 @@
}
}
}
+ svm = early_alloc_aligned(sizeof(*svm) * nr, __alignof__(*svm));
+
+ for_each_memblock(memory, reg) {
+ struct vm_struct *vm;
+
+ start = reg->base;
+ end = start + reg->size;
+
+ if (end > arm_lowmem_limit)
+ end = arm_lowmem_limit;
+ if (start >= end)
+ break;
+
+ vm = &svm->vm;
+ pfn = __phys_to_pfn(start);
+ vaddr = __phys_to_virt(start);
+ length = end - start;
+ type = MT_MEMORY_RW;
+
+ vm->addr = (void *)(vaddr & PAGE_MASK);
+ vm->size = PAGE_ALIGN(length + (vaddr & ~PAGE_MASK));
+ vm->phys_addr = __pfn_to_phys(pfn);
+ vm->flags = VM_LOWMEM;
+ vm->flags |= VM_ARM_MTYPE(type);
+ vm->caller = map_lowmem;
+ add_static_vm_early(svm++);
+ mark_vmalloc_reserved_area(vm->addr, vm->size);
+ }
}
#ifdef CONFIG_ARM_PV_FIXUP
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 9b20651..20288fe 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -2,16 +2,27 @@
dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
-
ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
dtbo-$(CONFIG_ARCH_SDM845) += \
sdm845-cdp-overlay.dtbo \
sdm845-mtp-overlay.dtbo \
- sdm845-qrd-overlay.dtbo
+ sdm845-qrd-overlay.dtbo \
+ sdm845-v2-cdp-overlay.dtbo \
+ sdm845-v2-mtp-overlay.dtbo \
+ sdm845-v2-qrd-overlay.dtbo \
+ sdm845-4k-panel-mtp-overlay.dtbo \
+ sdm845-4k-panel-cdp-overlay.dtbo \
+ sdm845-4k-panel-qrd-overlay.dtbo
sdm845-cdp-overlay.dtbo-base := sdm845.dtb
sdm845-mtp-overlay.dtbo-base := sdm845.dtb
sdm845-qrd-overlay.dtbo-base := sdm845.dtb
+sdm845-v2-cdp-overlay.dtbo-base := sdm845-v2.dtb
+sdm845-v2-mtp-overlay.dtbo-base := sdm845-v2.dtb
+sdm845-v2-qrd-overlay.dtbo-base := sdm845-v2.dtb
+sdm845-4k-panel-mtp-overlay.dtbo-base := sdm845.dtb
+sdm845-4k-panel-cdp-overlay.dtbo-base := sdm845.dtb
+sdm845-4k-panel-qrd-overlay.dtbo-base := sdm845.dtb
else
dtb-$(CONFIG_ARCH_SDM845) += sdm845-sim.dtb \
sdm845-rumi.dtb \
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
index c52c18b..44b817e 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
@@ -35,6 +35,11 @@
qcom,mdss-dsi-color-order = "rgb_swap_rgb";
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-panel-hdr-enabled;
+ qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000
+ 17000 15500 30000 8000 3000>;
+ qcom,mdss-dsi-panel-peak-brightness = <4200000>;
+ qcom,mdss-dsi-panel-blackness-level = <3230>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
15 01 00 00 00 00 02 ff 20
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
index fe9129c..515949e 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
@@ -30,6 +30,11 @@
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-panel-hdr-enabled;
+ qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000
+ 17000 15500 30000 8000 3000>;
+ qcom,mdss-dsi-panel-peak-brightness = <4200000>;
+ qcom,mdss-dsi-panel-blackness-level = <3230>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
15 01 00 00 00 00 02 ff 20
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
index e4a0370..647ea4e 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
@@ -54,6 +54,11 @@
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
+ qcom,mdss-dsi-panel-hdr-enabled;
+ qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000
+ 17000 15500 30000 8000 3000>;
+ qcom,mdss-dsi-panel-peak-brightness = <4200000>;
+ qcom,mdss-dsi-panel-blackness-level = <3230>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
15 01 00 00 00 00 02 FF 20
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
index d6ef3d8..346a8b4 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
@@ -30,6 +30,11 @@
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0x3ff>;
qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-panel-hdr-enabled;
+ qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000
+ 17000 15500 30000 8000 3000>;
+ qcom,mdss-dsi-panel-peak-brightness = <4200000>;
+ qcom,mdss-dsi-panel-blackness-level = <3230>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
15 01 00 00 00 00 02 FF 20
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
index 1a2ca5b..02fedbe 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
@@ -65,6 +65,7 @@
#iommu-cells = <2>;
qcom,skip-init;
qcom,use-3-lvl-tables;
+ qcom,no-asid-retention;
#global-interrupts = <1>;
#size-cells = <1>;
#address-cells = <1>;
@@ -339,10 +340,10 @@
apps_iommu_coherent_test_device {
compatible = "iommu-debug-test";
/*
- * This SID belongs to QUP1-DMA. We can't use a fake SID for
+ * This SID belongs to TSIF. We can't use a fake SID for
* the apps_smmu device.
*/
- iommus = <&apps_smmu 0x3 0>;
+ iommus = <&apps_smmu 0x20 0>;
dma-coherent;
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
index 2194a42..da3cf00 100644
--- a/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
@@ -199,25 +199,11 @@
status = "disabled";
};
- gpu_gx_domain_addr: syscon@0x5091508 {
- compatible = "syscon";
- reg = <0x5091508 0x4>;
- };
-
- gpu_gx_sw_reset: syscon@0x5091008 {
- compatible = "syscon";
- reg = <0x5091008 0x4>;
- };
-
gpu_gx_gdsc: qcom,gdsc@0x509100c {
compatible = "qcom,gdsc";
regulator-name = "gpu_gx_gdsc";
reg = <0x509100c 0x4>;
- domain-addr = <&gpu_gx_domain_addr>;
- sw-reset = <&gpu_gx_sw_reset>;
- qcom,reset-aon-logic;
qcom,poll-cfg-gdscr;
- qcom,toggle-sw-collapse-in-disable;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 6ea92ee..0cf48a3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -9,3 +9,27 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+
+&qupv3_se9_2uart {
+ status = "disabled";
+};
+
+&qupv3_se12_2uart {
+ status = "ok";
+};
+
+&qupv3_se8_spi {
+ status = "disabled";
+};
+
+&qupv3_se3_i2c {
+ status = "disabled";
+};
+
+&qupv3_se10_i2c {
+ status = "disabled";
+};
+
+&qupv3_se6_4uart {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 6ea92ee..0cf48a3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -9,3 +9,27 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+
+&qupv3_se9_2uart {
+ status = "disabled";
+};
+
+&qupv3_se12_2uart {
+ status = "ok";
+};
+
+&qupv3_se8_spi {
+ status = "disabled";
+};
+
+&qupv3_se3_i2c {
+ status = "disabled";
+};
+
+&qupv3_se10_i2c {
+ status = "disabled";
+};
+
+&qupv3_se6_4uart {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index cce0860..dcc5d1b 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -904,6 +904,34 @@
};
};
+ qupv3_se12_2uart_pins: qupv3_se12_2uart_pins {
+ qupv3_se12_2uart_active: qupv3_se12_2uart_active {
+ mux {
+ pins = "gpio51", "gpio52";
+ function = "qup9";
+ };
+
+ config {
+ pins = "gpio51", "gpio52";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ qupv3_se12_2uart_sleep: qupv3_se12_2uart_sleep {
+ mux {
+ pins = "gpio51", "gpio52";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio51", "gpio52";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+ };
+
qupv3_se12_spi_pins: qupv3_se12_spi_pins {
qupv3_se12_spi_active: qupv3_se12_spi_active {
mux {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sdm670-qupv3.dtsi
index 1fa6e26..657363f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-qupv3.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-qupv3.dtsi
@@ -407,6 +407,23 @@
status = "disabled";
};
+ /* Debug UART Instance for CDP/MTP platform on SDM670 */
+ qupv3_se12_2uart: qcom,qup_uart@0xa90000 {
+ compatible = "qcom,msm-geni-console", "qcom,msm-geni-uart";
+ reg = <0xa90000 0x4000>;
+ reg-names = "se_phys";
+ clock-names = "se-clk", "m-ahb", "s-ahb";
+ clocks = <&clock_gcc GCC_QUPV3_WRAP1_S4_CLK>,
+ <&clock_gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+ <&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&qupv3_se12_2uart_active>;
+ pinctrl-1 = <&qupv3_se12_2uart_sleep>;
+ interrupts = <GIC_SPI 357 0>;
+ qcom,wrapper-core = <&qupv3_1>;
+ status = "disabled";
+ };
+
/* I2C */
qupv3_se8_i2c: i2c@a80000 {
compatible = "qcom,i2c-geni";
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 3eae5f3..40f5d89 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -32,6 +32,14 @@
ufshc1 = &ufshc_mem; /* Embedded UFS slot */
};
+ aliases {
+ serial0 = &qupv3_se12_2uart;
+ spi0 = &qupv3_se8_spi;
+ i2c0 = &qupv3_se10_i2c;
+ i2c1 = &qupv3_se3_i2c;
+ hsuart0 = &qupv3_se6_4uart;
+ };
+
cpus {
#address-cells = <2>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp-overlay.dts
new file mode 100644
index 0000000..0006937
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp-overlay.dts
@@ -0,0 +1,66 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-cdp.dtsi"
+#include "sdm845-cdp-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel CDP";
+ compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <1 1>;
+};
+
+&dsi_nt35597_truly_dsc_cmd_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&mdss_mdp {
+ connectors = <&sde_rscc &sde_wb>;
+};
+
+&dsi_sharp_4k_dsc_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_sharp_4k_dsc_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_sharp_4k_dsc_video_display {
+ qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
index 94d74e2..faf09c4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-cdp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp-overlay.dts
new file mode 100644
index 0000000..2675b96
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp-overlay.dts
@@ -0,0 +1,66 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-mtp.dtsi"
+#include "sdm845-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel MTP";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <8 1>;
+};
+
+&dsi_nt35597_truly_dsc_cmd_display {
+ /delete-property/ qcom,dsi-display-active;
+};
+
+&mdss_mdp {
+ connectors = <&sde_rscc &sde_wb &sde_dp>;
+};
+
+&dsi_sharp_4k_dsc_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_sharp_4k_dsc_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_sharp_4k_dsc_video_display {
+ qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
index fca87e1..2ae9345 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-mtp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd-overlay.dts
new file mode 100644
index 0000000..39c9d37
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd-overlay.dts
@@ -0,0 +1,32 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-qrd.dtsi"
+#include "sdm845-qrd-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel QRD";
+ compatible = "qcom,sdm845-qrd", "qcom,sdm845", "qcom,qrd";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <11 1>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts
index 6171c7b..5951f6d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-qrd.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi
index 5db4c35..9d799cb 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-cdp.dtsi
@@ -153,6 +153,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
@@ -192,6 +193,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
@@ -234,6 +236,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi
index 5db4c35..ab6ba18 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-mtp.dtsi
@@ -153,6 +153,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
@@ -192,6 +193,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
@@ -234,6 +236,7 @@
status = "ok";
clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
clock-rates = <24000000>;
};
@@ -333,7 +336,7 @@
compatible = "qcom,cam-sensor";
reg = <0x02>;
csiphy-sd-index = <2>;
- sensor-position-roll = <90>;
+ sensor-position-roll = <270>;
sensor-position-pitch = <0>;
sensor-position-yaw = <0>;
eeprom-src = <&eeprom_front>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
index 4747c99..efc78e0 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
@@ -15,9 +15,11 @@
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "sdm845-sde-display.dtsi"
#include "sdm845-cdp.dtsi"
#include "sdm845-cdp-audio-overlay.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-cdp.dts
index 22e3aea..0a6aa5e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. 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
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-cdp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index 1ce68e1..fc80330 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -195,10 +195,10 @@
qcom,gpu-pwrlevel@3 {
reg = <3>;
- qcom,gpu-freq = <280000000>;
- qcom,bus-freq = <4>;
- qcom,bus-min = <3>;
- qcom,bus-max = <5>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
index 52c0f05..45941a1 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
@@ -15,9 +15,11 @@
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "sdm845-sde-display.dtsi"
#include "sdm845-mtp.dtsi"
#include "sdm845-audio-overlay.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index f7af60c..e74b342 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. 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
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-mtp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
index 5729d76..6cead9d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
@@ -15,9 +15,11 @@
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "sdm845-sde-display.dtsi"
#include "sdm845-qrd.dtsi"
#include "sdm845-qrd-audio-overlay.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dts b/arch/arm64/boot/dts/qcom/sdm845-qrd.dts
index 228b924..6cb7815 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-qrd.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index bde64b9..6fb4f37 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -496,7 +496,7 @@
qcom,display-topology = <1 1 1>,
<2 2 1>, /* dsc merge */
<2 1 1>; /* 3d mux */
- qcom,default-topology-index = <0>;
+ qcom,default-topology-index = <1>;
};
&dsi_nt35597_truly_dsc_video {
@@ -506,7 +506,7 @@
qcom,display-topology = <1 1 1>,
<2 2 1>, /* dsc merge */
<2 1 1>; /* 3d mux */
- qcom,default-topology-index = <0>;
+ qcom,default-topology-index = <1>;
};
&dsi_sharp_4k_dsc_video {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
index 41c1876..e313e58 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
@@ -57,6 +57,9 @@
0x48000 0x49000 0x4a000>;
qcom,sde-mixer-size = <0x320>;
+ qcom,sde-dspp-top-off = <0x1300>;
+ qcom,sde-dspp-top-size = <0xc>;
+
qcom,sde-dspp-off = <0x55000 0x57000 0x59000 0x5b000>;
qcom,sde-dspp-size = <0x17e0>;
@@ -188,8 +191,10 @@
};
qcom,sde-dspp-blocks {
+ qcom,sde-dspp-igc = <0x0 0x00030001>;
qcom,sde-dspp-vlut = <0xa00 0x00010008>;
qcom,sde-dspp-gamut = <0x1000 0x00040000>;
+ qcom,sde-dspp-pcc = <0x1700 0x00040000>;
qcom,sde-dspp-gc = <0x17c0 0x00010008>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-cdp-overlay.dts
new file mode 100644
index 0000000..3cd7678
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-cdp-overlay.dts
@@ -0,0 +1,31 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-cdp.dtsi"
+#include "sdm845-cdp-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v2 CDP";
+ compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
+ qcom,msm-id = <321 0x20000>;
+ qcom,board-id = <1 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-cdp.dts
index 8ab0593..66ee4c7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-cdp.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845-v2.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-cdp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-mtp-overlay.dts
new file mode 100644
index 0000000..e049357
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-mtp-overlay.dts
@@ -0,0 +1,31 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-mtp.dtsi"
+#include "sdm845-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v2 MTP";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ qcom,msm-id = <321 0x20000>;
+ qcom,board-id = <8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-mtp.dts
index 57c3e71..cea38e6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-mtp.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845-v2.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-mtp.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-qrd-overlay.dts
new file mode 100644
index 0000000..a5a32ab
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-qrd-overlay.dts
@@ -0,0 +1,31 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-qrd.dtsi"
+#include "sdm845-qrd-audio-overlay.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v2 QRD";
+ compatible = "qcom,sdm845-qrd", "qcom,sdm845", "qcom,qrd";
+ qcom,msm-id = <321 0x20000>;
+ qcom,board-id = <11 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-qrd.dts b/arch/arm64/boot/dts/qcom/sdm845-v2-qrd.dts
index 8a9a544..9a87617 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2-qrd.dts
@@ -14,6 +14,7 @@
/dts-v1/;
#include "sdm845-v2.dtsi"
+#include "sdm845-sde-display.dtsi"
#include "sdm845-qrd.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.dts b/arch/arm64/boot/dts/qcom/sdm845-v2.dts
new file mode 100644
index 0000000..d36d0fd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ */
+
+/dts-v1/;
+
+#include "sdm845-v2.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v2 SoC";
+ compatible = "qcom,sdm845";
+ qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 8f9618d..2408d48 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -645,7 +645,6 @@
#include "sdm845-sde-pll.dtsi"
#include "msm-rdbg.dtsi"
#include "sdm845-sde.dtsi"
-#include "sdm845-sde-display.dtsi"
#include "sdm845-qupv3.dtsi"
&soc {
@@ -979,7 +978,7 @@
< 1209600 806400000 >,
< 1516800 883200000 >,
< 1593600 960000000 >,
- < 1708800 1094400000 >;
+ < 1708800 1305600000 >;
};
devfreq_l3lat_4: qcom,cpu4-l3lat-mon {
@@ -993,7 +992,7 @@
< 1190400 806400000 >,
< 1574400 883200000 >,
< 1804800 960000000 >,
- < 2092800 1094400000 >;
+ < 1958400 1305600000 >;
};
cpu_pmu: cpu-pmu {
@@ -1319,10 +1318,6 @@
< 2112000000 0x4054176e 0x00005858 0x3 24 >,
< 2208000000 0x40541873 0x00005c5c 0x3 25 >;
- qcom,l3-min-cpr-vc-bin0 = <7>;
- qcom,pwrcl-min-cpr-vc-bin0 = <6>;
- qcom,perfcl-min-cpr-vc-bin0 = <7>;
-
qcom,up-timer =
<1000 1000 1000>;
qcom,down-timer =
@@ -1969,63 +1964,75 @@
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1401 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb2 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1402 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb3 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1403 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb4 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1404 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb5 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1405 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb6 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1406 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb7 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1407 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb8 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
iommus = <&apps_smmu 0x1408 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb9 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
qcom,secure-context-bank;
iommus = <&apps_smmu 0x1409 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb10 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
qcom,secure-context-bank;
iommus = <&apps_smmu 0x140A 0x30>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb11 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "adsprpc-smd";
iommus = <&apps_smmu 0x1823 0x0>;
+ dma-coherent;
};
qcom,msm_fastrpc_compute_cb12 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "adsprpc-smd";
iommus = <&apps_smmu 0x1824 0x0>;
+ dma-coherent;
};
};
@@ -2239,7 +2246,6 @@
compatible = "qcom,sdm845-llcc";
#cache-cells = <1>;
max-slices = <32>;
- qcom,dump-size = <0x3c0000>;
};
qcom,llcc-erp {
@@ -2253,19 +2259,19 @@
};
LLCC_1: llcc_1_dcache {
- qcom,dump-size = <0xd8000>;
+ qcom,dump-size = <0x114100>;
};
LLCC_2: llcc_2_dcache {
- qcom,dump-size = <0xd8000>;
+ qcom,dump-size = <0x114100>;
};
LLCC_3: llcc_3_dcache {
- qcom,dump-size = <0xd8000>;
+ qcom,dump-size = <0x114100>;
};
LLCC_4: llcc_4_dcache {
- qcom,dump-size = <0xd8000>;
+ qcom,dump-size = <0x114100>;
};
};
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 14243fb..b8f115b 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -86,7 +86,6 @@
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_BOOST=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
-CONFIG_CPU_FREQ_MSM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index b60dd01..0862486 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -131,6 +131,7 @@
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
@@ -520,6 +521,7 @@
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_CDSP_LOADER=y
CONFIG_MSM_AVTIMER=y
+CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
CONFIG_MSM_QBT1000=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 37f7d32..82455e5 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -136,6 +136,7 @@
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
@@ -538,6 +539,7 @@
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_CDSP_LOADER=y
CONFIG_MSM_AVTIMER=y
+CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
CONFIG_MSM_QBT1000=y
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index bb24b4e..b325f74 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1189,20 +1189,24 @@
{
int ret, cpu;
- for_each_possible_cpu(cpu)
- per_cpu(is_hotplugging, cpu) = false;
+ /* set to true so armv8pmu_idle_update doesn't try to load
+ * hw_events before arm_pmu_device_probe has initialized it.
+ */
+ for_each_possible_cpu(cpu) {
+ per_cpu(is_hotplugging, cpu) = true;
+ }
- ret = perf_event_cpu_hp_init();
+ ret = arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
+ (acpi_disabled ? NULL : armv8_pmu_probe_table));
- if (ret)
- return ret;
+ if (!ret) {
+ for_each_possible_cpu(cpu)
+ per_cpu(is_hotplugging, cpu) = false;
- if (acpi_disabled)
- return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
- NULL);
+ ret = perf_event_cpu_hp_init();
+ }
- return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
- armv8_pmu_probe_table);
+ return ret;
}
static struct platform_driver armv8_pmu_driver = {
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
index d376e4b..04c067b 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -84,7 +84,7 @@
movl %edx,%ecx
andl $63,%edx
shrl $6,%ecx
- jz 17f
+ jz .L_copy_short_string
1: movq (%rsi),%r8
2: movq 1*8(%rsi),%r9
3: movq 2*8(%rsi),%r10
@@ -105,7 +105,8 @@
leaq 64(%rdi),%rdi
decl %ecx
jnz 1b
-17: movl %edx,%ecx
+.L_copy_short_string:
+ movl %edx,%ecx
andl $7,%edx
shrl $3,%ecx
jz 20f
@@ -221,6 +222,8 @@
*/
ENTRY(copy_user_enhanced_fast_string)
ASM_STAC
+ cmpl $64,%edx
+ jb .L_copy_short_string /* less then 64 bytes, avoid the costly 'rep' */
movl %edx,%ecx
1: rep
movsb
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 0c2fae8..73eb7fd 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -992,11 +992,12 @@
die("Segment relocations found but --realmode not specified\n");
/* Order the relocations for more efficient processing */
- sort_relocs(&relocs16);
sort_relocs(&relocs32);
#if ELF_BITS == 64
sort_relocs(&relocs32neg);
sort_relocs(&relocs64);
+#else
+ sort_relocs(&relocs16);
#endif
/* Print the relocations */
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 123d211..8cac3d3 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1691,6 +1691,7 @@
return PTR_ERR(sk_tfm);
}
drbg->ctr_handle = sk_tfm;
+ init_completion(&drbg->ctr_completion);
req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
if (!req) {
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c4af003..5eba478 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -856,7 +856,7 @@
const char *buf, size_t count)
{
struct platform_device *pdev = to_platform_device(dev);
- char *driver_override, *old = pdev->driver_override, *cp;
+ char *driver_override, *old, *cp;
if (count > PATH_MAX)
return -EINVAL;
@@ -869,12 +869,15 @@
if (cp)
*cp = '\0';
+ device_lock(dev);
+ old = pdev->driver_override;
if (strlen(driver_override)) {
pdev->driver_override = driver_override;
} else {
kfree(driver_override);
pdev->driver_override = NULL;
}
+ device_unlock(dev);
kfree(old);
@@ -885,8 +888,12 @@
struct device_attribute *attr, char *buf)
{
struct platform_device *pdev = to_platform_device(dev);
+ ssize_t len;
- return sprintf(buf, "%s\n", pdev->driver_override);
+ device_lock(dev);
+ len = sprintf(buf, "%s\n", pdev->driver_override);
+ device_unlock(dev);
+ return len;
}
static DEVICE_ATTR_RW(driver_override);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index a7511a1..8069b36 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -59,7 +59,7 @@
/*
* Assigned numbers, used for dynamic minors
*/
-#define DYNAMIC_MINORS 75 /* like dynamic majors */
+#define DYNAMIC_MINORS 64 /* like dynamic majors */
static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS);
#ifdef CONFIG_PROC_FS
diff --git a/drivers/char/rdbg.c b/drivers/char/rdbg.c
index 92d9399..8612112 100644
--- a/drivers/char/rdbg.c
+++ b/drivers/char/rdbg.c
@@ -22,7 +22,7 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
-#define SMP2P_NUM_PROCS 8
+#define SMP2P_NUM_PROCS 16
#define MAX_RETRIES 20
#define SM_VERSION 1
@@ -146,9 +146,17 @@
{"rdbg_adsp", SMEM_LC_DEBUGGER, 16*1024}, /*ADSP*/
{0}, /*SMP2P_RESERVED_PROC_1*/
{"rdbg_wcnss", 0, 0}, /*WCNSS*/
- {0}, /*SMP2P_RESERVED_PROC_2*/
- {0}, /*SMP2P_POWER_PROC*/
- {0} /*SMP2P_REMOTE_MOCK_PROC*/
+ {"rdbg_cdsp", SMEM_LC_DEBUGGER, 16*1024}, /*CDSP*/
+ {NULL}, /*SMP2P_POWER_PROC*/
+ {NULL}, /*SMP2P_TZ_PROC*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL}, /*EMPTY*/
+ {NULL} /*SMP2P_REMOTE_MOCK_PROC*/
};
static int smq_blockmap_get(struct smq_block_map *block_map,
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index a76ab4a..4700584 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -35,9 +35,10 @@
ssize_t err;
int i, rc;
char *str = buf;
-
struct tpm_chip *chip = to_tpm_chip(dev);
+ memset(&tpm_cmd, 0, sizeof(tpm_cmd));
+
tpm_cmd.header.in = tpm_readpubek_header;
err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 0,
"attempting to read the PUBEK");
diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c
index f12f03d..ab938ba 100644
--- a/drivers/clk/qcom/clk-cpu-osm.c
+++ b/drivers/clk/qcom/clk-cpu-osm.c
@@ -150,12 +150,17 @@
#define DATA_MEM(n) (0x400 + (n) * 4)
-#define DCVS_PERF_STATE_DESIRED_REG_0 0x780
-#define DCVS_PERF_STATE_DESIRED_REG(n) (DCVS_PERF_STATE_DESIRED_REG_0 + \
- (4 * n))
-#define OSM_CYCLE_COUNTER_STATUS_REG_0 0x7d0
-#define OSM_CYCLE_COUNTER_STATUS_REG(n) (OSM_CYCLE_COUNTER_STATUS_REG_0 + \
- (4 * n))
+#define DCVS_PERF_STATE_DESIRED_REG_0_V1 0x780
+#define DCVS_PERF_STATE_DESIRED_REG_0_V2 0x920
+#define DCVS_PERF_STATE_DESIRED_REG(n, v2) \
+ (((v2) ? DCVS_PERF_STATE_DESIRED_REG_0_V2 \
+ : DCVS_PERF_STATE_DESIRED_REG_0_V1) + 4 * (n))
+
+#define OSM_CYCLE_COUNTER_STATUS_REG_0_V1 0x7d0
+#define OSM_CYCLE_COUNTER_STATUS_REG_0_V2 0x9c0
+#define OSM_CYCLE_COUNTER_STATUS_REG(n, v2) \
+ (((v2) ? OSM_CYCLE_COUNTER_STATUS_REG_0_V2 \
+ : OSM_CYCLE_COUNTER_STATUS_REG_0_V1) + 4 * (n))
/* ACD registers */
#define ACD_HW_VERSION 0x0
@@ -444,6 +449,8 @@
return 0;
}
+static bool is_v2;
+
static inline struct clk_osm *to_clk_osm(struct clk_hw *_hw)
{
return container_of(_hw, struct clk_osm, hw);
@@ -604,8 +611,8 @@
}
pr_debug("rate: %lu --> index %d\n", rate, index);
- clk_osm_write_reg(cpuclk, index, DCVS_PERF_STATE_DESIRED_REG_0,
- OSM_BASE);
+ clk_osm_write_reg(cpuclk, index, DCVS_PERF_STATE_DESIRED_REG(0, is_v2),
+ OSM_BASE);
/* Make sure the write goes through before proceeding */
clk_osm_mb(cpuclk, OSM_BASE);
@@ -622,7 +629,7 @@
if (!cpuclk)
return -EINVAL;
- index = clk_osm_read_reg(cpuclk, DCVS_PERF_STATE_DESIRED_REG_0);
+ index = clk_osm_read_reg(cpuclk, DCVS_PERF_STATE_DESIRED_REG(0, is_v2));
pr_debug("%s: Index %d, freq %ld\n", __func__, index,
cpuclk->osm_table[index].frequency);
@@ -890,7 +897,8 @@
static void
osm_set_index(struct clk_osm *c, unsigned int index, unsigned int num)
{
- clk_osm_write_reg(c, index, DCVS_PERF_STATE_DESIRED_REG(num), OSM_BASE);
+ clk_osm_write_reg(c, index, DCVS_PERF_STATE_DESIRED_REG(num, is_v2),
+ OSM_BASE);
/* Make sure the write goes through before proceeding */
clk_osm_mb(c, OSM_BASE);
@@ -915,8 +923,8 @@
return 0;
c = policy->driver_data;
- index = clk_osm_read_reg(c, DCVS_PERF_STATE_DESIRED_REG(c->core_num));
-
+ index = clk_osm_read_reg(c,
+ DCVS_PERF_STATE_DESIRED_REG(c->core_num, is_v2));
return policy->freq_table[index].frequency;
}
@@ -1872,6 +1880,7 @@
static u64 clk_osm_get_cpu_cycle_counter(int cpu)
{
u32 val;
+ int core_num;
unsigned long flags;
struct clk_osm *parent, *c = logical_cpu_to_clk(cpu);
@@ -1887,12 +1896,9 @@
* Use core 0's copy as proxy for the whole cluster when per
* core DCVS is disabled.
*/
- if (parent->per_core_dcvs)
- val = clk_osm_read_reg_no_log(parent,
- OSM_CYCLE_COUNTER_STATUS_REG(c->core_num));
- else
- val = clk_osm_read_reg_no_log(parent,
- OSM_CYCLE_COUNTER_STATUS_REG(0));
+ core_num = parent->per_core_dcvs ? c->core_num : 0;
+ val = clk_osm_read_reg_no_log(parent,
+ OSM_CYCLE_COUNTER_STATUS_REG(core_num, is_v2));
if (val < c->prev_cycle_counter) {
/* Handle counter overflow */
@@ -2061,6 +2067,10 @@
c->osm_table[j].override_data,
c->osm_table[j].mem_acc_level);
+ data = (array[i + FREQ_DATA] & GENMASK(29, 28)) >> 28;
+ if (j && !c->min_cpr_vc && !data)
+ c->min_cpr_vc = c->osm_table[j].virtual_corner;
+
data = (array[i + FREQ_DATA] & GENMASK(18, 16)) >> 16;
if (!last_entry && data == MAX_CORE_COUNT) {
fmax_temp[k] = array[i];
@@ -2243,9 +2253,6 @@
u32 *array;
int rc = 0;
struct resource *res;
- char l3_min_cpr_vc_str[] = "qcom,l3-min-cpr-vc-bin0";
- char pwrcl_min_cpr_vc_str[] = "qcom,pwrcl-min-cpr-vc-bin0";
- char perfcl_min_cpr_vc_str[] = "qcom,perfcl-min-cpr-vc-bin0";
array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32),
GFP_KERNEL);
@@ -2463,35 +2470,6 @@
return -ENOMEM;
}
- snprintf(l3_min_cpr_vc_str, ARRAY_SIZE(l3_min_cpr_vc_str),
- "qcom,l3-min-cpr-vc-bin%d", l3_clk.speedbin);
- rc = of_property_read_u32(of, l3_min_cpr_vc_str, &l3_clk.min_cpr_vc);
- if (rc) {
- dev_err(&pdev->dev, "unable to find %s property, rc=%d\n",
- l3_min_cpr_vc_str, rc);
- return -EINVAL;
- }
-
- snprintf(pwrcl_min_cpr_vc_str, ARRAY_SIZE(pwrcl_min_cpr_vc_str),
- "qcom,pwrcl-min-cpr-vc-bin%d", pwrcl_clk.speedbin);
- rc = of_property_read_u32(of, pwrcl_min_cpr_vc_str,
- &pwrcl_clk.min_cpr_vc);
- if (rc) {
- dev_err(&pdev->dev, "unable to find %s property, rc=%d\n",
- pwrcl_min_cpr_vc_str, rc);
- return -EINVAL;
- }
-
- snprintf(perfcl_min_cpr_vc_str, ARRAY_SIZE(perfcl_min_cpr_vc_str),
- "qcom,perfcl-min-cpr-vc-bin%d", perfcl_clk.speedbin);
- rc = of_property_read_u32(of, perfcl_min_cpr_vc_str,
- &perfcl_clk.min_cpr_vc);
- if (rc) {
- dev_err(&pdev->dev, "unable to find %s property, rc=%d\n",
- perfcl_min_cpr_vc_str, rc);
- return -EINVAL;
- }
-
l3_clk.secure_init = perfcl_clk.secure_init = pwrcl_clk.secure_init =
of_property_read_bool(pdev->dev.of_node, "qcom,osm-no-tz");
@@ -3025,6 +3003,9 @@
return PTR_ERR(ext_xo_clk);
}
+ is_v2 = of_device_is_compatible(pdev->dev.of_node,
+ "qcom,clk-cpu-osm-v2");
+
clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
GFP_KERNEL);
if (!clk_data)
@@ -3037,33 +3018,6 @@
clk_data->clk_num = num_clks;
- rc = clk_osm_parse_dt_configs(pdev);
- if (rc) {
- dev_err(&pdev->dev, "Unable to parse OSM device tree configurations\n");
- return rc;
- }
-
- rc = clk_osm_parse_acd_dt_configs(pdev);
- if (rc) {
- dev_err(&pdev->dev, "Unable to parse ACD device tree configurations\n");
- return rc;
- }
-
- rc = clk_osm_resources_init(pdev);
- if (rc) {
- if (rc != -EPROBE_DEFER)
- dev_err(&pdev->dev, "OSM resources init failed, rc=%d\n",
- rc);
- return rc;
- }
-
- rc = clk_osm_acd_resources_init(pdev);
- if (rc) {
- dev_err(&pdev->dev, "ACD resources init failed, rc=%d\n",
- rc);
- return rc;
- }
-
if (l3_clk.vbases[EFUSE_BASE]) {
/* Multiple speed-bins are supported */
pte_efuse = readl_relaxed(l3_clk.vbases[EFUSE_BASE]);
@@ -3123,6 +3077,33 @@
return rc;
}
+ rc = clk_osm_parse_dt_configs(pdev);
+ if (rc) {
+ dev_err(&pdev->dev, "Unable to parse OSM device tree configurations\n");
+ return rc;
+ }
+
+ rc = clk_osm_parse_acd_dt_configs(pdev);
+ if (rc) {
+ dev_err(&pdev->dev, "Unable to parse ACD device tree configurations\n");
+ return rc;
+ }
+
+ rc = clk_osm_resources_init(pdev);
+ if (rc) {
+ if (rc != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "OSM resources init failed, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ rc = clk_osm_acd_resources_init(pdev);
+ if (rc) {
+ dev_err(&pdev->dev, "ACD resources init failed, rc=%d\n",
+ rc);
+ return rc;
+ }
+
rc = clk_osm_resolve_open_loop_voltages(&l3_clk);
if (rc) {
if (rc == -EPROBE_DEFER)
@@ -3352,6 +3333,7 @@
static const struct of_device_id match_table[] = {
{ .compatible = "qcom,clk-cpu-osm" },
+ { .compatible = "qcom,clk-cpu-osm-v2" },
{}
};
diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c
index 5348491..c314d2c 100644
--- a/drivers/clk/qcom/clk-regmap-divider.c
+++ b/drivers/clk/qcom/clk-regmap-divider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -28,8 +28,10 @@
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
- return divider_round_rate(hw, rate, prate, NULL, divider->width,
- CLK_DIVIDER_ROUND_CLOSEST);
+ return divider_round_rate(hw, rate, prate, divider->table,
+ divider->width,
+ CLK_DIVIDER_ROUND_CLOSEST |
+ divider->flags);
}
static int div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -39,8 +41,9 @@
struct clk_regmap *clkr = ÷r->clkr;
u32 div;
- div = divider_get_val(rate, parent_rate, NULL, divider->width,
- CLK_DIVIDER_ROUND_CLOSEST);
+ div = divider_get_val(rate, parent_rate, divider->table,
+ divider->width, CLK_DIVIDER_ROUND_CLOSEST |
+ divider->flags);
return regmap_update_bits(clkr->regmap, divider->reg,
(BIT(divider->width) - 1) << divider->shift,
@@ -58,8 +61,8 @@
div >>= divider->shift;
div &= BIT(divider->width) - 1;
- return divider_recalc_rate(hw, parent_rate, div, NULL,
- CLK_DIVIDER_ROUND_CLOSEST);
+ return divider_recalc_rate(hw, parent_rate, div, divider->table,
+ CLK_DIVIDER_ROUND_CLOSEST | divider->flags);
}
const struct clk_ops clk_regmap_div_ops = {
diff --git a/drivers/clk/qcom/clk-regmap-divider.h b/drivers/clk/qcom/clk-regmap-divider.h
index fc4492e..1c5e087 100644
--- a/drivers/clk/qcom/clk-regmap-divider.h
+++ b/drivers/clk/qcom/clk-regmap-divider.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -18,10 +18,12 @@
#include "clk-regmap.h"
struct clk_regmap_div {
- u32 reg;
- u32 shift;
- u32 width;
- struct clk_regmap clkr;
+ u32 reg;
+ u32 shift;
+ u32 width;
+ u32 flags;
+ const struct clk_div_table *table;
+ struct clk_regmap clkr;
};
extern const struct clk_ops clk_regmap_div_ops;
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 894efd9..1450b91 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -53,7 +53,9 @@
P_CORE_BI_PLL_TEST_SE,
P_GPLL0_OUT_EVEN,
P_GPLL0_OUT_MAIN,
+ P_GPLL1_OUT_MAIN,
P_GPLL4_OUT_MAIN,
+ P_GPLL6_OUT_MAIN,
P_SLEEP_CLK,
};
@@ -166,6 +168,20 @@
"core_bi_pll_test_se",
};
+static const struct parent_map gcc_parent_map_9[] = {
+ { P_BI_TCXO, 0 },
+ { P_GPLL0_OUT_MAIN, 1 },
+ { P_GPLL1_OUT_MAIN, 4 },
+ { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_9[] = {
+ "bi_tcxo",
+ "gpll0",
+ "gpll1",
+ "core_bi_pll_test_se",
+};
+
static struct clk_dummy measure_only_snoc_clk = {
.rrate = 1000,
.hw.init = &(struct clk_init_data){
@@ -1224,6 +1240,49 @@
},
};
+static struct clk_rcg2 gcc_vs_ctrl_clk_src = {
+ .cmd_rcgr = 0x7a030,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = gcc_parent_map_3,
+ .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gcc_vs_ctrl_clk_src",
+ .parent_names = gcc_parent_names_3,
+ .num_parents = 3,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ VDD_CX_FMAX_MAP1(
+ MIN, 19200000),
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_vsensor_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+ F(600000000, P_GPLL0_OUT_MAIN, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gcc_vsensor_clk_src = {
+ .cmd_rcgr = 0x7a018,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = gcc_parent_map_9,
+ .freq_tbl = ftbl_gcc_vsensor_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gcc_vsensor_clk_src",
+ .parent_names = gcc_parent_names_9,
+ .num_parents = 4,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_ops,
+ VDD_CX_FMAX_MAP3(
+ MIN, 19200000,
+ LOW, 300000000,
+ LOW_L1, 600000000),
+ },
+};
+
static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = {
.halt_reg = 0x90014,
.halt_check = BRANCH_HALT,
@@ -1347,6 +1406,24 @@
},
};
+static struct clk_branch gcc_apc_vs_clk = {
+ .halt_reg = 0x7a050,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_apc_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_boot_rom_ahb_clk = {
.halt_reg = 0x38004,
.halt_check = BRANCH_HALT_VOTED,
@@ -1774,6 +1851,24 @@
},
};
+static struct clk_branch gcc_gpu_vs_clk = {
+ .halt_reg = 0x7a04c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a04c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gpu_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_mss_axis2_clk = {
.halt_reg = 0x8a008,
.halt_check = BRANCH_HALT,
@@ -1855,6 +1950,24 @@
},
};
+static struct clk_branch gcc_mss_vs_clk = {
+ .halt_reg = 0x7a048,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_pcie_0_aux_clk = {
.halt_reg = 0x6b01c,
.halt_check = BRANCH_HALT_VOTED,
@@ -3324,6 +3437,60 @@
},
};
+static struct clk_branch gcc_vdda_vs_clk = {
+ .halt_reg = 0x7a00c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a00c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vdda_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_vddcx_vs_clk = {
+ .halt_reg = 0x7a004,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vddcx_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_vddmx_vs_clk = {
+ .halt_reg = 0x7a008,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a008,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vddmx_vs_clk",
+ .parent_names = (const char *[]){
+ "gcc_vsensor_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_video_ahb_clk = {
.halt_reg = 0xb004,
.halt_check = BRANCH_HALT,
@@ -3365,6 +3532,39 @@
},
};
+static struct clk_branch gcc_vs_ctrl_ahb_clk = {
+ .halt_reg = 0x7a014,
+ .halt_check = BRANCH_HALT,
+ .hwcg_reg = 0x7a014,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x7a014,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vs_ctrl_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_vs_ctrl_clk = {
+ .halt_reg = 0x7a010,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x7a010,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vs_ctrl_clk",
+ .parent_names = (const char *[]){
+ "gcc_vs_ctrl_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
struct clk_hw *gcc_sdm845_hws[] = {
[MEASURE_ONLY_SNOC_CLK] = &measure_only_snoc_clk.hw,
[MEASURE_ONLY_CNOC_CLK] = &measure_only_cnoc_clk.hw,
@@ -3382,6 +3582,7 @@
&gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr,
[GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
[GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr,
+ [GCC_APC_VS_CLK] = &gcc_apc_vs_clk.clkr,
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
[GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
[GCC_CAMERA_AXI_CLK] = &gcc_camera_axi_clk.clkr,
@@ -3415,12 +3616,14 @@
[GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
[GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
[GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+ [GCC_GPU_VS_CLK] = &gcc_gpu_vs_clk.clkr,
[GCC_MSS_AXIS2_CLK] = &gcc_mss_axis2_clk.clkr,
[GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
[GCC_MSS_MFAB_AXIS_CLK] = &gcc_mss_mfab_axis_clk.clkr,
[GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+ [GCC_MSS_VS_CLK] = &gcc_mss_vs_clk.clkr,
[GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
[GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr,
[GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
@@ -3560,9 +3763,16 @@
[GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr,
[GCC_USB3_SEC_PHY_PIPE_CLK] = &gcc_usb3_sec_phy_pipe_clk.clkr,
[GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
+ [GCC_VDDA_VS_CLK] = &gcc_vdda_vs_clk.clkr,
+ [GCC_VDDCX_VS_CLK] = &gcc_vddcx_vs_clk.clkr,
+ [GCC_VDDMX_VS_CLK] = &gcc_vddmx_vs_clk.clkr,
[GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
[GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr,
[GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+ [GCC_VS_CTRL_AHB_CLK] = &gcc_vs_ctrl_ahb_clk.clkr,
+ [GCC_VS_CTRL_CLK] = &gcc_vs_ctrl_clk.clkr,
+ [GCC_VS_CTRL_CLK_SRC] = &gcc_vs_ctrl_clk_src.clkr,
+ [GCC_VSENSOR_CLK_SRC] = &gcc_vsensor_clk_src.clkr,
[GPLL0] = &gpll0.clkr,
[GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
};
diff --git a/drivers/firmware/qcom/tz_log.c b/drivers/firmware/qcom/tz_log.c
index 471476c..9c1c81b 100644
--- a/drivers/firmware/qcom/tz_log.c
+++ b/drivers/firmware/qcom/tz_log.c
@@ -960,7 +960,7 @@
for (i = 0; i < TZDBG_STATS_MAX; i++) {
tzdbg.debug_tz[i] = i;
- dent = debugfs_create_file(tzdbg.stat[i].name,
+ dent = debugfs_create_file_unsafe(tzdbg.stat[i].name,
0444, dent_dir,
&tzdbg.debug_tz[i], &tzdbg_fops);
if (dent == NULL) {
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 2beac0d..7e3d81f 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -211,7 +211,7 @@
static int dp_link_get_period(struct dp_link_private *link, int const addr)
{
int ret = 0;
- u8 *bp;
+ u8 bp;
u8 data;
u32 const param_len = 0x1;
u32 const max_audio_period = 0xA;
@@ -224,7 +224,7 @@
goto exit;
}
- data = *bp;
+ data = bp;
/* Period - Bits 3:0 */
data = data & 0xF;
@@ -322,7 +322,7 @@
static int dp_link_parse_audio_pattern_type(struct dp_link_private *link)
{
int ret = 0;
- u8 *bp;
+ u8 bp;
u8 data;
int rlen;
int const param_len = 0x1;
@@ -337,7 +337,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
/* Audio Pattern Type - Bits 7:0 */
if ((int)data > max_audio_pattern_type) {
@@ -356,7 +356,7 @@
static int dp_link_parse_audio_mode(struct dp_link_private *link)
{
int ret = 0;
- u8 *bp;
+ u8 bp;
u8 data;
int rlen;
int const param_len = 0x1;
@@ -374,7 +374,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
/* Sampling Rate - Bits 3:0 */
sampling_rate = data & 0xF;
@@ -528,14 +528,14 @@
static int dp_link_parse_timing_params1(struct dp_link_private *link,
int const addr, int const len, u32 *val)
{
- u8 *bp;
+ u8 bp[2];
int rlen;
if (len < 2)
return -EINVAL;
/* Read the requested video link pattern (Byte 0x221). */
- rlen = drm_dp_dpcd_read(link->aux->drm_aux, addr, &bp, len);
+ rlen = drm_dp_dpcd_read(link->aux->drm_aux, addr, bp, len);
if (rlen < len) {
pr_err("failed to read 0x%x\n", addr);
return -EINVAL;
@@ -549,14 +549,14 @@
static int dp_link_parse_timing_params2(struct dp_link_private *link,
int const addr, int const len, u32 *val1, u32 *val2)
{
- u8 *bp;
+ u8 bp[2];
int rlen;
if (len < 2)
return -EINVAL;
/* Read the requested video link pattern (Byte 0x221). */
- rlen = drm_dp_dpcd_read(link->aux->drm_aux, addr, &bp, len);
+ rlen = drm_dp_dpcd_read(link->aux->drm_aux, addr, bp, len);
if (rlen < len) {
pr_err("failed to read 0x%x\n", addr);
return -EINVAL;
@@ -571,7 +571,7 @@
static int dp_link_parse_timing_params3(struct dp_link_private *link,
int const addr, u32 *val)
{
- u8 *bp;
+ u8 bp;
u32 len = 1;
int rlen;
@@ -581,7 +581,7 @@
pr_err("failed to read 0x%x\n", addr);
return -EINVAL;
}
- *val = bp[0];
+ *val = bp;
return 0;
}
@@ -597,7 +597,7 @@
{
int ret = 0;
int rlen;
- u8 *bp;
+ u8 bp;
u8 data;
u32 dyn_range;
int const param_len = 0x1;
@@ -612,7 +612,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
if (!dp_link_is_video_pattern_valid(data)) {
pr_err("invalid link video pattern = 0x%x\n", data);
@@ -634,7 +634,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
/* Dynamic Range */
dyn_range = (data & BIT(3)) >> 3;
@@ -789,7 +789,7 @@
*/
static int dp_link_parse_link_training_params(struct dp_link_private *link)
{
- u8 *bp;
+ u8 bp;
u8 data;
int ret = 0;
int rlen;
@@ -803,7 +803,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
if (!dp_link_is_link_rate_valid(data)) {
pr_err("invalid link rate = 0x%x\n", data);
@@ -822,7 +822,7 @@
ret = -EINVAL;
goto exit;
}
- data = *bp;
+ data = bp;
data &= 0x1F;
if (!dp_link_is_lane_count_valid(data)) {
@@ -861,7 +861,7 @@
*/
static int dp_link_parse_phy_test_params(struct dp_link_private *link)
{
- u8 *bp;
+ u8 bp;
u8 data;
int rlen;
int const param_len = 0x1;
@@ -876,7 +876,7 @@
goto end;
}
- data = *bp;
+ data = bp;
link->request.phy_test_pattern_sel = data;
@@ -939,7 +939,7 @@
static int dp_link_parse_request(struct dp_link_private *link)
{
int ret = 0;
- u8 *bp;
+ u8 bp;
u8 data;
int rlen;
u32 const param_len = 0x1;
@@ -957,12 +957,12 @@
goto end;
}
- data = *bp;
+ data = bp;
pr_debug("device service irq vector = 0x%x\n", data);
if (!(data & BIT(1))) {
- pr_debug("no link requested\n");
+ pr_debug("no test requested\n");
goto end;
}
@@ -978,7 +978,7 @@
goto end;
}
- data = *bp;
+ data = bp;
if (!dp_link_is_test_supported(data)) {
pr_debug("link 0x%x not supported\n", data);
@@ -1032,7 +1032,7 @@
*/
static void dp_link_parse_sink_count(struct dp_link_private *link)
{
- u8 *bp;
+ u8 bp;
u8 data;
int rlen;
int const param_len = 0x1;
@@ -1044,7 +1044,7 @@
return;
}
- data = *bp;
+ data = bp;
/* BIT 7, BIT 5:0 */
link->sink_count.count = (data & BIT(7)) << 6 | (data & 0x63);
@@ -1109,7 +1109,7 @@
static int dp_link_parse_vx_px(struct dp_link_private *link)
{
- u8 *bp;
+ u8 bp;
u8 data;
int const param_len = 0x1;
int const addr1 = 0x206;
@@ -1127,7 +1127,7 @@
goto end;
}
- data = *bp;
+ data = bp;
pr_debug("lanes 0/1 (Byte 0x206): 0x%x\n", data);
@@ -1148,7 +1148,7 @@
goto end;
}
- data = *bp;
+ data = bp;
pr_debug("lanes 2/3 (Byte 0x207): 0x%x\n", data);
diff --git a/drivers/gpu/drm/msm/dp/dp_usbpd.c b/drivers/gpu/drm/msm/dp/dp_usbpd.c
index c6ed918..7bc1433 100644
--- a/drivers/gpu/drm/msm/dp/dp_usbpd.c
+++ b/drivers/gpu/drm/msm/dp/dp_usbpd.c
@@ -345,6 +345,9 @@
pd->vdo = *vdos;
dp_usbpd_get_status(pd);
+ if (pd->dp_cb && pd->dp_cb->attention)
+ pd->dp_cb->attention(pd->dev);
+
if (!pd->dp_usbpd.alt_mode_cfg_done)
dp_usbpd_send_event(pd, DP_USBPD_EVT_CONFIGURE);
break;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 11f1c4f..0be17b9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -521,6 +521,7 @@
struct msm_kms *kms;
struct sde_dbg_power_ctrl dbg_power_ctrl = { 0 };
int ret, i;
+ struct sched_param param;
ddev = drm_dev_alloc(drv, dev);
if (!ddev) {
@@ -624,6 +625,12 @@
}
ddev->mode_config.funcs = &mode_config_funcs;
+ /**
+ * this priority was found during empiric testing to have appropriate
+ * realtime scheduling to process display updates and interact with
+ * other real time and normal priority task
+ */
+ param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
/* initialize display thread */
@@ -634,6 +641,11 @@
kthread_run(kthread_worker_fn,
&priv->disp_thread[i].worker,
"crtc_commit:%d", priv->disp_thread[i].crtc_id);
+ ret = sched_setscheduler(priv->disp_thread[i].thread,
+ SCHED_FIFO, ¶m);
+ if (ret)
+ pr_warn("display thread priority update failed: %d\n",
+ ret);
if (IS_ERR(priv->disp_thread[i].thread)) {
dev_err(dev, "failed to create crtc_commit kthread\n");
@@ -648,6 +660,18 @@
kthread_run(kthread_worker_fn,
&priv->event_thread[i].worker,
"crtc_event:%d", priv->event_thread[i].crtc_id);
+ /**
+ * event thread should also run at same priority as disp_thread
+ * because it is handling frame_done events. A lower priority
+ * event thread and higher priority disp_thread can causes
+ * frame_pending counters beyond 2. This can lead to commit
+ * failure at crtc commit level.
+ */
+ ret = sched_setscheduler(priv->event_thread[i].thread,
+ SCHED_FIFO, ¶m);
+ if (ret)
+ pr_warn("display event thread priority update failed: %d\n",
+ ret);
if (IS_ERR(priv->event_thread[i].thread)) {
dev_err(dev, "failed to create crtc_event kthread\n");
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c
index e999a6a..0fc982e 100644
--- a/drivers/gpu/drm/msm/sde/sde_color_processing.c
+++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c
@@ -60,6 +60,8 @@
static void dspp_gc_install_property(struct drm_crtc *crtc);
+static void dspp_igc_install_property(struct drm_crtc *crtc);
+
typedef void (*dspp_prop_install_func_t)(struct drm_crtc *crtc);
static dspp_prop_install_func_t dspp_prop_install_func[SDE_DSPP_MAX];
@@ -80,6 +82,7 @@
func[SDE_DSPP_VLUT] = dspp_vlut_install_property; \
func[SDE_DSPP_GAMUT] = dspp_gamut_install_property; \
func[SDE_DSPP_GC] = dspp_gc_install_property; \
+ func[SDE_DSPP_IGC] = dspp_igc_install_property; \
} while (0)
typedef void (*lm_prop_install_func_t)(struct drm_crtc *crtc);
@@ -1061,6 +1064,7 @@
"SDE_DSPP_PCC_V", version);
switch (version) {
case 1:
+ case 4:
sde_cp_crtc_install_blob_property(crtc, feature_name,
SDE_CP_CRTC_DSPP_PCC, sizeof(struct drm_msm_pcc));
break;
@@ -1241,6 +1245,30 @@
}
}
+static void dspp_igc_install_property(struct drm_crtc *crtc)
+{
+ char feature_name[256];
+ struct sde_kms *kms = NULL;
+ struct sde_mdss_cfg *catalog = NULL;
+ u32 version;
+
+ kms = get_kms(crtc);
+ catalog = kms->catalog;
+
+ version = catalog->dspp[0].sblk->igc.version >> 16;
+ snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
+ "SDE_DSPP_IGC_V", version);
+ switch (version) {
+ case 3:
+ sde_cp_crtc_install_blob_property(crtc, feature_name,
+ SDE_CP_CRTC_DSPP_IGC, sizeof(struct drm_msm_igc_lut));
+ break;
+ default:
+ DRM_ERROR("version %d not supported\n", version);
+ break;
+ }
+}
+
static void sde_cp_update_list(struct sde_cp_node *prop_node,
struct sde_crtc *crtc, bool dirty_list)
{
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c
index 71dfc12..7243fe2 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c
@@ -225,8 +225,17 @@
struct sde_crtc_state *tmp_cstate =
to_sde_crtc_state(tmp_crtc->state);
- bw_sum_of_intfs +=
- tmp_cstate->new_perf.bw_ctl[i];
+ SDE_DEBUG("crtc:%d bw:%llu ctrl:%d\n",
+ tmp_crtc->base.id,
+ tmp_cstate->new_perf.bw_ctl[i],
+ tmp_cstate->bw_control);
+ /*
+ * For bw check only use the bw if the
+ * atomic property has been already set
+ */
+ if (tmp_cstate->bw_control)
+ bw_sum_of_intfs +=
+ tmp_cstate->new_perf.bw_ctl[i];
}
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 63979dd..6bc1309 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -55,9 +55,13 @@
static int sde_crtc_power_interrupt_handler(struct drm_crtc *crtc_drm,
bool en, struct sde_irq_callback *ad_irq);
+static int sde_crtc_pm_event_handler(struct drm_crtc *crtc_drm,
+ bool en, struct sde_irq_callback *noirq);
+
static struct sde_crtc_custom_events custom_events[] = {
{DRM_EVENT_AD_BACKLIGHT, sde_cp_ad_interrupt},
- {DRM_EVENT_CRTC_POWER, sde_crtc_power_interrupt_handler}
+ {DRM_EVENT_CRTC_POWER, sde_crtc_power_interrupt_handler},
+ {DRM_EVENT_SDE_POWER, sde_crtc_pm_event_handler},
};
/* default input fence timeout, in ms */
@@ -2429,6 +2433,8 @@
struct drm_crtc *crtc = arg;
struct sde_crtc *sde_crtc;
struct drm_encoder *encoder;
+ struct drm_event event;
+ u32 power_on = 0;
if (!crtc) {
SDE_ERROR("invalid crtc\n");
@@ -2449,6 +2455,11 @@
sde_encoder_virt_restore(encoder);
}
+ event.type = DRM_EVENT_SDE_POWER;
+ event.length = sizeof(power_on);
+ power_on = 1;
+ msm_mode_object_event_notify(&crtc->base, crtc->dev, &event,
+ (u8 *)&power_on);
} else if (event_type == SDE_POWER_EVENT_POST_DISABLE) {
struct drm_plane *plane;
@@ -2460,6 +2471,12 @@
sde_plane_set_revalidate(plane, true);
sde_cp_crtc_suspend(crtc);
+
+ event.type = DRM_EVENT_SDE_POWER;
+ event.length = sizeof(power_on);
+ power_on = 0;
+ msm_mode_object_event_notify(&crtc->base, crtc->dev, &event,
+ (u8 *)&power_on);
}
mutex_unlock(&sde_crtc->crtc_lock);
@@ -2758,7 +2775,8 @@
/* check dim layer stage with every plane */
for (i = 0; i < cstate->num_dim_layers; i++) {
- if (pstates[cnt].stage == cstate->dim_layer[i].stage) {
+ if (cstate->dim_layer[i].stage
+ == (pstates[cnt].stage + SDE_STAGE_0)) {
SDE_ERROR(
"plane:%d/dim_layer:%i-same stage:%d\n",
plane->base.id, i,
@@ -3975,3 +3993,13 @@
{
return 0;
}
+
+static int sde_crtc_pm_event_handler(struct drm_crtc *crtc, bool en,
+ struct sde_irq_callback *noirq)
+{
+ /*
+ * IRQ object noirq is not being used here since there is
+ * no crtc irq from pm event.
+ */
+ return 0;
+}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 56e1151..c713692 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1586,6 +1586,15 @@
sde_enc->cur_master->hw_mdptop,
sde_kms->catalog);
+ if (sde_enc->num_phys_encs > ARRAY_SIZE(te_cfg.ppnumber) ||
+ sde_enc->num_phys_encs > ARRAY_SIZE(sde_enc->hw_pp)) {
+ SDE_ERROR("invalid num phys enc %d/%d/%d\n",
+ sde_enc->num_phys_encs,
+ (int) ARRAY_SIZE(te_cfg.ppnumber),
+ (int) ARRAY_SIZE(sde_enc->hw_pp));
+ return;
+ }
+
if (hw_mdptop->ops.setup_vsync_sel) {
for (i = 0; i < sde_enc->num_phys_encs; i++)
te_cfg.ppnumber[i] = sde_enc->hw_pp[i]->idx;
@@ -1709,15 +1718,15 @@
}
}
+ if (sde_enc->cur_master && sde_enc->cur_master->ops.disable)
+ sde_enc->cur_master->ops.disable(sde_enc->cur_master);
+
/* after phys waits for frame-done, should be no more frames pending */
if (atomic_xchg(&sde_enc->frame_done_timeout, 0)) {
SDE_ERROR("enc%d timeout pending\n", drm_enc->base.id);
del_timer_sync(&sde_enc->frame_done_timer);
}
- if (sde_enc->cur_master && sde_enc->cur_master->ops.disable)
- sde_enc->cur_master->ops.disable(sde_enc->cur_master);
-
sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_STOP);
if (sde_enc->cur_master) {
@@ -2017,7 +2026,8 @@
if (rc) {
SDE_ERROR_ENC(sde_enc,
"connector soft reset failure\n");
- SDE_DBG_DUMP("panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus",
+ "panic");
}
}
}
@@ -2025,7 +2035,7 @@
rc = ctl->ops.reset(ctl);
if (rc) {
SDE_ERROR_ENC(sde_enc, "ctl %d reset failure\n", ctl->idx);
- SDE_DBG_DUMP("panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
}
phys_enc->enable_state = SDE_ENC_ENABLED;
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
index 6ee1aae..da85257 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -161,7 +161,7 @@
unsigned long lock_flags;
int new_cnt;
- if (!phys_enc)
+ if (!phys_enc || !phys_enc->hw_pp)
return;
/* notify all synchronous clients first, then asynchronous clients */
@@ -207,7 +207,7 @@
{
struct sde_encoder_phys *phys_enc = arg;
- if (!phys_enc)
+ if (!phys_enc || !phys_enc->hw_pp)
return;
SDE_EVT32_IRQ(DRMID(phys_enc->parent),
@@ -359,9 +359,7 @@
SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL);
sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
- SDE_DBG_DUMP("sde", "dsi0_ctrl", "dsi0_phy", "dsi1_ctrl",
- "dsi1_phy", "vbif", "dbg_bus",
- "vbif_dbg_bus", "panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
}
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
@@ -418,9 +416,7 @@
phys_enc->hw_pp->idx - PINGPONG_0,
timeout_us,
ret);
- SDE_DBG_DUMP("sde", "dsi0_ctrl", "dsi0_phy", "dsi1_ctrl",
- "dsi1_phy", "vbif_rt", "dbg_bus",
- "vbif_dbg_bus", "panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
}
return ret;
@@ -607,7 +603,7 @@
struct sde_encoder_phys_cmd *cmd_enc =
to_sde_encoder_phys_cmd(phys_enc);
struct sde_hw_tear_check tc_cfg = { 0 };
- struct drm_display_mode *mode = &phys_enc->cached_mode;
+ struct drm_display_mode *mode;
bool tc_enable = true;
u32 vsync_hz;
struct msm_drm_private *priv;
@@ -617,6 +613,7 @@
SDE_ERROR("invalid encoder\n");
return;
}
+ mode = &phys_enc->cached_mode;
SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
@@ -627,7 +624,12 @@
}
sde_kms = phys_enc->sde_kms;
+ if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev_private) {
+ SDE_ERROR("invalid device\n");
+ return;
+ }
priv = sde_kms->dev->dev_private;
+
/*
* TE default: dsi byte clock calculated base on 70 fps;
* around 14 ms to complete a kickoff cycle if te disabled;
@@ -638,8 +640,10 @@
* frequency divided by the no. of rows (lines) in the LCDpanel.
*/
vsync_hz = sde_power_clk_get_rate(&priv->phandle, "vsync_clk");
- if (!vsync_hz) {
- SDE_DEBUG_CMDENC(cmd_enc, "invalid vsync clock rate\n");
+ if (!vsync_hz || !mode->vtotal || !mode->vrefresh) {
+ SDE_DEBUG_CMDENC(cmd_enc,
+ "invalid params - vsync_hz %u vtot %u vrefresh %u\n",
+ vsync_hz, mode->vtotal, mode->vrefresh);
return;
}
@@ -687,8 +691,8 @@
struct sde_encoder_phys_cmd *cmd_enc =
to_sde_encoder_phys_cmd(phys_enc);
- if (!phys_enc || !phys_enc->hw_ctl ||
- !phys_enc->hw_ctl->ops.setup_intf_cfg) {
+ if (!phys_enc || !phys_enc->hw_ctl || !phys_enc->hw_pp
+ || !phys_enc->hw_ctl->ops.setup_intf_cfg) {
SDE_ERROR("invalid arg(s), enc %d\n", phys_enc != 0);
return;
}
@@ -717,7 +721,7 @@
struct sde_hw_ctl *ctl;
u32 flush_mask = 0;
- if (!phys_enc || !phys_enc->hw_ctl) {
+ if (!phys_enc || !phys_enc->hw_ctl || !phys_enc->hw_pp) {
SDE_ERROR("invalid arg(s), encoder %d\n", phys_enc != 0);
return;
}
@@ -747,10 +751,11 @@
struct sde_encoder_phys_cmd *cmd_enc =
to_sde_encoder_phys_cmd(phys_enc);
- if (!phys_enc) {
+ if (!phys_enc || !phys_enc->hw_pp) {
SDE_ERROR("invalid phys encoder\n");
return;
}
+
SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
if (phys_enc->enable_state == SDE_ENC_ENABLED) {
@@ -803,7 +808,7 @@
to_sde_encoder_phys_cmd(phys_enc);
int ret;
- if (!phys_enc) {
+ if (!phys_enc || !phys_enc->hw_pp) {
SDE_ERROR("invalid encoder\n");
return;
}
@@ -857,6 +862,12 @@
SDE_ERROR("invalid encoder\n");
return;
}
+
+ if ((phys_enc->intf_idx - INTF_0) >= INTF_MAX) {
+ SDE_ERROR("invalid intf idx:%d\n", phys_enc->intf_idx);
+ return;
+ }
+
SDE_DEBUG_CMDENC(cmd_enc, "\n");
hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD;
}
@@ -869,7 +880,7 @@
to_sde_encoder_phys_cmd(phys_enc);
int ret;
- if (!phys_enc) {
+ if (!phys_enc || !phys_enc->hw_pp) {
SDE_ERROR("invalid encoder\n");
return;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index afd61ae..e34f46e 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -49,6 +49,23 @@
struct intf_timing_params *timing)
{
memset(timing, 0, sizeof(*timing));
+
+ if ((mode->htotal < mode->hsync_end)
+ || (mode->hsync_start < mode->hdisplay)
+ || (mode->vtotal < mode->vsync_end)
+ || (mode->vsync_start < mode->vdisplay)
+ || (mode->hsync_end < mode->hsync_start)
+ || (mode->vsync_end < mode->vsync_start)) {
+ SDE_ERROR(
+ "invalid params - hstart:%d,hend:%d,htot:%d,hdisplay:%d\n",
+ mode->hsync_start, mode->hsync_end,
+ mode->htotal, mode->hdisplay);
+ SDE_ERROR("vstart:%d,vend:%d,vtot:%d,vdisplay:%d\n",
+ mode->vsync_start, mode->vsync_end,
+ mode->vtotal, mode->vdisplay);
+ return;
+ }
+
/*
* https://www.kernel.org/doc/htmldocs/drm/ch02s05.html
* Active Region Front Porch Sync Back Porch
@@ -139,6 +156,15 @@
u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines;
u32 actual_vfp_lines = 0;
+ if (worst_case_needed_lines < start_of_frame_lines) {
+ needed_vfp_lines = 0;
+ SDE_ERROR("invalid params - needed_lines:%d, frame_lines:%d\n",
+ worst_case_needed_lines, start_of_frame_lines);
+ } else {
+ needed_vfp_lines = worst_case_needed_lines
+ - start_of_frame_lines;
+ }
+
/* Fetch must be outside active lines, otherwise undefined. */
if (start_of_frame_lines >= worst_case_needed_lines) {
SDE_DEBUG_VIDENC(vid_enc,
@@ -442,15 +468,18 @@
struct sde_encoder_phys_vid *vid_enc;
if (!phys_enc || !phys_enc->sde_kms) {
- SDE_ERROR("invalid encoder\n");
+ SDE_ERROR("invalid encoder/kms\n");
return;
}
rm = &phys_enc->sde_kms->rm;
vid_enc = to_sde_encoder_phys_vid(phys_enc);
- phys_enc->cached_mode = *adj_mode;
- SDE_DEBUG_VIDENC(vid_enc, "caching mode:\n");
- drm_mode_debug_printmodeline(adj_mode);
+
+ if (adj_mode) {
+ phys_enc->cached_mode = *adj_mode;
+ drm_mode_debug_printmodeline(adj_mode);
+ SDE_DEBUG_VIDENC(vid_enc, "caching mode:\n");
+ }
instance = phys_enc->split_role == ENC_ROLE_SLAVE ? 1 : 0;
@@ -620,13 +649,18 @@
static int sde_encoder_phys_vid_wait_for_vblank(
struct sde_encoder_phys *phys_enc, bool notify)
{
- struct sde_encoder_wait_info wait_info = {
- .wq = &phys_enc->pending_kickoff_wq,
- .atomic_cnt = &phys_enc->pending_kickoff_cnt,
- .timeout_ms = KICKOFF_TIMEOUT_MS,
- };
+ struct sde_encoder_wait_info wait_info;
int ret;
+ if (!phys_enc) {
+ pr_err("invalid encoder\n");
+ return -EINVAL;
+ }
+
+ wait_info.wq = &phys_enc->pending_kickoff_wq;
+ wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
+ wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
if (!sde_encoder_phys_vid_is_master(phys_enc)) {
/* signal done for slave video encoder, unless it is pp-split */
if (!_sde_encoder_phys_is_ppsplit(phys_enc) &&
@@ -654,11 +688,7 @@
static int sde_encoder_phys_vid_wait_for_commit_done(
struct sde_encoder_phys *phys_enc)
{
- int ret;
-
- ret = sde_encoder_phys_vid_wait_for_vblank(phys_enc, true);
-
- return ret;
+ return sde_encoder_phys_vid_wait_for_vblank(phys_enc, true);
}
static void sde_encoder_phys_vid_prepare_for_kickoff(
@@ -688,7 +718,7 @@
SDE_ERROR_VIDENC(vid_enc, "ctl %d reset failure: %d\n",
ctl->idx, rc);
sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC);
- SDE_DBG_DUMP("panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
}
programmable_rot_fetch_config(phys_enc, params->inline_rotate_prefill);
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index 305d45e..b1772ed 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -230,6 +230,12 @@
};
enum {
+ DSPP_TOP_OFF,
+ DSPP_TOP_SIZE,
+ DSPP_TOP_PROP_MAX,
+};
+
+enum {
DSPP_OFF,
DSPP_SIZE,
DSPP_BLOCKS,
@@ -463,6 +469,11 @@
{MIXER_GC_PROP, "qcom,sde-mixer-gc", false, PROP_TYPE_U32_ARRAY},
};
+static struct sde_prop_type dspp_top_prop[] = {
+ {DSPP_TOP_OFF, "qcom,sde-dspp-top-off", true, PROP_TYPE_U32},
+ {DSPP_TOP_SIZE, "qcom,sde-dspp-top-size", false, PROP_TYPE_U32},
+};
+
static struct sde_prop_type dspp_prop[] = {
{DSPP_OFF, "qcom,sde-dspp-off", true, PROP_TYPE_U32_ARRAY},
{DSPP_SIZE, "qcom,sde-dspp-size", false, PROP_TYPE_U32},
@@ -1859,6 +1870,54 @@
return rc;
}
+static int sde_dspp_top_parse_dt(struct device_node *np,
+ struct sde_mdss_cfg *sde_cfg)
+{
+ int rc, prop_count[DSPP_TOP_PROP_MAX];
+ bool prop_exists[DSPP_TOP_PROP_MAX];
+ struct sde_prop_value *prop_value = NULL;
+ u32 off_count;
+
+ if (!sde_cfg) {
+ SDE_ERROR("invalid argument\n");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ prop_value = kzalloc(DSPP_TOP_PROP_MAX *
+ sizeof(struct sde_prop_value), GFP_KERNEL);
+ if (!prop_value) {
+ rc = -ENOMEM;
+ goto end;
+ }
+
+ rc = _validate_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
+ prop_count, &off_count);
+ if (rc)
+ goto end;
+
+ rc = _read_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
+ prop_count, prop_exists, prop_value);
+ if (rc)
+ goto end;
+
+ if (off_count != 1) {
+ SDE_ERROR("invalid dspp_top off_count:%d\n", off_count);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ sde_cfg->dspp_top.base =
+ PROP_VALUE_ACCESS(prop_value, DSPP_TOP_OFF, 0);
+ sde_cfg->dspp_top.len =
+ PROP_VALUE_ACCESS(prop_value, DSPP_TOP_SIZE, 0);
+ snprintf(sde_cfg->dspp_top.name, SDE_HW_BLK_NAME_LEN, "dspp_top");
+
+end:
+ kfree(prop_value);
+ return rc;
+}
+
static int sde_dspp_parse_dt(struct device_node *np,
struct sde_mdss_cfg *sde_cfg)
{
@@ -2992,6 +3051,10 @@
if (rc)
goto end;
+ rc = sde_dspp_top_parse_dt(np, sde_cfg);
+ if (rc)
+ goto end;
+
rc = sde_dspp_parse_dt(np, sde_cfg);
if (rc)
goto end;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
index 29698bc..db5a6b4 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h
@@ -568,6 +568,17 @@
};
/**
+ * struct sde_dspp_cfg - information of DSPP top block
+ * @id enum identifying this block
+ * @base register offset of this block
+ * @features bit mask identifying sub-blocks/features
+ * supported by this block
+ */
+struct sde_dspp_top_cfg {
+ SDE_HW_BLK_INFO;
+};
+
+/**
* struct sde_dspp_cfg - information of DSPP blocks
* @id enum identifying this block
* @base register offset of this block
@@ -891,6 +902,8 @@
u32 mixer_count;
struct sde_lm_cfg mixer[MAX_BLOCKS];
+ struct sde_dspp_top_cfg dspp_top;
+
u32 dspp_count;
struct sde_dspp_cfg dspp[MAX_BLOCKS];
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_common_v4.h b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_common_v4.h
index 8f7764d..5cbfe8e 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_common_v4.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_common_v4.h
@@ -37,4 +37,33 @@
#define GC_TBL_NUM 3
#define GC_LUT_SWAP_OFF 0x1c
+#define IGC_TBL_NUM 3
+#define IGC_DITHER_OFF 0x7e0
+#define IGC_OPMODE_OFF 0x0
+#define IGC_C0_OFF 0x0
+#define IGC_DATA_MASK (BIT(12) - 1)
+#define IGC_DSPP_SEL_MASK_MAX (BIT(4) - 1)
+#define IGC_DSPP_SEL_MASK(n) \
+ ((IGC_DSPP_SEL_MASK_MAX & ~(1 << (n))) << 28)
+#define IGC_INDEX_UPDATE BIT(25)
+#define IGC_EN BIT(0)
+#define IGC_DIS 0
+#define IGC_DITHER_DATA_MASK (BIT(4) - 1)
+
+#define PCC_NUM_PLANES 3
+#define PCC_NUM_COEFF 11
+#define PCC_EN BIT(0)
+#define PCC_DIS 0
+#define PCC_C_OFF 0x4
+#define PCC_R_OFF 0x10
+#define PCC_G_OFF 0x1c
+#define PCC_B_OFF 0x28
+#define PCC_RG_OFF 0x34
+#define PCC_RB_OFF 0x40
+#define PCC_GB_OFF 0x4c
+#define PCC_RGB_OFF 0x58
+#define PCC_RR_OFF 0x64
+#define PCC_GG_OFF 0x70
+#define PCC_BB_OFF 0x7c
+
#endif /* _SDE_HW_COLOR_PROC_COMMON_V4_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.c b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.c
index 42d1480..4da0456 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.c
@@ -109,3 +109,127 @@
&op_mode);
}
+
+void sde_setup_dspp_igcv3(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct drm_msm_igc_lut *lut_cfg;
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ int i = 0, j = 0;
+ u32 *addr = NULL;
+ u32 offset = 0;
+
+ if (!ctx || !cfg) {
+ DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
+ return;
+ }
+
+ if (!hw_cfg->payload) {
+ DRM_DEBUG_DRIVER("disable igc feature\n");
+ SDE_REG_WRITE(&ctx->hw, IGC_OPMODE_OFF, 0);
+ return;
+ }
+
+ if (hw_cfg->len != sizeof(struct drm_msm_igc_lut)) {
+ DRM_ERROR("invalid size of payload len %d exp %zd\n",
+ hw_cfg->len, sizeof(struct drm_msm_igc_lut));
+ return;
+ }
+
+ lut_cfg = hw_cfg->payload;
+
+ for (i = 0; i < IGC_TBL_NUM; i++) {
+ addr = lut_cfg->c0 + (i * ARRAY_SIZE(lut_cfg->c0));
+ offset = IGC_C0_OFF + (i * sizeof(u32));
+
+ for (j = 0; j < IGC_TBL_LEN; j++) {
+ addr[j] &= IGC_DATA_MASK;
+ addr[j] |= IGC_DSPP_SEL_MASK(ctx->idx - 1);
+ if (j == 0)
+ addr[j] |= IGC_INDEX_UPDATE;
+ /* IGC lut registers are part of DSPP Top HW block */
+ SDE_REG_WRITE(&ctx->hw_top, offset, addr[j]);
+ }
+ }
+
+ if (lut_cfg->flags & IGC_DITHER_ENABLE) {
+ SDE_REG_WRITE(&ctx->hw, IGC_DITHER_OFF,
+ lut_cfg->strength & IGC_DITHER_DATA_MASK);
+ }
+
+ SDE_REG_WRITE(&ctx->hw, IGC_OPMODE_OFF, IGC_EN);
+}
+
+void sde_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ struct drm_msm_pcc *pcc_cfg;
+ struct drm_msm_pcc_coeff *coeffs = NULL;
+ int i = 0;
+ u32 base = 0;
+
+ if (!ctx || !cfg) {
+ DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
+ return;
+ }
+
+ if (!hw_cfg->payload) {
+ DRM_DEBUG_DRIVER("disable pcc feature\n");
+ SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->pcc.base, 0);
+ return;
+ }
+
+ if (hw_cfg->len != sizeof(struct drm_msm_pcc)) {
+ DRM_ERROR("invalid size of payload len %d exp %zd\n",
+ hw_cfg->len, sizeof(struct drm_msm_pcc));
+ return;
+ }
+
+ pcc_cfg = hw_cfg->payload;
+
+ for (i = 0; i < PCC_NUM_PLANES; i++) {
+ base = ctx->cap->sblk->pcc.base + (i * sizeof(u32));
+ switch (i) {
+ case 0:
+ coeffs = &pcc_cfg->r;
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_RR_OFF, pcc_cfg->r_rr);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_GG_OFF, pcc_cfg->r_gg);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_BB_OFF, pcc_cfg->r_bb);
+ break;
+ case 1:
+ coeffs = &pcc_cfg->g;
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_RR_OFF, pcc_cfg->g_rr);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_GG_OFF, pcc_cfg->g_gg);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_BB_OFF, pcc_cfg->g_bb);
+ break;
+ case 2:
+ coeffs = &pcc_cfg->b;
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_RR_OFF, pcc_cfg->b_rr);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_GG_OFF, pcc_cfg->b_gg);
+ SDE_REG_WRITE(&ctx->hw,
+ base + PCC_BB_OFF, pcc_cfg->b_bb);
+ break;
+ default:
+ DRM_ERROR("invalid pcc plane: %d\n", i);
+ return;
+ }
+
+ SDE_REG_WRITE(&ctx->hw, base + PCC_C_OFF, coeffs->c);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_R_OFF, coeffs->r);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_G_OFF, coeffs->g);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_B_OFF, coeffs->b);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_RG_OFF, coeffs->rg);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_RB_OFF, coeffs->rb);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_GB_OFF, coeffs->gb);
+ SDE_REG_WRITE(&ctx->hw, base + PCC_RGB_OFF, coeffs->rgb);
+ }
+
+ SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->pcc.base, PCC_EN);
+}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.h b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.h
index 250830e..ad4f556 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_color_proc_v4.h
@@ -22,5 +22,19 @@
* @cfg: pointer to sde_hw_cp_cfg
*/
void sde_setup_dspp_3d_gamutv4(struct sde_hw_dspp *ctx, void *cfg);
+/**
+ * sde_setup_dspp_igcv3 - Function for igc v3 version feature
+ * programming.
+ * @ctx: dspp ctx pointer
+ * @cfg: pointer to sde_hw_cp_cfg
+ */
+void sde_setup_dspp_igcv3(struct sde_hw_dspp *ctx, void *cfg);
+/**
+ * sde_setup_dspp_pccv4 - Function for pcc v4 version feature
+ * programming.
+ * @ctx: dspp ctx pointer
+ * @cfg: pointer to sde_hw_cp_cfg
+ */
+void sde_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg);
#endif /* _SDE_HW_COLOR_PROC_V4_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_dspp.c b/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
index e766cdb..5b3f51e 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
@@ -58,6 +58,16 @@
if (c->cap->sblk->pcc.version ==
(SDE_COLOR_PROCESS_VER(0x1, 0x7)))
c->ops.setup_pcc = sde_setup_dspp_pcc_v1_7;
+ else if (c->cap->sblk->pcc.version ==
+ (SDE_COLOR_PROCESS_VER(0x4, 0x0))) {
+ ret = reg_dmav1_init_dspp_op_v4(i, c->idx);
+ if (!ret)
+ c->ops.setup_pcc =
+ reg_dmav1_setup_dspp_pccv4;
+ else
+ c->ops.setup_pcc =
+ sde_setup_dspp_pccv4;
+ }
break;
case SDE_DSPP_HSIC:
if (c->cap->sblk->hsic.version ==
@@ -104,6 +114,18 @@
sde_setup_dspp_gc_v1_7;
}
break;
+ case SDE_DSPP_IGC:
+ if (c->cap->sblk->igc.version ==
+ SDE_COLOR_PROCESS_VER(0x3, 0x1)) {
+ ret = reg_dmav1_init_dspp_op_v4(i, c->idx);
+ if (!ret)
+ c->ops.setup_igc =
+ reg_dmav1_setup_dspp_igcv31;
+ else
+ c->ops.setup_igc =
+ sde_setup_dspp_igcv3;
+ }
+ break;
case SDE_DSPP_AD:
if (c->cap->sblk->ad.version ==
SDE_COLOR_PROCESS_VER(4, 0)) {
@@ -145,6 +167,13 @@
return ERR_PTR(-EINVAL);
}
+ /* Populate DSPP Top HW block */
+ c->hw_top.base_off = addr;
+ c->hw_top.blk_off = m->dspp_top.base;
+ c->hw_top.length = m->dspp_top.len;
+ c->hw_top.hwversion = m->hwversion;
+ c->hw_top.log_mask = SDE_DBG_MASK_DSPP;
+
/* Assign ops */
c->idx = idx;
c->cap = cfg;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_dspp.h b/drivers/gpu/drm/msm/sde/sde_hw_dspp.h
index 0baa970..44b3831 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_dspp.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_dspp.h
@@ -170,13 +170,17 @@
* struct sde_hw_dspp - dspp description
* @base: Hardware block base structure
* @hw: Block hardware details
+ * @hw_top: Block hardware top details
* @idx: DSPP index
* @cap: Pointer to layer_cfg
* @ops: Pointer to operations possible for this DSPP
*/
struct sde_hw_dspp {
struct sde_hw_blk base;
- struct sde_hw_blk_reg_map hw;
+ struct sde_hw_blk_reg_map hw;
+
+ /* dspp top */
+ struct sde_hw_blk_reg_map hw_top;
/* dspp */
enum sde_dspp idx;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c
index 4140a12..9a5035a 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1.c
@@ -90,6 +90,8 @@
[GAMUT] = GRP_VIG_HW_BLK_SELECT | GRP_DSPP_HW_BLK_SELECT,
[VLUT] = GRP_DSPP_HW_BLK_SELECT,
[GC] = GRP_DSPP_HW_BLK_SELECT,
+ [IGC] = DSPP_IGC | GRP_DSPP_HW_BLK_SELECT,
+ [PCC] = GRP_DSPP_HW_BLK_SELECT,
};
static int validate_dma_cfg(struct sde_reg_dma_setup_ops_cfg *cfg);
@@ -182,7 +184,7 @@
loc = (u8 *)cfg->dma_buf->vaddr + cfg->dma_buf->index;
memcpy(loc, cfg->data, cfg->data_size);
cfg->dma_buf->index += cfg->data_size;
- cfg->dma_buf->next_op_allowed = REG_WRITE_OP;
+ cfg->dma_buf->next_op_allowed = REG_WRITE_OP | DECODE_SEL_OP;
cfg->dma_buf->ops_completed |= REG_WRITE_OP;
return 0;
@@ -244,7 +246,7 @@
loc[1] = *cfg->data;
cfg->dma_buf->index += ops_mem_size[cfg->ops];
cfg->dma_buf->ops_completed |= REG_WRITE_OP;
- cfg->dma_buf->next_op_allowed = REG_WRITE_OP;
+ cfg->dma_buf->next_op_allowed = REG_WRITE_OP | DECODE_SEL_OP;
return 0;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
index 285ef11..70427ab 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
@@ -30,6 +30,14 @@
#define GC_LUT_MEM_SIZE ((sizeof(struct drm_msm_pgc_lut)) + \
REG_DMA_HEADERS_BUFFER_SZ)
+#define IGC_LUT_MEM_SIZE ((sizeof(struct drm_msm_igc_lut)) + \
+ REG_DMA_HEADERS_BUFFER_SZ)
+
+#define PCC_LUT_ENTRIES (PCC_NUM_PLANES * PCC_NUM_COEFF)
+#define PCC_LEN (PCC_LUT_ENTRIES * sizeof(u32))
+#define PCC_MEM_SIZE (PCC_LEN + \
+ REG_DMA_HEADERS_BUFFER_SZ)
+
#define REG_MASK(n) ((BIT(n)) - 1)
static struct sde_reg_dma_buffer *dspp_buf[REG_DMA_FEATURES_MAX][DSPP_MAX];
@@ -37,8 +45,8 @@
static u32 feature_map[SDE_DSPP_MAX] = {
[SDE_DSPP_VLUT] = VLUT,
[SDE_DSPP_GAMUT] = GAMUT,
- [SDE_DSPP_IGC] = REG_DMA_FEATURES_MAX,
- [SDE_DSPP_PCC] = REG_DMA_FEATURES_MAX,
+ [SDE_DSPP_IGC] = IGC,
+ [SDE_DSPP_PCC] = PCC,
[SDE_DSPP_GC] = GC,
[SDE_DSPP_HSIC] = REG_DMA_FEATURES_MAX,
[SDE_DSPP_MEMCOLOR] = REG_DMA_FEATURES_MAX,
@@ -52,6 +60,8 @@
[SDE_DSPP_VLUT] = VLUT_MEM_SIZE,
[SDE_DSPP_GAMUT] = GAMUT_LUT_MEM_SIZE,
[SDE_DSPP_GC] = GC_LUT_MEM_SIZE,
+ [SDE_DSPP_IGC] = IGC_LUT_MEM_SIZE,
+ [SDE_DSPP_PCC] = PCC_MEM_SIZE,
};
static u32 dspp_mapping[DSPP_MAX] = {
@@ -233,6 +243,7 @@
int rc = -ENOTSUPP;
struct sde_hw_reg_dma_ops *dma_ops;
bool is_supported = false;
+ u32 blk;
if (feature >= SDE_DSPP_MAX || idx >= DSPP_MAX) {
DRM_ERROR("invalid feature %x max %x dspp idx %x max %xd\n",
@@ -250,8 +261,8 @@
if (IS_ERR_OR_NULL(dma_ops))
return -ENOTSUPP;
- rc = dma_ops->check_support(feature_map[feature], dspp_mapping[idx],
- &is_supported);
+ blk = (feature_map[feature] == IGC) ? DSPP_IGC : dspp_mapping[idx];
+ rc = dma_ops->check_support(feature_map[feature], blk, &is_supported);
if (!rc)
rc = (is_supported) ? 0 : -ENOTSUPP;
@@ -379,7 +390,7 @@
{
struct sde_reg_dma_kickoff_cfg kick_off;
struct sde_hw_cp_cfg *hw_cfg = cfg;
- u32 op_mode;
+ u32 op_mode = 0;
struct sde_hw_reg_dma_ops *dma_ops;
struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
int rc;
@@ -519,7 +530,7 @@
int rc, i = 0;
u32 reg;
- rc = reg_dma_dspp_check(ctx, cfg, GAMUT);
+ rc = reg_dma_dspp_check(ctx, cfg, GC);
if (rc)
return;
@@ -603,6 +614,298 @@
}
}
+static void _dspp_igcv31_off(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct sde_reg_dma_kickoff_cfg kick_off;
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ struct sde_hw_reg_dma_ops *dma_ops;
+ struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
+ int rc;
+ u32 reg;
+
+ dma_ops = sde_reg_dma_get_ops();
+ dma_ops->reset_reg_dma_buf(dspp_buf[IGC][ctx->idx]);
+
+ REG_DMA_INIT_OPS(dma_write_cfg, dspp_mapping[ctx->idx], IGC,
+ dspp_buf[IGC][ctx->idx]);
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write decode select failed ret %d\n", rc);
+ return;
+ }
+
+ reg = IGC_DIS;
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->igc.base + IGC_OPMODE_OFF,
+ ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("setting opcode failed ret %d\n", rc);
+ return;
+ }
+
+ REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl, dspp_buf[IGC][ctx->idx],
+ REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
+ rc = dma_ops->kick_off(&kick_off);
+ if (rc)
+ DRM_ERROR("failed to kick off ret %d\n", rc);
+}
+
+void reg_dmav1_setup_dspp_igcv31(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct drm_msm_igc_lut *lut_cfg;
+ struct sde_hw_reg_dma_ops *dma_ops;
+ struct sde_reg_dma_kickoff_cfg kick_off;
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
+ int rc, i = 0, j = 0;
+ u32 *addr = NULL;
+ u32 offset = 0;
+ u32 reg;
+
+ rc = reg_dma_dspp_check(ctx, cfg, IGC);
+ if (rc)
+ return;
+
+ if (!hw_cfg->payload) {
+ DRM_DEBUG_DRIVER("disable igc feature\n");
+ _dspp_igcv31_off(ctx, cfg);
+ return;
+ }
+
+ if (hw_cfg->len != sizeof(struct drm_msm_igc_lut)) {
+ DRM_ERROR("invalid size of payload len %d exp %zd\n",
+ hw_cfg->len, sizeof(struct drm_msm_igc_lut));
+ return;
+ }
+
+ lut_cfg = hw_cfg->payload;
+
+ dma_ops = sde_reg_dma_get_ops();
+ dma_ops->reset_reg_dma_buf(dspp_buf[IGC][ctx->idx]);
+
+ REG_DMA_INIT_OPS(dma_write_cfg, DSPP_IGC, IGC, dspp_buf[IGC][ctx->idx]);
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write decode select failed ret %d\n", rc);
+ return;
+ }
+
+ for (i = 0; i < IGC_TBL_NUM; i++) {
+ addr = lut_cfg->c0 + (i * ARRAY_SIZE(lut_cfg->c0));
+ offset = IGC_C0_OFF + (i * sizeof(u32));
+
+ for (j = 0; j < IGC_TBL_LEN; j++) {
+ addr[j] &= IGC_DATA_MASK;
+ addr[j] |= IGC_DSPP_SEL_MASK(ctx->idx - 1);
+ if (j == 0)
+ addr[j] |= IGC_INDEX_UPDATE;
+ }
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, offset, addr,
+ IGC_TBL_LEN * sizeof(u32),
+ REG_BLK_WRITE_INC, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("lut write failed ret %d\n", rc);
+ return;
+ }
+ }
+
+ REG_DMA_INIT_OPS(dma_write_cfg, dspp_mapping[ctx->idx], IGC,
+ dspp_buf[IGC][ctx->idx]);
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write decode select failed ret %d\n", rc);
+ return;
+ }
+
+ if (lut_cfg->flags & IGC_DITHER_ENABLE) {
+ reg = lut_cfg->strength & IGC_DITHER_DATA_MASK;
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->igc.base + IGC_DITHER_OFF,
+ ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("dither strength failed ret %d\n", rc);
+ return;
+ }
+ }
+
+ reg = IGC_EN;
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->igc.base + IGC_OPMODE_OFF,
+ ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("setting opcode failed ret %d\n", rc);
+ return;
+ }
+
+ REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl, dspp_buf[IGC][ctx->idx],
+ REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
+ rc = dma_ops->kick_off(&kick_off);
+ if (rc)
+ DRM_ERROR("failed to kick off ret %d\n", rc);
+}
+
+static void _dspp_pccv4_off(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct sde_reg_dma_kickoff_cfg kick_off;
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ struct sde_hw_reg_dma_ops *dma_ops;
+ struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
+ int rc;
+ u32 reg;
+
+ dma_ops = sde_reg_dma_get_ops();
+ dma_ops->reset_reg_dma_buf(dspp_buf[PCC][ctx->idx]);
+
+ REG_DMA_INIT_OPS(dma_write_cfg, dspp_mapping[ctx->idx], PCC,
+ dspp_buf[PCC][ctx->idx]);
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write decode select failed ret %d\n", rc);
+ return;
+ }
+
+ reg = PCC_DIS;
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->pcc.base,
+ ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("setting opcode failed ret %d\n", rc);
+ return;
+ }
+
+ REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl, dspp_buf[PCC][ctx->idx],
+ REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
+ rc = dma_ops->kick_off(&kick_off);
+ if (rc)
+ DRM_ERROR("failed to kick off ret %d\n", rc);
+}
+
+void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg)
+{
+ struct sde_hw_reg_dma_ops *dma_ops;
+ struct sde_reg_dma_kickoff_cfg kick_off;
+ struct sde_hw_cp_cfg *hw_cfg = cfg;
+ struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
+ struct drm_msm_pcc *pcc_cfg;
+ struct drm_msm_pcc_coeff *coeffs = NULL;
+ u32 *data = NULL;
+ int rc, i = 0;
+ u32 reg = 0;
+
+ rc = reg_dma_dspp_check(ctx, cfg, PCC);
+ if (rc)
+ return;
+
+ if (!hw_cfg->payload) {
+ DRM_DEBUG_DRIVER("disable pcc feature\n");
+ _dspp_pccv4_off(ctx, cfg);
+ return;
+ }
+
+ if (hw_cfg->len != sizeof(struct drm_msm_pcc)) {
+ DRM_ERROR("invalid size of payload len %d exp %zd\n",
+ hw_cfg->len, sizeof(struct drm_msm_pcc));
+ return;
+ }
+
+ pcc_cfg = hw_cfg->payload;
+
+ dma_ops = sde_reg_dma_get_ops();
+ dma_ops->reset_reg_dma_buf(dspp_buf[PCC][ctx->idx]);
+
+ REG_DMA_INIT_OPS(dma_write_cfg, dspp_mapping[ctx->idx],
+ PCC, dspp_buf[PCC][ctx->idx]);
+
+ REG_DMA_SETUP_OPS(dma_write_cfg, 0, NULL, 0, HW_BLK_SELECT, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write decode select failed ret %d\n", rc);
+ return;
+ }
+
+ data = kzalloc(PCC_LEN, GFP_KERNEL);
+ if (!data)
+ return;
+
+ for (i = 0; i < PCC_NUM_PLANES; i++) {
+ switch (i) {
+ case 0:
+ coeffs = &pcc_cfg->r;
+ data[i + 24] = pcc_cfg->r_rr;
+ data[i + 27] = pcc_cfg->r_gg;
+ data[i + 30] = pcc_cfg->r_bb;
+ break;
+ case 1:
+ coeffs = &pcc_cfg->g;
+ data[i + 24] = pcc_cfg->g_rr;
+ data[i + 27] = pcc_cfg->g_gg;
+ data[i + 30] = pcc_cfg->g_bb;
+ break;
+ case 2:
+ coeffs = &pcc_cfg->b;
+ data[i + 24] = pcc_cfg->b_rr;
+ data[i + 27] = pcc_cfg->b_gg;
+ data[i + 30] = pcc_cfg->b_bb;
+ break;
+ default:
+ DRM_ERROR("invalid pcc plane: %d\n", i);
+ goto exit;
+ }
+
+ data[i] = coeffs->c;
+ data[i + 3] = coeffs->r;
+ data[i + 6] = coeffs->g;
+ data[i + 9] = coeffs->b;
+ data[i + 12] = coeffs->rg;
+ data[i + 15] = coeffs->rb;
+ data[i + 18] = coeffs->gb;
+ data[i + 21] = coeffs->rgb;
+ }
+
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->pcc.base + PCC_C_OFF,
+ data, PCC_LEN,
+ REG_BLK_WRITE_SINGLE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("write pcc lut failed ret %d\n", rc);
+ goto exit;
+ }
+
+ reg = PCC_EN;
+ REG_DMA_SETUP_OPS(dma_write_cfg,
+ ctx->cap->sblk->pcc.base,
+ ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0);
+ rc = dma_ops->setup_payload(&dma_write_cfg);
+ if (rc) {
+ DRM_ERROR("setting opcode failed ret %d\n", rc);
+ goto exit;
+ }
+
+ REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl, dspp_buf[PCC][ctx->idx],
+ REG_DMA_WRITE, DMA_CTL_QUEUE0, WRITE_IMMEDIATE);
+ rc = dma_ops->kick_off(&kick_off);
+ if (rc)
+ DRM_ERROR("failed to kick off ret %d\n", rc);
+
+exit:
+ kfree(data);
+}
+
int reg_dmav1_deinit_dspp_ops(enum sde_dspp idx)
{
int i;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
index 94e1a5c..bb72c8f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
@@ -46,13 +46,27 @@
void reg_dmav1_setup_dspp_3d_gamutv4(struct sde_hw_dspp *ctx, void *cfg);
/**
- * reg_dmav1_setup_dspp_gc_v18() - gc v18 implementation using reg dma v1.
+ * reg_dmav1_setup_dspp_gcv18() - gc v18 implementation using reg dma v1.
* @ctx: dspp ctx info
* @cfg: pointer to struct sde_hw_cp_cfg
*/
void reg_dmav1_setup_dspp_gcv18(struct sde_hw_dspp *ctx, void *cfg);
/**
+ * reg_dmav1_setup_dspp_igcv31() - igc v31 implementation using reg dma v1.
+ * @ctx: dspp ctx info
+ * @cfg: pointer to struct sde_hw_cp_cfg
+ */
+void reg_dmav1_setup_dspp_igcv31(struct sde_hw_dspp *ctx, void *cfg);
+
+/**
+ * reg_dmav1_setup_dspp_pccv4() - pcc v4 implementation using reg dma v1.
+ * @ctx: dspp ctx info
+ * @cfg: pointer to struct sde_hw_cp_cfg
+ */
+void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg);
+
+/**
* reg_dmav1_deinit_dspp_ops() - deinitialize the dspp feature op for sde v4
* which were initialized.
* @idx: dspp idx
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.c b/drivers/gpu/drm/msm/sde/sde_hw_top.c
index b773187..9f5510b 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.c
@@ -212,7 +212,7 @@
int i = 0;
u32 pp_offset[] = {0xC, 0x8, 0x4, 0x13};
- if (!mdp)
+ if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
return;
reg = SDE_REG_READ(c, MDP_VSYNC_SEL);
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 8077756..20fca52 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1840,7 +1840,7 @@
struct sde_hw_fmt_layout layout;
memset(&layout, 0, sizeof(struct sde_hw_fmt_layout));
- sde_format_populate_layout(rstate->aspace, state->fb,
+ sde_format_populate_layout(pstate->aspace, state->fb,
&layout);
for (i = 0; i < ARRAY_SIZE(rot_cmd->src_iova); i++) {
rot_cmd->src_iova[i] = layout.plane_addr[i];
@@ -1849,7 +1849,7 @@
rot_cmd->src_planes = layout.num_planes;
memset(&layout, 0, sizeof(struct sde_hw_fmt_layout));
- sde_format_populate_layout(rstate->aspace, rstate->out_fb,
+ sde_format_populate_layout(pstate->aspace, rstate->out_fb,
&layout);
for (i = 0; i < ARRAY_SIZE(rot_cmd->dst_iova); i++) {
rot_cmd->dst_iova[i] = layout.plane_addr[i];
@@ -2042,7 +2042,6 @@
SDE_DEBUG("plane%d.%d allocate fb/fbo\n", plane->base.id,
new_rstate->sequence_id);
- new_rstate->aspace = new_pstate->aspace;
/* check if out_fb is already attached to rotator */
new_rstate->out_fbo = sde_kms_fbo_alloc(plane->dev, fb_w, fb_h,
@@ -2081,9 +2080,9 @@
}
/* prepare rotator input buffer */
- ret = msm_framebuffer_prepare(new_state->fb, new_rstate->aspace);
+ ret = msm_framebuffer_prepare(new_state->fb, new_pstate->aspace);
if (ret) {
- SDE_ERROR("failed to prepare input framebuffer\n");
+ SDE_ERROR("failed to prepare input framebuffer, %d\n", ret);
goto error_prepare_input_buffer;
}
@@ -2093,9 +2092,10 @@
new_rstate->sequence_id);
ret = msm_framebuffer_prepare(new_rstate->out_fb,
- new_rstate->aspace);
+ new_pstate->aspace);
if (ret) {
- SDE_ERROR("failed to prepare inline framebuffer\n");
+ SDE_ERROR("failed to prepare inline framebuffer, %d\n",
+ ret);
goto error_prepare_output_buffer;
}
}
@@ -2103,7 +2103,7 @@
return 0;
error_prepare_output_buffer:
- msm_framebuffer_cleanup(new_state->fb, new_rstate->aspace);
+ msm_framebuffer_cleanup(new_state->fb, new_pstate->aspace);
error_prepare_input_buffer:
sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FB,
(u64) &new_rstate->rot_hw->base);
@@ -2159,7 +2159,7 @@
if (sde_plane_enabled(old_state)) {
if (old_rstate->out_fb) {
msm_framebuffer_cleanup(old_rstate->out_fb,
- old_rstate->aspace);
+ old_pstate->aspace);
sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FB,
(u64) &old_rstate->rot_hw->base);
old_rstate->out_fb = NULL;
@@ -2168,7 +2168,7 @@
old_rstate->out_fbo = NULL;
}
- msm_framebuffer_cleanup(old_state->fb, old_rstate->aspace);
+ msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
}
}
@@ -2723,16 +2723,19 @@
struct drm_plane_state *old_state)
{
struct sde_plane *psde = to_sde_plane(plane);
+ struct sde_plane_state *old_pstate;
struct sde_plane_rot_state *old_rstate;
- if (!old_state->fb)
+ if (!old_state || !old_state->fb)
return;
+ old_pstate = to_sde_plane_state(old_state);
+
SDE_DEBUG_PLANE(psde, "FB[%u]\n", old_state->fb->base.id);
- old_rstate = &to_sde_plane_state(old_state)->rot;
+ old_rstate = &old_pstate->rot;
- msm_framebuffer_cleanup(old_rstate->out_fb, old_rstate->aspace);
+ msm_framebuffer_cleanup(old_rstate->out_fb, old_pstate->aspace);
sde_plane_rot_cleanup_fb(plane, old_state);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h
index be0ea67..2f0068a 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.h
+++ b/drivers/gpu/drm/msm/sde/sde_plane.h
@@ -34,7 +34,6 @@
* @rot90: true if rotation of 90 degree is required
* @hflip: true if horizontal flip is required
* @vflip: true if vertical flip is required
- * @aspace: pointer address space for input/output buffers
* @rot_cmd: rotator configuration command
* @nplane: total number of drm plane attached to rotator
* @in_fb: input fb attached to rotator
@@ -64,7 +63,6 @@
bool rot90;
bool hflip;
bool vflip;
- struct msm_gem_address_space *aspace;
struct sde_hw_rot_cmd rot_cmd;
int nplane;
/* input */
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 1483dae..6f66b73 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -81,8 +81,10 @@
return -ENOMEM;
size = roundup(size, PAGE_SIZE);
ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size);
- if (ret != 0)
+ if (ret != 0) {
+ kfree(bo);
return ret;
+ }
bo->dumb = false;
virtio_gpu_init_ttm_placement(bo, pinned);
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 13c36e6..742da91 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -55,7 +55,7 @@
{ adreno_is_a530, a530_vbif },
{ adreno_is_a512, a540_vbif },
{ adreno_is_a510, a530_vbif },
- { adreno_is_a508, a540_vbif },
+ { adreno_is_a508, a530_vbif },
{ adreno_is_a505, a530_vbif },
{ adreno_is_a506, a530_vbif },
};
diff --git a/drivers/gpu/msm/adreno_a5xx_preempt.c b/drivers/gpu/msm/adreno_a5xx_preempt.c
index 43302a0..4036530 100644
--- a/drivers/gpu/msm/adreno_a5xx_preempt.c
+++ b/drivers/gpu/msm/adreno_a5xx_preempt.c
@@ -547,13 +547,42 @@
KGSL_MEMFLAGS_GPUREADONLY, KGSL_MEMDESC_PRIVILEGED,
"smmu_info");
}
+
+static void a5xx_preemption_iommu_close(struct adreno_device *adreno_dev)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+ struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
+
+ kgsl_free_global(device, &iommu->smmu_info);
+}
+
#else
static int a5xx_preemption_iommu_init(struct adreno_device *adreno_dev)
{
return -ENODEV;
}
+
+static void a5xx_preemption_iommu_close(struct adreno_device *adreno_dev)
+{
+}
#endif
+static void a5xx_preemption_close(struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_preemption *preempt = &adreno_dev->preempt;
+ struct adreno_ringbuffer *rb;
+ unsigned int i;
+
+ del_timer(&preempt->timer);
+ kgsl_free_global(device, &preempt->counters);
+ a5xx_preemption_iommu_close(adreno_dev);
+
+ FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
+ kgsl_free_global(device, &rb->preemption_desc);
+ }
+}
+
int a5xx_preemption_init(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -578,7 +607,7 @@
A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0,
"preemption_counters");
if (ret)
- return ret;
+ goto err;
addr = preempt->counters.gpuaddr;
@@ -586,10 +615,16 @@
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
ret = a5xx_preemption_ringbuffer_init(adreno_dev, rb, addr);
if (ret)
- return ret;
+ goto err;
addr += A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE;
}
- return a5xx_preemption_iommu_init(adreno_dev);
+ ret = a5xx_preemption_iommu_init(adreno_dev);
+
+err:
+ if (ret)
+ a5xx_preemption_close(device);
+
+ return ret;
}
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 7636a42..6fb81ee 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -530,7 +530,8 @@
struct kgsl_device *device = dev_get_drvdata(dev);
struct kgsl_pwrctrl *pwr;
struct kgsl_pwrlevel *pwr_level;
- int level, i;
+ int level;
+ unsigned int i;
unsigned long cur_freq, rec_freq;
struct dev_pm_opp *opp;
@@ -574,7 +575,12 @@
/* If the governor recommends a new frequency, update it here */
if (rec_freq != cur_freq) {
level = pwr->max_pwrlevel;
- for (i = pwr->min_pwrlevel; i >= pwr->max_pwrlevel; i--)
+ /*
+ * Array index of pwrlevels[] should be within the permitted
+ * power levels, i.e., from max_pwrlevel to min_pwrlevel.
+ */
+ for (i = pwr->min_pwrlevel; (i >= pwr->max_pwrlevel
+ && i <= pwr->min_pwrlevel); i--)
if (rec_freq <= pwr->pwrlevels[i].gpu_freq) {
if (pwr->thermal_cycle == CYCLE_ACTIVE)
level = _thermal_adjust(pwr, i);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index cb3f515a..01e3a37 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -2342,6 +2342,10 @@
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ if (cmd.port_num < rdma_start_port(ib_dev) ||
+ cmd.port_num > rdma_end_port(ib_dev))
+ return -EINVAL;
+
INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
out_len);
@@ -2882,6 +2886,10 @@
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ if (cmd.attr.port_num < rdma_start_port(ib_dev) ||
+ cmd.attr.port_num > rdma_end_port(ib_dev))
+ return -EINVAL;
+
uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
if (!uobj)
return -ENOMEM;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1d5c514..9a4d11f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -238,6 +238,7 @@
#define ARM_SMMU_CB_FSYNR0 0x68
#define ARM_SMMU_CB_S1_TLBIVA 0x600
#define ARM_SMMU_CB_S1_TLBIASID 0x610
+#define ARM_SMMU_CB_S1_TLBIALL 0x618
#define ARM_SMMU_CB_S1_TLBIVAL 0x620
#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630
#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638
@@ -415,6 +416,7 @@
#define ARM_SMMU_OPT_SKIP_INIT (1 << 2)
#define ARM_SMMU_OPT_DYNAMIC (1 << 3)
#define ARM_SMMU_OPT_3LVL_TABLES (1 << 4)
+#define ARM_SMMU_OPT_NO_ASID_RETENTION (1 << 5)
u32 options;
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
@@ -534,6 +536,7 @@
{ ARM_SMMU_OPT_SKIP_INIT, "qcom,skip-init" },
{ ARM_SMMU_OPT_DYNAMIC, "qcom,dynamic" },
{ ARM_SMMU_OPT_3LVL_TABLES, "qcom,use-3-lvl-tables" },
+ { ARM_SMMU_OPT_NO_ASID_RETENTION, "qcom,no-asid-retention" },
{ 0, NULL},
};
@@ -991,12 +994,17 @@
struct arm_smmu_device *smmu = smmu_domain->smmu;
bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
void __iomem *base;
+ bool use_tlbiall = smmu->options & ARM_SMMU_OPT_NO_ASID_RETENTION;
- if (stage1) {
+ if (stage1 && !use_tlbiall) {
base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg),
base + ARM_SMMU_CB_S1_TLBIASID);
arm_smmu_tlb_sync_cb(smmu, cfg->cbndx);
+ } else if (stage1 && use_tlbiall) {
+ base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
+ writel_relaxed(0, base + ARM_SMMU_CB_S1_TLBIALL);
+ arm_smmu_tlb_sync_cb(smmu, cfg->cbndx);
} else {
base = ARM_SMMU_GR0(smmu);
writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg),
@@ -1013,8 +1021,9 @@
struct arm_smmu_device *smmu = smmu_domain->smmu;
bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
void __iomem *reg;
+ bool use_tlbiall = smmu->options & ARM_SMMU_OPT_NO_ASID_RETENTION;
- if (stage1) {
+ if (stage1 && !use_tlbiall) {
reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
@@ -1033,6 +1042,10 @@
iova += granule >> 12;
} while (size -= granule);
}
+ } else if (stage1 && use_tlbiall) {
+ reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
+ reg += ARM_SMMU_CB_S1_TLBIALL;
+ writel_relaxed(0, reg);
} else if (smmu->version == ARM_SMMU_V2) {
reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L :
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index d2cb1e8..3989bc6 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -330,6 +330,16 @@
}
EXPORT_SYMBOL(mbox_controller_is_idle);
+
+void mbox_chan_debug(struct mbox_chan *chan)
+{
+ if (!chan || !chan->cl || !chan->mbox->debug)
+ return;
+
+ return chan->mbox->debug(chan);
+}
+EXPORT_SYMBOL(mbox_chan_debug);
+
/**
* mbox_request_channel - Request a mailbox channel.
* @cl: Identity of the client requesting the channel.
diff --git a/drivers/mailbox/qti-tcs.c b/drivers/mailbox/qti-tcs.c
index be91a65..15d0805 100644
--- a/drivers/mailbox/qti-tcs.c
+++ b/drivers/mailbox/qti-tcs.c
@@ -241,11 +241,11 @@
return;
msg = resp->msg;
- pr_debug("Response object idx=%d:\n\tfor-tcs=%d\tin-use=%d\n",
+ pr_warn("Response object idx=%d:\n\tfor-tcs=%d\tin-use=%d\n",
resp->idx, resp->m, resp->in_use);
- pr_debug("Msg: state=%d\n", msg->state);
+ pr_warn("Msg: state=%d\n", msg->state);
for (i = 0; i < msg->num_payload; i++)
- pr_debug("addr=0x%x data=0x%x complete=0x%x\n",
+ pr_warn("addr=0x%x data=0x%x complete=0x%x\n",
msg->payload[i].addr,
msg->payload[i].data,
msg->payload[i].complete);
@@ -804,14 +804,14 @@
if (!enable)
return;
- pr_debug("TCS-%d contents:\n", m);
+ pr_warn("TCS-%d contents:\n", m);
for (n = 0; n < tcs->ncpt; n++) {
if (!(enable & BIT(n)))
continue;
addr = read_tcs_reg(base, TCS_DRV_CMD_ADDR, m, n);
data = read_tcs_reg(base, TCS_DRV_CMD_DATA, m, n);
msgid = read_tcs_reg(base, TCS_DRV_CMD_MSGID, m, n);
- pr_debug("\tn=%d addr=0x%x data=0x%x hdr=0x%x\n",
+ pr_warn("\tn=%d addr=0x%x data=0x%x hdr=0x%x\n",
n, addr, data, msgid);
}
}
@@ -824,7 +824,7 @@
for (i = 0; i < drv->num_tcs; i++) {
if (!atomic_read(&drv->tcs_in_use[i]))
continue;
- pr_debug("Time: %llu: TCS-%d:\n\tReq Sent:%d Last Sent:%llu\n\tResp Recv:%d Last Recvd:%llu\n",
+ pr_warn("Time: %llu: TCS-%d:\n\tReq Sent:%d Last Sent:%llu\n\tResp Recv:%d Last Recvd:%llu\n",
curr, i,
atomic_read(&drv->tcs_send_count[i]),
drv->tcs_last_sent_ts[i],
@@ -835,6 +835,13 @@
}
}
+static void chan_debug(struct mbox_chan *chan)
+{
+ struct tcs_drv *drv = container_of(chan->mbox, struct tcs_drv, mbox);
+
+ dump_tcs_stats(drv);
+}
+
/**
* chan_tcs_write: Validate the incoming message and write to the
* appropriate TCS block.
@@ -910,7 +917,6 @@
/* If we were just busy waiting for TCS, dump the state and return */
if (ret == -EBUSY) {
pr_info_ratelimited("TCS Busy, retrying RPMH message send\n");
- dump_tcs_stats(drv);
ret = -EAGAIN;
}
@@ -1162,6 +1168,7 @@
drv->mbox.txdone_irq = true;
drv->mbox.of_xlate = of_tcs_mbox_xlate;
drv->mbox.is_idle = tcs_drv_is_idle;
+ drv->mbox.debug = chan_debug;
drv->num_tcs = st;
drv->pdev = pdev;
INIT_LIST_HEAD(&drv->response_pending);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index c68239e..98b067b 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -468,7 +468,7 @@
while ((entity_err = media_entity_graph_walk_next(graph))) {
/* don't let the stream_count go negative */
- if (entity->stream_count > 0) {
+ if (entity_err->stream_count > 0) {
entity_err->stream_count--;
if (entity_err->stream_count == 0)
entity_err->pipe = NULL;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
index fc7a493..38f13c4 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
@@ -233,6 +233,7 @@
struct cam_cdm_client *clients[CAM_PER_CDM_MAX_REGISTERED_CLIENTS];
uint8_t bl_tag;
atomic_t error;
+ atomic_t bl_done;
struct cam_cdm_hw_mem gen_irq;
uint32_t cpas_handle;
};
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_core_common.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_core_common.c
index 341406a..3604357 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_core_common.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_core_common.c
@@ -107,7 +107,7 @@
if (node->bl_tag == tag)
return node;
}
- pr_err("Could not find the bl request for tag=%d\n", tag);
+ pr_err("Could not find the bl request for tag=%x\n", tag);
return NULL;
}
@@ -216,7 +216,7 @@
{
struct cam_hw_info *cdm_hw = hw_priv;
struct cam_cdm *core = NULL;
- int rc = -1;
+ int rc = -EPERM;
int client_idx;
struct cam_cdm_client *client;
uint32_t *handle = start_args;
@@ -476,7 +476,8 @@
core->clients[idx] = NULL;
mutex_unlock(
&cdm_hw->hw_mutex);
- rc = -1;
+ rc = -EPERM;
+ pr_err("Invalid ops for virtual cdm\n");
break;
}
} else {
@@ -521,7 +522,7 @@
if (client->refcount != 0) {
pr_err("CDM Client refcount not zero %d",
client->refcount);
- rc = -1;
+ rc = -EPERM;
mutex_unlock(&client->lock);
mutex_unlock(&cdm_hw->hw_mutex);
break;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
index 6009c25..5fac7d8 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
@@ -66,19 +66,74 @@
if (cam_cdm_read_hw_reg(cdm_hw, CDM_BL_FIFO_PENDING_REQ_RB,
pending_bl)) {
pr_err("Failed to read CDM pending BL's\n");
- rc = -1;
+ rc = -EIO;
}
return rc;
}
+static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw,
+ bool enable)
+{
+ int rc = -EIO;
+ uint32_t irq_mask = 0;
+ struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
+
+ if (cam_cdm_read_hw_reg(cdm_hw, CDM_IRQ_MASK,
+ &irq_mask)) {
+ pr_err("Failed to read CDM IRQ mask\n");
+ return rc;
+ }
+
+ if (enable == true) {
+ if (cam_cdm_write_hw_reg(cdm_hw, CDM_IRQ_MASK,
+ (irq_mask | 0x4))) {
+ pr_err("Write failed to enable BL done irq\n");
+ } else {
+ atomic_inc(&core->bl_done);
+ rc = 0;
+ CDM_CDBG("BL done irq enabled =%d\n",
+ atomic_read(&core->bl_done));
+ }
+ } else {
+ if (cam_cdm_write_hw_reg(cdm_hw, CDM_IRQ_MASK,
+ (irq_mask & 0x70003))) {
+ pr_err("Write failed to disable BL done irq\n");
+ } else {
+ atomic_dec(&core->bl_done);
+ rc = 0;
+ CDM_CDBG("BL done irq disable =%d\n",
+ atomic_read(&core->bl_done));
+ }
+ }
+ return rc;
+}
+
+static int cam_hw_cdm_enable_core(struct cam_hw_info *cdm_hw, bool enable)
+{
+ int rc = 0;
+
+ if (enable == true) {
+ if (cam_cdm_write_hw_reg(cdm_hw, CDM_CFG_CORE_EN, 0x01)) {
+ pr_err("Failed to Write CDM HW core enable\n");
+ rc = -EIO;
+ }
+ } else {
+ if (cam_cdm_write_hw_reg(cdm_hw, CDM_CFG_CORE_EN, 0x02)) {
+ pr_err("Failed to Write CDM HW core disable\n");
+ rc = -EIO;
+ }
+ }
+ return rc;
+}
+
int cam_hw_cdm_enable_core_dbg(struct cam_hw_info *cdm_hw)
{
int rc = 0;
if (cam_cdm_write_hw_reg(cdm_hw, CDM_DBG_CORE_DBUG, 0x10100)) {
pr_err("Failed to Write CDM HW core debug\n");
- rc = -1;
+ rc = -EIO;
}
return rc;
@@ -90,7 +145,7 @@
if (cam_cdm_write_hw_reg(cdm_hw, CDM_DBG_CORE_DBUG, 0)) {
pr_err("Failed to Write CDM HW core debug\n");
- rc = -1;
+ rc = -EIO;
}
return rc;
@@ -137,8 +192,8 @@
mutex_lock(&cdm_hw->hw_mutex);
cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg);
pr_err("CDM HW core status=%x\n", dump_reg);
- /* First pause CDM */
- cam_cdm_write_hw_reg(cdm_hw, CDM_CFG_CORE_EN, 0x03);
+ /* First pause CDM, If it fails still proceed to dump debug info */
+ cam_hw_cdm_enable_core(cdm_hw, false);
cam_hw_cdm_bl_fifo_pending_bl_rb(cdm_hw, &dump_reg);
pr_err("CDM HW current pending BL=%x\n", dump_reg);
loop_cnt = dump_reg;
@@ -196,7 +251,7 @@
pr_err("CDM HW current pending BL=%x\n", dump_reg);
/* Enable CDM back */
- cam_cdm_write_hw_reg(cdm_hw, CDM_CFG_CORE_EN, 1);
+ cam_hw_cdm_enable_core(cdm_hw, true);
mutex_unlock(&cdm_hw->hw_mutex);
}
@@ -206,7 +261,7 @@
{
uint32_t pending_bl = 0;
int32_t available_bl_slots = 0;
- int rc = -1;
+ int rc = -EIO;
long time_left;
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
@@ -214,7 +269,7 @@
if (cam_cdm_read_hw_reg(cdm_hw, CDM_BL_FIFO_PENDING_REQ_RB,
&pending_bl)) {
pr_err("Failed to read CDM pending BL's\n");
- rc = -1;
+ rc = -EIO;
break;
}
available_bl_slots = CAM_CDM_HWFIFO_SIZE - pending_bl;
@@ -230,14 +285,24 @@
rc = bl_count;
break;
} else if (0 == (available_bl_slots - 1)) {
+ rc = cam_hw_cdm_enable_bl_done_irq(cdm_hw, true);
+ if (rc) {
+ pr_err("Enable BL done irq failed\n");
+ break;
+ }
time_left = wait_for_completion_timeout(
&core->bl_complete, msecs_to_jiffies(
CAM_CDM_BL_FIFO_WAIT_TIMEOUT));
if (time_left <= 0) {
pr_err("CDM HW BL Wait timed out failed\n");
- rc = -1;
+ if (cam_hw_cdm_enable_bl_done_irq(cdm_hw,
+ false))
+ pr_err("Disable BL done irq failed\n");
+ rc = -EIO;
break;
}
+ if (cam_hw_cdm_enable_bl_done_irq(cdm_hw, false))
+ pr_err("Disable BL done irq failed\n");
rc = 0;
CDM_CDBG("CDM HW is ready for data\n");
} else {
@@ -286,8 +351,8 @@
rc = -EINVAL;
goto end;
}
- CDM_CDBG("CDM write BL last cmd tag=%d total=%d\n",
- core->bl_tag, req->data->cmd_arrary_count);
+ CDM_CDBG("CDM write BL last cmd tag=%x total=%d cookie=%d\n",
+ core->bl_tag, req->data->cmd_arrary_count, req->data->cookie);
node = kzalloc(sizeof(struct cam_cdm_bl_cb_request_entry),
GFP_KERNEL);
if (!node) {
@@ -311,7 +376,7 @@
core->bl_tag);
list_del_init(&node->entry);
kfree(node);
- rc = -1;
+ rc = -EIO;
goto end;
}
@@ -320,7 +385,7 @@
core->bl_tag);
list_del_init(&node->entry);
kfree(node);
- rc = -1;
+ rc = -EIO;
}
end:
@@ -331,7 +396,7 @@
struct cam_cdm_hw_intf_cmd_submit_bl *req,
struct cam_cdm_client *client)
{
- int i, rc = -1;
+ int i, rc;
struct cam_cdm_bl_request *cdm_cmd = req->data;
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
uint32_t pending_bl = 0;
@@ -342,10 +407,8 @@
req->data->cmd_arrary_count, CAM_CDM_HWFIFO_SIZE);
}
- if (atomic_read(&core->error) != 0) {
- pr_err("HW in error state, cannot trigger transactions now\n");
- return rc;
- }
+ if (atomic_read(&core->error))
+ return -EIO;
mutex_lock(&cdm_hw->hw_mutex);
mutex_lock(&client->lock);
@@ -366,13 +429,13 @@
pr_err("cmd len(%d) is invalid cnt=%d total cnt=%d\n",
cdm_cmd->cmd[i].len, i,
req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EINVAL;
break;
}
- if (atomic_read(&core->error) != 0) {
- pr_err("HW in error state cmd_count=%d total cnt=%d\n",
+ if (atomic_read(&core->error)) {
+ pr_err_ratelimited("In error state cnt=%d total cnt=%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EIO;
break;
}
if (write_count == 0) {
@@ -381,7 +444,7 @@
if (write_count < 0) {
pr_err("wait for bl fifo failed %d:%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EIO;
break;
}
} else {
@@ -397,7 +460,7 @@
if (!cdm_cmd->cmd[i].bl_addr.hw_iova) {
pr_err("Hw bl hw_iova is invalid %d:%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EINVAL;
break;
}
rc = 0;
@@ -407,13 +470,16 @@
} else {
pr_err("Only mem hdl/hw va type is supported %d\n",
req->data->type);
- rc = -1;
+ rc = -EINVAL;
break;
}
if ((!rc) && (hw_vaddr_ptr) && (len) &&
(len >= cdm_cmd->cmd[i].offset)) {
CDM_CDBG("Got the HW VA\n");
+ if (core->bl_tag >=
+ (CAM_CDM_HWFIFO_SIZE - 1))
+ core->bl_tag = 0;
rc = cam_hw_cdm_bl_write(cdm_hw,
((uint32_t)hw_vaddr_ptr +
cdm_cmd->cmd[i].offset),
@@ -421,7 +487,7 @@
if (rc) {
pr_err("Hw bl write failed %d:%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EIO;
break;
}
} else {
@@ -430,23 +496,24 @@
cdm_cmd->cmd[i].offset);
pr_err("Sanity check failed for %d:%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EINVAL;
break;
}
if (!rc) {
CDM_CDBG("write BL success for cnt=%d with tag=%d\n",
i, core->bl_tag);
- core->bl_tag++;
+
CDM_CDBG("Now commit the BL\n");
if (cam_hw_cdm_commit_bl_write(cdm_hw)) {
pr_err("Cannot commit the BL %d tag=%d\n",
- i, (core->bl_tag - 1));
- rc = -1;
+ i, core->bl_tag);
+ rc = -EIO;
break;
}
CDM_CDBG("BL commit success BL %d tag=%d\n", i,
- (core->bl_tag - 1));
+ core->bl_tag);
+ core->bl_tag++;
if ((req->data->flag == true) &&
(i == (req->data->cmd_arrary_count -
1))) {
@@ -455,9 +522,6 @@
if (rc == 0)
core->bl_tag++;
}
- if (!rc && ((CAM_CDM_HWFIFO_SIZE - 1) ==
- core->bl_tag))
- core->bl_tag = 0;
}
}
mutex_unlock(&client->lock);
@@ -502,7 +566,8 @@
list_del_init(&node->entry);
kfree(node);
} else {
- pr_err("Invalid node for inline irq\n");
+ pr_err("Invalid node for inline irq status=%x data=%x\n",
+ payload->irq_status, payload->irq_data);
}
mutex_unlock(&cdm_hw->hw_mutex);
}
@@ -514,25 +579,30 @@
}
if (payload->irq_status &
CAM_CDM_IRQ_STATUS_INFO_BL_DONE_MASK) {
- pr_err("CDM HW BL done IRQ\n");
- complete(&core->bl_complete);
+ if (atomic_read(&core->bl_done)) {
+ CDM_CDBG("CDM HW BL done IRQ\n");
+ complete(&core->bl_complete);
+ }
}
if (payload->irq_status &
CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) {
- pr_err("Invalid command IRQ, Need HW reset\n");
+ pr_err_ratelimited("Invalid command IRQ, Need HW reset\n");
+ atomic_inc(&core->error);
+ cam_hw_cdm_dump_core_debug_registers(cdm_hw);
+ }
+ if (payload->irq_status &
+ CAM_CDM_IRQ_STATUS_ERROR_AHB_BUS_MASK) {
+ pr_err_ratelimited("AHB Error IRQ\n");
atomic_inc(&core->error);
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
atomic_dec(&core->error);
}
if (payload->irq_status &
- CAM_CDM_IRQ_STATUS_ERROR_AHB_BUS_MASK) {
- pr_err("AHB IRQ\n");
- cam_hw_cdm_dump_core_debug_registers(cdm_hw);
- }
- if (payload->irq_status &
CAM_CDM_IRQ_STATUS_ERROR_OVER_FLOW_MASK) {
- pr_err("Overflow IRQ\n");
+ pr_err_ratelimited("Overflow Error IRQ\n");
+ atomic_inc(&core->error);
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
+ atomic_dec(&core->error);
}
kfree(payload);
} else {
@@ -552,7 +622,7 @@
core = (struct cam_cdm *)cdm_hw->core_info;
atomic_inc(&core->error);
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
- pr_err("Page fault iova addr %pK\n", (void *)iova);
+ pr_err_ratelimited("Page fault iova addr %pK\n", (void *)iova);
cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
(void *)iova);
atomic_dec(&core->error);
@@ -576,6 +646,11 @@
&payload->irq_status)) {
pr_err("Failed to read CDM HW IRQ status\n");
}
+ if (!payload->irq_status) {
+ pr_err_ratelimited("Invalid irq received\n");
+ kfree(payload);
+ return IRQ_HANDLED;
+ }
if (payload->irq_status &
CAM_CDM_IRQ_STATUS_INFO_INLINE_IRQ_MASK) {
if (cam_cdm_read_hw_reg(cdm_hw, CDM_IRQ_USR_DATA,
@@ -618,8 +693,7 @@
genirq_alloc_cmd.align = 0;
genirq_alloc_cmd.size = (8 * CAM_CDM_HWFIFO_SIZE);
genirq_alloc_cmd.smmu_hdl = cdm_core->iommu_hdl.non_secure;
- genirq_alloc_cmd.flags = 0;
- genirq_alloc_cmd.region = CAM_MEM_MGR_REGION_NON_SECURE_IO;
+ genirq_alloc_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
rc = cam_mem_mgr_request_mem(&genirq_alloc_cmd,
&genirq_alloc_out);
if (rc) {
@@ -679,6 +753,8 @@
CDM_CDBG("Enable soc done\n");
/* Before triggering the reset to HW, clear the reset complete */
+ atomic_set(&cdm_core->error, 0);
+ atomic_set(&cdm_core->bl_done, 0);
reinit_completion(&cdm_core->reset_complete);
reinit_completion(&cdm_core->bl_complete);
@@ -713,13 +789,12 @@
CDM_CDBG("CDM Init success\n");
cdm_hw->hw_state = CAM_HW_STATE_POWER_UP;
cam_cdm_write_hw_reg(cdm_hw, CDM_IRQ_MASK, 0x70003);
- cam_cdm_write_hw_reg(cdm_hw, CDM_CFG_CGC_CFG, 0x7);
rc = 0;
goto end;
}
disable_return:
- rc = -1;
+ rc = -EIO;
cam_soc_util_disable_platform_resource(soc_info, true, true);
end:
return rc;
@@ -757,6 +832,8 @@
struct cam_cdm *cdm_core = NULL;
struct cam_cdm_private_dt_data *soc_private = NULL;
struct cam_cpas_register_params cpas_parms;
+ struct cam_ahb_vote ahb_vote;
+ struct cam_axi_vote axi_vote;
cdm_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
if (!cdm_hw_intf)
@@ -788,7 +865,7 @@
pr_err("Failed to get dt properties\n");
goto release_mem;
}
- cdm_hw_intf->hw_idx = cdm_hw->soc_info.pdev->id;
+ cdm_hw_intf->hw_idx = cdm_hw->soc_info.index;
cdm_core = (struct cam_cdm *)cdm_hw->core_info;
soc_private = (struct cam_cdm_private_dt_data *)
cdm_hw->soc_info.soc_private;
@@ -798,7 +875,6 @@
cdm_core->flags = CAM_CDM_FLAG_PRIVATE_CDM;
cdm_core->bl_tag = 0;
- atomic_set(&cdm_core->error, 0);
cdm_core->id = cam_hw_cdm_get_id_by_name(cdm_core->name);
if (cdm_core->id >= CAM_CDM_MAX) {
pr_err("Failed to get CDM HW name for %s\n", cdm_core->name);
@@ -863,10 +939,20 @@
cpas_parms.client_handle);
cdm_core->cpas_handle = cpas_parms.client_handle;
+ ahb_vote.type = CAM_VOTE_ABSOLUTE;
+ ahb_vote.vote.level = CAM_SVS_VOTE;
+ axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ rc = cam_cpas_start(cdm_core->cpas_handle, &ahb_vote, &axi_vote);
+ if (rc) {
+ pr_err("CPAS start failed\n");
+ goto cpas_unregister;
+ }
+
rc = cam_hw_cdm_init(cdm_hw, NULL, 0);
if (rc) {
pr_err("Failed to Init CDM HW\n");
- goto init_failed;
+ goto cpas_stop;
}
cdm_hw->open_count++;
@@ -876,7 +962,7 @@
goto deinit;
}
- if (cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_HW_VERSION,
+ if (cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_TITAN_VERSION,
&cdm_core->hw_family_version)) {
pr_err("Failed to read CDM family Version\n");
goto deinit;
@@ -900,14 +986,23 @@
rc = cam_hw_cdm_deinit(cdm_hw, NULL, 0);
if (rc) {
pr_err("Failed to Deinit CDM HW\n");
- goto release_platform_resource;
+ cdm_hw->open_count--;
+ goto cpas_stop;
+ }
+
+ rc = cam_cpas_stop(cdm_core->cpas_handle);
+ if (rc) {
+ pr_err("CPAS stop failed\n");
+ cdm_hw->open_count--;
+ goto cpas_unregister;
}
rc = cam_cdm_intf_register_hw_cdm(cdm_hw_intf,
soc_private, CAM_HW_CDM, &cdm_core->index);
if (rc) {
pr_err("HW CDM Interface registration failed\n");
- goto release_platform_resource;
+ cdm_hw->open_count--;
+ goto cpas_unregister;
}
cdm_hw->open_count--;
mutex_unlock(&cdm_hw->hw_mutex);
@@ -920,7 +1015,10 @@
if (cam_hw_cdm_deinit(cdm_hw, NULL, 0))
pr_err("Deinit failed for hw\n");
cdm_hw->open_count--;
-init_failed:
+cpas_stop:
+ if (cam_cpas_stop(cdm_core->cpas_handle))
+ pr_err("CPAS stop failed\n");
+cpas_unregister:
if (cam_cpas_unregister_client(cdm_core->cpas_handle))
pr_err("CPAS unregister failed\n");
release_platform_resource:
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf.c
index b1b2117..59f5b92 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_intf.c
@@ -42,7 +42,7 @@
mutex_lock(&cam_cdm_mgr_lock);
if (cdm_mgr.probe_done == false) {
pr_err("CDM intf mgr not probed yet\n");
- rc = -1;
+ rc = -EPERM;
} else {
CDM_CDBG("CDM intf mgr get refcount=%d\n",
cdm_mgr.refcount);
@@ -73,7 +73,7 @@
static int get_cdm_iommu_handle(struct cam_iommu_handle *cdm_handles,
uint32_t hw_idx)
{
- int rc = -1;
+ int rc = -EPERM;
struct cam_hw_intf *hw = cdm_mgr.nodes[hw_idx].device;
if (hw->hw_ops.get_hw_caps) {
@@ -87,7 +87,7 @@
static int get_cdm_index_by_id(char *identifier,
uint32_t cell_index, uint32_t *hw_index)
{
- int rc = -1, i, j;
+ int rc = -EPERM, i, j;
char client_name[128];
CDM_CDBG("Looking for HW id of =%s and index=%d\n",
@@ -125,7 +125,7 @@
int cam_cdm_get_iommu_handle(char *identifier,
struct cam_iommu_handle *cdm_handles)
{
- int i, j, rc = -1;
+ int i, j, rc = -EPERM;
if ((!identifier) || (!cdm_handles))
return -EINVAL;
@@ -164,7 +164,7 @@
int cam_cdm_acquire(struct cam_cdm_acquire_data *data)
{
- int rc = -1;
+ int rc = -EPERM;
struct cam_hw_intf *hw;
uint32_t hw_index = 0;
@@ -179,7 +179,7 @@
if (data->id > CAM_CDM_HW_ANY) {
pr_err("only CAM_CDM_VIRTUAL/CAM_CDM_HW_ANY is supported\n");
- rc = -1;
+ rc = -EPERM;
goto end;
}
rc = get_cdm_index_by_id(data->identifier, data->cell_index,
@@ -200,7 +200,7 @@
}
} else {
pr_err("idx %d doesn't have acquire ops\n", hw_index);
- rc = -1;
+ rc = -EPERM;
}
}
end:
@@ -216,7 +216,7 @@
int cam_cdm_release(uint32_t handle)
{
uint32_t hw_index;
- int rc = -1;
+ int rc = -EPERM;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
@@ -250,7 +250,7 @@
int cam_cdm_submit_bls(uint32_t handle, struct cam_cdm_bl_request *data)
{
uint32_t hw_index;
- int rc = -1;
+ int rc = -EINVAL;
struct cam_hw_intf *hw;
if (!data)
@@ -258,6 +258,7 @@
if (get_cdm_mgr_refcount()) {
pr_err("CDM intf mgr get refcount failed\n");
+ rc = -EPERM;
return rc;
}
@@ -289,11 +290,12 @@
int cam_cdm_stream_on(uint32_t handle)
{
uint32_t hw_index;
- int rc = -1;
+ int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
pr_err("CDM intf mgr get refcount failed\n");
+ rc = -EPERM;
return rc;
}
@@ -320,11 +322,12 @@
int cam_cdm_stream_off(uint32_t handle)
{
uint32_t hw_index;
- int rc = -1;
+ int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
pr_err("CDM intf mgr get refcount failed\n");
+ rc = -EPERM;
return rc;
}
@@ -351,11 +354,12 @@
int cam_cdm_reset_hw(uint32_t handle)
{
uint32_t hw_index;
- int rc = -1;
+ int rc = -EINVAL;
struct cam_hw_intf *hw;
if (get_cdm_mgr_refcount()) {
pr_err("CDM intf mgr get refcount failed\n");
+ rc = -EPERM;
return rc;
}
@@ -426,13 +430,14 @@
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t index)
{
- int rc = -1;
+ int rc = -EINVAL;
if ((!hw) || (!data))
- return -EINVAL;
+ return rc;
if (get_cdm_mgr_refcount()) {
pr_err("CDM intf mgr get refcount failed\n");
+ rc = -EPERM;
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_soc.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_soc.c
index 0f5458c..fbf185c 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_soc.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_soc.c
@@ -48,13 +48,13 @@
if ((reg > cdm->offset_tbl->offset_max_size) ||
(reg > cdm->offset_tbl->last_offset)) {
- pr_err("CDM accessing invalid reg=%d\n", reg);
+ pr_err_ratelimited("Invalid reg=%d\n", reg);
goto permission_error;
} else {
reg_addr = (base + (CAM_CDM_OFFSET_FROM_REG(
cdm->offset_tbl, reg)));
if (reg_addr > (base + mem_len)) {
- pr_err("accessing invalid mapped region %d\n", reg);
+ pr_err_ratelimited("Invalid mapped region %d\n", reg);
goto permission_error;
}
*value = cam_io_r_mb(reg_addr);
@@ -84,13 +84,13 @@
if ((reg > cdm->offset_tbl->offset_max_size) ||
(reg > cdm->offset_tbl->last_offset)) {
- pr_err("CDM accessing invalid reg=%d\n", reg);
+ pr_err_ratelimited("CDM accessing invalid reg=%d\n", reg);
goto permission_error;
} else {
reg_addr = (base + CAM_CDM_OFFSET_FROM_REG(
cdm->offset_tbl, reg));
if (reg_addr > (base + mem_len)) {
- pr_err("Accessing invalid region %d:%d\n",
+ pr_err_ratelimited("Accessing invalid region %d:%d\n",
reg, (CAM_CDM_OFFSET_FROM_REG(
cdm->offset_tbl, reg)));
goto permission_error;
@@ -106,7 +106,7 @@
int cam_cdm_soc_load_dt_private(struct platform_device *pdev,
struct cam_cdm_private_dt_data *ptr)
{
- int i, rc = -1;
+ int i, rc = -EINVAL;
ptr->dt_num_supported_clients = of_property_count_strings(
pdev->dev.of_node,
@@ -186,7 +186,7 @@
return rc;
error:
- rc = -1;
+ rc = -EINVAL;
kfree(soc_ptr->soc_private);
soc_ptr->soc_private = NULL;
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c
index 3d258b4..a3de3d1 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_util.c
@@ -323,7 +323,7 @@
struct cam_soc_reg_map *base_table[CAM_SOC_MAX_BLOCK],
void __iomem **device_base)
{
- int ret = -1, i;
+ int ret = -EINVAL, i;
for (i = 0; i < base_array_size; i++) {
if (base_table[i])
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c
index e34bfc2..bfe14e1 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_virtual_core.c
@@ -83,7 +83,7 @@
struct cam_cdm_hw_intf_cmd_submit_bl *req,
struct cam_cdm_client *client)
{
- int i, rc = -1;
+ int i, rc = -EINVAL;
struct cam_cdm_bl_request *cdm_cmd = req->data;
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
@@ -97,7 +97,7 @@
pr_err("len(%d) is invalid count=%d total cnt=%d\n",
cdm_cmd->cmd[i].len, i,
req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EINVAL;
break;
}
if (req->data->type == CAM_CDM_BL_CMD_TYPE_MEM_HANDLE) {
@@ -113,7 +113,7 @@
} else {
pr_err("Only mem hdl/Kernel va type is supported %d\n",
req->data->type);
- rc = -1;
+ rc = -EINVAL;
break;
}
@@ -140,7 +140,7 @@
cdm_cmd->cmd[i].offset);
pr_err("Sanity check failed for cmd_count=%d cnt=%d\n",
i, req->data->cmd_arrary_count);
- rc = -1;
+ rc = -EINVAL;
break;
}
if (!rc) {
@@ -229,9 +229,8 @@
}
rc = cam_cdm_soc_load_dt_private(pdev, cdm_hw->soc_info.soc_private);
- if (rc != 0) {
+ if (rc) {
pr_err("Failed to load CDM dt private data\n");
- rc = -1;
kfree(cdm_hw->soc_info.soc_private);
cdm_hw->soc_info.soc_private = NULL;
goto soc_load_failed;
diff --git a/drivers/media/platform/msm/camera/cam_core/Makefile b/drivers/media/platform/msm/camera/cam_core/Makefile
index 60f94d1..6fb1200 100644
--- a/drivers/media/platform/msm/camera/cam_core/Makefile
+++ b/drivers/media/platform/msm/camera/cam_core/Makefile
@@ -1,4 +1,6 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sync
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_context.o cam_context_utils.o cam_node.o cam_subdev.o
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.h b/drivers/media/platform/msm/camera/cam_core/cam_context.h
index 7f0fb7f..d87c984 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.h
@@ -13,6 +13,7 @@
#ifndef _CAM_CONTEXT_H_
#define _CAM_CONTEXT_H_
+#include <linux/mutex.h>
#include <linux/spinlock.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index edd2e11..e934dff 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -19,11 +19,12 @@
#include <media/cam_sync.h>
#include <media/cam_defs.h>
-#include "cam_sync_api.h"
-#include "cam_req_mgr_util.h"
+#include "cam_context.h"
#include "cam_mem_mgr.h"
#include "cam_node.h"
-#include "cam_context.h"
+#include "cam_req_mgr_util.h"
+#include "cam_sync_api.h"
+#include "cam_trace.h"
int cam_context_buf_done_from_hw(struct cam_context *ctx,
void *done_event_data, uint32_t bubble_state)
@@ -42,6 +43,8 @@
req = list_first_entry(&ctx->active_req_list,
struct cam_ctx_request, list);
+ trace_cam_buf_done("UTILS", ctx, req);
+
if (done->request_id != req->request_id) {
pr_err("mismatch: done request [%lld], active request [%lld]\n",
done->request_id, req->request_id);
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c
index ab4c25d..fa26ea0 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_node.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c
@@ -15,6 +15,7 @@
#include <linux/uaccess.h>
#include "cam_node.h"
+#include "cam_trace.h"
static void __cam_node_handle_shutdown(struct cam_node *node)
{
@@ -255,6 +256,8 @@
return -EINVAL;
}
+ trace_cam_apply_req("Node", apply);
+
return cam_context_handle_crm_apply_req(ctx, apply);
}
diff --git a/drivers/media/platform/msm/camera/cam_icp/Makefile b/drivers/media/platform/msm/camera/cam_icp/Makefile
index b35e4e4..5aba168 100644
--- a/drivers/media/platform/msm/camera/cam_icp/Makefile
+++ b/drivers/media/platform/msm/camera/cam_icp/Makefile
@@ -8,6 +8,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_icp/fw_inc
ccflags-y += -Idrivers/media/platform/msm/camera
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += icp_hw/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_icp_subdev.o cam_icp_context.o hfi.o
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
index 2311f66..776847d 100644
--- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
+++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
@@ -25,6 +25,7 @@
#include "cam_icp_context.h"
#include "cam_req_mgr_util.h"
#include "cam_mem_mgr.h"
+#include "cam_trace.h"
static int __cam_icp_acquire_dev_in_available(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
@@ -32,8 +33,10 @@
int rc;
rc = cam_context_acquire_dev_to_hw(ctx, cmd);
- if (!rc)
+ if (!rc) {
ctx->state = CAM_CTX_ACQUIRED;
+ trace_cam_context_state("ICP", ctx);
+ }
return rc;
}
@@ -48,6 +51,7 @@
pr_err("Unable to release device\n");
ctx->state = CAM_CTX_AVAILABLE;
+ trace_cam_context_state("ICP", ctx);
return rc;
}
@@ -57,8 +61,10 @@
int rc;
rc = cam_context_start_dev_to_hw(ctx, cmd);
- if (!rc)
+ if (!rc) {
ctx->state = CAM_CTX_READY;
+ trace_cam_context_state("ICP", ctx);
+ }
return rc;
}
@@ -85,6 +91,7 @@
pr_err("Unable to stop device\n");
ctx->state = CAM_CTX_ACQUIRED;
+ trace_cam_context_state("ICP", ctx);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index fe719c7..f273a7b 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -416,7 +416,8 @@
memset(&out, 0, sizeof(out));
alloc.size = SZ_1M;
alloc.align = 0;
- alloc.region = CAM_MEM_MGR_REGION_SHARED;
+ alloc.flags = CAM_MEM_FLAG_HW_READ_WRITE |
+ CAM_MEM_FLAG_HW_SHARED_ACCESS;
alloc.smmu_hdl = icp_hw_mgr.iommu_hdl;
rc = cam_mem_mgr_request_mem(&alloc, &out);
if (rc)
@@ -462,7 +463,7 @@
int rc;
rc = cam_smmu_get_region_info(icp_hw_mgr.iommu_hdl,
- CAM_MEM_MGR_REGION_SHARED,
+ CAM_SMMU_REGION_SHARED,
&icp_hw_mgr.hfi_mem.shmem);
if (rc) {
pr_err("Unable to get shared memory info\n");
diff --git a/drivers/media/platform/msm/camera/cam_isp/Makefile b/drivers/media/platform/msm/camera/cam_isp/Makefile
index 77ad6fc..4851535 100644
--- a/drivers/media/platform/msm/camera/cam_isp/Makefile
+++ b/drivers/media/platform/msm/camera/cam_isp/Makefile
@@ -1,8 +1,9 @@
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
-ccflags-y += -Idrivers/media/platform/msm/camera/utils
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sync
ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sync
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += isp_hw_mgr/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_isp_dev.o cam_isp_context.o
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 83009d2..766ea89 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -21,10 +21,48 @@
#include "cam_mem_mgr.h"
#include "cam_sync_api.h"
#include "cam_req_mgr_dev.h"
+#include "cam_trace.h"
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+static uint64_t __cam_isp_ctx_get_event_ts(uint32_t evt_id, void *evt_data)
+{
+ uint64_t ts = 0;
+
+ if (!evt_data)
+ return 0;
+
+ switch (evt_id) {
+ case CAM_ISP_HW_EVENT_ERROR:
+ ts = ((struct cam_isp_hw_error_event_data *)evt_data)->
+ timestamp;
+ break;
+ case CAM_ISP_HW_EVENT_SOF:
+ ts = ((struct cam_isp_hw_sof_event_data *)evt_data)->
+ timestamp;
+ break;
+ case CAM_ISP_HW_EVENT_REG_UPDATE:
+ ts = ((struct cam_isp_hw_reg_update_event_data *)evt_data)->
+ timestamp;
+ break;
+ case CAM_ISP_HW_EVENT_EPOCH:
+ ts = ((struct cam_isp_hw_epoch_event_data *)evt_data)->
+ timestamp;
+ break;
+ case CAM_ISP_HW_EVENT_EOF:
+ ts = ((struct cam_isp_hw_eof_event_data *)evt_data)->
+ timestamp;
+ break;
+ case CAM_ISP_HW_EVENT_DONE:
+ break;
+ default:
+ CDBG("%s: Invalid Event Type %d\n", __func__, evt_id);
+ }
+
+ return ts;
+}
+
static int __cam_isp_ctx_handle_buf_done_in_activated_state(
struct cam_isp_context *ctx_isp,
struct cam_isp_hw_done_event_data *done,
@@ -45,6 +83,9 @@
req = list_first_entry(&ctx->active_req_list,
struct cam_ctx_request, list);
+
+ trace_cam_buf_done("ISP", ctx, req);
+
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
for (i = 0; i < done->num_handles; i++) {
for (j = 0; j < req_isp->num_fence_map_out; j++) {
@@ -99,12 +140,39 @@
if (req_isp->num_acked == req_isp->num_fence_map_out) {
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_req_list);
+ ctx_isp->active_req_cnt--;
+ CDBG("%s: Move active request %lld to free list(cnt = %d)\n",
+ __func__, req->request_id, ctx_isp->active_req_cnt);
}
end:
return rc;
}
+static void __cam_isp_ctx_send_sof_timestamp(
+ struct cam_isp_context *ctx_isp, uint64_t request_id,
+ uint32_t sof_event_status)
+{
+ struct cam_req_mgr_message req_msg;
+
+ req_msg.session_hdl = ctx_isp->base->session_hdl;
+ req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
+ req_msg.u.frame_msg.request_id = request_id;
+ req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val;
+ req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
+ req_msg.u.frame_msg.sof_status = sof_event_status;
+
+ CDBG("%s: request id:%lld frame number:%lld SOF time stamp:0x%llx\n",
+ __func__, request_id, ctx_isp->frame_id,
+ ctx_isp->sof_timestamp_val);
+ CDBG("%s sof status:%d\n", __func__, sof_event_status);
+
+ if (cam_req_mgr_notify_frame_message(&req_msg,
+ V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT))
+ pr_err("%s: Error in notifying the sof time for req id:%lld\n",
+ __func__, request_id);
+}
+
static int __cam_isp_ctx_reg_upd_in_activated_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
@@ -123,12 +191,15 @@
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
if (req_isp->num_fence_map_out != 0) {
- CDBG("%s: move request %lld to active list\n", __func__,
- req->request_id);
list_add_tail(&req->list, &ctx->active_req_list);
+ ctx_isp->active_req_cnt++;
+ CDBG("%s: move request %lld to active list(cnt = %d)\n",
+ __func__, req->request_id, ctx_isp->active_req_cnt);
} else {
/* no io config, so the request is completed. */
list_add_tail(&req->list, &ctx->free_req_list);
+ CDBG("%s: move active request %lld to free list(cnt = %d)\n",
+ __func__, req->request_id, ctx_isp->active_req_cnt);
}
/*
@@ -145,12 +216,20 @@
static int __cam_isp_ctx_notify_sof_in_actived_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
- int rc = 0;
struct cam_req_mgr_sof_notify notify;
struct cam_context *ctx = ctx_isp->base;
+ struct cam_ctx_request *req;
+ uint64_t request_id = 0;
- /* notify reqmgr with sof signal */
- if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) {
+ /*
+ * notify reqmgr with sof signal. Note, due to scheduling delay
+ * we can run into situation that two active requests has already
+ * be in the active queue while we try to do the notification.
+ * In this case, we need to skip the current notification. This
+ * helps the state machine to catch up the delay.
+ */
+ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof &&
+ ctx_isp->active_req_cnt <= 2) {
notify.link_hdl = ctx->link_hdl;
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
@@ -158,21 +237,40 @@
ctx->ctx_crm_intf->notify_sof(¬ify);
CDBG("%s: Notify CRM SOF frame %lld\n", __func__,
ctx_isp->frame_id);
+
+ list_for_each_entry(req, &ctx->active_req_list, list) {
+ if (req->request_id > ctx_isp->reported_req_id) {
+ request_id = req->request_id;
+ ctx_isp->reported_req_id = request_id;
+ break;
+ }
+ }
+
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+ CAM_REQ_MGR_SOF_EVENT_SUCCESS);
} else {
pr_err("%s: Can not notify SOF to CRM\n", __func__);
}
- return rc;
+ return 0;
}
-static int __cam_isp_ctx_sof_in_sof(struct cam_isp_context *ctx_isp,
- void *evt_data)
+static int __cam_isp_ctx_sof_in_activated_state(
+ struct cam_isp_context *ctx_isp, void *evt_data)
{
int rc = 0;
+ struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
- CDBG("%s: Enter\n", __func__);
+ if (!evt_data) {
+ pr_err("%s: in valid sof event data\n", __func__);
+ return -EINVAL;
+ }
+
ctx_isp->frame_id++;
+ ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
+ CDBG("%s: frame id: %lld time stamp:0x%llx\n", __func__,
+ ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
return rc;
}
@@ -199,11 +297,15 @@
struct cam_ctx_request, list);
list_del_init(&req->list);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
- if (req_isp->num_fence_map_out == req_isp->num_acked)
+ if (req_isp->num_fence_map_out == req_isp->num_acked) {
list_add_tail(&req->list, &ctx->free_req_list);
- else {
+ } else {
/* need to handle the buf done */
list_add_tail(&req->list, &ctx->active_req_list);
+ ctx_isp->active_req_cnt++;
+ CDBG("%s: move request %lld to active list(cnt = %d)\n",
+ __func__, req->request_id,
+ ctx_isp->active_req_cnt);
ctx_isp->substate_activated =
CAM_ISP_CTX_ACTIVATED_EPOCH;
}
@@ -215,10 +317,10 @@
static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
void *evt_data)
{
- int rc = 0;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
+ uint64_t request_id = 0;
if (list_empty(&ctx->pending_req_list)) {
/*
@@ -227,6 +329,11 @@
*/
pr_err("%s: No pending request\n", __func__);
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
+
+ /* Send SOF event as empty frame*/
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+ CAM_REQ_MGR_SOF_EVENT_SUCCESS);
+
goto end;
}
@@ -253,14 +360,21 @@
*/
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->active_req_list);
+ ctx_isp->active_req_cnt++;
+ CDBG("%s: move request %lld to active list(cnt = %d)\n",
+ __func__, req->request_id, ctx_isp->active_req_cnt);
req_isp->bubble_report = 0;
}
+ request_id = req->request_id;
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+ CAM_REQ_MGR_SOF_EVENT_ERROR);
+
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
CDBG("%s: next substate %d\n", __func__,
ctx_isp->substate_activated);
end:
- return rc;
+ return 0;
}
@@ -280,14 +394,22 @@
void *evt_data)
{
int rc = 0;
- struct cam_context *ctx = ctx_isp->base;
+ struct cam_context *ctx = ctx_isp->base;
+ struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
+ if (!evt_data) {
+ pr_err("%s: in valid sof event data\n", __func__);
+ return -EINVAL;
+ }
ctx_isp->frame_id++;
+ ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
+
if (list_empty(&ctx->active_req_list))
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
else
CDBG("%s: Still need to wait for the buf done\n", __func__);
+
CDBG("%s: next substate %d\n", __func__,
ctx_isp->substate_activated);
@@ -305,14 +427,6 @@
return rc;
}
-
-static int __cam_isp_ctx_sof_in_bubble(struct cam_isp_context *ctx_isp,
- void *evt_data)
-{
- ctx_isp->frame_id++;
- return 0;
-}
-
static int __cam_isp_ctx_buf_done_in_bubble(
struct cam_isp_context *ctx_isp, void *evt_data)
{
@@ -324,20 +438,13 @@
return rc;
}
-static int __cam_isp_ctx_sof_in_bubble_applied(
- struct cam_isp_context *ctx_isp, void *evt_data)
-{
- ctx_isp->frame_id++;
- return 0;
-}
-
-
static int __cam_isp_ctx_epoch_in_bubble_applied(
struct cam_isp_context *ctx_isp, void *evt_data)
{
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_context *ctx = ctx_isp->base;
+ uint64_t request_id = 0;
/*
* This means we missed the reg upd ack. So we need to
@@ -350,6 +457,9 @@
* Just go back to the bubble state.
*/
pr_err("%s: No pending request.\n", __func__);
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+ CAM_REQ_MGR_SOF_EVENT_SUCCESS);
+
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
goto end;
}
@@ -376,9 +486,16 @@
*/
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->active_req_list);
+ ctx_isp->active_req_cnt++;
+ CDBG("%s: move request %lld to active list(cnt = %d)\n",
+ __func__, req->request_id, ctx_isp->active_req_cnt);
req_isp->bubble_report = 0;
}
+ request_id = req->request_id;
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
+ CAM_REQ_MGR_SOF_EVENT_ERROR);
+
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated);
end:
@@ -457,7 +574,7 @@
{
.irq_ops = {
NULL,
- __cam_isp_ctx_sof_in_sof,
+ __cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_sof,
__cam_isp_ctx_notify_sof_in_actived_state,
NULL,
@@ -468,7 +585,7 @@
{
.irq_ops = {
__cam_isp_ctx_handle_error,
- __cam_isp_ctx_sof_in_sof,
+ __cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_activated_state,
__cam_isp_ctx_epoch_in_applied,
NULL,
@@ -490,7 +607,7 @@
{
.irq_ops = {
NULL,
- __cam_isp_ctx_sof_in_bubble,
+ __cam_isp_ctx_sof_in_activated_state,
NULL,
__cam_isp_ctx_notify_sof_in_actived_state,
NULL,
@@ -501,7 +618,7 @@
{
.irq_ops = {
NULL,
- __cam_isp_ctx_sof_in_bubble_applied,
+ __cam_isp_ctx_sof_in_activated_state,
__cam_isp_ctx_reg_upd_in_activated_state,
__cam_isp_ctx_epoch_in_bubble_applied,
NULL,
@@ -518,7 +635,6 @@
uint32_t next_state)
{
int rc = 0;
- int cnt = 0;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
struct cam_isp_context *ctx_isp;
@@ -537,13 +653,12 @@
* The maximum number of request allowed to be outstanding is 2.
*
*/
- list_for_each_entry(req, &ctx->active_req_list, list) {
- if (++cnt > 2) {
- pr_err_ratelimited("%s: Apply failed due to congest\n",
- __func__);
- rc = -EFAULT;
- goto end;
- }
+ ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
+ if (ctx_isp->active_req_cnt >= 2) {
+ CDBG("%s: Reject apply request due to congestion(cnt = %d)\n",
+ __func__, ctx_isp->active_req_cnt);
+ rc = -EFAULT;
+ goto end;
}
req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
@@ -560,7 +675,6 @@
CDBG("%s: Apply request %lld\n", __func__, req->request_id);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
- ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
req_isp->bubble_report = apply->report_if_bubble;
@@ -712,6 +826,8 @@
ctx->state = CAM_CTX_ACQUIRED;
spin_unlock(&ctx->lock);
+ trace_cam_context_state("ISP", ctx);
+
CDBG("%s: Flush request in ready state. next state %d\n",
__func__, ctx->state);
return rc;
@@ -786,6 +902,8 @@
ctx->link_hdl = 0;
ctx->ctx_crm_intf = NULL;
ctx_isp->frame_id = 0;
+ ctx_isp->active_req_cnt = 0;
+ ctx_isp->reported_req_id = 0;
/*
* Ideally, we should never have any active request here.
@@ -803,6 +921,8 @@
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, &flush_req);
ctx->state = CAM_CTX_AVAILABLE;
+
+ trace_cam_context_state("ISP", ctx);
CDBG("%s: next state %d\n", __func__, ctx->state);
return rc;
}
@@ -855,7 +975,7 @@
CDBG("%s: packet address is 0x%llx\n", __func__, packet_addr);
CDBG("%s: packet with length %zu, offset 0x%llx\n", __func__,
len, cmd->offset);
- CDBG("%s: Packet request id 0x%llx\n", __func__,
+ CDBG("%s: Packet request id %lld\n", __func__,
packet->header.request_id);
CDBG("%s: Packet size 0x%x\n", __func__, packet->header.size);
CDBG("%s: packet op %d\n", __func__, packet->header.op_code);
@@ -1011,6 +1131,7 @@
ctx->state = CAM_CTX_ACQUIRED;
+ trace_cam_context_state("ISP", ctx);
CDBG("%s:%d: Acquire success.\n", __func__, __LINE__);
kfree(isp_res);
return rc;
@@ -1032,8 +1153,10 @@
rc = __cam_isp_ctx_config_dev_in_top_state(ctx, cmd);
- if (!rc && ctx->link_hdl)
+ if (!rc && ctx->link_hdl) {
ctx->state = CAM_CTX_READY;
+ trace_cam_context_state("ISP", ctx);
+ }
CDBG("%s: next state %d\n", __func__, ctx->state);
return rc;
@@ -1050,8 +1173,10 @@
ctx->ctx_crm_intf = link->crm_cb;
/* change state only if we had the init config */
- if (!list_empty(&ctx->pending_req_list))
+ if (!list_empty(&ctx->pending_req_list)) {
ctx->state = CAM_CTX_READY;
+ trace_cam_context_state("ISP", ctx);
+ }
CDBG("%s: next state %d\n", __func__, ctx->state);
@@ -1121,6 +1246,8 @@
arg.num_hw_update_entries = req_isp->num_cfg;
ctx_isp->frame_id = 0;
+ ctx_isp->active_req_cnt = 0;
+ ctx_isp->reported_req_id = 0;
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/*
@@ -1129,11 +1256,13 @@
* irq handling comes early
*/
ctx->state = CAM_CTX_ACTIVATED;
+ trace_cam_context_state("ISP", ctx);
rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, &arg);
if (rc) {
/* HW failure. user need to clean up the resource */
pr_err("Start HW failed\n");
ctx->state = CAM_CTX_READY;
+ trace_cam_context_state("ISP", ctx);
goto end;
}
CDBG("%s: start device success\n", __func__);
@@ -1149,6 +1278,7 @@
ctx->link_hdl = 0;
ctx->ctx_crm_intf = NULL;
ctx->state = CAM_CTX_ACQUIRED;
+ trace_cam_context_state("ISP", ctx);
return rc;
}
@@ -1209,6 +1339,8 @@
list_add_tail(&req->list, &ctx->free_req_list);
}
ctx_isp->frame_id = 0;
+ ctx_isp->active_req_cnt = 0;
+ ctx_isp->reported_req_id = 0;
CDBG("%s: next state %d", __func__, ctx->state);
return rc;
@@ -1221,6 +1353,7 @@
__cam_isp_ctx_stop_dev_in_activated_unlock(ctx);
ctx->state = CAM_CTX_ACQUIRED;
+ trace_cam_context_state("ISP", ctx);
return rc;
}
@@ -1248,6 +1381,7 @@
ctx->ctx_crm_intf = NULL;
ctx->state = CAM_CTX_AVAILABLE;
+ trace_cam_context_state("ISP", ctx);
return rc;
}
@@ -1259,8 +1393,9 @@
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv;
- CDBG("%s: Enter: apply req in Substate %d\n",
- __func__, ctx_isp->substate_activated);
+ trace_cam_apply_req("ISP", apply);
+ CDBG("%s: Enter: apply req in Substate %d request _id:%lld\n",
+ __func__, ctx_isp->substate_activated, apply->request_id);
if (ctx_isp->substate_machine[ctx_isp->substate_activated].
crm_ops.apply_req) {
rc = ctx_isp->substate_machine[ctx_isp->substate_activated].
@@ -1288,6 +1423,10 @@
(struct cam_isp_context *)ctx->ctx_priv;
spin_lock_bh(&ctx->lock);
+
+ trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
+ __cam_isp_ctx_get_event_ts(evt_id, evt_data));
+
CDBG("%s: Enter: State %d, Substate %d, evt id %d\n",
__func__, ctx->state, ctx_isp->substate_activated, evt_id);
if (ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
@@ -1383,6 +1522,8 @@
ctx->base = ctx_base;
ctx->frame_id = 0;
+ ctx->active_req_cnt = 0;
+ ctx->reported_req_id = 0;
ctx->hw_ctx = NULL;
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
ctx->substate_machine = cam_isp_ctx_activated_state_machine;
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
index dae1dda..b0b883c 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
@@ -106,7 +106,9 @@
* @req_base: Common request object storage
* @req_isp: ISP private request object storage
* @hw_ctx: HW object returned by the acquire device command
- *
+ * @sof_timestamp_val: Captured time stamp value at sof hw event
+ * @active_req_cnt: Counter for the active request
+ * @reported_req_id: Last reported request id
*/
struct cam_isp_context {
struct cam_context *base;
@@ -120,6 +122,9 @@
struct cam_isp_ctx_req req_isp[CAM_CTX_REQ_MAX];
void *hw_ctx;
+ uint64_t sof_timestamp_val;
+ int32_t active_req_cnt;
+ int64_t reported_req_id;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/Makefile b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/Makefile
index 2c6eaba..7e3c353 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/Makefile
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/Makefile
@@ -7,6 +7,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += hw_utils/ isp_hw/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_isp_hw_mgr.o cam_ife_hw_mgr.o
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 2bc4b00..cb38d8f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -489,6 +489,7 @@
continue;
vfe_acquire.vfe_out.cdm_ops = ife_ctx->cdm_ops;
+ vfe_acquire.vfe_out.ctx = ife_ctx;
vfe_acquire.vfe_out.out_port_info = out_port;
vfe_acquire.vfe_out.split_id = CAM_ISP_HW_SPLIT_LEFT;
vfe_acquire.vfe_out.unique_id = ife_ctx->ctx_index;
@@ -552,6 +553,7 @@
vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_OUT;
vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
vfe_acquire.vfe_out.cdm_ops = ife_ctx->cdm_ops;
+ vfe_acquire.vfe_out.ctx = ife_ctx;
vfe_acquire.vfe_out.out_port_info = out_port;
vfe_acquire.vfe_out.is_dual = ife_src_res->is_dual_vfe;
vfe_acquire.vfe_out.unique_id = ife_ctx->ctx_index;
@@ -1334,7 +1336,7 @@
return -EPERM;
}
- CDBG("%s%d: Enter...ctx id:%d\n", __func__, __LINE__, ctx->ctx_index);
+ CDBG("%s:%d Enter ctx id:%d\n", __func__, __LINE__, ctx->ctx_index);
if (cfg->num_hw_update_entries > 0) {
cdm_cmd = ctx->cdm_cmd;
@@ -1980,6 +1982,57 @@
return rc;
}
+static int cam_ife_mgr_cmd_get_sof_timestamp(
+ struct cam_ife_hw_mgr_ctx *ife_ctx,
+ uint64_t *time_stamp)
+{
+ int rc = -EINVAL;
+ uint32_t i;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ struct cam_csid_get_time_stamp_args csid_get_time;
+
+ list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i] ||
+ (i == CAM_ISP_HW_SPLIT_RIGHT))
+ continue;
+ /*
+ * Get the SOF time stamp from left resource only.
+ * Left resource is master for dual vfe case and
+ * Rdi only context case left resource only hold
+ * the RDI resource
+ */
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf->hw_ops.process_cmd) {
+ csid_get_time.node_res =
+ hw_mgr_res->hw_res[i];
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_IFE_CSID_CMD_GET_TIME_STAMP,
+ &csid_get_time,
+ sizeof(
+ struct cam_csid_get_time_stamp_args));
+ if (!rc)
+ *time_stamp =
+ csid_get_time.time_stamp_val;
+ /*
+ * Single VFE case, Get the time stamp from available
+ * one csid hw in the context
+ * Dual VFE case, get the time stamp from master(left)
+ * would be sufficient
+ */
+ goto end;
+ }
+ }
+ }
+end:
+ if (rc)
+ pr_err("%s:error in getting sof time stamp\n", __func__);
+
+ return rc;
+}
+
static int cam_ife_mgr_process_recovery_cb(void *priv, void *data)
{
int32_t rc = 0;
@@ -2326,7 +2379,9 @@
}
- CDBG("%s: Exit (rup_status = %d)!\n", __func__, rup_status);
+ if (!rup_status)
+ CDBG("%s: Exit rup_status = %d\n", __func__, rup_status);
+
return 0;
}
@@ -2470,7 +2525,9 @@
}
}
- CDBG("%s: Exit (epoch_status = %d)!\n", __func__, epoch_status);
+ if (!epoch_status)
+ CDBG("%s: Exit epoch_status = %d\n", __func__, epoch_status);
+
return 0;
}
@@ -2566,11 +2623,16 @@
if (core_idx == hw_res_l->hw_intf->hw_idx) {
sof_status = hw_res_l->bottom_half_handler(
hw_res_l, evt_payload);
- if (!sof_status)
+ if (!sof_status) {
+ cam_ife_mgr_cmd_get_sof_timestamp(
+ ife_hwr_mgr_ctx,
+ &sof_done_event_data.timestamp);
+
ife_hwr_irq_sof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_SOF,
&sof_done_event_data);
+ }
}
break;
@@ -2617,12 +2679,16 @@
rc = cam_ife_hw_mgr_check_sof_for_dual_vfe(
ife_hwr_mgr_ctx, core_index0, core_index1);
- if (!rc)
+ if (!rc) {
+ cam_ife_mgr_cmd_get_sof_timestamp(
+ ife_hwr_mgr_ctx,
+ &sof_done_event_data.timestamp);
+
ife_hwr_irq_sof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_SOF,
&sof_done_event_data);
-
+ }
break;
default:
@@ -2640,11 +2706,11 @@
{
int32_t buf_done_status = 0;
- int32_t i = 0;
+ int32_t i;
int32_t rc = 0;
cam_hw_event_cb_func ife_hwr_irq_wm_done_cb;
struct cam_isp_resource_node *hw_res_l = NULL;
- struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx = handler_priv;
+ struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx = NULL;
struct cam_vfe_bus_irq_evt_payload *evt_payload = payload;
struct cam_ife_hw_mgr_res *isp_ife_out_res = NULL;
struct cam_hw_event_recovery_data recovery_data;
@@ -2655,6 +2721,7 @@
CDBG("%s:Enter\n", __func__);
+ ife_hwr_mgr_ctx = evt_payload->ctx;
ife_hwr_irq_wm_done_cb =
ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE];
@@ -2734,13 +2801,11 @@
}
break;
}
- CDBG("%s:buf_done status:(%d),isp_ife_out_res->res_id : 0x%x\n",
- __func__, buf_done_status, isp_ife_out_res->res_id);
+ if (!buf_done_status)
+ CDBG("buf_done status:(%d),out_res->res_id: 0x%x\n",
+ buf_done_status, isp_ife_out_res->res_id);
}
-
- CDBG("%s: Exit (buf_done_status (Success) = %d)!\n", __func__,
- buf_done_status);
return rc;
err:
@@ -2775,7 +2840,7 @@
return rc;
evt_payload = evt_payload_priv;
- ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)handler_priv;
+ ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)evt_payload->ctx;
CDBG("addr of evt_payload = %llx\n", (uint64_t)evt_payload);
CDBG("bus_irq_status_0: = %x\n", evt_payload->irq_reg_val[0]);
@@ -2786,19 +2851,6 @@
CDBG("bus_irq_dual_comp_err: = %x\n", evt_payload->irq_reg_val[5]);
CDBG("bus_irq_dual_comp_owrt: = %x\n", evt_payload->irq_reg_val[6]);
- /*
- * If overflow/overwrite/error/violation are pending
- * for this context it needs to be handled remaining
- * interrupts are ignored.
- */
- rc = cam_ife_hw_mgr_handle_camif_error(ife_hwr_mgr_ctx,
- evt_payload_priv);
- if (rc) {
- pr_err("%s: Encountered Error (%d), ignoring other irqs\n",
- __func__, rc);
- return IRQ_HANDLED;
- }
-
CDBG("%s: Calling Buf_done\n", __func__);
/* WM Done */
return cam_ife_hw_mgr_handle_buf_done_for_hw_res(ife_hwr_mgr_ctx,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/Makefile b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/Makefile
index 19da180..b60e7de 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/Makefile
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/Makefile
@@ -6,6 +6,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_tasklet_util.o cam_isp_packet_parser.o
obj-$(CONFIG_SPECTRA_CAMERA) += irq_controller/
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index bf4d174..9a42b6e 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -271,14 +271,6 @@
return -EINVAL;
}
- if (sizeof(evt_bit_mask_arr) !=
- sizeof(uint32_t) * controller->num_registers) {
- pr_err("Invalid evt_mask size = %lu expected = %lu\n",
- sizeof(evt_bit_mask_arr),
- sizeof(uint32_t) * controller->num_registers);
- return -EINVAL;
- }
-
evt_handler = kzalloc(sizeof(struct cam_irq_evt_handler), GFP_KERNEL);
if (!evt_handler) {
CDBG("Error allocating hlist_node\n");
@@ -306,6 +298,8 @@
evt_handler->bottom_half = bottom_half;
evt_handler->bottom_half_enqueue_func = bottom_half_enqueue_func;
evt_handler->index = controller->hdl_idx++;
+
+ /* Avoid rollover to negative values */
if (controller->hdl_idx > 0x3FFFFFFF)
controller->hdl_idx = 1;
@@ -468,7 +462,8 @@
(void *)th_payload);
if (!rc && evt_handler->bottom_half_handler) {
- CDBG("Enqueuing bottom half\n");
+ CDBG("Enqueuing bottom half for %s\n",
+ controller->name);
if (evt_handler->bottom_half_enqueue_func) {
evt_handler->bottom_half_enqueue_func(
evt_handler->bottom_half,
@@ -492,6 +487,8 @@
if (!controller)
return IRQ_NONE;
+ CDBG("locking controller %pK name %s rw_lock %pK\n",
+ controller, controller->name, &controller->rw_lock);
read_lock(&controller->rw_lock);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_status_arr[i] = cam_io_r_mb(
@@ -500,7 +497,8 @@
cam_io_w_mb(controller->irq_status_arr[i],
controller->mem_base +
controller->irq_register_arr[i].clear_reg_offset);
- CDBG("Read irq status%d = 0x%x\n", i,
+ CDBG("Read irq status%d (0x%x) = 0x%x\n", i,
+ controller->irq_register_arr[i].status_reg_offset,
controller->irq_status_arr[i]);
for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
if (controller->irq_register_arr[i].
@@ -512,6 +510,8 @@
}
}
read_unlock(&controller->rw_lock);
+ CDBG("unlocked controller %pK name %s rw_lock %pK\n",
+ controller, controller->name, &controller->rw_lock);
CDBG("Status Registers read Successful\n");
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
index 9f2204b4..b32bdb2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
@@ -50,32 +50,32 @@
/**
* struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
*
- * @timestamp: Timestamp for the buf done event
+ * @timestamp: Time stamp for the sof event
*
*/
struct cam_isp_hw_sof_event_data {
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
* struct cam_isp_hw_reg_update_event_data - Event payload for
* CAM_HW_EVENT_REG_UPDATE
*
- * @timestamp: Timestamp for the buf done event
+ * @timestamp: Time stamp for the reg update event
*
*/
struct cam_isp_hw_reg_update_event_data {
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
* struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH
*
- * @timestamp: Timestamp for the buf done event
+ * @timestamp: Time stamp for the epoch event
*
*/
struct cam_isp_hw_epoch_event_data {
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
@@ -90,29 +90,29 @@
uint32_t num_handles;
uint32_t resource_handle[
CAM_NUM_OUT_PER_COMP_IRQ_MAX];
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
* struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF
*
- * @timestamp: Timestamp for the buf done event
+ * @timestamp: Timestamp for the eof event
*
*/
struct cam_isp_hw_eof_event_data {
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
* struct cam_isp_hw_error_event_data - Event payload for CAM_HW_EVENT_ERROR
*
- * @error_type: error type for the error event
- * @timestamp: Timestamp for the buf done event
+ * @error_type: Error type for the error event
+ * @timestamp: Timestamp for the error event
*
*/
struct cam_isp_hw_error_event_data {
uint32_t error_type;
- struct timeval timestamp;
+ uint64_t timestamp;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index f09fdc7..e779aef 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -1033,7 +1033,7 @@
val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
(csid_hw->csi2_rx_cfg.lane_cfg << 4) |
(csid_hw->csi2_rx_cfg.lane_type << 24);
- val |= csid_hw->csi2_rx_cfg.phy_sel & 0x3;
+ val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
@@ -1150,6 +1150,10 @@
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_ipp_cfg0_addr);
+ /* select the post irq sub sample strobe for time stamp capture */
+ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_ipp_cfg1_addr);
+
if (path_data->crop_enable) {
val = ((path_data->width +
path_data->start_pixel) & 0xFFFF <<
@@ -1435,6 +1439,10 @@
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
+ /* select the post irq sub sample strobe for time stamp capture */
+ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
+
if (path_data->crop_enable) {
val = ((path_data->width +
path_data->start_pixel) & 0xFFFF <<
@@ -2220,7 +2228,6 @@
csid_hw_info = (struct cam_hw_info *)hw_priv;
csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
- mutex_lock(&csid_hw->hw_info->hw_mutex);
switch (cmd_type) {
case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
@@ -2231,7 +2238,6 @@
rc = -EINVAL;
break;
}
- mutex_unlock(&csid_hw->hw_info->hw_mutex);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index d36c576..60e184b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -65,6 +65,7 @@
#define CSID_PATH_ERROR_PIX_COUNT BIT(13)
#define CSID_PATH_ERROR_LINE_COUNT BIT(14)
+/* enum cam_csid_path_halt_mode select the path halt mode control */
enum cam_csid_path_halt_mode {
CSID_HALT_MODE_INTERNAL,
CSID_HALT_MODE_GLOBAL,
@@ -72,6 +73,16 @@
CSID_HALT_MODE_SLAVE,
};
+/**
+ *enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to
+ * capture the timestamp
+ */
+enum cam_csid_path_timestamp_stb_sel {
+ CSID_TIMESTAMP_STB_PRE_HALT,
+ CSID_TIMESTAMP_STB_POST_HALT,
+ CSID_TIMESTAMP_STB_POST_IRQ,
+ CSID_TIMESTAMP_STB_MAX,
+};
struct cam_ife_csid_ipp_reg_offset {
/*Image pixel path register offsets*/
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
index 15db6a6..418280a 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
@@ -108,6 +108,7 @@
* (Default is Master in case of Single VFE)
* @dual_slave_core: If Master and Slave exists, HW Index of Slave
* @cdm_ops: CDM operations
+ * @ctx: Context data
*/
struct cam_vfe_hw_vfe_out_acquire_args {
struct cam_isp_resource_node *rsrc_node;
@@ -118,6 +119,7 @@
uint32_t is_master;
uint32_t dual_slave_core;
struct cam_cdm_utils_ops *cdm_ops;
+ void *ctx;
};
/*
@@ -192,22 +194,21 @@
*
* @list: list_head node for the payload
* @core_index: Index of VFE HW that generated this IRQ event
- * @core_info: Private data of handler in bottom half context
* @evt_id: IRQ event
* @irq_reg_val: IRQ and Error register values, read when IRQ was
* handled
* @error_type: Identify different errors
* @ts: Timestamp
+ * @ctx: Context data received during acquire
*/
struct cam_vfe_bus_irq_evt_payload {
- struct list_head list;
- uint32_t core_index;
- void *core_info;
- uint32_t evt_id;
- uint32_t irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX];
- uint32_t error_type;
- struct cam_vfe_bus_ver2_priv *bus_priv;
- struct cam_isp_timestamp ts;
+ struct list_head list;
+ uint32_t core_index;
+ uint32_t evt_id;
+ uint32_t irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX];
+ uint32_t error_type;
+ struct cam_isp_timestamp ts;
+ void *ctx;
};
/*
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index f6aab7f..e25d973 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -51,11 +51,6 @@
0x00000000,
};
-static uint32_t bus_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
- 0x00000200,
- 0x00000000,
-};
-
static int cam_vfe_get_evt_payload(struct cam_vfe_hw_core_info *core_info,
struct cam_vfe_top_irq_evt_payload **evt_payload)
{
@@ -188,15 +183,25 @@
CDBG("Enable soc done\n");
+ rc = core_info->vfe_bus->hw_ops.init(core_info->vfe_bus->bus_priv,
+ NULL, 0);
+ if (rc) {
+ pr_err("Bus HW init Failed rc=%d\n", rc);
+ goto disable_soc;
+ }
+
/* Do HW Reset */
rc = cam_vfe_reset(hw_priv, NULL, 0);
if (rc) {
- pr_err("Reset Failed\n");
- goto disable_soc;
+ pr_err("Reset Failed rc=%d\n", rc);
+ goto deinit_bus;
}
return 0;
+deinit_bus:
+ core_info->vfe_bus->hw_ops.deinit(core_info->vfe_bus->bus_priv,
+ NULL, 0);
disable_soc:
cam_vfe_disable_soc_resources(soc_info);
decrement_open_cnt:
@@ -382,10 +387,11 @@
rc = core_info->vfe_top->hw_ops.reserve(
core_info->vfe_top->top_priv,
acquire,
- sizeof(acquire));
+ sizeof(*acquire));
else if (acquire->rsrc_type == CAM_ISP_RESOURCE_VFE_OUT)
- rc = core_info->vfe_bus->acquire_resource(
- core_info->vfe_bus->bus_priv, acquire);
+ rc = core_info->vfe_bus->hw_ops.reserve(
+ core_info->vfe_bus->bus_priv, acquire,
+ sizeof(*acquire));
else
pr_err("Invalid res type:%d\n", acquire->rsrc_type);
@@ -415,10 +421,11 @@
if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN)
rc = core_info->vfe_top->hw_ops.release(
core_info->vfe_top->top_priv, isp_res,
- sizeof(struct cam_isp_resource_node));
+ sizeof(*isp_res));
else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT)
- rc = core_info->vfe_bus->release_resource(
- core_info->vfe_bus->bus_priv, isp_res);
+ rc = core_info->vfe_bus->hw_ops.release(
+ core_info->vfe_bus->bus_priv, isp_res,
+ sizeof(*isp_res));
else
pr_err("Invalid res type:%d\n", isp_res->res_type);
@@ -468,16 +475,7 @@
else
pr_err("Error! subscribe irq controller failed\n");
} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
- isp_res->irq_handle = cam_irq_controller_subscribe_irq(
- core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_2,
- bus_irq_reg_mask, &core_info->irq_payload,
- core_info->vfe_bus->top_half_handler,
- cam_ife_mgr_do_tasklet_buf_done,
- isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
- if (isp_res->irq_handle > 0)
- rc = core_info->vfe_bus->start_resource(isp_res);
- else
- pr_err("Error! subscribe irq controller failed\n");
+ rc = core_info->vfe_bus->hw_ops.start(isp_res, NULL, 0);
} else {
pr_err("Invalid res type:%d\n", isp_res->res_type);
}
@@ -513,7 +511,7 @@
} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
cam_irq_controller_unsubscribe_irq(
core_info->vfe_irq_controller, isp_res->irq_handle);
- rc = core_info->vfe_bus->stop_resource(isp_res);
+ rc = core_info->vfe_bus->hw_ops.stop(isp_res, NULL, 0);
} else {
pr_err("Invalid res type:%d\n", isp_res->res_type);
}
@@ -560,7 +558,7 @@
break;
case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
- rc = core_info->vfe_bus->process_cmd(
+ rc = core_info->vfe_bus->hw_ops.process_cmd(
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
arg_size);
break;
@@ -611,15 +609,15 @@
&core_info->vfe_top);
if (rc) {
pr_err("Error! cam_vfe_top_init failed\n");
- return rc;
+ goto deinit_controller;
}
- rc = cam_vfe_bus_init(vfe_hw_info->bus_version,
- soc_info->reg_map[0].mem_base, hw_intf,
- vfe_hw_info->bus_hw_info, NULL, &core_info->vfe_bus);
+ rc = cam_vfe_bus_init(vfe_hw_info->bus_version, soc_info, hw_intf,
+ vfe_hw_info->bus_hw_info, core_info->vfe_irq_controller,
+ &core_info->vfe_bus);
if (rc) {
pr_err("Error! cam_vfe_bus_init failed\n");
- return rc;
+ goto deinit_top;
}
INIT_LIST_HEAD(&core_info->free_payload_list);
@@ -632,4 +630,46 @@
spin_lock_init(&core_info->spin_lock);
return rc;
+
+deinit_top:
+ cam_vfe_top_deinit(vfe_hw_info->top_version,
+ &core_info->vfe_top);
+
+deinit_controller:
+ cam_irq_controller_deinit(&core_info->vfe_irq_controller);
+
+ return rc;
}
+
+int cam_vfe_core_deinit(struct cam_vfe_hw_core_info *core_info,
+ struct cam_vfe_hw_info *vfe_hw_info)
+{
+ int rc = -EINVAL;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&core_info->spin_lock, flags);
+
+ INIT_LIST_HEAD(&core_info->free_payload_list);
+ for (i = 0; i < CAM_VFE_EVT_MAX; i++)
+ INIT_LIST_HEAD(&core_info->evt_payload[i].list);
+
+ rc = cam_vfe_bus_deinit(vfe_hw_info->bus_version,
+ &core_info->vfe_bus);
+ if (rc)
+ pr_err("Error cam_vfe_bus_deinit failed rc=%d\n", rc);
+
+ rc = cam_vfe_top_deinit(vfe_hw_info->top_version,
+ &core_info->vfe_top);
+ if (rc)
+ pr_err("Error cam_vfe_top_deinit failed rc=%d\n", rc);
+
+ rc = cam_irq_controller_deinit(&core_info->vfe_irq_controller);
+ if (rc)
+ pr_err("Error cam_irq_controller_deinit failed rc=%d\n", rc);
+
+ spin_unlock_irqrestore(&core_info->spin_lock, flags);
+
+ return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
index 94b4cf0..ee29e1cf 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h
@@ -89,4 +89,7 @@
struct cam_hw_intf *hw_intf,
struct cam_vfe_hw_info *vfe_hw_info);
+int cam_vfe_core_deinit(struct cam_vfe_hw_core_info *core_info,
+ struct cam_vfe_hw_info *vfe_hw_info);
+
#endif /* _CAM_VFE_CORE_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c
index 40279ae..cdb8d6f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c
@@ -88,14 +88,14 @@
rc = cam_vfe_init_soc_resources(&vfe_hw->soc_info, cam_vfe_irq,
vfe_hw);
if (rc < 0) {
- pr_err("Failed to init soc\n");
+ pr_err("Failed to init soc rc=%d\n", rc);
goto free_core_info;
}
rc = cam_vfe_core_init(core_info, &vfe_hw->soc_info,
vfe_hw_intf, hw_info);
if (rc < 0) {
- pr_err("Failed to init core\n");
+ pr_err("Failed to init core rc=%d\n", rc);
goto deinit_soc;
}
@@ -115,6 +115,8 @@
return rc;
deinit_soc:
+ if (cam_vfe_deinit_soc_resources(&vfe_hw->soc_info))
+ pr_err("Failed to deinit soc\n");
free_core_info:
kfree(vfe_hw->core_info);
free_vfe_hw:
@@ -125,6 +127,60 @@
return rc;
}
+int cam_vfe_remove(struct platform_device *pdev)
+{
+ struct cam_hw_info *vfe_hw = NULL;
+ struct cam_hw_intf *vfe_hw_intf = NULL;
+ struct cam_vfe_hw_core_info *core_info = NULL;
+ int rc = 0;
+
+ vfe_hw_intf = platform_get_drvdata(pdev);
+ if (!vfe_hw_intf) {
+ pr_err("Error! No data in pdev\n");
+ return -EINVAL;
+ }
+
+ CDBG("type %d index %d\n", vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
+
+ if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
+ cam_vfe_hw_list[vfe_hw_intf->hw_idx] = NULL;
+
+ vfe_hw = vfe_hw_intf->hw_priv;
+ if (!vfe_hw) {
+ pr_err("Error! HW data is NULL\n");
+ rc = -ENODEV;
+ goto free_vfe_hw_intf;
+ }
+
+ core_info = (struct cam_vfe_hw_core_info *)vfe_hw->core_info;
+ if (!core_info) {
+ pr_err("Error! core data NULL");
+ rc = -EINVAL;
+ goto deinit_soc;
+ }
+
+ rc = cam_vfe_core_deinit(core_info, core_info->vfe_hw_info);
+ if (rc < 0)
+ pr_err("Failed to deinit core rc=%d\n", rc);
+
+ kfree(vfe_hw->core_info);
+
+deinit_soc:
+ rc = cam_vfe_deinit_soc_resources(&vfe_hw->soc_info);
+ if (rc < 0)
+ pr_err("Failed to deinit soc rc=%d\n", rc);
+
+ mutex_destroy(&vfe_hw->hw_mutex);
+ kfree(vfe_hw);
+
+ CDBG("VFE%d remove successful\n", vfe_hw_intf->hw_idx);
+
+free_vfe_hw_intf:
+ kfree(vfe_hw_intf);
+
+ return rc;
+}
+
int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.h
index ca54d81..9e73528 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.h
@@ -27,4 +27,16 @@
*/
int cam_vfe_probe(struct platform_device *pdev);
+/*
+ * cam_vfe_remove()
+ *
+ * @brief: Driver remove function
+ *
+ * @pdev: Platform Device pointer
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
+ */
+int cam_vfe_remove(struct platform_device *pdev);
+
#endif /* _CAM_VFE_DEV_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
index 9f8f8c5..fa9d86b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
@@ -25,7 +25,7 @@
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc) {
- pr_err("Error! get DT properties failed\n");
+ pr_err("Error! get DT properties failed rc=%d\n", rc);
return rc;
}
@@ -40,6 +40,19 @@
rc = cam_soc_util_request_platform_resource(soc_info, vfe_irq_handler,
irq_data);
+ if (rc)
+ pr_err("Error! Request platform resource failed rc=%d\n", rc);
+
+ return rc;
+}
+
+static int cam_vfe_release_platform_resource(struct cam_hw_soc_info *soc_info)
+{
+ int rc = 0;
+
+ rc = cam_soc_util_release_platform_resource(soc_info);
+ if (rc)
+ pr_err("Error! Release platform resource failed rc=%d\n", rc);
return rc;
}
@@ -61,14 +74,14 @@
rc = cam_vfe_get_dt_properties(soc_info);
if (rc < 0) {
- pr_err("Error! Get DT properties failed\n");
+ pr_err("Error! Get DT properties failed rc=%d\n", rc);
goto free_soc_private;
}
rc = cam_vfe_request_platform_resource(soc_info, vfe_irq_handler,
irq_data);
if (rc < 0) {
- pr_err("Error! Request platform resources failed\n");
+ pr_err("Error! Request platform resources failed rc=%d\n", rc);
goto free_soc_private;
}
@@ -79,7 +92,7 @@
cpas_register_param.dev = &soc_info->pdev->dev;
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
- pr_err("CPAS registration failed\n");
+ pr_err("CPAS registration failed rc=%d\n", rc);
goto release_soc;
} else {
soc_private->cpas_handle = cpas_register_param.client_handle;
@@ -95,6 +108,35 @@
return rc;
}
+int cam_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
+{
+ int rc = 0;
+ struct cam_vfe_soc_private *soc_private;
+
+ if (!soc_info) {
+ pr_err("Error! soc_info NULL\n");
+ return -ENODEV;
+ }
+
+ soc_private = soc_info->soc_private;
+ if (!soc_private) {
+ pr_err("Error! soc_private NULL\n");
+ return -ENODEV;
+ }
+
+ rc = cam_cpas_unregister_client(soc_private->cpas_handle);
+ if (rc)
+ pr_err("CPAS unregistration failed rc=%d\n", rc);
+
+ rc = cam_vfe_release_platform_resource(soc_info);
+ if (rc < 0)
+ pr_err("Error! Release platform resources failed rc=%d\n", rc);
+
+ kfree(soc_private);
+
+ return rc;
+}
+
int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
@@ -117,7 +159,7 @@
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
- pr_err("Error! CPAS start failed.\n");
+ pr_err("Error! CPAS start failed rc=%d\n", rc);
rc = -EFAULT;
goto end;
}
@@ -125,7 +167,7 @@
rc = cam_soc_util_enable_platform_resource(soc_info, true,
CAM_TURBO_VOTE, true);
if (rc) {
- pr_err("Error! enable platform failed\n");
+ pr_err("Error! enable platform failed rc=%d\n", rc);
goto stop_cpas;
}
@@ -152,13 +194,13 @@
rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
if (rc) {
- pr_err("%s: disable platform failed\n", __func__);
+ pr_err("Disable platform failed rc=%d\n", rc);
return rc;
}
rc = cam_cpas_stop(soc_private->cpas_handle);
if (rc) {
- pr_err("Error! CPAS stop failed.\n");
+ pr_err("Error! CPAS stop failed rc=%d\n", rc);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h
index 27fb192..094c977 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h
@@ -45,6 +45,18 @@
irq_handler_t vfe_irq_handler, void *irq_data);
/*
+ * cam_vfe_deinit_soc_resources()
+ *
+ * @Brief: Deinitialize SOC resources including private data
+ *
+ * @soc_info: Device soc information
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
+ */
+int cam_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
+
+/*
* cam_vfe_enable_soc_resources()
*
* @brief: Enable regulator, irq resources, start CPAS
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.c
index 2245ab1..0ac5f6d 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.c
@@ -30,6 +30,7 @@
static struct platform_driver cam_vfe170_driver = {
.probe = cam_vfe_probe,
+ .remove = cam_vfe_remove,
.driver = {
.name = "cam_vfe170",
.owner = THIS_MODULE,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/Makefile b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/Makefile
index cea1137..4a328ee 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/Makefile
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/Makefile
@@ -1,7 +1,10 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cdm/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_core/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus.c
index 50952f8..63ca5c2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus.c
@@ -17,17 +17,17 @@
#include "cam_vfe_bus_ver2.h"
int cam_vfe_bus_init(uint32_t bus_version,
- void __iomem *mem_base,
+ struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *bus_hw_info,
void *vfe_irq_controller,
- struct cam_vfe_bus **vfe_bus)
+ struct cam_vfe_bus **vfe_bus)
{
int rc = -ENODEV;
switch (bus_version) {
case CAM_VFE_BUS_VER_2_0:
- rc = cam_vfe_bus_ver2_init(mem_base, hw_intf, bus_hw_info,
+ rc = cam_vfe_bus_ver2_init(soc_info, hw_intf, bus_hw_info,
vfe_irq_controller, vfe_bus);
break;
default:
@@ -37,3 +37,21 @@
return rc;
}
+
+int cam_vfe_bus_deinit(uint32_t bus_version,
+ struct cam_vfe_bus **vfe_bus)
+{
+ int rc = -ENODEV;
+
+ switch (bus_version) {
+ case CAM_VFE_BUS_VER_2_0:
+ rc = cam_vfe_bus_ver2_deinit(vfe_bus);
+ break;
+ default:
+ pr_err("Unsupported Bus Version %x\n", bus_version);
+ break;
+ }
+
+ return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index c4fae99..489689c 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -17,8 +17,10 @@
#include "cam_io_util.h"
#include "cam_cdm_util.h"
#include "cam_hw_intf.h"
+#include "cam_ife_hw_mgr.h"
#include "cam_vfe_hw_intf.h"
#include "cam_irq_controller.h"
+#include "cam_tasklet_util.h"
#include "cam_vfe_bus.h"
#include "cam_vfe_bus_ver2.h"
#include "cam_vfe_core.h"
@@ -26,28 +28,25 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
-#define FRAME_BASED_EN 0
+static const char drv_name[] = "vfe_bus";
+
+#define CAM_VFE_BUS_IRQ_REG0 0
+#define CAM_VFE_BUS_IRQ_REG1 1
+#define CAM_VFE_BUS_IRQ_REG2 2
+#define CAM_VFE_BUS_IRQ_MAX 3
+
+#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
#define MAX_BUF_UPDATE_REG_NUM \
(sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
#define MAX_REG_VAL_PAIR_SIZE \
- (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
+ (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
- do { \
- buf_array[index++] = offset; \
- buf_array[index++] = val; \
- } while (0)
-
-static uint32_t irq_reg_offset[CAM_IFE_BUS_IRQ_REGISTERS_MAX] = {
- 0x0000205C,
- 0x00002060,
- 0x00002064,
- 0x0000206C,
- 0x00002070,
- 0x00002074,
- 0x00002078,
-};
+ do { \
+ buf_array[index++] = offset; \
+ buf_array[index++] = val; \
+ } while (0)
enum cam_vfe_bus_packer_format {
PACKER_FMT_PLAIN_128 = 0x0,
@@ -70,23 +69,29 @@
};
struct cam_vfe_bus_ver2_common_data {
+ uint32_t core_index;
void __iomem *mem_base;
struct cam_hw_intf *hw_intf;
void *bus_irq_controller;
void *vfe_irq_controller;
struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
uint32_t io_buf_update[
- MAX_REG_VAL_PAIR_SIZE];
+ MAX_REG_VAL_PAIR_SIZE];
+
+ struct cam_vfe_bus_irq_evt_payload evt_payload[
+ CAM_VFE_BUS_VER2_PAYLOAD_MAX];
+ struct list_head free_payload_list;
};
struct cam_vfe_bus_ver2_wm_resource_data {
uint32_t index;
struct cam_vfe_bus_ver2_common_data *common_data;
struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
+ void *ctx;
uint32_t irq_enabled;
-
uint32_t init_cfg_done;
+
uint32_t offset;
uint32_t width;
uint32_t height;
@@ -127,6 +132,8 @@
uint32_t dual_slave_core;
uint32_t intra_client_mask;
uint32_t composite_mask;
+
+ void *ctx;
};
struct cam_vfe_bus_ver2_vfe_out_data {
@@ -147,7 +154,6 @@
struct cam_cdm_utils_ops *cdm_util_ops;
};
-
struct cam_vfe_bus_ver2_priv {
struct cam_vfe_bus_ver2_common_data common_data;
@@ -159,12 +165,59 @@
struct list_head free_dual_comp_grp;
struct list_head used_comp_grp;
- struct cam_vfe_bus_irq_evt_payload evt_payload[128];
- struct list_head free_payload_list;
+ uint32_t irq_handle;
};
+static int cam_vfe_bus_get_evt_payload(
+ struct cam_vfe_bus_ver2_common_data *common_data,
+ struct cam_vfe_bus_irq_evt_payload **evt_payload)
+{
+ if (list_empty(&common_data->free_payload_list)) {
+ *evt_payload = NULL;
+ pr_err("No free payload\n");
+ return -ENODEV;
+ }
+
+ *evt_payload = list_first_entry(&common_data->free_payload_list,
+ struct cam_vfe_bus_irq_evt_payload, list);
+ list_del_init(&(*evt_payload)->list);
+ return 0;
+}
+
static int cam_vfe_bus_put_evt_payload(void *core_info,
- struct cam_vfe_bus_irq_evt_payload **evt_payload);
+ struct cam_vfe_bus_irq_evt_payload **evt_payload)
+{
+ struct cam_vfe_bus_ver2_common_data *common_data = NULL;
+ uint32_t *ife_irq_regs = NULL;
+ uint32_t status_reg0, status_reg1, status_reg2;
+
+ if (!core_info) {
+ pr_err("Invalid param core_info NULL");
+ return -EINVAL;
+ }
+ if (*evt_payload == NULL) {
+ pr_err("No payload to put\n");
+ return -EINVAL;
+ }
+
+ ife_irq_regs = (*evt_payload)->irq_reg_val;
+ status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
+ status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
+ status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
+
+ if (status_reg0 || status_reg1 || status_reg2) {
+ CDBG("status0 0x%x status1 0x%x status2 0x%x\n",
+ status_reg0, status_reg1, status_reg2);
+ return 0;
+ }
+
+ common_data = core_info;
+ list_add_tail(&(*evt_payload)->list,
+ &common_data->free_payload_list);
+ *evt_payload = NULL;
+
+ return 0;
+}
static int cam_vfe_bus_ver2_get_intra_client_mask(
enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
@@ -371,7 +424,6 @@
case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
switch (format) {
case CAM_FORMAT_PLAIN64:
- case CAM_FORMAT_PLAIN128:
return 1;
default:
break;
@@ -583,7 +635,26 @@
switch (out_fmt) {
case CAM_FORMAT_NV21:
case CAM_FORMAT_NV12:
- return PACKER_FMT_PLAIN_8;
+ return PACKER_FMT_PLAIN_8_LSB_MSB_10;
+ case CAM_FORMAT_PLAIN16_16:
+ return PACKER_FMT_PLAIN_16_16BPP;
+ case CAM_FORMAT_PLAIN64:
+ return PACKER_FMT_PLAIN_64;
+ case CAM_FORMAT_MIPI_RAW_6:
+ case CAM_FORMAT_MIPI_RAW_8:
+ case CAM_FORMAT_MIPI_RAW_10:
+ case CAM_FORMAT_MIPI_RAW_12:
+ case CAM_FORMAT_MIPI_RAW_14:
+ case CAM_FORMAT_MIPI_RAW_16:
+ case CAM_FORMAT_MIPI_RAW_20:
+ case CAM_FORMAT_QTI_RAW_8:
+ case CAM_FORMAT_QTI_RAW_10:
+ case CAM_FORMAT_QTI_RAW_12:
+ case CAM_FORMAT_QTI_RAW_14:
+ case CAM_FORMAT_PLAIN128:
+ case CAM_FORMAT_PD8:
+ case CAM_FORMAT_PD10:
+ return PACKER_FMT_PLAIN_128;
default:
return PACKER_FMT_MAX;
}
@@ -592,6 +663,8 @@
static int cam_vfe_bus_acquire_wm(
struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
struct cam_isp_out_port_info *out_port_info,
+ void *tasklet,
+ void *ctx,
enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
enum cam_vfe_bus_plane_type plane,
enum cam_isp_hw_split_id split_id,
@@ -615,10 +688,12 @@
}
wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
+ wm_res_local->tasklet_info = tasklet;
wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
rsrc_data = wm_res_local->res_priv;
rsrc_data->irq_enabled = subscribe_irq;
+ rsrc_data->ctx = ctx;
rsrc_data->format = out_port_info->format;
rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
@@ -628,7 +703,6 @@
if (rsrc_data->index < 3) {
rsrc_data->width = rsrc_data->width * 5/4 * rsrc_data->height;
rsrc_data->height = 1;
- rsrc_data->pack_fmt = 0x0;
rsrc_data->en_cfg = 0x3;
} else if (rsrc_data->index < 5 ||
rsrc_data->index == 7 || rsrc_data->index == 8) {
@@ -664,18 +738,15 @@
pr_err("Invalid plane type %d\n", plane);
return -EINVAL;
}
- rsrc_data->pack_fmt = 0xE;
rsrc_data->en_cfg = 0x1;
} else if (rsrc_data->index >= 11) {
rsrc_data->width = 0;
rsrc_data->height = 0;
- rsrc_data->pack_fmt = 0x0;
rsrc_data->stride = 1;
rsrc_data->en_cfg = 0x3;
} else {
rsrc_data->width = rsrc_data->width * 4;
rsrc_data->height = rsrc_data->height / 2;
- rsrc_data->pack_fmt = 0x0;
rsrc_data->en_cfg = 0x1;
}
@@ -718,6 +789,8 @@
rsrc_data->ubwc_meta_offset = 0;
rsrc_data->init_cfg_done = 0;
rsrc_data->en_cfg = 0;
+
+ wm_res->tasklet_info = NULL;
wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
return 0;
@@ -730,6 +803,7 @@
wm_res->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
rsrc_data->common_data;
+ uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
@@ -753,6 +827,28 @@
cam_io_w(0x0,
common_data->mem_base + rsrc_data->hw_regs->framedrop_period);
+ /* Subscribe IRQ */
+ if (rsrc_data->irq_enabled) {
+ CDBG("Subscribe WM%d IRQ\n", rsrc_data->index);
+ bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
+ (1 << rsrc_data->index);
+ wm_res->irq_handle = cam_irq_controller_subscribe_irq(
+ common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
+ bus_irq_reg_mask, wm_res,
+ wm_res->top_half_handler,
+ cam_ife_mgr_do_tasklet_buf_done,
+ wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
+ if (wm_res->irq_handle < 0) {
+ pr_err("Subscribe IRQ failed for WM %d\n",
+ rsrc_data->index);
+ return -EFAULT;
+ }
+ }
+
+ /* Enable WM */
+ cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
+ rsrc_data->hw_regs->cfg);
+
CDBG("WM res %d width = %d, height = %d\n", rsrc_data->index,
rsrc_data->width, rsrc_data->height);
CDBG("WM res %d pk_fmt = %d\n", rsrc_data->index,
@@ -781,12 +877,10 @@
CDBG("irq_enabled %d", rsrc_data->irq_enabled);
/* Unsubscribe IRQ */
- if (rsrc_data->irq_enabled) {
- /*
- * Currently all WM IRQ are unsubscribed in one place. Need to
- * make it dynamic.
- */
- }
+ if (rsrc_data->irq_enabled)
+ rc = cam_irq_controller_unsubscribe_irq(
+ common_data->bus_irq_controller,
+ wm_res->irq_handle);
/* Halt & Reset WM */
cam_io_w_mb(BIT(rsrc_data->index),
@@ -800,7 +894,42 @@
static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
{
- return -EPERM;
+ int32_t rc;
+ int i;
+ struct cam_isp_resource_node *wm_res = NULL;
+ struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
+ struct cam_vfe_bus_irq_evt_payload *evt_payload;
+
+ wm_res = th_payload->handler_priv;
+ if (!wm_res) {
+ pr_err_ratelimited("Error! No resource\n");
+ return -ENODEV;
+ }
+
+ rsrc_data = wm_res->res_priv;
+
+ CDBG("IRQ status_0 = %x\n", th_payload->evt_status_arr[0]);
+ CDBG("IRQ status_1 = %x\n", th_payload->evt_status_arr[1]);
+
+ rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
+ if (rc) {
+ pr_err_ratelimited("No tasklet_cmd is free in queue\n");
+ return rc;
+ }
+
+ cam_isp_hw_get_timestamp(&evt_payload->ts);
+
+ evt_payload->ctx = rsrc_data->ctx;
+ evt_payload->core_index = rsrc_data->common_data->core_index;
+ evt_payload->evt_id = evt_id;
+
+ for (i = 0; i < th_payload->num_registers; i++)
+ evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
+
+ th_payload->evt_payload_priv = evt_payload;
+
+ CDBG("Exit\n");
+ return rc;
}
static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
@@ -825,9 +954,10 @@
~BIT(rsrc_data->index);
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
}
+ CDBG("status_reg %x rc %d\n", status_reg, rc);
if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
- cam_vfe_bus_put_evt_payload(evt_payload->core_info,
+ cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
&evt_payload);
return rc;
@@ -838,15 +968,13 @@
struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
struct cam_isp_resource_node *wm_res)
{
- int rc = 0;
struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
GFP_KERNEL);
if (!rsrc_data) {
- CDBG("Failed to alloc for wm res priv\n");
- rc = -ENOMEM;
- return rc;
+ CDBG("Failed to alloc for WM res priv\n");
+ return -ENOMEM;
}
wm_res->res_priv = rsrc_data;
@@ -863,7 +991,32 @@
wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
- return rc;
+ return 0;
+}
+
+static int cam_vfe_bus_deinit_wm_resource(
+ struct cam_isp_resource_node *wm_res)
+{
+ struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
+
+ wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
+ INIT_LIST_HEAD(&wm_res->list);
+
+ wm_res->start = NULL;
+ wm_res->stop = NULL;
+ wm_res->top_half_handler = NULL;
+ wm_res->bottom_half_handler = NULL;
+ wm_res->hw_intf = NULL;
+
+ rsrc_data = wm_res->res_priv;
+ wm_res->res_priv = NULL;
+ if (!rsrc_data) {
+ pr_err("Error! WM res priv is NULL\n");
+ return -ENOMEM;
+ }
+ kfree(rsrc_data);
+
+ return 0;
}
static void cam_vfe_bus_add_wm_to_comp_grp(
@@ -901,6 +1054,8 @@
static int cam_vfe_bus_acquire_comp_grp(
struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
struct cam_isp_out_port_info *out_port_info,
+ void *tasklet,
+ void *ctx,
uint32_t unique_id,
uint32_t is_dual,
uint32_t is_master,
@@ -942,6 +1097,7 @@
}
list_del(&comp_grp_local->list);
+ comp_grp_local->tasklet_info = tasklet;
comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
rsrc_data->is_master = is_master;
@@ -964,6 +1120,7 @@
}
}
+ rsrc_data->ctx = ctx;
*comp_grp = comp_grp_local;
return rc;
@@ -1017,6 +1174,7 @@
in_rsrc_data->composite_mask = 0;
in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
+ comp_grp->tasklet_info = NULL;
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
return 0;
@@ -1029,11 +1187,7 @@
comp_grp->res_priv;
struct cam_vfe_bus_ver2_common_data *common_data =
rsrc_data->common_data;
-
- /*
- * Individual Comp_Grp Subscribe IRQ can be done here once
- * dynamic IRQ enable support is added.
- */
+ uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
rsrc_data->hw_regs->comp_mask);
@@ -1055,9 +1209,30 @@
cam_io_w_mb(intra_client_en, common_data->mem_base +
common_data->common_reg->dual_master_comp_cfg);
+
+ bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
+ } else {
+ /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
+ bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
+ (1 << (rsrc_data->comp_grp_type + 5));
+ }
+
+ /* Subscribe IRQ */
+ CDBG("Subscribe COMP_GRP%d IRQ\n", rsrc_data->comp_grp_type);
+ comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
+ common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
+ bus_irq_reg_mask, comp_grp,
+ comp_grp->top_half_handler,
+ cam_ife_mgr_do_tasklet_buf_done,
+ comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
+ if (comp_grp->irq_handle < 0) {
+ pr_err("Subscribe IRQ failed for comp_grp %d\n",
+ rsrc_data->comp_grp_type);
+ return -EFAULT;
}
comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
+
return rc;
}
@@ -1070,6 +1245,9 @@
rsrc_data->common_data;
/* Unsubscribe IRQ */
+ rc = cam_irq_controller_unsubscribe_irq(
+ common_data->bus_irq_controller,
+ comp_grp->irq_handle);
cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
rsrc_data->hw_regs->comp_mask);
@@ -1097,7 +1275,42 @@
static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
{
- return -EPERM;
+ int32_t rc;
+ int i;
+ struct cam_isp_resource_node *comp_grp = NULL;
+ struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
+ struct cam_vfe_bus_irq_evt_payload *evt_payload;
+
+ comp_grp = th_payload->handler_priv;
+ if (!comp_grp) {
+ pr_err_ratelimited("Error! No resource\n");
+ return -ENODEV;
+ }
+
+ rsrc_data = comp_grp->res_priv;
+
+ CDBG("IRQ status_0 = %x\n", th_payload->evt_status_arr[0]);
+ CDBG("IRQ status_1 = %x\n", th_payload->evt_status_arr[1]);
+
+ rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
+ if (rc) {
+ pr_err_ratelimited("No tasklet_cmd is free in queue\n");
+ return rc;
+ }
+
+ cam_isp_hw_get_timestamp(&evt_payload->ts);
+
+ evt_payload->ctx = rsrc_data->ctx;
+ evt_payload->core_index = rsrc_data->common_data->core_index;
+ evt_payload->evt_id = evt_id;
+
+ for (i = 0; i < th_payload->num_registers; i++)
+ evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
+
+ th_payload->evt_payload_priv = evt_payload;
+
+ CDBG("Exit\n");
+ return rc;
}
static int cam_vfe_bus_handle_comp_done_bottom_half(
@@ -1113,12 +1326,13 @@
uint32_t comp_err_reg;
uint32_t comp_grp_id;
+ CDBG("comp grp type %d\n", rsrc_data->comp_grp_type);
+
if (!evt_payload)
return rc;
cam_ife_irq_regs = evt_payload->irq_reg_val;
- CDBG("comp grp type %d\n", rsrc_data->comp_grp_type);
switch (rsrc_data->comp_grp_type) {
case CAM_VFE_BUS_VER2_COMP_GRP_0:
case CAM_VFE_BUS_VER2_COMP_GRP_1:
@@ -1155,8 +1369,8 @@
rc = CAM_VFE_IRQ_STATUS_SUCCESS;
}
- CDBG("status reg = 0x%x, bit index = %d\n",
- status_reg, (comp_grp_id + 5));
+ CDBG("status reg = 0x%x, bit index = %d rc %d\n",
+ status_reg, (comp_grp_id + 5), rc);
break;
case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
@@ -1197,11 +1411,13 @@
break;
default:
rc = CAM_VFE_IRQ_STATUS_ERR;
+ pr_err("Error! Invalid comp_grp_type %u\n",
+ rsrc_data->comp_grp_type);
break;
}
if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
- cam_vfe_bus_put_evt_payload(evt_payload->core_info,
+ cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
&evt_payload);
return rc;
@@ -1212,8 +1428,7 @@
struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
struct cam_isp_resource_node *comp_grp)
{
- struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
- comp_grp->res_priv;
+ struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
GFP_KERNEL);
@@ -1231,7 +1446,6 @@
rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
-
if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
list_add_tail(&comp_grp->list,
@@ -1250,7 +1464,34 @@
return 0;
}
-static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args)
+static int cam_vfe_bus_deinit_comp_grp(
+ struct cam_isp_resource_node *comp_grp)
+{
+ struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
+ comp_grp->res_priv;
+
+ comp_grp->start = NULL;
+ comp_grp->stop = NULL;
+ comp_grp->top_half_handler = NULL;
+ comp_grp->bottom_half_handler = NULL;
+ comp_grp->hw_intf = NULL;
+
+ list_del_init(&comp_grp->list);
+ comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
+
+ comp_grp->res_priv = NULL;
+
+ if (!rsrc_data) {
+ pr_err("Error! comp_grp_priv is NULL\n");
+ return -ENODEV;
+ }
+ kfree(rsrc_data);
+
+ return 0;
+}
+
+static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
+ uint32_t args_size)
{
int rc = -ENODEV;
int i;
@@ -1306,30 +1547,43 @@
CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
out_acquire_args->out_port_info,
+ acq_args->tasklet,
+ out_acquire_args->ctx,
out_acquire_args->unique_id,
out_acquire_args->is_dual,
out_acquire_args->is_master,
out_acquire_args->dual_slave_core,
&rsrc_data->comp_grp);
- if (rc < 0)
+ if (rc) {
+ pr_err("VFE%d Comp_Grp acquire failed for Out %d rc=%d\n",
+ rsrc_data->common_data->core_index,
+ vfe_out_res_id, rc);
return rc;
+ }
subscribe_irq = 0;
- } else
+ } else {
subscribe_irq = 1;
+ }
/* Reserve WM */
for (i = 0; i < num_wm; i++) {
rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
out_acquire_args->out_port_info,
+ acq_args->tasklet,
+ out_acquire_args->ctx,
vfe_out_res_id,
i,
out_acquire_args->split_id,
subscribe_irq,
&rsrc_data->wm_res[i],
&client_done_mask);
- if (rc < 0)
+ if (rc) {
+ pr_err("VFE%d WM acquire failed for Out %d rc=%d\n",
+ rsrc_data->common_data->core_index,
+ vfe_out_res_id, rc);
goto release_wm;
+ }
if (rsrc_data->comp_grp)
cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
@@ -1352,11 +1606,21 @@
return rc;
}
-static int cam_vfe_bus_release_vfe_out(void *bus_priv,
- struct cam_isp_resource_node *vfe_out)
+static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
+ uint32_t args_size)
{
uint32_t i;
- struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+ struct cam_isp_resource_node *vfe_out = NULL;
+ struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
+
+ if (!bus_priv || !release_args) {
+ pr_err("Invalid input bus_priv %pK release_args %pK\n",
+ bus_priv, release_args);
+ return -EINVAL;
+ }
+
+ vfe_out = release_args;
+ rsrc_data = vfe_out->res_priv;
if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
pr_err("Error! Invalid resource state:%d\n",
@@ -1381,12 +1645,20 @@
return 0;
}
-static int cam_vfe_bus_start_vfe_out(struct cam_isp_resource_node *vfe_out)
+static int cam_vfe_bus_start_vfe_out(
+ struct cam_isp_resource_node *vfe_out)
{
int rc = 0, i;
- struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
- struct cam_vfe_bus_ver2_common_data *common_data =
- rsrc_data->common_data;
+ struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
+ struct cam_vfe_bus_ver2_common_data *common_data = NULL;
+
+ if (!vfe_out) {
+ pr_err("Invalid input\n");
+ return -EINVAL;
+ }
+
+ rsrc_data = vfe_out->res_priv;
+ common_data = rsrc_data->common_data;
CDBG("Start resource index %d\n", rsrc_data->out_type);
@@ -1396,28 +1668,12 @@
return -EACCES;
}
- /* Enable IRQ Mask */
- cam_io_w_mb(0x00001FE0, common_data->mem_base + 0x2044);
- cam_io_w_mb(0x000FFFE7, common_data->mem_base + 0x2048);
- cam_io_w_mb(0x000000FF, common_data->mem_base + 0x204c);
-
for (i = 0; i < rsrc_data->num_wm; i++)
rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
if (rsrc_data->comp_grp)
rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
- /* VFE_MODULE_BUS_CGC_OVERRIDE */
- cam_io_w_mb(0xFFFFFFFF, rsrc_data->common_data->mem_base + 0x0000003C);
- /* VFE_MODULE_COLOR_CGC_OVERRIDE */
- cam_io_w_mb(0xFFFFFFFF, rsrc_data->common_data->mem_base + 0x00000034);
- /* VFE_MODULE_ZOOM_CGC_OVERRIDE */
- cam_io_w_mb(0xFFFFFFFF, rsrc_data->common_data->mem_base + 0x38);
- /* VFE_MODULE_LENS_CGC_OVERRIDE */
- cam_io_w_mb(0xFFFFFFFF, rsrc_data->common_data->mem_base + 0x0000002C);
- /* VFE_MODULE_STATS_CGC_OVERRIDE */
- cam_io_w_mb(0xFFFFFFFF, rsrc_data->common_data->mem_base + 0x00000030);
-
/* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
/* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
@@ -1440,13 +1696,22 @@
/* BUS_WR_TEST_BUS_CTRL */
cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
+ vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
return rc;
}
-static int cam_vfe_bus_stop_vfe_out(struct cam_isp_resource_node *vfe_out)
+static int cam_vfe_bus_stop_vfe_out(
+ struct cam_isp_resource_node *vfe_out)
{
int rc = 0, i;
- struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+ struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
+
+ if (!vfe_out) {
+ pr_err("Invalid input\n");
+ return -EINVAL;
+ }
+
+ rsrc_data = vfe_out->res_priv;
if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
@@ -1459,7 +1724,6 @@
for (i = 0; i < rsrc_data->num_wm; i++)
rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
- vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
return rc;
@@ -1533,122 +1797,39 @@
return 0;
}
-static int cam_vfe_bus_get_evt_payload(
- struct cam_vfe_bus_ver2_priv *bus_priv,
- struct cam_vfe_bus_irq_evt_payload **evt_payload)
+static int cam_vfe_bus_deinit_vfe_out_resource(
+ struct cam_isp_resource_node *vfe_out)
{
- if (list_empty(&bus_priv->free_payload_list)) {
- *evt_payload = NULL;
- pr_err("No free payload\n");
- return -ENODEV;
+ struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
+
+ vfe_out->start = NULL;
+ vfe_out->stop = NULL;
+ vfe_out->top_half_handler = NULL;
+ vfe_out->bottom_half_handler = NULL;
+ vfe_out->hw_intf = NULL;
+
+ vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
+ INIT_LIST_HEAD(&vfe_out->list);
+ vfe_out->res_priv = NULL;
+
+ if (!rsrc_data) {
+ pr_err("Error! vfe out priv is NULL\n");
+ return -ENOMEM;
}
+ kfree(rsrc_data);
- *evt_payload = list_first_entry(&bus_priv->free_payload_list,
- struct cam_vfe_bus_irq_evt_payload, list);
- list_del_init(&(*evt_payload)->list);
- return 0;
-}
-
-static int cam_vfe_bus_put_evt_payload(void *core_info,
- struct cam_vfe_bus_irq_evt_payload **evt_payload)
-{
- struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
- uint32_t *cam_ife_irq_regs = (*evt_payload)->irq_reg_val;
- uint32_t status_reg0, status_reg1;
-
- status_reg0 = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
- status_reg1 = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
-
- if (status_reg0 || status_reg1) {
- CDBG("status0 0x%x status1 0x%x\n", status_reg0, status_reg1);
- return 0;
- }
-
- if (!core_info) {
- pr_err("Invalid param core_info NULL");
- return -EINVAL;
- }
- if (*evt_payload == NULL) {
- pr_err("No payload to put\n");
- return -EINVAL;
- }
- bus_priv = (*evt_payload)->bus_priv;
- list_add_tail(&(*evt_payload)->list, &bus_priv->free_payload_list);
- *evt_payload = NULL;
return 0;
}
static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
struct cam_irq_th_payload *th_payload)
{
- int32_t rc;
- int i;
- struct cam_vfe_irq_handler_priv *handler_priv;
- struct cam_vfe_hw_core_info *core_info;
- struct cam_vfe_bus_irq_evt_payload *evt_payload;
- struct cam_vfe_bus *bus_info;
struct cam_vfe_bus_ver2_priv *bus_priv;
- struct cam_irq_controller_reg_info *reg_info;
- uint32_t irq_mask;
- int found = 0;
- handler_priv = th_payload->handler_priv;
- core_info = handler_priv->core_info;
- bus_info = core_info->vfe_bus;
- bus_priv = bus_info->bus_priv;
- reg_info = &bus_priv->common_data.common_reg->irq_reg_info;
-
- /*
- * add reset ack handling here once supported.
- * Just clear all the bus irq status registers and ignore the reset.
- */
-
+ bus_priv = th_payload->handler_priv;
CDBG("Enter\n");
- rc = cam_vfe_bus_get_evt_payload(bus_priv, &evt_payload);
- if (rc) {
- pr_err("No tasklet_cmd is free in queue\n");
- return rc;
- }
-
- cam_isp_hw_get_timestamp(&evt_payload->ts);
-
- evt_payload->core_index = handler_priv->core_index;
- evt_payload->core_info = handler_priv->core_info;
- evt_payload->bus_priv = bus_priv;
- CDBG("core_idx %d, core_info %llx\n", handler_priv->core_index,
- (uint64_t)handler_priv->core_info);
-
- for (i = 0; i < CAM_IFE_BUS_IRQ_REGISTERS_MAX; i++) {
- irq_mask = cam_io_r(handler_priv->mem_base +
- irq_reg_offset[i] - (0xC * 2));
- evt_payload->irq_reg_val[i] = irq_mask &
- cam_io_r(handler_priv->mem_base + irq_reg_offset[i]);
- if (evt_payload->irq_reg_val[i])
- found = 1;
- CDBG("irq_status%d = 0x%x\n", i, evt_payload->irq_reg_val[i]);
- }
- for (i = 0; i <= CAM_IFE_IRQ_BUS_REG_STATUS2; i++) {
- cam_io_w(evt_payload->irq_reg_val[i], handler_priv->mem_base +
- reg_info->irq_reg_set[i].clear_reg_offset);
- CDBG("Clear irq_status%d = 0x%x offset 0x%x\n", i,
- evt_payload->irq_reg_val[i],
- reg_info->irq_reg_set[i].clear_reg_offset);
- }
- cam_io_w(reg_info->global_clear_bitmask, handler_priv->mem_base +
- reg_info->global_clear_offset);
- CDBG("Global clear bitmask = 0x%x offset 0x%x\n",
- reg_info->global_clear_bitmask,
- reg_info->global_clear_offset);
-
- if (found)
- th_payload->evt_payload_priv = evt_payload;
- else {
- cam_vfe_bus_put_evt_payload(evt_payload->core_info,
- &evt_payload);
- rc = -ENOMSG;
- }
-
- return rc;
+ return cam_irq_controller_handle_irq(evt_id,
+ bus_priv->common_data.bus_irq_controller);
}
static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
@@ -1882,6 +2063,69 @@
return 0;
}
+static int cam_vfe_bus_start_hw(void *hw_priv,
+ void *start_hw_args, uint32_t arg_size)
+{
+ return cam_vfe_bus_start_vfe_out(hw_priv);
+}
+
+static int cam_vfe_bus_stop_hw(void *hw_priv,
+ void *stop_hw_args, uint32_t arg_size)
+{
+ return cam_vfe_bus_stop_vfe_out(hw_priv);
+}
+
+static int cam_vfe_bus_init_hw(void *hw_priv,
+ void *init_hw_args, uint32_t arg_size)
+{
+ struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
+ uint32_t top_irq_reg_mask[2] = {0};
+
+ if (!bus_priv) {
+ pr_err("Error! Invalid args\n");
+ return -EINVAL;
+ }
+
+ top_irq_reg_mask[0] = (1 << 9);
+
+ bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
+ bus_priv->common_data.vfe_irq_controller,
+ CAM_IRQ_PRIORITY_2,
+ top_irq_reg_mask,
+ bus_priv,
+ cam_vfe_bus_ver2_handle_irq,
+ NULL,
+ NULL,
+ NULL);
+
+ if (bus_priv->irq_handle <= 0) {
+ pr_err("Failed to subscribe BUS IRQ\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int cam_vfe_bus_deinit_hw(void *hw_priv,
+ void *deinit_hw_args, uint32_t arg_size)
+{
+ struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
+ int rc;
+
+ if (!bus_priv || (bus_priv->irq_handle <= 0)) {
+ pr_err("Error! Invalid args\n");
+ return -EINVAL;
+ }
+
+ rc = cam_irq_controller_unsubscribe_irq(
+ bus_priv->common_data.vfe_irq_controller,
+ bus_priv->irq_handle);
+ if (rc)
+ pr_err("Failed to unsubscribe irq rc=%d\n", rc);
+
+ return rc;
+}
+
static int cam_vfe_bus_process_cmd(void *priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -1906,7 +2150,7 @@
}
int cam_vfe_bus_ver2_init(
- void __iomem *mem_base,
+ struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *bus_hw_info,
void *vfe_irq_controller,
@@ -1919,11 +2163,18 @@
CDBG("Enter\n");
+ if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
+ pr_err("Error! Invalid params soc_info %pK hw_intf %pK hw_info %pK controller %pK\n",
+ soc_info, hw_intf, bus_hw_info, vfe_irq_controller);
+ rc = -EINVAL;
+ goto end;
+ }
+
vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
if (!vfe_bus_local) {
CDBG("Failed to alloc for vfe_bus\n");
rc = -ENOMEM;
- goto err_alloc_bus;
+ goto end;
}
bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
@@ -1931,15 +2182,25 @@
if (!bus_priv) {
CDBG("Failed to alloc for vfe_bus_priv\n");
rc = -ENOMEM;
- goto err_alloc_priv;
+ goto free_bus_local;
}
vfe_bus_local->bus_priv = bus_priv;
- bus_priv->common_data.mem_base = mem_base;
+ bus_priv->common_data.core_index = soc_info->index;
+ bus_priv->common_data.mem_base =
+ CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
bus_priv->common_data.hw_intf = hw_intf;
bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
+ rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
+ &ver2_hw_info->common_reg.irq_reg_info,
+ &bus_priv->common_data.bus_irq_controller);
+ if (rc) {
+ pr_err("Error! cam_irq_controller_init failed\n");
+ goto free_bus_priv;
+ }
+
INIT_LIST_HEAD(&bus_priv->free_comp_grp);
INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
INIT_LIST_HEAD(&bus_priv->used_comp_grp);
@@ -1948,8 +2209,8 @@
rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
&bus_priv->bus_client[i]);
if (rc < 0) {
- pr_err("Error! Init WM failed\n");
- goto err_init_wm;
+ pr_err("Error! Init WM failed rc=%d\n", rc);
+ goto deinit_wm;
}
}
@@ -1957,8 +2218,8 @@
rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
&bus_priv->comp_grp[i]);
if (rc < 0) {
- pr_err("Error! Init Comp Grp failed\n");
- goto err_init_comp_grp;
+ pr_err("Error! Init Comp Grp failed rc=%d\n", rc);
+ goto deinit_comp_grp;
}
}
@@ -1966,36 +2227,119 @@
rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
&bus_priv->vfe_out[i]);
if (rc < 0) {
- pr_err("Error! Init VFE Out failed\n");
- goto err_init_vfe_out;
+ pr_err("Error! Init VFE Out failed rc=%d\n", rc);
+ goto deinit_vfe_out;
}
}
- INIT_LIST_HEAD(&bus_priv->free_payload_list);
- for (i = 0; i < 128; i++) {
- INIT_LIST_HEAD(&bus_priv->evt_payload[i].list);
- list_add_tail(&bus_priv->evt_payload[i].list,
- &bus_priv->free_payload_list);
+ INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
+ for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
+ INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
+ list_add_tail(&bus_priv->common_data.evt_payload[i].list,
+ &bus_priv->common_data.free_payload_list);
}
- vfe_bus_local->acquire_resource = cam_vfe_bus_acquire_vfe_out;
- vfe_bus_local->release_resource = cam_vfe_bus_release_vfe_out;
- vfe_bus_local->start_resource = cam_vfe_bus_start_vfe_out;
- vfe_bus_local->stop_resource = cam_vfe_bus_stop_vfe_out;
- vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
+ vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
+ vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
+ vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
+ vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
+ vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
+ vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
+ vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
vfe_bus_local->bottom_half_handler = NULL;
- vfe_bus_local->process_cmd = cam_vfe_bus_process_cmd;
+ vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
*vfe_bus = vfe_bus_local;
+ CDBG("Exit\n");
return rc;
-err_init_vfe_out:
-err_init_comp_grp:
-err_init_wm:
+deinit_vfe_out:
+ if (i < 0)
+ i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
+ for (--i; i >= 0; i--)
+ cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
+
+deinit_comp_grp:
+ if (i < 0)
+ i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
+ for (--i; i >= 0; i--)
+ cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
+
+deinit_wm:
+ if (i < 0)
+ i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
+ for (--i; i >= 0; i--)
+ cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
+
+free_bus_priv:
kfree(vfe_bus_local->bus_priv);
-err_alloc_priv:
+
+free_bus_local:
kfree(vfe_bus_local);
-err_alloc_bus:
+
+end:
return rc;
}
+
+int cam_vfe_bus_ver2_deinit(
+ struct cam_vfe_bus **vfe_bus)
+{
+ int i, rc = 0;
+ struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
+ struct cam_vfe_bus *vfe_bus_local;
+
+ if (!vfe_bus || !*vfe_bus) {
+ pr_err("Error! Invalid input\n");
+ return -EINVAL;
+ }
+ vfe_bus_local = *vfe_bus;
+
+ bus_priv = vfe_bus_local->bus_priv;
+ if (!bus_priv) {
+ pr_err("Error! bus_priv is NULL\n");
+ rc = -ENODEV;
+ goto free_bus_local;
+ }
+
+ INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
+ for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
+ INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
+
+ for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
+ rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
+ if (rc < 0)
+ pr_err("Error! Deinit WM failed rc=%d\n", rc);
+ }
+
+ for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
+ rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
+ if (rc < 0)
+ pr_err("Error! Deinit Comp Grp failed rc=%d\n", rc);
+ }
+
+ for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
+ rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
+ if (rc < 0)
+ pr_err("Error! Deinit VFE Out failed rc=%d\n", rc);
+ }
+
+ INIT_LIST_HEAD(&bus_priv->free_comp_grp);
+ INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
+ INIT_LIST_HEAD(&bus_priv->used_comp_grp);
+
+ rc = cam_irq_controller_deinit(
+ &bus_priv->common_data.bus_irq_controller);
+ if (rc)
+ pr_err("Error! Deinit IRQ Controller failed rc=%d\n", rc);
+
+ kfree(vfe_bus_local->bus_priv);
+
+free_bus_local:
+ kfree(vfe_bus_local);
+
+ *vfe_bus = NULL;
+
+ return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h
index e451174..ba98077 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h
@@ -171,18 +171,34 @@
*
* @Brief: Initialize Bus layer
*
- * @mem_base: Mapped base address of register space
+ * @soc_info: Soc Information for the associated HW
* @hw_intf: HW Interface of HW to which this resource belongs
* @bus_hw_info: BUS HW info that contains details of BUS registers
* @vfe_irq_controller: VFE IRQ Controller to use for subscribing to Top
* level IRQs
* @vfe_bus: Pointer to vfe_bus structure which will be filled
* and returned on successful initialize
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
*/
-int cam_vfe_bus_ver2_init(void __iomem *mem_base,
+int cam_vfe_bus_ver2_init(
+ struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *bus_hw_info,
void *vfe_irq_controller,
struct cam_vfe_bus **vfe_bus);
+/*
+ * cam_vfe_bus_ver2_deinit()
+ *
+ * @Brief: Deinitialize Bus layer
+ *
+ * @vfe_bus: Pointer to vfe_bus structure to deinitialize
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
+ */
+int cam_vfe_bus_ver2_deinit(struct cam_vfe_bus **vfe_bus);
+
#endif /* _CAM_VFE_BUS_VER2_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/include/cam_vfe_bus.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/include/cam_vfe_bus.h
index d202c13..c089911 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/include/cam_vfe_bus.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/include/cam_vfe_bus.h
@@ -14,6 +14,7 @@
#define _CAM_VFE_BUS_H_
#include <uapi/media/cam_isp.h>
+#include "cam_hw_intf.h"
#include "cam_isp_hw.h"
#define CAM_VFE_BUS_VER_1_0 0x1000
@@ -31,25 +32,14 @@
* @Brief: Bus interface structure
*
* @bus_priv: Private data of BUS
- * @acquire_resource: Function pointer for acquiring BUS output resource
- * @release_resource: Function pointer for releasing BUS resource
- * @start_resource: Function for starting BUS Output resource
- * @stop_resource: Function for stopping BUS Output resource
- * @process_cmd: Function to process commands specific to BUS
- * resources
+ * @hw_ops: Hardware interface functions
* @top_half_handler: Top Half handler function
* @bottom_half_handler: Bottom Half handler function
*/
struct cam_vfe_bus {
void *bus_priv;
- int (*acquire_resource)(void *bus_priv, void *acquire_args);
- int (*release_resource)(void *bus_priv,
- struct cam_isp_resource_node *vfe_out);
- int (*start_resource)(struct cam_isp_resource_node *vfe_out);
- int (*stop_resource)(struct cam_isp_resource_node *vfe_out);
- int (*process_cmd)(void *priv, uint32_t cmd_type, void *cmd_args,
- uint32_t arg_size);
+ struct cam_hw_ops hw_ops;
CAM_IRQ_HANDLER_TOP_HALF top_half_handler;
CAM_IRQ_HANDLER_BOTTOM_HALF bottom_half_handler;
};
@@ -60,19 +50,36 @@
* @Brief: Initialize Bus layer
*
* @bus_version: Version of BUS to initialize
- * @mem_base: Mapped base address of register space
+ * @soc_info: Soc Information for the associated HW
* @hw_intf: HW Interface of HW to which this resource belongs
* @bus_hw_info: BUS HW info that contains details of BUS registers
* @vfe_irq_controller: VFE IRQ Controller to use for subscribing to Top
* level IRQs
* @vfe_bus: Pointer to vfe_bus structure which will be filled
* and returned on successful initialize
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
*/
int cam_vfe_bus_init(uint32_t bus_version,
- void __iomem *mem_base,
+ struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *bus_hw_info,
void *vfe_irq_controller,
struct cam_vfe_bus **vfe_bus);
+/*
+ * cam_vfe_bus_deinit()
+ *
+ * @Brief: Deinitialize Bus layer
+ *
+ * @bus_version: Version of BUS to deinitialize
+ * @vfe_bus: Pointer to vfe_bus structure to deinitialize
+ *
+ * @Return: 0: Success
+ * Non-zero: Failure
+ */
+int cam_vfe_bus_deinit(uint32_t bus_version,
+ struct cam_vfe_bus **vfe_bus);
+
#endif /* _CAM_VFE_BUS_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 6dd67df..fa00769 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -229,7 +229,7 @@
struct cam_vfe_camif_ver2_hw_info *camif_info = camif_hw_info;
camif_priv = kzalloc(sizeof(struct cam_vfe_mux_camif_data),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!camif_priv) {
CDBG("Error! Failed to alloc for camif_priv\n");
return -ENOMEM;
@@ -251,3 +251,24 @@
return 0;
}
+int cam_vfe_camif_ver2_deinit(
+ struct cam_isp_resource_node *camif_node)
+{
+ struct cam_vfe_mux_camif_data *camif_priv = camif_node->res_priv;
+
+ camif_node->start = NULL;
+ camif_node->stop = NULL;
+ camif_node->top_half_handler = NULL;
+ camif_node->bottom_half_handler = NULL;
+
+ camif_node->res_priv = NULL;
+
+ if (!camif_priv) {
+ pr_err("Error! camif_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ kfree(camif_priv);
+
+ return 0;
+}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
index cc6aab0..553abf2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.h
@@ -75,4 +75,7 @@
void *camif_hw_info,
struct cam_isp_resource_node *camif_node);
+int cam_vfe_camif_ver2_deinit(
+ struct cam_isp_resource_node *camif_node);
+
#endif /* _CAM_VFE_CAMIF_VER2_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
index 5f77a7c..f96f4d9 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
@@ -187,3 +187,23 @@
return 0;
}
+int cam_vfe_rdi_ver2_deinit(
+ struct cam_isp_resource_node *rdi_node)
+{
+ struct cam_vfe_mux_rdi_data *rdi_priv = rdi_node->res_priv;
+
+ rdi_node->start = NULL;
+ rdi_node->stop = NULL;
+ rdi_node->top_half_handler = NULL;
+ rdi_node->bottom_half_handler = NULL;
+
+ rdi_node->res_priv = NULL;
+
+ if (!rdi_priv) {
+ pr_err("Error! rdi_priv NULL\n");
+ return -ENODEV;
+ }
+ kfree(rdi_priv);
+
+ return 0;
+}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h
index 967cec3..9893474 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.h
@@ -43,4 +43,7 @@
void *rdi_hw_info,
struct cam_isp_resource_node *rdi_node);
+int cam_vfe_rdi_ver2_deinit(
+ struct cam_isp_resource_node *rdi_node);
+
#endif /* _CAM_VFE_RDI_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top.c
index e2bceb8..ee608fa 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top.c
@@ -36,3 +36,20 @@
return rc;
}
+int cam_vfe_top_deinit(uint32_t top_version,
+ struct cam_vfe_top **vfe_top)
+{
+ int rc = -EINVAL;
+
+ switch (top_version) {
+ case CAM_VFE_TOP_VER_2_0:
+ rc = cam_vfe_top_ver2_deinit(vfe_top);
+ break;
+ default:
+ pr_err("Error! Unsupported Version %x\n", top_version);
+ break;
+ }
+
+ return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 3ef4f49..ce7c63e 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -359,7 +359,7 @@
if (!vfe_top) {
CDBG("Error! Failed to alloc for vfe_top\n");
rc = -ENOMEM;
- goto err_alloc_top;
+ goto end;
}
top_priv = kzalloc(sizeof(struct cam_vfe_top_ver2_priv),
@@ -367,7 +367,7 @@
if (!top_priv) {
CDBG("Error! Failed to alloc for vfe_top_priv\n");
rc = -ENOMEM;
- goto err_alloc_priv;
+ goto free_vfe_top;
}
vfe_top->top_priv = top_priv;
@@ -384,16 +384,16 @@
&ver2_hw_info->camif_hw_info,
&top_priv->mux_rsrc[i]);
if (rc)
- goto err_mux_init;
+ goto deinit_resources;
} else {
/* set the RDI resource id */
top_priv->mux_rsrc[i].res_id =
- CAM_ISP_HW_VFE_IN_RDI0 + j;
+ CAM_ISP_HW_VFE_IN_RDI0 + j++;
+
rc = cam_vfe_rdi_ver2_init(hw_intf, soc_info,
NULL, &top_priv->mux_rsrc[i]);
if (rc)
goto deinit_resources;
- j++;
}
}
@@ -416,10 +416,71 @@
return rc;
deinit_resources:
-err_mux_init:
+ for (--i; i >= 0; i--) {
+ if (ver2_hw_info->mux_type[i] == CAM_VFE_CAMIF_VER_2_0) {
+ if (cam_vfe_camif_ver2_deinit(&top_priv->mux_rsrc[i]))
+ pr_err("Camif Deinit failed\n");
+ } else {
+ if (cam_vfe_rdi_ver2_deinit(&top_priv->mux_rsrc[i]))
+ pr_err("RDI Deinit failed\n");
+ }
+ top_priv->mux_rsrc[i].res_state =
+ CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
+ }
+
kfree(vfe_top->top_priv);
-err_alloc_priv:
+free_vfe_top:
kfree(vfe_top);
-err_alloc_top:
+end:
return rc;
}
+
+int cam_vfe_top_ver2_deinit(struct cam_vfe_top **vfe_top_ptr)
+{
+ int i, rc = 0;
+ struct cam_vfe_top_ver2_priv *top_priv = NULL;
+ struct cam_vfe_top *vfe_top;
+
+ if (!vfe_top_ptr) {
+ pr_err("Error! Invalid input\n");
+ return -EINVAL;
+ }
+
+ vfe_top = *vfe_top_ptr;
+ if (!vfe_top) {
+ pr_err("Error! vfe_top NULL\n");
+ return -ENODEV;
+ }
+
+ top_priv = vfe_top->top_priv;
+ if (!top_priv) {
+ pr_err("Error! vfe_top_priv NULL\n");
+ rc = -ENODEV;
+ goto free_vfe_top;
+ }
+
+ for (i = 0; i < CAM_VFE_TOP_VER2_MUX_MAX; i++) {
+ top_priv->mux_rsrc[i].res_state =
+ CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
+ if (top_priv->mux_rsrc[i].res_id ==
+ CAM_ISP_HW_VFE_IN_CAMIF) {
+ rc = cam_vfe_camif_ver2_deinit(&top_priv->mux_rsrc[i]);
+ if (rc)
+ pr_err("Error! Camif deinit failed rc=%d\n",
+ rc);
+ } else {
+ rc = cam_vfe_rdi_ver2_deinit(&top_priv->mux_rsrc[i]);
+ if (rc)
+ pr_err("Error! RDI deinit failed rc=%d\n", rc);
+ }
+ }
+
+ kfree(vfe_top->top_priv);
+
+free_vfe_top:
+ kfree(vfe_top);
+ *vfe_top_ptr = NULL;
+
+ return rc;
+}
+
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
index 1038721..0813202 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.h
@@ -58,6 +58,8 @@
int cam_vfe_top_ver2_init(struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *top_hw_info,
- struct cam_vfe_top **vfe_top);
+ struct cam_vfe_top **vfe_top);
+
+int cam_vfe_top_ver2_deinit(struct cam_vfe_top **vfe_top);
#endif /* _CAM_VFE_TOP_VER2_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h
index 44c046d..dbb211f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include/cam_vfe_top.h
@@ -50,4 +50,7 @@
void *top_hw_info,
struct cam_vfe_top **vfe_top);
+int cam_vfe_top_deinit(uint32_t top_version,
+ struct cam_vfe_top **vfe_top);
+
#endif /* _CAM_VFE_TOP_H_*/
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/Makefile b/drivers/media/platform/msm/camera/cam_req_mgr/Makefile
index e6da6ca..f514139 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/Makefile
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/Makefile
@@ -1,4 +1,6 @@
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_core/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_dev.o \
cam_req_mgr_util.o \
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
index edfc245..2f9db97 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
@@ -735,18 +735,19 @@
if (tbl.bufq[idx].i_hdl && tbl.bufq[idx].kmdvaddr)
ion_unmap_kernel(tbl.client, tbl.bufq[idx].i_hdl);
- if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_READ_WRITE ||
- tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) {
-
+ /* SHARED flag gets precedence, all other flags after it */
+ if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) {
+ region = CAM_SMMU_REGION_SHARED;
+ } else {
if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_READ_WRITE)
region = CAM_SMMU_REGION_IO;
-
- if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS)
- region = CAM_SMMU_REGION_SHARED;
-
- rc = cam_mem_util_unmap_hw_va(idx, region);
}
+ if (tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_READ_WRITE ||
+ tbl.bufq[idx].flags & CAM_MEM_FLAG_HW_SHARED_ACCESS)
+ rc = cam_mem_util_unmap_hw_va(idx, region);
+
+
mutex_lock(&tbl.bufq[idx].q_lock);
tbl.bufq[idx].flags = 0;
tbl.bufq[idx].buf_handle = -1;
@@ -820,15 +821,16 @@
uint32_t mem_handle;
int32_t smmu_hdl = 0;
int32_t num_hdl = 0;
- enum cam_smmu_region_id region;
+ enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED;
if (!inp || !out) {
pr_err("Invalid params\n");
return -EINVAL;
}
- if (inp->region != CAM_MEM_MGR_REGION_SHARED &&
- inp->region != CAM_MEM_MGR_REGION_NON_SECURE_IO) {
+ if (!(inp->flags & CAM_MEM_FLAG_HW_READ_WRITE ||
+ inp->flags & CAM_MEM_FLAG_HW_SHARED_ACCESS ||
+ inp->flags & CAM_MEM_FLAG_CACHE)) {
pr_err("Invalid flags for request mem\n");
return -EINVAL;
}
@@ -866,11 +868,13 @@
goto smmu_fail;
}
- if (inp->region == CAM_MEM_MGR_REGION_SHARED)
+ /* SHARED flag gets precedence, all other flags after it */
+ if (inp->flags & CAM_MEM_FLAG_HW_SHARED_ACCESS) {
region = CAM_SMMU_REGION_SHARED;
-
- if (inp->region == CAM_MEM_MGR_REGION_NON_SECURE_IO)
- region = CAM_SMMU_REGION_IO;
+ } else {
+ if (inp->flags & CAM_MEM_FLAG_HW_READ_WRITE)
+ region = CAM_SMMU_REGION_IO;
+ }
rc = cam_smmu_map_iova(inp->smmu_hdl,
ion_fd,
@@ -915,13 +919,13 @@
out->smmu_hdl = smmu_hdl;
out->mem_handle = mem_handle;
out->len = inp->size;
- out->region = inp->region;
+ out->region = region;
return rc;
slot_fail:
cam_smmu_unmap_iova(inp->smmu_hdl,
ion_fd,
- inp->region);
+ region);
smmu_fail:
ion_unmap_kernel(tbl.client, hdl);
map_fail:
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
index 32a754e..0858b8a 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr_api.h
@@ -14,13 +14,7 @@
#define _CAM_MEM_MGR_API_H_
#include <media/cam_req_mgr.h>
-
-/* Region IDs for memory manager */
-#define CAM_MEM_MGR_REGION_FIRMWARE 0
-#define CAM_MEM_MGR_REGION_SHARED 1
-#define CAM_MEM_MGR_REGION_NON_SECURE_IO 2
-#define CAM_MEM_MGR_REGION_SECURE_IO 3
-#define CAM_MEM_MGR_REGION_SCRATCH 4
+#include "cam_smmu_api.h"
/**
* struct cam_mem_mgr_request_desc
@@ -36,7 +30,6 @@
uint64_t align;
int32_t smmu_hdl;
uint32_t flags;
- uint32_t region;
};
/**
@@ -55,7 +48,7 @@
int32_t smmu_hdl;
uint32_t mem_handle;
uint64_t len;
- uint32_t region;
+ enum cam_smmu_region_id region;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index ed251eb..f5dfcf2 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -19,6 +19,7 @@
#include "cam_req_mgr_core.h"
#include "cam_req_mgr_workq.h"
#include "cam_req_mgr_debug.h"
+#include "cam_trace.h"
static struct cam_req_mgr_core_device *g_crm_core_dev;
@@ -975,7 +976,7 @@
* cam_req_mgr_process_flush_req()
*
* @brief: This runs in workque thread context. Call core funcs to check
- * which requests need to be removedcancelled.
+ * which requests need to be removed/cancelled.
* @priv : link information.
* @data : contains information about frame_id, link etc.
*
@@ -1007,6 +1008,8 @@
in_q = link->req.in_q;
+ trace_cam_flush_req(flush_info);
+
mutex_lock(&link->req.lock);
if (flush_info->flush_type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
for (i = 0; i < in_q->num_slots; i++) {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/Makefile
index 8670d80..4e8ea8b 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/Makefile
@@ -1,8 +1,10 @@
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_actuator_dev.o cam_actuator_core.o cam_actuator_soc.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
index 0a96f18..37dbf9e 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -13,7 +13,8 @@
#include <linux/module.h>
#include <cam_sensor_cmn_header.h>
#include "cam_actuator_core.h"
-#include <cam_sensor_util.h>
+#include "cam_sensor_util.h"
+#include "cam_trace.h"
int32_t cam_actuator_slaveInfo_pkt_parser(struct cam_actuator_ctrl_t *a_ctrl,
uint32_t *cmd_buf)
@@ -111,6 +112,9 @@
return -EINVAL;
}
request_id = apply->request_id % MAX_PER_FRAME_ARRAY;
+
+ trace_cam_apply_req("Actuator", apply);
+
CDBG("%s:%d Request Id: %lld\n",
__func__, __LINE__, apply->request_id);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c
index 48e3c2e..f8ea769 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_dev.c
@@ -14,6 +14,7 @@
#include "cam_req_mgr_dev.h"
#include "cam_actuator_soc.h"
#include "cam_actuator_core.h"
+#include "cam_trace.h"
static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/Makefile
index 57dfed5..ba81259 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/Makefile
@@ -3,5 +3,6 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_cci_dev.o cam_cci_core.o cam_cci_soc.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile
index 0337b32..8edbea5 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/Makefile
@@ -4,5 +4,6 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_csiphy_soc.o cam_csiphy_dev.o cam_csiphy_core.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 71a88bf..6b20bcc 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -37,7 +37,7 @@
base = soc_info->reg_map[0].mem_base;
for (i = 0; i < size; i++) {
- cam_io_w(
+ cam_io_w_mb(
csiphy_dev->ctrl_reg->
csiphy_reset_reg[i].reg_data,
base +
@@ -128,7 +128,7 @@
csiphy_dev->soc_info.reg_map[0].mem_base;
for (i = 0; i < csiphy_dev->num_irq_registers; i++)
- cam_io_w(csiphy_dev->ctrl_reg->
+ cam_io_w_mb(csiphy_dev->ctrl_reg->
csiphy_irq_reg[i].reg_data,
csiphybase +
csiphy_dev->ctrl_reg->
@@ -142,7 +142,7 @@
csiphy_dev->soc_info.reg_map[0].mem_base;
for (i = 0; i < csiphy_dev->num_irq_registers; i++)
- cam_io_w(0x0,
+ cam_io_w_mb(0x0,
csiphybase +
csiphy_dev->ctrl_reg->
csiphy_irq_reg[i].reg_addr);
@@ -171,22 +171,22 @@
base +
csiphy_dev->ctrl_reg->csiphy_reg.
mipi_csiphy_interrupt_status0_addr + 0x4*i);
- cam_io_w(irq,
+ cam_io_w_mb(irq,
base +
csiphy_dev->ctrl_reg->csiphy_reg.
mipi_csiphy_interrupt_clear0_addr + 0x4*i);
pr_err_ratelimited(
"%s CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x\n",
__func__, soc_info->index, i, irq);
- cam_io_w(0x0,
+ cam_io_w_mb(0x0,
base +
csiphy_dev->ctrl_reg->csiphy_reg.
mipi_csiphy_interrupt_clear0_addr + 0x4*i);
}
- cam_io_w(0x1, base +
+ cam_io_w_mb(0x1, base +
csiphy_dev->ctrl_reg->
csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
- cam_io_w(0x0, base +
+ cam_io_w_mb(0x0, base +
csiphy_dev->ctrl_reg->
csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
@@ -198,7 +198,8 @@
int32_t rc = 0;
uint32_t lane_enable = 0, mask = 1, size = 0;
uint16_t lane_mask = 0, i = 0, cfg_size = 0;
- uint8_t settle_cnt, lane_cnt, lane_pos = 0;
+ uint8_t lane_cnt, lane_pos = 0;
+ uint16_t settle_cnt = 0;
void __iomem *csiphybase;
struct csiphy_reg_t (*reg_array)[MAX_SETTINGS_PER_LANE];
@@ -257,13 +258,13 @@
switch (csiphy_dev->ctrl_reg->
csiphy_common_reg[i].csiphy_param_type) {
case CSIPHY_LANE_ENABLE:
- cam_io_w(lane_enable,
+ cam_io_w_mb(lane_enable,
csiphybase +
csiphy_dev->ctrl_reg->
csiphy_common_reg[i].reg_addr);
break;
case CSIPHY_DEFAULT_PARAMS:
- cam_io_w(csiphy_dev->ctrl_reg->
+ cam_io_w_mb(csiphy_dev->ctrl_reg->
csiphy_common_reg[i].reg_data,
csiphybase +
csiphy_dev->ctrl_reg->
@@ -284,22 +285,22 @@
for (i = 0; i < cfg_size; i++) {
switch (reg_array[lane_pos][i].csiphy_param_type) {
case CSIPHY_LANE_ENABLE:
- cam_io_w(lane_enable,
+ cam_io_w_mb(lane_enable,
csiphybase +
reg_array[lane_pos][i].reg_addr);
break;
case CSIPHY_DEFAULT_PARAMS:
- cam_io_w(reg_array[lane_pos][i].reg_data,
+ cam_io_w_mb(reg_array[lane_pos][i].reg_data,
csiphybase +
reg_array[lane_pos][i].reg_addr);
break;
case CSIPHY_SETTLE_CNT_LOWER_BYTE:
- cam_io_w(settle_cnt & 0xFF,
+ cam_io_w_mb(settle_cnt & 0xFF,
csiphybase +
reg_array[lane_pos][i].reg_addr);
break;
case CSIPHY_SETTLE_CNT_HIGHER_BYTE:
- cam_io_w((settle_cnt >> 8) & 0xFF,
+ cam_io_w_mb((settle_cnt >> 8) & 0xFF,
csiphybase +
reg_array[lane_pos][i].reg_addr);
break;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile
index d8c75fb..5a9441f 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile
@@ -1,8 +1,10 @@
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
-ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_dev.o cam_sensor_core.o cam_sensor_soc.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 031c340..be8306c 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -13,8 +13,9 @@
#include <linux/module.h>
#include <cam_sensor_cmn_header.h>
#include "cam_sensor_core.h"
-#include <cam_sensor_util.h>
+#include "cam_sensor_util.h"
#include "cam_soc_util.h"
+#include "cam_trace.h"
static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
void *arg)
@@ -1004,6 +1005,9 @@
}
CDBG("%s:%d Req Id: %lld\n", __func__, __LINE__,
apply->request_id);
+
+ trace_cam_apply_req("Sensor", apply);
+
rc = cam_sensor_apply_settings(s_ctrl, apply->request_id);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/Makefile
index 6292a9f..4c3b8e8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/Makefile
@@ -4,5 +4,6 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_io.o cam_sensor_cci_i2c.o cam_sensor_qup_i2c.o
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/Makefile b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/Makefile
index 770391c..bf61fb3 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/Makefile
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/Makefile
@@ -2,5 +2,6 @@
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io
ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_util.o
diff --git a/drivers/media/platform/msm/camera/cam_utils/Makefile b/drivers/media/platform/msm/camera/cam_utils/Makefile
index f22115c..370651f 100644
--- a/drivers/media/platform/msm/camera/cam_utils/Makefile
+++ b/drivers/media/platform/msm/camera/cam_utils/Makefile
@@ -1,3 +1,5 @@
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_core/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr/
+ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/
-obj-$(CONFIG_SPECTRA_CAMERA) += cam_soc_util.o cam_io_util.o cam_packet_util.o
+obj-$(CONFIG_SPECTRA_CAMERA) += cam_soc_util.o cam_io_util.o cam_packet_util.o cam_debug_util.o cam_trace.o
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c
new file mode 100644
index 0000000..eb5e7d8
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2017, The Linux Foundataion. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include "cam_debug_util.h"
+
+static const char *cam_debug_module_id_to_name(unsigned int module_id)
+{
+ const char *name = NULL;
+
+ switch (module_id) {
+ case CAM_CDM:
+ name = "CAM-CDM";
+ break;
+ case CAM_CORE:
+ name = "CAM-CORE";
+ break;
+ case CAM_CRM:
+ name = "CAM_CRM";
+ break;
+ case CAM_CPAS:
+ name = "CAM-CPAS";
+ break;
+ case CAM_ISP:
+ name = "CAM-ISP";
+ break;
+ case CAM_SENSOR:
+ name = "CAM-SENSOR";
+ break;
+ case CAM_SMMU:
+ name = "CAM-SMMU";
+ break;
+ case CAM_SYNC:
+ name = "CAM-SYNC";
+ break;
+ case CAM_ICP:
+ name = "CAM-ICP";
+ break;
+ case CAM_JPEG:
+ name = "CAM-JPEG";
+ break;
+ case CAM_FD:
+ name = "CAM-FD";
+ break;
+ case CAM_LRME:
+ name = "CAM-LRME";
+ break;
+ case CAM_FLASH:
+ name = "CAM-FLASH";
+ break;
+ default:
+ name = "CAM";
+ break;
+ }
+
+ return name;
+}
+
+void cam_debug_log(unsigned int module_id, enum cam_debug_level dbg_level,
+ const char *func, const int line, const char *fmt, ...)
+{
+ char str_buffer[STR_BUFFER_MAX_LENGTH];
+ const char *module_name;
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args);
+ va_end(args);
+
+ module_name = cam_debug_module_id_to_name(module_id);
+
+ switch (dbg_level) {
+ case CAM_LEVEL_INFO:
+ pr_info("CAM_INFO: %s: %s: %d: %s\n",
+ module_name, func, line, str_buffer);
+ break;
+ case CAM_LEVEL_WARN:
+ pr_warn("CAM_WARN: %s: %s: %d: %s\n",
+ module_name, func, line, str_buffer);
+ break;
+ case CAM_LEVEL_ERR:
+ pr_err("CAM_ERR: %s: %s: %d: %s\n",
+ module_name, func, line, str_buffer);
+ break;
+ case CAM_LEVEL_DBG:
+ pr_info("CAM_DBG: %s: %s: %d: %s\n",
+ module_name, func, line, str_buffer);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
index 5989f1a..34adb0e 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2017, The Linux Foundation. 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
@@ -13,7 +13,6 @@
#ifndef _CAM_DEBUG_UTIL_H_
#define _CAM_DEBUG_UTIL_H_
-#define DEFAULT 0xFFFF
#define CAM_CDM (1 << 0)
#define CAM_CORE (1 << 1)
#define CAM_CPAS (1 << 2)
@@ -26,32 +25,91 @@
#define CAM_JPEG (1 << 9)
#define CAM_FD (1 << 10)
#define CAM_LRME (1 << 11)
+#define CAM_FLASH (1 << 12)
-#define GROUP DEFAULT
-#define TRACE_ON 0
+#define STR_BUFFER_MAX_LENGTH 1024
+#define GROUP 0x0000
-#define CAM_ERR(__module, fmt, args...) \
- do { if (GROUP & __module) { \
- if (TRACE_ON) \
- trace_printk(fmt, ##args); \
- else \
- pr_err(fmt, ##args); \
- } } while (0)
+enum cam_debug_level {
+ CAM_LEVEL_INFO,
+ CAM_LEVEL_WARN,
+ CAM_LEVEL_ERR,
+ CAM_LEVEL_DBG,
+};
-#define CAM_WARN(__module, fmt, args...) \
- do { if (GROUP & __module) { \
- if (TRACE_ON) \
- trace_printk(fmt, ##args); \
- else \
- pr_warn(fmt, ##args); \
- } } while (0)
+/*
+ * cam_debug_log()
+ *
+ * @brief: Get the Module name form module ID and print
+ * respective debug logs
+ *
+ * @module_id : Respective Module ID which is calling this function
+ * @dbg_level : Debug level from cam_module_debug_level enum entries
+ * @func : Function which is calling to print logs
+ * @line : Line number associated with the function which is calling
+ * to print log
+ * @fmt : Formatted string which needs to be print in the log
+ *
+ */
+void cam_debug_log(unsigned int module_id, enum cam_debug_level dbg_level,
+ const char *func, const int line, const char *fmt, ...);
-#define CAM_INFO(__module, fmt, args...) \
- do { if (GROUP & __module) { \
- if (TRACE_ON) \
- trace_printk(fmt, ##args); \
- else \
- pr_info(fmt, ##args); \
- } } while (0)
+/*
+ * CAM_ERR
+ * @brief : This Macro will print error logs
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @fmt : Formatted string which needs to be print in log
+ * @args: Arguments which needs to be print in log
+ */
+#define CAM_ERR(__module, fmt, args...) \
+ { \
+ cam_debug_log(__module, CAM_LEVEL_ERR, \
+ __func__, __LINE__, fmt, ##args); \
+ }
+
+/*
+ * CAM_WARN
+ * @brief : This Macro will print warning logs
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @fmt : Formatted string which needs to be print in log
+ * @args : Arguments which needs to be print in log
+ */
+#define CAM_WARN(__module, fmt, args...) \
+ { \
+ cam_debug_log(__module, CAM_LEVEL_WARN, \
+ __func__, __LINE__, fmt, ##args); \
+ }
+
+/*
+ * CAM_INFO
+ * @brief : This Macro will print Information logs
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @fmt : Formatted string which needs to be print in log
+ * @args : Arguments which needs to be print in log
+ */
+#define CAM_INFO(__module, fmt, args...) \
+ { \
+ cam_debug_log(__module, CAM_LEVEL_INFO, \
+ __func__, __LINE__, fmt, ##args); \
+ }
+
+/*
+ * CAM_DBG
+ * @brief : This Macro will print debug logs when enabled using GROUP
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @fmt : Formatted string which needs to be print in log
+ * @args : Arguments which needs to be print in log
+ */
+#define CAM_DBG(__module, fmt, args...) \
+ do { \
+ if (GROUP & __module) { \
+ cam_debug_log(__module, CAM_LEVEL_DBG, \
+ __func__, __LINE__, fmt, ##args); \
+ } \
+ } while (0)
#endif /* _CAM_DEBUG_UTIL_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
index 0be2aaa..1d86bb1 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
@@ -574,7 +574,7 @@
goto free_gpio_array;
}
- for (i = 0; i <= gpio_array_size; i++)
+ for (i = 0; i < gpio_array_size; i++)
gconf->cam_gpio_common_tbl[i].gpio = gpio_array[i];
gconf->cam_gpio_common_tbl_size = gpio_array_size;
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_trace.c b/drivers/media/platform/msm/camera/cam_utils/cam_trace.c
new file mode 100644
index 0000000..08129f3
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_trace.c
@@ -0,0 +1,16 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ *
+ */
+
+/* Instantiate tracepoints */
+#define CREATE_TRACE_POINTS
+#include "cam_trace.h"
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_trace.h b/drivers/media/platform/msm/camera/cam_utils/cam_trace.h
new file mode 100644
index 0000000..f233799
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_trace.h
@@ -0,0 +1,128 @@
+/* Copyright (c) 2017, The Linux Foundation. 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.
+ *
+ */
+
+#if !defined(_CAM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _CAM_TRACE_H
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM camera
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE cam_trace
+
+#include <linux/tracepoint.h>
+#include <media/cam_req_mgr.h>
+#include "cam_context.h"
+
+TRACE_EVENT(cam_context_state,
+ TP_PROTO(const char *name, struct cam_context *ctx),
+ TP_ARGS(name, ctx),
+ TP_STRUCT__entry(
+ __field(void*, ctx)
+ __field(uint32_t, state)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->ctx = ctx;
+ __entry->state = ctx->state;
+ __assign_str(name, name);
+ ),
+ TP_printk(
+ "%s: State ctx=%p ctx_state=%u",
+ __get_str(name), __entry->ctx, __entry->state
+ )
+);
+
+TRACE_EVENT(cam_isp_activated_irq,
+ TP_PROTO(struct cam_context *ctx, unsigned int substate,
+ unsigned int event, uint64_t timestamp),
+ TP_ARGS(ctx, substate, event, timestamp),
+ TP_STRUCT__entry(
+ __field(void*, ctx)
+ __field(uint32_t, state)
+ __field(uint32_t, substate)
+ __field(uint32_t, event)
+ __field(uint64_t, ts)
+ ),
+ TP_fast_assign(
+ __entry->ctx = ctx;
+ __entry->state = ctx->state;
+ __entry->substate = substate;
+ __entry->event = event;
+ __entry->ts = timestamp;
+ ),
+ TP_printk(
+ "ISP: IRQ ctx=%p ctx_state=%u substate=%u event=%u ts=%llu",
+ __entry->ctx, __entry->state, __entry->substate,
+ __entry->event, __entry->ts
+ )
+);
+
+TRACE_EVENT(cam_buf_done,
+ TP_PROTO(const char *ctx_type, struct cam_context *ctx,
+ struct cam_ctx_request *req),
+ TP_ARGS(ctx_type, ctx, req),
+ TP_STRUCT__entry(
+ __string(ctx_type, ctx_type)
+ __field(void*, ctx)
+ __field(uint64_t, request)
+ ),
+ TP_fast_assign(
+ __assign_str(ctx_type, ctx_type);
+ __entry->ctx = ctx;
+ __entry->request = req->request_id;
+ ),
+ TP_printk(
+ "%5s: BufDone ctx=%p request=%llu",
+ __get_str(ctx_type), __entry->ctx, __entry->request
+ )
+);
+
+TRACE_EVENT(cam_apply_req,
+ TP_PROTO(const char *entity, struct cam_req_mgr_apply_request *req),
+ TP_ARGS(entity, req),
+ TP_STRUCT__entry(
+ __string(entity, entity)
+ __field(uint64_t, req_id)
+ ),
+ TP_fast_assign(
+ __assign_str(entity, entity);
+ __entry->req_id = req->request_id;
+ ),
+ TP_printk(
+ "%8s: ApplyRequest request=%llu",
+ __get_str(entity), __entry->req_id
+ )
+);
+
+TRACE_EVENT(cam_flush_req,
+ TP_PROTO(struct cam_req_mgr_flush_info *info),
+ TP_ARGS(info),
+ TP_STRUCT__entry(
+ __field(uint32_t, type)
+ __field(int64_t, req_id)
+ ),
+ TP_fast_assign(
+ __entry->type = info->flush_type;
+ __entry->req_id = info->req_id;
+ ),
+ TP_printk(
+ "FlushRequest type=%u request=%llu",
+ __entry->type, __entry->req_id
+ )
+);
+#endif /* _CAM_TRACE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 743d2f7..205eeef 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1446,6 +1446,9 @@
if (bw > 0xFF)
bw = 0xFF;
+ else if (bw == 0)
+ bw = 1;
+
SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT,
BIT(31) | (cfg->prefill_bw ? BIT(27) : 0) | bw);
SDEROT_DBG("Enable ROT_WB Traffic Shaper:%d\n", bw);
diff --git a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
index 9f8b341..a7b1852 100644
--- a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
+++ b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
@@ -846,10 +846,6 @@
if (!dev || !freq)
return -EINVAL;
- /* Start with highest frequecy and decide correct one later*/
-
- ab_kbps = INT_MAX;
-
gov = container_of(dev->governor,
struct governor, devfreq_gov);
dev->profile->get_dev_status(dev->dev.parent, &stats);
@@ -860,11 +856,11 @@
for (c = 0; c < vidc_data->data_count; ++c) {
if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
+ ab_kbps = INT_MAX;
goto exit;
}
}
- ab_kbps = 0;
for (c = 0; c < vidc_data->data_count; ++c)
ab_kbps += __calculate(&vidc_data->data[c], gov->mode);
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 1991a34..32e79f2 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1360,11 +1360,15 @@
pkt->rg_property_data[0] =
HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR;
hfi = (struct hfi_conceal_color *) &pkt->rg_property_data[1];
- if (hfi)
- hfi->conceal_color =
+ if (hfi) {
+ hfi->conceal_color_8bit =
((struct hfi_conceal_color *) pdata)->
- conceal_color;
- pkt->size += sizeof(u32) * 2;
+ conceal_color_8bit;
+ hfi->conceal_color_10bit =
+ ((struct hfi_conceal_color *) pdata)->
+ conceal_color_10bit;
+ }
+ pkt->size += sizeof(u32) + sizeof(struct hfi_conceal_color);
break;
}
case HAL_PARAM_VPE_ROTATION:
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 6e28e70..472beb1 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -24,7 +24,8 @@
#define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS MIN_NUM_CAPTURE_BUFFERS
#define MIN_NUM_DEC_OUTPUT_BUFFERS 4
#define MIN_NUM_DEC_CAPTURE_BUFFERS 4
-#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8010
+// Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default
+#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010
#define MB_SIZE_IN_PIXEL (16 * 16)
#define OPERATING_FRAME_RATE_STEP (1 << 16)
@@ -264,11 +265,20 @@
.flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
},
{
- .id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR,
- .name = "Picture concealed color",
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT,
+ .name = "Picture concealed color 8bit",
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0x0,
- .maximum = 0xffffff,
+ .maximum = 0xff3fcff,
+ .default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK,
+ .step = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT,
+ .name = "Picture concealed color 10bit",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0x0,
+ .maximum = 0x3fffffff,
.default_value = DEFAULT_VIDEO_CONCEAL_COLOR_BLACK,
.step = 1,
},
@@ -991,11 +1001,6 @@
break;
}
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR:
- property_id = HAL_PARAM_VDEC_CONCEAL_COLOR;
- property_val = ctrl->val;
- pdata = &property_val;
- break;
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
property_id =
@@ -1084,29 +1089,37 @@
int rc = 0, i = 0, fourcc = 0;
struct v4l2_ext_control *ext_control;
struct v4l2_control control;
+ struct hal_conceal_color conceal_color = {0};
+ struct hfi_device *hdev;
- if (!inst || !inst->core || !ctrl) {
+ if (!inst || !inst->core || !inst->core->device || !ctrl) {
dprintk(VIDC_ERR,
"%s invalid parameters\n", __func__);
return -EINVAL;
}
+ hdev = inst->core->device;
+
+ v4l2_try_ext_ctrls(&inst->ctrl_handler, ctrl);
+
ext_control = ctrl->controls;
- control.id =
- V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
for (i = 0; i < ctrl->count; i++) {
switch (ext_control[i].id) {
case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE:
control.value = ext_control[i].value;
-
+ control.id =
+ V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
rc = msm_comm_s_ctrl(inst, &control);
if (rc)
dprintk(VIDC_ERR,
"%s Failed setting stream output mode : %d\n",
__func__, rc);
+ rc = msm_vidc_update_host_buff_counts(inst);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT:
+ control.id =
+ V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
switch (ext_control[i].value) {
case V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE:
if (!msm_comm_g_ctrl_for_id(inst, control.id)) {
@@ -1142,6 +1155,7 @@
break;
}
}
+ rc = msm_vidc_update_host_buff_counts(inst);
inst->clk_data.dpb_fourcc = fourcc;
break;
default:
@@ -1152,6 +1166,36 @@
break;
}
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT:
+ conceal_color.conceal_color_8bit = ext_control[i].value;
+ i++;
+ switch (ext_control[i].id) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT:
+ conceal_color.conceal_color_10bit =
+ ext_control[i].value;
+ dprintk(VIDC_DBG,
+ "conceal color: 8bit=0x%x 10bit=0x%x",
+ conceal_color.conceal_color_8bit,
+ conceal_color.conceal_color_10bit);
+ rc = call_hfi_op(hdev, session_set_property,
+ inst->session,
+ HAL_PARAM_VDEC_CONCEAL_COLOR,
+ &conceal_color);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s Failed setting conceal color",
+ __func__);
+ }
+ break;
+ default:
+ dprintk(VIDC_ERR,
+ "%s Could not find CONCEAL_COLOR_10BIT ext_control",
+ __func__);
+ rc = -ENOTSUPP;
+ break;
+ }
+
+ break;
default:
dprintk(VIDC_ERR
, "%s Unsupported set control %d",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 98a59a5..427568c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -429,7 +429,7 @@
print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf);
msm_comm_unmap_vidc_buffer(inst, mbuf);
list_del(&mbuf->list);
- kfree(mbuf);
+ kref_put_mbuf(mbuf);
}
mutex_unlock(&inst->registeredbufs.lock);
@@ -998,7 +998,7 @@
}
msm_comm_unmap_vidc_buffer(inst, temp);
list_del(&temp->list);
- kfree(temp);
+ kref_put_mbuf(temp);
}
mutex_unlock(&inst->registeredbufs.lock);
}
@@ -1075,10 +1075,16 @@
inst, vb2);
return;
}
+ if (!kref_get_mbuf(inst, mbuf)) {
+ dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
+ return;
+ }
rc = msm_comm_qbuf(inst, mbuf);
if (rc)
print_vidc_buffer(VIDC_ERR, "failed qbuf", inst, mbuf);
+
+ kref_put_mbuf(mbuf);
}
static const struct vb2_ops msm_vidc_vb2q_ops = {
@@ -1620,7 +1626,7 @@
print_vidc_buffer(VIDC_ERR, "undequeud buf", inst, temp);
msm_comm_unmap_vidc_buffer(inst, temp);
list_del(&temp->list);
- kfree(temp);
+ kref_put_mbuf(temp);
}
mutex_unlock(&inst->registeredbufs.lock);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 844a4e1..fbef464 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1492,6 +1492,7 @@
break;
case HAL_EVENT_RELEASE_BUFFER_REFERENCE:
{
+ struct msm_vidc_buffer *mbuf;
u32 planes[VIDEO_MAX_PLANES] = {0};
dprintk(VIDC_DBG,
@@ -1501,8 +1502,15 @@
planes[0] = event_notify->packet_buffer;
planes[1] = event_notify->extra_data_buffer;
- handle_release_buffer_reference(inst, planes);
-
+ mbuf = msm_comm_get_buffer_using_device_planes(inst, planes);
+ if (!mbuf || !kref_get_mbuf(inst, mbuf)) {
+ dprintk(VIDC_ERR,
+ "%s: data_addr %x, extradata_addr %x not found\n",
+ __func__, planes[0], planes[1]);
+ } else {
+ handle_release_buffer_reference(inst, mbuf);
+ kref_put_mbuf(mbuf);
+ }
goto err_bad_event;
}
default:
@@ -2200,7 +2208,7 @@
planes[1] = empty_buf_done->extra_data_buffer;
mbuf = msm_comm_get_buffer_using_device_planes(inst, planes);
- if (!mbuf) {
+ if (!mbuf || !kref_get_mbuf(inst, mbuf)) {
dprintk(VIDC_ERR,
"%s: data_addr %x, extradata_addr %x not found\n",
__func__, planes[0], planes[1]);
@@ -2242,12 +2250,11 @@
/*
* put_buffer should be done before vb2_buffer_done else
* client might queue the same buffer before it is unmapped
- * in put_buffer. also don't use mbuf after put_buffer
- * as it may be freed in put_buffer.
+ * in put_buffer.
*/
msm_comm_put_vidc_buffer(inst, mbuf);
msm_comm_vb2_buffer_done(inst, vb);
-
+ kref_put_mbuf(mbuf);
exit:
put_inst(inst);
}
@@ -2326,7 +2333,7 @@
buffer_type = msm_comm_get_hal_output_buffer(inst);
if (fill_buf_done->buffer_type == buffer_type) {
mbuf = msm_comm_get_buffer_using_device_planes(inst, planes);
- if (!mbuf) {
+ if (!mbuf || !kref_get_mbuf(inst, mbuf)) {
dprintk(VIDC_ERR,
"%s: data_addr %x, extradata_addr %x not found\n",
__func__, planes[0], planes[1]);
@@ -2429,6 +2436,7 @@
*/
msm_comm_put_vidc_buffer(inst, mbuf);
msm_comm_vb2_buffer_done(inst, vb);
+ kref_put_mbuf(mbuf);
exit:
put_inst(inst);
@@ -3174,6 +3182,11 @@
buffer_type);
return 0;
}
+
+ /* For DPB buffers, Always use FW count */
+ output_buf->buffer_count_actual = output_buf->buffer_count_min_host =
+ output_buf->buffer_count_min;
+
dprintk(VIDC_DBG,
"output: num = %d, size = %d\n",
output_buf->buffer_count_actual,
@@ -4749,8 +4762,7 @@
/* remove from list */
list_del(&mbuf->list);
- kfree(mbuf);
- mbuf = NULL;
+ kref_put_mbuf(mbuf);
}
mutex_unlock(&inst->registeredbufs.lock);
@@ -4940,6 +4952,7 @@
{
u32 x_min, x_max, y_min, y_max;
u32 input_height, input_width, output_height, output_width;
+ u32 rotation;
input_height = inst->prop.height[OUTPUT_PORT];
input_width = inst->prop.width[OUTPUT_PORT];
@@ -4975,6 +4988,20 @@
return 0;
}
+ rotation = msm_comm_g_ctrl_for_id(inst,
+ V4L2_CID_MPEG_VIDC_VIDEO_ROTATION);
+
+ if ((output_width != output_height) &&
+ (rotation == V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90 ||
+ rotation == V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270)) {
+
+ output_width = inst->prop.height[CAPTURE_PORT];
+ output_height = inst->prop.width[CAPTURE_PORT];
+ dprintk(VIDC_DBG,
+ "Rotation=%u Swapped Output W=%u H=%u to check scaling",
+ rotation, output_width, output_height);
+ }
+
x_min = (1<<16)/inst->capability.scale_x.min;
y_min = (1<<16)/inst->capability.scale_y.min;
x_max = inst->capability.scale_x.max >> 16;
@@ -5923,6 +5950,7 @@
rc = -ENOMEM;
goto exit;
}
+ kref_init(&mbuf->kref);
}
vbuf = to_vb2_v4l2_buffer(vb2);
@@ -5986,11 +6014,11 @@
return mbuf;
exit:
- mutex_unlock(&inst->registeredbufs.lock);
dprintk(VIDC_ERR, "%s: rc %d\n", __func__, rc);
msm_comm_unmap_vidc_buffer(inst, mbuf);
if (!found)
- kfree(mbuf);
+ kref_put_mbuf(mbuf);
+ mutex_unlock(&inst->registeredbufs.lock);
return ERR_PTR(rc);
}
@@ -6042,24 +6070,26 @@
*/
if (!mbuf->smem[0].refcount) {
list_del(&mbuf->list);
- kfree(mbuf);
- mbuf = NULL;
+ kref_put_mbuf(mbuf);
}
unlock:
mutex_unlock(&inst->registeredbufs.lock);
}
-void handle_release_buffer_reference(struct msm_vidc_inst *inst, u32 *planes)
+void handle_release_buffer_reference(struct msm_vidc_inst *inst,
+ struct msm_vidc_buffer *mbuf)
{
int rc = 0;
- struct msm_vidc_buffer *mbuf = NULL;
+ struct msm_vidc_buffer *temp;
bool found = false;
int i = 0;
mutex_lock(&inst->registeredbufs.lock);
found = false;
- list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
- if (msm_comm_compare_device_planes(mbuf, planes)) {
+ /* check if mbuf was not removed by any chance */
+ list_for_each_entry(temp, &inst->registeredbufs.list, list) {
+ if (msm_comm_compare_vb2_planes(inst, mbuf,
+ &temp->vvb.vb2_buf)) {
found = true;
break;
}
@@ -6077,13 +6107,10 @@
/* refcount is not zero if client queued the same buffer */
if (!mbuf->smem[0].refcount) {
list_del(&mbuf->list);
- kfree(mbuf);
- mbuf = NULL;
+ kref_put_mbuf(mbuf);
}
} else {
- dprintk(VIDC_ERR,
- "%s: data_addr %x extradata_addr %x not found\n",
- __func__, planes[0], planes[1]);
+ print_vidc_buffer(VIDC_ERR, "mbuf not found", inst, mbuf);
goto unlock;
}
@@ -6097,8 +6124,9 @@
* and if found queue it to video hw (if not flushing).
*/
found = false;
- list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
- if (msm_comm_compare_device_plane(mbuf, planes, 0)) {
+ list_for_each_entry(temp, &inst->registeredbufs.list, list) {
+ if (msm_comm_compare_vb2_plane(inst, mbuf,
+ &temp->vvb.vb2_buf, 0)) {
found = true;
break;
}
@@ -6113,8 +6141,7 @@
msm_comm_unmap_vidc_buffer(inst, mbuf);
/* remove from list */
list_del(&mbuf->list);
- kfree(mbuf);
- mbuf = NULL;
+ kref_put_mbuf(mbuf);
/* don't queue the buffer */
found = false;
@@ -6161,3 +6188,41 @@
return rc;
}
+static void kref_free_mbuf(struct kref *kref)
+{
+ struct msm_vidc_buffer *mbuf = container_of(kref,
+ struct msm_vidc_buffer, kref);
+
+ kfree(mbuf);
+}
+
+void kref_put_mbuf(struct msm_vidc_buffer *mbuf)
+{
+ if (!mbuf)
+ return;
+
+ kref_put(&mbuf->kref, kref_free_mbuf);
+}
+
+bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
+{
+ struct msm_vidc_buffer *temp;
+ bool matches = false;
+ bool ret = false;
+
+ if (!inst || !mbuf)
+ return false;
+
+ mutex_lock(&inst->registeredbufs.lock);
+ list_for_each_entry(temp, &inst->registeredbufs.list, list) {
+ if (temp == mbuf) {
+ matches = true;
+ break;
+ }
+ }
+ ret = (matches && kref_get_unless_zero(&mbuf->kref)) ? true : false;
+ mutex_unlock(&inst->registeredbufs.lock);
+
+ return ret;
+}
+
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index bc881a0..18ba4a5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -116,7 +116,8 @@
struct vb2_buffer *vb2);
void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *mbuf);
-void handle_release_buffer_reference(struct msm_vidc_inst *inst, u32 *planes);
+void handle_release_buffer_reference(struct msm_vidc_inst *inst,
+ struct msm_vidc_buffer *mbuf);
int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
struct vb2_buffer *vb);
int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
@@ -145,4 +146,7 @@
struct vb2_buffer *vb2);
void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
struct v4l2_buffer *v4l2);
+void kref_put_mbuf(struct msm_vidc_buffer *mbuf);
+bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf);
+
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 49e6c3ec..e554a46 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -387,6 +387,7 @@
struct msm_vidc_buffer {
struct list_head list;
+ struct kref kref;
struct msm_smem smem[VIDEO_MAX_PLANES];
struct vb2_v4l2_buffer vvb;
bool deferred;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 0069e40..b430d14 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1681,9 +1681,16 @@
}
dev = device;
- mutex_lock(&dev->lock);
dprintk(VIDC_DBG, "Core initializing\n");
+
+ mutex_lock(&dev->lock);
+
+ dev->bus_vote.data =
+ kzalloc(sizeof(struct vidc_bus_vote_data), GFP_KERNEL);
+ dev->bus_vote.data_count = 1;
+ dev->bus_vote.data->power_mode = VIDC_POWER_TURBO;
+
rc = __load_fw(dev);
if (rc) {
dprintk(VIDC_ERR, "Failed to load Venus FW\n");
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 79ce858..fbd3b02 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -996,6 +996,11 @@
struct hal_buffer_requirements buffer[HAL_BUFFER_MAX];
};
+struct hal_conceal_color {
+ u32 conceal_color_8bit;
+ u32 conceal_color_10bit;
+};
+
union hal_get_property {
struct hal_frame_rate frame_rate;
struct hal_uncompressed_format_select format_select;
@@ -1045,6 +1050,7 @@
struct hal_buffer_alloc_mode buffer_alloc_mode;
struct buffer_requirements buf_req;
enum hal_h264_entropy h264_entropy;
+ struct hal_conceal_color conceal_color;
};
/* HAL Response */
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index d5624ce..a522918 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -478,7 +478,8 @@
};
struct hfi_conceal_color {
- u32 conceal_color;
+ u32 conceal_color_8bit;
+ u32 conceal_color_10bit;
};
struct hfi_intra_period {
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index b373acb..232c290 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -228,7 +228,7 @@
if (!wcd9xxx->dev_up) {
dev_dbg_ratelimited(
- wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n",
+ wcd9xxx->dev, "%s: No read allowed. dev_up = %lu\n",
__func__, wcd9xxx->dev_up);
return 0;
}
@@ -268,7 +268,7 @@
if (!wcd9xxx->dev_up) {
dev_dbg_ratelimited(
- wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n",
__func__, wcd9xxx->dev_up);
return 0;
}
@@ -345,7 +345,7 @@
if (!wcd9xxx->dev_up) {
dev_dbg_ratelimited(
- wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n",
__func__, wcd9xxx->dev_up);
ret = 0;
goto done;
@@ -426,7 +426,7 @@
if (!wcd9xxx->dev_up) {
dev_dbg_ratelimited(
- wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
+ wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n",
__func__, wcd9xxx->dev_up);
return 0;
}
@@ -1479,12 +1479,27 @@
return -EINVAL;
}
- dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n",
- __func__, wcd9xxx->dev_up);
- if (wcd9xxx->dev_up)
- return 0;
+ /*
+ * Wait for 500 ms for device down to complete. Observed delay
+ * of ~200ms for device down to complete after being called,
+ * due to context switch issue.
+ */
+ ret = wait_on_bit_timeout(&wcd9xxx->dev_up, 0,
+ TASK_INTERRUPTIBLE,
+ msecs_to_jiffies(500));
+ if (ret)
+ pr_err("%s: slim device down not complete in 500 msec\n",
+ __func__);
mutex_lock(&wcd9xxx->reset_lock);
+
+ dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %lu\n",
+ __func__, wcd9xxx->dev_up);
+ if (wcd9xxx->dev_up) {
+ mutex_unlock(&wcd9xxx->reset_lock);
+ return 0;
+ }
+
ret = wcd9xxx_reset(wcd9xxx->dev);
if (ret)
dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__);
@@ -1502,8 +1517,8 @@
pr_err("%s: wcd9xxx is NULL\n", __func__);
return -EINVAL;
}
- dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n",
- __func__, wcd9xxx->dev_up);
+ dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %lu\n",
+ __func__, wcd9xxx->dev_up);
if (wcd9xxx->dev_up)
return 0;
@@ -1525,18 +1540,20 @@
return -EINVAL;
}
- dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n",
- __func__, wcd9xxx->dev_up);
- if (!wcd9xxx->dev_up)
- return 0;
-
- wcd9xxx->dev_up = false;
-
mutex_lock(&wcd9xxx->reset_lock);
+
+ dev_info(wcd9xxx->dev, "%s: device down, dev_up = %lu\n",
+ __func__, wcd9xxx->dev_up);
+ if (!wcd9xxx->dev_up) {
+ mutex_unlock(&wcd9xxx->reset_lock);
+ return 0;
+ }
+
if (wcd9xxx->dev_down)
wcd9xxx->dev_down(wcd9xxx);
wcd9xxx_irq_exit(&wcd9xxx->core_res);
wcd9xxx_reset_low(wcd9xxx->dev);
+ wcd9xxx->dev_up = false;
mutex_unlock(&wcd9xxx->reset_lock);
return 0;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e8b9b48..7077b30 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -281,6 +281,7 @@
wait_queue_head_t app_block_wq;
atomic_t qseecom_state;
int is_apps_region_protected;
+ bool smcinvoke_support;
};
struct qseecom_sec_buf_fd_info {
@@ -580,10 +581,12 @@
desc.args[1] = req_64bit->sb_ptr;
desc.args[2] = req_64bit->sb_len;
}
+ qseecom.smcinvoke_support = true;
smc_id = TZ_OS_REGISTER_LISTENER_SMCINVOKE_ID;
__qseecom_reentrancy_check_if_no_app_blocked(smc_id);
ret = scm_call2(smc_id, &desc);
if (ret) {
+ qseecom.smcinvoke_support = false;
smc_id = TZ_OS_REGISTER_LISTENER_ID;
__qseecom_reentrancy_check_if_no_app_blocked(
smc_id);
@@ -1012,10 +1015,14 @@
struct qseecom_continue_blocked_request_ireq *req =
(struct qseecom_continue_blocked_request_ireq *)
req_buf;
- smc_id = TZ_OS_CONTINUE_BLOCKED_REQUEST_ID;
+ if (qseecom.smcinvoke_support)
+ smc_id =
+ TZ_OS_CONTINUE_BLOCKED_REQUEST_SMCINVOKE_ID;
+ else
+ smc_id = TZ_OS_CONTINUE_BLOCKED_REQUEST_ID;
desc.arginfo =
TZ_OS_CONTINUE_BLOCKED_REQUEST_ID_PARAM_ID;
- desc.args[0] = req->app_id;
+ desc.args[0] = req->app_or_session_id;
ret = scm_call2(smc_id, &desc);
break;
}
@@ -1842,7 +1849,7 @@
return ret;
}
-int __qseecom_process_reentrancy_blocked_on_listener(
+static int __qseecom_process_blocked_on_listener_legacy(
struct qseecom_command_scm_resp *resp,
struct qseecom_registered_app_list *ptr_app,
struct qseecom_dev_handle *data)
@@ -1851,9 +1858,8 @@
int ret = 0;
struct qseecom_continue_blocked_request_ireq ireq;
struct qseecom_command_scm_resp continue_resp;
- sigset_t new_sigset, old_sigset;
- unsigned long flags;
bool found_app = false;
+ unsigned long flags;
if (!resp || !data) {
pr_err("invalid resp or data pointer\n");
@@ -1893,32 +1899,30 @@
pr_debug("lsntr %d in_use = %d\n",
resp->data, list_ptr->listener_in_use);
ptr_app->blocked_on_listener_id = resp->data;
+
/* sleep until listener is available */
- do {
- qseecom.app_block_ref_cnt++;
- ptr_app->app_blocked = true;
- sigfillset(&new_sigset);
- sigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);
- mutex_unlock(&app_access_lock);
- do {
- if (!wait_event_freezable(
- list_ptr->listener_block_app_wq,
- !list_ptr->listener_in_use)) {
- break;
- }
- } while (1);
- mutex_lock(&app_access_lock);
- sigprocmask(SIG_SETMASK, &old_sigset, NULL);
- ptr_app->app_blocked = false;
- qseecom.app_block_ref_cnt--;
- } while (list_ptr->listener_in_use == true);
+ qseecom.app_block_ref_cnt++;
+ ptr_app->app_blocked = true;
+ mutex_unlock(&app_access_lock);
+ if (wait_event_freezable(
+ list_ptr->listener_block_app_wq,
+ !list_ptr->listener_in_use)) {
+ pr_err("Interrupted: listener_id %d, app_id %d\n",
+ resp->data, ptr_app->app_id);
+ ret = -ERESTARTSYS;
+ goto exit;
+ }
+ mutex_lock(&app_access_lock);
+ ptr_app->app_blocked = false;
+ qseecom.app_block_ref_cnt--;
+
ptr_app->blocked_on_listener_id = 0;
/* notify the blocked app that listener is available */
pr_warn("Lsntr %d is available, unblock app(%d) %s in TZ\n",
resp->data, data->client.app_id,
data->client.app_name);
ireq.qsee_cmd_id = QSEOS_CONTINUE_BLOCKED_REQ_COMMAND;
- ireq.app_id = data->client.app_id;
+ ireq.app_or_session_id = data->client.app_id;
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
&ireq, sizeof(ireq),
&continue_resp, sizeof(continue_resp));
@@ -1937,6 +1941,73 @@
return ret;
}
+static int __qseecom_process_blocked_on_listener_smcinvoke(
+ struct qseecom_command_scm_resp *resp)
+{
+ struct qseecom_registered_listener_list *list_ptr;
+ int ret = 0;
+ struct qseecom_continue_blocked_request_ireq ireq;
+ struct qseecom_command_scm_resp continue_resp;
+ unsigned int session_id;
+
+ if (!resp) {
+ pr_err("invalid resp pointer\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+ session_id = resp->resp_type;
+ list_ptr = __qseecom_find_svc(resp->data);
+ if (!list_ptr) {
+ pr_err("Invalid listener ID\n");
+ ret = -ENODATA;
+ goto exit;
+ }
+ pr_debug("lsntr %d in_use = %d\n",
+ resp->data, list_ptr->listener_in_use);
+ /* sleep until listener is available */
+ qseecom.app_block_ref_cnt++;
+ mutex_unlock(&app_access_lock);
+ if (wait_event_freezable(
+ list_ptr->listener_block_app_wq,
+ !list_ptr->listener_in_use)) {
+ pr_err("Interrupted: listener_id %d, session_id %d\n",
+ resp->data, session_id);
+ ret = -ERESTARTSYS;
+ goto exit;
+ }
+ mutex_lock(&app_access_lock);
+ qseecom.app_block_ref_cnt--;
+
+ /* notify TZ that listener is available */
+ pr_warn("Lsntr %d is available, unblock session(%d) in TZ\n",
+ resp->data, session_id);
+ ireq.qsee_cmd_id = QSEOS_CONTINUE_BLOCKED_REQ_COMMAND;
+ ireq.app_or_session_id = session_id;
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+ &ireq, sizeof(ireq),
+ &continue_resp, sizeof(continue_resp));
+ if (ret) {
+ pr_err("scm_call for continue blocked req for session %d failed, ret %d\n",
+ session_id, ret);
+ goto exit;
+ }
+ resp->result = QSEOS_RESULT_INCOMPLETE;
+exit:
+ return ret;
+}
+
+static int __qseecom_process_reentrancy_blocked_on_listener(
+ struct qseecom_command_scm_resp *resp,
+ struct qseecom_registered_app_list *ptr_app,
+ struct qseecom_dev_handle *data)
+{
+ if (!qseecom.smcinvoke_support)
+ return __qseecom_process_blocked_on_listener_legacy(
+ resp, ptr_app, data);
+ else
+ return __qseecom_process_blocked_on_listener_smcinvoke(
+ resp);
+}
static int __qseecom_reentrancy_process_incomplete_cmd(
struct qseecom_dev_handle *data,
struct qseecom_command_scm_resp *resp)
@@ -4703,18 +4774,15 @@
}
resp.result = desc->ret[0]; /*req_cmd*/
- resp.resp_type = desc->ret[1]; /*app_id*/
+ resp.resp_type = desc->ret[1]; /*incomplete:unused;blocked:session_id*/
resp.data = desc->ret[2]; /*listener_id*/
- dummy_private_data.client.app_id = desc->ret[1];
- dummy_app_entry.app_id = desc->ret[1];
-
mutex_lock(&app_access_lock);
ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry,
&dummy_private_data);
mutex_unlock(&app_access_lock);
if (ret)
- pr_err("Failed to req cmd %d lsnr %d on app %d, ret = %d\n",
+ pr_err("Failed on cmd %d for lsnr %d session %d, ret = %d\n",
(int)desc->ret[0], (int)desc->ret[2],
(int)desc->ret[1], ret);
desc->ret[0] = resp.result;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index f3f181d..d7409a8 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1940,6 +1940,8 @@
msm_host->core_3_0v_support = true;
pdata->sdr104_wa = of_property_read_bool(np, "qcom,sdr104-wa");
+ msm_host->regs_restore.is_supported =
+ of_property_read_bool(np, "qcom,restore-after-cx-collapse");
return pdata;
out:
@@ -2831,6 +2833,103 @@
return sel_clk;
}
+static void sdhci_msm_registers_save(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ const struct sdhci_msm_offset *msm_host_offset =
+ msm_host->offset;
+
+ if (!msm_host->regs_restore.is_supported)
+ return;
+
+ msm_host->regs_restore.vendor_func = readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC);
+ msm_host->regs_restore.vendor_pwrctl_mask =
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_PWRCTL_MASK);
+ msm_host->regs_restore.vendor_func2 =
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC_FUNC2);
+ msm_host->regs_restore.vendor_func3 =
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC3);
+ msm_host->regs_restore.hc_2c_2e =
+ sdhci_readl(host, SDHCI_CLOCK_CONTROL);
+ msm_host->regs_restore.hc_3c_3e =
+ sdhci_readl(host, SDHCI_AUTO_CMD_ERR);
+ msm_host->regs_restore.vendor_pwrctl_ctl =
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_PWRCTL_CTL);
+ msm_host->regs_restore.hc_38_3a =
+ sdhci_readl(host, SDHCI_SIGNAL_ENABLE);
+ msm_host->regs_restore.hc_34_36 =
+ sdhci_readl(host, SDHCI_INT_ENABLE);
+ msm_host->regs_restore.hc_28_2a =
+ sdhci_readl(host, SDHCI_HOST_CONTROL);
+ msm_host->regs_restore.vendor_caps_0 =
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC_CAPABILITIES0);
+ msm_host->regs_restore.hc_caps_1 =
+ sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ msm_host->regs_restore.testbus_config = readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_TESTBUS_CONFIG);
+ msm_host->regs_restore.is_valid = true;
+
+ pr_debug("%s: %s: registers saved. PWRCTL_MASK = 0x%x\n",
+ mmc_hostname(host->mmc), __func__,
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_PWRCTL_MASK));
+}
+
+static void sdhci_msm_registers_restore(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ const struct sdhci_msm_offset *msm_host_offset =
+ msm_host->offset;
+
+ if (!msm_host->regs_restore.is_supported ||
+ !msm_host->regs_restore.is_valid)
+ return;
+
+ writel_relaxed(msm_host->regs_restore.vendor_func, host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC);
+ writel_relaxed(msm_host->regs_restore.vendor_pwrctl_mask,
+ host->ioaddr + msm_host_offset->CORE_PWRCTL_MASK);
+ writel_relaxed(msm_host->regs_restore.vendor_func2,
+ host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC_FUNC2);
+ writel_relaxed(msm_host->regs_restore.vendor_func3,
+ host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC3);
+ sdhci_writel(host, msm_host->regs_restore.hc_2c_2e,
+ SDHCI_CLOCK_CONTROL);
+ sdhci_writel(host, msm_host->regs_restore.hc_3c_3e,
+ SDHCI_AUTO_CMD_ERR);
+ writel_relaxed(msm_host->regs_restore.vendor_pwrctl_ctl,
+ host->ioaddr + msm_host_offset->CORE_PWRCTL_CTL);
+ sdhci_writel(host, msm_host->regs_restore.hc_38_3a,
+ SDHCI_SIGNAL_ENABLE);
+ sdhci_writel(host, msm_host->regs_restore.hc_34_36,
+ SDHCI_INT_ENABLE);
+ sdhci_writel(host, msm_host->regs_restore.hc_28_2a,
+ SDHCI_HOST_CONTROL);
+ writel_relaxed(msm_host->regs_restore.vendor_caps_0,
+ host->ioaddr +
+ msm_host_offset->CORE_VENDOR_SPEC_CAPABILITIES0);
+ sdhci_writel(host, msm_host->regs_restore.hc_caps_1,
+ SDHCI_CAPABILITIES_1);
+ writel_relaxed(msm_host->regs_restore.testbus_config, host->ioaddr +
+ msm_host_offset->CORE_TESTBUS_CONFIG);
+ msm_host->regs_restore.is_valid = false;
+
+ pr_debug("%s: %s: registers restored. PWRCTL_MASK = 0x%x\n",
+ mmc_hostname(host->mmc), __func__,
+ readl_relaxed(host->ioaddr +
+ msm_host_offset->CORE_PWRCTL_MASK));
+}
+
static int sdhci_msm_enable_controller_clock(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -2861,6 +2960,7 @@
atomic_set(&msm_host->controller_clock, 1);
pr_debug("%s: %s: enabled controller clock\n",
mmc_hostname(host->mmc), __func__);
+ sdhci_msm_registers_restore(host);
goto out;
disable_pclk:
@@ -2879,6 +2979,7 @@
struct sdhci_msm_host *msm_host = pltfm_host->priv;
if (atomic_read(&msm_host->controller_clock)) {
+ sdhci_msm_registers_save(host);
if (!IS_ERR(msm_host->clk))
clk_disable_unprepare(msm_host->clk);
if (!IS_ERR(msm_host->pclk))
@@ -2957,14 +3058,9 @@
clk_disable_unprepare(msm_host->sleep_clk);
if (!IS_ERR_OR_NULL(msm_host->ff_clk))
clk_disable_unprepare(msm_host->ff_clk);
- clk_disable_unprepare(msm_host->clk);
- if (!IS_ERR(msm_host->pclk))
- clk_disable_unprepare(msm_host->pclk);
if (!IS_ERR_OR_NULL(msm_host->bus_clk))
clk_disable_unprepare(msm_host->bus_clk);
-
- atomic_set(&msm_host->controller_clock, 0);
- sdhci_msm_bus_voting(host, 0);
+ sdhci_msm_disable_controller_clock(host);
}
atomic_set(&msm_host->clks_on, enable);
goto out;
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index c536a7d..53a8c67 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -170,6 +170,24 @@
int state;
};
+struct sdhci_msm_regs_restore {
+ bool is_supported;
+ bool is_valid;
+ u32 vendor_pwrctl_mask;
+ u32 vendor_pwrctl_ctl;
+ u32 vendor_caps_0;
+ u32 vendor_func;
+ u32 vendor_func2;
+ u32 vendor_func3;
+ u32 hc_2c_2e;
+ u32 hc_28_2a;
+ u32 hc_34_36;
+ u32 hc_38_3a;
+ u32 hc_3c_3e;
+ u32 hc_caps_1;
+ u32 testbus_config;
+};
+
struct sdhci_msm_debug_data {
struct mmc_host copy_mmc;
struct mmc_card copy_card;
@@ -226,6 +244,7 @@
const struct sdhci_msm_offset *offset;
bool core_3_0v_support;
bool pltfm_init_done;
+ struct sdhci_msm_regs_restore regs_restore;
};
extern char *saved_command_line;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 6063cf4..410bcda 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -3133,7 +3133,7 @@
setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry,
(unsigned long)ar);
- if (QCA_REV_6174(ar))
+ if (QCA_REV_6174(ar) || QCA_REV_9377(ar))
ath10k_pci_override_ce_config(ar);
ret = ath10k_pci_alloc_pipes(ar);
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 9afd6f2..bb36fe5 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -46,6 +46,12 @@
/* channel 4 not supported yet */
};
+#ifdef CONFIG_PM
+static struct wiphy_wowlan_support wil_wowlan_support = {
+ .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
+};
+#endif
+
/* Vendor id to be used in vendor specific command and events
* to user space.
* NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
@@ -1883,6 +1889,10 @@
wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
}
+
+#ifdef CONFIG_PM
+ wiphy->wowlan = &wil_wowlan_support;
+#endif
}
struct wireless_dev *wil_cfg80211_init(struct device *dev)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index d3bad57..0fd7d7e 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2662,7 +2662,7 @@
tasklet_hrtimer_init(&data->beacon_timer,
mac80211_hwsim_beacon,
- CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
spin_lock_bh(&hwsim_radio_lock);
list_add_tail(&data->list, &hwsim_radios);
diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c
index 41b5b07..6852010 100644
--- a/drivers/pinctrl/freescale/pinctrl-mxs.c
+++ b/drivers/pinctrl/freescale/pinctrl-mxs.c
@@ -194,6 +194,16 @@
return 0;
}
+static void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, void __iomem *reg)
+{
+ u32 tmp;
+
+ tmp = readl(reg);
+ tmp &= ~(mask << shift);
+ tmp |= value << shift;
+ writel(tmp, reg);
+}
+
static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
{
@@ -211,8 +221,7 @@
reg += bank * 0x20 + pin / 16 * 0x10;
shift = pin % 16 * 2;
- writel(0x3 << shift, reg + CLR);
- writel(g->muxsel[i] << shift, reg + SET);
+ mxs_pinctrl_rmwl(g->muxsel[i], 0x3, shift, reg);
}
return 0;
@@ -279,8 +288,7 @@
/* mA */
if (config & MA_PRESENT) {
shift = pin % 8 * 4;
- writel(0x3 << shift, reg + CLR);
- writel(ma << shift, reg + SET);
+ mxs_pinctrl_rmwl(ma, 0x3, shift, reg);
}
/* vol */
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index c43b1e9..0d34d8a4 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -13,6 +13,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -1524,10 +1525,32 @@
chained_irq_exit(chip, desc);
}
+/*
+ * Certain machines seem to hardcode Linux IRQ numbers in their ACPI
+ * tables. Since we leave GPIOs that are not capable of generating
+ * interrupts out of the irqdomain the numbering will be different and
+ * cause devices using the hardcoded IRQ numbers fail. In order not to
+ * break such machines we will only mask pins from irqdomain if the machine
+ * is not listed below.
+ */
+static const struct dmi_system_id chv_no_valid_mask[] = {
+ {
+ /* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */
+ .ident = "Acer Chromebook (CYAN)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"),
+ DMI_MATCH(DMI_BIOS_DATE, "05/21/2016"),
+ },
+ },
+ {}
+};
+
static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
{
const struct chv_gpio_pinrange *range;
struct gpio_chip *chip = &pctrl->chip;
+ bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
int ret, i, offset;
*chip = chv_gpio_chip;
@@ -1536,7 +1559,7 @@
chip->label = dev_name(pctrl->dev);
chip->parent = pctrl->dev;
chip->base = -1;
- chip->irq_need_valid_mask = true;
+ chip->irq_need_valid_mask = need_valid_mask;
ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
if (ret) {
@@ -1567,7 +1590,7 @@
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
- if (intsel >= pctrl->community->nirqs)
+ if (need_valid_mask && intsel >= pctrl->community->nirqs)
clear_bit(i, chip->irq_valid_mask);
}
diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c
index 76f077f..f87ef5a 100644
--- a/drivers/pinctrl/meson/pinctrl-meson8b.c
+++ b/drivers/pinctrl/meson/pinctrl-meson8b.c
@@ -739,8 +739,8 @@
static const char * const nand_groups[] = {
"nand_io", "nand_io_ce0", "nand_io_ce1",
"nand_io_rb0", "nand_ale", "nand_cle",
- "nand_wen_clk", "nand_ren_clk", "nand_dqs0",
- "nand_dqs1"
+ "nand_wen_clk", "nand_ren_clk", "nand_dqs_0",
+ "nand_dqs_1"
};
static const char * const nor_groups[] = {
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
index b68ae42..743d1f4 100644
--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -405,6 +405,36 @@
PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(88, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(89, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(92, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(93, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
};
static const struct msm_pinctrl_soc_data ipq4019_pinctrl = {
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm670.c b/drivers/pinctrl/qcom/pinctrl-sdm670.c
index c93628e..1f742f8 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm670.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm670.c
@@ -28,6 +28,7 @@
#define NORTH 0x00500000
#define SOUTH 0x00900000
#define WEST 0x00100000
+#define DUMMY 0x0
#define REG_SIZE 0x1000
#define PINGROUP(id, base, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
{ \
@@ -254,12 +255,14 @@
PINCTRL_PIN(147, "GPIO_147"),
PINCTRL_PIN(148, "GPIO_148"),
PINCTRL_PIN(149, "GPIO_149"),
- PINCTRL_PIN(150, "SDC1_CLK"),
- PINCTRL_PIN(151, "SDC1_CMD"),
- PINCTRL_PIN(152, "SDC1_DATA"),
- PINCTRL_PIN(153, "SDC2_CLK"),
- PINCTRL_PIN(154, "SDC2_CMD"),
- PINCTRL_PIN(155, "SDC2_DATA"),
+ PINCTRL_PIN(150, "SDC1_RCLK"),
+ PINCTRL_PIN(151, "SDC1_CLK"),
+ PINCTRL_PIN(152, "SDC1_CMD"),
+ PINCTRL_PIN(153, "SDC1_DATA"),
+ PINCTRL_PIN(154, "SDC2_CLK"),
+ PINCTRL_PIN(155, "SDC2_CMD"),
+ PINCTRL_PIN(156, "SDC2_DATA"),
+ PINCTRL_PIN(157, "UFS_RESET"),
};
#define DECLARE_MSM_GPIO_PINS(pin) \
@@ -322,10 +325,23 @@
DECLARE_MSM_GPIO_PINS(55);
DECLARE_MSM_GPIO_PINS(56);
DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
DECLARE_MSM_GPIO_PINS(65);
DECLARE_MSM_GPIO_PINS(66);
DECLARE_MSM_GPIO_PINS(67);
DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
DECLARE_MSM_GPIO_PINS(75);
DECLARE_MSM_GPIO_PINS(76);
DECLARE_MSM_GPIO_PINS(77);
@@ -355,6 +371,7 @@
DECLARE_MSM_GPIO_PINS(101);
DECLARE_MSM_GPIO_PINS(102);
DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
DECLARE_MSM_GPIO_PINS(105);
DECLARE_MSM_GPIO_PINS(106);
DECLARE_MSM_GPIO_PINS(107);
@@ -401,243 +418,128 @@
DECLARE_MSM_GPIO_PINS(148);
DECLARE_MSM_GPIO_PINS(149);
-static const unsigned int sdc1_clk_pins[] = { 150 };
-static const unsigned int sdc1_cmd_pins[] = { 151 };
-static const unsigned int sdc1_data_pins[] = { 152 };
-static const unsigned int sdc2_clk_pins[] = { 153 };
-static const unsigned int sdc2_cmd_pins[] = { 154 };
-static const unsigned int sdc2_data_pins[] = { 155 };
+static const unsigned int sdc1_rclk_pins[] = { 150 };
+static const unsigned int sdc1_clk_pins[] = { 151 };
+static const unsigned int sdc1_cmd_pins[] = { 152 };
+static const unsigned int sdc1_data_pins[] = { 153 };
+static const unsigned int sdc2_clk_pins[] = { 154 };
+static const unsigned int sdc2_cmd_pins[] = { 155 };
+static const unsigned int sdc2_data_pins[] = { 156 };
+static const unsigned int ufs_reset_pins[] = { 157 };
enum sdm670_functions {
msm_mux_qup0,
msm_mux_gpio,
- msm_mux_reserved0,
- msm_mux_reserved1,
- msm_mux_reserved2,
- msm_mux_reserved3,
msm_mux_qup9,
msm_mux_qdss_cti,
- msm_mux_reserved4,
- msm_mux_reserved5,
msm_mux_ddr_pxi0,
- msm_mux_reserved6,
msm_mux_ddr_bist,
msm_mux_atest_tsens2,
msm_mux_vsense_trigger,
msm_mux_atest_usb1,
- msm_mux_reserved7,
msm_mux_qup_l4,
msm_mux_GP_PDM1,
- msm_mux_reserved8,
msm_mux_qup_l5,
- msm_mux_reserved9,
msm_mux_mdp_vsync,
msm_mux_qup_l6,
msm_mux_wlan2_adc1,
msm_mux_atest_usb11,
msm_mux_ddr_pxi2,
- msm_mux_reserved10,
msm_mux_edp_lcd,
msm_mux_dbg_out,
msm_mux_wlan2_adc0,
msm_mux_atest_usb10,
- msm_mux_reserved11,
msm_mux_m_voc,
msm_mux_tsif1_sync,
msm_mux_ddr_pxi3,
- msm_mux_reserved12,
msm_mux_cam_mclk,
msm_mux_pll_bypassnl,
msm_mux_qdss_gpio0,
- msm_mux_reserved13,
msm_mux_pll_reset,
msm_mux_qdss_gpio1,
- msm_mux_reserved14,
msm_mux_qdss_gpio2,
- msm_mux_reserved15,
msm_mux_qdss_gpio3,
- msm_mux_reserved16,
msm_mux_cci_i2c,
msm_mux_qup1,
msm_mux_qdss_gpio4,
- msm_mux_reserved17,
msm_mux_qdss_gpio5,
- msm_mux_reserved18,
msm_mux_qdss_gpio6,
- msm_mux_reserved19,
msm_mux_qdss_gpio7,
- msm_mux_reserved20,
msm_mux_cci_timer0,
msm_mux_gcc_gp2,
msm_mux_qdss_gpio8,
- msm_mux_reserved21,
msm_mux_cci_timer1,
msm_mux_gcc_gp3,
msm_mux_qdss_gpio,
- msm_mux_reserved22,
msm_mux_cci_timer2,
msm_mux_qdss_gpio9,
- msm_mux_reserved23,
msm_mux_cci_timer3,
msm_mux_cci_async,
msm_mux_qdss_gpio10,
- msm_mux_reserved24,
msm_mux_cci_timer4,
msm_mux_qdss_gpio11,
- msm_mux_reserved25,
msm_mux_qdss_gpio12,
msm_mux_JITTER_BIST,
- msm_mux_reserved26,
msm_mux_qup2,
msm_mux_qdss_gpio13,
msm_mux_PLL_BIST,
- msm_mux_reserved27,
msm_mux_qdss_gpio14,
msm_mux_AGERA_PLL,
- msm_mux_reserved28,
msm_mux_phase_flag1,
msm_mux_qdss_gpio15,
msm_mux_atest_tsens,
- msm_mux_reserved29,
msm_mux_phase_flag2,
- msm_mux_reserved30,
msm_mux_qup11,
msm_mux_qup14,
- msm_mux_reserved31,
- msm_mux_reserved32,
- msm_mux_reserved33,
- msm_mux_reserved34,
msm_mux_pci_e0,
msm_mux_QUP_L4,
- msm_mux_reserved35,
msm_mux_QUP_L5,
- msm_mux_reserved36,
msm_mux_QUP_L6,
- msm_mux_reserved37,
msm_mux_usb_phy,
- msm_mux_reserved38,
msm_mux_lpass_slimbus,
- msm_mux_reserved39,
msm_mux_sd_write,
msm_mux_tsif1_error,
- msm_mux_reserved40,
msm_mux_qup3,
- msm_mux_reserved41,
- msm_mux_reserved42,
- msm_mux_reserved43,
- msm_mux_reserved44,
- msm_mux_bt_reset,
msm_mux_qup6,
- msm_mux_reserved45,
- msm_mux_reserved46,
- msm_mux_reserved47,
- msm_mux_reserved124,
- msm_mux_reserved125,
- msm_mux_reserved126,
- msm_mux_reserved127,
- msm_mux_reserved128,
- msm_mux_reserved129,
- msm_mux_qlink_request,
- msm_mux_reserved130,
- msm_mux_qlink_enable,
- msm_mux_reserved131,
- msm_mux_reserved132,
- msm_mux_reserved133,
- msm_mux_reserved134,
- msm_mux_pa_indicator,
- msm_mux_reserved135,
- msm_mux_reserved136,
- msm_mux_phase_flag26,
- msm_mux_reserved137,
- msm_mux_phase_flag27,
- msm_mux_reserved138,
- msm_mux_phase_flag28,
- msm_mux_reserved139,
- msm_mux_phase_flag6,
- msm_mux_reserved140,
- msm_mux_phase_flag29,
- msm_mux_reserved141,
- msm_mux_phase_flag30,
- msm_mux_reserved142,
- msm_mux_phase_flag31,
- msm_mux_reserved143,
- msm_mux_mss_lte,
- msm_mux_reserved144,
- msm_mux_reserved145,
- msm_mux_reserved146,
- msm_mux_reserved147,
- msm_mux_reserved148,
- msm_mux_reserved149,
- msm_mux_reserved48,
msm_mux_qup12,
- msm_mux_reserved49,
- msm_mux_reserved50,
- msm_mux_reserved51,
msm_mux_phase_flag16,
- msm_mux_reserved52,
msm_mux_qup10,
msm_mux_phase_flag11,
- msm_mux_reserved53,
msm_mux_GP_PDM0,
msm_mux_phase_flag12,
msm_mux_wlan1_adc1,
msm_mux_atest_usb13,
msm_mux_ddr_pxi1,
- msm_mux_reserved54,
msm_mux_phase_flag13,
msm_mux_wlan1_adc0,
msm_mux_atest_usb12,
- msm_mux_reserved55,
msm_mux_phase_flag17,
- msm_mux_reserved56,
msm_mux_qua_mi2s,
msm_mux_gcc_gp1,
msm_mux_phase_flag18,
- msm_mux_reserved57,
msm_mux_pri_mi2s,
msm_mux_qup8,
msm_mux_wsa_clk,
- msm_mux_reserved65,
msm_mux_pri_mi2s_ws,
msm_mux_wsa_data,
- msm_mux_reserved66,
- msm_mux_wsa_en,
msm_mux_atest_usb2,
- msm_mux_reserved67,
msm_mux_atest_usb23,
- msm_mux_reserved68,
msm_mux_ter_mi2s,
msm_mux_phase_flag8,
msm_mux_atest_usb22,
- msm_mux_reserved75,
msm_mux_phase_flag9,
msm_mux_atest_usb21,
- msm_mux_reserved76,
msm_mux_phase_flag4,
msm_mux_atest_usb20,
- msm_mux_reserved77,
- msm_mux_ssc_irq,
- msm_mux_reserved78,
msm_mux_sec_mi2s,
msm_mux_GP_PDM2,
- msm_mux_reserved79,
- msm_mux_reserved80,
msm_mux_qup15,
- msm_mux_reserved81,
- msm_mux_reserved82,
- msm_mux_reserved83,
- msm_mux_reserved84,
msm_mux_qup5,
- msm_mux_reserved85,
msm_mux_copy_gp,
- msm_mux_reserved86,
- msm_mux_reserved87,
- msm_mux_reserved88,
msm_mux_tsif1_clk,
msm_mux_qup4,
msm_mux_tgu_ch3,
msm_mux_phase_flag10,
- msm_mux_reserved89,
msm_mux_tsif1_en,
msm_mux_mdp_vsync0,
msm_mux_mdp_vsync1,
@@ -645,83 +547,61 @@
msm_mux_mdp_vsync3,
msm_mux_tgu_ch0,
msm_mux_phase_flag0,
- msm_mux_reserved90,
msm_mux_tsif1_data,
msm_mux_sdc4_cmd,
msm_mux_tgu_ch1,
- msm_mux_reserved91,
msm_mux_tsif2_error,
msm_mux_sdc43,
msm_mux_vfr_1,
msm_mux_tgu_ch2,
- msm_mux_reserved92,
msm_mux_tsif2_clk,
msm_mux_sdc4_clk,
msm_mux_qup7,
- msm_mux_reserved93,
msm_mux_tsif2_en,
msm_mux_sdc42,
- msm_mux_reserved94,
msm_mux_tsif2_data,
msm_mux_sdc41,
- msm_mux_reserved95,
msm_mux_tsif2_sync,
msm_mux_sdc40,
msm_mux_phase_flag3,
- msm_mux_reserved96,
msm_mux_ldo_en,
- msm_mux_reserved97,
msm_mux_ldo_update,
- msm_mux_reserved98,
msm_mux_phase_flag14,
msm_mux_prng_rosc,
- msm_mux_reserved99,
msm_mux_phase_flag15,
- msm_mux_reserved100,
msm_mux_phase_flag5,
- msm_mux_reserved101,
msm_mux_pci_e1,
- msm_mux_reserved102,
msm_mux_COPY_PHASE,
- msm_mux_reserved103,
msm_mux_uim2_data,
msm_mux_qup13,
- msm_mux_reserved105,
msm_mux_uim2_clk,
- msm_mux_reserved106,
msm_mux_uim2_reset,
- msm_mux_reserved107,
msm_mux_uim2_present,
- msm_mux_reserved108,
msm_mux_uim1_data,
- msm_mux_reserved109,
msm_mux_uim1_clk,
- msm_mux_reserved110,
msm_mux_uim1_reset,
- msm_mux_reserved111,
msm_mux_uim1_present,
- msm_mux_reserved112,
msm_mux_uim_batt,
msm_mux_edp_hot,
- msm_mux_reserved113,
msm_mux_NAV_PPS,
msm_mux_GPS_TX,
- msm_mux_reserved114,
- msm_mux_reserved115,
- msm_mux_reserved116,
msm_mux_atest_char,
- msm_mux_reserved117,
msm_mux_adsp_ext,
msm_mux_atest_char3,
- msm_mux_reserved118,
msm_mux_atest_char2,
- msm_mux_reserved119,
msm_mux_atest_char1,
- msm_mux_reserved120,
msm_mux_atest_char0,
- msm_mux_reserved121,
- msm_mux_reserved122,
- msm_mux_reserved123,
+ msm_mux_qlink_request,
+ msm_mux_qlink_enable,
+ msm_mux_pa_indicator,
+ msm_mux_phase_flag26,
+ msm_mux_phase_flag27,
+ msm_mux_phase_flag28,
+ msm_mux_phase_flag6,
+ msm_mux_phase_flag29,
+ msm_mux_phase_flag30,
+ msm_mux_phase_flag31,
+ msm_mux_mss_lte,
msm_mux_NA,
};
@@ -735,31 +615,21 @@
"gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
"gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
"gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
- "gpio43", "gpio44", "gpio46", "gpio47", "gpio48", "gpio49", "gpio50",
- "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio57",
- "gpio65", "gpio66", "gpio75", "gpio76", "gpio77", "gpio81", "gpio82",
- "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88", "gpio89",
- "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96",
- "gpio97", "gpio98", "gpio99", "gpio100", "gpio101", "gpio102",
- "gpio103", "gpio105", "gpio106", "gpio107", "gpio108", "gpio109",
- "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", "gpio115",
- "gpio116", "gpio126", "gpio127", "gpio128", "gpio129", "gpio130",
- "gpio131", "gpio132", "gpio133", "gpio134", "gpio135", "gpio136",
- "gpio137", "gpio138", "gpio139", "gpio140", "gpio141", "gpio142",
- "gpio143", "gpio144", "gpio145", "gpio146", "gpio147", "gpio148",
- "gpio149",
-};
-static const char * const reserved0_groups[] = {
- "gpio0",
-};
-static const char * const reserved1_groups[] = {
- "gpio1",
-};
-static const char * const reserved2_groups[] = {
- "gpio2",
-};
-static const char * const reserved3_groups[] = {
- "gpio3",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio65", "gpio66", "gpio67", "gpio68", "gpio75", "gpio76",
+ "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83",
+ "gpio84", "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90",
+ "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97",
+ "gpio98", "gpio99", "gpio100", "gpio101", "gpio102", "gpio103",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149",
};
static const char * const qup9_groups[] = {
"gpio4", "gpio5", "gpio6", "gpio7",
@@ -767,18 +637,9 @@
static const char * const qdss_cti_groups[] = {
"gpio4", "gpio5", "gpio51", "gpio52", "gpio90", "gpio91",
};
-static const char * const reserved4_groups[] = {
- "gpio4",
-};
-static const char * const reserved5_groups[] = {
- "gpio5",
-};
static const char * const ddr_pxi0_groups[] = {
"gpio6", "gpio7",
};
-static const char * const reserved6_groups[] = {
- "gpio6",
-};
static const char * const ddr_bist_groups[] = {
"gpio7", "gpio8", "gpio9", "gpio10",
};
@@ -791,24 +652,15 @@
static const char * const atest_usb1_groups[] = {
"gpio7",
};
-static const char * const reserved7_groups[] = {
- "gpio7",
-};
static const char * const qup_l4_groups[] = {
"gpio8", "gpio105", "gpio123",
};
static const char * const GP_PDM1_groups[] = {
"gpio8", "gpio66",
};
-static const char * const reserved8_groups[] = {
- "gpio8",
-};
static const char * const qup_l5_groups[] = {
"gpio9", "gpio106", "gpio124",
};
-static const char * const reserved9_groups[] = {
- "gpio9",
-};
static const char * const mdp_vsync_groups[] = {
"gpio10", "gpio11", "gpio12", "gpio97", "gpio98",
};
@@ -824,9 +676,6 @@
static const char * const ddr_pxi2_groups[] = {
"gpio10", "gpio11",
};
-static const char * const reserved10_groups[] = {
- "gpio10",
-};
static const char * const edp_lcd_groups[] = {
"gpio11",
};
@@ -839,9 +688,6 @@
static const char * const atest_usb10_groups[] = {
"gpio11",
};
-static const char * const reserved11_groups[] = {
- "gpio11",
-};
static const char * const m_voc_groups[] = {
"gpio12",
};
@@ -851,9 +697,6 @@
static const char * const ddr_pxi3_groups[] = {
"gpio12", "gpio13",
};
-static const char * const reserved12_groups[] = {
- "gpio12",
-};
static const char * const cam_mclk_groups[] = {
"gpio13", "gpio14", "gpio15", "gpio16",
};
@@ -863,30 +706,18 @@
static const char * const qdss_gpio0_groups[] = {
"gpio13", "gpio117",
};
-static const char * const reserved13_groups[] = {
- "gpio13",
-};
static const char * const pll_reset_groups[] = {
"gpio14",
};
static const char * const qdss_gpio1_groups[] = {
"gpio14", "gpio118",
};
-static const char * const reserved14_groups[] = {
- "gpio14",
-};
static const char * const qdss_gpio2_groups[] = {
"gpio15", "gpio119",
};
-static const char * const reserved15_groups[] = {
- "gpio15",
-};
static const char * const qdss_gpio3_groups[] = {
"gpio16", "gpio120",
};
-static const char * const reserved16_groups[] = {
- "gpio16",
-};
static const char * const cci_i2c_groups[] = {
"gpio17", "gpio18", "gpio19", "gpio20",
};
@@ -896,27 +727,15 @@
static const char * const qdss_gpio4_groups[] = {
"gpio17", "gpio121",
};
-static const char * const reserved17_groups[] = {
- "gpio17",
-};
static const char * const qdss_gpio5_groups[] = {
"gpio18", "gpio122",
};
-static const char * const reserved18_groups[] = {
- "gpio18",
-};
static const char * const qdss_gpio6_groups[] = {
"gpio19", "gpio41",
};
-static const char * const reserved19_groups[] = {
- "gpio19",
-};
static const char * const qdss_gpio7_groups[] = {
"gpio20", "gpio42",
};
-static const char * const reserved20_groups[] = {
- "gpio20",
-};
static const char * const cci_timer0_groups[] = {
"gpio21",
};
@@ -926,9 +745,6 @@
static const char * const qdss_gpio8_groups[] = {
"gpio21", "gpio75",
};
-static const char * const reserved21_groups[] = {
- "gpio21",
-};
static const char * const cci_timer1_groups[] = {
"gpio22",
};
@@ -938,18 +754,12 @@
static const char * const qdss_gpio_groups[] = {
"gpio22", "gpio30", "gpio123", "gpio124",
};
-static const char * const reserved22_groups[] = {
- "gpio22",
-};
static const char * const cci_timer2_groups[] = {
"gpio23",
};
static const char * const qdss_gpio9_groups[] = {
"gpio23", "gpio76",
};
-static const char * const reserved23_groups[] = {
- "gpio23",
-};
static const char * const cci_timer3_groups[] = {
"gpio24",
};
@@ -959,27 +769,18 @@
static const char * const qdss_gpio10_groups[] = {
"gpio24", "gpio77",
};
-static const char * const reserved24_groups[] = {
- "gpio24",
-};
static const char * const cci_timer4_groups[] = {
"gpio25",
};
static const char * const qdss_gpio11_groups[] = {
"gpio25", "gpio79",
};
-static const char * const reserved25_groups[] = {
- "gpio25",
-};
static const char * const qdss_gpio12_groups[] = {
"gpio26", "gpio80",
};
static const char * const JITTER_BIST_groups[] = {
"gpio26", "gpio35",
};
-static const char * const reserved26_groups[] = {
- "gpio26",
-};
static const char * const qup2_groups[] = {
"gpio27", "gpio28", "gpio29", "gpio30",
};
@@ -989,18 +790,12 @@
static const char * const PLL_BIST_groups[] = {
"gpio27", "gpio36",
};
-static const char * const reserved27_groups[] = {
- "gpio27",
-};
static const char * const qdss_gpio14_groups[] = {
"gpio28", "gpio43",
};
static const char * const AGERA_PLL_groups[] = {
"gpio28", "gpio37",
};
-static const char * const reserved28_groups[] = {
- "gpio28",
-};
static const char * const phase_flag1_groups[] = {
"gpio29",
};
@@ -1010,246 +805,57 @@
static const char * const atest_tsens_groups[] = {
"gpio29",
};
-static const char * const reserved29_groups[] = {
- "gpio29",
-};
static const char * const phase_flag2_groups[] = {
"gpio30",
};
-static const char * const reserved30_groups[] = {
- "gpio30",
-};
static const char * const qup11_groups[] = {
"gpio31", "gpio32", "gpio33", "gpio34",
};
static const char * const qup14_groups[] = {
"gpio31", "gpio32", "gpio33", "gpio34",
};
-static const char * const reserved31_groups[] = {
- "gpio31",
-};
-static const char * const reserved32_groups[] = {
- "gpio32",
-};
-static const char * const reserved33_groups[] = {
- "gpio33",
-};
-static const char * const reserved34_groups[] = {
- "gpio34",
-};
static const char * const pci_e0_groups[] = {
"gpio35", "gpio36",
};
static const char * const QUP_L4_groups[] = {
"gpio35", "gpio75",
};
-static const char * const reserved35_groups[] = {
- "gpio35",
-};
static const char * const QUP_L5_groups[] = {
"gpio36", "gpio76",
};
-static const char * const reserved36_groups[] = {
- "gpio36",
-};
static const char * const QUP_L6_groups[] = {
"gpio37", "gpio77",
};
-static const char * const reserved37_groups[] = {
- "gpio37",
-};
static const char * const usb_phy_groups[] = {
"gpio38",
};
-static const char * const reserved38_groups[] = {
- "gpio38",
-};
static const char * const lpass_slimbus_groups[] = {
"gpio39",
};
-static const char * const reserved39_groups[] = {
- "gpio39",
-};
static const char * const sd_write_groups[] = {
"gpio40",
};
static const char * const tsif1_error_groups[] = {
"gpio40",
};
-static const char * const reserved40_groups[] = {
- "gpio40",
-};
static const char * const qup3_groups[] = {
"gpio41", "gpio42", "gpio43", "gpio44",
};
-static const char * const reserved41_groups[] = {
- "gpio41",
-};
-static const char * const reserved42_groups[] = {
- "gpio42",
-};
-static const char * const reserved43_groups[] = {
- "gpio43",
-};
-static const char * const reserved44_groups[] = {
- "gpio44",
-};
-static const char * const bt_reset_groups[] = {
- "gpio45",
-};
static const char * const qup6_groups[] = {
"gpio45", "gpio46", "gpio47", "gpio48",
};
-static const char * const reserved45_groups[] = {
- "gpio45",
-};
-static const char * const reserved46_groups[] = {
- "gpio46",
-};
-static const char * const reserved47_groups[] = {
- "gpio47",
-};
-static const char * const reserved124_groups[] = {
- "gpio124",
-};
-static const char * const reserved125_groups[] = {
- "gpio125",
-};
-static const char * const reserved126_groups[] = {
- "gpio126",
-};
-static const char * const reserved127_groups[] = {
- "gpio127",
-};
-static const char * const reserved128_groups[] = {
- "gpio128",
-};
-static const char * const reserved129_groups[] = {
- "gpio129",
-};
-static const char * const qlink_request_groups[] = {
- "gpio130",
-};
-static const char * const reserved130_groups[] = {
- "gpio130",
-};
-static const char * const qlink_enable_groups[] = {
- "gpio131",
-};
-static const char * const reserved131_groups[] = {
- "gpio131",
-};
-static const char * const reserved132_groups[] = {
- "gpio132",
-};
-static const char * const reserved133_groups[] = {
- "gpio133",
-};
-static const char * const reserved134_groups[] = {
- "gpio134",
-};
-static const char * const pa_indicator_groups[] = {
- "gpio135",
-};
-static const char * const reserved135_groups[] = {
- "gpio135",
-};
-static const char * const reserved136_groups[] = {
- "gpio136",
-};
-static const char * const phase_flag26_groups[] = {
- "gpio137",
-};
-static const char * const reserved137_groups[] = {
- "gpio137",
-};
-static const char * const phase_flag27_groups[] = {
- "gpio138",
-};
-static const char * const reserved138_groups[] = {
- "gpio138",
-};
-static const char * const phase_flag28_groups[] = {
- "gpio139",
-};
-static const char * const reserved139_groups[] = {
- "gpio139",
-};
-static const char * const phase_flag6_groups[] = {
- "gpio140",
-};
-static const char * const reserved140_groups[] = {
- "gpio140",
-};
-static const char * const phase_flag29_groups[] = {
- "gpio141",
-};
-static const char * const reserved141_groups[] = {
- "gpio141",
-};
-static const char * const phase_flag30_groups[] = {
- "gpio142",
-};
-static const char * const reserved142_groups[] = {
- "gpio142",
-};
-static const char * const phase_flag31_groups[] = {
- "gpio143",
-};
-static const char * const reserved143_groups[] = {
- "gpio143",
-};
-static const char * const mss_lte_groups[] = {
- "gpio144", "gpio145",
-};
-static const char * const reserved144_groups[] = {
- "gpio144",
-};
-static const char * const reserved145_groups[] = {
- "gpio145",
-};
-static const char * const reserved146_groups[] = {
- "gpio146",
-};
-static const char * const reserved147_groups[] = {
- "gpio147",
-};
-static const char * const reserved148_groups[] = {
- "gpio148",
-};
-static const char * const reserved149_groups[] = {
- "gpio149", "gpio149",
-};
-static const char * const reserved48_groups[] = {
- "gpio48",
-};
static const char * const qup12_groups[] = {
"gpio49", "gpio50", "gpio51", "gpio52",
};
-static const char * const reserved49_groups[] = {
- "gpio49",
-};
-static const char * const reserved50_groups[] = {
- "gpio50",
-};
-static const char * const reserved51_groups[] = {
- "gpio51",
-};
static const char * const phase_flag16_groups[] = {
"gpio52",
};
-static const char * const reserved52_groups[] = {
- "gpio52",
-};
static const char * const qup10_groups[] = {
"gpio53", "gpio54", "gpio55", "gpio56",
};
static const char * const phase_flag11_groups[] = {
"gpio53",
};
-static const char * const reserved53_groups[] = {
- "gpio53",
-};
static const char * const GP_PDM0_groups[] = {
"gpio54", "gpio95",
};
@@ -1265,9 +871,6 @@
static const char * const ddr_pxi1_groups[] = {
"gpio54", "gpio55",
};
-static const char * const reserved54_groups[] = {
- "gpio54",
-};
static const char * const phase_flag13_groups[] = {
"gpio55",
};
@@ -1277,15 +880,9 @@
static const char * const atest_usb12_groups[] = {
"gpio55",
};
-static const char * const reserved55_groups[] = {
- "gpio55",
-};
static const char * const phase_flag17_groups[] = {
"gpio56",
};
-static const char * const reserved56_groups[] = {
- "gpio56",
-};
static const char * const qua_mi2s_groups[] = {
"gpio57",
};
@@ -1295,9 +892,6 @@
static const char * const phase_flag18_groups[] = {
"gpio57",
};
-static const char * const reserved57_groups[] = {
- "gpio57",
-};
static const char * const pri_mi2s_groups[] = {
"gpio65", "gpio67", "gpio68",
};
@@ -1307,33 +901,18 @@
static const char * const wsa_clk_groups[] = {
"gpio65",
};
-static const char * const reserved65_groups[] = {
- "gpio65",
-};
static const char * const pri_mi2s_ws_groups[] = {
"gpio66",
};
static const char * const wsa_data_groups[] = {
"gpio66",
};
-static const char * const reserved66_groups[] = {
- "gpio66",
-};
-static const char * const wsa_en_groups[] = {
- "gpio67", "gpio68",
-};
static const char * const atest_usb2_groups[] = {
"gpio67",
};
-static const char * const reserved67_groups[] = {
- "gpio67",
-};
static const char * const atest_usb23_groups[] = {
"gpio68",
};
-static const char * const reserved68_groups[] = {
- "gpio68",
-};
static const char * const ter_mi2s_groups[] = {
"gpio75", "gpio76", "gpio77", "gpio78",
};
@@ -1343,79 +922,33 @@
static const char * const atest_usb22_groups[] = {
"gpio75",
};
-static const char * const reserved75_groups[] = {
- "gpio75",
-};
static const char * const phase_flag9_groups[] = {
"gpio76",
};
static const char * const atest_usb21_groups[] = {
"gpio76",
};
-static const char * const reserved76_groups[] = {
- "gpio76",
-};
static const char * const phase_flag4_groups[] = {
"gpio77",
};
static const char * const atest_usb20_groups[] = {
"gpio77",
};
-static const char * const reserved77_groups[] = {
- "gpio77",
-};
-static const char * const ssc_irq_groups[] = {
- "gpio78", "gpio79", "gpio80", "gpio117", "gpio118", "gpio119",
- "gpio120", "gpio121", "gpio122", "gpio123", "gpio124", "gpio125",
-};
-static const char * const reserved78_groups[] = {
- "gpio78",
-};
static const char * const sec_mi2s_groups[] = {
"gpio79", "gpio80", "gpio81", "gpio82", "gpio83",
};
static const char * const GP_PDM2_groups[] = {
"gpio79",
};
-static const char * const reserved79_groups[] = {
- "gpio79",
-};
-static const char * const reserved80_groups[] = {
- "gpio80",
-};
static const char * const qup15_groups[] = {
"gpio81", "gpio82", "gpio83", "gpio84",
};
-static const char * const reserved81_groups[] = {
- "gpio81",
-};
-static const char * const reserved82_groups[] = {
- "gpio82",
-};
-static const char * const reserved83_groups[] = {
- "gpio83",
-};
-static const char * const reserved84_groups[] = {
- "gpio84",
-};
static const char * const qup5_groups[] = {
"gpio85", "gpio86", "gpio87", "gpio88",
};
-static const char * const reserved85_groups[] = {
- "gpio85",
-};
static const char * const copy_gp_groups[] = {
"gpio86",
};
-static const char * const reserved86_groups[] = {
- "gpio86",
-};
-static const char * const reserved87_groups[] = {
- "gpio87",
-};
-static const char * const reserved88_groups[] = {
- "gpio88",
-};
static const char * const tsif1_clk_groups[] = {
"gpio89",
};
@@ -1428,9 +961,6 @@
static const char * const phase_flag10_groups[] = {
"gpio89",
};
-static const char * const reserved89_groups[] = {
- "gpio89",
-};
static const char * const tsif1_en_groups[] = {
"gpio90",
};
@@ -1452,9 +982,6 @@
static const char * const phase_flag0_groups[] = {
"gpio90",
};
-static const char * const reserved90_groups[] = {
- "gpio90",
-};
static const char * const tsif1_data_groups[] = {
"gpio91",
};
@@ -1464,9 +991,6 @@
static const char * const tgu_ch1_groups[] = {
"gpio91",
};
-static const char * const reserved91_groups[] = {
- "gpio91",
-};
static const char * const tsif2_error_groups[] = {
"gpio92",
};
@@ -1479,9 +1003,6 @@
static const char * const tgu_ch2_groups[] = {
"gpio92",
};
-static const char * const reserved92_groups[] = {
- "gpio92",
-};
static const char * const tsif2_clk_groups[] = {
"gpio93",
};
@@ -1491,27 +1012,18 @@
static const char * const qup7_groups[] = {
"gpio93", "gpio94", "gpio95", "gpio96",
};
-static const char * const reserved93_groups[] = {
- "gpio93",
-};
static const char * const tsif2_en_groups[] = {
"gpio94",
};
static const char * const sdc42_groups[] = {
"gpio94",
};
-static const char * const reserved94_groups[] = {
- "gpio94",
-};
static const char * const tsif2_data_groups[] = {
"gpio95",
};
static const char * const sdc41_groups[] = {
"gpio95",
};
-static const char * const reserved95_groups[] = {
- "gpio95",
-};
static const char * const tsif2_sync_groups[] = {
"gpio96",
};
@@ -1521,114 +1033,63 @@
static const char * const phase_flag3_groups[] = {
"gpio96",
};
-static const char * const reserved96_groups[] = {
- "gpio96",
-};
static const char * const ldo_en_groups[] = {
"gpio97",
};
-static const char * const reserved97_groups[] = {
- "gpio97",
-};
static const char * const ldo_update_groups[] = {
"gpio98",
};
-static const char * const reserved98_groups[] = {
- "gpio98",
-};
static const char * const phase_flag14_groups[] = {
"gpio99",
};
static const char * const prng_rosc_groups[] = {
"gpio99", "gpio102",
};
-static const char * const reserved99_groups[] = {
- "gpio99",
-};
static const char * const phase_flag15_groups[] = {
"gpio100",
};
-static const char * const reserved100_groups[] = {
- "gpio100",
-};
static const char * const phase_flag5_groups[] = {
"gpio101",
};
-static const char * const reserved101_groups[] = {
- "gpio101",
-};
static const char * const pci_e1_groups[] = {
"gpio102", "gpio103",
};
-static const char * const reserved102_groups[] = {
- "gpio102",
-};
static const char * const COPY_PHASE_groups[] = {
"gpio103",
};
-static const char * const reserved103_groups[] = {
- "gpio103",
-};
static const char * const uim2_data_groups[] = {
"gpio105",
};
static const char * const qup13_groups[] = {
"gpio105", "gpio106", "gpio107", "gpio108",
};
-static const char * const reserved105_groups[] = {
- "gpio105",
-};
static const char * const uim2_clk_groups[] = {
"gpio106",
};
-static const char * const reserved106_groups[] = {
- "gpio106",
-};
static const char * const uim2_reset_groups[] = {
"gpio107",
};
-static const char * const reserved107_groups[] = {
- "gpio107",
-};
static const char * const uim2_present_groups[] = {
"gpio108",
};
-static const char * const reserved108_groups[] = {
- "gpio108",
-};
static const char * const uim1_data_groups[] = {
"gpio109",
};
-static const char * const reserved109_groups[] = {
- "gpio109",
-};
static const char * const uim1_clk_groups[] = {
"gpio110",
};
-static const char * const reserved110_groups[] = {
- "gpio110",
-};
static const char * const uim1_reset_groups[] = {
"gpio111",
};
-static const char * const reserved111_groups[] = {
- "gpio111",
-};
static const char * const uim1_present_groups[] = {
"gpio112",
};
-static const char * const reserved112_groups[] = {
- "gpio112",
-};
static const char * const uim_batt_groups[] = {
"gpio113",
};
static const char * const edp_hot_groups[] = {
"gpio113",
};
-static const char * const reserved113_groups[] = {
- "gpio113",
-};
static const char * const NAV_PPS_groups[] = {
"gpio114", "gpio114", "gpio115", "gpio115", "gpio128", "gpio128",
"gpio129", "gpio129", "gpio143", "gpio143",
@@ -1636,285 +1097,171 @@
static const char * const GPS_TX_groups[] = {
"gpio114", "gpio115", "gpio128", "gpio129", "gpio143", "gpio145",
};
-static const char * const reserved114_groups[] = {
- "gpio114",
-};
-static const char * const reserved115_groups[] = {
- "gpio115",
-};
-static const char * const reserved116_groups[] = {
- "gpio116",
-};
static const char * const atest_char_groups[] = {
"gpio117",
};
-static const char * const reserved117_groups[] = {
- "gpio117",
-};
static const char * const adsp_ext_groups[] = {
"gpio118",
};
static const char * const atest_char3_groups[] = {
"gpio118",
};
-static const char * const reserved118_groups[] = {
- "gpio118",
-};
static const char * const atest_char2_groups[] = {
"gpio119",
};
-static const char * const reserved119_groups[] = {
- "gpio119",
-};
static const char * const atest_char1_groups[] = {
"gpio120",
};
-static const char * const reserved120_groups[] = {
- "gpio120",
-};
static const char * const atest_char0_groups[] = {
"gpio121",
};
-static const char * const reserved121_groups[] = {
- "gpio121",
+static const char * const qlink_request_groups[] = {
+ "gpio130",
};
-static const char * const reserved122_groups[] = {
- "gpio122",
+static const char * const qlink_enable_groups[] = {
+ "gpio131",
};
-static const char * const reserved123_groups[] = {
- "gpio123",
+static const char * const pa_indicator_groups[] = {
+ "gpio135",
+};
+static const char * const phase_flag26_groups[] = {
+ "gpio137",
+};
+static const char * const phase_flag27_groups[] = {
+ "gpio138",
+};
+static const char * const phase_flag28_groups[] = {
+ "gpio139",
+};
+static const char * const phase_flag6_groups[] = {
+ "gpio140",
+};
+static const char * const phase_flag29_groups[] = {
+ "gpio141",
+};
+static const char * const phase_flag30_groups[] = {
+ "gpio142",
+};
+static const char * const phase_flag31_groups[] = {
+ "gpio143",
+};
+static const char * const mss_lte_groups[] = {
+ "gpio144", "gpio145",
};
static const struct msm_function sdm670_functions[] = {
FUNCTION(qup0),
FUNCTION(gpio),
- FUNCTION(reserved0),
- FUNCTION(reserved1),
- FUNCTION(reserved2),
- FUNCTION(reserved3),
FUNCTION(qup9),
FUNCTION(qdss_cti),
- FUNCTION(reserved4),
- FUNCTION(reserved5),
FUNCTION(ddr_pxi0),
- FUNCTION(reserved6),
FUNCTION(ddr_bist),
FUNCTION(atest_tsens2),
FUNCTION(vsense_trigger),
FUNCTION(atest_usb1),
- FUNCTION(reserved7),
FUNCTION(qup_l4),
FUNCTION(GP_PDM1),
- FUNCTION(reserved8),
FUNCTION(qup_l5),
- FUNCTION(reserved9),
FUNCTION(mdp_vsync),
FUNCTION(qup_l6),
FUNCTION(wlan2_adc1),
FUNCTION(atest_usb11),
FUNCTION(ddr_pxi2),
- FUNCTION(reserved10),
FUNCTION(edp_lcd),
FUNCTION(dbg_out),
FUNCTION(wlan2_adc0),
FUNCTION(atest_usb10),
- FUNCTION(reserved11),
FUNCTION(m_voc),
FUNCTION(tsif1_sync),
FUNCTION(ddr_pxi3),
- FUNCTION(reserved12),
FUNCTION(cam_mclk),
FUNCTION(pll_bypassnl),
FUNCTION(qdss_gpio0),
- FUNCTION(reserved13),
FUNCTION(pll_reset),
FUNCTION(qdss_gpio1),
- FUNCTION(reserved14),
FUNCTION(qdss_gpio2),
- FUNCTION(reserved15),
FUNCTION(qdss_gpio3),
- FUNCTION(reserved16),
FUNCTION(cci_i2c),
FUNCTION(qup1),
FUNCTION(qdss_gpio4),
- FUNCTION(reserved17),
FUNCTION(qdss_gpio5),
- FUNCTION(reserved18),
FUNCTION(qdss_gpio6),
- FUNCTION(reserved19),
FUNCTION(qdss_gpio7),
- FUNCTION(reserved20),
FUNCTION(cci_timer0),
FUNCTION(gcc_gp2),
FUNCTION(qdss_gpio8),
- FUNCTION(reserved21),
FUNCTION(cci_timer1),
FUNCTION(gcc_gp3),
FUNCTION(qdss_gpio),
- FUNCTION(reserved22),
FUNCTION(cci_timer2),
FUNCTION(qdss_gpio9),
- FUNCTION(reserved23),
FUNCTION(cci_timer3),
FUNCTION(cci_async),
FUNCTION(qdss_gpio10),
- FUNCTION(reserved24),
FUNCTION(cci_timer4),
FUNCTION(qdss_gpio11),
- FUNCTION(reserved25),
FUNCTION(qdss_gpio12),
FUNCTION(JITTER_BIST),
- FUNCTION(reserved26),
FUNCTION(qup2),
FUNCTION(qdss_gpio13),
FUNCTION(PLL_BIST),
- FUNCTION(reserved27),
FUNCTION(qdss_gpio14),
FUNCTION(AGERA_PLL),
- FUNCTION(reserved28),
FUNCTION(phase_flag1),
FUNCTION(qdss_gpio15),
FUNCTION(atest_tsens),
- FUNCTION(reserved29),
FUNCTION(phase_flag2),
- FUNCTION(reserved30),
FUNCTION(qup11),
FUNCTION(qup14),
- FUNCTION(reserved31),
- FUNCTION(reserved32),
- FUNCTION(reserved33),
- FUNCTION(reserved34),
FUNCTION(pci_e0),
FUNCTION(QUP_L4),
- FUNCTION(reserved35),
FUNCTION(QUP_L5),
- FUNCTION(reserved36),
FUNCTION(QUP_L6),
- FUNCTION(reserved37),
FUNCTION(usb_phy),
- FUNCTION(reserved38),
FUNCTION(lpass_slimbus),
- FUNCTION(reserved39),
FUNCTION(sd_write),
FUNCTION(tsif1_error),
- FUNCTION(reserved40),
FUNCTION(qup3),
- FUNCTION(reserved41),
- FUNCTION(reserved42),
- FUNCTION(reserved43),
- FUNCTION(reserved44),
- FUNCTION(bt_reset),
FUNCTION(qup6),
- FUNCTION(reserved45),
- FUNCTION(reserved46),
- FUNCTION(reserved47),
- FUNCTION(reserved124),
- FUNCTION(reserved125),
- FUNCTION(reserved126),
- FUNCTION(reserved127),
- FUNCTION(reserved128),
- FUNCTION(reserved129),
- FUNCTION(qlink_request),
- FUNCTION(reserved130),
- FUNCTION(qlink_enable),
- FUNCTION(reserved131),
- FUNCTION(reserved132),
- FUNCTION(reserved133),
- FUNCTION(reserved134),
- FUNCTION(pa_indicator),
- FUNCTION(reserved135),
- FUNCTION(reserved136),
- FUNCTION(phase_flag26),
- FUNCTION(reserved137),
- FUNCTION(phase_flag27),
- FUNCTION(reserved138),
- FUNCTION(phase_flag28),
- FUNCTION(reserved139),
- FUNCTION(phase_flag6),
- FUNCTION(reserved140),
- FUNCTION(phase_flag29),
- FUNCTION(reserved141),
- FUNCTION(phase_flag30),
- FUNCTION(reserved142),
- FUNCTION(phase_flag31),
- FUNCTION(reserved143),
- FUNCTION(mss_lte),
- FUNCTION(reserved144),
- FUNCTION(reserved145),
- FUNCTION(reserved146),
- FUNCTION(reserved147),
- FUNCTION(reserved148),
- FUNCTION(reserved149),
- FUNCTION(reserved48),
FUNCTION(qup12),
- FUNCTION(reserved49),
- FUNCTION(reserved50),
- FUNCTION(reserved51),
FUNCTION(phase_flag16),
- FUNCTION(reserved52),
FUNCTION(qup10),
FUNCTION(phase_flag11),
- FUNCTION(reserved53),
FUNCTION(GP_PDM0),
FUNCTION(phase_flag12),
FUNCTION(wlan1_adc1),
FUNCTION(atest_usb13),
FUNCTION(ddr_pxi1),
- FUNCTION(reserved54),
FUNCTION(phase_flag13),
FUNCTION(wlan1_adc0),
FUNCTION(atest_usb12),
- FUNCTION(reserved55),
FUNCTION(phase_flag17),
- FUNCTION(reserved56),
FUNCTION(qua_mi2s),
FUNCTION(gcc_gp1),
FUNCTION(phase_flag18),
- FUNCTION(reserved57),
FUNCTION(pri_mi2s),
FUNCTION(qup8),
FUNCTION(wsa_clk),
- FUNCTION(reserved65),
FUNCTION(pri_mi2s_ws),
FUNCTION(wsa_data),
- FUNCTION(reserved66),
- FUNCTION(wsa_en),
FUNCTION(atest_usb2),
- FUNCTION(reserved67),
FUNCTION(atest_usb23),
- FUNCTION(reserved68),
FUNCTION(ter_mi2s),
FUNCTION(phase_flag8),
FUNCTION(atest_usb22),
- FUNCTION(reserved75),
FUNCTION(phase_flag9),
FUNCTION(atest_usb21),
- FUNCTION(reserved76),
FUNCTION(phase_flag4),
FUNCTION(atest_usb20),
- FUNCTION(reserved77),
- FUNCTION(ssc_irq),
- FUNCTION(reserved78),
FUNCTION(sec_mi2s),
FUNCTION(GP_PDM2),
- FUNCTION(reserved79),
- FUNCTION(reserved80),
FUNCTION(qup15),
- FUNCTION(reserved81),
- FUNCTION(reserved82),
- FUNCTION(reserved83),
- FUNCTION(reserved84),
FUNCTION(qup5),
- FUNCTION(reserved85),
FUNCTION(copy_gp),
- FUNCTION(reserved86),
- FUNCTION(reserved87),
- FUNCTION(reserved88),
FUNCTION(tsif1_clk),
FUNCTION(qup4),
FUNCTION(tgu_ch3),
FUNCTION(phase_flag10),
- FUNCTION(reserved89),
FUNCTION(tsif1_en),
FUNCTION(mdp_vsync0),
FUNCTION(mdp_vsync1),
@@ -1922,326 +1269,320 @@
FUNCTION(mdp_vsync3),
FUNCTION(tgu_ch0),
FUNCTION(phase_flag0),
- FUNCTION(reserved90),
FUNCTION(tsif1_data),
FUNCTION(sdc4_cmd),
FUNCTION(tgu_ch1),
- FUNCTION(reserved91),
FUNCTION(tsif2_error),
FUNCTION(sdc43),
FUNCTION(vfr_1),
FUNCTION(tgu_ch2),
- FUNCTION(reserved92),
FUNCTION(tsif2_clk),
FUNCTION(sdc4_clk),
FUNCTION(qup7),
- FUNCTION(reserved93),
FUNCTION(tsif2_en),
FUNCTION(sdc42),
- FUNCTION(reserved94),
FUNCTION(tsif2_data),
FUNCTION(sdc41),
- FUNCTION(reserved95),
FUNCTION(tsif2_sync),
FUNCTION(sdc40),
FUNCTION(phase_flag3),
- FUNCTION(reserved96),
FUNCTION(ldo_en),
- FUNCTION(reserved97),
FUNCTION(ldo_update),
- FUNCTION(reserved98),
FUNCTION(phase_flag14),
FUNCTION(prng_rosc),
- FUNCTION(reserved99),
FUNCTION(phase_flag15),
- FUNCTION(reserved100),
FUNCTION(phase_flag5),
- FUNCTION(reserved101),
FUNCTION(pci_e1),
- FUNCTION(reserved102),
FUNCTION(COPY_PHASE),
- FUNCTION(reserved103),
FUNCTION(uim2_data),
FUNCTION(qup13),
- FUNCTION(reserved105),
FUNCTION(uim2_clk),
- FUNCTION(reserved106),
FUNCTION(uim2_reset),
- FUNCTION(reserved107),
FUNCTION(uim2_present),
- FUNCTION(reserved108),
FUNCTION(uim1_data),
- FUNCTION(reserved109),
FUNCTION(uim1_clk),
- FUNCTION(reserved110),
FUNCTION(uim1_reset),
- FUNCTION(reserved111),
FUNCTION(uim1_present),
- FUNCTION(reserved112),
FUNCTION(uim_batt),
FUNCTION(edp_hot),
- FUNCTION(reserved113),
FUNCTION(NAV_PPS),
FUNCTION(GPS_TX),
- FUNCTION(reserved114),
- FUNCTION(reserved115),
- FUNCTION(reserved116),
FUNCTION(atest_char),
- FUNCTION(reserved117),
FUNCTION(adsp_ext),
FUNCTION(atest_char3),
- FUNCTION(reserved118),
FUNCTION(atest_char2),
- FUNCTION(reserved119),
FUNCTION(atest_char1),
- FUNCTION(reserved120),
FUNCTION(atest_char0),
- FUNCTION(reserved121),
- FUNCTION(reserved122),
- FUNCTION(reserved123),
+ FUNCTION(qlink_request),
+ FUNCTION(qlink_enable),
+ FUNCTION(pa_indicator),
+ FUNCTION(phase_flag26),
+ FUNCTION(phase_flag27),
+ FUNCTION(phase_flag28),
+ FUNCTION(phase_flag6),
+ FUNCTION(phase_flag29),
+ FUNCTION(phase_flag30),
+ FUNCTION(phase_flag31),
+ FUNCTION(mss_lte),
};
+/* Every pin is maintained as a single group, and missing or non-existing pin
+ * would be maintained as dummy group to synchronize pin group index with
+ * pin descriptor registered with pinctrl core.
+ * Clients would not be able to request these dummy pin groups.
+ */
static const struct msm_pingroup sdm670_groups[] = {
- PINGROUP(0, SOUTH, qup0, NA, reserved0, NA, NA, NA, NA, NA, NA),
- PINGROUP(1, SOUTH, qup0, NA, reserved1, NA, NA, NA, NA, NA, NA),
- PINGROUP(2, SOUTH, qup0, NA, reserved2, NA, NA, NA, NA, NA, NA),
- PINGROUP(3, SOUTH, qup0, NA, reserved3, NA, NA, NA, NA, NA, NA),
- PINGROUP(4, NORTH, qup9, qdss_cti, reserved4, NA, NA, NA, NA, NA, NA),
- PINGROUP(5, NORTH, qup9, qdss_cti, reserved5, NA, NA, NA, NA, NA, NA),
- PINGROUP(6, NORTH, qup9, NA, ddr_pxi0, reserved6, NA, NA, NA, NA, NA),
- PINGROUP(7, NORTH, qup9, ddr_bist, NA, atest_tsens2, vsense_trigger,
- atest_usb1, ddr_pxi0, reserved7, NA),
- PINGROUP(8, WEST, qup_l4, GP_PDM1, ddr_bist, NA, reserved8, NA, NA, NA,
- NA),
- PINGROUP(9, WEST, qup_l5, ddr_bist, reserved9, NA, NA, NA, NA, NA, NA),
- PINGROUP(10, NORTH, mdp_vsync, qup_l6, ddr_bist, wlan2_adc1,
- atest_usb11, ddr_pxi2, reserved10, NA, NA),
- PINGROUP(11, NORTH, mdp_vsync, edp_lcd, dbg_out, wlan2_adc0,
- atest_usb10, ddr_pxi2, reserved11, NA, NA),
- PINGROUP(12, SOUTH, mdp_vsync, m_voc, tsif1_sync, ddr_pxi3, reserved12,
- NA, NA, NA, NA),
- PINGROUP(13, WEST, cam_mclk, pll_bypassnl, qdss_gpio0, ddr_pxi3,
- reserved13, NA, NA, NA, NA),
- PINGROUP(14, WEST, cam_mclk, pll_reset, qdss_gpio1, reserved14, NA, NA,
- NA, NA, NA),
- PINGROUP(15, WEST, cam_mclk, qdss_gpio2, reserved15, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(16, WEST, cam_mclk, qdss_gpio3, reserved16, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(17, WEST, cci_i2c, qup1, qdss_gpio4, reserved17, NA, NA, NA,
- NA, NA),
- PINGROUP(18, WEST, cci_i2c, qup1, NA, qdss_gpio5, reserved18, NA, NA,
- NA, NA),
- PINGROUP(19, WEST, cci_i2c, qup1, NA, qdss_gpio6, reserved19, NA, NA,
- NA, NA),
- PINGROUP(20, WEST, cci_i2c, qup1, NA, qdss_gpio7, reserved20, NA, NA,
- NA, NA),
- PINGROUP(21, WEST, cci_timer0, gcc_gp2, qdss_gpio8, NA, reserved21, NA,
- NA, NA, NA),
- PINGROUP(22, WEST, cci_timer1, gcc_gp3, qdss_gpio, NA, reserved22, NA,
- NA, NA, NA),
- PINGROUP(23, WEST, cci_timer2, qdss_gpio9, NA, reserved23, NA, NA, NA,
- NA, NA),
- PINGROUP(24, WEST, cci_timer3, cci_async, qdss_gpio10, reserved24, NA,
- NA, NA, NA, NA),
- PINGROUP(25, WEST, cci_timer4, cci_async, qdss_gpio11, NA, reserved25,
- NA, NA, NA, NA),
- PINGROUP(26, WEST, cci_async, qdss_gpio12, JITTER_BIST, NA, reserved26,
- NA, NA, NA, NA),
- PINGROUP(27, WEST, qup2, qdss_gpio13, PLL_BIST, NA, reserved27, NA, NA,
- NA, NA),
- PINGROUP(28, WEST, qup2, qdss_gpio14, AGERA_PLL, NA, reserved28, NA,
- NA, NA, NA),
- PINGROUP(29, WEST, qup2, NA, phase_flag1, qdss_gpio15, atest_tsens,
- reserved29, NA, NA, NA),
- PINGROUP(30, WEST, qup2, phase_flag2, qdss_gpio, reserved30, NA, NA,
- NA, NA, NA),
- PINGROUP(31, WEST, qup11, qup14, reserved31, NA, NA, NA, NA, NA, NA),
- PINGROUP(32, WEST, qup11, qup14, NA, reserved32, NA, NA, NA, NA, NA),
- PINGROUP(33, WEST, qup11, qup14, NA, reserved33, NA, NA, NA, NA, NA),
- PINGROUP(34, WEST, qup11, qup14, NA, reserved34, NA, NA, NA, NA, NA),
- PINGROUP(35, NORTH, pci_e0, QUP_L4, JITTER_BIST, NA, reserved35, NA,
- NA, NA, NA),
- PINGROUP(36, NORTH, pci_e0, QUP_L5, PLL_BIST, NA, reserved36, NA, NA,
- NA, NA),
- PINGROUP(37, NORTH, QUP_L6, AGERA_PLL, NA, reserved37, NA, NA, NA, NA,
- NA),
- PINGROUP(38, NORTH, usb_phy, NA, reserved38, NA, NA, NA, NA, NA, NA),
- PINGROUP(39, NORTH, lpass_slimbus, NA, reserved39, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(40, NORTH, sd_write, tsif1_error, NA, reserved40, NA, NA, NA,
- NA, NA),
- PINGROUP(41, SOUTH, qup3, NA, qdss_gpio6, reserved41, NA, NA, NA, NA,
- NA),
- PINGROUP(42, SOUTH, qup3, NA, qdss_gpio7, reserved42, NA, NA, NA, NA,
- NA),
- PINGROUP(43, SOUTH, qup3, NA, qdss_gpio14, reserved43, NA, NA, NA, NA,
- NA),
- PINGROUP(44, SOUTH, qup3, NA, qdss_gpio15, reserved44, NA, NA, NA, NA,
- NA),
- PINGROUP(45, SOUTH, qup6, NA, reserved45, NA, NA, NA, NA, NA, NA),
- PINGROUP(46, SOUTH, qup6, NA, reserved46, NA, NA, NA, NA, NA, NA),
- PINGROUP(47, SOUTH, qup6, reserved47, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(48, SOUTH, qup6, reserved48, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(49, NORTH, qup12, reserved49, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(50, NORTH, qup12, reserved50, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(51, NORTH, qup12, qdss_cti, reserved51, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(52, NORTH, qup12, phase_flag16, qdss_cti, reserved52, NA, NA,
- NA, NA, NA),
- PINGROUP(53, NORTH, qup10, phase_flag11, reserved53, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(54, NORTH, qup10, GP_PDM0, phase_flag12, NA, wlan1_adc1,
- atest_usb13, ddr_pxi1, reserved54, NA),
- PINGROUP(55, NORTH, qup10, phase_flag13, NA, wlan1_adc0, atest_usb12,
- ddr_pxi1, reserved55, NA, NA),
- PINGROUP(56, NORTH, qup10, phase_flag17, reserved56, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(57, NORTH, qua_mi2s, gcc_gp1, phase_flag18, reserved57, NA,
- NA, NA, NA, NA),
- PINGROUP(65, NORTH, pri_mi2s, qup8, wsa_clk, NA, reserved65, NA, NA,
- NA, NA),
- PINGROUP(66, NORTH, pri_mi2s_ws, qup8, wsa_data, GP_PDM1, NA,
- reserved66, NA, NA, NA),
- PINGROUP(67, NORTH, pri_mi2s, qup8, NA, atest_usb2, reserved67, NA, NA,
- NA, NA),
- PINGROUP(68, NORTH, pri_mi2s, qup8, NA, atest_usb23, reserved68, NA,
- NA, NA, NA),
- PINGROUP(75, NORTH, ter_mi2s, phase_flag8, qdss_gpio8, atest_usb22,
- QUP_L4, reserved75, NA, NA, NA),
- PINGROUP(76, NORTH, ter_mi2s, phase_flag9, qdss_gpio9, atest_usb21,
- QUP_L5, reserved76, NA, NA, NA),
- PINGROUP(77, NORTH, ter_mi2s, phase_flag4, qdss_gpio10, atest_usb20,
- QUP_L6, reserved77, NA, NA, NA),
- PINGROUP(78, NORTH, ter_mi2s, gcc_gp1, NA, reserved78, NA, NA, NA, NA,
- NA),
- PINGROUP(79, NORTH, sec_mi2s, GP_PDM2, NA, qdss_gpio11, NA, reserved79,
- NA, NA, NA),
- PINGROUP(80, NORTH, sec_mi2s, NA, qdss_gpio12, reserved80, NA, NA, NA,
- NA, NA),
- PINGROUP(81, NORTH, sec_mi2s, qup15, NA, reserved81, NA, NA, NA, NA,
- NA),
- PINGROUP(82, NORTH, sec_mi2s, qup15, NA, reserved82, NA, NA, NA, NA,
- NA),
- PINGROUP(83, NORTH, sec_mi2s, qup15, NA, reserved83, NA, NA, NA, NA,
- NA),
- PINGROUP(84, NORTH, qup15, NA, reserved84, NA, NA, NA, NA, NA, NA),
- PINGROUP(85, SOUTH, qup5, NA, reserved85, NA, NA, NA, NA, NA, NA),
- PINGROUP(86, SOUTH, qup5, copy_gp, NA, reserved86, NA, NA, NA, NA, NA),
- PINGROUP(87, SOUTH, qup5, NA, reserved87, NA, NA, NA, NA, NA, NA),
- PINGROUP(88, SOUTH, qup5, NA, reserved88, NA, NA, NA, NA, NA, NA),
- PINGROUP(89, SOUTH, tsif1_clk, qup4, tgu_ch3, phase_flag10, reserved89,
- NA, NA, NA, NA),
- PINGROUP(90, SOUTH, tsif1_en, mdp_vsync0, qup4, mdp_vsync1, mdp_vsync2,
- mdp_vsync3, tgu_ch0, phase_flag0, qdss_cti),
- PINGROUP(91, SOUTH, tsif1_data, sdc4_cmd, qup4, tgu_ch1, NA, qdss_cti,
- reserved91, NA, NA),
- PINGROUP(92, SOUTH, tsif2_error, sdc43, qup4, vfr_1, tgu_ch2, NA,
- reserved92, NA, NA),
- PINGROUP(93, SOUTH, tsif2_clk, sdc4_clk, qup7, NA, qdss_gpio13,
- reserved93, NA, NA, NA),
- PINGROUP(94, SOUTH, tsif2_en, sdc42, qup7, NA, reserved94, NA, NA, NA,
- NA),
- PINGROUP(95, SOUTH, tsif2_data, sdc41, qup7, GP_PDM0, NA, reserved95,
- NA, NA, NA),
- PINGROUP(96, SOUTH, tsif2_sync, sdc40, qup7, phase_flag3, reserved96,
- NA, NA, NA, NA),
- PINGROUP(97, WEST, NA, NA, mdp_vsync, ldo_en, reserved97, NA, NA, NA,
- NA),
- PINGROUP(98, WEST, NA, mdp_vsync, ldo_update, reserved98, NA, NA, NA,
- NA, NA),
- PINGROUP(99, NORTH, phase_flag14, prng_rosc, reserved99, NA, NA, NA,
- NA, NA, NA),
- PINGROUP(100, WEST, phase_flag15, reserved100, NA, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(101, WEST, NA, phase_flag5, reserved101, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(102, WEST, pci_e1, prng_rosc, reserved102, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(103, WEST, pci_e1, COPY_PHASE, reserved103, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(105, NORTH, uim2_data, qup13, qup_l4, NA, reserved105, NA, NA,
- NA, NA),
- PINGROUP(106, NORTH, uim2_clk, qup13, qup_l5, NA, reserved106, NA, NA,
- NA, NA),
- PINGROUP(107, NORTH, uim2_reset, qup13, qup_l6, reserved107, NA, NA,
- NA, NA, NA),
- PINGROUP(108, NORTH, uim2_present, qup13, reserved108, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(109, NORTH, uim1_data, reserved109, NA, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(110, NORTH, uim1_clk, reserved110, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(111, NORTH, uim1_reset, reserved111, NA, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(112, NORTH, uim1_present, reserved112, NA, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(113, NORTH, uim_batt, edp_hot, reserved113, NA, NA, NA, NA,
- NA, NA),
- PINGROUP(114, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, NA, reserved114, NA,
- NA, NA),
- PINGROUP(115, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, NA, reserved115, NA,
- NA, NA),
- PINGROUP(116, SOUTH, NA, reserved116, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(117, NORTH, NA, qdss_gpio0, atest_char, reserved117, NA, NA,
- NA, NA, NA),
- PINGROUP(118, NORTH, adsp_ext, NA, qdss_gpio1, atest_char3,
- reserved118, NA, NA, NA, NA),
- PINGROUP(119, NORTH, NA, qdss_gpio2, atest_char2, reserved119, NA, NA,
- NA, NA, NA),
- PINGROUP(120, NORTH, NA, qdss_gpio3, atest_char1, reserved120, NA, NA,
- NA, NA, NA),
- PINGROUP(121, NORTH, NA, qdss_gpio4, atest_char0, reserved121, NA, NA,
- NA, NA, NA),
- PINGROUP(122, NORTH, NA, qdss_gpio5, reserved122, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(123, NORTH, qup_l4, NA, qdss_gpio, reserved123, NA, NA, NA,
- NA, NA),
- PINGROUP(124, NORTH, qup_l5, NA, qdss_gpio, reserved124, NA, NA, NA,
- NA, NA),
- PINGROUP(125, NORTH, qup_l6, NA, reserved125, NA, NA, NA, NA, NA, NA),
- PINGROUP(126, NORTH, NA, reserved126, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(127, WEST, NA, NA, reserved127, NA, NA, NA, NA, NA, NA),
- PINGROUP(128, WEST, NAV_PPS, NAV_PPS, GPS_TX, NA, reserved128, NA, NA,
- NA, NA),
- PINGROUP(129, WEST, NAV_PPS, NAV_PPS, GPS_TX, NA, reserved129, NA, NA,
- NA, NA),
- PINGROUP(130, WEST, qlink_request, NA, reserved130, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(131, WEST, qlink_enable, NA, reserved131, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(132, WEST, NA, NA, reserved132, NA, NA, NA, NA, NA, NA),
- PINGROUP(133, NORTH, NA, reserved133, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(134, NORTH, NA, reserved134, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(135, WEST, NA, pa_indicator, NA, reserved135, NA, NA, NA, NA,
- NA),
- PINGROUP(136, WEST, NA, NA, reserved136, NA, NA, NA, NA, NA, NA),
- PINGROUP(137, WEST, NA, NA, phase_flag26, reserved137, NA, NA, NA, NA,
- NA),
- PINGROUP(138, WEST, NA, NA, phase_flag27, reserved138, NA, NA, NA, NA,
- NA),
- PINGROUP(139, WEST, NA, phase_flag28, reserved139, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(140, WEST, NA, NA, phase_flag6, reserved140, NA, NA, NA, NA,
- NA),
- PINGROUP(141, WEST, NA, phase_flag29, reserved141, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(142, WEST, NA, phase_flag30, reserved142, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(143, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, phase_flag31,
- reserved143, NA, NA, NA),
- PINGROUP(144, SOUTH, mss_lte, reserved144, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(145, SOUTH, mss_lte, GPS_TX, reserved145, NA, NA, NA, NA, NA,
- NA),
- PINGROUP(146, WEST, NA, NA, reserved146, NA, NA, NA, NA, NA, NA),
- PINGROUP(147, WEST, NA, NA, reserved147, NA, NA, NA, NA, NA, NA),
- PINGROUP(148, WEST, NA, reserved148, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(149, WEST, NA, reserved149, NA, NA, NA, NA, NA, NA, NA),
- SDC_QDSD_PINGROUP(sdc1_clk, 0x599000, 13, 6),
- SDC_QDSD_PINGROUP(sdc1_cmd, 0x599000, 11, 3),
- SDC_QDSD_PINGROUP(sdc1_data, 0x599000, 9, 0),
- SDC_QDSD_PINGROUP(sdc2_clk, 0x99a000, 14, 6),
- SDC_QDSD_PINGROUP(sdc2_cmd, 0x99a000, 11, 3),
- SDC_QDSD_PINGROUP(sdc2_data, 0x99a000, 9, 0),
+ [0] = PINGROUP(0, SOUTH, qup0, NA, NA, NA, NA, NA, NA, NA, NA),
+ [1] = PINGROUP(1, SOUTH, qup0, NA, NA, NA, NA, NA, NA, NA, NA),
+ [2] = PINGROUP(2, SOUTH, qup0, NA, NA, NA, NA, NA, NA, NA, NA),
+ [3] = PINGROUP(3, SOUTH, qup0, NA, NA, NA, NA, NA, NA, NA, NA),
+ [4] = PINGROUP(4, NORTH, qup9, qdss_cti, NA, NA, NA, NA, NA, NA, NA),
+ [5] = PINGROUP(5, NORTH, qup9, qdss_cti, NA, NA, NA, NA, NA, NA, NA),
+ [6] = PINGROUP(6, NORTH, qup9, NA, ddr_pxi0, NA, NA, NA, NA, NA, NA),
+ [7] = PINGROUP(7, NORTH, qup9, ddr_bist, NA, atest_tsens2,
+ vsense_trigger, atest_usb1, ddr_pxi0, NA, NA),
+ [8] = PINGROUP(8, WEST, qup_l4, GP_PDM1, ddr_bist, NA, NA, NA, NA, NA,
+ NA),
+ [9] = PINGROUP(9, WEST, qup_l5, ddr_bist, NA, NA, NA, NA, NA, NA, NA),
+ [10] = PINGROUP(10, NORTH, mdp_vsync, qup_l6, ddr_bist, wlan2_adc1,
+ atest_usb11, ddr_pxi2, NA, NA, NA),
+ [11] = PINGROUP(11, NORTH, mdp_vsync, edp_lcd, dbg_out, wlan2_adc0,
+ atest_usb10, ddr_pxi2, NA, NA, NA),
+ [12] = PINGROUP(12, SOUTH, mdp_vsync, m_voc, tsif1_sync, ddr_pxi3, NA,
+ NA, NA, NA, NA),
+ [13] = PINGROUP(13, WEST, cam_mclk, pll_bypassnl, qdss_gpio0, ddr_pxi3,
+ NA, NA, NA, NA, NA),
+ [14] = PINGROUP(14, WEST, cam_mclk, pll_reset, qdss_gpio1, NA, NA, NA,
+ NA, NA, NA),
+ [15] = PINGROUP(15, WEST, cam_mclk, qdss_gpio2, NA, NA, NA, NA, NA, NA,
+ NA),
+ [16] = PINGROUP(16, WEST, cam_mclk, qdss_gpio3, NA, NA, NA, NA, NA, NA,
+ NA),
+ [17] = PINGROUP(17, WEST, cci_i2c, qup1, qdss_gpio4, NA, NA, NA, NA,
+ NA, NA),
+ [18] = PINGROUP(18, WEST, cci_i2c, qup1, NA, qdss_gpio5, NA, NA, NA,
+ NA, NA),
+ [19] = PINGROUP(19, WEST, cci_i2c, qup1, NA, qdss_gpio6, NA, NA, NA,
+ NA, NA),
+ [20] = PINGROUP(20, WEST, cci_i2c, qup1, NA, qdss_gpio7, NA, NA, NA,
+ NA, NA),
+ [21] = PINGROUP(21, WEST, cci_timer0, gcc_gp2, qdss_gpio8, NA, NA, NA,
+ NA, NA, NA),
+ [22] = PINGROUP(22, WEST, cci_timer1, gcc_gp3, qdss_gpio, NA, NA, NA,
+ NA, NA, NA),
+ [23] = PINGROUP(23, WEST, cci_timer2, qdss_gpio9, NA, NA, NA, NA, NA,
+ NA, NA),
+ [24] = PINGROUP(24, WEST, cci_timer3, cci_async, qdss_gpio10, NA, NA,
+ NA, NA, NA, NA),
+ [25] = PINGROUP(25, WEST, cci_timer4, cci_async, qdss_gpio11, NA, NA,
+ NA, NA, NA, NA),
+ [26] = PINGROUP(26, WEST, cci_async, qdss_gpio12, JITTER_BIST, NA, NA,
+ NA, NA, NA, NA),
+ [27] = PINGROUP(27, WEST, qup2, qdss_gpio13, PLL_BIST, NA, NA, NA, NA,
+ NA, NA),
+ [28] = PINGROUP(28, WEST, qup2, qdss_gpio14, AGERA_PLL, NA, NA, NA, NA,
+ NA, NA),
+ [29] = PINGROUP(29, WEST, qup2, NA, phase_flag1, qdss_gpio15,
+ atest_tsens, NA, NA, NA, NA),
+ [30] = PINGROUP(30, WEST, qup2, phase_flag2, qdss_gpio, NA, NA, NA, NA,
+ NA, NA),
+ [31] = PINGROUP(31, WEST, qup11, qup14, NA, NA, NA, NA, NA, NA, NA),
+ [32] = PINGROUP(32, WEST, qup11, qup14, NA, NA, NA, NA, NA, NA, NA),
+ [33] = PINGROUP(33, WEST, qup11, qup14, NA, NA, NA, NA, NA, NA, NA),
+ [34] = PINGROUP(34, WEST, qup11, qup14, NA, NA, NA, NA, NA, NA, NA),
+ [35] = PINGROUP(35, NORTH, pci_e0, QUP_L4, JITTER_BIST, NA, NA, NA, NA,
+ NA, NA),
+ [36] = PINGROUP(36, NORTH, pci_e0, QUP_L5, PLL_BIST, NA, NA, NA, NA,
+ NA, NA),
+ [37] = PINGROUP(37, NORTH, QUP_L6, AGERA_PLL, NA, NA, NA, NA, NA, NA,
+ NA),
+ [38] = PINGROUP(38, NORTH, usb_phy, NA, NA, NA, NA, NA, NA, NA, NA),
+ [39] = PINGROUP(39, NORTH, lpass_slimbus, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [40] = PINGROUP(40, NORTH, sd_write, tsif1_error, NA, NA, NA, NA, NA,
+ NA, NA),
+ [41] = PINGROUP(41, SOUTH, qup3, NA, qdss_gpio6, NA, NA, NA, NA, NA,
+ NA),
+ [42] = PINGROUP(42, SOUTH, qup3, NA, qdss_gpio7, NA, NA, NA, NA, NA,
+ NA),
+ [43] = PINGROUP(43, SOUTH, qup3, NA, qdss_gpio14, NA, NA, NA, NA, NA,
+ NA),
+ [44] = PINGROUP(44, SOUTH, qup3, NA, qdss_gpio15, NA, NA, NA, NA, NA,
+ NA),
+ [45] = PINGROUP(45, SOUTH, qup6, NA, NA, NA, NA, NA, NA, NA, NA),
+ [46] = PINGROUP(46, SOUTH, qup6, NA, NA, NA, NA, NA, NA, NA, NA),
+ [47] = PINGROUP(47, SOUTH, qup6, NA, NA, NA, NA, NA, NA, NA, NA),
+ [48] = PINGROUP(48, SOUTH, qup6, NA, NA, NA, NA, NA, NA, NA, NA),
+ [49] = PINGROUP(49, NORTH, qup12, NA, NA, NA, NA, NA, NA, NA, NA),
+ [50] = PINGROUP(50, NORTH, qup12, NA, NA, NA, NA, NA, NA, NA, NA),
+ [51] = PINGROUP(51, NORTH, qup12, qdss_cti, NA, NA, NA, NA, NA, NA, NA),
+ [52] = PINGROUP(52, NORTH, qup12, phase_flag16, qdss_cti, NA, NA, NA,
+ NA, NA, NA),
+ [53] = PINGROUP(53, NORTH, qup10, phase_flag11, NA, NA, NA, NA, NA, NA,
+ NA),
+ [54] = PINGROUP(54, NORTH, qup10, GP_PDM0, phase_flag12, NA,
+ wlan1_adc1, atest_usb13, ddr_pxi1, NA, NA),
+ [55] = PINGROUP(55, NORTH, qup10, phase_flag13, NA, wlan1_adc0,
+ atest_usb12, ddr_pxi1, NA, NA, NA),
+ [56] = PINGROUP(56, NORTH, qup10, phase_flag17, NA, NA, NA, NA, NA, NA,
+ NA),
+ [57] = PINGROUP(57, NORTH, qua_mi2s, gcc_gp1, phase_flag18, NA, NA, NA,
+ NA, NA, NA),
+ [58] = PINGROUP(58, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [59] = PINGROUP(59, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [60] = PINGROUP(60, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [61] = PINGROUP(61, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [62] = PINGROUP(62, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [63] = PINGROUP(63, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [64] = PINGROUP(64, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [65] = PINGROUP(65, NORTH, pri_mi2s, qup8, wsa_clk, NA, NA, NA, NA, NA,
+ NA),
+ [66] = PINGROUP(66, NORTH, pri_mi2s_ws, qup8, wsa_data, GP_PDM1, NA,
+ NA, NA, NA, NA),
+ [67] = PINGROUP(67, NORTH, pri_mi2s, qup8, NA, atest_usb2, NA, NA, NA,
+ NA, NA),
+ [68] = PINGROUP(68, NORTH, pri_mi2s, qup8, NA, atest_usb23, NA, NA, NA,
+ NA, NA),
+ [69] = PINGROUP(69, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [70] = PINGROUP(70, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [71] = PINGROUP(71, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [72] = PINGROUP(72, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [73] = PINGROUP(73, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [74] = PINGROUP(74, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [75] = PINGROUP(75, NORTH, ter_mi2s, phase_flag8, qdss_gpio8,
+ atest_usb22, QUP_L4, NA, NA, NA, NA),
+ [76] = PINGROUP(76, NORTH, ter_mi2s, phase_flag9, qdss_gpio9,
+ atest_usb21, QUP_L5, NA, NA, NA, NA),
+ [77] = PINGROUP(77, NORTH, ter_mi2s, phase_flag4, qdss_gpio10,
+ atest_usb20, QUP_L6, NA, NA, NA, NA),
+ [78] = PINGROUP(78, NORTH, ter_mi2s, gcc_gp1, NA, NA, NA, NA, NA, NA,
+ NA),
+ [79] = PINGROUP(79, NORTH, sec_mi2s, GP_PDM2, NA, qdss_gpio11, NA, NA,
+ NA, NA, NA),
+ [80] = PINGROUP(80, NORTH, sec_mi2s, NA, qdss_gpio12, NA, NA, NA, NA,
+ NA, NA),
+ [81] = PINGROUP(81, NORTH, sec_mi2s, qup15, NA, NA, NA, NA, NA, NA, NA),
+ [82] = PINGROUP(82, NORTH, sec_mi2s, qup15, NA, NA, NA, NA, NA, NA, NA),
+ [83] = PINGROUP(83, NORTH, sec_mi2s, qup15, NA, NA, NA, NA, NA, NA, NA),
+ [84] = PINGROUP(84, NORTH, qup15, NA, NA, NA, NA, NA, NA, NA, NA),
+ [85] = PINGROUP(85, SOUTH, qup5, NA, NA, NA, NA, NA, NA, NA, NA),
+ [86] = PINGROUP(86, SOUTH, qup5, copy_gp, NA, NA, NA, NA, NA, NA, NA),
+ [87] = PINGROUP(87, SOUTH, qup5, NA, NA, NA, NA, NA, NA, NA, NA),
+ [88] = PINGROUP(88, SOUTH, qup5, NA, NA, NA, NA, NA, NA, NA, NA),
+ [89] = PINGROUP(89, SOUTH, tsif1_clk, qup4, tgu_ch3, phase_flag10, NA,
+ NA, NA, NA, NA),
+ [90] = PINGROUP(90, SOUTH, tsif1_en, mdp_vsync0, qup4, mdp_vsync1,
+ mdp_vsync2, mdp_vsync3, tgu_ch0, phase_flag0, qdss_cti),
+ [91] = PINGROUP(91, SOUTH, tsif1_data, sdc4_cmd, qup4, tgu_ch1, NA,
+ qdss_cti, NA, NA, NA),
+ [92] = PINGROUP(92, SOUTH, tsif2_error, sdc43, qup4, vfr_1, tgu_ch2,
+ NA, NA, NA, NA),
+ [93] = PINGROUP(93, SOUTH, tsif2_clk, sdc4_clk, qup7, NA, qdss_gpio13,
+ NA, NA, NA, NA),
+ [94] = PINGROUP(94, SOUTH, tsif2_en, sdc42, qup7, NA, NA, NA, NA, NA,
+ NA),
+ [95] = PINGROUP(95, SOUTH, tsif2_data, sdc41, qup7, GP_PDM0, NA, NA,
+ NA, NA, NA),
+ [96] = PINGROUP(96, SOUTH, tsif2_sync, sdc40, qup7, phase_flag3, NA,
+ NA, NA, NA, NA),
+ [97] = PINGROUP(97, WEST, NA, NA, mdp_vsync, ldo_en, NA, NA, NA, NA,
+ NA),
+ [98] = PINGROUP(98, WEST, NA, mdp_vsync, ldo_update, NA, NA, NA, NA,
+ NA, NA),
+ [99] = PINGROUP(99, NORTH, phase_flag14, prng_rosc, NA, NA, NA, NA, NA,
+ NA, NA),
+ [100] = PINGROUP(100, WEST, phase_flag15, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [101] = PINGROUP(101, WEST, NA, phase_flag5, NA, NA, NA, NA, NA, NA,
+ NA),
+ [102] = PINGROUP(102, WEST, pci_e1, prng_rosc, NA, NA, NA, NA, NA, NA,
+ NA),
+ [103] = PINGROUP(103, WEST, pci_e1, COPY_PHASE, NA, NA, NA, NA, NA, NA,
+ NA),
+ [104] = PINGROUP(104, DUMMY, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [105] = PINGROUP(105, NORTH, uim2_data, qup13, qup_l4, NA, NA, NA, NA,
+ NA, NA),
+ [106] = PINGROUP(106, NORTH, uim2_clk, qup13, qup_l5, NA, NA, NA, NA,
+ NA, NA),
+ [107] = PINGROUP(107, NORTH, uim2_reset, qup13, qup_l6, NA, NA, NA, NA,
+ NA, NA),
+ [108] = PINGROUP(108, NORTH, uim2_present, qup13, NA, NA, NA, NA, NA,
+ NA, NA),
+ [109] = PINGROUP(109, NORTH, uim1_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ [110] = PINGROUP(110, NORTH, uim1_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ [111] = PINGROUP(111, NORTH, uim1_reset, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [112] = PINGROUP(112, NORTH, uim1_present, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [113] = PINGROUP(113, NORTH, uim_batt, edp_hot, NA, NA, NA, NA, NA, NA,
+ NA),
+ [114] = PINGROUP(114, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, NA,
+ NA, NA),
+ [115] = PINGROUP(115, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, NA,
+ NA, NA),
+ [116] = PINGROUP(116, SOUTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [117] = PINGROUP(117, NORTH, NA, qdss_gpio0, atest_char, NA, NA, NA,
+ NA, NA, NA),
+ [118] = PINGROUP(118, NORTH, adsp_ext, NA, qdss_gpio1, atest_char3, NA,
+ NA, NA, NA, NA),
+ [119] = PINGROUP(119, NORTH, NA, qdss_gpio2, atest_char2, NA, NA, NA,
+ NA, NA, NA),
+ [120] = PINGROUP(120, NORTH, NA, qdss_gpio3, atest_char1, NA, NA, NA,
+ NA, NA, NA),
+ [121] = PINGROUP(121, NORTH, NA, qdss_gpio4, atest_char0, NA, NA, NA,
+ NA, NA, NA),
+ [122] = PINGROUP(122, NORTH, NA, qdss_gpio5, NA, NA, NA, NA, NA, NA,
+ NA),
+ [123] = PINGROUP(123, NORTH, qup_l4, NA, qdss_gpio, NA, NA, NA, NA, NA,
+ NA),
+ [124] = PINGROUP(124, NORTH, qup_l5, NA, qdss_gpio, NA, NA, NA, NA, NA,
+ NA),
+ [125] = PINGROUP(125, NORTH, qup_l6, NA, NA, NA, NA, NA, NA, NA, NA),
+ [126] = PINGROUP(126, NORTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [127] = PINGROUP(127, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [128] = PINGROUP(128, WEST, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, NA, NA,
+ NA, NA),
+ [129] = PINGROUP(129, WEST, NAV_PPS, NAV_PPS, GPS_TX, NA, NA, NA, NA,
+ NA, NA),
+ [130] = PINGROUP(130, WEST, qlink_request, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [131] = PINGROUP(131, WEST, qlink_enable, NA, NA, NA, NA, NA, NA, NA,
+ NA),
+ [132] = PINGROUP(132, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [133] = PINGROUP(133, NORTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [134] = PINGROUP(134, NORTH, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [135] = PINGROUP(135, WEST, NA, pa_indicator, NA, NA, NA, NA, NA, NA,
+ NA),
+ [136] = PINGROUP(136, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [137] = PINGROUP(137, WEST, NA, NA, phase_flag26, NA, NA, NA, NA, NA,
+ NA),
+ [138] = PINGROUP(138, WEST, NA, NA, phase_flag27, NA, NA, NA, NA, NA,
+ NA),
+ [139] = PINGROUP(139, WEST, NA, phase_flag28, NA, NA, NA, NA, NA, NA,
+ NA),
+ [140] = PINGROUP(140, WEST, NA, NA, phase_flag6, NA, NA, NA, NA, NA,
+ NA),
+ [141] = PINGROUP(141, WEST, NA, phase_flag29, NA, NA, NA, NA, NA, NA,
+ NA),
+ [142] = PINGROUP(142, WEST, NA, phase_flag30, NA, NA, NA, NA, NA, NA,
+ NA),
+ [143] = PINGROUP(143, WEST, NA, NAV_PPS, NAV_PPS, GPS_TX, phase_flag31,
+ NA, NA, NA, NA),
+ [144] = PINGROUP(144, SOUTH, mss_lte, NA, NA, NA, NA, NA, NA, NA, NA),
+ [145] = PINGROUP(145, SOUTH, mss_lte, GPS_TX, NA, NA, NA, NA, NA, NA,
+ NA),
+ [146] = PINGROUP(146, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [147] = PINGROUP(147, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [148] = PINGROUP(148, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [149] = PINGROUP(149, WEST, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ [150] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x599000, 15, 0),
+ [151] = SDC_QDSD_PINGROUP(sdc1_clk, 0x599000, 13, 6),
+ [152] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x599000, 11, 3),
+ [153] = SDC_QDSD_PINGROUP(sdc1_data, 0x599000, 9, 0),
+ [154] = SDC_QDSD_PINGROUP(sdc2_clk, 0x99a000, 14, 6),
+ [155] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x99a000, 11, 3),
+ [156] = SDC_QDSD_PINGROUP(sdc2_data, 0x99a000, 9, 0),
+ [157] = UFS_RESET(ufs_reset, 0x99f000),
};
static const struct msm_pinctrl_soc_data sdm670_pinctrl = {
@@ -2251,7 +1592,7 @@
.nfunctions = ARRAY_SIZE(sdm670_functions),
.groups = sdm670_groups,
.ngroups = ARRAY_SIZE(sdm670_groups),
- .ngpios = 136,
+ .ngpios = 150,
};
static int sdm670_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index cf80ce1..4a5a0fe 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -586,6 +586,9 @@
ret = info->ops->init(pfc);
if (ret < 0)
return ret;
+
+ /* .init() may have overridden pfc->info */
+ info = pfc->info;
}
/* Enable dummy states for those platforms without pinctrl support */
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
index 7ca37c3..baa98d7 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
@@ -203,7 +203,7 @@
/* IPSR6 */
FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B,
- FN_SCIF_CLK, FN_BPFCLK_E,
+ FN_SCIF_CLK, FN_DVC_MUTE, FN_BPFCLK_E,
FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2,
FN_SCIFA2_RXD, FN_FMIN_E,
FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD,
@@ -573,7 +573,7 @@
/* IPSR6 */
AUDIO_CLKB_MARK, STP_OPWM_0_B_MARK, MSIOF1_SCK_B_MARK,
- SCIF_CLK_MARK, BPFCLK_E_MARK,
+ SCIF_CLK_MARK, DVC_MUTE_MARK, BPFCLK_E_MARK,
AUDIO_CLKC_MARK, SCIFB0_SCK_C_MARK, MSIOF1_SYNC_B_MARK, RX2_MARK,
SCIFA2_RXD_MARK, FMIN_E_MARK,
AUDIO_CLKOUT_MARK, MSIOF1_SS1_B_MARK, TX2_MARK, SCIFA2_TXD_MARK,
@@ -1010,14 +1010,17 @@
PINMUX_IPSR_MSEL(IP4_12_10, SCL2, SEL_IIC2_0),
PINMUX_IPSR_MSEL(IP4_12_10, GPS_CLK_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_12_10, GLO_Q0_D, SEL_GPS_3),
+ PINMUX_IPSR_MSEL(IP4_12_10, HSCK1_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_15_13, SSI_WS2),
PINMUX_IPSR_MSEL(IP4_15_13, SDA2, SEL_IIC2_0),
PINMUX_IPSR_MSEL(IP4_15_13, GPS_SIGN_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_15_13, RX2_E, SEL_SCIF2_4),
PINMUX_IPSR_MSEL(IP4_15_13, GLO_Q1_D, SEL_GPS_3),
+ PINMUX_IPSR_MSEL(IP4_15_13, HCTS1_N_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_18_16, SSI_SDATA2),
PINMUX_IPSR_MSEL(IP4_18_16, GPS_MAG_B, SEL_GPS_1),
PINMUX_IPSR_MSEL(IP4_18_16, TX2_E, SEL_SCIF2_4),
+ PINMUX_IPSR_MSEL(IP4_18_16, HRTS1_N_E, SEL_HSCIF1_4),
PINMUX_IPSR_GPSR(IP4_19, SSI_SCK34),
PINMUX_IPSR_GPSR(IP4_20, SSI_WS34),
PINMUX_IPSR_GPSR(IP4_21, SSI_SDATA3),
@@ -1090,6 +1093,7 @@
PINMUX_IPSR_MSEL(IP6_2_0, STP_OPWM_0_B, SEL_SSP_1),
PINMUX_IPSR_MSEL(IP6_2_0, MSIOF1_SCK_B, SEL_SOF1_1),
PINMUX_IPSR_MSEL(IP6_2_0, SCIF_CLK, SEL_SCIF_0),
+ PINMUX_IPSR_GPSR(IP6_2_0, DVC_MUTE),
PINMUX_IPSR_MSEL(IP6_2_0, BPFCLK_E, SEL_FM_4),
PINMUX_IPSR_GPSR(IP6_5_3, AUDIO_CLKC),
PINMUX_IPSR_MSEL(IP6_5_3, SCIFB0_SCK_C, SEL_SCIFB_2),
@@ -1099,7 +1103,7 @@
PINMUX_IPSR_MSEL(IP6_5_3, FMIN_E, SEL_FM_4),
PINMUX_IPSR_GPSR(IP6_7_6, AUDIO_CLKOUT),
PINMUX_IPSR_MSEL(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1),
- PINMUX_IPSR_MSEL(IP6_5_3, TX2, SEL_SCIF2_0),
+ PINMUX_IPSR_MSEL(IP6_7_6, TX2, SEL_SCIF2_0),
PINMUX_IPSR_MSEL(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0),
PINMUX_IPSR_GPSR(IP6_9_8, IRQ0),
PINMUX_IPSR_MSEL(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3),
@@ -5810,7 +5814,7 @@
0, 0,
/* IP6_2_0 [3] */
FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B,
- FN_SCIF_CLK, 0, FN_BPFCLK_E,
+ FN_SCIF_CLK, FN_DVC_MUTE, FN_BPFCLK_E,
0, 0, }
},
{ PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32,
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
index ed734f56..ef093ac 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
@@ -281,8 +281,8 @@
FN_AVB_AVTP_CAPTURE, FN_ETH_CRS_DV_B, FN_SSI_WS1, FN_SCIF1_TXD_B,
FN_IIC1_SDA_C, FN_VI1_DATA0, FN_CAN0_TX_D, FN_AVB_AVTP_MATCH,
FN_ETH_RX_ER_B, FN_SSI_SDATA1, FN_HSCIF1_HRX_B, FN_SDATA, FN_VI1_DATA1,
- FN_ATAG0_N, FN_ETH_RXD0_B, FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2,
- FN_MDATA, FN_ATAWR0_N, FN_ETH_RXD1_B,
+ FN_ATAWR0_N, FN_ETH_RXD0_B, FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2,
+ FN_MDATA, FN_ATAG0_N, FN_ETH_RXD1_B,
/* IPSR13 */
FN_SSI_WS2, FN_HSCIF1_HCTS_N_B, FN_SCIFA0_RXD_D, FN_VI1_DATA3, FN_SCKZ,
@@ -575,8 +575,8 @@
ETH_CRS_DV_B_MARK, SSI_WS1_MARK, SCIF1_TXD_B_MARK, IIC1_SDA_C_MARK,
VI1_DATA0_MARK, CAN0_TX_D_MARK, AVB_AVTP_MATCH_MARK, ETH_RX_ER_B_MARK,
SSI_SDATA1_MARK, HSCIF1_HRX_B_MARK, VI1_DATA1_MARK, SDATA_MARK,
- ATAG0_N_MARK, ETH_RXD0_B_MARK, SSI_SCK2_MARK, HSCIF1_HTX_B_MARK,
- VI1_DATA2_MARK, MDATA_MARK, ATAWR0_N_MARK, ETH_RXD1_B_MARK,
+ ATAWR0_N_MARK, ETH_RXD0_B_MARK, SSI_SCK2_MARK, HSCIF1_HTX_B_MARK,
+ VI1_DATA2_MARK, MDATA_MARK, ATAG0_N_MARK, ETH_RXD1_B_MARK,
/* IPSR13 */
SSI_WS2_MARK, HSCIF1_HCTS_N_B_MARK, SCIFA0_RXD_D_MARK, VI1_DATA3_MARK,
@@ -1413,13 +1413,13 @@
PINMUX_IPSR_MSEL(IP12_26_24, HSCIF1_HRX_B, SEL_HSCIF1_1),
PINMUX_IPSR_GPSR(IP12_26_24, VI1_DATA1),
PINMUX_IPSR_MSEL(IP12_26_24, SDATA, SEL_FSN_0),
- PINMUX_IPSR_GPSR(IP12_26_24, ATAG0_N),
+ PINMUX_IPSR_GPSR(IP12_26_24, ATAWR0_N),
PINMUX_IPSR_MSEL(IP12_26_24, ETH_RXD0_B, SEL_ETH_1),
PINMUX_IPSR_MSEL(IP12_29_27, SSI_SCK2, SEL_SSI2_0),
PINMUX_IPSR_MSEL(IP12_29_27, HSCIF1_HTX_B, SEL_HSCIF1_1),
PINMUX_IPSR_GPSR(IP12_29_27, VI1_DATA2),
PINMUX_IPSR_MSEL(IP12_29_27, MDATA, SEL_FSN_0),
- PINMUX_IPSR_GPSR(IP12_29_27, ATAWR0_N),
+ PINMUX_IPSR_GPSR(IP12_29_27, ATAG0_N),
PINMUX_IPSR_MSEL(IP12_29_27, ETH_RXD1_B, SEL_ETH_1),
/* IPSR13 */
@@ -4938,10 +4938,10 @@
0, 0, 0, 0,
/* IP12_29_27 [3] */
FN_SSI_SCK2, FN_HSCIF1_HTX_B, FN_VI1_DATA2, FN_MDATA,
- FN_ATAWR0_N, FN_ETH_RXD1_B, 0, 0,
+ FN_ATAG0_N, FN_ETH_RXD1_B, 0, 0,
/* IP12_26_24 [3] */
FN_SSI_SDATA1, FN_HSCIF1_HRX_B, FN_VI1_DATA1, FN_SDATA,
- FN_ATAG0_N, FN_ETH_RXD0_B, 0, 0,
+ FN_ATAWR0_N, FN_ETH_RXD0_B, 0, 0,
/* IP12_23_21 [3] */
FN_SSI_WS1, FN_SCIF1_TXD_B, FN_IIC1_SDA_C, FN_VI1_DATA0,
FN_CAN0_TX_D, FN_AVB_AVTP_MATCH, FN_ETH_RX_ER_B, 0,
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
index 84cee66..0acb0a7 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
@@ -2056,7 +2056,7 @@
RCAR_GP_PIN(6, 21),
};
static const unsigned int hscif2_clk_b_mux[] = {
- HSCK1_B_MARK,
+ HSCK2_B_MARK,
};
static const unsigned int hscif2_ctrl_b_pins[] = {
/* RTS, CTS */
@@ -2129,7 +2129,7 @@
RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14),
};
static const unsigned int hscif4_ctrl_mux[] = {
- HRTS4_N_MARK, HCTS3_N_MARK,
+ HRTS4_N_MARK, HCTS4_N_MARK,
};
static const unsigned int hscif4_data_b_pins[] = {
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index efc4371..a36fd4b 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -798,7 +798,7 @@
break;
case PIN_CONFIG_OUTPUT:
__stm32_gpio_set(bank, offset, arg);
- ret = stm32_pmx_gpio_set_direction(pctldev, NULL, pin, false);
+ ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false);
break;
default:
ret = -EINVAL;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
index 90b973e..a7c81e9 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
@@ -394,7 +394,7 @@
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x3, "owa")), /* DOUT */
+ SUNXI_FUNCTION(0x3, "spdif")), /* DOUT */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out")),
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index 3418896..8d9f0e0 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -1025,7 +1025,7 @@
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -1046,7 +1046,7 @@
}
INIT_LIST_HEAD(&entry->link);
entry->rule = *rule;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_FLT_COOKIE;
entry->rt_tbl = rt_tbl;
entry->tbl = tbl;
if (add_rear) {
@@ -1065,13 +1065,19 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
-
+ipa_insert_failed:
+ tbl->rule_cnt--;
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ list_del(&entry->link);
+ kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
return -EPERM;
}
@@ -1087,7 +1093,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1119,7 +1125,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -1140,7 +1146,7 @@
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
index bb6f8ec..a6a7613 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
@@ -547,7 +547,7 @@
{
struct ipa_hdr_entry *hdr_entry;
struct ipa_hdr_proc_ctx_entry *entry;
- struct ipa_hdr_proc_ctx_offset_entry *offset;
+ struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
int id;
@@ -563,7 +563,7 @@
}
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
- if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
@@ -580,7 +580,7 @@
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -640,6 +640,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -647,6 +648,14 @@
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
+
bad_len:
if (add_ref_hdr)
hdr_entry->ref_cnt--;
@@ -659,7 +668,7 @@
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
int id;
@@ -691,7 +700,7 @@
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -780,6 +789,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -804,10 +814,19 @@
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
+
fail_dma_mapping:
entry->is_hdr_proc_ctx = false;
bad_hdr_len:
@@ -824,7 +843,7 @@
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
entry = ipa_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -875,7 +894,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1444,7 +1463,7 @@
goto bail;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
index 5568f8b..877e4c7 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
@@ -37,7 +37,15 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
+
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
+
#define MTU_BYTE 1500
#define IPA_MAX_NUM_PIPES 0x14
@@ -196,8 +204,8 @@
*/
struct ipa_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa_flt_tbl *tbl;
struct ipa_rt_tbl *rt_tbl;
u32 hw_len;
@@ -222,13 +230,13 @@
*/
struct ipa_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa_rt_tbl_set *set;
- u32 cookie;
bool in_sys;
u32 sz;
struct ipa_mem_buffer curr_mem;
@@ -259,6 +267,7 @@
*/
struct ipa_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -268,7 +277,6 @@
dma_addr_t phys_base;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -341,10 +349,10 @@
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -400,8 +408,8 @@
*/
struct ipa_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa_rt_tbl *tbl;
struct ipa_hdr_entry *hdr;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c
index dc27636..12b1a99 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c
@@ -271,6 +271,14 @@
mutex_lock(&ipa_ctx->lock);
list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
if (!strcmp(entry->name, tx->name)) {
+ /* add the entry check */
+ if (entry->num_tx_props != tx->num_tx_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_tx_props,
+ tx->num_tx_props);
+ mutex_unlock(&ipa_ctx->lock);
+ return result;
+ }
memcpy(tx->tx, entry->tx, entry->num_tx_props *
sizeof(struct ipa_ioc_tx_intf_prop));
result = 0;
@@ -304,6 +312,14 @@
mutex_lock(&ipa_ctx->lock);
list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
if (!strcmp(entry->name, rx->name)) {
+ /* add the entry check */
+ if (entry->num_rx_props != rx->num_rx_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_rx_props,
+ rx->num_rx_props);
+ mutex_unlock(&ipa_ctx->lock);
+ return result;
+ }
memcpy(rx->rx, entry->rx, entry->num_rx_props *
sizeof(struct ipa_ioc_rx_intf_prop));
result = 0;
@@ -337,6 +353,14 @@
mutex_lock(&ipa_ctx->lock);
list_for_each_entry(entry, &ipa_ctx->intf_list, link) {
if (!strcmp(entry->name, ext->name)) {
+ /* add the entry check */
+ if (entry->num_ext_props != ext->num_ext_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_ext_props,
+ ext->num_ext_props);
+ mutex_unlock(&ipa_ctx->lock);
+ return result;
+ }
memcpy(ext->ext, entry->ext, entry->num_ext_props *
sizeof(struct ipa_ioc_ext_intf_prop));
result = 0;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 5b70853..2c71143 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -902,7 +902,7 @@
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys = (ip == IPA_IP_v4) ?
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
set->tbl_cnt++;
@@ -915,12 +915,16 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -933,7 +937,7 @@
enum ipa_ip_type ip = IPA_IP_MAX;
u32 id;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -947,8 +951,11 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
+
if (!entry->in_sys) {
list_del(&entry->link);
@@ -987,13 +994,14 @@
if (rule->hdr_hdl) {
hdr = ipa_id_find(rule->hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rule->hdr_proc_ctx_hdl) {
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -1001,7 +1009,7 @@
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad params\n");
goto error;
}
@@ -1022,7 +1030,7 @@
goto error;
}
INIT_LIST_HEAD(&entry->link);
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_RULE_COOKIE;
entry->rule = *rule;
entry->tbl = tbl;
entry->hdr = hdr;
@@ -1115,7 +1123,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1350,7 +1358,7 @@
}
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
entry->ref_cnt++;
lookup->hdl = entry->id;
@@ -1387,7 +1395,7 @@
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1397,8 +1405,11 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ result = -EINVAL;
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1425,7 +1436,7 @@
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
@@ -1437,7 +1448,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 4fb4da8..b2a00de 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -759,6 +759,15 @@
trace_idle_sleep_enter3(sys->ep->client);
usleep_range(POLLING_MIN_SLEEP_RX, POLLING_MAX_SLEEP_RX);
trace_idle_sleep_exit3(sys->ep->client);
+
+ /*
+ * if pipe is out of buffers there is no point polling for
+ * completed descs; release the worker so delayed work can
+ * run in a timely manner
+ */
+ if (sys->len - sys->len_pending_xfer == 0)
+ break;
+
} while (inactive_cycles <= POLLING_INACTIVITY_RX);
trace_poll_to_intr3(sys->ep->client);
@@ -1549,6 +1558,8 @@
struct ipa3_rx_pkt_wrapper *rx_pkt;
struct ipa3_rx_pkt_wrapper *tmp;
+ spin_lock_bh(&ipa3_ctx->wc_memb.wlan_spinlock);
+
list_for_each_entry_safe(rx_pkt, tmp,
&ipa3_ctx->wc_memb.wlan_comm_desc_list, link) {
list_del(&rx_pkt->link);
@@ -1569,6 +1580,8 @@
IPAERR("wlan comm buff total cnt: %d\n",
ipa3_ctx->wc_memb.wlan_comm_total_cnt);
+ spin_unlock_bh(&ipa3_ctx->wc_memb.wlan_spinlock);
+
}
static void ipa3_alloc_wlan_rx_common_cache(u32 size)
@@ -1606,11 +1619,13 @@
goto fail_dma_mapping;
}
+ spin_lock_bh(&ipa3_ctx->wc_memb.wlan_spinlock);
list_add_tail(&rx_pkt->link,
&ipa3_ctx->wc_memb.wlan_comm_desc_list);
rx_len_cached = ++ipa3_ctx->wc_memb.wlan_comm_total_cnt;
ipa3_ctx->wc_memb.wlan_comm_free_cnt++;
+ spin_unlock_bh(&ipa3_ctx->wc_memb.wlan_spinlock);
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index bfcaa2b..b1e50ac 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -741,7 +741,7 @@
goto error;
}
- if ((*rt_tbl)->cookie != IPA_COOKIE) {
+ if ((*rt_tbl)->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -800,7 +800,7 @@
}
INIT_LIST_HEAD(&((*entry)->link));
(*entry)->rule = *rule;
- (*entry)->cookie = IPA_COOKIE;
+ (*entry)->cookie = IPA_FLT_COOKIE;
(*entry)->rt_tbl = rt_tbl;
(*entry)->tbl = tbl;
if (rule->rule_id) {
@@ -835,12 +835,18 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
+ipa_insert_failed:
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ tbl->rule_cnt--;
+ return -EPERM;
}
static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
@@ -866,9 +872,16 @@
list_add(&entry->link, &tbl->head_flt_rule_list);
}
- __ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
+ if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
+ goto ipa_insert_failed;
return 0;
+ipa_insert_failed:
+ list_del(&entry->link);
+ /* if rule id was allocated from idr, remove it */
+ if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
+ idr_remove(&entry->tbl->rule_ids, entry->rule_id);
+ kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
error:
return -EPERM;
@@ -900,7 +913,8 @@
list_add(&entry->link, &((*add_after_entry)->link));
- __ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
+ if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
+ goto ipa_insert_failed;
/*
* prepare for next insertion
@@ -909,6 +923,13 @@
return 0;
+ipa_insert_failed:
+ list_del(&entry->link);
+ /* if rule id was allocated from idr, remove it */
+ if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
+ idr_remove(&entry->tbl->rule_ids, entry->rule_id);
+ kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
+
error:
*add_after_entry = NULL;
return -EPERM;
@@ -925,7 +946,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -962,7 +983,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -983,7 +1004,7 @@
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index 14d776e..0c1832c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -336,7 +336,7 @@
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
- if (hdr_entry->cookie != IPA_COOKIE) {
+ if (hdr_entry->cookie != IPA_HDR_COOKIE) {
IPAERR("Invalid header cookie %u\n", hdr_entry->cookie);
WARN_ON(1);
return -EINVAL;
@@ -357,7 +357,7 @@
entry->l2tp_params = proc_ctx->l2tp_params;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);
@@ -415,6 +415,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -422,6 +423,14 @@
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
+
bad_len:
if (add_ref_hdr)
hdr_entry->ref_cnt--;
@@ -434,7 +443,7 @@
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa3_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl;
int id;
@@ -465,7 +474,7 @@
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -544,6 +553,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -568,10 +578,19 @@
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa3_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
+
fail_dma_mapping:
entry->is_hdr_proc_ctx = false;
@@ -589,7 +608,7 @@
struct ipa3_hdr_proc_ctx_tbl *htbl = &ipa3_ctx->hdr_proc_ctx_tbl;
entry = ipa3_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -640,7 +659,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1186,7 +1205,7 @@
goto bail;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index fcb7c72..9fab8fb 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -39,6 +39,12 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
#define MTU_BYTE 1500
#define IPA_EP_NOT_ALLOCATED (-1)
@@ -207,8 +213,8 @@
*/
struct ipa3_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa3_flt_tbl *tbl;
struct ipa3_rt_tbl *rt_tbl;
u32 hw_len;
@@ -236,13 +242,13 @@
*/
struct ipa3_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa3_rt_tbl_set *set;
- u32 cookie;
bool in_sys[IPA_RULE_TYPE_MAX];
u32 sz[IPA_RULE_TYPE_MAX];
struct ipa_mem_buffer curr_mem[IPA_RULE_TYPE_MAX];
@@ -274,6 +280,7 @@
*/
struct ipa3_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -283,7 +290,6 @@
dma_addr_t phys_base;
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -333,11 +339,11 @@
*/
struct ipa3_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
union ipa_l2tp_hdr_proc_ctx_params l2tp_params;
struct ipa3_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa3_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -399,8 +405,8 @@
*/
struct ipa3_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa3_rt_tbl *tbl;
struct ipa3_hdr_entry *hdr;
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c b/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c
index fe6d245..38e8d4e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c
@@ -275,6 +275,14 @@
mutex_lock(&ipa3_ctx->lock);
list_for_each_entry(entry, &ipa3_ctx->intf_list, link) {
if (!strcmp(entry->name, tx->name)) {
+ /* add the entry check */
+ if (entry->num_tx_props != tx->num_tx_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_tx_props,
+ tx->num_tx_props);
+ mutex_unlock(&ipa3_ctx->lock);
+ return result;
+ }
memcpy(tx->tx, entry->tx, entry->num_tx_props *
sizeof(struct ipa_ioc_tx_intf_prop));
result = 0;
@@ -314,6 +322,14 @@
mutex_lock(&ipa3_ctx->lock);
list_for_each_entry(entry, &ipa3_ctx->intf_list, link) {
if (!strcmp(entry->name, rx->name)) {
+ /* add the entry check */
+ if (entry->num_rx_props != rx->num_rx_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_rx_props,
+ rx->num_rx_props);
+ mutex_unlock(&ipa3_ctx->lock);
+ return result;
+ }
memcpy(rx->rx, entry->rx, entry->num_rx_props *
sizeof(struct ipa_ioc_rx_intf_prop));
result = 0;
@@ -348,6 +364,14 @@
mutex_lock(&ipa3_ctx->lock);
list_for_each_entry(entry, &ipa3_ctx->intf_list, link) {
if (!strcmp(entry->name, ext->name)) {
+ /* add the entry check */
+ if (entry->num_ext_props != ext->num_ext_props) {
+ IPAERR("invalid entry number(%u %u)\n",
+ entry->num_ext_props,
+ ext->num_ext_props);
+ mutex_unlock(&ipa3_ctx->lock);
+ return result;
+ }
memcpy(ext->ext, entry->ext, entry->num_ext_props *
sizeof(struct ipa_ioc_ext_intf_prop));
result = 0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index cf28986..767dae4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -790,7 +790,7 @@
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys[IPA_RULE_HASHABLE] = (ip == IPA_IP_v4) ?
!ipa3_ctx->ip4_rt_tbl_hash_lcl :
!ipa3_ctx->ip6_rt_tbl_hash_lcl;
@@ -808,12 +808,16 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
-
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
+ idr_destroy(&entry->rule_ids);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa3_ctx->rt_tbl_cache, entry);
@@ -827,7 +831,7 @@
u32 id;
struct ipa3_rt_tbl_set *rset;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -841,8 +845,10 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
rset = &ipa3_ctx->reap_rt_tbl_set[ip];
@@ -879,14 +885,14 @@
if (rule->hdr_hdl) {
*hdr = ipa3_id_find(rule->hdr_hdl);
- if ((*hdr == NULL) || ((*hdr)->cookie != IPA_COOKIE)) {
+ if ((*hdr == NULL) || ((*hdr)->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
return -EPERM;
}
} else if (rule->hdr_proc_ctx_hdl) {
*proc_ctx = ipa3_id_find(rule->hdr_proc_ctx_hdl);
if ((*proc_ctx == NULL) ||
- ((*proc_ctx)->cookie != IPA_COOKIE)) {
+ ((*proc_ctx)->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
return -EPERM;
@@ -909,7 +915,7 @@
goto error;
}
INIT_LIST_HEAD(&(*entry)->link);
- (*(entry))->cookie = IPA_COOKIE;
+ (*(entry))->cookie = IPA_RT_RULE_COOKIE;
(*(entry))->rule = *rule;
(*(entry))->tbl = tbl;
(*(entry))->hdr = hdr;
@@ -977,7 +983,7 @@
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("failed adding rt tbl name = %s\n",
name ? name : "");
goto error;
@@ -1112,7 +1118,7 @@
mutex_lock(&ipa3_ctx->lock);
tbl = __ipa3_find_rt_tbl(rules->ip, rules->rt_tbl_name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("failed finding rt tbl name = %s\n",
rules->rt_tbl_name ? rules->rt_tbl_name : "");
ret = -EINVAL;
@@ -1196,7 +1202,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1434,7 +1440,7 @@
}
mutex_lock(&ipa3_ctx->lock);
entry = __ipa3_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
entry->ref_cnt++;
lookup->hdl = entry->id;
@@ -1471,7 +1477,7 @@
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1481,8 +1487,11 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ result = -EINVAL;
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1512,13 +1521,14 @@
if (rtrule->rule.hdr_hdl) {
hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rtrule->rule.hdr_proc_ctx_hdl) {
proc_ctx = ipa3_id_find(rtrule->rule.hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -1530,7 +1540,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 11da6b3..45cb41c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -26,6 +26,15 @@
#define IPA_V3_0_CLK_RATE_SVS (75 * 1000 * 1000UL)
#define IPA_V3_0_CLK_RATE_NOMINAL (150 * 1000 * 1000UL)
#define IPA_V3_0_CLK_RATE_TURBO (200 * 1000 * 1000UL)
+
+#define IPA_V3_5_CLK_RATE_SVS (200 * 1000 * 1000UL)
+#define IPA_V3_5_CLK_RATE_NOMINAL (400 * 1000 * 1000UL)
+#define IPA_V3_5_CLK_RATE_TURBO (42640 * 10 * 1000UL)
+
+#define IPA_V4_0_CLK_RATE_SVS (125 * 1000 * 1000UL)
+#define IPA_V4_0_CLK_RATE_NOMINAL (220 * 1000 * 1000UL)
+#define IPA_V4_0_CLK_RATE_TURBO (250 * 1000 * 1000UL)
+
#define IPA_V3_0_MAX_HOLB_TMR_VAL (4294967296 - 1)
#define IPA_V3_0_BW_THRESHOLD_TURBO_MBPS (1000)
@@ -3767,13 +3776,24 @@
int ipa3_controller_static_bind(struct ipa3_controller *ctrl,
enum ipa_hw_type hw_type)
{
+ if (hw_type >= IPA_HW_v4_0) {
+ ctrl->ipa_clk_rate_turbo = IPA_V4_0_CLK_RATE_TURBO;
+ ctrl->ipa_clk_rate_nominal = IPA_V4_0_CLK_RATE_NOMINAL;
+ ctrl->ipa_clk_rate_svs = IPA_V4_0_CLK_RATE_SVS;
+ } else if (hw_type >= IPA_HW_v3_5) {
+ ctrl->ipa_clk_rate_turbo = IPA_V3_5_CLK_RATE_TURBO;
+ ctrl->ipa_clk_rate_nominal = IPA_V3_5_CLK_RATE_NOMINAL;
+ ctrl->ipa_clk_rate_svs = IPA_V3_5_CLK_RATE_SVS;
+ } else {
+ ctrl->ipa_clk_rate_turbo = IPA_V3_0_CLK_RATE_TURBO;
+ ctrl->ipa_clk_rate_nominal = IPA_V3_0_CLK_RATE_NOMINAL;
+ ctrl->ipa_clk_rate_svs = IPA_V3_0_CLK_RATE_SVS;
+ }
+
ctrl->ipa_init_rt4 = _ipa_init_rt4_v3;
ctrl->ipa_init_rt6 = _ipa_init_rt6_v3;
ctrl->ipa_init_flt4 = _ipa_init_flt4_v3;
ctrl->ipa_init_flt6 = _ipa_init_flt6_v3;
- ctrl->ipa_clk_rate_turbo = IPA_V3_0_CLK_RATE_TURBO;
- ctrl->ipa_clk_rate_nominal = IPA_V3_0_CLK_RATE_NOMINAL;
- ctrl->ipa_clk_rate_svs = IPA_V3_0_CLK_RATE_SVS;
ctrl->ipa3_read_ep_reg = _ipa_read_ep_reg_v3_0;
ctrl->ipa3_commit_flt = __ipa_commit_flt_v3;
ctrl->ipa3_commit_rt = __ipa_commit_rt_v3;
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index e6c2aa3..1f7286b 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -632,6 +632,14 @@
between MSM and WCD DSP over glink transport protocol. This driver
provides read and write interface via char device.
+config QCOM_SMCINVOKE
+ bool "Secure QSEE Support"
+ help
+ Enable SMCInvoke driver which supports capability based secure
+ communication between QTI Secure Execution Environment (QSEE)
+ and high level operating system. It exposes APIs for both
+ userspace and kernel clients.
+
config MSM_EVENT_TIMER
bool "Event timer"
help
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 64fb7a0..7820f8b 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -77,3 +77,4 @@
obj-$(CONFIG_APSS_CORE_EA) += msm-core.o debug_core.o
obj-$(CONFIG_QCOM_DCC_V2) += dcc_v2.o
obj-$(CONFIG_QTI_RPM_STATS_LOG) += rpm_stats.o
+obj-$(CONFIG_QCOM_SMCINVOKE) += smcinvoke.o
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index cded512..405d05c 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -358,6 +358,7 @@
uint32_t vbatt_req;
uint32_t vbatt_resp;
uint32_t vbatt_req_err;
+ u32 rejuvenate_ind;
uint32_t rejuvenate_ack_req;
uint32_t rejuvenate_ack_resp;
uint32_t rejuvenate_ack_err;
@@ -435,6 +436,10 @@
bool is_wlan_mac_set;
struct icnss_wlan_mac_addr wlan_mac_addr;
bool bypass_s1_smmu;
+ u8 cause_for_rejuvenation;
+ u8 requesting_sub_system;
+ u16 line_number;
+ char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1];
} *penv;
#ifdef CONFIG_ICNSS_DEBUG
@@ -1670,6 +1675,60 @@
return ret;
}
+static int icnss_decode_rejuvenate_ind(void *msg, unsigned int msg_len)
+{
+ struct msg_desc ind_desc;
+ struct wlfw_rejuvenate_ind_msg_v01 ind_msg;
+ int ret = 0;
+
+ if (!penv || !penv->wlfw_clnt) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ memset(&ind_msg, 0, sizeof(ind_msg));
+
+ ind_desc.msg_id = QMI_WLFW_REJUVENATE_IND_V01;
+ ind_desc.max_msg_len = WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN;
+ ind_desc.ei_array = wlfw_rejuvenate_ind_msg_v01_ei;
+
+ ret = qmi_kernel_decode(&ind_desc, &ind_msg, msg, msg_len);
+ if (ret < 0) {
+ icnss_pr_err("Failed to decode rejuvenate ind message: ret %d, msg_len %u\n",
+ ret, msg_len);
+ goto out;
+ }
+
+ if (ind_msg.cause_for_rejuvenation_valid)
+ penv->cause_for_rejuvenation = ind_msg.cause_for_rejuvenation;
+ else
+ penv->cause_for_rejuvenation = 0;
+ if (ind_msg.requesting_sub_system_valid)
+ penv->requesting_sub_system = ind_msg.requesting_sub_system;
+ else
+ penv->requesting_sub_system = 0;
+ if (ind_msg.line_number_valid)
+ penv->line_number = ind_msg.line_number;
+ else
+ penv->line_number = 0;
+ if (ind_msg.function_name_valid)
+ memcpy(penv->function_name, ind_msg.function_name,
+ QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1);
+ else
+ memset(penv->function_name, 0,
+ QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1);
+
+ icnss_pr_info("Cause for rejuvenation: 0x%x, requesting sub-system: 0x%x, line number: %u, function name: %s\n",
+ penv->cause_for_rejuvenation,
+ penv->requesting_sub_system,
+ penv->line_number,
+ penv->function_name);
+
+ penv->stats.rejuvenate_ind++;
+out:
+ return ret;
+}
+
static int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv)
{
int ret;
@@ -1863,6 +1922,7 @@
msg_id, penv->state);
icnss_ignore_qmi_timeout(true);
+ icnss_decode_rejuvenate_ind(msg, msg_len);
event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
if (event_data == NULL)
return;
@@ -3617,9 +3677,6 @@
if (ret)
return ret;
- if (ret == 0)
- memset(&priv->stats, 0, sizeof(priv->stats));
-
return count;
}
@@ -3743,6 +3800,26 @@
return 0;
}
+static int icnss_stats_show_rejuvenate_info(struct seq_file *s,
+ struct icnss_priv *priv)
+{
+ if (priv->stats.rejuvenate_ind) {
+ seq_puts(s, "\n<---------------- Rejuvenate Info ----------------->\n");
+ seq_printf(s, "Number of Rejuvenations: %u\n",
+ priv->stats.rejuvenate_ind);
+ seq_printf(s, "Cause for Rejuvenation: 0x%x\n",
+ priv->cause_for_rejuvenation);
+ seq_printf(s, "Requesting Sub-System: 0x%x\n",
+ priv->requesting_sub_system);
+ seq_printf(s, "Line Number: %u\n",
+ priv->line_number);
+ seq_printf(s, "Function Name: %s\n",
+ priv->function_name);
+ }
+
+ return 0;
+}
+
static int icnss_stats_show_events(struct seq_file *s, struct icnss_priv *priv)
{
int i;
@@ -3808,6 +3885,7 @@
ICNSS_STATS_DUMP(s, priv, vbatt_req);
ICNSS_STATS_DUMP(s, priv, vbatt_resp);
ICNSS_STATS_DUMP(s, priv, vbatt_req_err);
+ ICNSS_STATS_DUMP(s, priv, rejuvenate_ind);
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_req);
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_resp);
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_err);
@@ -3829,6 +3907,8 @@
icnss_stats_show_capability(s, priv);
+ icnss_stats_show_rejuvenate_info(s, priv);
+
icnss_stats_show_events(s, priv);
icnss_stats_show_state(s, priv);
diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c
index be2b7da..739c053 100644
--- a/drivers/soc/qcom/llcc-sdm845.c
+++ b/drivers/soc/qcom/llcc-sdm845.c
@@ -57,23 +57,23 @@
}
static struct llcc_slice_config sdm845_data[] = {
- SCT_ENTRY("cpuss", 1, 1, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 1),
- SCT_ENTRY("vidsc0", 2, 2, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("vidsc1", 3, 3, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("rotator", 4, 4, 563, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("voice", 5, 5, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("audio", 6, 6, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("modemhp_grow", 7, 7, 1024, 2, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("modem", 8, 8, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("compute", 10, 10, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("gpuhtw", 11, 11, 515, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("gpu", 12, 12, 2560, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("mmuhwt", 13, 13, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 0, 1),
- SCT_ENTRY("compute_dma", 15, 15, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("display", 16, 16, 3072, 1, 0, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("modemhp_fix", 20, 20, 1024, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("modem_paging", 21, 21, 1024, 0, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("audiohw", 22, 22, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0),
+ SCT_ENTRY("cpuss", 1, 1, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 1),
+ SCT_ENTRY("vidsc0", 2, 2, 512, 2, 1, 0x0, 0x0F0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("vidsc1", 3, 3, 512, 2, 1, 0x0, 0x0F0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("rotator", 4, 4, 563, 2, 1, 0x0, 0x00F, 2, 0, 1, 1, 0),
+ SCT_ENTRY("voice", 5, 5, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("audio", 6, 6, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modemhp_grow", 7, 7, 1024, 2, 0, 0x0F0, 0xF0F, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modem", 8, 8, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("compute", 10, 10, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("gpuhtw", 11, 11, 512, 1, 1, 0x0, 0xC, 0, 0, 1, 1, 0),
+ SCT_ENTRY("gpu", 12, 12, 2560, 1, 0, 0xFF0, 0x3, 0, 0, 1, 1, 0),
+ SCT_ENTRY("mmuhwt", 13, 13, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 0, 1),
+ SCT_ENTRY("compute_dma", 15, 15, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("display", 16, 16, 3072, 1, 0, 0xFF0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modemhp_fix", 20, 20, 1024, 2, 1, 0x0, 0xF00, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modem_paging", 21, 21, 1024, 0, 1, 0x0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("audiohw", 22, 22, 1024, 1, 1, 0xFF0, 0xF, 0, 0, 1, 1, 0),
};
static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
index 36c0154..ed78af7 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
@@ -746,18 +746,16 @@
static int msm_bus_disable_node_qos_clk(struct msm_bus_node_device_type *node)
{
- struct msm_bus_node_device_type *bus_node = NULL;
int i;
int ret = 0;
- if (!node || (!to_msm_bus_node(node->node_info->bus_device))) {
+ if (!node) {
ret = -ENXIO;
goto exit_disable_node_qos_clk;
}
- bus_node = to_msm_bus_node(node->node_info->bus_device);
- for (i = 0; i < bus_node->num_node_qos_clks; i++)
- ret = disable_nodeclk(&bus_node->node_qos_clks[i]);
+ for (i = 0; i < node->num_node_qos_clks; i++)
+ ret = disable_nodeclk(&node->node_qos_clks[i]);
exit_disable_node_qos_clk:
return ret;
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index 9a98063..17e0a4c 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -32,6 +32,7 @@
#define RPMH_MAX_MBOXES 2
#define RPMH_MAX_FAST_RES 32
#define RPMH_MAX_REQ_IN_BATCH 10
+#define RPMH_TIMEOUT msecs_to_jiffies(10000)
#define DEFINE_RPMH_MSG_ONSTACK(rc, s, q, c, name) \
struct rpmh_msg name = { \
@@ -166,6 +167,41 @@
complete(compl);
}
+/**
+ * wait_for_tx_done: Wait forever until the response is received.
+ *
+ * @rc: The RPMH client
+ * @compl: The completion object
+ * @addr: An addr that we sent in that request
+ * @data: The data for the address in that request
+ *
+ */
+static inline void wait_for_tx_done(struct rpmh_client *rc,
+ struct completion *compl, u32 addr, u32 data)
+{
+ int ret;
+ int count = 4;
+
+ do {
+ ret = wait_for_completion_timeout(compl, RPMH_TIMEOUT);
+ if (ret) {
+ if (count != 4)
+ dev_notice(rc->dev,
+ "RPMH response received addr=0x%x data=0x%x\n",
+ addr, data);
+ return;
+ }
+ if (!count) {
+ mbox_chan_debug(rc->chan);
+ } else {
+ dev_err(rc->dev,
+ "RPMH response timeout (%d) addr=0x%x,data=0x%x\n",
+ count, addr, data);
+ count--;
+ }
+ } while (true);
+}
+
static struct rpmh_req *__find_req(struct rpmh_client *rc, u32 addr)
{
struct rpmh_req *p, *req = NULL;
@@ -365,7 +401,7 @@
if (ret < 0)
return ret;
- wait_for_completion(&compl);
+ wait_for_tx_done(rc, &compl, addr, data);
return rpm_msg.err;
}
@@ -469,7 +505,7 @@
if (ret)
return ret;
- wait_for_completion(&compl);
+ wait_for_tx_done(rc, &compl, cmd[0].addr, cmd[0].data);
return rpm_msg.err;
}
@@ -500,6 +536,7 @@
int count = 0;
int ret, i, j, k;
bool complete_set;
+ u32 addr, data;
if (IS_ERR_OR_NULL(rc) || !cmd || !n)
return -EINVAL;
@@ -537,6 +574,8 @@
}
}
+ addr = cmd[0].addr;
+ data = cmd[0].data;
/* Create async request batches */
for (i = 0; i < count; i++) {
rpm_msg[i] = __get_rpmh_msg_async(rc, state, cmd, n[i]);
@@ -566,7 +605,7 @@
/* For those unsent requests, spoof tx_done */
for (j = i; j < count; j++)
rpmh_tx_done(&rc->client, &rpm_msg[j]->msg, ret);
- wait_for_completion(&compl);
+ wait_for_tx_done(rc, &compl, addr, data);
} else {
/* Send Sleep requests to the controller, expect no response */
for (i = 0; i < count; i++) {
@@ -719,7 +758,7 @@
return ret;
/* Wait until the response is received from RPMH */
- wait_for_completion(&compl);
+ wait_for_tx_done(rc, &compl, addr, 0);
/* Read the data back from the tcs_mbox_msg structrure */
*resp = rpm_msg.cmd[0].data;
diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c
index 63cce5c..d337b7a 100644
--- a/drivers/soc/qcom/secure_buffer.c
+++ b/drivers/soc/qcom/secure_buffer.c
@@ -416,6 +416,8 @@
return "VMID_CP_SPSS_SP";
case VMID_CP_SPSS_SP_SHARED:
return "VMID_CP_SPSS_SP_SHARED";
+ case VMID_CP_SPSS_HLOS_SHARED:
+ return "VMID_CP_SPSS_HLOS_SHARED";
case VMID_INVAL:
return "VMID_INVAL";
default:
diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c
new file mode 100644
index 0000000..3f31fb1
--- /dev/null
+++ b/drivers/soc/qcom/smcinvoke.c
@@ -0,0 +1,575 @@
+/*
+ * SMC Invoke driver
+ *
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/anon_inodes.h>
+#include <linux/smcinvoke.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+
+#include <soc/qcom/scm.h>
+#include <asm/cacheflush.h>
+#include <soc/qcom/qseecomi.h>
+
+#include "smcinvoke_object.h"
+#include "../../misc/qseecom_kernel.h"
+
+#define SMCINVOKE_DEV "smcinvoke"
+#define SMCINVOKE_TZ_PARAM_ID 0x224
+#define SMCINVOKE_TZ_CMD 0x32000600
+#define SMCINVOKE_TZ_ROOT_OBJ 1
+#define SMCINVOKE_TZ_MIN_BUF_SIZE 4096
+#define SMCINVOKE_ARGS_ALIGN_SIZE (sizeof(uint64_t))
+#define SMCINVOKE_TZ_OBJ_NULL 0
+
+#define FOR_ARGS(ndxvar, counts, section) \
+ for (ndxvar = object_counts_index_##section(counts); \
+ ndxvar < (object_counts_index_##section(counts) \
+ + object_counts_num_##section(counts)); \
+ ++ndxvar)
+
+static long smcinvoke_ioctl(struct file *, unsigned int, unsigned long);
+static int smcinvoke_open(struct inode *, struct file *);
+static int smcinvoke_release(struct inode *, struct file *);
+
+static const struct file_operations smcinvoke_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = smcinvoke_ioctl,
+ .compat_ioctl = smcinvoke_ioctl,
+ .open = smcinvoke_open,
+ .release = smcinvoke_release,
+};
+
+struct smcinvoke_buf_hdr {
+ uint32_t offset;
+ uint32_t size;
+};
+
+union smcinvoke_tz_args {
+ struct smcinvoke_buf_hdr b;
+ uint32_t tzhandle;
+};
+struct smcinvoke_msg_hdr {
+ uint32_t tzhandle;
+ uint32_t op;
+ uint32_t counts;
+};
+
+struct smcinvoke_tzobj_context {
+ uint32_t tzhandle;
+};
+
+static dev_t smcinvoke_device_no;
+struct cdev smcinvoke_cdev;
+struct class *driver_class;
+struct device *class_dev;
+
+/*
+ * size_add saturates at SIZE_MAX. If integer overflow is detected,
+ * this function would return SIZE_MAX otherwise normal a+b is returned.
+ */
+static inline size_t size_add(size_t a, size_t b)
+{
+ return (b > (SIZE_MAX - a)) ? SIZE_MAX : a + b;
+}
+
+/*
+ * pad_size is used along with size_align to define a buffer overflow
+ * protected version of ALIGN
+ */
+static inline size_t pad_size(size_t a, size_t b)
+{
+ return (~a + 1) % b;
+}
+
+/*
+ * size_align saturates at SIZE_MAX. If integer overflow is detected, this
+ * function would return SIZE_MAX otherwise next aligned size is returned.
+ */
+static inline size_t size_align(size_t a, size_t b)
+{
+ return size_add(a, pad_size(a, b));
+}
+
+/*
+ * This function retrieves file pointer corresponding to FD provided. It stores
+ * retrived file pointer until IOCTL call is concluded. Once call is completed,
+ * all stored file pointers are released. file pointers are stored to prevent
+ * other threads from releasing that FD while IOCTL is in progress.
+ */
+static int get_tzhandle_from_fd(int64_t fd, struct file **filp,
+ uint32_t *tzhandle)
+{
+ int ret = -EBADF;
+ struct file *tmp_filp = NULL;
+ struct smcinvoke_tzobj_context *tzobj = NULL;
+
+ if (fd == SMCINVOKE_USERSPACE_OBJ_NULL) {
+ *tzhandle = SMCINVOKE_TZ_OBJ_NULL;
+ ret = 0;
+ goto out;
+ } else if (fd < SMCINVOKE_USERSPACE_OBJ_NULL) {
+ goto out;
+ }
+
+ tmp_filp = fget(fd);
+ if (!tmp_filp)
+ goto out;
+
+ /* Verify if filp is smcinvoke device's file pointer */
+ if (!tmp_filp->f_op || !tmp_filp->private_data ||
+ (tmp_filp->f_op != &smcinvoke_fops)) {
+ fput(tmp_filp);
+ goto out;
+ }
+
+ tzobj = tmp_filp->private_data;
+ *tzhandle = tzobj->tzhandle;
+ *filp = tmp_filp;
+ ret = 0;
+out:
+ return ret;
+}
+
+static int get_fd_from_tzhandle(uint32_t tzhandle, int64_t *fd)
+{
+ int unused_fd = -1, ret = -1;
+ struct file *f = NULL;
+ struct smcinvoke_tzobj_context *cxt = NULL;
+
+ if (tzhandle == SMCINVOKE_TZ_OBJ_NULL) {
+ *fd = SMCINVOKE_USERSPACE_OBJ_NULL;
+ ret = 0;
+ goto out;
+ }
+
+ cxt = kzalloc(sizeof(*cxt), GFP_KERNEL);
+ if (!cxt) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ unused_fd = get_unused_fd_flags(O_RDWR);
+ if (unused_fd < 0)
+ goto out;
+
+ f = anon_inode_getfile(SMCINVOKE_DEV, &smcinvoke_fops, cxt, O_RDWR);
+ if (IS_ERR(f))
+ goto out;
+
+ *fd = unused_fd;
+ fd_install(*fd, f);
+ ((struct smcinvoke_tzobj_context *)
+ (f->private_data))->tzhandle = tzhandle;
+ return 0;
+out:
+ if (unused_fd >= 0)
+ put_unused_fd(unused_fd);
+ kfree(cxt);
+
+ return ret;
+}
+
+static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len,
+ const uint8_t *out_buf, size_t out_buf_len,
+ int32_t *smcinvoke_result)
+{
+ int ret = 0;
+ struct scm_desc desc = {0};
+ size_t inbuf_flush_size = (1UL << get_order(in_buf_len)) * PAGE_SIZE;
+ size_t outbuf_flush_size = (1UL << get_order(out_buf_len)) * PAGE_SIZE;
+
+ desc.arginfo = SMCINVOKE_TZ_PARAM_ID;
+ desc.args[0] = (uint64_t)virt_to_phys(in_buf);
+ desc.args[1] = inbuf_flush_size;
+ desc.args[2] = (uint64_t)virt_to_phys(out_buf);
+ desc.args[3] = outbuf_flush_size;
+
+ dmac_flush_range(in_buf, in_buf + inbuf_flush_size);
+ dmac_flush_range(out_buf, out_buf + outbuf_flush_size);
+
+ ret = scm_call2(SMCINVOKE_TZ_CMD, &desc);
+
+ /* process listener request */
+ if (!ret && (desc.ret[0] == QSEOS_RESULT_INCOMPLETE ||
+ desc.ret[0] == QSEOS_RESULT_BLOCKED_ON_LISTENER))
+ ret = qseecom_process_listener_from_smcinvoke(&desc);
+
+ *smcinvoke_result = (int32_t)desc.ret[1];
+ if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0])
+ pr_err("SCM call failed with ret val = %d %d %d %d\n",
+ ret, (int)desc.ret[0],
+ (int)desc.ret[1], (int)desc.ret[2]);
+
+ dmac_inv_range(in_buf, in_buf + inbuf_flush_size);
+ dmac_inv_range(out_buf, out_buf + outbuf_flush_size);
+ return ret;
+}
+
+static int marshal_out(void *buf, uint32_t buf_size,
+ struct smcinvoke_cmd_req *req,
+ union smcinvoke_arg *args_buf)
+{
+ int ret = -EINVAL, i = 0;
+ union smcinvoke_tz_args *tz_args = NULL;
+ size_t offset = sizeof(struct smcinvoke_msg_hdr) +
+ object_counts_total(req->counts) *
+ sizeof(union smcinvoke_tz_args);
+
+ if (offset > buf_size)
+ goto out;
+
+ tz_args = (union smcinvoke_tz_args *)
+ (buf + sizeof(struct smcinvoke_msg_hdr));
+
+ tz_args += object_counts_num_BI(req->counts);
+
+ FOR_ARGS(i, req->counts, BO) {
+ args_buf[i].b.size = tz_args->b.size;
+ if ((buf_size - tz_args->b.offset < tz_args->b.size) ||
+ tz_args->b.offset > buf_size) {
+ pr_err("%s: buffer overflow detected\n", __func__);
+ goto out;
+ }
+ if (copy_to_user((void __user *)(uintptr_t)(args_buf[i].b.addr),
+ (uint8_t *)(buf) + tz_args->b.offset,
+ tz_args->b.size)) {
+ pr_err("Error %d copying ctxt to user\n", ret);
+ goto out;
+ }
+ tz_args++;
+ }
+ tz_args += object_counts_num_OI(req->counts);
+
+ FOR_ARGS(i, req->counts, OO) {
+ /*
+ * create a new FD and assign to output object's
+ * context
+ */
+ ret = get_fd_from_tzhandle(tz_args->tzhandle,
+ &(args_buf[i].o.fd));
+ if (ret)
+ goto out;
+ tz_args++;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+/*
+ * SMC expects arguments in following format
+ * ---------------------------------------------------------------------------
+ * | cxt | op | counts | ptr|size |ptr|size...|ORef|ORef|...| rest of payload |
+ * ---------------------------------------------------------------------------
+ * cxt: target, op: operation, counts: total arguments
+ * offset: offset is from beginning of buffer i.e. cxt
+ * size: size is 8 bytes aligned value
+ */
+static size_t compute_in_msg_size(const struct smcinvoke_cmd_req *req,
+ const union smcinvoke_arg *args_buf)
+{
+ uint32_t i = 0;
+
+ size_t total_size = sizeof(struct smcinvoke_msg_hdr) +
+ object_counts_total(req->counts) *
+ sizeof(union smcinvoke_tz_args);
+
+ /* Computed total_size should be 8 bytes aligned from start of buf */
+ total_size = ALIGN(total_size, SMCINVOKE_ARGS_ALIGN_SIZE);
+
+ /* each buffer has to be 8 bytes aligned */
+ while (i < object_counts_num_buffers(req->counts))
+ total_size = size_add(total_size,
+ size_align(args_buf[i++].b.size, SMCINVOKE_ARGS_ALIGN_SIZE));
+
+ /* Since we're using get_free_pages, no need for explicit PAGE align */
+ return total_size;
+}
+
+static int marshal_in(const struct smcinvoke_cmd_req *req,
+ const union smcinvoke_arg *args_buf, uint32_t tzhandle,
+ uint8_t *buf, size_t buf_size, struct file **arr_filp)
+{
+ int ret = -EINVAL, i = 0;
+ union smcinvoke_tz_args *tz_args = NULL;
+ struct smcinvoke_msg_hdr msg_hdr = {tzhandle, req->op, req->counts};
+ uint32_t offset = sizeof(struct smcinvoke_msg_hdr) +
+ sizeof(union smcinvoke_tz_args) *
+ object_counts_total(req->counts);
+
+ if (buf_size < offset)
+ goto out;
+
+ *(struct smcinvoke_msg_hdr *)buf = msg_hdr;
+ tz_args = (union smcinvoke_tz_args *)
+ (buf + sizeof(struct smcinvoke_msg_hdr));
+
+ FOR_ARGS(i, req->counts, BI) {
+ offset = size_align(offset, SMCINVOKE_ARGS_ALIGN_SIZE);
+ if ((offset > buf_size) ||
+ (args_buf[i].b.size > (buf_size - offset)))
+ goto out;
+
+ tz_args->b.offset = offset;
+ tz_args->b.size = args_buf[i].b.size;
+ tz_args++;
+
+ if (copy_from_user(buf+offset,
+ (void __user *)(uintptr_t)(args_buf[i].b.addr),
+ args_buf[i].b.size))
+ goto out;
+
+ offset += args_buf[i].b.size;
+ }
+ FOR_ARGS(i, req->counts, BO) {
+ offset = size_align(offset, SMCINVOKE_ARGS_ALIGN_SIZE);
+ if ((offset > buf_size) ||
+ (args_buf[i].b.size > (buf_size - offset)))
+ goto out;
+
+ tz_args->b.offset = offset;
+ tz_args->b.size = args_buf[i].b.size;
+ tz_args++;
+
+ offset += args_buf[i].b.size;
+ }
+ FOR_ARGS(i, req->counts, OI) {
+ if (get_tzhandle_from_fd(args_buf[i].o.fd,
+ &arr_filp[i], &(tz_args->tzhandle)))
+ goto out;
+ tz_args++;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+long smcinvoke_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int ret = -1, i = 0, nr_args = 0;
+ struct smcinvoke_cmd_req req = {0};
+ void *in_msg = NULL;
+ size_t inmsg_size = 0;
+ void *out_msg = NULL;
+ union smcinvoke_arg *args_buf = NULL;
+ struct file *filp_to_release[object_counts_max_OO] = {NULL};
+ struct smcinvoke_tzobj_context *tzobj = filp->private_data;
+
+ switch (cmd) {
+ case SMCINVOKE_IOCTL_INVOKE_REQ:
+ if (_IOC_SIZE(cmd) != sizeof(req)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = copy_from_user(&req, (void __user *)arg, sizeof(req));
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ nr_args = object_counts_num_buffers(req.counts) +
+ object_counts_num_objects(req.counts);
+
+ if (req.argsize != sizeof(union smcinvoke_arg)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (nr_args) {
+
+ args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL);
+ if (!args_buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = copy_from_user(args_buf,
+ (void __user *)(uintptr_t)(req.args),
+ nr_args * req.argsize);
+
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+
+ inmsg_size = compute_in_msg_size(&req, args_buf);
+ in_msg = (void *)__get_free_pages(GFP_KERNEL,
+ get_order(inmsg_size));
+ if (!in_msg) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ out_msg = (void *)__get_free_page(GFP_KERNEL);
+ if (!out_msg) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = marshal_in(&req, args_buf, tzobj->tzhandle, in_msg,
+ inmsg_size, filp_to_release);
+ if (ret)
+ goto out;
+
+ ret = prepare_send_scm_msg(in_msg, inmsg_size, out_msg,
+ SMCINVOKE_TZ_MIN_BUF_SIZE, &req.result);
+ if (ret)
+ goto out;
+
+ /*
+ * if invoke op results in an err, no need to marshal_out and
+ * copy args buf to user space
+ */
+ if (!req.result) {
+ ret = marshal_out(in_msg, inmsg_size, &req, args_buf);
+
+ ret |= copy_to_user(
+ (void __user *)(uintptr_t)(req.args),
+ args_buf, nr_args * req.argsize);
+ }
+ ret |= copy_to_user((void __user *)arg, &req, sizeof(req));
+ if (ret)
+ goto out;
+
+ break;
+ default:
+ ret = -ENOIOCTLCMD;
+ break;
+ }
+out:
+ free_page((long)out_msg);
+ free_pages((long)in_msg, get_order(inmsg_size));
+ kfree(args_buf);
+ for (i = 0; i < object_counts_max_OO; i++) {
+ if (filp_to_release[i])
+ fput(filp_to_release[i]);
+ }
+
+ return ret;
+}
+
+static int smcinvoke_open(struct inode *nodp, struct file *filp)
+{
+ struct smcinvoke_tzobj_context *tzcxt = NULL;
+
+ tzcxt = kzalloc(sizeof(*tzcxt), GFP_KERNEL);
+ if (!tzcxt)
+ return -ENOMEM;
+
+ tzcxt->tzhandle = SMCINVOKE_TZ_ROOT_OBJ;
+ filp->private_data = tzcxt;
+
+ return 0;
+}
+
+static int smcinvoke_release(struct inode *nodp, struct file *filp)
+{
+ int ret = 0, smcinvoke_result = 0;
+ uint8_t *in_buf = NULL;
+ uint8_t *out_buf = NULL;
+ struct smcinvoke_msg_hdr hdr = {0};
+ struct smcinvoke_tzobj_context *tzobj = filp->private_data;
+ uint32_t tzhandle = tzobj->tzhandle;
+
+ /* Root object is special in sense it is indestructible */
+ if (!tzhandle || tzhandle == SMCINVOKE_TZ_ROOT_OBJ)
+ goto out;
+
+ in_buf = (uint8_t *)__get_free_page(GFP_KERNEL);
+ out_buf = (uint8_t *)__get_free_page(GFP_KERNEL);
+ if (!in_buf || !out_buf)
+ goto out;
+
+ hdr.tzhandle = tzhandle;
+ hdr.op = object_op_RELEASE;
+ hdr.counts = 0;
+ *(struct smcinvoke_msg_hdr *)in_buf = hdr;
+
+ ret = prepare_send_scm_msg(in_buf, SMCINVOKE_TZ_MIN_BUF_SIZE,
+ out_buf, SMCINVOKE_TZ_MIN_BUF_SIZE, &smcinvoke_result);
+out:
+ kfree(filp->private_data);
+ free_page((long)in_buf);
+ free_page((long)out_buf);
+
+ return ret;
+}
+
+static int __init smcinvoke_init(void)
+{
+ unsigned int baseminor = 0;
+ unsigned int count = 1;
+ int rc = 0;
+
+ rc = alloc_chrdev_region(&smcinvoke_device_no, baseminor, count,
+ SMCINVOKE_DEV);
+ if (rc < 0) {
+ pr_err("chrdev_region failed %d for %s\n", rc, SMCINVOKE_DEV);
+ return rc;
+ }
+ driver_class = class_create(THIS_MODULE, SMCINVOKE_DEV);
+ if (IS_ERR(driver_class)) {
+ rc = -ENOMEM;
+ pr_err("class_create failed %d\n", rc);
+ goto exit_unreg_chrdev_region;
+ }
+ class_dev = device_create(driver_class, NULL, smcinvoke_device_no,
+ NULL, SMCINVOKE_DEV);
+ if (!class_dev) {
+ pr_err("class_device_create failed %d\n", rc);
+ rc = -ENOMEM;
+ goto exit_destroy_class;
+ }
+
+ cdev_init(&smcinvoke_cdev, &smcinvoke_fops);
+ smcinvoke_cdev.owner = THIS_MODULE;
+
+ rc = cdev_add(&smcinvoke_cdev, MKDEV(MAJOR(smcinvoke_device_no), 0),
+ count);
+ if (rc < 0) {
+ pr_err("cdev_add failed %d for %s\n", rc, SMCINVOKE_DEV);
+ goto exit_destroy_device;
+ }
+ return 0;
+
+exit_destroy_device:
+ device_destroy(driver_class, smcinvoke_device_no);
+exit_destroy_class:
+ class_destroy(driver_class);
+exit_unreg_chrdev_region:
+ unregister_chrdev_region(smcinvoke_device_no, count);
+
+ return rc;
+}
+
+static void __exit smcinvoke_exit(void)
+{
+ int count = 1;
+
+ cdev_del(&smcinvoke_cdev);
+ device_destroy(driver_class, smcinvoke_device_no);
+ class_destroy(driver_class);
+ unregister_chrdev_region(smcinvoke_device_no, count);
+}
+device_initcall(smcinvoke_init);
+module_exit(smcinvoke_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SMC Invoke driver");
diff --git a/drivers/soc/qcom/smcinvoke_object.h b/drivers/soc/qcom/smcinvoke_object.h
new file mode 100644
index 0000000..670b425
--- /dev/null
+++ b/drivers/soc/qcom/smcinvoke_object.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2016-2017, The Linux Foundation. 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.
+ */
+#ifndef __SMCINVOKE_OBJECT_H
+#define __SMCINVOKE_OBJECT_H
+
+#include <linux/types.h>
+
+#define object_op_METHOD_MASK ((uint32_t)0x0000FFFFu)
+#define object_op_RELEASE (object_op_METHOD_MASK - 0)
+#define object_op_RETAIN (object_op_METHOD_MASK - 1)
+
+#define object_counts_max_BI 0xF
+#define object_counts_max_BO 0xF
+#define object_counts_max_OI 0xF
+#define object_counts_max_OO 0xF
+
+/* unpack counts */
+
+#define object_counts_num_BI(k) ((size_t) (((k) >> 0) & object_counts_max_BI))
+#define object_counts_num_BO(k) ((size_t) (((k) >> 4) & object_counts_max_BO))
+#define object_counts_num_OI(k) ((size_t) (((k) >> 8) & object_counts_max_OI))
+#define object_counts_num_OO(k) ((size_t) (((k) >> 12) & object_counts_max_OO))
+#define object_counts_num_buffers(k) \
+ (object_counts_num_BI(k) + object_counts_num_BO(k))
+
+#define object_counts_num_objects(k) \
+ (object_counts_num_OI(k) + object_counts_num_OO(k))
+
+/* Indices into args[] */
+
+#define object_counts_index_BI(k) 0
+#define object_counts_index_BO(k) \
+ (object_counts_index_BI(k) + object_counts_num_BI(k))
+#define object_counts_index_OI(k) \
+ (object_counts_index_BO(k) + object_counts_num_BO(k))
+#define object_counts_index_OO(k) \
+ (object_counts_index_OI(k) + object_counts_num_OI(k))
+#define object_counts_total(k) \
+ (object_counts_index_OO(k) + object_counts_num_OO(k))
+
+
+#endif /* __SMCINVOKE_OBJECT_H */
diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c
index 52926f0..a9ebfed 100644
--- a/drivers/staging/android/ion/msm/msm_ion.c
+++ b/drivers/staging/android/ion/msm/msm_ion.c
@@ -621,7 +621,8 @@
vmid == VMID_CP_APP ||
vmid == VMID_CP_CAMERA_PREVIEW ||
vmid == VMID_CP_SPSS_SP ||
- vmid == VMID_CP_SPSS_SP_SHARED);
+ vmid == VMID_CP_SPSS_SP_SHARED ||
+ vmid == VMID_CP_SPSS_HLOS_SHARED);
}
unsigned int count_set_bits(unsigned long val)
@@ -669,6 +670,8 @@
return VMID_CP_SPSS_SP;
if (flags & ION_FLAG_CP_SPSS_SP_SHARED)
return VMID_CP_SPSS_SP_SHARED;
+ if (flags & ION_FLAG_CP_SPSS_HLOS_SHARED)
+ return VMID_CP_SPSS_HLOS_SHARED;
return -EINVAL;
}
/* fix up the cases where the ioctl direction bits are incorrect */
diff --git a/drivers/staging/android/uapi/msm_ion.h b/drivers/staging/android/uapi/msm_ion.h
index 7381ee9..84598db 100644
--- a/drivers/staging/android/uapi/msm_ion.h
+++ b/drivers/staging/android/uapi/msm_ion.h
@@ -89,6 +89,7 @@
#define ION_FLAG_CP_SEC_DISPLAY ION_BIT(25)
#define ION_FLAG_CP_APP ION_BIT(26)
#define ION_FLAG_CP_CAMERA_PREVIEW ION_BIT(27)
+#define ION_FLAG_CP_SPSS_HLOS_SHARED ION_BIT(30)
/**
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 94ba2c3e..d1cde1b 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -1069,6 +1069,14 @@
SE_GENI_TX_PACKING_CFG0);
geni_write_reg_nolog(cfg1, uport->membase,
SE_GENI_TX_PACKING_CFG1);
+ msm_port->handle_rx = handle_rx_hs;
+ msm_port->rx_fifo = devm_kzalloc(uport->dev,
+ sizeof(msm_port->rx_fifo_depth * sizeof(u32)),
+ GFP_KERNEL);
+ if (!msm_port->rx_fifo) {
+ ret = -ENOMEM;
+ goto exit_portsetup;
+ }
} else {
/*
* Make an unconditional cancel on the main sequencer to reset
@@ -1166,12 +1174,12 @@
goto exit_startup;
}
+ get_tx_fifo_size(msm_port);
if (!msm_port->port_setup) {
if (msm_geni_serial_port_setup(uport))
goto exit_startup;
}
- get_tx_fifo_size(msm_port);
msm_geni_serial_start_rx(uport);
/*
* Ensure that all the port configuration writes complete
@@ -1790,10 +1798,6 @@
dev_port->rx_fifo = devm_kzalloc(uport->dev, sizeof(u32),
GFP_KERNEL);
} else {
- dev_port->handle_rx = handle_rx_hs;
- dev_port->rx_fifo = devm_kzalloc(uport->dev,
- sizeof(dev_port->rx_fifo_depth * sizeof(u32)),
- GFP_KERNEL);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_enable(&pdev->dev);
}
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 96b21b0..3116edf 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -223,6 +223,10 @@
/* Blackmagic Design UltraStudio SDI */
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+ /* Hauppauge HVR-950q */
+ { USB_DEVICE(0x2040, 0x7200), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
+
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7272f9a..92e5d13 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -279,6 +279,8 @@
usb_destroy_configuration(udev);
usb_release_bos_descriptor(udev);
+ if (udev->parent)
+ of_node_put(dev->of_node);
usb_put_hcd(hcd);
kfree(udev->product);
kfree(udev->manufacturer);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 81f3384..3e9d233 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1768,9 +1768,10 @@
/*
* Below sequence is used when controller is working without
- * having ssphy and only USB high speed is supported.
+ * having ssphy and only USB high/full speed is supported.
*/
- if (dwc->maximum_speed == USB_SPEED_HIGH) {
+ if (dwc->maximum_speed == USB_SPEED_HIGH ||
+ dwc->maximum_speed == USB_SPEED_FULL) {
dwc3_msm_write_reg(mdwc->base, QSCRATCH_GENERAL_CFG,
dwc3_msm_read_reg(mdwc->base,
QSCRATCH_GENERAL_CFG)
@@ -3763,20 +3764,9 @@
platform_device_del(dwc->xhci);
usb_unregister_notify(&mdwc->host_nb);
- /*
- * Perform USB hardware RESET (both core reset and DBM reset)
- * when moving from host to peripheral. This is required for
- * peripheral mode to work.
- */
- dwc3_msm_block_reset(mdwc, true);
-
dwc3_usb3_phy_suspend(dwc, false);
- dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
-
mdwc->in_host_mode = false;
- /* re-init core and OTG registers as block reset clears these */
- dwc3_post_host_reset_core_init(dwc);
pm_runtime_mark_last_busy(mdwc->dev);
pm_runtime_put_sync_autosuspend(mdwc->dev);
dbg_event(0xFF, "StopHost psync",
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index aaaf256..4cf5381 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -231,7 +231,7 @@
dwc3_data->syscfg_reg_off = res->start;
- dev_vdbg(&pdev->dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n",
+ dev_vdbg(&pdev->dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n",
dwc3_data->glue_base, dwc3_data->syscfg_reg_off);
dwc3_data->rstc_pwrdn =
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7d8566f..edd000b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1211,9 +1211,9 @@
return -ESHUTDOWN;
}
- if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
+ if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
&req->request, req->dep->name)) {
- dwc3_trace(trace_dwc3_gadget, "request %p belongs to '%s'",
+ dwc3_trace(trace_dwc3_gadget, "request %pK belongs to '%s'",
&req->request, req->dep->name);
return -EINVAL;
}
@@ -1405,7 +1405,7 @@
dwc3_stop_active_transfer(dwc, dep->number, true);
goto out1;
}
- dev_err(dwc->dev, "request %p was not queued to %s\n",
+ dev_err(dwc->dev, "request %pK was not queued to %s\n",
request, ep->name);
ret = -EINVAL;
goto out0;
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index e9e8f46..af3ce4f 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -19,6 +19,39 @@
#include "core.h"
+static int dwc3_host_get_irq(struct dwc3 *dwc)
+{
+ struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
+ int irq;
+
+ irq = platform_get_irq_byname(dwc3_pdev, "host");
+ if (irq > 0)
+ goto out;
+
+ if (irq == -EPROBE_DEFER)
+ goto out;
+
+ irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
+ if (irq > 0)
+ goto out;
+
+ if (irq == -EPROBE_DEFER)
+ goto out;
+
+ irq = platform_get_irq(dwc3_pdev, 0);
+ if (irq > 0)
+ goto out;
+
+ if (irq != -EPROBE_DEFER)
+ dev_err(dwc->dev, "missing host IRQ\n");
+
+ if (!irq)
+ irq = -EINVAL;
+
+out:
+ return irq;
+}
+
int dwc3_host_init(struct dwc3 *dwc)
{
struct property_entry props[3];
@@ -28,39 +61,18 @@
struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
int prop_idx = 0;
- irq = platform_get_irq_byname(dwc3_pdev, "host");
- if (irq == -EPROBE_DEFER)
+ irq = dwc3_host_get_irq(dwc);
+ if (irq < 0)
return irq;
- if (irq <= 0) {
- irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
- if (irq == -EPROBE_DEFER)
- return irq;
-
- if (irq <= 0) {
- irq = platform_get_irq(dwc3_pdev, 0);
- if (irq <= 0) {
- if (irq != -EPROBE_DEFER) {
- dev_err(dwc->dev,
- "missing host IRQ\n");
- }
- if (!irq)
- irq = -EINVAL;
- return irq;
- } else {
- res = platform_get_resource(dwc3_pdev,
- IORESOURCE_IRQ, 0);
- }
- } else {
- res = platform_get_resource_byname(dwc3_pdev,
- IORESOURCE_IRQ,
- "dwc_usb3");
- }
-
- } else {
+ res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ, "host");
+ if (!res)
res = platform_get_resource_byname(dwc3_pdev, IORESOURCE_IRQ,
- "host");
- }
+ "dwc_usb3");
+ if (!res)
+ res = platform_get_resource(dwc3_pdev, IORESOURCE_IRQ, 0);
+ if (!res)
+ return -ENOMEM;
dwc->xhci_resources[1].start = irq;
dwc->xhci_resources[1].end = irq;
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index ea17164..102003d 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -1545,7 +1545,7 @@
}
seq_printf(s, "vfs_write(time in usec) min:%d\t max:%d\t avg:%d\n",
- min, max, sum / iteration);
+ min, max, (iteration ? (sum / iteration) : 0));
min = max = sum = iteration = 0;
seq_puts(s, "\n=======================\n");
seq_puts(s, "USB MTP IN related VFS read stats:\n");
@@ -1567,7 +1567,7 @@
}
seq_printf(s, "vfs_read(time in usec) min:%d\t max:%d\t avg:%d\n",
- min, max, sum / iteration);
+ min, max, (iteration ? (sum / iteration) : 0));
spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 32aa45e..b0c4f12 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1535,6 +1535,9 @@
t2 |= PORT_WKOC_E | PORT_WKCONN_E;
t2 &= ~PORT_WKDISC_E;
}
+ if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
+ (hcd->speed < HCD_USB3))
+ t2 &= ~PORT_WAKE_BITS;
} else
t2 &= ~PORT_WAKE_BITS;
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 69864ba..672751e 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -54,6 +54,11 @@
#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+
static const char hcd_name[] = "xhci_hcd";
static struct hc_driver __read_mostly xhci_pci_hc_driver;
@@ -135,6 +140,13 @@
if (pdev->vendor == PCI_VENDOR_ID_AMD)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
+ ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
+ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
+ xhci->quirks |= XHCI_U2_DISABLE_WAKE;
+
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
xhci->quirks |= XHCI_LPM_SUPPORT;
xhci->quirks |= XHCI_INTEL_HOST;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 86d578e..3a7fb29 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1668,6 +1668,7 @@
/* For controller with a broken Port Disable implementation */
#define XHCI_BROKEN_PORT_PED (1 << 25)
#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
+#define XHCI_U2_DISABLE_WAKE (1 << 27)
unsigned int num_active_eps;
unsigned int limit_active_eps;
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 2682d29..f232f2d 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -182,7 +182,7 @@
#define PS_HARD_RESET_TIME 25
#define PS_SOURCE_ON 400
#define PS_SOURCE_OFF 750
-#define SWAP_SOURCE_START_TIME 20
+#define FIRST_SOURCE_CAP_TIME 200
#define VDM_BUSY_TIME 50
#define VCONN_ON_TIME 100
@@ -796,17 +796,27 @@
pd->pd_phy_opened = true;
}
- pd->current_state = PE_SRC_SEND_CAPABILITIES;
if (pd->in_pr_swap) {
- kick_sm(pd, SWAP_SOURCE_START_TIME);
pd->in_pr_swap = false;
val.intval = 0;
power_supply_set_property(pd->usb_psy,
POWER_SUPPLY_PROP_PR_SWAP, &val);
- break;
}
- /* fall-through */
+ /*
+ * A sink might remove its terminations (during some Type-C
+ * compliance tests or a sink attempting to do Try.SRC)
+ * at this point just after we enabled VBUS. Sending PD
+ * messages now would delay detecting the detach beyond the
+ * required timing. Instead, delay sending out the first
+ * source capabilities to allow for the other side to
+ * completely settle CC debounce and allow HW to detect detach
+ * sooner in the meantime. PD spec allows up to
+ * tFirstSourceCap (250ms).
+ */
+ pd->current_state = PE_SRC_SEND_CAPABILITIES;
+ kick_sm(pd, FIRST_SOURCE_CAP_TIME);
+ break;
case PE_SRC_SEND_CAPABILITIES:
kick_sm(pd, 0);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 8bb4875..84b444f 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -135,6 +135,7 @@
{ USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
+ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 3bf61ac..ebe51f11 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1877,6 +1877,10 @@
.driver_info = (kernel_ulong_t)&four_g_w100_blacklist
},
{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff),
+ .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+ { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff),
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index fd509ed6c..652b433 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -158,6 +158,7 @@
{DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */
{DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */
{DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */
+ {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */
{DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */
{DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */
{DEVICE_SWI(0x1199, 0x9078)}, /* Sierra Wireless EM74xx */
diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c
index 44ab43f..af10f7b 100644
--- a/drivers/usb/usbip/stub_main.c
+++ b/drivers/usb/usbip/stub_main.c
@@ -262,7 +262,11 @@
kmem_cache_free(stub_priv_cache, priv);
kfree(urb->transfer_buffer);
+ urb->transfer_buffer = NULL;
+
kfree(urb->setup_packet);
+ urb->setup_packet = NULL;
+
usb_free_urb(urb);
}
}
diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c
index 6b1e8c3..be50cef 100644
--- a/drivers/usb/usbip/stub_tx.c
+++ b/drivers/usb/usbip/stub_tx.c
@@ -28,7 +28,11 @@
struct urb *urb = priv->urb;
kfree(urb->setup_packet);
+ urb->setup_packet = NULL;
+
kfree(urb->transfer_buffer);
+ urb->transfer_buffer = NULL;
+
list_del(&priv->list);
kmem_cache_free(stub_priv_cache, priv);
usb_free_urb(urb);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 1afa111..aca0d88 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -315,7 +315,7 @@
struct ceph_mds_client *mdsc = fsc->mdsc;
int i;
int err;
- u32 ftype;
+ unsigned frag = -1;
struct ceph_mds_reply_info_parsed *rinfo;
dout("readdir %p file %p pos %llx\n", inode, file, ctx->pos);
@@ -362,7 +362,6 @@
/* do we have the correct frag content buffered? */
if (need_send_readdir(fi, ctx->pos)) {
struct ceph_mds_request *req;
- unsigned frag;
int op = ceph_snap(inode) == CEPH_SNAPDIR ?
CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR;
@@ -373,8 +372,11 @@
}
if (is_hash_order(ctx->pos)) {
- frag = ceph_choose_frag(ci, fpos_hash(ctx->pos),
- NULL, NULL);
+ /* fragtree isn't always accurate. choose frag
+ * based on previous reply when possible. */
+ if (frag == (unsigned)-1)
+ frag = ceph_choose_frag(ci, fpos_hash(ctx->pos),
+ NULL, NULL);
} else {
frag = fpos_frag(ctx->pos);
}
@@ -497,6 +499,7 @@
struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
struct ceph_vino vino;
ino_t ino;
+ u32 ftype;
BUG_ON(rde->offset < ctx->pos);
@@ -519,15 +522,17 @@
ctx->pos++;
}
+ ceph_mdsc_put_request(fi->last_readdir);
+ fi->last_readdir = NULL;
+
if (fi->next_offset > 2) {
- ceph_mdsc_put_request(fi->last_readdir);
- fi->last_readdir = NULL;
+ frag = fi->frag;
goto more;
}
/* more frags? */
if (!ceph_frag_is_rightmost(fi->frag)) {
- unsigned frag = ceph_frag_next(fi->frag);
+ frag = ceph_frag_next(fi->frag);
if (is_hash_order(ctx->pos)) {
loff_t new_pos = ceph_make_fpos(ceph_frag_value(frag),
fi->next_offset, true);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 350a2c8..1493ceb 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -741,16 +741,10 @@
* Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
* is defined as O_NONBLOCK on some platforms and not on others.
*/
- BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
- O_RDONLY | O_WRONLY | O_RDWR |
- O_CREAT | O_EXCL | O_NOCTTY |
- O_TRUNC | O_APPEND | /* O_NONBLOCK | */
- __O_SYNC | O_DSYNC | FASYNC |
- O_DIRECT | O_LARGEFILE | O_DIRECTORY |
- O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
- __FMODE_EXEC | O_PATH | __O_TMPFILE |
- __FMODE_NONOTIFY
- ));
+ BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
+ HWEIGHT32(
+ (VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
+ __FMODE_EXEC | __FMODE_NONOTIFY));
fasync_cache = kmem_cache_create("fasync_cache",
sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 6528724..7bff6f4 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -80,9 +80,9 @@
static struct rhashtable gl_hash_table;
-void gfs2_glock_free(struct gfs2_glock *gl)
+static void gfs2_glock_dealloc(struct rcu_head *rcu)
{
- struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+ struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
if (gl->gl_ops->go_flags & GLOF_ASPACE) {
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
@@ -90,6 +90,13 @@
kfree(gl->gl_lksb.sb_lvbptr);
kmem_cache_free(gfs2_glock_cachep, gl);
}
+}
+
+void gfs2_glock_free(struct gfs2_glock *gl)
+{
+ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+ call_rcu(&gl->gl_rcu, gfs2_glock_dealloc);
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
wake_up(&sdp->sd_glock_wait);
}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 51519c2..a04bf95 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -370,6 +370,7 @@
loff_t end;
} gl_vm;
};
+ struct rcu_head gl_rcu;
struct rhash_head gl_node;
};
diff --git a/fs/open.c b/fs/open.c
index 568749b..73b7d19 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -915,6 +915,12 @@
int lookup_flags = 0;
int acc_mode = ACC_MODE(flags);
+ /*
+ * Clear out all open flags we don't know about so that we don't report
+ * them in fcntl(F_GETFD) or similar interfaces.
+ */
+ flags &= VALID_OPEN_FLAGS;
+
if (flags & (O_CREAT | __O_TMPFILE))
op->mode = (mode & S_IALLUGO) | S_IFREG;
else
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 3c5b51d..80825b2 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -364,41 +364,34 @@
return err;
}
-/* A feature which supports mount_nodev() with options */
-static struct dentry *mount_nodev_with_options(struct vfsmount *mnt,
- struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data,
- int (*fill_super)(struct vfsmount *, struct super_block *,
- const char *, void *, int))
+struct sdcardfs_mount_private {
+ struct vfsmount *mnt;
+ const char *dev_name;
+ void *raw_data;
+};
+static int __sdcardfs_fill_super(
+ struct super_block *sb,
+ void *_priv, int silent)
{
- int error;
- struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL);
+ struct sdcardfs_mount_private *priv = _priv;
- if (IS_ERR(s))
- return ERR_CAST(s);
-
- s->s_flags = flags;
-
- error = fill_super(mnt, s, dev_name, data, flags & MS_SILENT ? 1 : 0);
- if (error) {
- deactivate_locked_super(s);
- return ERR_PTR(error);
- }
- s->s_flags |= MS_ACTIVE;
- return dget(s->s_root);
+ return sdcardfs_read_super(priv->mnt,
+ sb, priv->dev_name, priv->raw_data, silent);
}
static struct dentry *sdcardfs_mount(struct vfsmount *mnt,
struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
- /*
- * dev_name is a lower_path_name,
- * raw_data is a option string.
- */
- return mount_nodev_with_options(mnt, fs_type, flags, dev_name,
- raw_data, sdcardfs_read_super);
+ struct sdcardfs_mount_private priv = {
+ .mnt = mnt,
+ .dev_name = dev_name,
+ .raw_data = raw_data
+ };
+
+ return mount_nodev(fs_type, flags,
+ &priv, __sdcardfs_fill_super);
}
static struct dentry *sdcardfs_mount_wrn(struct file_system_type *fs_type,
@@ -423,7 +416,7 @@
list_del(&sbi->list);
mutex_unlock(&sdcardfs_super_list_lock);
}
- generic_shutdown_super(sb);
+ kill_anon_super(sb);
}
static struct file_system_type sdcardfs_fs_type = {
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h
index 678a885..3d58645 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdm845.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h
@@ -201,7 +201,16 @@
#define GCC_SDCC1_ICE_CORE_CLK 183
#define GCC_SDCC1_APPS_CLK_SRC 184
#define GCC_SDCC1_ICE_CORE_CLK_SRC 185
-
+#define GCC_APC_VS_CLK 186
+#define GCC_GPU_VS_CLK 187
+#define GCC_MSS_VS_CLK 188
+#define GCC_VDDA_VS_CLK 189
+#define GCC_VDDCX_VS_CLK 190
+#define GCC_VDDMX_VS_CLK 191
+#define GCC_VS_CTRL_AHB_CLK 192
+#define GCC_VS_CTRL_CLK 193
+#define GCC_VS_CTRL_CLK_SRC 194
+#define GCC_VSENSOR_CLK_SRC 195
/* GCC reset clocks */
#define GCC_MMSS_BCR 0
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 76ce329..1b48d9c 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -3,6 +3,12 @@
#include <uapi/linux/fcntl.h>
+/* list of all valid flags for the open/openat flags argument: */
+#define VALID_OPEN_FLAGS \
+ (O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
+ O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \
+ FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
+ O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
#ifndef force_o_largefile
#define force_o_largefile() (BITS_PER_LONG != 32)
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 78f01ea..86a2dc6 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -49,5 +49,6 @@
bool mbox_client_peek_data(struct mbox_chan *chan); /* atomic */
void mbox_free_channel(struct mbox_chan *chan); /* may sleep */
bool mbox_controller_is_idle(struct mbox_chan *chan); /* atomic */
+void mbox_chan_debug(struct mbox_chan *chan);
#endif /* __MAILBOX_CLIENT_H */
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 30a4ed2..7827c68 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -49,6 +49,8 @@
* Used only if txdone_poll:=true && txdone_irq:=false
* @peek_data: Atomic check for any received data. Return true if controller
* has some data to push to the client. False otherwise.
+ * @debug: Allow chan to be debugged when the client detects a channel is
+ * locked up.
*/
struct mbox_chan_ops {
int (*send_data)(struct mbox_chan *chan, void *data);
@@ -90,6 +92,7 @@
struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
const struct of_phandle_args *sp);
bool (*is_idle)(struct mbox_controller *mbox);
+ void (*debug)(struct mbox_chan *chan);
/* Internal to API */
struct hrtimer poll_hrt;
struct list_head node;
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index d6ebc01..37e5178 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -415,6 +415,11 @@
for (idx = 0, rgn = &memblock_type->regions[0]; \
idx < memblock_type->cnt; \
idx++, rgn = &memblock_type->regions[idx])
+#define for_each_memblock_rev(memblock_type, region) \
+ for (region = memblock.memblock_type.regions + \
+ memblock.memblock_type.cnt - 1; \
+ region >= memblock.memblock_type.regions; \
+ region--)
#ifdef CONFIG_MEMTEST
extern void early_memtest(phys_addr_t start, phys_addr_t end);
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index b4c1be4..b994010 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -350,7 +350,7 @@
int (*post_reset)(struct wcd9xxx *wcd9xxx);
void *ssr_priv;
- bool dev_up;
+ unsigned long dev_up;
u32 num_of_supplies;
struct regulator_bulk_data *supplies;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6a14034..ebc54fc 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -478,16 +478,16 @@
* On nommu, vmalloc/vfree wrap through kmalloc/kfree directly, so there
* is no special casing required.
*/
-static inline bool is_vmalloc_addr(const void *x)
-{
-#ifdef CONFIG_MMU
- unsigned long addr = (unsigned long)x;
- return addr >= VMALLOC_START && addr < VMALLOC_END;
+#ifdef CONFIG_MMU
+extern int is_vmalloc_addr(const void *x);
#else
- return false;
-#endif
+static inline int is_vmalloc_addr(const void *x)
+{
+ return 0;
}
+#endif
+
#ifdef CONFIG_MMU
extern int is_vmalloc_or_module_addr(const void *x);
#else
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 5c0b3fa..b305b0e 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -582,9 +582,9 @@
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointRequest \
- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 3d9d786..826eef8 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -19,6 +19,8 @@
#define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */
#define VM_NO_GUARD 0x00000040 /* don't add guard page */
#define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */
+#define VM_LOWMEM 0x00000100 /* Tracking of direct mapped lowmem */
+
/* bits [20..32] reserved for arch specific ioremap internals */
/*
@@ -159,6 +161,13 @@
extern struct list_head vmap_area_list;
extern __init void vm_area_add_early(struct vm_struct *vm);
extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
+extern __init int vm_area_check_early(struct vm_struct *vm);
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+extern void mark_vmalloc_reserved_area(void *addr, unsigned long size);
+#else
+static inline void mark_vmalloc_reserved_area(void *addr, unsigned long size)
+{ };
+#endif
#ifdef CONFIG_SMP
# ifdef CONFIG_MMU
@@ -184,7 +193,12 @@
#endif
#ifdef CONFIG_MMU
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+extern unsigned long total_vmalloc_size;
+#define VMALLOC_TOTAL total_vmalloc_size
+#else
#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
+#endif
#else
#define VMALLOC_TOTAL 0UL
#endif
diff --git a/include/soc/qcom/qseecomi.h b/include/soc/qcom/qseecomi.h
index 0efea04..a7d4190 100644
--- a/include/soc/qcom/qseecomi.h
+++ b/include/soc/qcom/qseecomi.h
@@ -336,7 +336,7 @@
__packed struct qseecom_continue_blocked_request_ireq {
uint32_t qsee_cmd_id;
- uint32_t app_id;
+ uint32_t app_or_session_id; /*legacy: app_id; smcinvoke: session_id*/
};
@@ -682,6 +682,9 @@
#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x04)
+#define TZ_OS_CONTINUE_BLOCKED_REQUEST_SMCINVOKE_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x07)
+
#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
diff --git a/include/soc/qcom/secure_buffer.h b/include/soc/qcom/secure_buffer.h
index a08cfe1..6afaf67 100644
--- a/include/soc/qcom/secure_buffer.h
+++ b/include/soc/qcom/secure_buffer.h
@@ -40,6 +40,7 @@
VMID_CP_SPSS_SP = 0x1A,
VMID_CP_CAMERA_PREVIEW = 0x1D,
VMID_CP_SPSS_SP_SHARED = 0x22,
+ VMID_CP_SPSS_HLOS_SHARED = 0x24,
VMID_LAST,
VMID_INVAL = -1
};
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index eb7e0c6..71c2c9e 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -322,6 +322,7 @@
#define DRM_EVENT_AD_BACKLIGHT 0x80000001
#define DRM_EVENT_CRTC_POWER 0x80000002
#define DRM_EVENT_SYS_BACKLIGHT 0x80000003
+#define DRM_EVENT_SDE_POWER 0x80000004
#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
diff --git a/include/uapi/drm/msm_drm_pp.h b/include/uapi/drm/msm_drm_pp.h
index 7945af0..c7f2308 100644
--- a/include/uapi/drm/msm_drm_pp.h
+++ b/include/uapi/drm/msm_drm_pp.h
@@ -28,17 +28,35 @@
/**
* struct drm_msm_pcc - pcc feature structure
- * flags: for customizing operations
- * r: red coefficients.
- * g: green coefficients.
- * b: blue coefficients.
+ * @flags: for customizing operations
+ * @r: red coefficients.
+ * @g: green coefficients.
+ * @b: blue coefficients.
+ * @r_rr: second order coefficients
+ * @r_gg: second order coefficients
+ * @r_bb: second order coefficients
+ * @g_rr: second order coefficients
+ * @g_gg: second order coefficients
+ * @g_bb: second order coefficients
+ * @b_rr: second order coefficients
+ * @b_gg: second order coefficients
+ * @b_bb: second order coefficients
*/
-
+#define DRM_MSM_PCC3
struct drm_msm_pcc {
__u64 flags;
struct drm_msm_pcc_coeff r;
struct drm_msm_pcc_coeff g;
struct drm_msm_pcc_coeff b;
+ __u32 r_rr;
+ __u32 r_gg;
+ __u32 r_bb;
+ __u32 g_rr;
+ __u32 g_gg;
+ __u32 g_bb;
+ __u32 b_rr;
+ __u32 b_gg;
+ __u32 b_bb;
};
/* struct drm_msm_pa_vlut - picture adjustment vLUT structure
@@ -135,6 +153,26 @@
__u32 c2[PGC_TBL_LEN];
};
+#define IGC_TBL_LEN 256
+#define IGC_DITHER_ENABLE (1 << 0)
+/**
+ * struct drm_msm_igc_lut - igc lut feature structure
+ * @flags: flags for the feature customization, values can be:
+ * - IGC_DITHER_ENABLE: Enable dither functionality
+ * @c0: color0 component lut
+ * @c1: color1 component lut
+ * @c2: color2 component lut
+ * @strength: dither strength, considered valid when IGC_DITHER_ENABLE
+ * is set in flags. Strength value based on source bit width.
+ */
+struct drm_msm_igc_lut {
+ __u64 flags;
+ __u32 c0[IGC_TBL_LEN];
+ __u32 c1[IGC_TBL_LEN];
+ __u32 c2[IGC_TBL_LEN];
+ __u32 strength;
+};
+
#define AD4_LUT_GRP0_SIZE 33
#define AD4_LUT_GRP1_SIZE 32
/*
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index e5c4ddf..731b2f0 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1074,6 +1074,11 @@
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
};
+#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 109)
+#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 110)
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index e6c1a45..e073c5c 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -43,6 +43,10 @@
#define V4L_EVENT_CAM_REQ_MGR_ERROR 1
#define V4L_EVENT_CAM_REQ_MGR_MAX 2
+/* SOF Event status */
+#define CAM_REQ_MGR_SOF_EVENT_SUCCESS 0
+#define CAM_REQ_MGR_SOF_EVENT_ERROR 1
+
/**
* Request Manager : flush_type
* @CAM_REQ_MGR_FLUSH_TYPE_ALL: Req mgr will remove all the pending
@@ -353,14 +357,18 @@
/**
* struct cam_req_mgr_frame_msg
- * @request_id: request id of frame
- * @frame_count: running count of frames
- * @timestamp: timestamp of frame
+ * @request_id: request id of the frame
+ * @frame_id: frame id of the frame
+ * @timestamp: timestamp of the frame
+ * @link_hdl: link handle associated with this message
+ * @sof_status: sof status success or fail
*/
struct cam_req_mgr_frame_msg {
uint64_t request_id;
- uint64_t frame_count;
+ uint64_t frame_id;
uint64_t timestamp;
+ int32_t link_hdl;
+ uint32_t sof_status;
};
/**
diff --git a/include/uapi/sound/devdep_params.h b/include/uapi/sound/devdep_params.h
index 5061ec0..9e3133b 100644
--- a/include/uapi/sound/devdep_params.h
+++ b/include/uapi/sound/devdep_params.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015,2017, The Linux Foundation. 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
@@ -66,4 +66,14 @@
uint32_t device;
} __packed;
+#define HWDEP_FE_BASE 3000 /*unique base for FE hw dep nodes*/
+struct snd_pcm_mmap_fd {
+ int32_t dir;
+ int32_t fd;
+ int32_t size;
+ int32_t actual_size;
+};
+
+#define SNDRV_PCM_IOCTL_MMAP_DATA_FD _IOWR('U', 0xd2, struct snd_pcm_mmap_fd)
+
#endif
diff --git a/kernel/configs/android-base.config b/kernel/configs/android-base.config
index 301e1a6..80df048 100644
--- a/kernel/configs/android-base.config
+++ b/kernel/configs/android-base.config
@@ -17,7 +17,6 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_BPF=y
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index b6a639b..dce76d1 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -404,12 +404,13 @@
static void sugov_work(struct kthread_work *work)
{
struct sugov_policy *sg_policy = container_of(work, struct sugov_policy, work);
+ unsigned long flags;
mutex_lock(&sg_policy->work_lock);
- raw_spin_lock(&sg_policy->update_lock);
+ raw_spin_lock_irqsave(&sg_policy->update_lock, flags);
sugov_track_cycles(sg_policy, sg_policy->policy->cur,
sched_ktime_clock());
- raw_spin_unlock(&sg_policy->update_lock);
+ raw_spin_unlock_irqrestore(&sg_policy->update_lock, flags);
__cpufreq_driver_target(sg_policy->policy, sg_policy->next_freq,
CPUFREQ_RELATION_L);
mutex_unlock(&sg_policy->work_lock);
@@ -488,18 +489,19 @@
unsigned int val;
struct sugov_policy *sg_policy;
unsigned long hs_util;
+ unsigned long flags;
if (kstrtouint(buf, 10, &val))
return -EINVAL;
tunables->hispeed_freq = val;
list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook) {
- raw_spin_lock(&sg_policy->update_lock);
+ raw_spin_lock_irqsave(&sg_policy->update_lock, flags);
hs_util = freq_to_util(sg_policy,
sg_policy->tunables->hispeed_freq);
hs_util = mult_frac(hs_util, TARGET_LOAD, 100);
sg_policy->hispeed_util = hs_util;
- raw_spin_unlock(&sg_policy->update_lock);
+ raw_spin_unlock_irqrestore(&sg_policy->update_lock, flags);
}
return count;
@@ -784,13 +786,14 @@
static void sugov_limits(struct cpufreq_policy *policy)
{
struct sugov_policy *sg_policy = policy->governor_data;
+ unsigned long flags;
if (!policy->fast_switch_enabled) {
mutex_lock(&sg_policy->work_lock);
- raw_spin_lock(&sg_policy->update_lock);
+ raw_spin_lock_irqsave(&sg_policy->update_lock, flags);
sugov_track_cycles(sg_policy, sg_policy->policy->cur,
sched_ktime_clock());
- raw_spin_unlock(&sg_policy->update_lock);
+ raw_spin_unlock_irqrestore(&sg_policy->update_lock, flags);
cpufreq_policy_apply_limits(policy);
mutex_unlock(&sg_policy->work_lock);
}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d06ac7d..1c5bb37 100755
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5407,10 +5407,13 @@
}
static inline bool
-bias_to_waker_cpu(struct task_struct *p, int cpu)
+bias_to_waker_cpu(struct task_struct *p, int cpu, struct cpumask *rtg_target)
{
+ int rtg_target_cpu = rtg_target ? cpumask_first(rtg_target) : cpu;
+
return cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
cpu_active(cpu) && !cpu_isolated(cpu) &&
+ capacity_orig_of(cpu) >= capacity_orig_of(rtg_target_cpu) &&
task_fits_max(p, cpu);
}
@@ -6730,6 +6733,7 @@
bool need_idle;
enum sched_boost_policy placement_boost = task_sched_boost(p) ?
sched_boost_policy() : SCHED_BOOST_NONE;
+ struct related_thread_group *grp;
sd = rcu_dereference(per_cpu(sd_ea, task_cpu(p)));
@@ -6745,22 +6749,17 @@
need_idle = wake_to_idle(p);
- if (sync && bias_to_waker_cpu(p, cpu)) {
+ grp = task_related_thread_group(p);
+ if (grp && grp->preferred_cluster)
+ rtg_target = &grp->preferred_cluster->cpus;
+
+ if (sync && bias_to_waker_cpu(p, cpu, rtg_target)) {
trace_sched_task_util_bias_to_waker(p, task_cpu(p),
task_util(p), cpu, cpu, 0, need_idle);
return cpu;
}
if (sysctl_sched_is_big_little) {
- struct related_thread_group *grp;
-
- rcu_read_lock();
- grp = task_related_thread_group(p);
- rcu_read_unlock();
-
- if (grp && grp->preferred_cluster)
- rtg_target = &grp->preferred_cluster->cpus;
-
task_util_boosted = boosted_task_util(p);
/*
@@ -7080,8 +7079,12 @@
return select_best_cpu(p, prev_cpu, 0, sync);
#endif
- if (energy_aware())
- return energy_aware_wake_cpu(p, prev_cpu, sync);
+ if (energy_aware()) {
+ rcu_read_lock();
+ new_cpu = energy_aware_wake_cpu(p, prev_cpu, sync);
+ rcu_read_unlock();
+ return new_cpu;
+ }
if (sd_flag & SD_BALANCE_WAKE) {
record_wakee(p);
@@ -12296,7 +12299,9 @@
rq->curr->nr_cpus_allowed == 1)
return;
+ rcu_read_lock();
new_cpu = energy_aware_wake_cpu(p, cpu, 0);
+ rcu_read_unlock();
if (capacity_orig_of(new_cpu) > capacity_orig_of(cpu)) {
active_balance = kick_active_balance(rq, p, new_cpu);
if (active_balance) {
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index b076cba..674bbd82 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2463,9 +2463,12 @@
if (write) {
if (*negp)
return -EINVAL;
+ if (*lvalp > UINT_MAX)
+ return -EINVAL;
*valp = *lvalp;
} else {
unsigned int val = *valp;
+ *negp = false;
*lvalp = (unsigned long)val;
}
return 0;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 8d2b4d8..5ff45ca 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -667,30 +667,25 @@
pr_info("Probe point is not specified.\n");
return -EINVAL;
}
- if (isdigit(argv[1][0])) {
- if (is_return) {
- pr_info("Return probe point must be a symbol.\n");
- return -EINVAL;
- }
- /* an address specified */
- ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr);
- if (ret) {
- pr_info("Failed to parse address.\n");
- return ret;
- }
- } else {
+
+ /* try to parse an address. if that fails, try to read the
+ * input as a symbol. */
+ if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
/* a symbol specified */
symbol = argv[1];
/* TODO: support .init module functions */
ret = traceprobe_split_symbol_offset(symbol, &offset);
if (ret) {
- pr_info("Failed to parse symbol.\n");
+ pr_info("Failed to parse either an address or a symbol.\n");
return ret;
}
if (offset && is_return) {
pr_info("Return probe must be used without offset.\n");
return -EINVAL;
}
+ } else if (is_return) {
+ pr_info("Return probe point must be a symbol.\n");
+ return -EINVAL;
}
argc -= 2; argv += 2;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 195de42..ad182e6 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -301,6 +301,57 @@
static unsigned long vmap_area_pcpu_hole;
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+#define POSSIBLE_VMALLOC_START PAGE_OFFSET
+
+#define VMALLOC_BITMAP_SIZE ((VMALLOC_END - PAGE_OFFSET) >> \
+ PAGE_SHIFT)
+#define VMALLOC_TO_BIT(addr) ((addr - PAGE_OFFSET) >> PAGE_SHIFT)
+#define BIT_TO_VMALLOC(i) (PAGE_OFFSET + i * PAGE_SIZE)
+
+unsigned long total_vmalloc_size;
+unsigned long vmalloc_reserved;
+
+DECLARE_BITMAP(possible_areas, VMALLOC_BITMAP_SIZE);
+
+void mark_vmalloc_reserved_area(void *x, unsigned long size)
+{
+ unsigned long addr = (unsigned long)x;
+
+ bitmap_set(possible_areas, VMALLOC_TO_BIT(addr), size >> PAGE_SHIFT);
+ vmalloc_reserved += size;
+}
+
+int is_vmalloc_addr(const void *x)
+{
+ unsigned long addr = (unsigned long)x;
+
+ if (addr < POSSIBLE_VMALLOC_START || addr >= VMALLOC_END)
+ return 0;
+
+ if (test_bit(VMALLOC_TO_BIT(addr), possible_areas))
+ return 0;
+
+ return 1;
+}
+
+static void calc_total_vmalloc_size(void)
+{
+ total_vmalloc_size = VMALLOC_END - POSSIBLE_VMALLOC_START -
+ vmalloc_reserved;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+ unsigned long addr = (unsigned long)x;
+
+ return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+
+static void calc_total_vmalloc_size(void) { }
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
static struct vmap_area *__find_vmap_area(unsigned long addr)
{
struct rb_node *n = vmap_area_root.rb_node;
@@ -1178,6 +1229,33 @@
EXPORT_SYMBOL(vm_map_ram);
static struct vm_struct *vmlist __initdata;
+
+/**
+ * vm_area_check_early - check if vmap area is already mapped
+ * @vm: vm_struct to be checked
+ *
+ * This function is used to check if the vmap area has been
+ * mapped already. @vm->addr, @vm->size and @vm->flags should
+ * contain proper values.
+ *
+ */
+int __init vm_area_check_early(struct vm_struct *vm)
+{
+ struct vm_struct *tmp, **p;
+
+ BUG_ON(vmap_initialized);
+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+ if (tmp->addr >= vm->addr) {
+ if (tmp->addr < vm->addr + vm->size)
+ return 1;
+ } else {
+ if (tmp->addr + tmp->size > vm->addr)
+ return 1;
+ }
+ }
+ return 0;
+}
+
/**
* vm_area_add_early - add vmap area early during boot
* @vm: vm_struct to add
@@ -1258,7 +1336,7 @@
}
vmap_area_pcpu_hole = VMALLOC_END;
-
+ calc_total_vmalloc_size();
vmap_initialized = true;
}
@@ -1422,16 +1500,27 @@
*/
struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
{
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ return __get_vm_area_node(size, 1, flags, PAGE_OFFSET, VMALLOC_END,
+ NUMA_NO_NODE, GFP_KERNEL,
+ __builtin_return_address(0));
+#else
return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
NUMA_NO_NODE, GFP_KERNEL,
__builtin_return_address(0));
+#endif
}
struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
const void *caller)
{
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ return __get_vm_area_node(size, 1, flags, PAGE_OFFSET, VMALLOC_END,
+ NUMA_NO_NODE, GFP_KERNEL, caller);
+#else
return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
NUMA_NO_NODE, GFP_KERNEL, caller);
+#endif
}
/**
@@ -2683,6 +2772,9 @@
if (is_vmalloc_addr(v->pages))
seq_puts(m, " vpages");
+ if (v->flags & VM_LOWMEM)
+ seq_puts(m, " lowmem");
+
show_numa_info(m, v);
seq_putc(m, '\n');
return 0;
diff --git a/net/netfilter/xt_HARDIDLETIMER.c b/net/netfilter/xt_HARDIDLETIMER.c
index fc0b83f..c6f70da9 100644
--- a/net/netfilter/xt_HARDIDLETIMER.c
+++ b/net/netfilter/xt_HARDIDLETIMER.c
@@ -72,7 +72,7 @@
{
char iface_msg[NLMSG_MAX_SIZE];
char state_msg[NLMSG_MAX_SIZE];
- static const char * const envp[] = { iface_msg, state_msg, NULL };
+ char *envp[] = { iface_msg, state_msg, NULL };
int res;
res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s",
diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c
index 2a30d55..50d9b51 100644
--- a/net/rmnet_data/rmnet_data_config.c
+++ b/net/rmnet_data/rmnet_data_config.c
@@ -1173,6 +1173,7 @@
{
int i, j;
struct net_device *vndev;
+ struct rmnet_phys_ep_config *config;
struct rmnet_logical_ep_conf_s *cfg;
struct rmnet_free_vnd_work *vnd_work;
@@ -1228,6 +1229,16 @@
kfree(vnd_work);
}
+ config = _rmnet_get_phys_ep_config(dev);
+
+ if (config) {
+ cfg = &config->local_ep;
+
+ if (cfg && cfg->refcount)
+ rmnet_unset_logical_endpoint_config
+ (cfg->egress_dev, RMNET_LOCAL_LOGICAL_ENDPOINT);
+ }
+
/* Clear the mappings on the phys ep */
trace_rmnet_unregister_cb_clear_lepcs(dev);
rmnet_unset_logical_endpoint_config(dev, RMNET_LOCAL_LOGICAL_ENDPOINT);
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index 46fdf5a..35be79e 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -552,12 +552,9 @@
LOGD("headroom of %d bytes", required_headroom);
if (skb_headroom(skb) < required_headroom) {
- if (pskb_expand_head(skb, required_headroom, 0, GFP_KERNEL)) {
- LOGD("Failed to add headroom of %d bytes",
- required_headroom);
- kfree_skb(skb);
- return 1;
- }
+ LOGE("Not enough headroom for %d bytes", required_headroom);
+ kfree_skb(skb);
+ return 1;
}
if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) ||
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 56c458d..8d9330a 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -437,7 +437,7 @@
static struct key *request_master_key(struct encrypted_key_payload *epayload,
const u8 **master_key, size_t *master_keylen)
{
- struct key *mkey = NULL;
+ struct key *mkey = ERR_PTR(-EINVAL);
if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
KEY_TRUSTED_PREFIX_LEN)) {
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f800858..f9a0a47 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -882,7 +882,6 @@
tristate
depends on WCD9XXX_CODEC_CORE
select SND_SOC_WCD9XXX
- select SND_SOC_WCD_MBHC
select SND_SOC_WCD_MBHC_LEGACY
select SND_SOC_WCD_CPE
@@ -900,7 +899,6 @@
config SND_SOC_WCD934X_MBHC
tristate
depends on SND_SOC_WCD934X
- select SND_SOC_WCD_MBHC
select SND_SOC_WCD_MBHC_ADC
config REGMAP_SWR
@@ -933,9 +931,11 @@
config SND_SOC_WCD_MBHC_LEGACY
tristate
+ select SND_SOC_WCD_MBHC
config SND_SOC_WCD_MBHC_ADC
tristate
+ select SND_SOC_WCD_MBHC
config SND_SOC_WCD_DSP_MGR
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d5e4ab2..5cf93b1 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -172,10 +172,12 @@
endif
snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o
snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o
+snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o
ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_LEGACY),y m))
- snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o wcd-mbhc-legacy.o
-else ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m))
- snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o wcd-mbhc-adc.o
+ snd-soc-wcd-mbhc-objs += wcd-mbhc-legacy.o
+endif
+ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m))
+ snd-soc-wcd-mbhc-objs += wcd-mbhc-adc.o
endif
snd-soc-wsa881x-analog-objs := wsa881x-analog.o wsa881x-tables-analog.o
snd-soc-wsa881x-analog-objs += wsa881x-regmap-analog.o wsa881x-irq.o
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 9c365a7..7899a2c 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1108,6 +1108,13 @@
DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
}
},
+ {
+ .ident = "Thinkpad Helix 2nd",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix 2nd")
+ }
+ },
{ }
};
diff --git a/sound/soc/codecs/sdm660_cdc/Kconfig b/sound/soc/codecs/sdm660_cdc/Kconfig
index 2f36c39..e618258 100644
--- a/sound/soc/codecs/sdm660_cdc/Kconfig
+++ b/sound/soc/codecs/sdm660_cdc/Kconfig
@@ -1,5 +1,4 @@
config SND_SOC_SDM660_CDC
tristate "MSM Internal PMIC based codec"
- select SND_SOC_WCD_MBHC
select SND_SOC_WCD_MBHC_LEGACY
diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
index 7892f61..f126d35 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -2055,6 +2055,9 @@
"ZERO", "RX2", "RX1"
};
+static const struct snd_kcontrol_new adc1_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
static const struct soc_enum rdac2_mux_enum =
SOC_ENUM_SINGLE(MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL,
0, 3, rdac2_mux_text);
@@ -3105,7 +3108,8 @@
{"ADC2 MUX", "INP2", "ADC2_INP2"},
{"ADC2 MUX", "INP3", "ADC2_INP3"},
- {"ADC1", NULL, "AMIC1"},
+ {"ADC1", NULL, "ADC1_INP1"},
+ {"ADC1_INP1", "Switch", "AMIC1"},
{"ADC2_INP2", NULL, "AMIC2"},
{"ADC2_INP3", NULL, "AMIC3"},
@@ -3446,6 +3450,8 @@
SND_SOC_DAPM_SPK("Ext Spk", msm_anlg_cdc_codec_enable_spk_ext_pa),
+ SND_SOC_DAPM_SWITCH("ADC1_INP1", SND_SOC_NOPM, 0, 0,
+ &adc1_switch),
SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL,
0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL,
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index 3b2426d..d9bdf05 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -1108,7 +1108,7 @@
* For ADC MBHC, ADC_COMPLETE interrupt will be generated
* in this case. So skip the check here.
*/
- if (!WCD_MBHC_DETECTION &&
+ if (mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY &&
mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) {
wcd_mbhc_find_plug_and_report(mbhc, MBHC_PLUG_TYPE_HEADSET);
goto exit;
@@ -1922,7 +1922,7 @@
init_waitqueue_head(&mbhc->wait_btn_press);
mutex_init(&mbhc->codec_resource_lock);
- switch (WCD_MBHC_DETECTION) {
+ switch (mbhc->mbhc_detection_logic) {
case WCD_DETECTION_LEGACY:
wcd_mbhc_legacy_init(mbhc);
break;
@@ -1931,7 +1931,7 @@
break;
default:
pr_err("%s: Unknown detection logic type %d\n",
- __func__, WCD_MBHC_DETECTION);
+ __func__, mbhc->mbhc_detection_logic);
break;
}
diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h
index 7ed06c3..a7655d2 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.h
+++ b/sound/soc/codecs/wcd-mbhc-v2.h
@@ -157,12 +157,6 @@
WCD_DETECTION_ADC,
};
-#ifdef CONFIG_SND_SOC_WCD_MBHC_ADC
-#define WCD_MBHC_DETECTION WCD_DETECTION_ADC
-#else
-#define WCD_MBHC_DETECTION WCD_DETECTION_LEGACY
-#endif
-
enum wcd_mbhc_cs_mb_en_flag {
WCD_MBHC_EN_CS = 0,
WCD_MBHC_EN_MB,
@@ -565,6 +559,9 @@
struct mutex hphl_pa_lock;
struct mutex hphr_pa_lock;
+ /* Holds mbhc detection method - ADC/Legacy */
+ unsigned int mbhc_detection_logic;
+
unsigned long intr_status;
bool is_hph_ocp_pending;
diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
index a1a5e2d..76316af 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
+++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
@@ -998,19 +998,26 @@
struct snd_soc_codec *codec)
{
int ret;
+ struct wcd_mbhc *wcd_mbhc;
if (!mbhc || !codec)
return -EINVAL;
- wcd_mbhc_deinit(&mbhc->wcd_mbhc);
- ret = wcd_mbhc_init(&mbhc->wcd_mbhc, codec, &mbhc_cb, &intr_ids,
+ wcd_mbhc = &mbhc->wcd_mbhc;
+ if (wcd_mbhc == NULL) {
+ pr_err("%s: wcd_mbhc is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ wcd_mbhc_deinit(wcd_mbhc);
+ ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED);
if (ret) {
dev_err(codec->dev, "%s: mbhc initialization failed\n",
__func__);
goto done;
}
- if (!WCD_MBHC_DETECTION) {
+ if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) {
snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04);
snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01);
}
@@ -1033,6 +1040,7 @@
{
struct regulator *supply;
struct wcd934x_mbhc *wcd934x_mbhc;
+ struct wcd_mbhc *wcd_mbhc;
int ret;
wcd934x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd934x_mbhc),
@@ -1043,8 +1051,18 @@
wcd934x_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent);
wcd934x_mbhc->fw_data = fw_data;
BLOCKING_INIT_NOTIFIER_HEAD(&wcd934x_mbhc->notifier);
+ wcd_mbhc = &wcd934x_mbhc->wcd_mbhc;
+ if (wcd_mbhc == NULL) {
+ pr_err("%s: wcd_mbhc is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
- ret = wcd_mbhc_init(&wcd934x_mbhc->wcd_mbhc, codec, &mbhc_cb,
+
+ /* Setting default mbhc detection logic to ADC for Tavil */
+ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC;
+
+ ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb,
&intr_ids, wcd_mbhc_registers,
TAVIL_ZDET_SUPPORTED);
if (ret) {
@@ -1070,7 +1088,7 @@
snd_soc_add_codec_controls(codec, hph_type_detect_controls,
ARRAY_SIZE(hph_type_detect_controls));
- if (!WCD_MBHC_DETECTION) {
+ if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) {
snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04);
snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01);
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
index 325d642..75a2bff 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
@@ -30,9 +30,12 @@
#include <sound/control.h>
#include <sound/q6audio-v2.h>
#include <sound/timer.h>
+#include <sound/hwdep.h>
+
#include <asm/dma.h>
#include <sound/tlv.h>
#include <sound/pcm_params.h>
+#include <sound/devdep_params.h>
#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
@@ -421,6 +424,42 @@
return ret;
}
+
+static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream,
+ struct snd_pcm_mmap_fd *mmap_fd)
+{
+ struct msm_audio *prtd;
+ struct audio_port_data *apd;
+ struct audio_buffer *ab;
+ int dir = -1;
+
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ return -EFAULT;
+ }
+
+ prtd = substream->runtime->private_data;
+ if (!prtd || !prtd->audio_client || !prtd->mmap_flag) {
+ pr_err("%s no audio client or not an mmap session\n", __func__);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+
+ apd = prtd->audio_client->port;
+ ab = &(apd[dir].buf[0]);
+ mmap_fd->fd = ion_share_dma_buf_fd(ab->client, ab->handle);
+ if (mmap_fd->fd >= 0) {
+ mmap_fd->dir = dir;
+ mmap_fd->actual_size = ab->actual_size;
+ mmap_fd->size = ab->size;
+ }
+ return mmap_fd->fd < 0 ? -EFAULT : 0;
+}
+
static int msm_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
@@ -445,6 +484,15 @@
return snd_pcm_lib_ioctl(substream, cmd, arg);
}
+#ifdef CONFIG_COMPAT
+static int msm_pcm_compat_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ /* we only handle RESET which is common for both modes */
+ return msm_pcm_ioctl(substream, cmd, arg);
+}
+#endif
+
static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -994,6 +1042,101 @@
return 0;
}
+static int msm_pcm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ struct snd_pcm *pcm = hw->private_data;
+ struct snd_pcm_mmap_fd __user *_mmap_fd = NULL;
+ struct snd_pcm_mmap_fd mmap_fd;
+ struct snd_pcm_substream *substream = NULL;
+ int32_t dir = -1;
+
+ switch (cmd) {
+ case SNDRV_PCM_IOCTL_MMAP_DATA_FD:
+ _mmap_fd = (struct snd_pcm_mmap_fd __user *)arg;
+ if (get_user(dir, (int32_t __user *)&(_mmap_fd->dir))) {
+ pr_err("%s: error copying mmap_fd from user\n",
+ __func__);
+ ret = -EFAULT;
+ break;
+ }
+ if (dir != OUT && dir != IN) {
+ pr_err("%s invalid stream dir\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
+ substream = pcm->streams[dir].substream;
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ ret = -ENODEV;
+ break;
+ }
+ pr_debug("%s : %s MMAP Data fd\n", __func__,
+ dir == 0 ? "P" : "C");
+ if (msm_pcm_mmap_fd(substream, &mmap_fd) < 0) {
+ pr_err("%s: error getting fd\n",
+ __func__);
+ ret = -EFAULT;
+ break;
+ }
+ if (put_user(mmap_fd.fd, &_mmap_fd->fd) ||
+ put_user(mmap_fd.size, &_mmap_fd->size) ||
+ put_user(mmap_fd.actual_size, &_mmap_fd->actual_size)) {
+ pr_err("%s: error copying fd\n", __func__);
+ return -EFAULT;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static int msm_pcm_hwdep_compat_ioctl(struct snd_hwdep *hw,
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ /* we only support mmap fd. Handling is common in both modes */
+ return msm_pcm_hwdep_ioctl(hw, file, cmd, arg);
+}
+#else
+static int msm_pcm_hwdep_compat_ioctl(struct snd_hwdep *hw,
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ return -EINVAL;
+}
+#endif
+
+static int msm_pcm_add_hwdep_dev(struct snd_soc_pcm_runtime *runtime)
+{
+ struct snd_hwdep *hwdep;
+ int rc;
+ char id[] = "NOIRQ_NN";
+
+ snprintf(id, sizeof(id), "NOIRQ_%d", runtime->pcm->device);
+ pr_debug("%s: pcm dev %d\n", __func__, runtime->pcm->device);
+ rc = snd_hwdep_new(runtime->card->snd_card,
+ &id[0],
+ HWDEP_FE_BASE + runtime->pcm->device,
+ &hwdep);
+ if (!hwdep || rc < 0) {
+ pr_err("%s: hwdep intf failed to create %s - hwdep\n", __func__,
+ id);
+ return rc;
+ }
+
+ hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE; /* for lack of a FE iface */
+ hwdep->private_data = runtime->pcm; /* of type struct snd_pcm */
+ hwdep->ops.ioctl = msm_pcm_hwdep_ioctl;
+ hwdep->ops.ioctl_compat = msm_pcm_hwdep_compat_ioctl;
+ return 0;
+}
static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
@@ -1027,7 +1170,9 @@
pr_err("%s: Could not add app type controls failed %d\n",
__func__, ret);
}
-
+ ret = msm_pcm_add_hwdep_dev(rtd);
+ if (ret)
+ pr_err("%s: Could not add hw dep node\n", __func__);
pcm->nonatomic = true;
exit:
return ret;
@@ -1040,6 +1185,9 @@
.copy = msm_pcm_copy,
.hw_params = msm_pcm_hw_params,
.ioctl = msm_pcm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = msm_pcm_compat_ioctl,
+#endif
.trigger = msm_pcm_trigger,
.pointer = msm_pcm_pointer,
.mmap = msm_pcm_mmap,
diff --git a/sound/soc/msm/sdm845.c b/sound/soc/msm/sdm845.c
index 9248766..3be194c 100644
--- a/sound/soc/msm/sdm845.c
+++ b/sound/soc/msm/sdm845.c
@@ -495,6 +495,8 @@
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
static struct platform_device *spdev;
@@ -2252,7 +2254,7 @@
return sample_rate;
}
-static int mi2s_get_format(int value)
+static int mi2s_auxpcm_get_format(int value)
{
int format;
@@ -2276,7 +2278,7 @@
return format;
}
-static int mi2s_get_format_value(int format)
+static int mi2s_auxpcm_get_format_value(int format)
{
int value;
@@ -2441,7 +2443,7 @@
return idx;
ucontrol->value.enumerated.item[0] =
- mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format);
+ mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format);
pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
idx, mi2s_rx_cfg[idx].bit_format,
@@ -2459,7 +2461,7 @@
return idx;
mi2s_rx_cfg[idx].bit_format =
- mi2s_get_format(ucontrol->value.enumerated.item[0]);
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
idx, mi2s_rx_cfg[idx].bit_format,
@@ -2477,7 +2479,7 @@
return idx;
ucontrol->value.enumerated.item[0] =
- mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format);
+ mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format);
pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
idx, mi2s_tx_cfg[idx].bit_format,
@@ -2495,7 +2497,7 @@
return idx;
mi2s_tx_cfg[idx].bit_format =
- mi2s_get_format(ucontrol->value.enumerated.item[0]);
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
idx, mi2s_tx_cfg[idx].bit_format,
@@ -2504,6 +2506,78 @@
return 0;
}
+static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_rx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_tx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
static int msm_hifi_ctrl(struct snd_soc_codec *codec)
{
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -2765,6 +2839,22 @@
msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format,
msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
msm_hifi_put),
};
@@ -3166,6 +3256,8 @@
break;
case MSM_BACKEND_DAI_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3173,6 +3265,8 @@
break;
case MSM_BACKEND_DAI_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3180,6 +3274,8 @@
break;
case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3187,6 +3283,8 @@
break;
case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3194,6 +3292,8 @@
break;
case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3201,6 +3301,8 @@
break;
case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3208,6 +3310,8 @@
break;
case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
channels->min = channels->max =
@@ -3215,6 +3319,8 @@
break;
case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format);
rate->min = rate->max =
aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
channels->min = channels->max =