Merge "clk: qcom: Fix clock GPUCC PLL1 crash when call regulator_set_voltage"
diff --git a/Documentation/devicetree/bindings/drm/msm/sde-dp.txt b/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
index 790da12..c811c28 100644
--- a/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
+++ b/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
@@ -25,7 +25,46 @@
- qcom,aux-en-gpio: Specifies the aux-channel enable gpio.
- qcom,aux-sel-gpio: Specifies the aux-channel select gpio.
- qcom,usbplug-cc-gpio: Specifies the usbplug orientation gpio.
-- qcom,aux-cfg-settings: An array that specifies the DP AUX configuration settings.
+- qcom,aux-cfg0-settings: Specifies the DP AUX configuration 0 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg1-settings: Specifies the DP AUX configuration 1 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg2-settings: Specifies the DP AUX configuration 2 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg3-settings: Specifies the DP AUX configuration 3 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg4-settings: Specifies the DP AUX configuration 4 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg5-settings: Specifies the DP AUX configuration 5 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg6-settings: Specifies the DP AUX configuration 6 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg7-settings: Specifies the DP AUX configuration 7 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg8-settings: Specifies the DP AUX configuration 8 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
+- qcom,aux-cfg9-settings: Specifies the DP AUX configuration 9 settings. The first
+ entry in this array corresponds to the register offset
+ within DP AUX, while the remaining entries indicate the
+ programmable values.
- qcom,max-pclk-frequency-khz: An integer specifying the max. pixel clock in KHz supported by Display Port.
- qcom,dp-usbpd-detection: Phandle for the PMI regulator node for USB PHY PD detection.
- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the a particular "type" of DSI module. The module "types"
@@ -93,7 +132,16 @@
qcom,dp-usbpd-detection = <&pmi8998_pdphy>;
- qcom,aux-cfg-settings = [00 13 04 00 0a 26 0a 03 bb 03];
+ qcom,aux-cfg0-settings = [1c 00];
+ qcom,aux-cfg1-settings = [20 13 23 1d];
+ qcom,aux-cfg2-settings = [24 00];
+ qcom,aux-cfg3-settings = [28 00];
+ qcom,aux-cfg4-settings = [2c 0a];
+ qcom,aux-cfg5-settings = [30 26];
+ qcom,aux-cfg6-settings = [34 0a];
+ qcom,aux-cfg7-settings = [38 03];
+ qcom,aux-cfg8-settings = [3c bb];
+ qcom,aux-cfg9-settings = [40 03];
qcom,max-pclk-frequency-khz = <593470>;
pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
pinctrl-0 = <&sde_dp_aux_active &sde_dp_usbplug_cc_active>;
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 196f6f7..0f8dc27 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -96,6 +96,12 @@
retention. No cache invalidation operations involving asid
may be used.
+- qcom,deferred-regulator-disable-delay : The time delay for deferred regulator
+ disable in ms. In case of unmap call, regulator is
+ enabled/disabled. This may introduce additional delay. For
+ clients who do not detach, it's not possible to keep regulator
+ vote while smmu is attached. Type is <u32>.
+
- 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/leds/leds-qpnp-wled.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
index 1e6aac5..42e97f7 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt
@@ -78,6 +78,8 @@
- qcom,lcd-psm-ctrl : A boolean property to specify if PSM needs to be
controlled dynamically when WLED module is enabled
or disabled.
+- qcom,auto-calibration-enable : A boolean property which enables auto-calibration
+ of the WLED sink configuration.
Optional properties if 'qcom,disp-type-amoled' is mentioned in DT:
- qcom,loop-comp-res-kohm : control to select the compensation resistor in kohm. default is 320.
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 0123682..d0d878b 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -385,6 +385,11 @@
property "qcom,slope-limit-temp-threshold" to make dynamic
slope limit adjustment functional.
+- qcom,fg-bmd-en-delay-ms
+ Usage: optional
+ Value type: <u32>
+ Definition: The delay in ms for FG to enable BMD after reading RID.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
index 6df71af..05fa6e4 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt
@@ -178,6 +178,10 @@
Definition: WD bark-timeout in seconds. The possible values are
16, 32, 64, 128. If not defined it defaults to 64.
+- qcom,sw-jeita-enable
+ Usage: optional
+ Value type: bool
+ Definition: Boolean flag which when present enables sw compensation for jeita
=============================================
Second Level Nodes - SMB2 Charger Peripherals
diff --git a/Documentation/devicetree/bindings/sound/wcd_codec.txt b/Documentation/devicetree/bindings/sound/wcd_codec.txt
index 0df9417..c848ab5 100644
--- a/Documentation/devicetree/bindings/sound/wcd_codec.txt
+++ b/Documentation/devicetree/bindings/sound/wcd_codec.txt
@@ -12,7 +12,6 @@
- qcom,wcd-rst-gpio-node: Phandle reference to the DT node having codec reset gpio
configuration. If this property is not defined, it is
expected to atleast define "qcom,cdc-reset-gpio" property.
-
- cdc-vdd-buck-supply: phandle of buck supply's regulator device tree node.
- qcom,cdc-vdd-buck-voltage: buck supply's voltage level min and max in mV.
- qcom,cdc-vdd-buck-current: buck supply's max current in mA.
@@ -142,6 +141,11 @@
- clock-names : clock name defined for external clock.
- clocks : external clock defined for codec clock.
+ - qcom,has-buck-vsel-gpio: Boolean property to select if WCD_BUCK has VSEL
+ controlled by GPIO.
+ - qcom,buck-vsel-gpio-node: Phandle reference to the DT node having wcd buck
+ VSEL gpio configuration.
+
Example:
taiko_codec {
diff --git a/Documentation/devicetree/bindings/thermal/qcom-lmh-dcvs.txt b/Documentation/devicetree/bindings/thermal/qcom-lmh-dcvs.txt
index 8bead0d..be50d45 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-lmh-dcvs.txt
+++ b/Documentation/devicetree/bindings/thermal/qcom-lmh-dcvs.txt
@@ -31,12 +31,29 @@
Definition: Should specify the cluster affinity this hardware
corresponds to.
+- isens_vref-supply:
+ Usage: optional
+ Value type: <phandle>
+ Definition: Should specify the phandle of the vref regulator used by
+ the isens hardware. This active only regulator will be
+ enabled by LMH DCVSh.
+
+- isens-vref-settings:
+ Usage: optional
+ Value type: <u32 array>
+ Definition: Should specify the min voltage(uV), max voltage(uV) and
+ max load(uA) for the isens vref regulator. This
+ property is valid only if there is valid entry for
+ isens_vref-supply.
+
Example:
lmh_dcvs0: qcom,limits-dcvs@0 {
compatible = "qcom,msm-hw-limits";
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
qcom,affinity = <0>;
+ isens_vref-supply = <&pm8998_l1_ao>;
+ isens-vref-settings = <880000 880000 36000>;
};
CPU0: cpu@0 {
diff --git a/arch/Kconfig b/arch/Kconfig
index 659bdd0..babac73 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -218,6 +218,12 @@
config GENERIC_IDLE_POLL_SETUP
bool
+config ARCH_HAS_FORTIFY_SOURCE
+ bool
+ help
+ An architecture should select this when it can successfully
+ build and run with CONFIG_FORTIFY_SOURCE.
+
# Select if arch init_task initializer is different to init/init_task.c
config ARCH_INIT_TASK
bool
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index ee4a723..8e349ce 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -178,6 +178,8 @@
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
+extern void __dma_map_area(const void *addr, size_t size, int dir);
+extern void __dma_unmap_area(const void *addr, size_t size, int dir);
extern void dmac_inv_range(const void *, const void *);
extern void dmac_clean_range(const void *, const void *);
extern void dmac_flush_range(const void *, const void *);
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index b4e74af..74643f5 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -8,6 +8,7 @@
#include <linux/dma-debug.h>
#include <linux/kmemcheck.h>
#include <linux/kref.h>
+#include <linux/dma-mapping-fast.h>
struct dma_iommu_mapping {
/* iommu specific data */
@@ -22,6 +23,8 @@
spinlock_t lock;
struct kref kref;
+
+ struct dma_fast_smmu_mapping *fast;
};
#ifdef CONFIG_ARM_DMA_USE_IOMMU
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index d14f310..f7c75dc 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -157,6 +157,11 @@
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
#define dmac_inv_range __glue(_CACHE, _dma_inv_range)
#define dmac_clean_range __glue(_CACHE, _dma_clean_range)
+#define dmac_map_area __glue(_CACHE, _dma_map_area)
+#define dmac_unmap_area __glue(_CACHE, _dma_unmap_area)
+
+#define __dma_map_area dmac_map_area
+#define __dma_unmap_area dmac_unmap_area
#endif
#endif
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 441063f..cb2c9f4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -29,6 +29,7 @@
#include <linux/sizes.h>
#include <linux/cma.h>
#include <linux/msm_dma_iommu_mapping.h>
+#include <linux/dma-mapping-fast.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -50,6 +51,8 @@
pgprot_t prot;
const void *caller;
bool want_vaddr;
+ bool skip_cpu_sync;
+ bool skip_zeroing;
int coherent_flag;
};
@@ -113,6 +116,21 @@
static void __dma_page_dev_to_cpu(struct page *, unsigned long,
size_t, enum dma_data_direction);
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller);
+
+static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn);
+
+static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot);
+
+static void *arm_dma_remap(struct device *dev, void *cpu_addr,
+ dma_addr_t handle, size_t size,
+ unsigned long attrs);
+
+static void arm_dma_unremap(struct device *dev, void *remapped_addr,
+ size_t size);
+
/**
* arm_dma_map_page - map a portion of a page for streaming DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -194,6 +212,8 @@
.sync_single_for_device = arm_dma_sync_single_for_device,
.sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
.sync_sg_for_device = arm_dma_sync_sg_for_device,
+ .remap = arm_dma_remap,
+ .unremap = arm_dma_unremap,
};
EXPORT_SYMBOL(arm_dma_ops);
@@ -276,7 +296,8 @@
return mask;
}
-static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag)
+static void __dma_clear_buffer(struct page *page, size_t size,
+ bool skip_zeroing, int coherent_flag)
{
/*
* Ensure that the allocated pages are zeroed, and that any data
@@ -287,7 +308,8 @@
phys_addr_t end = base + size;
while (size > 0) {
void *ptr = kmap_atomic(page);
- memset(ptr, 0, PAGE_SIZE);
+ if (!skip_zeroing)
+ memset(ptr, 0, PAGE_SIZE);
if (coherent_flag != COHERENT)
dmac_flush_range(ptr, ptr + PAGE_SIZE);
kunmap_atomic(ptr);
@@ -298,7 +320,8 @@
outer_flush_range(base, end);
} else {
void *ptr = page_address(page);
- memset(ptr, 0, size);
+ if (!skip_zeroing)
+ memset(ptr, 0, size);
if (coherent_flag != COHERENT) {
dmac_flush_range(ptr, ptr + size);
outer_flush_range(__pa(ptr), __pa(ptr) + size);
@@ -327,7 +350,7 @@
for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
__free_page(p);
- __dma_clear_buffer(page, size, coherent_flag);
+ __dma_clear_buffer(page, size, false, coherent_flag);
return page;
}
@@ -350,6 +373,7 @@
static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page,
const void *caller, bool want_vaddr,
+ bool skip_cpu_sync, bool skip_zeroing,
int coherent_flag);
static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
@@ -369,10 +393,10 @@
prot, caller);
}
-static void __dma_free_remap(void *cpu_addr, size_t size)
+static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn)
{
dma_common_free_remap(cpu_addr, size,
- VM_ARM_DMA_CONSISTENT | VM_USERMAP, false);
+ VM_ARM_DMA_CONSISTENT | VM_USERMAP, no_warn);
}
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
@@ -421,7 +445,8 @@
*/
if (dev_get_cma_area(NULL))
ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
- &page, atomic_pool_init, true, NORMAL);
+ &page, atomic_pool_init, true, false,
+ false, NORMAL);
else
ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
&page, atomic_pool_init, true);
@@ -520,21 +545,39 @@
return 0;
}
-static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
+static int __dma_clear_pte(pte_t *pte, pgtable_t token, unsigned long addr,
+ void *data)
+{
+ pte_clear(&init_mm, addr, pte);
+ return 0;
+}
+
+static void __dma_remap(struct page *page, size_t size, pgprot_t prot,
+ bool want_vaddr)
{
unsigned long start = (unsigned long) page_address(page);
unsigned end = start + size;
+ int (*func)(pte_t *pte, pgtable_t token, unsigned long addr,
+ void *data);
- apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot);
+ if (!want_vaddr)
+ func = __dma_clear_pte;
+ else
+ func = __dma_update_pte;
+
+ apply_to_page_range(&init_mm, start, size, func, &prot);
+ mb(); /*Ensure pte's are updated */
flush_tlb_kernel_range(start, end);
}
+
+#define NO_KERNEL_MAPPING_DUMMY 0x2222
static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
pgprot_t prot, struct page **ret_page,
const void *caller, bool want_vaddr)
{
struct page *page;
- void *ptr = NULL;
+ void *ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
/*
* __alloc_remap_buffer is only called when the device is
* non-coherent
@@ -595,6 +638,7 @@
static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page,
const void *caller, bool want_vaddr,
+ bool skip_cpu_sync, bool skip_zeroing,
int coherent_flag)
{
unsigned long order = get_order(size);
@@ -606,23 +650,37 @@
if (!page)
return NULL;
- __dma_clear_buffer(page, size, coherent_flag);
-
- if (!want_vaddr)
- goto out;
+ /*
+ * skip completely if we neither need to zero nor sync.
+ */
+ if (!(skip_cpu_sync && skip_zeroing))
+ __dma_clear_buffer(page, size, skip_zeroing, coherent_flag);
if (PageHighMem(page)) {
- ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller);
- if (!ptr) {
- dma_release_from_contiguous(dev, page, count);
- return NULL;
+ if (!want_vaddr) {
+ /*
+ * Something non-NULL needs to be returned here. Give
+ * back a dummy address that is unmapped to catch
+ * clients trying to use the address incorrectly
+ */
+ ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
+
+ /* also flush out the stale highmem mappings */
+ kmap_flush_unused();
+ kmap_atomic_flush_unused();
+ } else {
+ ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot,
+ caller);
+ if (!ptr) {
+ dma_release_from_contiguous(dev, page, count);
+ return NULL;
+ }
}
} else {
- __dma_remap(page, size, prot);
+ __dma_remap(page, size, prot, want_vaddr);
ptr = page_address(page);
}
- out:
*ret_page = page;
return ptr;
}
@@ -630,12 +688,10 @@
static void __free_from_contiguous(struct device *dev, struct page *page,
void *cpu_addr, size_t size, bool want_vaddr)
{
- if (want_vaddr) {
- if (PageHighMem(page))
- __dma_free_remap(cpu_addr, size);
- else
- __dma_remap(page, size, PAGE_KERNEL);
- }
+ if (PageHighMem(page))
+ __dma_free_remap(cpu_addr, size, true);
+ else
+ __dma_remap(page, size, PAGE_KERNEL, true);
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
}
@@ -656,10 +712,11 @@
#define __get_dma_pgprot(attrs, prot) __pgprot(0)
#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL
#define __alloc_from_pool(size, ret_page) NULL
-#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag) NULL
+#define __alloc_from_contiguous(dev, size, prot, ret, c, \
+ wv, scs, sz, coherent_flag) NULL
#define __free_from_pool(cpu_addr, size) do { } while (0)
#define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0)
-#define __dma_free_remap(cpu_addr, size) do { } while (0)
+#define __dma_free_remap(cpu_addr, size, w) do { } while (0)
#endif /* CONFIG_MMU */
@@ -698,7 +755,8 @@
{
return __alloc_from_contiguous(args->dev, args->size, args->prot,
ret_page, args->caller,
- args->want_vaddr, args->coherent_flag);
+ args->want_vaddr, args->skip_cpu_sync,
+ args->skip_zeroing, args->coherent_flag);
}
static void cma_allocator_free(struct arm_dma_free_args *args)
@@ -739,7 +797,7 @@
static void remap_allocator_free(struct arm_dma_free_args *args)
{
if (args->want_vaddr)
- __dma_free_remap(args->cpu_addr, args->size);
+ __dma_free_remap(args->cpu_addr, args->size, false);
__dma_free_buffer(args->page, args->size);
}
@@ -765,6 +823,8 @@
.prot = prot,
.caller = caller,
.want_vaddr = ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0),
+ .skip_cpu_sync = (attrs & DMA_ATTR_SKIP_CPU_SYNC),
+ .skip_zeroing = (attrs & DMA_ATTR_SKIP_ZEROING),
.coherent_flag = is_coherent ? COHERENT : NORMAL,
};
@@ -826,7 +886,7 @@
kfree(buf);
}
- return args.want_vaddr ? addr : page;
+ return addr;
}
/*
@@ -874,6 +934,38 @@
return ret;
}
+static void *arm_dma_remap(struct device *dev, void *cpu_addr,
+ dma_addr_t handle, size_t size,
+ unsigned long attrs)
+{
+ void *ptr;
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
+ unsigned long offset = handle & ~PAGE_MASK;
+
+ size = PAGE_ALIGN(size + offset);
+ ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot,
+ __builtin_return_address(0));
+ return ptr ? ptr + offset : ptr;
+}
+
+static void arm_dma_unremap(struct device *dev, void *remapped_addr,
+ size_t size)
+{
+ unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
+ struct vm_struct *area;
+
+ remapped_addr = (void *)((unsigned long)remapped_addr & PAGE_MASK);
+
+ area = find_vm_area(remapped_addr);
+ if (!area || (area->flags & flags) != flags) {
+ WARN(1, "trying to free invalid coherent area: %p\n",
+ remapped_addr);
+ return;
+ }
+
+ vunmap(remapped_addr);
+}
/*
* Create userspace mapping for the DMA-coherent memory.
*/
@@ -1298,7 +1390,7 @@
if (!page)
goto error;
- __dma_clear_buffer(page, size, coherent_flag);
+ __dma_clear_buffer(page, size, false, coherent_flag);
for (i = 0; i < count; i++)
pages[i] = page + i;
@@ -1348,7 +1440,8 @@
pages[i + j] = pages[i] + j;
}
- __dma_clear_buffer(pages[i], PAGE_SIZE << order, coherent_flag);
+ __dma_clear_buffer(pages[i], PAGE_SIZE << order,
+ false, coherent_flag);
i += 1 << order;
count -= 1 << order;
}
@@ -2287,12 +2380,21 @@
struct dma_iommu_mapping *mapping)
{
int err;
+ int s1_bypass = 0;
+ int is_fast = 0;
+
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
+ if (is_fast)
+ return fast_smmu_attach_device(dev, mapping);
err = __arm_iommu_attach_device(dev, mapping);
if (err)
return err;
- set_dma_ops(dev, &iommu_ops);
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
+ &s1_bypass);
+ if (!s1_bypass)
+ set_dma_ops(dev, &iommu_ops);
return 0;
}
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
@@ -2300,6 +2402,7 @@
static void __arm_iommu_detach_device(struct device *dev)
{
struct dma_iommu_mapping *mapping;
+ int is_fast;
mapping = to_dma_iommu_mapping(dev);
if (!mapping) {
@@ -2309,6 +2412,9 @@
if (msm_dma_unmap_all_for_dev(dev))
dev_warn(dev, "IOMMU detach with outstanding mappings\n");
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
+ if (is_fast)
+ return fast_smmu_detach_device(dev, mapping);
iommu_detach_device(mapping->domain, dev);
kref_put(&mapping->kref, release_iommu_mapping);
@@ -2326,8 +2432,21 @@
*/
void arm_iommu_detach_device(struct device *dev)
{
+ struct dma_iommu_mapping *mapping;
+ int s1_bypass = 0;
+
+ mapping = to_dma_iommu_mapping(dev);
+ if (!mapping) {
+ dev_warn(dev, "Not attached\n");
+ return;
+ }
+
__arm_iommu_detach_device(dev);
- set_dma_ops(dev, NULL);
+
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
+ &s1_bypass);
+ if (!s1_bypass)
+ set_dma_ops(dev, NULL);
}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
diff --git a/arch/arm/mm/dma.h b/arch/arm/mm/dma.h
index 70ea6852..29c54f7 100644
--- a/arch/arm/mm/dma.h
+++ b/arch/arm/mm/dma.h
@@ -4,9 +4,6 @@
#include <asm/glue-cache.h>
#ifndef MULTI_CACHE
-#define dmac_map_area __glue(_CACHE,_dma_map_area)
-#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
-
/*
* These are private to the dma-mapping API. Do not use directly.
* Their sole purpose is to ensure that data held in the cache
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 842c38a..b5f9be7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -9,6 +9,7 @@
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ELF_RANDOMIZE
+ select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 20288fe..ee7f735 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -12,7 +12,9 @@
sdm845-v2-qrd-overlay.dtbo \
sdm845-4k-panel-mtp-overlay.dtbo \
sdm845-4k-panel-cdp-overlay.dtbo \
- sdm845-4k-panel-qrd-overlay.dtbo
+ sdm845-4k-panel-qrd-overlay.dtbo \
+ sdm845-interposer-sdm670-cdp-overlay.dtbo \
+ sdm845-interposer-sdm670-mtp-overlay.dtbo
sdm845-cdp-overlay.dtbo-base := sdm845.dtb
sdm845-mtp-overlay.dtbo-base := sdm845.dtb
@@ -23,6 +25,8 @@
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
+sdm845-interposer-sdm670-cdp-overlay.dtbo-base := sdm845-interposer-sdm670.dtb
+sdm845-interposer-sdm670-mtp-overlay.dtbo-base := sdm845-interposer-sdm670.dtb
else
dtb-$(CONFIG_ARCH_SDM845) += sdm845-sim.dtb \
sdm845-rumi.dtb \
@@ -35,7 +39,9 @@
sdm845-v2-qrd.dtb \
sdm845-4k-panel-mtp.dtb \
sdm845-4k-panel-cdp.dtb \
- sdm845-4k-panel-qrd.dtb
+ sdm845-4k-panel-qrd.dtb \
+ sdm845-interposer-sdm670-mtp.dtb \
+ sdm845-interposer-sdm670-cdp.dtb
endif
dtb-$(CONFIG_ARCH_SDM670) += sdm670-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 bffcdf5..0ca1175 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
@@ -15,22 +15,8 @@
qcom,mdss-dsi-panel-name =
"nt35597 cmd mode dsi truly panel with DSC";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1440>;
- qcom,mdss-dsi-panel-height = <2560>;
- qcom,mdss-dsi-h-front-porch = <100>;
- qcom,mdss-dsi-h-back-porch = <32>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <8>;
- qcom,mdss-dsi-v-front-porch = <10>;
- qcom,mdss-dsi-v-pulse-width = <2>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-pan-physical-width-dimension = <74>;
qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-bpp = <24>;
@@ -42,172 +28,6 @@
17000 15500 30000 8000 3000>;
qcom,mdss-dsi-panel-peak-brightness = <4200000>;
qcom,mdss-dsi-panel-blackness-level = <3230>;
- qcom,mdss-dsi-panel-jitter = <0x1 0x1>;
- qcom,mdss-dsi-on-command = [
- /* CMD2_P0 */
- 15 01 00 00 00 00 02 ff 20
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 01
- 15 01 00 00 00 00 02 01 55
- 15 01 00 00 00 00 02 02 45
- 15 01 00 00 00 00 02 05 40
- 15 01 00 00 00 00 02 06 19
- 15 01 00 00 00 00 02 07 1e
- 15 01 00 00 00 00 02 0b 73
- 15 01 00 00 00 00 02 0c 73
- 15 01 00 00 00 00 02 0e b0
- 15 01 00 00 00 00 02 0f ae
- 15 01 00 00 00 00 02 11 b8
- 15 01 00 00 00 00 02 13 00
- 15 01 00 00 00 00 02 58 80
- 15 01 00 00 00 00 02 59 01
- 15 01 00 00 00 00 02 5a 00
- 15 01 00 00 00 00 02 5b 01
- 15 01 00 00 00 00 02 5c 80
- 15 01 00 00 00 00 02 5d 81
- 15 01 00 00 00 00 02 5e 00
- 15 01 00 00 00 00 02 5f 01
- 15 01 00 00 00 00 02 72 31
- 15 01 00 00 00 00 02 68 03
- /* CMD2_P4 */
- 15 01 00 00 00 00 02 ff 24
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 1c
- 15 01 00 00 00 00 02 01 0b
- 15 01 00 00 00 00 02 02 0c
- 15 01 00 00 00 00 02 03 01
- 15 01 00 00 00 00 02 04 0f
- 15 01 00 00 00 00 02 05 10
- 15 01 00 00 00 00 02 06 10
- 15 01 00 00 00 00 02 07 10
- 15 01 00 00 00 00 02 08 89
- 15 01 00 00 00 00 02 09 8a
- 15 01 00 00 00 00 02 0a 13
- 15 01 00 00 00 00 02 0b 13
- 15 01 00 00 00 00 02 0c 15
- 15 01 00 00 00 00 02 0d 15
- 15 01 00 00 00 00 02 0e 17
- 15 01 00 00 00 00 02 0f 17
- 15 01 00 00 00 00 02 10 1c
- 15 01 00 00 00 00 02 11 0b
- 15 01 00 00 00 00 02 12 0c
- 15 01 00 00 00 00 02 13 01
- 15 01 00 00 00 00 02 14 0f
- 15 01 00 00 00 00 02 15 10
- 15 01 00 00 00 00 02 16 10
- 15 01 00 00 00 00 02 17 10
- 15 01 00 00 00 00 02 18 89
- 15 01 00 00 00 00 02 19 8a
- 15 01 00 00 00 00 02 1a 13
- 15 01 00 00 00 00 02 1b 13
- 15 01 00 00 00 00 02 1c 15
- 15 01 00 00 00 00 02 1d 15
- 15 01 00 00 00 00 02 1e 17
- 15 01 00 00 00 00 02 1f 17
- /* STV */
- 15 01 00 00 00 00 02 20 40
- 15 01 00 00 00 00 02 21 01
- 15 01 00 00 00 00 02 22 00
- 15 01 00 00 00 00 02 23 40
- 15 01 00 00 00 00 02 24 40
- 15 01 00 00 00 00 02 25 6d
- 15 01 00 00 00 00 02 26 40
- 15 01 00 00 00 00 02 27 40
- /* Vend */
- 15 01 00 00 00 00 02 e0 00
- 15 01 00 00 00 00 02 dc 21
- 15 01 00 00 00 00 02 dd 22
- 15 01 00 00 00 00 02 de 07
- 15 01 00 00 00 00 02 df 07
- 15 01 00 00 00 00 02 e3 6D
- 15 01 00 00 00 00 02 e1 07
- 15 01 00 00 00 00 02 e2 07
- /* UD */
- 15 01 00 00 00 00 02 29 d8
- 15 01 00 00 00 00 02 2a 2a
- /* CLK */
- 15 01 00 00 00 00 02 4b 03
- 15 01 00 00 00 00 02 4c 11
- 15 01 00 00 00 00 02 4d 10
- 15 01 00 00 00 00 02 4e 01
- 15 01 00 00 00 00 02 4f 01
- 15 01 00 00 00 00 02 50 10
- 15 01 00 00 00 00 02 51 00
- 15 01 00 00 00 00 02 52 80
- 15 01 00 00 00 00 02 53 00
- 15 01 00 00 00 00 02 56 00
- 15 01 00 00 00 00 02 54 07
- 15 01 00 00 00 00 02 58 07
- 15 01 00 00 00 00 02 55 25
- /* Reset XDONB */
- 15 01 00 00 00 00 02 5b 43
- 15 01 00 00 00 00 02 5c 00
- 15 01 00 00 00 00 02 5f 73
- 15 01 00 00 00 00 02 60 73
- 15 01 00 00 00 00 02 63 22
- 15 01 00 00 00 00 02 64 00
- 15 01 00 00 00 00 02 67 08
- 15 01 00 00 00 00 02 68 04
- /* Resolution:1440x2560*/
- 15 01 00 00 00 00 02 72 02
- /* mux */
- 15 01 00 00 00 00 02 7a 80
- 15 01 00 00 00 00 02 7b 91
- 15 01 00 00 00 00 02 7c D8
- 15 01 00 00 00 00 02 7d 60
- 15 01 00 00 00 00 02 7f 15
- 15 01 00 00 00 00 02 75 15
- /* ABOFF */
- 15 01 00 00 00 00 02 b3 C0
- 15 01 00 00 00 00 02 b4 00
- 15 01 00 00 00 00 02 b5 00
- /* Source EQ */
- 15 01 00 00 00 00 02 78 00
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 80 00
- 15 01 00 00 00 00 02 83 00
- /* FP BP */
- 15 01 00 00 00 00 02 93 0a
- 15 01 00 00 00 00 02 94 0a
- /* Inversion Type */
- 15 01 00 00 00 00 02 8a 00
- 15 01 00 00 00 00 02 9b ff
- /* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 00 00 02 9d b0
- 15 01 00 00 00 00 02 9f 63
- 15 01 00 00 00 00 02 98 10
- /* FRM */
- 15 01 00 00 00 00 02 ec 00
- /* CMD1 */
- 15 01 00 00 00 00 02 ff 10
- /* VESA DSC PPS settings(1440x2560 slide 16H) */
- 39 01 00 00 00 00 11 c1 09 20 00 10 02 00 02 68
- 01 bb 00 0a 06 67 04 c5
- 39 01 00 00 00 00 03 c2 10 f0
- /* C0h = 0x0(2 Port SDC)0x01(1 PortA FBC)
- * 0x02(MTK) 0x03(1 PortA VESA)
- */
- 15 01 00 00 00 00 02 c0 03
- /* VBP+VSA=,VFP = 10H */
- 15 01 00 00 00 00 04 3b 03 0a 0a
- /* FTE on */
- 15 01 00 00 00 00 02 35 00
- /* EN_BK =1(auto black) */
- 15 01 00 00 00 00 02 e5 01
- /* CMD mode(10) VDO mode(03) */
- 15 01 00 00 00 00 02 bb 10
- /* Non Reload MTP */
- 15 01 00 00 00 00 02 fb 01
- /* SlpOut + DispOn */
- 05 01 00 00 78 00 02 11 00
- 05 01 00 00 78 00 02 29 00
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
-
- qcom,mdss-dsi-on-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -218,7 +38,6 @@
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
-
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,adjust-timer-wakeup-ms = <1>;
qcom,mdss-dsi-te-pin-select = <1>;
@@ -228,13 +47,201 @@
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
- qcom,compression-mode = "dsc";
- qcom,mdss-dsc-slice-height = <16>;
- qcom,mdss-dsc-slice-width = <720>;
- qcom,mdss-dsc-slice-per-pkt = <2>;
- qcom,mdss-dsc-bit-per-component = <8>;
- qcom,mdss-dsc-bit-per-pixel = <8>;
- qcom,mdss-dsc-block-prediction-enable;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-panel-width = <1440>;
+ qcom,mdss-dsi-panel-height = <2560>;
+ qcom,mdss-dsi-h-front-porch = <100>;
+ qcom,mdss-dsi-h-back-porch = <32>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <8>;
+ qcom,mdss-dsi-v-front-porch = <10>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-panel-jitter = <0x1 0x1>;
+ qcom,mdss-dsi-on-command = [
+ /* CMD2_P0 */
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1e
+ 15 01 00 00 00 00 02 0b 73
+ 15 01 00 00 00 00 02 0c 73
+ 15 01 00 00 00 00 02 0e b0
+ 15 01 00 00 00 00 02 0f ae
+ 15 01 00 00 00 00 02 11 b8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5a 00
+ 15 01 00 00 00 00 02 5b 01
+ 15 01 00 00 00 00 02 5c 80
+ 15 01 00 00 00 00 02 5d 81
+ 15 01 00 00 00 00 02 5e 00
+ 15 01 00 00 00 00 02 5f 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
+ /* CMD2_P4 */
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1c
+ 15 01 00 00 00 00 02 01 0b
+ 15 01 00 00 00 00 02 02 0c
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0f
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8a
+ 15 01 00 00 00 00 02 0a 13
+ 15 01 00 00 00 00 02 0b 13
+ 15 01 00 00 00 00 02 0c 15
+ 15 01 00 00 00 00 02 0d 15
+ 15 01 00 00 00 00 02 0e 17
+ 15 01 00 00 00 00 02 0f 17
+ 15 01 00 00 00 00 02 10 1c
+ 15 01 00 00 00 00 02 11 0b
+ 15 01 00 00 00 00 02 12 0c
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0f
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8a
+ 15 01 00 00 00 00 02 1a 13
+ 15 01 00 00 00 00 02 1b 13
+ 15 01 00 00 00 00 02 1c 15
+ 15 01 00 00 00 00 02 1d 15
+ 15 01 00 00 00 00 02 1e 17
+ 15 01 00 00 00 00 02 1f 17
+ /* STV */
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6d
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
+ /* Vend */
+ 15 01 00 00 00 00 02 e0 00
+ 15 01 00 00 00 00 02 dc 21
+ 15 01 00 00 00 00 02 dd 22
+ 15 01 00 00 00 00 02 de 07
+ 15 01 00 00 00 00 02 df 07
+ 15 01 00 00 00 00 02 e3 6D
+ 15 01 00 00 00 00 02 e1 07
+ 15 01 00 00 00 00 02 e2 07
+ /* UD */
+ 15 01 00 00 00 00 02 29 d8
+ 15 01 00 00 00 00 02 2a 2a
+ /* CLK */
+ 15 01 00 00 00 00 02 4b 03
+ 15 01 00 00 00 00 02 4c 11
+ 15 01 00 00 00 00 02 4d 10
+ 15 01 00 00 00 00 02 4e 01
+ 15 01 00 00 00 00 02 4f 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
+ /* Reset XDONB */
+ 15 01 00 00 00 00 02 5b 43
+ 15 01 00 00 00 00 02 5c 00
+ 15 01 00 00 00 00 02 5f 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
+ /* Resolution:1440x2560*/
+ 15 01 00 00 00 00 02 72 02
+ /* mux */
+ 15 01 00 00 00 00 02 7a 80
+ 15 01 00 00 00 00 02 7b 91
+ 15 01 00 00 00 00 02 7c D8
+ 15 01 00 00 00 00 02 7d 60
+ 15 01 00 00 00 00 02 7f 15
+ 15 01 00 00 00 00 02 75 15
+ /* ABOFF */
+ 15 01 00 00 00 00 02 b3 C0
+ 15 01 00 00 00 00 02 b4 00
+ 15 01 00 00 00 00 02 b5 00
+ /* Source EQ */
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
+ /* FP BP */
+ 15 01 00 00 00 00 02 93 0a
+ 15 01 00 00 00 00 02 94 0a
+ /* Inversion Type */
+ 15 01 00 00 00 00 02 8a 00
+ 15 01 00 00 00 00 02 9b ff
+ /* IMGSWAP =1 @PortSwap=1 */
+ 15 01 00 00 00 00 02 9d b0
+ 15 01 00 00 00 00 02 9f 63
+ 15 01 00 00 00 00 02 98 10
+ /* FRM */
+ 15 01 00 00 00 00 02 ec 00
+ /* CMD1 */
+ 15 01 00 00 00 00 02 ff 10
+ /* VESA DSC PPS settings
+ * (1440x2560 slide 16H)
+ */
+ 39 01 00 00 00 00 11 c1 09
+ 20 00 10 02 00 02 68 01 bb
+ 00 0a 06 67 04 c5
+ 39 01 00 00 00 00 03 c2 10 f0
+ /* C0h = 0x0(2 Port SDC)
+ * 0x01(1 PortA FBC)
+ * 0x02(MTK) 0x03(1 PortA VESA)
+ */
+ 15 01 00 00 00 00 02 c0 03
+ /* VBP+VSA=,VFP = 10H */
+ 15 01 00 00 00 00 04 3b 03 0a 0a
+ /* FTE on */
+ 15 01 00 00 00 00 02 35 00
+ /* EN_BK =1(auto black) */
+ 15 01 00 00 00 00 02 e5 01
+ /* CMD mode(10) VDO mode(03) */
+ 15 01 00 00 00 00 02 bb 10
+ /* Non Reload MTP */
+ 15 01 00 00 00 00 02 fb 01
+ /* SlpOut + DispOn */
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
+ ];
+ qcom,mdss-dsi-off-command = [05 01 00 00 78 00
+ 02 28 00 05 01 00 00 78 00 02 10 00];
+
+ qcom,mdss-dsi-on-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,compression-mode = "dsc";
+ qcom,mdss-dsc-slice-height = <16>;
+ qcom,mdss-dsc-slice-width = <720>;
+ qcom,mdss-dsc-slice-per-pkt = <2>;
+ qcom,mdss-dsc-bit-per-component = <8>;
+ qcom,mdss-dsc-bit-per-pixel = <8>;
+ qcom,mdss-dsc-block-prediction-enable;
+ };
+ };
};
};
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 515949e..ac8a956 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
@@ -15,18 +15,8 @@
qcom,mdss-dsi-panel-name =
"nt35597 video mode dsi truly panel with DSC";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1440>;
- qcom,mdss-dsi-panel-height = <2560>;
- qcom,mdss-dsi-h-front-porch = <100>;
- qcom,mdss-dsi-h-back-porch = <32>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <8>;
- qcom,mdss-dsi-v-front-porch = <10>;
- qcom,mdss-dsi-v-pulse-width = <2>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
@@ -35,170 +25,6 @@
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
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 01
- 15 01 00 00 00 00 02 01 55
- 15 01 00 00 00 00 02 02 45
- 15 01 00 00 00 00 02 05 40
- 15 01 00 00 00 00 02 06 19
- 15 01 00 00 00 00 02 07 1e
- 15 01 00 00 00 00 02 0b 73
- 15 01 00 00 00 00 02 0c 73
- 15 01 00 00 00 00 02 0e b0
- 15 01 00 00 00 00 02 0f aE
- 15 01 00 00 00 00 02 11 b8
- 15 01 00 00 00 00 02 13 00
- 15 01 00 00 00 00 02 58 80
- 15 01 00 00 00 00 02 59 01
- 15 01 00 00 00 00 02 5a 00
- 15 01 00 00 00 00 02 5b 01
- 15 01 00 00 00 00 02 5c 80
- 15 01 00 00 00 00 02 5d 81
- 15 01 00 00 00 00 02 5e 00
- 15 01 00 00 00 00 02 5f 01
- 15 01 00 00 00 00 02 72 31
- 15 01 00 00 00 00 02 68 03
- /* CMD2_P4 */
- 15 01 00 00 00 00 02 ff 24
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 1c
- 15 01 00 00 00 00 02 01 0b
- 15 01 00 00 00 00 02 02 0c
- 15 01 00 00 00 00 02 03 01
- 15 01 00 00 00 00 02 04 0f
- 15 01 00 00 00 00 02 05 10
- 15 01 00 00 00 00 02 06 10
- 15 01 00 00 00 00 02 07 10
- 15 01 00 00 00 00 02 08 89
- 15 01 00 00 00 00 02 09 8a
- 15 01 00 00 00 00 02 0a 13
- 15 01 00 00 00 00 02 0b 13
- 15 01 00 00 00 00 02 0c 15
- 15 01 00 00 00 00 02 0d 15
- 15 01 00 00 00 00 02 0e 17
- 15 01 00 00 00 00 02 0f 17
- 15 01 00 00 00 00 02 10 1c
- 15 01 00 00 00 00 02 11 0b
- 15 01 00 00 00 00 02 12 0c
- 15 01 00 00 00 00 02 13 01
- 15 01 00 00 00 00 02 14 0f
- 15 01 00 00 00 00 02 15 10
- 15 01 00 00 00 00 02 16 10
- 15 01 00 00 00 00 02 17 10
- 15 01 00 00 00 00 02 18 89
- 15 01 00 00 00 00 02 19 8a
- 15 01 00 00 00 00 02 1a 13
- 15 01 00 00 00 00 02 1b 13
- 15 01 00 00 00 00 02 1c 15
- 15 01 00 00 00 00 02 1d 15
- 15 01 00 00 00 00 02 1e 17
- 15 01 00 00 00 00 02 1f 17
- /* STV */
- 15 01 00 00 00 00 02 20 40
- 15 01 00 00 00 00 02 21 01
- 15 01 00 00 00 00 02 22 00
- 15 01 00 00 00 00 02 23 40
- 15 01 00 00 00 00 02 24 40
- 15 01 00 00 00 00 02 25 6d
- 15 01 00 00 00 00 02 26 40
- 15 01 00 00 00 00 02 27 40
- /* Vend */
- 15 01 00 00 00 00 02 e0 00
- 15 01 00 00 00 00 02 dc 21
- 15 01 00 00 00 00 02 dd 22
- 15 01 00 00 00 00 02 de 07
- 15 01 00 00 00 00 02 df 07
- 15 01 00 00 00 00 02 e3 6d
- 15 01 00 00 00 00 02 e1 07
- 15 01 00 00 00 00 02 e2 07
- /* UD */
- 15 01 00 00 00 00 02 29 d8
- 15 01 00 00 00 00 02 2a 2a
- /* CLK */
- 15 01 00 00 00 00 02 4b 03
- 15 01 00 00 00 00 02 4c 11
- 15 01 00 00 00 00 02 4d 10
- 15 01 00 00 00 00 02 4e 01
- 15 01 00 00 00 00 02 4f 01
- 15 01 00 00 00 00 02 50 10
- 15 01 00 00 00 00 02 51 00
- 15 01 00 00 00 00 02 52 80
- 15 01 00 00 00 00 02 53 00
- 15 01 00 00 00 00 02 56 00
- 15 01 00 00 00 00 02 54 07
- 15 01 00 00 00 00 02 58 07
- 15 01 00 00 00 00 02 55 25
- /* Reset XDONB */
- 15 01 00 00 00 00 02 5b 43
- 15 01 00 00 00 00 02 5c 00
- 15 01 00 00 00 00 02 5f 73
- 15 01 00 00 00 00 02 60 73
- 15 01 00 00 00 00 02 63 22
- 15 01 00 00 00 00 02 64 00
- 15 01 00 00 00 00 02 67 08
- 15 01 00 00 00 00 02 68 04
- /* Resolution:1440x2560*/
- 15 01 00 00 00 00 02 72 02
- /* mux */
- 15 01 00 00 00 00 02 7a 80
- 15 01 00 00 00 00 02 7b 91
- 15 01 00 00 00 00 02 7c d8
- 15 01 00 00 00 00 02 7d 60
- 15 01 00 00 00 00 02 7f 15
- 15 01 00 00 00 00 02 75 15
- /* ABOFF */
- 15 01 00 00 00 00 02 b3 c0
- 15 01 00 00 00 00 02 b4 00
- 15 01 00 00 00 00 02 b5 00
- /* Source EQ */
- 15 01 00 00 00 00 02 78 00
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 80 00
- 15 01 00 00 00 00 02 83 00
- /* FP BP */
- 15 01 00 00 00 00 02 93 0a
- 15 01 00 00 00 00 02 94 0a
- /* Inversion Type */
- 15 01 00 00 00 00 02 8a 00
- 15 01 00 00 00 00 02 9b ff
- /* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 00 00 02 9d b0
- 15 01 00 00 00 00 02 9f 63
- 15 01 00 00 00 00 02 98 10
- /* FRM */
- 15 01 00 00 00 00 02 ec 00
- /* CMD1 */
- 15 01 00 00 00 00 02 ff 10
- /* VESA DSC PPS settings(1440x2560 slide 16H) */
- 39 01 00 00 00 00 11 c1 09 20 00 10 02 00 02 68 01
- bb 00 0a 06 67 04 c5
- 39 01 00 00 00 00 03 c2 10 f0
- /* C0h = 0x00(2 Port SDC); 0x01(1 PortA FBC);
- * 0x02(MTK); 0x03(1 PortA VESA)
- */
- 15 01 00 00 00 00 02 c0 03
- /* VBP+VSA=,VFP = 10H */
- 39 01 00 00 00 00 04 3b 03 0a 0a
- /* FTE on */
- 15 01 00 00 00 00 02 35 00
- /* EN_BK =1(auto black) */
- 15 01 00 00 00 00 02 e5 01
- /* CMD mode(10) VDO mode(03) */
- 15 01 00 00 00 00 02 bb 03
- /* Non Reload MTP */
- 15 01 00 00 00 00 02 fb 01
- /* SlpOut + DispOn */
- 05 01 00 00 78 00 02 11 00
- 05 01 00 00 78 00 02 29 00
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -212,12 +38,195 @@
qcom,mdss-pan-physical-width-dimension = <74>;
qcom,mdss-pan-physical-height-dimension = <131>;
- qcom,compression-mode = "dsc";
- qcom,mdss-dsc-slice-height = <16>;
- qcom,mdss-dsc-slice-width = <720>;
- qcom,mdss-dsc-slice-per-pkt = <2>;
- qcom,mdss-dsc-bit-per-component = <8>;
- qcom,mdss-dsc-bit-per-pixel = <8>;
- qcom,mdss-dsc-block-prediction-enable;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1440>;
+ qcom,mdss-dsi-panel-height = <2560>;
+ qcom,mdss-dsi-h-front-porch = <100>;
+ qcom,mdss-dsi-h-back-porch = <32>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <8>;
+ qcom,mdss-dsi-v-front-porch = <10>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-on-command = [
+ /* CMD2_P0 */
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1e
+ 15 01 00 00 00 00 02 0b 73
+ 15 01 00 00 00 00 02 0c 73
+ 15 01 00 00 00 00 02 0e b0
+ 15 01 00 00 00 00 02 0f aE
+ 15 01 00 00 00 00 02 11 b8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5a 00
+ 15 01 00 00 00 00 02 5b 01
+ 15 01 00 00 00 00 02 5c 80
+ 15 01 00 00 00 00 02 5d 81
+ 15 01 00 00 00 00 02 5e 00
+ 15 01 00 00 00 00 02 5f 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
+ /* CMD2_P4 */
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1c
+ 15 01 00 00 00 00 02 01 0b
+ 15 01 00 00 00 00 02 02 0c
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0f
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8a
+ 15 01 00 00 00 00 02 0a 13
+ 15 01 00 00 00 00 02 0b 13
+ 15 01 00 00 00 00 02 0c 15
+ 15 01 00 00 00 00 02 0d 15
+ 15 01 00 00 00 00 02 0e 17
+ 15 01 00 00 00 00 02 0f 17
+ 15 01 00 00 00 00 02 10 1c
+ 15 01 00 00 00 00 02 11 0b
+ 15 01 00 00 00 00 02 12 0c
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0f
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8a
+ 15 01 00 00 00 00 02 1a 13
+ 15 01 00 00 00 00 02 1b 13
+ 15 01 00 00 00 00 02 1c 15
+ 15 01 00 00 00 00 02 1d 15
+ 15 01 00 00 00 00 02 1e 17
+ 15 01 00 00 00 00 02 1f 17
+ /* STV */
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6d
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
+ /* Vend */
+ 15 01 00 00 00 00 02 e0 00
+ 15 01 00 00 00 00 02 dc 21
+ 15 01 00 00 00 00 02 dd 22
+ 15 01 00 00 00 00 02 de 07
+ 15 01 00 00 00 00 02 df 07
+ 15 01 00 00 00 00 02 e3 6d
+ 15 01 00 00 00 00 02 e1 07
+ 15 01 00 00 00 00 02 e2 07
+ /* UD */
+ 15 01 00 00 00 00 02 29 d8
+ 15 01 00 00 00 00 02 2a 2a
+ /* CLK */
+ 15 01 00 00 00 00 02 4b 03
+ 15 01 00 00 00 00 02 4c 11
+ 15 01 00 00 00 00 02 4d 10
+ 15 01 00 00 00 00 02 4e 01
+ 15 01 00 00 00 00 02 4f 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
+ /* Reset XDONB */
+ 15 01 00 00 00 00 02 5b 43
+ 15 01 00 00 00 00 02 5c 00
+ 15 01 00 00 00 00 02 5f 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
+ /* Resolution:1440x2560*/
+ 15 01 00 00 00 00 02 72 02
+ /* mux */
+ 15 01 00 00 00 00 02 7a 80
+ 15 01 00 00 00 00 02 7b 91
+ 15 01 00 00 00 00 02 7c d8
+ 15 01 00 00 00 00 02 7d 60
+ 15 01 00 00 00 00 02 7f 15
+ 15 01 00 00 00 00 02 75 15
+ /* ABOFF */
+ 15 01 00 00 00 00 02 b3 c0
+ 15 01 00 00 00 00 02 b4 00
+ 15 01 00 00 00 00 02 b5 00
+ /* Source EQ */
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
+ /* FP BP */
+ 15 01 00 00 00 00 02 93 0a
+ 15 01 00 00 00 00 02 94 0a
+ /* Inversion Type */
+ 15 01 00 00 00 00 02 8a 00
+ 15 01 00 00 00 00 02 9b ff
+ /* IMGSWAP =1 @PortSwap=1 */
+ 15 01 00 00 00 00 02 9d b0
+ 15 01 00 00 00 00 02 9f 63
+ 15 01 00 00 00 00 02 98 10
+ /* FRM */
+ 15 01 00 00 00 00 02 ec 00
+ /* CMD1 */
+ 15 01 00 00 00 00 02 ff 10
+ /* VESA DSC PPS settings
+ * (1440x2560 slide 16H)
+ */
+ 39 01 00 00 00 00 11 c1 09
+ 20 00 10 02 00 02 68 01 bb
+ 00 0a 06 67 04 c5
+
+ 39 01 00 00 00 00 03 c2 10 f0
+ /* C0h = 0x00(2 Port SDC);
+ * 0x01(1 PortA FBC);
+ * 0x02(MTK); 0x03(1 PortA VESA)
+ */
+ 15 01 00 00 00 00 02 c0 03
+ /* VBP+VSA=,VFP = 10H */
+ 39 01 00 00 00 00 04 3b 03 0a 0a
+ /* FTE on */
+ 15 01 00 00 00 00 02 35 00
+ /* EN_BK =1(auto black) */
+ 15 01 00 00 00 00 02 e5 01
+ /* CMD mode(10) VDO mode(03) */
+ 15 01 00 00 00 00 02 bb 03
+ /* Non Reload MTP */
+ 15 01 00 00 00 00 02 fb 01
+ /* SlpOut + DispOn */
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
+ ];
+ qcom,mdss-dsi-off-command = [05 01 00 00 78 00
+ 02 28 00 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,compression-mode = "dsc";
+ qcom,mdss-dsc-slice-height = <16>;
+ qcom,mdss-dsc-slice-width = <720>;
+ qcom,mdss-dsc-slice-per-pkt = <2>;
+ qcom,mdss-dsc-bit-per-component = <8>;
+ qcom,mdss-dsc-bit-per-pixel = <8>;
+ qcom,mdss-dsc-block-prediction-enable;
+ };
+ };
};
};
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 f860ea3..87cabae 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
@@ -15,28 +15,12 @@
qcom,mdss-dsi-panel-name =
"Dual nt35597 cmd mode dsi truly panel without DSC";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <720>;
- qcom,mdss-dsi-panel-height = <2560>;
- qcom,mdss-dsi-h-front-porch = <100>;
- qcom,mdss-dsi-h-back-porch = <32>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <7>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <1>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-color-order = "rgb_swap_rgb";
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-panel-jitter = <0x1 0x1>;
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -62,167 +46,181 @@
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
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 01
- 15 01 00 00 00 00 02 01 55
- 15 01 00 00 00 00 02 02 45
- 15 01 00 00 00 00 02 05 40
- 15 01 00 00 00 00 02 06 19
- 15 01 00 00 00 00 02 07 1E
- 15 01 00 00 00 00 02 0B 73
- 15 01 00 00 00 00 02 0C 73
- 15 01 00 00 00 00 02 0E B0
- 15 01 00 00 00 00 02 0F AE
- 15 01 00 00 00 00 02 11 B8
- 15 01 00 00 00 00 02 13 00
- 15 01 00 00 00 00 02 58 80
- 15 01 00 00 00 00 02 59 01
- 15 01 00 00 00 00 02 5A 00
- 15 01 00 00 00 00 02 5B 01
- 15 01 00 00 00 00 02 5C 80
- 15 01 00 00 00 00 02 5D 81
- 15 01 00 00 00 00 02 5E 00
- 15 01 00 00 00 00 02 5F 01
- 15 01 00 00 00 00 02 72 31
- 15 01 00 00 00 00 02 68 03
- /* CMD2_P4 */
- 15 01 00 00 00 00 02 ff 24
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 1C
- 15 01 00 00 00 00 02 01 0B
- 15 01 00 00 00 00 02 02 0C
- 15 01 00 00 00 00 02 03 01
- 15 01 00 00 00 00 02 04 0F
- 15 01 00 00 00 00 02 05 10
- 15 01 00 00 00 00 02 06 10
- 15 01 00 00 00 00 02 07 10
- 15 01 00 00 00 00 02 08 89
- 15 01 00 00 00 00 02 09 8A
- 15 01 00 00 00 00 02 0A 13
- 15 01 00 00 00 00 02 0B 13
- 15 01 00 00 00 00 02 0C 15
- 15 01 00 00 00 00 02 0D 15
- 15 01 00 00 00 00 02 0E 17
- 15 01 00 00 00 00 02 0F 17
- 15 01 00 00 00 00 02 10 1C
- 15 01 00 00 00 00 02 11 0B
- 15 01 00 00 00 00 02 12 0C
- 15 01 00 00 00 00 02 13 01
- 15 01 00 00 00 00 02 14 0F
- 15 01 00 00 00 00 02 15 10
- 15 01 00 00 00 00 02 16 10
- 15 01 00 00 00 00 02 17 10
- 15 01 00 00 00 00 02 18 89
- 15 01 00 00 00 00 02 19 8A
- 15 01 00 00 00 00 02 1A 13
- 15 01 00 00 00 00 02 1B 13
- 15 01 00 00 00 00 02 1C 15
- 15 01 00 00 00 00 02 1D 15
- 15 01 00 00 00 00 02 1E 17
- 15 01 00 00 00 00 02 1F 17
- /* STV */
- 15 01 00 00 00 00 02 20 40
- 15 01 00 00 00 00 02 21 01
- 15 01 00 00 00 00 02 22 00
- 15 01 00 00 00 00 02 23 40
- 15 01 00 00 00 00 02 24 40
- 15 01 00 00 00 00 02 25 6D
- 15 01 00 00 00 00 02 26 40
- 15 01 00 00 00 00 02 27 40
- /* Vend */
- 15 01 00 00 00 00 02 E0 00
- 15 01 00 00 00 00 02 DC 21
- 15 01 00 00 00 00 02 DD 22
- 15 01 00 00 00 00 02 DE 07
- 15 01 00 00 00 00 02 DF 07
- 15 01 00 00 00 00 02 E3 6D
- 15 01 00 00 00 00 02 E1 07
- 15 01 00 00 00 00 02 E2 07
- /* UD */
- 15 01 00 00 00 00 02 29 D8
- 15 01 00 00 00 00 02 2A 2A
- /* CLK */
- 15 01 00 00 00 00 02 4B 03
- 15 01 00 00 00 00 02 4C 11
- 15 01 00 00 00 00 02 4D 10
- 15 01 00 00 00 00 02 4E 01
- 15 01 00 00 00 00 02 4F 01
- 15 01 00 00 00 00 02 50 10
- 15 01 00 00 00 00 02 51 00
- 15 01 00 00 00 00 02 52 80
- 15 01 00 00 00 00 02 53 00
- 15 01 00 00 00 00 02 56 00
- 15 01 00 00 00 00 02 54 07
- 15 01 00 00 00 00 02 58 07
- 15 01 00 00 00 00 02 55 25
- /* Reset XDONB */
- 15 01 00 00 00 00 02 5B 43
- 15 01 00 00 00 00 02 5C 00
- 15 01 00 00 00 00 02 5F 73
- 15 01 00 00 00 00 02 60 73
- 15 01 00 00 00 00 02 63 22
- 15 01 00 00 00 00 02 64 00
- 15 01 00 00 00 00 02 67 08
- 15 01 00 00 00 00 02 68 04
- /* Resolution:1440x2560*/
- 15 01 00 00 00 00 02 72 02
- /* mux */
- 15 01 00 00 00 00 02 7A 80
- 15 01 00 00 00 00 02 7B 91
- 15 01 00 00 00 00 02 7C D8
- 15 01 00 00 00 00 02 7D 60
- 15 01 00 00 00 00 02 7F 15
- 15 01 00 00 00 00 02 75 15
- /* ABOFF */
- 15 01 00 00 00 00 02 B3 C0
- 15 01 00 00 00 00 02 B4 00
- 15 01 00 00 00 00 02 B5 00
- /* Source EQ */
- 15 01 00 00 00 00 02 78 00
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 80 00
- 15 01 00 00 00 00 02 83 00
- /* FP BP */
- 15 01 00 00 00 00 02 93 0A
- 15 01 00 00 00 00 02 94 0A
- /* Inversion Type */
- 15 01 00 00 00 00 02 8A 00
- 15 01 00 00 00 00 02 9B FF
- /* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 00 00 02 9D B0
- 15 01 00 00 00 00 02 9F 63
- 15 01 00 00 00 00 02 98 10
- /* FRM */
- 15 01 00 00 00 00 02 EC 00
- /* CMD1 */
- 15 01 00 00 00 00 02 ff 10
- /* VBP+VSA=,VFP = 10H */
- 15 01 00 00 00 00 04 3B 03 0A 0A
- /* FTE on */
- 15 01 00 00 00 00 02 35 00
- /* EN_BK =1(auto black) */
- 15 01 00 00 00 00 02 E5 01
- /* CMD mode(10) VDO mode(03) */
- 15 01 00 00 00 00 02 BB 10
- /* Non Reload MTP */
- 15 01 00 00 00 00 02 FB 01
- /* SlpOut + DispOn */
- 05 01 00 00 78 00 02 11 00
- 05 01 00 00 78 00 02 29 00
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
-
- qcom,config-select = <&dsi_dual_nt35597_truly_cmd_config0>;
-
- dsi_dual_nt35597_truly_cmd_config0: config0 {
- qcom,split-mode = "dualctl-split";
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-panel-width = <720>;
+ qcom,mdss-dsi-panel-height = <2560>;
+ qcom,mdss-dsi-h-front-porch = <100>;
+ qcom,mdss-dsi-h-back-porch = <32>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <7>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-jitter = <0x1 0x1>;
+ qcom,mdss-dsi-on-command = [
+ /* CMD2_P0 */
+ 15 01 00 00 00 00 02 FF 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1E
+ 15 01 00 00 00 00 02 0B 73
+ 15 01 00 00 00 00 02 0C 73
+ 15 01 00 00 00 00 02 0E B0
+ 15 01 00 00 00 00 02 0F AE
+ 15 01 00 00 00 00 02 11 B8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5A 00
+ 15 01 00 00 00 00 02 5B 01
+ 15 01 00 00 00 00 02 5C 80
+ 15 01 00 00 00 00 02 5D 81
+ 15 01 00 00 00 00 02 5E 00
+ 15 01 00 00 00 00 02 5F 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
+ /* CMD2_P4 */
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1C
+ 15 01 00 00 00 00 02 01 0B
+ 15 01 00 00 00 00 02 02 0C
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0F
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8A
+ 15 01 00 00 00 00 02 0A 13
+ 15 01 00 00 00 00 02 0B 13
+ 15 01 00 00 00 00 02 0C 15
+ 15 01 00 00 00 00 02 0D 15
+ 15 01 00 00 00 00 02 0E 17
+ 15 01 00 00 00 00 02 0F 17
+ 15 01 00 00 00 00 02 10 1C
+ 15 01 00 00 00 00 02 11 0B
+ 15 01 00 00 00 00 02 12 0C
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0F
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8A
+ 15 01 00 00 00 00 02 1A 13
+ 15 01 00 00 00 00 02 1B 13
+ 15 01 00 00 00 00 02 1C 15
+ 15 01 00 00 00 00 02 1D 15
+ 15 01 00 00 00 00 02 1E 17
+ 15 01 00 00 00 00 02 1F 17
+ /* STV */
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6D
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
+ /* Vend */
+ 15 01 00 00 00 00 02 E0 00
+ 15 01 00 00 00 00 02 DC 21
+ 15 01 00 00 00 00 02 DD 22
+ 15 01 00 00 00 00 02 DE 07
+ 15 01 00 00 00 00 02 DF 07
+ 15 01 00 00 00 00 02 E3 6D
+ 15 01 00 00 00 00 02 E1 07
+ 15 01 00 00 00 00 02 E2 07
+ /* UD */
+ 15 01 00 00 00 00 02 29 D8
+ 15 01 00 00 00 00 02 2A 2A
+ /* CLK */
+ 15 01 00 00 00 00 02 4B 03
+ 15 01 00 00 00 00 02 4C 11
+ 15 01 00 00 00 00 02 4D 10
+ 15 01 00 00 00 00 02 4E 01
+ 15 01 00 00 00 00 02 4F 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
+ /* Reset XDONB */
+ 15 01 00 00 00 00 02 5B 43
+ 15 01 00 00 00 00 02 5C 00
+ 15 01 00 00 00 00 02 5F 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
+ /* Resolution:1440x2560*/
+ 15 01 00 00 00 00 02 72 02
+ /* mux */
+ 15 01 00 00 00 00 02 7A 80
+ 15 01 00 00 00 00 02 7B 91
+ 15 01 00 00 00 00 02 7C D8
+ 15 01 00 00 00 00 02 7D 60
+ 15 01 00 00 00 00 02 7F 15
+ 15 01 00 00 00 00 02 75 15
+ /* ABOFF */
+ 15 01 00 00 00 00 02 B3 C0
+ 15 01 00 00 00 00 02 B4 00
+ 15 01 00 00 00 00 02 B5 00
+ /* Source EQ */
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
+ /* FP BP */
+ 15 01 00 00 00 00 02 93 0A
+ 15 01 00 00 00 00 02 94 0A
+ /* Inversion Type */
+ 15 01 00 00 00 00 02 8A 00
+ 15 01 00 00 00 00 02 9B FF
+ /* IMGSWAP =1 @PortSwap=1 */
+ 15 01 00 00 00 00 02 9D B0
+ 15 01 00 00 00 00 02 9F 63
+ 15 01 00 00 00 00 02 98 10
+ /* FRM */
+ 15 01 00 00 00 00 02 EC 00
+ /* CMD1 */
+ 15 01 00 00 00 00 02 ff 10
+ /* VBP+VSA=,VFP = 10H */
+ 15 01 00 00 00 00 04 3B 03 0A 0A
+ /* FTE on */
+ 15 01 00 00 00 00 02 35 00
+ /* EN_BK =1(auto black) */
+ 15 01 00 00 00 00 02 E5 01
+ /* CMD mode(10) VDO mode(03) */
+ 15 01 00 00 00 00 02 BB 10
+ /* Non Reload MTP */
+ 15 01 00 00 00 00 02 FB 01
+ /* SlpOut + DispOn */
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
+ ];
+ qcom,mdss-dsi-off-command = [05 01 00 00 78 00
+ 02 28 00 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
};
};
};
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 23a96a4..0d0e7f7 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
@@ -15,182 +15,13 @@
qcom,mdss-dsi-panel-name =
"Dual nt35597 video mode dsi truly panel without DSC";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <720>;
- qcom,mdss-dsi-panel-height = <2560>;
- qcom,mdss-dsi-h-front-porch = <100>;
- qcom,mdss-dsi-h-back-porch = <32>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <7>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <1>;
- 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
- 15 01 00 00 00 00 02 FB 01
- 15 01 00 00 00 00 02 00 01
- 15 01 00 00 00 00 02 01 55
- 15 01 00 00 00 00 02 02 45
- 15 01 00 00 00 00 02 05 40
- 15 01 00 00 00 00 02 06 19
- 15 01 00 00 00 00 02 07 1E
- 15 01 00 00 00 00 02 0B 73
- 15 01 00 00 00 00 02 0C 73
- 15 01 00 00 00 00 02 0E B0
- 15 01 00 00 00 00 02 0F AE
- 15 01 00 00 00 00 02 11 B8
- 15 01 00 00 00 00 02 13 00
- 15 01 00 00 00 00 02 58 80
- 15 01 00 00 00 00 02 59 01
- 15 01 00 00 00 00 02 5A 00
- 15 01 00 00 00 00 02 5B 01
- 15 01 00 00 00 00 02 5C 80
- 15 01 00 00 00 00 02 5D 81
- 15 01 00 00 00 00 02 5E 00
- 15 01 00 00 00 00 02 5F 01
- 15 01 00 00 00 00 02 72 31
- 15 01 00 00 00 00 02 68 03
- /* CMD2_P4 */
- 15 01 00 00 00 00 02 FF 24
- 15 01 00 00 00 00 02 FB 01
- 15 01 00 00 00 00 02 00 1C
- 15 01 00 00 00 00 02 01 0B
- 15 01 00 00 00 00 02 02 0C
- 15 01 00 00 00 00 02 03 01
- 15 01 00 00 00 00 02 04 0F
- 15 01 00 00 00 00 02 05 10
- 15 01 00 00 00 00 02 06 10
- 15 01 00 00 00 00 02 07 10
- 15 01 00 00 00 00 02 08 89
- 15 01 00 00 00 00 02 09 8A
- 15 01 00 00 00 00 02 0A 13
- 15 01 00 00 00 00 02 0B 13
- 15 01 00 00 00 00 02 0C 15
- 15 01 00 00 00 00 02 0D 15
- 15 01 00 00 00 00 02 0E 17
- 15 01 00 00 00 00 02 0F 17
- 15 01 00 00 00 00 02 10 1C
- 15 01 00 00 00 00 02 11 0B
- 15 01 00 00 00 00 02 12 0C
- 15 01 00 00 00 00 02 13 01
- 15 01 00 00 00 00 02 14 0F
- 15 01 00 00 00 00 02 15 10
- 15 01 00 00 00 00 02 16 10
- 15 01 00 00 00 00 02 17 10
- 15 01 00 00 00 00 02 18 89
- 15 01 00 00 00 00 02 19 8A
- 15 01 00 00 00 00 02 1A 13
- 15 01 00 00 00 00 02 1B 13
- 15 01 00 00 00 00 02 1C 15
- 15 01 00 00 00 00 02 1D 15
- 15 01 00 00 00 00 02 1E 17
- 15 01 00 00 00 00 02 1F 17
- /* STV */
- 15 01 00 00 00 00 02 20 40
- 15 01 00 00 00 00 02 21 01
- 15 01 00 00 00 00 02 22 00
- 15 01 00 00 00 00 02 23 40
- 15 01 00 00 00 00 02 24 40
- 15 01 00 00 00 00 02 25 6D
- 15 01 00 00 00 00 02 26 40
- 15 01 00 00 00 00 02 27 40
- /* Vend */
- 15 01 00 00 00 00 02 E0 00
- 15 01 00 00 00 00 02 DC 21
- 15 01 00 00 00 00 02 DD 22
- 15 01 00 00 00 00 02 DE 07
- 15 01 00 00 00 00 02 DF 07
- 15 01 00 00 00 00 02 E3 6D
- 15 01 00 00 00 00 02 E1 07
- 15 01 00 00 00 00 02 E2 07
- /* UD */
- 15 01 00 00 00 00 02 29 D8
- 15 01 00 00 00 00 02 2A 2A
- /* CLK */
- 15 01 00 00 00 00 02 4B 03
- 15 01 00 00 00 00 02 4C 11
- 15 01 00 00 00 00 02 4D 10
- 15 01 00 00 00 00 02 4E 01
- 15 01 00 00 00 00 02 4F 01
- 15 01 00 00 00 00 02 50 10
- 15 01 00 00 00 00 02 51 00
- 15 01 00 00 00 00 02 52 80
- 15 01 00 00 00 00 02 53 00
- 15 01 00 00 00 00 02 56 00
- 15 01 00 00 00 00 02 54 07
- 15 01 00 00 00 00 02 58 07
- 15 01 00 00 00 00 02 55 25
- /* Reset XDONB */
- 15 01 00 00 00 00 02 5B 43
- 15 01 00 00 00 00 02 5C 00
- 15 01 00 00 00 00 02 5F 73
- 15 01 00 00 00 00 02 60 73
- 15 01 00 00 00 00 02 63 22
- 15 01 00 00 00 00 02 64 00
- 15 01 00 00 00 00 02 67 08
- 15 01 00 00 00 00 02 68 04
- /* Resolution:1440x2560*/
- 15 01 00 00 00 00 02 72 02
- /* mux */
- 15 01 00 00 00 00 02 7A 80
- 15 01 00 00 00 00 02 7B 91
- 15 01 00 00 00 00 02 7C D8
- 15 01 00 00 00 00 02 7D 60
- 15 01 00 00 00 00 02 7F 15
- 15 01 00 00 00 00 02 75 15
- /* ABOFF */
- 15 01 00 00 00 00 02 B3 C0
- 15 01 00 00 00 00 02 B4 00
- 15 01 00 00 00 00 02 B5 00
- /* Source EQ */
- 15 01 00 00 00 00 02 78 00
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 80 00
- 15 01 00 00 00 00 02 83 00
- /* FP BP */
- 15 01 00 00 00 00 02 93 0A
- 15 01 00 00 00 00 02 94 0A
- /* Inversion Type */
- 15 01 00 00 00 00 02 8A 00
- 15 01 00 00 00 00 02 9B FF
- /* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 00 00 02 9D B0
- 15 01 00 00 00 00 02 9F 63
- 15 01 00 00 00 00 02 98 10
- /* FRM */
- 15 01 00 00 00 00 02 EC 00
- /* CMD1 */
- 15 01 00 00 00 00 02 FF 10
- /* VBP+VSA=,VFP = 10H */
- 15 01 00 00 00 00 04 3B 03 0A 0A
- /* FTE on */
- 15 01 00 00 00 00 02 35 00
- /* EN_BK =1(auto black) */
- 15 01 00 00 00 00 02 E5 01
- /* CMD mode(10) VDO mode(03) */
- 15 01 00 00 00 00 02 BB 03
- /* Non Reload MTP */
- 15 01 00 00 00 00 02 FB 01
- /* SlpOut + DispOn */
- 05 01 00 00 78 00 02 11 00
- 05 01 00 00 78 00 02 29 00
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -205,13 +36,179 @@
qcom,mdss-pan-physical-width-dimension = <74>;
qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-tx-eot-append;
+ qcom,mdss-dsi-underflow-color = <0x3ff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-bpp = <24>;
- qcom,config-select = <&dsi_dual_nt35597_truly_video_config0>;
-
- dsi_dual_nt35597_truly_video_config0: config0 {
- qcom,split-mode = "dualctl-split";
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <720>;
+ qcom,mdss-dsi-panel-height = <2560>;
+ qcom,mdss-dsi-h-front-porch = <100>;
+ qcom,mdss-dsi-h-back-porch = <32>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <7>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-on-command = [
+ /* CMD2_P0 */
+ 15 01 00 00 00 00 02 FF 20
+ 15 01 00 00 00 00 02 FB 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1E
+ 15 01 00 00 00 00 02 0B 73
+ 15 01 00 00 00 00 02 0C 73
+ 15 01 00 00 00 00 02 0E B0
+ 15 01 00 00 00 00 02 0F AE
+ 15 01 00 00 00 00 02 11 B8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5A 00
+ 15 01 00 00 00 00 02 5B 01
+ 15 01 00 00 00 00 02 5C 80
+ 15 01 00 00 00 00 02 5D 81
+ 15 01 00 00 00 00 02 5E 00
+ 15 01 00 00 00 00 02 5F 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
+ /* CMD2_P4 */
+ 15 01 00 00 00 00 02 FF 24
+ 15 01 00 00 00 00 02 FB 01
+ 15 01 00 00 00 00 02 00 1C
+ 15 01 00 00 00 00 02 01 0B
+ 15 01 00 00 00 00 02 02 0C
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0F
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8A
+ 15 01 00 00 00 00 02 0A 13
+ 15 01 00 00 00 00 02 0B 13
+ 15 01 00 00 00 00 02 0C 15
+ 15 01 00 00 00 00 02 0D 15
+ 15 01 00 00 00 00 02 0E 17
+ 15 01 00 00 00 00 02 0F 17
+ 15 01 00 00 00 00 02 10 1C
+ 15 01 00 00 00 00 02 11 0B
+ 15 01 00 00 00 00 02 12 0C
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0F
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8A
+ 15 01 00 00 00 00 02 1A 13
+ 15 01 00 00 00 00 02 1B 13
+ 15 01 00 00 00 00 02 1C 15
+ 15 01 00 00 00 00 02 1D 15
+ 15 01 00 00 00 00 02 1E 17
+ 15 01 00 00 00 00 02 1F 17
+ /* STV */
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6D
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
+ /* Vend */
+ 15 01 00 00 00 00 02 E0 00
+ 15 01 00 00 00 00 02 DC 21
+ 15 01 00 00 00 00 02 DD 22
+ 15 01 00 00 00 00 02 DE 07
+ 15 01 00 00 00 00 02 DF 07
+ 15 01 00 00 00 00 02 E3 6D
+ 15 01 00 00 00 00 02 E1 07
+ 15 01 00 00 00 00 02 E2 07
+ /* UD */
+ 15 01 00 00 00 00 02 29 D8
+ 15 01 00 00 00 00 02 2A 2A
+ /* CLK */
+ 15 01 00 00 00 00 02 4B 03
+ 15 01 00 00 00 00 02 4C 11
+ 15 01 00 00 00 00 02 4D 10
+ 15 01 00 00 00 00 02 4E 01
+ 15 01 00 00 00 00 02 4F 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
+ /* Reset XDONB */
+ 15 01 00 00 00 00 02 5B 43
+ 15 01 00 00 00 00 02 5C 00
+ 15 01 00 00 00 00 02 5F 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
+ /* Resolution:1440x2560*/
+ 15 01 00 00 00 00 02 72 02
+ /* mux */
+ 15 01 00 00 00 00 02 7A 80
+ 15 01 00 00 00 00 02 7B 91
+ 15 01 00 00 00 00 02 7C D8
+ 15 01 00 00 00 00 02 7D 60
+ 15 01 00 00 00 00 02 7F 15
+ 15 01 00 00 00 00 02 75 15
+ /* ABOFF */
+ 15 01 00 00 00 00 02 B3 C0
+ 15 01 00 00 00 00 02 B4 00
+ 15 01 00 00 00 00 02 B5 00
+ /* Source EQ */
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
+ /* FP BP */
+ 15 01 00 00 00 00 02 93 0A
+ 15 01 00 00 00 00 02 94 0A
+ /* Inversion Type */
+ 15 01 00 00 00 00 02 8A 00
+ 15 01 00 00 00 00 02 9B FF
+ /* IMGSWAP =1 @PortSwap=1 */
+ 15 01 00 00 00 00 02 9D B0
+ 15 01 00 00 00 00 02 9F 63
+ 15 01 00 00 00 00 02 98 10
+ /* FRM */
+ 15 01 00 00 00 00 02 EC 00
+ /* CMD1 */
+ 15 01 00 00 00 00 02 FF 10
+ /* VBP+VSA=,VFP = 10H */
+ 15 01 00 00 00 00 04 3B 03 0A 0A
+ /* FTE on */
+ 15 01 00 00 00 00 02 35 00
+ /* EN_BK =1(auto black) */
+ 15 01 00 00 00 00 02 E5 01
+ /* CMD mode(10) VDO mode(03) */
+ 15 01 00 00 00 00 02 BB 03
+ /* Non Reload MTP */
+ 15 01 00 00 00 00 02 FB 01
+ /* SlpOut + DispOn */
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
+ ];
+ qcom,mdss-dsi-off-command = [05 01 00 00 78 00
+ 02 28 00 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ };
};
-
-
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-1080p-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-1080p-cmd.dtsi
index 6f66e8e..aebc8b9 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-1080p-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-1080p-cmd.dtsi
@@ -16,50 +16,15 @@
qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
qcom,mdss-dsi-panel-destination = "display_1";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-panel-clockrate = <850000000>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1080>;
- qcom,mdss-dsi-panel-height = <1920>;
- qcom,mdss-dsi-h-front-porch = <0>;
- qcom,mdss-dsi-h-back-porch = <0>;
- qcom,mdss-dsi-h-pulse-width = <0>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <0>;
- qcom,mdss-dsi-v-front-porch = <0>;
- qcom,mdss-dsi-v-pulse-width = <0>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
qcom,mdss-pan-physical-width-dimension = <64>;
qcom,mdss-pan-physical-height-dimension = <117>;
- qcom,mdss-dsi-on-command = [
- 15 01 00 00 00 00 02 bb 10
- 15 01 00 00 00 00 02 b0 03
- 05 01 00 00 78 00 01 11
- 15 01 00 00 00 00 02 51 ff
- 15 01 00 00 00 00 02 53 24
- 15 01 00 00 00 00 02 ff 23
- 15 01 00 00 00 00 02 08 05
- 15 01 00 00 00 00 02 46 90
- 15 01 00 00 00 00 02 ff 10
- 15 01 00 00 00 00 02 ff f0
- 15 01 00 00 00 00 02 92 01
- 15 01 00 00 00 00 02 ff 10
- 15 01 00 00 00 00 02 35 00 /* enable TE generation */
- 05 01 00 00 28 00 01 29];
- qcom,mdss-dsi-off-command = [
- 05 01 00 00 10 00 01 28
- 05 01 00 00 40 00 01 10];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -76,5 +41,46 @@
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
+
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1080>;
+ qcom,mdss-dsi-panel-height = <1920>;
+ qcom,mdss-dsi-h-front-porch = <0>;
+ qcom,mdss-dsi-h-back-porch = <0>;
+ qcom,mdss-dsi-h-pulse-width = <0>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <0>;
+ qcom,mdss-dsi-v-front-porch = <0>;
+ qcom,mdss-dsi-v-pulse-width = <0>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-on-command = [
+ 15 01 00 00 00 00 02 bb 10
+ 15 01 00 00 00 00 02 b0 03
+ 05 01 00 00 78 00 01 11
+ 15 01 00 00 00 00 02 51 ff
+ 15 01 00 00 00 00 02 53 24
+ 15 01 00 00 00 00 02 ff 23
+ 15 01 00 00 00 00 02 08 05
+ 15 01 00 00 00 00 02 46 90
+ 15 01 00 00 00 00 02 ff 10
+ 15 01 00 00 00 00 02 ff f0
+ 15 01 00 00 00 00 02 92 01
+ 15 01 00 00 00 00 02 ff 10
+ /* enable TE generation */
+ 15 01 00 00 00 00 02 35 00
+ 05 01 00 00 28 00 01 29];
+ qcom,mdss-dsi-off-command = [
+ 05 01 00 00 10 00 01 28
+ 05 01 00 00 40 00 01 10];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-cmd.dtsi
index 4562f8c..ce849c6 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-cmd.dtsi
@@ -14,23 +14,10 @@
dsi_sharp_4k_dsc_cmd: qcom,mdss_dsi_sharp_4k_dsc_cmd {
qcom,mdss-dsi-panel-name = "Sharp 4k cmd mode dsc dsi panel";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1080>;
- qcom,mdss-dsi-panel-height = <3840>;
- qcom,mdss-dsi-h-front-porch = <30>;
- qcom,mdss-dsi-h-back-porch = <100>;
- qcom,mdss-dsi-h-pulse-width = <4>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <7>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <1>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -51,40 +38,61 @@
qcom,mdss-dsi-te-using-te-pin;
qcom,dcs-cmd-by-left;
qcom,mdss-dsi-tx-eot-append;
- qcom,mdss-dsi-panel-jitter = <0x8 0xa>;
-
qcom,adjust-timer-wakeup-ms = <1>;
- qcom,mdss-dsi-on-command = [
- 39 01 00 00 00 00 11 91 09 20 00 20 02 00 03 1c 04 21 00
- 0f 03 19 01 97
- 39 01 00 00 00 00 03 92 10 f0
- 15 01 00 00 00 00 02 90 03
- 15 01 00 00 00 00 02 03 01
- 39 01 00 00 00 00 06 f0 55 aa 52 08 04
- 15 01 00 00 00 00 02 c0 03
- 39 01 00 00 00 00 06 f0 55 aa 52 08 07
- 15 01 00 00 00 00 02 ef 01
- 39 01 00 00 00 00 06 f0 55 aa 52 08 00
- 15 01 00 00 00 00 02 b4 01
- 15 01 00 00 00 00 02 35 00
- 39 01 00 00 00 00 06 f0 55 aa 52 08 01
- 39 01 00 00 00 00 05 ff aa 55 a5 80
- 15 01 00 00 00 00 02 6f 01
- 15 01 00 00 00 00 02 f3 10
- 39 01 00 00 00 00 05 ff aa 55 a5 00
- 05 01 00 00 78 00 01 11 /* sleep out + delay 120ms */
- 05 01 00 00 78 00 01 29 /* display on + delay 120ms */
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1080>;
+ qcom,mdss-dsi-panel-height = <3840>;
+ qcom,mdss-dsi-h-front-porch = <30>;
+ qcom,mdss-dsi-h-back-porch = <100>;
+ qcom,mdss-dsi-h-pulse-width = <4>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <7>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-panel-jitter = <0x8 0xa>;
- qcom,compression-mode = "dsc";
- qcom,mdss-dsc-slice-height = <32>;
- qcom,mdss-dsc-slice-width = <1080>;
- qcom,mdss-dsc-slice-per-pkt = <1>;
- qcom,mdss-dsc-bit-per-component = <8>;
- qcom,mdss-dsc-bit-per-pixel = <8>;
- qcom,mdss-dsc-block-prediction-enable;
+ qcom,mdss-dsi-on-command = [
+ 39 01 00 00 00 00 11 91 09 20 00 20 02
+ 00 03 1c 04 21 00
+ 0f 03 19 01 97
+ 39 01 00 00 00 00 03 92 10 f0
+ 15 01 00 00 00 00 02 90 03
+ 15 01 00 00 00 00 02 03 01
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 04
+ 15 01 00 00 00 00 02 c0 03
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 07
+ 15 01 00 00 00 00 02 ef 01
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 00
+ 15 01 00 00 00 00 02 b4 01
+ 15 01 00 00 00 00 02 35 00
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 01
+ 39 01 00 00 00 00 05 ff aa 55 a5 80
+ 15 01 00 00 00 00 02 6f 01
+ 15 01 00 00 00 00 02 f3 10
+ 39 01 00 00 00 00 05 ff aa 55 a5 00
+ /* sleep out + delay 120ms */
+ 05 01 00 00 78 00 01 11
+ /* display on + delay 120ms */
+ 05 01 00 00 78 00 01 29
+ ];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command =
+ [05 01 00 00 78 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+
+ qcom,compression-mode = "dsc";
+ qcom,mdss-dsc-slice-height = <32>;
+ qcom,mdss-dsc-slice-width = <1080>;
+ qcom,mdss-dsc-slice-per-pkt = <1>;
+ qcom,mdss-dsc-bit-per-component = <8>;
+ qcom,mdss-dsc-bit-per-pixel = <8>;
+ qcom,mdss-dsc-block-prediction-enable;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-video.dtsi
index 7954856..d3411c8 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dsc-4k-video.dtsi
@@ -14,23 +14,10 @@
dsi_sharp_4k_dsc_video: qcom,mdss_dsi_sharp_4k_dsc_video {
qcom,mdss-dsi-panel-name = "Sharp 4k video mode dsc dsi panel";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1080>;
- qcom,mdss-dsi-panel-height = <3840>;
- qcom,mdss-dsi-h-front-porch = <30>;
- qcom,mdss-dsi-h-back-porch = <100>;
- qcom,mdss-dsi-h-pulse-width = <4>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <7>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <1>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -46,37 +33,59 @@
qcom,mdss-dsi-tx-eot-append;
qcom,adjust-timer-wakeup-ms = <1>;
- qcom,mdss-dsi-on-command = [
- 39 01 00 00 00 00 11 91 09 20 00 20 02 00 03 1c 04 21 00
- 0f 03 19 01 97
- 39 01 00 00 00 00 03 92 10 f0
- 15 01 00 00 00 00 02 90 03
- 15 01 00 00 00 00 02 03 01
- 39 01 00 00 00 00 06 f0 55 aa 52 08 04
- 15 01 00 00 00 00 02 c0 03
- 39 01 00 00 00 00 06 f0 55 aa 52 08 07
- 15 01 00 00 00 00 02 ef 01
- 39 01 00 00 00 00 06 f0 55 aa 52 08 00
- 15 01 00 00 00 00 02 b4 10
- 15 01 00 00 00 00 02 35 00
- 39 01 00 00 00 00 06 f0 55 aa 52 08 01
- 39 01 00 00 00 00 05 ff aa 55 a5 80
- 15 01 00 00 00 00 02 6f 01
- 15 01 00 00 00 00 02 f3 10
- 39 01 00 00 00 00 05 ff aa 55 a5 00
- 05 01 00 00 78 00 01 11 /* sleep out + delay 120ms */
- 05 01 00 00 78 00 01 29 /* display on + delay 120ms */
- ];
- qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1080>;
+ qcom,mdss-dsi-panel-height = <3840>;
+ qcom,mdss-dsi-h-front-porch = <30>;
+ qcom,mdss-dsi-h-back-porch = <100>;
+ qcom,mdss-dsi-h-pulse-width = <4>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <7>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
- qcom,compression-mode = "dsc";
- qcom,mdss-dsc-slice-height = <32>;
- qcom,mdss-dsc-slice-width = <1080>;
- qcom,mdss-dsc-slice-per-pkt = <1>;
- qcom,mdss-dsc-bit-per-component = <8>;
- qcom,mdss-dsc-bit-per-pixel = <8>;
- qcom,mdss-dsc-block-prediction-enable;
+ qcom,mdss-dsi-on-command = [
+ 39 01 00 00 00 00 11 91 09 20 00 20 02
+ 00 03 1c 04 21 00
+ 0f 03 19 01 97
+ 39 01 00 00 00 00 03 92 10 f0
+ 15 01 00 00 00 00 02 90 03
+ 15 01 00 00 00 00 02 03 01
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 04
+ 15 01 00 00 00 00 02 c0 03
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 07
+ 15 01 00 00 00 00 02 ef 01
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 00
+ 15 01 00 00 00 00 02 b4 10
+ 15 01 00 00 00 00 02 35 00
+ 39 01 00 00 00 00 06 f0 55 aa 52 08 01
+ 39 01 00 00 00 00 05 ff aa 55 a5 80
+ 15 01 00 00 00 00 02 6f 01
+ 15 01 00 00 00 00 02 f3 10
+ 39 01 00 00 00 00 05 ff aa 55 a5 00
+ /* sleep out + delay 120ms */
+ 05 01 00 00 78 00 01 11
+ /* display on + delay 120ms */
+ 05 01 00 00 78 00 01 29
+ ];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command =
+ [05 01 00 00 78 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+
+ qcom,compression-mode = "dsc";
+ qcom,mdss-dsc-slice-height = <32>;
+ qcom,mdss-dsc-slice-width = <1080>;
+ qcom,mdss-dsc-slice-per-pkt = <1>;
+ qcom,mdss-dsc-bit-per-component = <8>;
+ qcom,mdss-dsc-bit-per-pixel = <8>;
+ qcom,mdss-dsc-block-prediction-enable;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dualmipi-1080p-120hz.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dualmipi-1080p-120hz.dtsi
index 2071649..6dc621e 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dualmipi-1080p-120hz.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sharp-dualmipi-1080p-120hz.dtsi
@@ -15,595 +15,12 @@
qcom,mdss-dsi-panel-name =
"sharp 1080p 120hz dual dsi cmd mode panel";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <120>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <540>;
- qcom,mdss-dsi-panel-height = <1920>;
- qcom,mdss-dsi-h-front-porch = <28>;
- qcom,mdss-dsi-h-back-porch = <4>;
- qcom,mdss-dsi-h-pulse-width = <4>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <12>;
- qcom,mdss-dsi-v-front-porch = <12>;
- qcom,mdss-dsi-v-pulse-width = <2>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-reset-sequence = <1 20>, <0 1>, <1 10>;
- qcom,mdss-dsi-on-command = [15 01 00 00 00 00 02 ff 10
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 ba 07
- 15 01 00 00 00 00 02 c0 00
- 15 01 00 00 00 00 02 bb 10
- 15 01 00 00 00 00 02 d9 00
- 15 01 00 00 00 00 02 ef 70
- 15 01 00 00 00 00 02 f7 80
- 39 01 00 00 00 00 06 3b 03 0e 0c 08 1c
- 15 01 00 00 00 00 02 e9 0e
- 15 01 00 00 00 00 02 ea 0c
- 15 01 00 00 00 00 02 35 00
- 15 01 00 00 00 00 02 c0 00
- 15 01 00 00 00 00 02 ff 20
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 59 6a
- 15 01 00 00 00 00 02 0b 1b
- 15 01 00 00 00 00 02 61 f7
- 15 01 00 00 00 00 02 62 6c
- 15 01 00 00 00 00 02 00 01
- 15 01 00 00 00 00 02 01 55
- 15 01 00 00 00 00 02 04 c8
- 15 01 00 00 00 00 02 05 1a
- 15 01 00 00 00 00 02 0d 93
- 15 01 00 00 00 00 02 0e 93
- 15 01 00 00 00 00 02 0f 7e
- 15 01 00 00 00 00 02 06 69
- 15 01 00 00 00 00 02 07 bc
- 15 01 00 00 00 00 02 10 03
- 15 01 00 00 00 00 02 11 64
- 15 01 00 00 00 00 02 12 5a
- 15 01 00 00 00 00 02 13 40
- 15 01 00 00 00 00 02 14 40
- 15 01 00 00 00 00 02 15 00
- 15 01 00 00 00 00 02 33 13
- 15 01 00 00 00 00 02 5a 40
- 15 01 00 00 00 00 02 5b 40
- 15 01 00 00 00 00 02 5e 80
- 15 01 00 00 00 00 02 ff 24
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 80
- 15 01 00 00 00 00 02 14 80
- 15 01 00 00 00 00 02 01 80
- 15 01 00 00 00 00 02 15 80
- 15 01 00 00 00 00 02 02 80
- 15 01 00 00 00 00 02 16 80
- 15 01 00 00 00 00 02 03 0a
- 15 01 00 00 00 00 02 17 0c
- 15 01 00 00 00 00 02 04 06
- 15 01 00 00 00 00 02 18 08
- 15 01 00 00 00 00 02 05 80
- 15 01 00 00 00 00 02 19 80
- 15 01 00 00 00 00 02 06 80
- 15 01 00 00 00 00 02 1a 80
- 15 01 00 00 00 00 02 07 80
- 15 01 00 00 00 00 02 1b 80
- 15 01 00 00 00 00 02 08 80
- 15 01 00 00 00 00 02 1c 80
- 15 01 00 00 00 00 02 09 80
- 15 01 00 00 00 00 02 1d 80
- 15 01 00 00 00 00 02 0a 80
- 15 01 00 00 00 00 02 1e 80
- 15 01 00 00 00 00 02 0b 1a
- 15 01 00 00 00 00 02 1f 1b
- 15 01 00 00 00 00 02 0c 16
- 15 01 00 00 00 00 02 20 17
- 15 01 00 00 00 00 02 0d 1c
- 15 01 00 00 00 00 02 21 1d
- 15 01 00 00 00 00 02 0e 18
- 15 01 00 00 00 00 02 22 19
- 15 01 00 00 00 00 02 0f 0e
- 15 01 00 00 00 00 02 23 10
- 15 01 00 00 00 00 02 10 80
- 15 01 00 00 00 00 02 24 80
- 15 01 00 00 00 00 02 11 80
- 15 01 00 00 00 00 02 25 80
- 15 01 00 00 00 00 02 12 80
- 15 01 00 00 00 00 02 26 80
- 15 01 00 00 00 00 02 13 80
- 15 01 00 00 00 00 02 27 80
- 15 01 00 00 00 00 02 74 ff
- 15 01 00 00 00 00 02 75 ff
- 15 01 00 00 00 00 02 8d 00
- 15 01 00 00 00 00 02 8e 00
- 15 01 00 00 00 00 02 8f 9c
- 15 01 00 00 00 00 02 90 0c
- 15 01 00 00 00 00 02 91 0e
- 15 01 00 00 00 00 02 d6 00
- 15 01 00 00 00 00 02 d7 20
- 15 01 00 00 00 00 02 d8 00
- 15 01 00 00 00 00 02 d9 88
- 15 01 00 00 00 00 02 e5 05
- 15 01 00 00 00 00 02 e6 10
- 15 01 00 00 00 00 02 54 06
- 15 01 00 00 00 00 02 55 05
- 15 01 00 00 00 00 02 56 04
- 15 01 00 00 00 00 02 58 03
- 15 01 00 00 00 00 02 59 33
- 15 01 00 00 00 00 02 5a 33
- 15 01 00 00 00 00 02 5b 01
- 15 01 00 00 00 00 02 5c 00
- 15 01 00 00 00 00 02 5d 01
- 15 01 00 00 00 00 02 5e 0a
- 15 01 00 00 00 00 02 5f 0a
- 15 01 00 00 00 00 02 60 0a
- 15 01 00 00 00 00 02 61 0a
- 15 01 00 00 00 00 02 62 10
- 15 01 00 00 00 00 02 63 01
- 15 01 00 00 00 00 02 64 00
- 15 01 00 00 00 00 02 65 00
- 15 01 00 00 00 00 02 ef 00
- 15 01 00 00 00 00 02 f0 00
- 15 01 00 00 00 00 02 6d 20
- 15 01 00 00 00 00 02 66 44
- 15 01 00 00 00 00 02 68 01
- 15 01 00 00 00 00 02 69 00
- 15 01 00 00 00 00 02 67 11
- 15 01 00 00 00 00 02 6a 06
- 15 01 00 00 00 00 02 6b 31
- 15 01 00 00 00 00 02 6c 90
- 15 01 00 00 00 00 02 ab c3
- 15 01 00 00 00 00 02 b1 49
- 15 01 00 00 00 00 02 aa 80
- 15 01 00 00 00 00 02 b0 90
- 15 01 00 00 00 00 02 b2 a4
- 15 01 00 00 00 00 02 b3 00
- 15 01 00 00 00 00 02 b4 23
- 15 01 00 00 00 00 02 b5 00
- 15 01 00 00 00 00 02 b6 00
- 15 01 00 00 00 00 02 b7 00
- 15 01 00 00 00 00 02 b8 00
- 15 01 00 00 00 00 02 b9 00
- 15 01 00 00 00 00 02 ba 00
- 15 01 00 00 00 00 02 bb 00
- 15 01 00 00 00 00 02 bc 00
- 15 01 00 00 00 00 02 bd 00
- 15 01 00 00 00 00 02 be 00
- 15 01 00 00 00 00 02 bf 00
- 15 01 00 00 00 00 02 c0 00
- 15 01 00 00 00 00 02 c7 40
- 15 01 00 00 00 00 02 c9 00
- 15 01 00 00 00 00 02 c1 2a
- 15 01 00 00 00 00 02 c2 2a
- 15 01 00 00 00 00 02 c3 00
- 15 01 00 00 00 00 02 c4 00
- 15 01 00 00 00 00 02 c5 00
- 15 01 00 00 00 00 02 c6 00
- 15 01 00 00 00 00 02 c8 ab
- 15 01 00 00 00 00 02 ca 00
- 15 01 00 00 00 00 02 cb 00
- 15 01 00 00 00 00 02 cc 20
- 15 01 00 00 00 00 02 cd 40
- 15 01 00 00 00 00 02 ce a8
- 15 01 00 00 00 00 02 cf a8
- 15 01 00 00 00 00 02 d0 00
- 15 01 00 00 00 00 02 d1 00
- 15 01 00 00 00 00 02 d2 00
- 15 01 00 00 00 00 02 d3 00
- 15 01 00 00 00 00 02 af 01
- 15 01 00 00 00 00 02 a4 1e
- 15 01 00 00 00 00 02 95 41
- 15 01 00 00 00 00 02 96 03
- 15 01 00 00 00 00 02 98 00
- 15 01 00 00 00 00 02 9a 9a
- 15 01 00 00 00 00 02 9b 03
- 15 01 00 00 00 00 02 9d 80
- 15 01 00 00 00 00 02 ff 26
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 fa d0
- 15 01 00 00 00 00 02 6b 80
- 15 01 00 00 00 00 02 6c 5c
- 15 01 00 00 00 00 02 6d 0c
- 15 01 00 00 00 00 02 6e 0e
- 15 01 00 00 00 00 02 58 01
- 15 01 00 00 00 00 02 59 15
- 15 01 00 00 00 00 02 5a 01
- 15 01 00 00 00 00 02 5b 00
- 15 01 00 00 00 00 02 5c 01
- 15 01 00 00 00 00 02 5d 2b
- 15 01 00 00 00 00 02 74 00
- 15 01 00 00 00 00 02 75 ba
- 15 01 00 00 00 00 02 81 0a
- 15 01 00 00 00 00 02 4e 81
- 15 01 00 00 00 00 02 4f 83
- 15 01 00 00 00 00 02 51 00
- 15 01 00 00 00 00 02 53 4d
- 15 01 00 00 00 00 02 54 03
- 15 01 00 00 00 00 02 ff e0
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 b2 81
- 15 01 00 00 00 00 02 62 28
- 15 01 00 00 00 00 02 a2 09
- 15 01 00 00 00 00 02 b3 01
- 15 01 00 00 00 00 02 ed 00
- 15 01 00 00 00 00 02 ff 10
- 05 01 00 00 78 00 01 11
- 15 01 00 00 00 00 02 ff 20
- 15 01 00 00 00 00 02 75 00
- 15 01 00 00 00 00 02 76 71
- 15 01 00 00 00 00 02 77 00
- 15 01 00 00 00 00 02 78 84
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 7a a5
- 15 01 00 00 00 00 02 7b 00
- 15 01 00 00 00 00 02 7c bb
- 15 01 00 00 00 00 02 7d 00
- 15 01 00 00 00 00 02 7e ce
- 15 01 00 00 00 00 02 7f 00
- 15 01 00 00 00 00 02 80 e0
- 15 01 00 00 00 00 02 81 00
- 15 01 00 00 00 00 02 82 ef
- 15 01 00 00 00 00 02 83 00
- 15 01 00 00 00 00 02 84 ff
- 15 01 00 00 00 00 02 85 01
- 15 01 00 00 00 00 02 86 0b
- 15 01 00 00 00 00 02 87 01
- 15 01 00 00 00 00 02 88 38
- 15 01 00 00 00 00 02 89 01
- 15 01 00 00 00 00 02 8a 5b
- 15 01 00 00 00 00 02 8b 01
- 15 01 00 00 00 00 02 8c 95
- 15 01 00 00 00 00 02 8d 01
- 15 01 00 00 00 00 02 8e c4
- 15 01 00 00 00 00 02 8f 02
- 15 01 00 00 00 00 02 90 0d
- 15 01 00 00 00 00 02 91 02
- 15 01 00 00 00 00 02 92 4a
- 15 01 00 00 00 00 02 93 02
- 15 01 00 00 00 00 02 94 4c
- 15 01 00 00 00 00 02 95 02
- 15 01 00 00 00 00 02 96 85
- 15 01 00 00 00 00 02 97 02
- 15 01 00 00 00 00 02 98 c3
- 15 01 00 00 00 00 02 99 02
- 15 01 00 00 00 00 02 9a e9
- 15 01 00 00 00 00 02 9b 03
- 15 01 00 00 00 00 02 9c 16
- 15 01 00 00 00 00 02 9d 03
- 15 01 00 00 00 00 02 9e 34
- 15 01 00 00 00 00 02 9f 03
- 15 01 00 00 00 00 02 a0 56
- 15 01 00 00 00 00 02 a2 03
- 15 01 00 00 00 00 02 a3 62
- 15 01 00 00 00 00 02 a4 03
- 15 01 00 00 00 00 02 a5 6c
- 15 01 00 00 00 00 02 a6 03
- 15 01 00 00 00 00 02 a7 74
- 15 01 00 00 00 00 02 a9 03
- 15 01 00 00 00 00 02 aa 80
- 15 01 00 00 00 00 02 ab 03
- 15 01 00 00 00 00 02 ac 89
- 15 01 00 00 00 00 02 ad 03
- 15 01 00 00 00 00 02 ae 8b
- 15 01 00 00 00 00 02 af 03
- 15 01 00 00 00 00 02 b0 8d
- 15 01 00 00 00 00 02 b1 03
- 15 01 00 00 00 00 02 b2 8e
- 15 01 00 00 00 00 02 b3 00
- 15 01 00 00 00 00 02 b4 71
- 15 01 00 00 00 00 02 b5 00
- 15 01 00 00 00 00 02 b6 84
- 15 01 00 00 00 00 02 b7 00
- 15 01 00 00 00 00 02 b8 a5
- 15 01 00 00 00 00 02 b9 00
- 15 01 00 00 00 00 02 ba bb
- 15 01 00 00 00 00 02 bb 00
- 15 01 00 00 00 00 02 bc ce
- 15 01 00 00 00 00 02 bd 00
- 15 01 00 00 00 00 02 be e0
- 15 01 00 00 00 00 02 bf 00
- 15 01 00 00 00 00 02 c0 ef
- 15 01 00 00 00 00 02 c1 00
- 15 01 00 00 00 00 02 c2 ff
- 15 01 00 00 00 00 02 c3 01
- 15 01 00 00 00 00 02 c4 0b
- 15 01 00 00 00 00 02 c5 01
- 15 01 00 00 00 00 02 c6 38
- 15 01 00 00 00 00 02 c7 01
- 15 01 00 00 00 00 02 c8 5b
- 15 01 00 00 00 00 02 c9 01
- 15 01 00 00 00 00 02 ca 95
- 15 01 00 00 00 00 02 cb 01
- 15 01 00 00 00 00 02 cc c4
- 15 01 00 00 00 00 02 cd 02
- 15 01 00 00 00 00 02 ce 0d
- 15 01 00 00 00 00 02 cf 02
- 15 01 00 00 00 00 02 d0 4a
- 15 01 00 00 00 00 02 d1 02
- 15 01 00 00 00 00 02 d2 4c
- 15 01 00 00 00 00 02 d3 02
- 15 01 00 00 00 00 02 d4 85
- 15 01 00 00 00 00 02 d5 02
- 15 01 00 00 00 00 02 d6 c3
- 15 01 00 00 00 00 02 d7 02
- 15 01 00 00 00 00 02 d8 e9
- 15 01 00 00 00 00 02 d9 03
- 15 01 00 00 00 00 02 da 16
- 15 01 00 00 00 00 02 db 03
- 15 01 00 00 00 00 02 dc 34
- 15 01 00 00 00 00 02 dd 03
- 15 01 00 00 00 00 02 de 56
- 15 01 00 00 00 00 02 df 03
- 15 01 00 00 00 00 02 e0 62
- 15 01 00 00 00 00 02 e1 03
- 15 01 00 00 00 00 02 e2 6c
- 15 01 00 00 00 00 02 e3 03
- 15 01 00 00 00 00 02 e4 74
- 15 01 00 00 00 00 02 e5 03
- 15 01 00 00 00 00 02 e6 80
- 15 01 00 00 00 00 02 e7 03
- 15 01 00 00 00 00 02 e8 89
- 15 01 00 00 00 00 02 e9 03
- 15 01 00 00 00 00 02 ea 8b
- 15 01 00 00 00 00 02 eb 03
- 15 01 00 00 00 00 02 ec 8d
- 15 01 00 00 00 00 02 ed 03
- 15 01 00 00 00 00 02 ee 8e
- 15 01 00 00 00 00 02 ef 00
- 15 01 00 00 00 00 02 f0 71
- 15 01 00 00 00 00 02 f1 00
- 15 01 00 00 00 00 02 f2 84
- 15 01 00 00 00 00 02 f3 00
- 15 01 00 00 00 00 02 f4 a5
- 15 01 00 00 00 00 02 f5 00
- 15 01 00 00 00 00 02 f6 bb
- 15 01 00 00 00 00 02 f7 00
- 15 01 00 00 00 00 02 f8 ce
- 15 01 00 00 00 00 02 f9 00
- 15 01 00 00 00 00 02 fa e0
- 15 01 00 00 00 00 02 ff 21
- 15 01 00 00 00 00 02 fb 01
- 15 01 00 00 00 00 02 00 00
- 15 01 00 00 00 00 02 01 ef
- 15 01 00 00 00 00 02 02 00
- 15 01 00 00 00 00 02 03 ff
- 15 01 00 00 00 00 02 04 01
- 15 01 00 00 00 00 02 05 0b
- 15 01 00 00 00 00 02 06 01
- 15 01 00 00 00 00 02 07 38
- 15 01 00 00 00 00 02 08 01
- 15 01 00 00 00 00 02 09 5b
- 15 01 00 00 00 00 02 0a 01
- 15 01 00 00 00 00 02 0b 95
- 15 01 00 00 00 00 02 0c 01
- 15 01 00 00 00 00 02 0d c4
- 15 01 00 00 00 00 02 0e 02
- 15 01 00 00 00 00 02 0f 0d
- 15 01 00 00 00 00 02 10 02
- 15 01 00 00 00 00 02 11 4a
- 15 01 00 00 00 00 02 12 02
- 15 01 00 00 00 00 02 13 4c
- 15 01 00 00 00 00 02 14 02
- 15 01 00 00 00 00 02 15 85
- 15 01 00 00 00 00 02 16 02
- 15 01 00 00 00 00 02 17 c3
- 15 01 00 00 00 00 02 18 02
- 15 01 00 00 00 00 02 19 e9
- 15 01 00 00 00 00 02 1a 03
- 15 01 00 00 00 00 02 1b 16
- 15 01 00 00 00 00 02 1c 03
- 15 01 00 00 00 00 02 1d 34
- 15 01 00 00 00 00 02 1e 03
- 15 01 00 00 00 00 02 1f 56
- 15 01 00 00 00 00 02 20 03
- 15 01 00 00 00 00 02 21 62
- 15 01 00 00 00 00 02 22 03
- 15 01 00 00 00 00 02 23 6c
- 15 01 00 00 00 00 02 24 03
- 15 01 00 00 00 00 02 25 74
- 15 01 00 00 00 00 02 26 03
- 15 01 00 00 00 00 02 27 80
- 15 01 00 00 00 00 02 28 03
- 15 01 00 00 00 00 02 29 89
- 15 01 00 00 00 00 02 2a 03
- 15 01 00 00 00 00 02 2b 8b
- 15 01 00 00 00 00 02 2d 03
- 15 01 00 00 00 00 02 2f 8d
- 15 01 00 00 00 00 02 30 03
- 15 01 00 00 00 00 02 31 8e
- 15 01 00 00 00 00 02 32 00
- 15 01 00 00 00 00 02 33 71
- 15 01 00 00 00 00 02 34 00
- 15 01 00 00 00 00 02 35 84
- 15 01 00 00 00 00 02 36 00
- 15 01 00 00 00 00 02 37 a5
- 15 01 00 00 00 00 02 38 00
- 15 01 00 00 00 00 02 39 bb
- 15 01 00 00 00 00 02 3a 00
- 15 01 00 00 00 00 02 3b ce
- 15 01 00 00 00 00 02 3d 00
- 15 01 00 00 00 00 02 3f e0
- 15 01 00 00 00 00 02 40 00
- 15 01 00 00 00 00 02 41 ef
- 15 01 00 00 00 00 02 42 00
- 15 01 00 00 00 00 02 43 ff
- 15 01 00 00 00 00 02 44 01
- 15 01 00 00 00 00 02 45 0b
- 15 01 00 00 00 00 02 46 01
- 15 01 00 00 00 00 02 47 38
- 15 01 00 00 00 00 02 48 01
- 15 01 00 00 00 00 02 49 5b
- 15 01 00 00 00 00 02 4a 01
- 15 01 00 00 00 00 02 4b 95
- 15 01 00 00 00 00 02 4c 01
- 15 01 00 00 00 00 02 4d c4
- 15 01 00 00 00 00 02 4e 02
- 15 01 00 00 00 00 02 4f 0d
- 15 01 00 00 00 00 02 50 02
- 15 01 00 00 00 00 02 51 4a
- 15 01 00 00 00 00 02 52 02
- 15 01 00 00 00 00 02 53 4c
- 15 01 00 00 00 00 02 54 02
- 15 01 00 00 00 00 02 55 85
- 15 01 00 00 00 00 02 56 02
- 15 01 00 00 00 00 02 58 c3
- 15 01 00 00 00 00 02 59 02
- 15 01 00 00 00 00 02 5a e9
- 15 01 00 00 00 00 02 5b 03
- 15 01 00 00 00 00 02 5c 16
- 15 01 00 00 00 00 02 5d 03
- 15 01 00 00 00 00 02 5e 34
- 15 01 00 00 00 00 02 5f 03
- 15 01 00 00 00 00 02 60 56
- 15 01 00 00 00 00 02 61 03
- 15 01 00 00 00 00 02 62 62
- 15 01 00 00 00 00 02 63 03
- 15 01 00 00 00 00 02 64 6c
- 15 01 00 00 00 00 02 65 03
- 15 01 00 00 00 00 02 66 74
- 15 01 00 00 00 00 02 67 03
- 15 01 00 00 00 00 02 68 80
- 15 01 00 00 00 00 02 69 03
- 15 01 00 00 00 00 02 6a 89
- 15 01 00 00 00 00 02 6b 03
- 15 01 00 00 00 00 02 6c 8b
- 15 01 00 00 00 00 02 6d 03
- 15 01 00 00 00 00 02 6e 8d
- 15 01 00 00 00 00 02 6f 03
- 15 01 00 00 00 00 02 70 8e
- 15 01 00 00 00 00 02 71 00
- 15 01 00 00 00 00 02 72 71
- 15 01 00 00 00 00 02 73 00
- 15 01 00 00 00 00 02 74 84
- 15 01 00 00 00 00 02 75 00
- 15 01 00 00 00 00 02 76 a5
- 15 01 00 00 00 00 02 77 00
- 15 01 00 00 00 00 02 78 bb
- 15 01 00 00 00 00 02 79 00
- 15 01 00 00 00 00 02 7a ce
- 15 01 00 00 00 00 02 7b 00
- 15 01 00 00 00 00 02 7c e0
- 15 01 00 00 00 00 02 7d 00
- 15 01 00 00 00 00 02 7e ef
- 15 01 00 00 00 00 02 7f 00
- 15 01 00 00 00 00 02 80 ff
- 15 01 00 00 00 00 02 81 01
- 15 01 00 00 00 00 02 82 0b
- 15 01 00 00 00 00 02 83 01
- 15 01 00 00 00 00 02 84 38
- 15 01 00 00 00 00 02 85 01
- 15 01 00 00 00 00 02 86 5b
- 15 01 00 00 00 00 02 87 01
- 15 01 00 00 00 00 02 88 95
- 15 01 00 00 00 00 02 89 01
- 15 01 00 00 00 00 02 8a c4
- 15 01 00 00 00 00 02 8b 02
- 15 01 00 00 00 00 02 8c 0d
- 15 01 00 00 00 00 02 8d 02
- 15 01 00 00 00 00 02 8e 4a
- 15 01 00 00 00 00 02 8f 02
- 15 01 00 00 00 00 02 90 4c
- 15 01 00 00 00 00 02 91 02
- 15 01 00 00 00 00 02 92 85
- 15 01 00 00 00 00 02 93 02
- 15 01 00 00 00 00 02 94 c3
- 15 01 00 00 00 00 02 95 02
- 15 01 00 00 00 00 02 96 e9
- 15 01 00 00 00 00 02 97 03
- 15 01 00 00 00 00 02 98 16
- 15 01 00 00 00 00 02 99 03
- 15 01 00 00 00 00 02 9a 34
- 15 01 00 00 00 00 02 9b 03
- 15 01 00 00 00 00 02 9c 56
- 15 01 00 00 00 00 02 9d 03
- 15 01 00 00 00 00 02 9e 62
- 15 01 00 00 00 00 02 9f 03
- 15 01 00 00 00 00 02 a0 6c
- 15 01 00 00 00 00 02 a2 03
- 15 01 00 00 00 00 02 a3 74
- 15 01 00 00 00 00 02 a4 03
- 15 01 00 00 00 00 02 a5 80
- 15 01 00 00 00 00 02 a6 03
- 15 01 00 00 00 00 02 a7 89
- 15 01 00 00 00 00 02 a9 03
- 15 01 00 00 00 00 02 aa 8b
- 15 01 00 00 00 00 02 ab 03
- 15 01 00 00 00 00 02 ac 8d
- 15 01 00 00 00 00 02 ad 03
- 15 01 00 00 00 00 02 ae 8e
- 15 01 00 00 00 00 02 af 00
- 15 01 00 00 00 00 02 b0 71
- 15 01 00 00 00 00 02 b1 00
- 15 01 00 00 00 00 02 b2 84
- 15 01 00 00 00 00 02 b3 00
- 15 01 00 00 00 00 02 b4 a5
- 15 01 00 00 00 00 02 b5 00
- 15 01 00 00 00 00 02 b6 bb
- 15 01 00 00 00 00 02 b7 00
- 15 01 00 00 00 00 02 b8 ce
- 15 01 00 00 00 00 02 b9 00
- 15 01 00 00 00 00 02 ba e0
- 15 01 00 00 00 00 02 bb 00
- 15 01 00 00 00 00 02 bc ef
- 15 01 00 00 00 00 02 bd 00
- 15 01 00 00 00 00 02 be ff
- 15 01 00 00 00 00 02 bf 01
- 15 01 00 00 00 00 02 c0 0b
- 15 01 00 00 00 00 02 c1 01
- 15 01 00 00 00 00 02 c2 38
- 15 01 00 00 00 00 02 c3 01
- 15 01 00 00 00 00 02 c4 5b
- 15 01 00 00 00 00 02 c5 01
- 15 01 00 00 00 00 02 c6 95
- 15 01 00 00 00 00 02 c7 01
- 15 01 00 00 00 00 02 c8 c4
- 15 01 00 00 00 00 02 c9 02
- 15 01 00 00 00 00 02 ca 0d
- 15 01 00 00 00 00 02 cb 02
- 15 01 00 00 00 00 02 cc 4a
- 15 01 00 00 00 00 02 cd 02
- 15 01 00 00 00 00 02 ce 4c
- 15 01 00 00 00 00 02 cf 02
- 15 01 00 00 00 00 02 d0 85
- 15 01 00 00 00 00 02 d1 02
- 15 01 00 00 00 00 02 d2 c3
- 15 01 00 00 00 00 02 d3 02
- 15 01 00 00 00 00 02 d4 e9
- 15 01 00 00 00 00 02 d5 03
- 15 01 00 00 00 00 02 d6 16
- 15 01 00 00 00 00 02 d7 03
- 15 01 00 00 00 00 02 d8 34
- 15 01 00 00 00 00 02 d9 03
- 15 01 00 00 00 00 02 da 56
- 15 01 00 00 00 00 02 db 03
- 15 01 00 00 00 00 02 dc 62
- 15 01 00 00 00 00 02 dd 03
- 15 01 00 00 00 00 02 de 6c
- 15 01 00 00 00 00 02 df 03
- 15 01 00 00 00 00 02 e0 74
- 15 01 00 00 00 00 02 e1 03
- 15 01 00 00 00 00 02 e2 80
- 15 01 00 00 00 00 02 e3 03
- 15 01 00 00 00 00 02 e4 89
- 15 01 00 00 00 00 02 e5 03
- 15 01 00 00 00 00 02 e6 8b
- 15 01 00 00 00 00 02 e7 03
- 15 01 00 00 00 00 02 e8 8d
- 15 01 00 00 00 00 02 e9 03
- 15 01 00 00 00 00 02 ea 8e
- 15 01 00 00 00 00 02 FF 10
- 05 01 00 00 00 00 01 29];
- qcom,mdss-dsi-off-command = [15 01 00 00 00 00 02 ff 10
- 05 01 00 00 10 00 01 28
- 15 01 00 00 00 00 02 b0 00
- 05 01 00 00 40 00 01 10
- 15 01 00 00 00 00 02 4f 01];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -623,10 +40,594 @@
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
- qcom,config-select = <&dsi_dual_sharp_cmd_config0>;
-
- dsi_dual_sharp_cmd_config0: config0 {
- qcom,split-mode = "dualctl-split";
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <540>;
+ qcom,mdss-dsi-panel-height = <1920>;
+ qcom,mdss-dsi-h-front-porch = <28>;
+ qcom,mdss-dsi-h-back-porch = <4>;
+ qcom,mdss-dsi-h-pulse-width = <4>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <12>;
+ qcom,mdss-dsi-v-front-porch = <12>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-panel-framerate = <120>;
+ qcom,mdss-dsi-on-command =
+ [15 01 00 00 00 00 02 ff 10
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 ba 07
+ 15 01 00 00 00 00 02 c0 00
+ 15 01 00 00 00 00 02 bb 10
+ 15 01 00 00 00 00 02 d9 00
+ 15 01 00 00 00 00 02 ef 70
+ 15 01 00 00 00 00 02 f7 80
+ 39 01 00 00 00 00 06 3b 03 0e 0c 08 1c
+ 15 01 00 00 00 00 02 e9 0e
+ 15 01 00 00 00 00 02 ea 0c
+ 15 01 00 00 00 00 02 35 00
+ 15 01 00 00 00 00 02 c0 00
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 59 6a
+ 15 01 00 00 00 00 02 0b 1b
+ 15 01 00 00 00 00 02 61 f7
+ 15 01 00 00 00 00 02 62 6c
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 04 c8
+ 15 01 00 00 00 00 02 05 1a
+ 15 01 00 00 00 00 02 0d 93
+ 15 01 00 00 00 00 02 0e 93
+ 15 01 00 00 00 00 02 0f 7e
+ 15 01 00 00 00 00 02 06 69
+ 15 01 00 00 00 00 02 07 bc
+ 15 01 00 00 00 00 02 10 03
+ 15 01 00 00 00 00 02 11 64
+ 15 01 00 00 00 00 02 12 5a
+ 15 01 00 00 00 00 02 13 40
+ 15 01 00 00 00 00 02 14 40
+ 15 01 00 00 00 00 02 15 00
+ 15 01 00 00 00 00 02 33 13
+ 15 01 00 00 00 00 02 5a 40
+ 15 01 00 00 00 00 02 5b 40
+ 15 01 00 00 00 00 02 5e 80
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 80
+ 15 01 00 00 00 00 02 14 80
+ 15 01 00 00 00 00 02 01 80
+ 15 01 00 00 00 00 02 15 80
+ 15 01 00 00 00 00 02 02 80
+ 15 01 00 00 00 00 02 16 80
+ 15 01 00 00 00 00 02 03 0a
+ 15 01 00 00 00 00 02 17 0c
+ 15 01 00 00 00 00 02 04 06
+ 15 01 00 00 00 00 02 18 08
+ 15 01 00 00 00 00 02 05 80
+ 15 01 00 00 00 00 02 19 80
+ 15 01 00 00 00 00 02 06 80
+ 15 01 00 00 00 00 02 1a 80
+ 15 01 00 00 00 00 02 07 80
+ 15 01 00 00 00 00 02 1b 80
+ 15 01 00 00 00 00 02 08 80
+ 15 01 00 00 00 00 02 1c 80
+ 15 01 00 00 00 00 02 09 80
+ 15 01 00 00 00 00 02 1d 80
+ 15 01 00 00 00 00 02 0a 80
+ 15 01 00 00 00 00 02 1e 80
+ 15 01 00 00 00 00 02 0b 1a
+ 15 01 00 00 00 00 02 1f 1b
+ 15 01 00 00 00 00 02 0c 16
+ 15 01 00 00 00 00 02 20 17
+ 15 01 00 00 00 00 02 0d 1c
+ 15 01 00 00 00 00 02 21 1d
+ 15 01 00 00 00 00 02 0e 18
+ 15 01 00 00 00 00 02 22 19
+ 15 01 00 00 00 00 02 0f 0e
+ 15 01 00 00 00 00 02 23 10
+ 15 01 00 00 00 00 02 10 80
+ 15 01 00 00 00 00 02 24 80
+ 15 01 00 00 00 00 02 11 80
+ 15 01 00 00 00 00 02 25 80
+ 15 01 00 00 00 00 02 12 80
+ 15 01 00 00 00 00 02 26 80
+ 15 01 00 00 00 00 02 13 80
+ 15 01 00 00 00 00 02 27 80
+ 15 01 00 00 00 00 02 74 ff
+ 15 01 00 00 00 00 02 75 ff
+ 15 01 00 00 00 00 02 8d 00
+ 15 01 00 00 00 00 02 8e 00
+ 15 01 00 00 00 00 02 8f 9c
+ 15 01 00 00 00 00 02 90 0c
+ 15 01 00 00 00 00 02 91 0e
+ 15 01 00 00 00 00 02 d6 00
+ 15 01 00 00 00 00 02 d7 20
+ 15 01 00 00 00 00 02 d8 00
+ 15 01 00 00 00 00 02 d9 88
+ 15 01 00 00 00 00 02 e5 05
+ 15 01 00 00 00 00 02 e6 10
+ 15 01 00 00 00 00 02 54 06
+ 15 01 00 00 00 00 02 55 05
+ 15 01 00 00 00 00 02 56 04
+ 15 01 00 00 00 00 02 58 03
+ 15 01 00 00 00 00 02 59 33
+ 15 01 00 00 00 00 02 5a 33
+ 15 01 00 00 00 00 02 5b 01
+ 15 01 00 00 00 00 02 5c 00
+ 15 01 00 00 00 00 02 5d 01
+ 15 01 00 00 00 00 02 5e 0a
+ 15 01 00 00 00 00 02 5f 0a
+ 15 01 00 00 00 00 02 60 0a
+ 15 01 00 00 00 00 02 61 0a
+ 15 01 00 00 00 00 02 62 10
+ 15 01 00 00 00 00 02 63 01
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 65 00
+ 15 01 00 00 00 00 02 ef 00
+ 15 01 00 00 00 00 02 f0 00
+ 15 01 00 00 00 00 02 6d 20
+ 15 01 00 00 00 00 02 66 44
+ 15 01 00 00 00 00 02 68 01
+ 15 01 00 00 00 00 02 69 00
+ 15 01 00 00 00 00 02 67 11
+ 15 01 00 00 00 00 02 6a 06
+ 15 01 00 00 00 00 02 6b 31
+ 15 01 00 00 00 00 02 6c 90
+ 15 01 00 00 00 00 02 ab c3
+ 15 01 00 00 00 00 02 b1 49
+ 15 01 00 00 00 00 02 aa 80
+ 15 01 00 00 00 00 02 b0 90
+ 15 01 00 00 00 00 02 b2 a4
+ 15 01 00 00 00 00 02 b3 00
+ 15 01 00 00 00 00 02 b4 23
+ 15 01 00 00 00 00 02 b5 00
+ 15 01 00 00 00 00 02 b6 00
+ 15 01 00 00 00 00 02 b7 00
+ 15 01 00 00 00 00 02 b8 00
+ 15 01 00 00 00 00 02 b9 00
+ 15 01 00 00 00 00 02 ba 00
+ 15 01 00 00 00 00 02 bb 00
+ 15 01 00 00 00 00 02 bc 00
+ 15 01 00 00 00 00 02 bd 00
+ 15 01 00 00 00 00 02 be 00
+ 15 01 00 00 00 00 02 bf 00
+ 15 01 00 00 00 00 02 c0 00
+ 15 01 00 00 00 00 02 c7 40
+ 15 01 00 00 00 00 02 c9 00
+ 15 01 00 00 00 00 02 c1 2a
+ 15 01 00 00 00 00 02 c2 2a
+ 15 01 00 00 00 00 02 c3 00
+ 15 01 00 00 00 00 02 c4 00
+ 15 01 00 00 00 00 02 c5 00
+ 15 01 00 00 00 00 02 c6 00
+ 15 01 00 00 00 00 02 c8 ab
+ 15 01 00 00 00 00 02 ca 00
+ 15 01 00 00 00 00 02 cb 00
+ 15 01 00 00 00 00 02 cc 20
+ 15 01 00 00 00 00 02 cd 40
+ 15 01 00 00 00 00 02 ce a8
+ 15 01 00 00 00 00 02 cf a8
+ 15 01 00 00 00 00 02 d0 00
+ 15 01 00 00 00 00 02 d1 00
+ 15 01 00 00 00 00 02 d2 00
+ 15 01 00 00 00 00 02 d3 00
+ 15 01 00 00 00 00 02 af 01
+ 15 01 00 00 00 00 02 a4 1e
+ 15 01 00 00 00 00 02 95 41
+ 15 01 00 00 00 00 02 96 03
+ 15 01 00 00 00 00 02 98 00
+ 15 01 00 00 00 00 02 9a 9a
+ 15 01 00 00 00 00 02 9b 03
+ 15 01 00 00 00 00 02 9d 80
+ 15 01 00 00 00 00 02 ff 26
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 fa d0
+ 15 01 00 00 00 00 02 6b 80
+ 15 01 00 00 00 00 02 6c 5c
+ 15 01 00 00 00 00 02 6d 0c
+ 15 01 00 00 00 00 02 6e 0e
+ 15 01 00 00 00 00 02 58 01
+ 15 01 00 00 00 00 02 59 15
+ 15 01 00 00 00 00 02 5a 01
+ 15 01 00 00 00 00 02 5b 00
+ 15 01 00 00 00 00 02 5c 01
+ 15 01 00 00 00 00 02 5d 2b
+ 15 01 00 00 00 00 02 74 00
+ 15 01 00 00 00 00 02 75 ba
+ 15 01 00 00 00 00 02 81 0a
+ 15 01 00 00 00 00 02 4e 81
+ 15 01 00 00 00 00 02 4f 83
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 53 4d
+ 15 01 00 00 00 00 02 54 03
+ 15 01 00 00 00 00 02 ff e0
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 b2 81
+ 15 01 00 00 00 00 02 62 28
+ 15 01 00 00 00 00 02 a2 09
+ 15 01 00 00 00 00 02 b3 01
+ 15 01 00 00 00 00 02 ed 00
+ 15 01 00 00 00 00 02 ff 10
+ 05 01 00 00 78 00 01 11
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 75 00
+ 15 01 00 00 00 00 02 76 71
+ 15 01 00 00 00 00 02 77 00
+ 15 01 00 00 00 00 02 78 84
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 7a a5
+ 15 01 00 00 00 00 02 7b 00
+ 15 01 00 00 00 00 02 7c bb
+ 15 01 00 00 00 00 02 7d 00
+ 15 01 00 00 00 00 02 7e ce
+ 15 01 00 00 00 00 02 7f 00
+ 15 01 00 00 00 00 02 80 e0
+ 15 01 00 00 00 00 02 81 00
+ 15 01 00 00 00 00 02 82 ef
+ 15 01 00 00 00 00 02 83 00
+ 15 01 00 00 00 00 02 84 ff
+ 15 01 00 00 00 00 02 85 01
+ 15 01 00 00 00 00 02 86 0b
+ 15 01 00 00 00 00 02 87 01
+ 15 01 00 00 00 00 02 88 38
+ 15 01 00 00 00 00 02 89 01
+ 15 01 00 00 00 00 02 8a 5b
+ 15 01 00 00 00 00 02 8b 01
+ 15 01 00 00 00 00 02 8c 95
+ 15 01 00 00 00 00 02 8d 01
+ 15 01 00 00 00 00 02 8e c4
+ 15 01 00 00 00 00 02 8f 02
+ 15 01 00 00 00 00 02 90 0d
+ 15 01 00 00 00 00 02 91 02
+ 15 01 00 00 00 00 02 92 4a
+ 15 01 00 00 00 00 02 93 02
+ 15 01 00 00 00 00 02 94 4c
+ 15 01 00 00 00 00 02 95 02
+ 15 01 00 00 00 00 02 96 85
+ 15 01 00 00 00 00 02 97 02
+ 15 01 00 00 00 00 02 98 c3
+ 15 01 00 00 00 00 02 99 02
+ 15 01 00 00 00 00 02 9a e9
+ 15 01 00 00 00 00 02 9b 03
+ 15 01 00 00 00 00 02 9c 16
+ 15 01 00 00 00 00 02 9d 03
+ 15 01 00 00 00 00 02 9e 34
+ 15 01 00 00 00 00 02 9f 03
+ 15 01 00 00 00 00 02 a0 56
+ 15 01 00 00 00 00 02 a2 03
+ 15 01 00 00 00 00 02 a3 62
+ 15 01 00 00 00 00 02 a4 03
+ 15 01 00 00 00 00 02 a5 6c
+ 15 01 00 00 00 00 02 a6 03
+ 15 01 00 00 00 00 02 a7 74
+ 15 01 00 00 00 00 02 a9 03
+ 15 01 00 00 00 00 02 aa 80
+ 15 01 00 00 00 00 02 ab 03
+ 15 01 00 00 00 00 02 ac 89
+ 15 01 00 00 00 00 02 ad 03
+ 15 01 00 00 00 00 02 ae 8b
+ 15 01 00 00 00 00 02 af 03
+ 15 01 00 00 00 00 02 b0 8d
+ 15 01 00 00 00 00 02 b1 03
+ 15 01 00 00 00 00 02 b2 8e
+ 15 01 00 00 00 00 02 b3 00
+ 15 01 00 00 00 00 02 b4 71
+ 15 01 00 00 00 00 02 b5 00
+ 15 01 00 00 00 00 02 b6 84
+ 15 01 00 00 00 00 02 b7 00
+ 15 01 00 00 00 00 02 b8 a5
+ 15 01 00 00 00 00 02 b9 00
+ 15 01 00 00 00 00 02 ba bb
+ 15 01 00 00 00 00 02 bb 00
+ 15 01 00 00 00 00 02 bc ce
+ 15 01 00 00 00 00 02 bd 00
+ 15 01 00 00 00 00 02 be e0
+ 15 01 00 00 00 00 02 bf 00
+ 15 01 00 00 00 00 02 c0 ef
+ 15 01 00 00 00 00 02 c1 00
+ 15 01 00 00 00 00 02 c2 ff
+ 15 01 00 00 00 00 02 c3 01
+ 15 01 00 00 00 00 02 c4 0b
+ 15 01 00 00 00 00 02 c5 01
+ 15 01 00 00 00 00 02 c6 38
+ 15 01 00 00 00 00 02 c7 01
+ 15 01 00 00 00 00 02 c8 5b
+ 15 01 00 00 00 00 02 c9 01
+ 15 01 00 00 00 00 02 ca 95
+ 15 01 00 00 00 00 02 cb 01
+ 15 01 00 00 00 00 02 cc c4
+ 15 01 00 00 00 00 02 cd 02
+ 15 01 00 00 00 00 02 ce 0d
+ 15 01 00 00 00 00 02 cf 02
+ 15 01 00 00 00 00 02 d0 4a
+ 15 01 00 00 00 00 02 d1 02
+ 15 01 00 00 00 00 02 d2 4c
+ 15 01 00 00 00 00 02 d3 02
+ 15 01 00 00 00 00 02 d4 85
+ 15 01 00 00 00 00 02 d5 02
+ 15 01 00 00 00 00 02 d6 c3
+ 15 01 00 00 00 00 02 d7 02
+ 15 01 00 00 00 00 02 d8 e9
+ 15 01 00 00 00 00 02 d9 03
+ 15 01 00 00 00 00 02 da 16
+ 15 01 00 00 00 00 02 db 03
+ 15 01 00 00 00 00 02 dc 34
+ 15 01 00 00 00 00 02 dd 03
+ 15 01 00 00 00 00 02 de 56
+ 15 01 00 00 00 00 02 df 03
+ 15 01 00 00 00 00 02 e0 62
+ 15 01 00 00 00 00 02 e1 03
+ 15 01 00 00 00 00 02 e2 6c
+ 15 01 00 00 00 00 02 e3 03
+ 15 01 00 00 00 00 02 e4 74
+ 15 01 00 00 00 00 02 e5 03
+ 15 01 00 00 00 00 02 e6 80
+ 15 01 00 00 00 00 02 e7 03
+ 15 01 00 00 00 00 02 e8 89
+ 15 01 00 00 00 00 02 e9 03
+ 15 01 00 00 00 00 02 ea 8b
+ 15 01 00 00 00 00 02 eb 03
+ 15 01 00 00 00 00 02 ec 8d
+ 15 01 00 00 00 00 02 ed 03
+ 15 01 00 00 00 00 02 ee 8e
+ 15 01 00 00 00 00 02 ef 00
+ 15 01 00 00 00 00 02 f0 71
+ 15 01 00 00 00 00 02 f1 00
+ 15 01 00 00 00 00 02 f2 84
+ 15 01 00 00 00 00 02 f3 00
+ 15 01 00 00 00 00 02 f4 a5
+ 15 01 00 00 00 00 02 f5 00
+ 15 01 00 00 00 00 02 f6 bb
+ 15 01 00 00 00 00 02 f7 00
+ 15 01 00 00 00 00 02 f8 ce
+ 15 01 00 00 00 00 02 f9 00
+ 15 01 00 00 00 00 02 fa e0
+ 15 01 00 00 00 00 02 ff 21
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 00
+ 15 01 00 00 00 00 02 01 ef
+ 15 01 00 00 00 00 02 02 00
+ 15 01 00 00 00 00 02 03 ff
+ 15 01 00 00 00 00 02 04 01
+ 15 01 00 00 00 00 02 05 0b
+ 15 01 00 00 00 00 02 06 01
+ 15 01 00 00 00 00 02 07 38
+ 15 01 00 00 00 00 02 08 01
+ 15 01 00 00 00 00 02 09 5b
+ 15 01 00 00 00 00 02 0a 01
+ 15 01 00 00 00 00 02 0b 95
+ 15 01 00 00 00 00 02 0c 01
+ 15 01 00 00 00 00 02 0d c4
+ 15 01 00 00 00 00 02 0e 02
+ 15 01 00 00 00 00 02 0f 0d
+ 15 01 00 00 00 00 02 10 02
+ 15 01 00 00 00 00 02 11 4a
+ 15 01 00 00 00 00 02 12 02
+ 15 01 00 00 00 00 02 13 4c
+ 15 01 00 00 00 00 02 14 02
+ 15 01 00 00 00 00 02 15 85
+ 15 01 00 00 00 00 02 16 02
+ 15 01 00 00 00 00 02 17 c3
+ 15 01 00 00 00 00 02 18 02
+ 15 01 00 00 00 00 02 19 e9
+ 15 01 00 00 00 00 02 1a 03
+ 15 01 00 00 00 00 02 1b 16
+ 15 01 00 00 00 00 02 1c 03
+ 15 01 00 00 00 00 02 1d 34
+ 15 01 00 00 00 00 02 1e 03
+ 15 01 00 00 00 00 02 1f 56
+ 15 01 00 00 00 00 02 20 03
+ 15 01 00 00 00 00 02 21 62
+ 15 01 00 00 00 00 02 22 03
+ 15 01 00 00 00 00 02 23 6c
+ 15 01 00 00 00 00 02 24 03
+ 15 01 00 00 00 00 02 25 74
+ 15 01 00 00 00 00 02 26 03
+ 15 01 00 00 00 00 02 27 80
+ 15 01 00 00 00 00 02 28 03
+ 15 01 00 00 00 00 02 29 89
+ 15 01 00 00 00 00 02 2a 03
+ 15 01 00 00 00 00 02 2b 8b
+ 15 01 00 00 00 00 02 2d 03
+ 15 01 00 00 00 00 02 2f 8d
+ 15 01 00 00 00 00 02 30 03
+ 15 01 00 00 00 00 02 31 8e
+ 15 01 00 00 00 00 02 32 00
+ 15 01 00 00 00 00 02 33 71
+ 15 01 00 00 00 00 02 34 00
+ 15 01 00 00 00 00 02 35 84
+ 15 01 00 00 00 00 02 36 00
+ 15 01 00 00 00 00 02 37 a5
+ 15 01 00 00 00 00 02 38 00
+ 15 01 00 00 00 00 02 39 bb
+ 15 01 00 00 00 00 02 3a 00
+ 15 01 00 00 00 00 02 3b ce
+ 15 01 00 00 00 00 02 3d 00
+ 15 01 00 00 00 00 02 3f e0
+ 15 01 00 00 00 00 02 40 00
+ 15 01 00 00 00 00 02 41 ef
+ 15 01 00 00 00 00 02 42 00
+ 15 01 00 00 00 00 02 43 ff
+ 15 01 00 00 00 00 02 44 01
+ 15 01 00 00 00 00 02 45 0b
+ 15 01 00 00 00 00 02 46 01
+ 15 01 00 00 00 00 02 47 38
+ 15 01 00 00 00 00 02 48 01
+ 15 01 00 00 00 00 02 49 5b
+ 15 01 00 00 00 00 02 4a 01
+ 15 01 00 00 00 00 02 4b 95
+ 15 01 00 00 00 00 02 4c 01
+ 15 01 00 00 00 00 02 4d c4
+ 15 01 00 00 00 00 02 4e 02
+ 15 01 00 00 00 00 02 4f 0d
+ 15 01 00 00 00 00 02 50 02
+ 15 01 00 00 00 00 02 51 4a
+ 15 01 00 00 00 00 02 52 02
+ 15 01 00 00 00 00 02 53 4c
+ 15 01 00 00 00 00 02 54 02
+ 15 01 00 00 00 00 02 55 85
+ 15 01 00 00 00 00 02 56 02
+ 15 01 00 00 00 00 02 58 c3
+ 15 01 00 00 00 00 02 59 02
+ 15 01 00 00 00 00 02 5a e9
+ 15 01 00 00 00 00 02 5b 03
+ 15 01 00 00 00 00 02 5c 16
+ 15 01 00 00 00 00 02 5d 03
+ 15 01 00 00 00 00 02 5e 34
+ 15 01 00 00 00 00 02 5f 03
+ 15 01 00 00 00 00 02 60 56
+ 15 01 00 00 00 00 02 61 03
+ 15 01 00 00 00 00 02 62 62
+ 15 01 00 00 00 00 02 63 03
+ 15 01 00 00 00 00 02 64 6c
+ 15 01 00 00 00 00 02 65 03
+ 15 01 00 00 00 00 02 66 74
+ 15 01 00 00 00 00 02 67 03
+ 15 01 00 00 00 00 02 68 80
+ 15 01 00 00 00 00 02 69 03
+ 15 01 00 00 00 00 02 6a 89
+ 15 01 00 00 00 00 02 6b 03
+ 15 01 00 00 00 00 02 6c 8b
+ 15 01 00 00 00 00 02 6d 03
+ 15 01 00 00 00 00 02 6e 8d
+ 15 01 00 00 00 00 02 6f 03
+ 15 01 00 00 00 00 02 70 8e
+ 15 01 00 00 00 00 02 71 00
+ 15 01 00 00 00 00 02 72 71
+ 15 01 00 00 00 00 02 73 00
+ 15 01 00 00 00 00 02 74 84
+ 15 01 00 00 00 00 02 75 00
+ 15 01 00 00 00 00 02 76 a5
+ 15 01 00 00 00 00 02 77 00
+ 15 01 00 00 00 00 02 78 bb
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 7a ce
+ 15 01 00 00 00 00 02 7b 00
+ 15 01 00 00 00 00 02 7c e0
+ 15 01 00 00 00 00 02 7d 00
+ 15 01 00 00 00 00 02 7e ef
+ 15 01 00 00 00 00 02 7f 00
+ 15 01 00 00 00 00 02 80 ff
+ 15 01 00 00 00 00 02 81 01
+ 15 01 00 00 00 00 02 82 0b
+ 15 01 00 00 00 00 02 83 01
+ 15 01 00 00 00 00 02 84 38
+ 15 01 00 00 00 00 02 85 01
+ 15 01 00 00 00 00 02 86 5b
+ 15 01 00 00 00 00 02 87 01
+ 15 01 00 00 00 00 02 88 95
+ 15 01 00 00 00 00 02 89 01
+ 15 01 00 00 00 00 02 8a c4
+ 15 01 00 00 00 00 02 8b 02
+ 15 01 00 00 00 00 02 8c 0d
+ 15 01 00 00 00 00 02 8d 02
+ 15 01 00 00 00 00 02 8e 4a
+ 15 01 00 00 00 00 02 8f 02
+ 15 01 00 00 00 00 02 90 4c
+ 15 01 00 00 00 00 02 91 02
+ 15 01 00 00 00 00 02 92 85
+ 15 01 00 00 00 00 02 93 02
+ 15 01 00 00 00 00 02 94 c3
+ 15 01 00 00 00 00 02 95 02
+ 15 01 00 00 00 00 02 96 e9
+ 15 01 00 00 00 00 02 97 03
+ 15 01 00 00 00 00 02 98 16
+ 15 01 00 00 00 00 02 99 03
+ 15 01 00 00 00 00 02 9a 34
+ 15 01 00 00 00 00 02 9b 03
+ 15 01 00 00 00 00 02 9c 56
+ 15 01 00 00 00 00 02 9d 03
+ 15 01 00 00 00 00 02 9e 62
+ 15 01 00 00 00 00 02 9f 03
+ 15 01 00 00 00 00 02 a0 6c
+ 15 01 00 00 00 00 02 a2 03
+ 15 01 00 00 00 00 02 a3 74
+ 15 01 00 00 00 00 02 a4 03
+ 15 01 00 00 00 00 02 a5 80
+ 15 01 00 00 00 00 02 a6 03
+ 15 01 00 00 00 00 02 a7 89
+ 15 01 00 00 00 00 02 a9 03
+ 15 01 00 00 00 00 02 aa 8b
+ 15 01 00 00 00 00 02 ab 03
+ 15 01 00 00 00 00 02 ac 8d
+ 15 01 00 00 00 00 02 ad 03
+ 15 01 00 00 00 00 02 ae 8e
+ 15 01 00 00 00 00 02 af 00
+ 15 01 00 00 00 00 02 b0 71
+ 15 01 00 00 00 00 02 b1 00
+ 15 01 00 00 00 00 02 b2 84
+ 15 01 00 00 00 00 02 b3 00
+ 15 01 00 00 00 00 02 b4 a5
+ 15 01 00 00 00 00 02 b5 00
+ 15 01 00 00 00 00 02 b6 bb
+ 15 01 00 00 00 00 02 b7 00
+ 15 01 00 00 00 00 02 b8 ce
+ 15 01 00 00 00 00 02 b9 00
+ 15 01 00 00 00 00 02 ba e0
+ 15 01 00 00 00 00 02 bb 00
+ 15 01 00 00 00 00 02 bc ef
+ 15 01 00 00 00 00 02 bd 00
+ 15 01 00 00 00 00 02 be ff
+ 15 01 00 00 00 00 02 bf 01
+ 15 01 00 00 00 00 02 c0 0b
+ 15 01 00 00 00 00 02 c1 01
+ 15 01 00 00 00 00 02 c2 38
+ 15 01 00 00 00 00 02 c3 01
+ 15 01 00 00 00 00 02 c4 5b
+ 15 01 00 00 00 00 02 c5 01
+ 15 01 00 00 00 00 02 c6 95
+ 15 01 00 00 00 00 02 c7 01
+ 15 01 00 00 00 00 02 c8 c4
+ 15 01 00 00 00 00 02 c9 02
+ 15 01 00 00 00 00 02 ca 0d
+ 15 01 00 00 00 00 02 cb 02
+ 15 01 00 00 00 00 02 cc 4a
+ 15 01 00 00 00 00 02 cd 02
+ 15 01 00 00 00 00 02 ce 4c
+ 15 01 00 00 00 00 02 cf 02
+ 15 01 00 00 00 00 02 d0 85
+ 15 01 00 00 00 00 02 d1 02
+ 15 01 00 00 00 00 02 d2 c3
+ 15 01 00 00 00 00 02 d3 02
+ 15 01 00 00 00 00 02 d4 e9
+ 15 01 00 00 00 00 02 d5 03
+ 15 01 00 00 00 00 02 d6 16
+ 15 01 00 00 00 00 02 d7 03
+ 15 01 00 00 00 00 02 d8 34
+ 15 01 00 00 00 00 02 d9 03
+ 15 01 00 00 00 00 02 da 56
+ 15 01 00 00 00 00 02 db 03
+ 15 01 00 00 00 00 02 dc 62
+ 15 01 00 00 00 00 02 dd 03
+ 15 01 00 00 00 00 02 de 6c
+ 15 01 00 00 00 00 02 df 03
+ 15 01 00 00 00 00 02 e0 74
+ 15 01 00 00 00 00 02 e1 03
+ 15 01 00 00 00 00 02 e2 80
+ 15 01 00 00 00 00 02 e3 03
+ 15 01 00 00 00 00 02 e4 89
+ 15 01 00 00 00 00 02 e5 03
+ 15 01 00 00 00 00 02 e6 8b
+ 15 01 00 00 00 00 02 e7 03
+ 15 01 00 00 00 00 02 e8 8d
+ 15 01 00 00 00 00 02 e9 03
+ 15 01 00 00 00 00 02 ea 8e
+ 15 01 00 00 00 00 02 FF 10
+ 05 01 00 00 00 00 01 29];
+ qcom,mdss-dsi-off-command =
+ [15 01 00 00 00 00 02 ff 10
+ 05 01 00 00 10 00 01 28
+ 15 01 00 00 00 00 02 b0 00
+ 05 01 00 00 40 00 01 10
+ 15 01 00 00 00 00 02 4f 01];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ };
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sim-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sim-cmd.dtsi
index 1f08294..50da1bf 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sim-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sim-cmd.dtsi
@@ -14,27 +14,12 @@
dsi_sim_cmd: qcom,mdss_dsi_sim_cmd{
qcom,mdss-dsi-panel-name = "Simulator cmd mode dsi panel";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <640>;
- qcom,mdss-dsi-panel-height = <480>;
- qcom,mdss-dsi-h-front-porch = <20>;
- qcom,mdss-dsi-h-back-porch = <20>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <16>;
- qcom,mdss-dsi-v-front-porch = <4>;
- qcom,mdss-dsi-v-pulse-width = <1>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-color-order = "rgb_swap_rgb";
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -42,11 +27,6 @@
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-lane-2-state;
qcom,mdss-dsi-lane-3-state;
- qcom,mdss-dsi-hor-line-idle = <0 40 256>,
- <40 120 128>,
- <120 240 64>;
- qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03
- 04 00];
qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
qcom,mdss-dsi-t-clk-post = <0x03>;
qcom,mdss-dsi-t-clk-pre = <0x27>;
@@ -65,33 +45,60 @@
17000 15500 30000 8000 3000>;
qcom,mdss-dsi-panel-peak-brightness = <4200000>;
qcom,mdss-dsi-panel-blackness-level = <3230>;
- qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03
- 05 01 00 00 0a 00 01 00
- /* Soft reset, wait 10ms */
- 15 01 00 00 0a 00 02 3a 77
- /* Set Pixel format (24 bpp) */
- 39 01 00 00 0a 00 05 2a 00 00 04 ff
- /* Set Column address */
- 39 01 00 00 0a 00 05 2b 00 00 05 9f
- /* Set page address */
- 15 01 00 00 0a 00 02 35 00
- /* Set tear on */
- 39 01 00 00 0a 00 03 44 00 00
- /* Set tear scan line */
- 15 01 00 00 0a 00 02 51 ff
- /* write display brightness */
- 15 01 00 00 0a 00 02 53 24
- /* write control brightness */
- 15 01 00 00 0a 00 02 55 00
- /* CABC brightness */
- 05 01 00 00 78 00 01 11
- /* exit sleep mode, wait 120ms */
- 05 01 00 00 10 00 01 29];
- /* Set display on, wait 16ms */
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,panel-ack-disabled;
+
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <640>;
+ qcom,mdss-dsi-panel-height = <480>;
+ qcom,mdss-dsi-h-front-porch = <20>;
+ qcom,mdss-dsi-h-back-porch = <20>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <16>;
+ qcom,mdss-dsi-v-front-porch = <4>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-hor-line-idle = <0 40 256>,
+ <40 120 128>,
+ <120 240 64>;
+ qcom,mdss-dsi-panel-timings =
+ [cd 32 22 00 60 64 26 34 29 03 04 00];
+ qcom,mdss-dsi-on-command =
+ [29 01 00 00 00 00 02 b0 03
+ 05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command =
+ [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-cmd.dtsi
index 36f36fb..a93deb5 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-cmd.dtsi
@@ -14,27 +14,12 @@
dsi_dual_sim_cmd: qcom,mdss_dsi_dual_sim_cmd {
qcom,mdss-dsi-panel-name = "Sim dual cmd mode dsi panel";
qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1280>;
- qcom,mdss-dsi-panel-height = <1440>;
- qcom,mdss-dsi-h-front-porch = <120>;
- qcom,mdss-dsi-h-back-porch = <44>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <4>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <4>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-color-order = "rgb_swap_rgb";
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -57,33 +42,55 @@
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-wd;
qcom,mdss-dsi-te-using-te-pin;
- qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03
- 05 01 00 00 0a 00 01 00
- /* Soft reset, wait 10ms */
- 15 01 00 00 0a 00 02 3a 77
- /* Set Pixel format (24 bpp) */
- 39 01 00 00 0a 00 05 2a 00 00 04 ff
- /* Set Column address */
- 39 01 00 00 0a 00 05 2b 00 00 05 9f
- /* Set page address */
- 15 01 00 00 0a 00 02 35 00
- /* Set tear on */
- 39 01 00 00 0a 00 03 44 00 00
- /* Set tear scan line */
- 15 01 00 00 0a 00 02 51 ff
- /* write display brightness */
- 15 01 00 00 0a 00 02 53 24
- /* write control brightness */
- 15 01 00 00 0a 00 02 55 00
- /* CABC brightness */
- 05 01 00 00 78 00 01 11
- /* exit sleep mode, wait 120ms */
- 05 01 00 00 10 00 01 29];
- /* Set display on, wait 16ms */
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,panel-ack-disabled;
+
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-on-command =
+ [29 01 00 00 00 00 02 b0 03
+ 05 01 00 00 0a 00 01 00
+ /* Soft reset, wait 10ms */
+ 15 01 00 00 0a 00 02 3a 77
+ /* Set Pixel format (24 bpp) */
+ 39 01 00 00 0a 00 05 2a 00 00 04 ff
+ /* Set Column address */
+ 39 01 00 00 0a 00 05 2b 00 00 05 9f
+ /* Set page address */
+ 15 01 00 00 0a 00 02 35 00
+ /* Set tear on */
+ 39 01 00 00 0a 00 03 44 00 00
+ /* Set tear scan line */
+ 15 01 00 00 0a 00 02 51 ff
+ /* write display brightness */
+ 15 01 00 00 0a 00 02 53 24
+ /* write control brightness */
+ 15 01 00 00 0a 00 02 55 00
+ /* CABC brightness */
+ 05 01 00 00 78 00 01 11
+ /* exit sleep mode, wait 120ms */
+ 05 01 00 00 10 00 01 29];
+ /* Set display on, wait 16ms */
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command =
+ [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-video.dtsi
index cca28c7..dbfedb9 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sim-dualmipi-video.dtsi
@@ -14,26 +14,11 @@
dsi_dual_sim_vid: qcom,mdss_dsi_dual_sim_video {
qcom,mdss-dsi-panel-name = "Sim dual video mode dsi panel";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <1280>;
- qcom,mdss-dsi-panel-height = <1440>;
- qcom,mdss-dsi-h-front-porch = <120>;
- qcom,mdss-dsi-h-back-porch = <44>;
- qcom,mdss-dsi-h-pulse-width = <16>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <4>;
- qcom,mdss-dsi-v-front-porch = <8>;
- qcom,mdss-dsi-v-pulse-width = <4>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -45,11 +30,32 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
- qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>;
qcom,panel-ack-disabled;
+
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <1280>;
+ qcom,mdss-dsi-panel-height = <1440>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <44>;
+ qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <4>;
+ qcom,mdss-dsi-v-front-porch = <8>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command =
+ [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-sim-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-sim-video.dtsi
index 98a1f61..40bedd0 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-sim-video.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-sim-video.dtsi
@@ -14,22 +14,8 @@
dsi_sim_vid: qcom,mdss_dsi_sim_video {
qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
- qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
- qcom,mdss-dsi-panel-width = <640>;
- qcom,mdss-dsi-panel-height = <480>;
- qcom,mdss-dsi-h-front-porch = <8>;
- qcom,mdss-dsi-h-back-porch = <8>;
- qcom,mdss-dsi-h-pulse-width = <8>;
- qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <6>;
- qcom,mdss-dsi-v-front-porch = <6>;
- qcom,mdss-dsi-v-pulse-width = <2>;
- qcom,mdss-dsi-h-left-border = <0>;
- qcom,mdss-dsi-h-right-border = <0>;
- qcom,mdss-dsi-v-top-border = <0>;
- qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
@@ -38,11 +24,6 @@
17000 15500 30000 8000 3000>;
qcom,mdss-dsi-panel-peak-brightness = <4200000>;
qcom,mdss-dsi-panel-blackness-level = <3230>;
- qcom,mdss-dsi-on-command = [32 01 00 00 00 00 02 00 00];
- qcom,mdss-dsi-off-command = [22 01 00 00 00 00 02 00 00];
- qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
@@ -50,13 +31,39 @@
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-lane-2-state;
qcom,mdss-dsi-lane-3-state;
- qcom,mdss-dsi-panel-timings =
- [00 00 00 00 00 00 00 00 00 00 00 00];
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1b>;
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 0>, <0 0>, <1 0>;
qcom,panel-ack-disabled;
+
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-width = <640>;
+ qcom,mdss-dsi-panel-height = <480>;
+ qcom,mdss-dsi-h-front-porch = <8>;
+ qcom,mdss-dsi-h-back-porch = <8>;
+ qcom,mdss-dsi-h-pulse-width = <8>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <6>;
+ qcom,mdss-dsi-v-front-porch = <6>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-panel-timings =
+ [00 00 00 00 00 00 00 00 00 00 00 00];
+ qcom,mdss-dsi-on-command =
+ [32 01 00 00 00 00 02 00 00];
+ qcom,mdss-dsi-off-command =
+ [22 01 00 00 00 00 02 00 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ };
+ };
};
};
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 02fedbe..56e74be 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
@@ -34,14 +34,10 @@
<GIC_SPI 369 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 370 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 371 IRQ_TYPE_EDGE_RISING>;
- clock-names = "gcc_ddrss_gpu_axi_clk",
- "gcc_gpu_memnoc_gfx_clk",
- "gpu_cc_ahb_clk",
- "gpu_cc_cx_gmu_clk";
- clocks = <&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
- <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
- <&clock_gpucc GPU_CC_AHB_CLK>,
- <&clock_gpucc GPU_CC_CX_GMU_CLK>;
+ clock-names = "gcc_gpu_memnoc_gfx_clk",
+ "gpu_cc_ahb_clk";
+ clocks = <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&clock_gpucc GPU_CC_AHB_CLK>;
attach-impl-defs =
<0x6000 0x2378>,
<0x6060 0x1055>,
diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
index bc0b118..0d2f9e8 100644
--- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
@@ -85,7 +85,7 @@
compatible = "qcom,msm-pcm-loopback";
};
- qcom,msm-dai-mi2s {
+ msm_dai_mi2s: qcom,msm-dai-mi2s {
compatible = "qcom,msm-dai-mi2s";
dai_mi2s0: qcom,msm-dai-q6-mi2s-prim {
compatible = "qcom,msm-dai-q6-mi2s";
diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi
index 9cd117c..075eaef2 100644
--- a/arch/arm64/boot/dts/qcom/pm660l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi
@@ -269,6 +269,7 @@
qcom,led-strings-list = [00 01 02];
qcom,loop-auto-gm-en;
qcom,pmic-revid = <&pm660l_revid>;
+ qcom,auto-calibration-enable;
status = "ok";
};
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
index 09405ee..12b469c 100644
--- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
@@ -563,6 +563,7 @@
qcom,en-ext-pfet-sc-pro;
qcom,pmic-revid = <&pmi8998_revid>;
qcom,loop-auto-gm-en;
+ qcom,auto-calibration-enable;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
new file mode 100644
index 0000000..3bd0350
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
@@ -0,0 +1,568 @@
+/*
+ * 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.
+ */
+
+#include "msm-audio-lpass.dtsi"
+#include "sdm670-wsa881x.dtsi"
+#include "sdm670-wcd.dtsi"
+#include "sdm670-lpi.dtsi"
+#include <dt-bindings/clock/qcom,audio-ext-clk.h>
+
+&msm_audio_ion {
+ iommus = <&apps_smmu 0x1801 0x0>;
+ qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+};
+
+&soc {
+ qcom,avtimer@62cf700c {
+ compatible = "qcom,avtimer";
+ reg = <0x62cf700c 0x4>,
+ <0x62cf7010 0x4>;
+ reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
+ qcom,clk-div = <192>;
+ qcom,clk-mult = <10>;
+ };
+
+ tavil_snd: sound-tavil {
+ status = "disabled";
+ compatible = "qcom,sdm670-asoc-snd-tavil";
+ qcom,model = "sdm670-tavil-snd-card";
+ qcom,wcn-btfm;
+ qcom,mi2s-audio-intf;
+ qcom,auxpcm-audio-intf;
+ qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
+ qcom,audio-routing =
+ "AIF4 VI", "MCLK",
+ "RX_BIAS", "MCLK",
+ "MADINPUT", "MCLK",
+ "hifi amp", "LINEOUT1",
+ "hifi amp", "LINEOUT2",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "AMIC3", "MIC BIAS2",
+ "MIC BIAS2", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2",
+ "MIC BIAS2", "ANCLeft Headset Mic",
+ "AMIC5", "MIC BIAS3",
+ "MIC BIAS3", "Handset Mic",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
+ "DMIC4", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic4",
+ "DMIC5", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic5",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT";
+
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <1>;
+ qcom,hph-en0-gpio = <&tavil_hph_en0>;
+ qcom,hph-en1-gpio = <&tavil_hph_en1>;
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>;
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>,
+ <&pcm_noirq>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing", "msm-cpe-lsm",
+ "msm-compr-dsp", "msm-pcm-dsp-noirq";
+ asoc-cpu = <&dai_mi2s0>, <&dai_mi2s1>,
+ <&dai_mi2s2>, <&dai_mi2s3>,
+ <&dai_pri_auxpcm>, <&dai_sec_auxpcm>,
+ <&dai_tert_auxpcm>, <&dai_quat_auxpcm>,
+ <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
+ <&sb_4_rx>, <&sb_4_tx>, <&sb_5_rx>, <&sb_5_tx>,
+ <&sb_6_rx>, <&sb_7_rx>, <&sb_7_tx>,
+ <&sb_8_rx>, <&sb_8_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
+ <&afe_proxy_tx>, <&incall_record_rx>,
+ <&incall_record_tx>, <&incall_music_rx>,
+ <&incall_music_2_rx>,
+ <&usb_audio_rx>, <&usb_audio_tx>,
+ <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>,
+ <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>,
+ <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>,
+ <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>;
+ asoc-cpu-names = "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
+ "msm-dai-q6-auxpcm.3", "msm-dai-q6-auxpcm.4",
+ "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385",
+ "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+ "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389",
+ "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+ "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.16394", "msm-dai-q6-dev.16395",
+ "msm-dai-q6-dev.16396",
+ "msm-dai-q6-dev.16398", "msm-dai-q6-dev.16399",
+ "msm-dai-q6-dev.16400", "msm-dai-q6-dev.16401",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770",
+ "msm-dai-q6-dev.28672", "msm-dai-q6-dev.28673",
+ "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865",
+ "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
+ "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
+ "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913";
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>,
+ <&wsa881x_0213>, <&wsa881x_0214>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+ };
+
+int_codec: sound {
+ status = "okay";
+ compatible = "qcom,sdm670-asoc-snd";
+ qcom,model = "sdm670-snd-card";
+ qcom,wcn-btfm;
+ qcom,mi2s-audio-intf;
+ qcom,auxpcm-audio-intf;
+ qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <1>;
+ qcom,msm-micbias2-ext-cap;
+ qcom,msm-hs-micbias-type = "external";
+ qcom,cdc-pdm-gpios = <&cdc_pdm_gpios>;
+ qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
+ qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
+ qcom,audio-routing =
+ "RX_BIAS", "INT_MCLK0",
+ "SPK_RX_BIAS", "INT_MCLK0",
+ "INT_LDO_H", "INT_MCLK0",
+ "MIC BIAS External", "Handset Mic",
+ "MIC BIAS External2", "Headset Mic",
+ "MIC BIAS External", "Secondary Mic",
+ "AMIC1", "MIC BIAS External",
+ "AMIC2", "MIC BIAS External2",
+ "AMIC3", "MIC BIAS External",
+ "DMIC1", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic1",
+ "DMIC2", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic2",
+ "DMIC3", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic3",
+ "DMIC4", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic4",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT",
+ "PDM_IN_RX1", "PDM_OUT_RX1",
+ "PDM_IN_RX2", "PDM_OUT_RX2",
+ "PDM_IN_RX3", "PDM_OUT_RX3",
+ "ADC1_IN", "ADC1_OUT",
+ "ADC2_IN", "ADC2_OUT",
+ "ADC3_IN", "ADC3_OUT";
+
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&pcm_noirq>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-dsp-noirq";
+ asoc-cpu = <&dai_mi2s0>, <&dai_mi2s1>,
+ <&dai_mi2s2>, <&dai_mi2s3>,
+ <&dai_int_mi2s0>, <&dai_int_mi2s1>,
+ <&dai_int_mi2s2>, <&dai_int_mi2s3>,
+ <&dai_int_mi2s4>, <&dai_int_mi2s5>,
+ <&dai_pri_auxpcm>, <&dai_sec_auxpcm>,
+ <&dai_tert_auxpcm>, <&dai_quat_auxpcm>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
+ <&afe_proxy_tx>, <&incall_record_rx>,
+ <&incall_record_tx>, <&incall_music_rx>,
+ <&incall_music_2_rx>, <&sb_7_rx>, <&sb_7_tx>,
+ <&sb_8_tx>, <&sb_8_rx>,
+ <&usb_audio_rx>, <&usb_audio_tx>,
+ <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>,
+ <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>,
+ <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>,
+ <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>;
+ asoc-cpu-names = "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-mi2s.7", "msm-dai-q6-mi2s.8",
+ "msm-dai-q6-mi2s.9", "msm-dai-q6-mi2s.10",
+ "msm-dai-q6-mi2s.11", "msm-dai-q6-mi2s.12",
+ "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
+ "msm-dai-q6-auxpcm.3", "msm-dai-q6-auxpcm.4",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770",
+ "msm-dai-q6-dev.16398", "msm-dai-q6-dev.16399",
+ "msm-dai-q6-dev.16401", "msm-dai-q6-dev.16400",
+ "msm-dai-q6-dev.28672", "msm-dai-q6-dev.28673",
+ "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865",
+ "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
+ "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
+ "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913";
+ asoc-codec = <&stub_codec>, <&msm_digital_codec>,
+ <&pmic_analog_codec>, <&msm_sdw_codec>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
+ "analog-codec", "msm_sdw_codec";
+
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_211_en>, <&wsa881x_212_en>,
+ <&wsa881x_213_en>, <&wsa881x_214_en>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+ };
+
+ cdc_pdm_gpios: cdc_pdm_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_pdm_clk_active &cdc_pdm_sync_active
+ &cdc_pdm_rx0_active &cdc_pdm_rx1_2_active
+ &cdc_pdm_2_gpios_active>;
+ pinctrl-1 = <&cdc_pdm_clk_sleep &cdc_pdm_sync_sleep
+ &cdc_pdm_rx0_sleep &cdc_pdm_rx1_2_sleep
+ &cdc_pdm_2_gpios_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_comp_gpios: cdc_comp_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_rx0_comp_active &cdc_rx1_comp_active>;
+ pinctrl-1 = <&cdc_rx0_comp_sleep &cdc_rx1_comp_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_dmic_gpios: cdc_dmic_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_dmic12_gpios_active
+ &cdc_dmic34_gpios_active>;
+ pinctrl-1 = <&cdc_dmic12_gpios_sleep
+ &cdc_dmic34_gpios_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_sdw_gpios: sdw_clk_data_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&sdw_clk_active &sdw_data_active>;
+ pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>;
+ };
+
+ wsa_spkr_en1: wsa_spkr_en1_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_1_sd_n_active>;
+ pinctrl-1 = <&spkr_1_sd_n_sleep>;
+ };
+
+ wsa_spkr_en2: wsa_spkr_en2_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_2_sd_n_active>;
+ pinctrl-1 = <&spkr_2_sd_n_sleep>;
+ };
+
+ msm_sdw_codec: msm-sdw-codec@62ec1000 {
+ status = "okay";
+ compatible = "qcom,msm-sdw-codec";
+ reg = <0x62ec1000 0x0>;
+ interrupts = <0 161 0>;
+ interrupt-names = "swr_master_irq";
+ qcom,cdc-sdw-gpios = <&cdc_sdw_gpios>;
+
+ swr_master {
+ compatible = "qcom,swr-wcd";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ wsa881x_211_en: wsa881x_en@20170211 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170211>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+ };
+
+ wsa881x_212_en: wsa881x_en@20170212 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170212>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+ };
+
+ wsa881x_213_en: wsa881x_en@21170213 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170213>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+ };
+
+ wsa881x_214_en: wsa881x_en@21170214 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170214>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+ };
+ };
+ };
+
+ wcd9xxx_intc: wcd9xxx-irq {
+ status = "disabled";
+ compatible = "qcom,wcd9xxx-irq";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&tlmm>;
+ qcom,gpio-connect = <&tlmm 80 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wcd_intr_default>;
+ };
+
+ clock_audio_lnbb: audio_ext_clk_lnbb {
+ status = "disabled";
+ compatible = "qcom,audio-ref-clk";
+ clock-names = "osr_clk";
+ clocks = <&clock_rpmh RPMH_LN_BB_CLK2>;
+ qcom,node_has_rpm_clock;
+ #clock-cells = <1>;
+ };
+
+ wcd_rst_gpio: msm_cdc_pinctrl@64 {
+ status = "disabled";
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&lpi_cdc_reset_active>;
+ pinctrl-1 = <&lpi_cdc_reset_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cpe: qcom,msm-cpe-lsm {
+ compatible = "qcom,msm-cpe-lsm";
+ };
+
+ cpe3: qcom,msm-cpe-lsm@3 {
+ compatible = "qcom,msm-cpe-lsm";
+ qcom,msm-cpe-lsm-id = <3>;
+ };
+
+ wdsp_mgr: qcom,wcd-dsp-mgr {
+ compatible = "qcom,wcd-dsp-mgr";
+ qcom,wdsp-components = <&wcd934x_cdc 0>,
+ <&wcd_spi_0 1>,
+ <&glink_spi_xprt_wdsp 2>;
+ qcom,img-filename = "cpe_9340";
+ };
+
+ wdsp_glink: qcom,wcd-dsp-glink {
+ compatible = "qcom,wcd-dsp-glink";
+ };
+};
+
+&slim_aud {
+ status = "disabled";
+ dai_slim: msm_dai_slim {
+ status = "disabled";
+ compatible = "qcom,msm-dai-slim";
+ elemental-addr = [ff ff ff fe 17 02];
+ };
+
+ wcd934x_cdc: tavil_codec {
+ status = "disabled";
+ compatible = "qcom,tavil-slim-pgd";
+ elemental-addr = [00 01 50 02 17 02];
+
+ interrupt-parent = <&wcd9xxx_intc>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29
+ 30 31>;
+
+ qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+
+ clock-names = "wcd_clk";
+ clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>;
+
+ cdc-vdd-mic-bias-supply = <&pm660l_bob>;
+ qcom,cdc-vdd-mic-bias-voltage = <3300000 3300000>;
+ qcom,cdc-vdd-mic-bias-current = <30400>;
+
+ qcom,cdc-static-supplies = "cdc-vdd-mic-bias";
+
+ qcom,cdc-micbias1-mv = <1800>;
+ qcom,cdc-micbias2-mv = <1800>;
+ qcom,cdc-micbias3-mv = <1800>;
+ qcom,cdc-micbias4-mv = <1800>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+ qcom,cdc-slim-ifd = "tavil-slim-ifd";
+ qcom,cdc-slim-ifd-elemental-addr = [00 00 50 02 17 02];
+ qcom,cdc-dmic-sample-rate = <4800000>;
+ qcom,cdc-mad-dmic-rate = <600000>;
+
+ qcom,wdsp-cmpnt-dev-name = "tavil_codec";
+
+ wcd_spi_0: wcd_spi {
+ compatible = "qcom,wcd-spi-v2";
+ qcom,master-bus-num = <8>;
+ qcom,chip-select = <0>;
+ qcom,max-frequency = <24000000>;
+ qcom,mem-base-addr = <0x100000>;
+ };
+
+ wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl_usbc_audio_en1 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wcd_usbc_analog_en1_active>;
+ pinctrl-1 = <&wcd_usbc_analog_en1_idle>;
+ };
+ };
+};
+
+&msm_dai_mi2s {
+ dai_int_mi2s0: qcom,msm-dai-q6-int-mi2s0 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <7>;
+ qcom,msm-mi2s-rx-lines = <3>;
+ qcom,msm-mi2s-tx-lines = <0>;
+ };
+
+ dai_int_mi2s1: qcom,msm-dai-q6-int-mi2s1 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <8>;
+ qcom,msm-mi2s-rx-lines = <3>;
+ qcom,msm-mi2s-tx-lines = <0>;
+ };
+
+ dai_int_mi2s2: qcom,msm-dai-q6-int-mi2s2 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <9>;
+ qcom,msm-mi2s-rx-lines = <0>;
+ qcom,msm-mi2s-tx-lines = <3>;
+ };
+
+ dai_int_mi2s3: qcom,msm-dai-q6-int-mi2s3 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <10>;
+ qcom,msm-mi2s-rx-lines = <0>;
+ qcom,msm-mi2s-tx-lines = <3>;
+ };
+
+ dai_int_mi2s4: qcom,msm-dai-q6-int-mi2s4 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <11>;
+ qcom,msm-mi2s-rx-lines = <3>;
+ qcom,msm-mi2s-tx-lines = <0>;
+ };
+
+ dai_int_mi2s5: qcom,msm-dai-q6-int-mi2s5 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <12>;
+ qcom,msm-mi2s-rx-lines = <0>;
+ qcom,msm-mi2s-tx-lines = <3>;
+ };
+
+ dai_int_mi2s6: qcom,msm-dai-q6-int-mi2s6 {
+ compatible = "qcom,msm-dai-q6-mi2s";
+ qcom,msm-dai-q6-mi2s-dev-id = <13>;
+ qcom,msm-mi2s-rx-lines = <0>;
+ qcom,msm-mi2s-tx-lines = <3>;
+ };
+};
+
+&pm660l_3 {
+ pmic_analog_codec: analog-codec@f000 {
+ status = "okay";
+ compatible = "qcom,pmic-analog-codec";
+ reg = <0xf000 0x200>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x3 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "spk_cnp_int",
+ "spk_clip_int",
+ "spk_ocp_int",
+ "ins_rem_det1",
+ "but_rel_det",
+ "but_press_det",
+ "ins_rem_det",
+ "mbhc_int",
+ "ear_ocp_int",
+ "hphr_ocp_int",
+ "hphl_ocp_det",
+ "ear_cnp_int",
+ "hphr_cnp_int",
+ "hphl_cnp_int";
+
+
+ cdc-vdda-cp-supply = <&pm660_s4>;
+ qcom,cdc-vdda-cp-voltage = <1900000 2050000>;
+ qcom,cdc-vdda-cp-current = <50000>;
+
+ cdc-vdd-pa-supply = <&pm660_s4>;
+ qcom,cdc-vdd-pa-voltage = <2040000 2040000>;
+ qcom,cdc-vdd-pa-current = <260000>;
+
+ cdc-vdd-mic-bias-supply = <&pm660l_l7>;
+ qcom,cdc-vdd-mic-bias-voltage = <3088000 3088000>;
+ qcom,cdc-vdd-mic-bias-current = <5000>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+
+ qcom,cdc-static-supplies = "cdc-vdda-cp",
+ "cdc-vdd-pa";
+
+ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+
+ /*
+ * Not marking address @ as driver searches this child
+ * with name msm-dig-codec
+ */
+ msm_digital_codec: msm-dig-codec {
+ compatible = "qcom,msm-digital-codec";
+ reg = <0x62ec0000 0x0>;
+ };
+ };
+};
+
+&pm660_gpios {
+ gpio@c200 {
+ status = "ok";
+ qcom,mode = <1>;
+ qcom,pull = <4>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ qcom,out-strength = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-lpi.dtsi b/arch/arm64/boot/dts/qcom/sdm670-lpi.dtsi
new file mode 100644
index 0000000..6e92f0e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-lpi.dtsi
@@ -0,0 +1,284 @@
+/* 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.
+ */
+
+&soc {
+ lpi_tlmm: lpi_pinctrl@62b40000 {
+ compatible = "qcom,lpi-pinctrl";
+ reg = <0x62b40000 0x0>;
+ qcom,num-gpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ cdc_pdm_clk_active: cdc_pdm_clk_active {
+ mux {
+ pins = "gpio18";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio18";
+ drive-strength = <8>;
+ output-high;
+ };
+ };
+
+ cdc_pdm_clk_sleep: cdc_pdm_clk_sleep {
+ mux {
+ pins = "gpio18";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio18";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_pdm_sync_active: cdc_pdm_sync_active {
+ mux {
+ pins = "gpio19";
+ function = "func3";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <8>;
+ output-high;
+ };
+ };
+
+ cdc_pdm_sync_sleep: cdc_pdm_sync_sleep {
+ mux {
+ pins = "gpio19";
+ function = "func3";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_pdm_rx0_active: cdc_pdm_rx0_active {
+ mux {
+ pins = "gpio21";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <8>;
+ output-high;
+ };
+ };
+
+ cdc_pdm_rx0_sleep: cdc_pdm_rx0_sleep {
+ mux {
+ pins = "gpio21";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_pdm_rx1_2_active: cdc_pdm_rx1_2_active {
+ mux {
+ pins = "gpio23", "gpio25";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio23", "gpio25";
+ drive-strength = <8>;
+ output-high;
+ };
+ };
+
+ cdc_pdm_rx1_2_sleep: cdc_pdm_rx1_2_sleep {
+ mux {
+ pins = "gpio23", "gpio25";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio23", "gpio25";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_pdm_2_gpios_active: cdc_pdm_2_gpios_active {
+ mux {
+ pins = "gpio20";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <8>;
+ };
+ };
+
+ cdc_pdm_2_gpios_sleep: cdc_pdm_2_gpios_sleep {
+ mux {
+ pins = "gpio20";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cdc_rx0_comp_active: cdc_pdm_rx0_comp_active {
+ mux {
+ pins = "gpio22";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <8>;
+ };
+ };
+
+ cdc_rx0_comp_sleep: cdc_pdm_rx0_comp_sleep {
+ mux {
+ pins = "gpio22";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio22";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cdc_rx1_comp_active: cdc_pdm_rx1_comp_active {
+ mux {
+ pins = "gpio24";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio24";
+ drive-strength = <8>;
+ };
+ };
+
+ cdc_rx1_comp_sleep: cdc_pdm_rx1_comp_sleep {
+ mux {
+ pins = "gpio24";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio24";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ lpi_cdc_reset_active: lpi_cdc_reset_active {
+ mux {
+ pins = "gpio29";
+ function = "func2";
+ };
+ config {
+ pins = "gpio29";
+ drive-strength = <16>;
+ output-high;
+ };
+ };
+
+ lpi_cdc_reset_sleep: lpi_cdc_reset_sleep {
+ mux {
+ pins = "gpio29";
+ function = "func2";
+ };
+
+ config {
+ pins = "gpio29";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_dmic12_gpios_active: dmic12_gpios_active {
+ mux {
+ pins = "gpio26", "gpio28";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio26", "gpio28";
+ drive-strength = <8>;
+ output-high;
+ };
+ };
+
+ cdc_dmic12_gpios_sleep: dmic12_gpios_sleep {
+ mux {
+ pins = "gpio26", "gpio28";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio26", "gpio28";
+ drive-strength = <2>;
+ bias-disable;
+ output-low;
+ };
+ };
+
+ cdc_dmic34_gpios_active: dmic34_gpios_active {
+ mux {
+ pins = "gpio27", "gpio29";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio27", "gpio29";
+ drive-strength = <8>;
+ input-enable;
+ };
+ };
+
+ cdc_dmic34_gpios_sleep: dmic34_gpios_sleep {
+ mux {
+ pins = "gpio27", "gpio29";
+ function = "func1";
+ };
+
+ config {
+ pins = "gpio27", "gpio29";
+ drive-strength = <2>;
+ pull-down;
+ input-enable;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 46d4aa6..73df253 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -1244,5 +1244,198 @@
};
};
+ /* USB C analog configuration */
+ wcd_usbc_analog_en1 {
+ wcd_usbc_analog_en1_idle: wcd_usbc_ana_en1_idle {
+ mux {
+ pins = "gpio49";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio49";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+
+ wcd_usbc_analog_en1_active: wcd_usbc_ana_en1_active {
+ mux {
+ pins = "gpio49";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio49";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
+ sdw_clk_pin {
+ sdw_clk_sleep: sdw_clk_sleep {
+ mux {
+ pins = "gpio65";
+ function = "wsa_clk";
+ };
+
+ config {
+ pins = "gpio65";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+ };
+
+ sdw_clk_active: sdw_clk_active {
+ mux {
+ pins = "gpio65";
+ function = "wsa_clk";
+ };
+
+ config {
+ pins = "gpio65";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+ };
+ };
+
+ sdw_data_pin {
+ sdw_data_sleep: sdw_data_sleep {
+ mux {
+ pins = "gpio66";
+ function = "wsa_data";
+ };
+
+ config {
+ pins = "gpio66";
+ drive-strength = <4>;
+ bias-bus-hold;
+ };
+ };
+
+ sdw_data_active: sdw_data_active {
+ mux {
+ pins = "gpio66";
+ function = "wsa_data";
+ };
+
+ config {
+ pins = "gpio66";
+ drive-strength = <4>;
+ bias-bus-hold;
+ };
+ };
+ };
+
+ /* WSA speaker reset pins */
+ spkr_1_sd_n {
+ spkr_1_sd_n_sleep: spkr_1_sd_n_sleep {
+ mux {
+ pins = "gpio67";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio67";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down;
+ input-enable;
+ };
+ };
+
+ spkr_1_sd_n_active: spkr_1_sd_n_active {
+ mux {
+ pins = "gpio67";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio67";
+ drive-strength = <16>; /* 16 mA */
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
+ spkr_2_sd_n {
+ spkr_2_sd_n_sleep: spkr_2_sd_n_sleep {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio68";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down;
+ input-enable;
+ };
+ };
+
+ spkr_2_sd_n_active: spkr_2_sd_n_active {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio68";
+ drive-strength = <16>; /* 16 mA */
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
+ wcd_gnd_mic_swap {
+ wcd_gnd_mic_swap_idle: wcd_gnd_mic_swap_idle {
+ mux {
+ pins = "gpio40";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio40";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+
+ wcd_gnd_mic_swap_active: wcd_gnd_mic_swap_active {
+ mux {
+ pins = "gpio40";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio40";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
+ wcd9xxx_intr {
+ wcd_intr_default: wcd_intr_default{
+ mux {
+ pins = "gpio80";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio80";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* pull down */
+ input-enable;
+ };
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index b0c436f..0a8c49f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -15,331 +15,6 @@
/* Stub regulators */
/ {
- pm660_s4: regulator-pm660-s4 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_s4";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <2040000>;
- regulator-max-microvolt = <2040000>;
- };
-
- /* pm660 S5 - VDD_MODEM supply */
- pm660_s5_level: regulator-pm660-s5 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_s5_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660_s6: regulator-pm660-s6 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_s6";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <1352000>;
- regulator-max-microvolt = <1352000>;
- };
-
- /* pm660l S1 - VDD_MX supply */
- pm660l_s1_level: regulator-pm660l-s1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s1_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_s1_floor_level: regulator-pm660l-s1-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s1_floor_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_s1_level_ao: regulator-pm660l-s1-level-ao {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s1_level_ao";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- /* pm660l S2 - VDD_GFX supply */
- pm660l_s2_level: regulator-pm660l-s2 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s2_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- /* pm660l S3 + S4 - VDD_CX supply */
- pm660l_s3_level: regulator-pm660l-s3-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s3_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_s3_floor_level: regulator-pm660l-s3-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_s3_floor_level";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_s3_level_ao: regulator-pm660l-s3-level-ao {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_s3_level_ao";
- qcom,hpm-min-load = <100000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660_l1: regulator-pm660-l1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l1";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1250000>;
- };
-
- pm660_l2: regulator-pm660-l2 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l2";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- };
-
- pm660_l3: regulator-pm660-l3 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l3";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- };
-
- pm660_l5: regulator-pm660-l5 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l5";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <800000>;
- };
-
- pm660_l6: regulator-pm660-l6 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l6";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1304000>;
- regulator-max-microvolt = <1304000>;
- };
-
- pm660_l7: regulator-pm660-l7 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l7";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- pm660_l8: regulator-pm660-l8 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l8";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l9: regulator-pm660-l9 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l9";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l10: regulator-pm660-l10 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l10";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l11: regulator-pm660-l11 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l11";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l12: regulator-pm660-l12 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l12";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l13: regulator-pm660-l13 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l13";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l14: regulator-pm660-l14 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l14";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- pm660_l15: regulator-pm660-l15 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l15";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pm660_l16: regulator-pm660-l16 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l16";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- };
-
- pm660_l17: regulator-pm660-l17 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l17";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- };
-
- pm660_l19: regulator-pm660-l19 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660_l19";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3312000>;
- regulator-max-microvolt = <3312000>;
- };
-
- pm660l_l1: regulator-pm660l-l1 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l1";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <880000>;
- regulator-max-microvolt = <900000>;
- };
-
- pm660l_l2: regulator-pm660l-l2 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l2";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2960000>;
- };
-
- pm660l_l3: regulator-pm660l-l3 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l3";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <3008000>;
- };
-
- pm660l_l4: regulator-pm660l-l4 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l4";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2960000>;
- regulator-max-microvolt = <2960000>;
- };
-
- pm660l_l5: regulator-pm660l-l5 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l5";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <2960000>;
- regulator-max-microvolt = <2960000>;
- };
-
- pm660l_l6: regulator-pm660l-l6 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l6";
- qcom,hpm-min-load = <5000>;
- regulator-min-microvolt = <3008000>;
- regulator-max-microvolt = <3300000>;
- };
-
- pm660l_l7: regulator-pm660l-l7 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l7";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3088000>;
- regulator-max-microvolt = <3100000>;
- };
-
- pm660l_l8: regulator-pm660l-l8 {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l8";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3312000>;
- };
-
- /* pm660l L9 = VDD_LPI_CX supply */
- pm660l_l9_level: regulator-pm660l-l9-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l9_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_l9_floor_level: regulator-pm660l-l9-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l9_floor_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- /* pm660l L10 = VDD_LPI_MX supply */
- pm660l_l10_level: regulator-pm660l-l10-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l10_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_l10_floor_level: regulator-pm660l-l10-floor-level {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_l10_floor_level";
- qcom,hpm-min-load = <10000>;
- regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
- regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
- };
-
- pm660l_bob: regulator-pm660l-bob {
- compatible = "qcom,stub-regulator";
- regulator-name = "pm660l_bob";
- regulator-min-microvolt = <3312000>;
- regulator-max-microvolt = <3312000>;
- };
-
apc0_pwrcl_vreg: regulator-pwrcl {
compatible = "qcom,stub-regulator";
regulator-name = "apc0_pwrcl_corner";
@@ -362,6 +37,598 @@
};
};
+&soc {
+ /* RPMh regulators: */
+ rpmh-regulator-smpa4 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "smpa4";
+ pm660_s4: regulator-pm660-s4 {
+ regulator-name = "pm660_s4";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <2040000>;
+ regulator-max-microvolt = <2040000>;
+ qcom,init-voltage = <2040000>;
+ };
+ };
+
+ /* pm660 S5 - VDD_MODEM supply */
+ rpmh-regulator-modemlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "mss.lvl";
+ pm660_s5_level: regulator-pm660-s5 {
+ regulator-name = "pm660_s5_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ };
+ };
+
+ rpmh-regulator-smpa6 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "smpa6";
+ pm660_s6: regulator-pm660-s6 {
+ regulator-name = "pm660_s6";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
+ qcom,init-voltage = <1352000>;
+ };
+ };
+
+ /* pm660l S1 - VDD_MX supply */
+ rpmh-regulator-mxlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "mx.lvl";
+ pm660l_s1_level: regulator-pm660l-s1 {
+ regulator-name = "pm660l_s1_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ };
+
+ pm660l_s1_level_ao: regulator-pm660l-s1-level-ao {
+ regulator-name = "pm660l_s1_level_ao";
+ qcom,set = <RPMH_REGULATOR_SET_ACTIVE>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ };
+ };
+
+ /* pm660l S2 - VDD_GFX supply */
+ rpmh-regulator-gfxlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "gfx.lvl";
+ pm660l_s2_level: regulator-pm660l-s2 {
+ regulator-name = "pm660l_s2_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt
+ = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+ regulator-max-microvolt
+ = <RPMH_REGULATOR_LEVEL_MAX>;
+ qcom,init-voltage-level
+ = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+ };
+ };
+
+ /* pm660l S3 + S4 - VDD_CX supply */
+ rpmh-regulator-cxlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "cx.lvl";
+ pm660l_s3_level-parent-supply = <&pm660l_s1_level>;
+ pm660l_s3_level_ao-parent-supply = <&pm660l_s1_level_ao>;
+ pm660l_s3_level: regulator-pm660l-s3-level {
+ regulator-name = "pm660l_s3_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ qcom,min-dropout-voltage-level = <(-1)>;
+ };
+
+ pm660l_s3_level_ao: regulator-pm660l-s3-level-ao {
+ regulator-name = "pm660l_s3_level_ao";
+ qcom,set = <RPMH_REGULATOR_SET_ACTIVE>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ qcom,min-dropout-voltage-level = <(-1)>;
+ };
+ };
+
+ rpmh-regulator-ldoa1 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa1";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l1: regulator-pm660-l1 {
+ regulator-name = "pm660_l1";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1250000>;
+ qcom,init-voltage = <1200000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa2 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa2";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l2: regulator-pm660-l2 {
+ regulator-name = "pm660_l2";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ qcom,init-voltage = <1000000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa3 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa3";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l3: regulator-pm660-l3 {
+ regulator-name = "pm660_l3";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ qcom,init-voltage = <1000000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa5 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa5";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l5: regulator-pm660-l5 {
+ regulator-name = "pm660_l5";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ qcom,init-voltage = <800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa6 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa6";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l6: regulator-pm660-l6 {
+ regulator-name = "pm660_l6";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ qcom,init-voltage = <1304000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa7 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa7";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l7: regulator-pm660-l7 {
+ regulator-name = "pm660_l7";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,init-voltage = <1200000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa8 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa8";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l8: regulator-pm660-l8 {
+ regulator-name = "pm660_l8";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa9 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa9";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l9: regulator-pm660-l9 {
+ regulator-name = "pm660_l9";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa10 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa10";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l10: regulator-pm660-l10 {
+ regulator-name = "pm660_l10";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa11 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa11";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l11: regulator-pm660-l11 {
+ regulator-name = "pm660_l11";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa12 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa12";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l12: regulator-pm660-l12 {
+ regulator-name = "pm660_l12";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa13 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa13";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l13: regulator-pm660-l13 {
+ regulator-name = "pm660_l13";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa14 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa14";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l14: regulator-pm660-l14 {
+ regulator-name = "pm660_l14";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa15 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa15";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l15: regulator-pm660-l15 {
+ regulator-name = "pm660_l15";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa16 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa16";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l16: regulator-pm660-l16 {
+ regulator-name = "pm660_l16";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ qcom,init-voltage = <2700000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa17 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa17";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l17: regulator-pm660-l17 {
+ regulator-name = "pm660_l17";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldoa19 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldoa19";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660_l19: regulator-pm660-l19 {
+ regulator-name = "pm660_l19";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3312000>;
+ qcom,init-voltage = <3312000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob1 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob1";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l1: regulator-pm660l-l1 {
+ regulator-name = "pm660l_l1";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <900000>;
+ qcom,init-voltage = <880000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob2 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob2";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l2: regulator-pm660l-l2 {
+ regulator-name = "pm660l_l2";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob3 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob3";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l3: regulator-pm660l-l3 {
+ regulator-name = "pm660l_l3";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <3008000>;
+ qcom,init-voltage = <2850000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob4 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob4";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l4: regulator-pm660l-l4 {
+ regulator-name = "pm660l_l4";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ qcom,init-voltage = <2960000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob5 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob5";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l5: regulator-pm660l-l5 {
+ regulator-name = "pm660l_l5";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ qcom,init-voltage = <2960000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob6 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob6";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l6: regulator-pm660l-l6 {
+ regulator-name = "pm660l_l6";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3300000>;
+ qcom,init-voltage = <3008000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob7 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob7";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l7: regulator-pm660l-l7 {
+ regulator-name = "pm660l_l7";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <3088000>;
+ regulator-max-microvolt = <3100000>;
+ qcom,init-voltage = <3088000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ rpmh-regulator-ldob8 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "ldob8";
+ qcom,supported-modes =
+ <RPMH_REGULATOR_MODE_LDO_LPM
+ RPMH_REGULATOR_MODE_LDO_HPM>;
+ qcom,mode-threshold-currents = <0 1>;
+ pm660l_l8: regulator-pm660l-l8 {
+ regulator-name = "pm660l_l8";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3312000>;
+ qcom,init-voltage = <3300000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+ };
+
+ /* pm660l L9 = VDD_LPI_CX supply */
+ rpmh-regulator-lcxlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "lcx.lvl";
+ pm660l_l9_level: regulator-pm660l-l9-level {
+ regulator-name = "pm660l_l9_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ };
+ };
+
+ /* pm660l L10 = VDD_LPI_MX supply */
+ rpmh-regulator-lmxlvl {
+ compatible = "qcom,rpmh-arc-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "lmx.lvl";
+ pm660l_l10_level: regulator-pm660l-l10-level {
+ regulator-name = "pm660l_l10_level";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
+ regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+ };
+ };
+
+ rpmh-regulator-bobb1 {
+ compatible = "qcom,rpmh-vrm-regulator";
+ mboxes = <&apps_rsc 0>;
+ qcom,resource-name = "bobb1";
+ pm660l_bob: regulator-pm660l-bob {
+ regulator-name = "pm660l_bob";
+ qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3312000>;
+ qcom,init-voltage = <3312000>;
+ };
+ };
+};
+
&pm660_charger {
smb2_vbus: qcom,smb2-vbus {
regulator-name = "smb2-vbus";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-wcd.dtsi b/arch/arm64/boot/dts/qcom/sdm670-wcd.dtsi
new file mode 100644
index 0000000..f8d2a04
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-wcd.dtsi
@@ -0,0 +1,167 @@
+/* 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.
+ */
+
+&slim_aud {
+ tavil_codec {
+ wcd: wcd_pinctrl@5 {
+ compatible = "qcom,wcd-pinctrl";
+ qcom,num-gpios = <5>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ us_euro_sw_wcd_active: us_euro_sw_wcd_active {
+ mux {
+ pins = "gpio1";
+ };
+
+ config {
+ pins = "gpio1";
+ output-high;
+ };
+ };
+
+ us_euro_sw_wcd_sleep: us_euro_sw_wcd_sleep {
+ mux {
+ pins = "gpio1";
+ };
+
+ config {
+ pins = "gpio1";
+ output-low;
+ };
+ };
+
+ spkr_1_wcd_en_active: spkr_1_wcd_en_active {
+ mux {
+ pins = "gpio2";
+ };
+
+ config {
+ pins = "gpio2";
+ output-high;
+ };
+ };
+
+ spkr_1_wcd_en_sleep: spkr_1_wcd_en_sleep {
+ mux {
+ pins = "gpio2";
+ };
+
+ config {
+ pins = "gpio2";
+ input-enable;
+ };
+ };
+
+ spkr_2_wcd_en_active: spkr_2_sd_n_active {
+ mux {
+ pins = "gpio3";
+ };
+
+ config {
+ pins = "gpio3";
+ output-high;
+ };
+ };
+
+ spkr_2_wcd_en_sleep: spkr_2_sd_n_sleep {
+ mux {
+ pins = "gpio3";
+ };
+
+ config {
+ pins = "gpio3";
+ input-enable;
+ };
+ };
+
+ hph_en0_wcd_active: hph_en0_wcd_active {
+ mux {
+ pins = "gpio4";
+ };
+
+ config {
+ pins = "gpio4";
+ output-high;
+ };
+ };
+
+ hph_en0_wcd_sleep: hph_en0_wcd_sleep {
+ mux {
+ pins = "gpio4";
+ };
+
+ config {
+ pins = "gpio4";
+ output-low;
+ };
+ };
+
+ hph_en1_wcd_active: hph_en1_wcd_active {
+ mux {
+ pins = "gpio5";
+ };
+
+ config {
+ pins = "gpio5";
+ output-high;
+ };
+ };
+
+ hph_en1_wcd_sleep: hph_en1_wcd_sleep {
+ mux {
+ pins = "gpio5";
+ };
+
+ config {
+ pins = "gpio5";
+ output-low;
+ };
+ };
+ };
+
+ wsa_spkr_wcd_sd1: msm_cdc_pinctrll {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_1_wcd_en_active>;
+ pinctrl-1 = <&spkr_1_wcd_en_sleep>;
+ };
+
+ wsa_spkr_wcd_sd2: msm_cdc_pinctrlr {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_2_wcd_en_active>;
+ pinctrl-1 = <&spkr_2_wcd_en_sleep>;
+ };
+
+ tavil_us_euro_sw: msm_cdc_pinctrl_us_euro_sw {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&us_euro_sw_wcd_active>;
+ pinctrl-1 = <&us_euro_sw_wcd_sleep>;
+ };
+
+ tavil_hph_en0: msm_cdc_pinctrl_hph_en0 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&hph_en0_wcd_active>;
+ pinctrl-1 = <&hph_en0_wcd_sleep>;
+ };
+
+ tavil_hph_en1: msm_cdc_pinctrl_hph_en1 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&hph_en1_wcd_active>;
+ pinctrl-1 = <&hph_en1_wcd_sleep>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-wsa881x.dtsi b/arch/arm64/boot/dts/qcom/sdm670-wsa881x.dtsi
new file mode 100644
index 0000000..c35850d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-wsa881x.dtsi
@@ -0,0 +1,45 @@
+/* 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.
+ */
+
+&slim_aud {
+ tavil_codec {
+ swr_master {
+ compatible = "qcom,swr-wcd";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ wsa881x_0211: wsa881x@20170211 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170211>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd1>;
+ };
+
+ wsa881x_0212: wsa881x@20170212 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170212>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd2>;
+ };
+
+ wsa881x_0213: wsa881x@21170213 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170213>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd1>;
+ };
+
+ wsa881x_0214: wsa881x@21170214 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170214>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd2>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 3bef777..0dec428 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -1815,6 +1815,89 @@
qcom,scaling-lower-bus-speed-mode = "DDR52";
status = "disabled";
};
+
+ qcom,msm-cdsp-loader {
+ compatible = "qcom,cdsp-loader";
+ qcom,proc-img-to-load = "cdsp";
+ };
+
+ qcom,msm-adsprpc-mem {
+ compatible = "qcom,msm-adsprpc-mem-region";
+ memory-region = <&adsp_mem>;
+ };
+
+ qcom,msm_fastrpc {
+ compatible = "qcom,msm-fastrpc-compute";
+
+ qcom,msm_fastrpc_compute_cb1 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1421 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb2 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1422 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb3 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1423 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb4 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1424 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb5 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1425 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb6 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ iommus = <&apps_smmu 0x1426 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb7 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ qcom,secure-context-bank;
+ iommus = <&apps_smmu 0x1429 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb8 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "cdsprpc-smd";
+ qcom,secure-context-bank;
+ iommus = <&apps_smmu 0x142A 0x30>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb9 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&apps_smmu 0x1803 0x0>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb10 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&apps_smmu 0x1804 0x0>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb11 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&apps_smmu 0x1805 0x0>;
+ dma-coherent;
+ };
+ };
};
#include "sdm670-pinctrl.dtsi"
@@ -1842,6 +1925,18 @@
status = "ok";
};
+&hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc {
+ status = "ok";
+};
+
+&hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc {
+ status = "ok";
+};
+
+&hlos1_vote_mmnoc_mmu_tbu_sf_gdsc {
+ status = "ok";
+};
+
&bps_gdsc {
status = "ok";
};
@@ -1878,6 +1973,7 @@
clock-names = "core_root_clk";
clocks = <&clock_gfx GPU_CC_GX_GFX3D_CLK_SRC>;
qcom,force-enable-root-clk;
+ parent-supply = <&pm660l_s2_level>;
status = "ok";
};
@@ -1898,3 +1994,4 @@
#include "pm660.dtsi"
#include "pm660l.dtsi"
#include "sdm670-regulator.dtsi"
+#include "sdm670-audio.dtsi"
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
index 0006937..a78672d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp-overlay.dts
@@ -27,7 +27,7 @@
/ {
model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel CDP";
compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <1 1>;
};
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
index 2675b96..a776d42 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp-overlay.dts
@@ -27,7 +27,7 @@
/ {
model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel MTP";
compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <8 1>;
};
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
index 76b89eb..c6622d4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd-overlay.dts
@@ -27,7 +27,7 @@
/ {
model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel QRD";
compatible = "qcom,sdm845-qrd", "qcom,sdm845", "qcom,qrd";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <11 1>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
index efc78e0..7991aad 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
@@ -26,6 +26,6 @@
/ {
model = "Qualcomm Technologies, Inc. SDM845 v1 CDP";
compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <1 0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index 3f05846..de50aec 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -27,26 +27,20 @@
compatible = "qcom,devbw";
governor = "bw_vbif";
qcom,src-dst-ports = <26 512>;
- /*
- * active-only flag is used while registering the bus
- * governor.It helps release the bus vote when the CPU
- * subsystem is inactiv3
- */
- qcom,active-only;
qcom,bw-tbl =
< 0 /* off */ >,
- < 762 /* 100 MHz */ >,
- < 1144 /* 150 MHz */ >,
- < 1525 /* 200 MHz */ >,
- < 2288 /* 300 MHz */ >,
- < 3143 /* 412 MHz */ >,
- < 4173 /* 547 MHz */ >,
- < 5195 /* 681 MHz */ >,
- < 5859 /* 768 MHz */ >,
- < 7759 /* 1017 MHz */ >,
- < 9887 /* 1296 MHz */ >,
- < 11863 /* 1555 MHz */ >,
- < 13763 /* 1804 MHz */ >;
+ < 381 /* 100 MHz */ >,
+ < 572 /* 150 MHz */ >,
+ < 762 /* 200 MHz */ >,
+ < 1144 /* 300 MHz */ >,
+ < 1571 /* 412 MHz */ >,
+ < 2086 /* 547 MHz */ >,
+ < 2597 /* 681 MHz */ >,
+ < 2929 /* 768 MHz */ >,
+ < 3879 /* 1017 MHz */ >,
+ < 4943 /* 1296 MHz */ >,
+ < 5931 /* 1555 MHz */ >,
+ < 6881 /* 1804 MHz */ >;
};
msm_gpu: qcom,kgsl-3d0@5000000 {
@@ -61,7 +55,7 @@
qcom,chipid = <0x06030000>;
- qcom,initial-pwrlevel = <2>;
+ qcom,initial-pwrlevel = <5>;
qcom,gpu-quirk-hfi-use-reg;
@@ -99,23 +93,24 @@
qcom,gpubw-dev = <&gpubw>;
qcom,bus-control;
qcom,msm-bus,name = "grp3d";
+ qcom,bus-width = <32>;
qcom,msm-bus,num-cases = <13>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<26 512 0 0>,
- <26 512 0 800000>, // 1 bus=100
- <26 512 0 1200000>, // 2 bus=150
- <26 512 0 1600000>, // 3 bus=200
- <26 512 0 2400000>, // 4 bus=300
- <26 512 0 3296000>, // 5 bus=412
- <26 512 0 4376000>, // 6 bus=547
- <26 512 0 5448000>, // 7 bus=681
- <26 512 0 6144000>, // 8 bus=768
- <26 512 0 8136000>, // 9 bus=1017
- <26 512 0 10368000>, // 10 bus=1296
- <26 512 0 12440000>, // 11 bus=1555
- <26 512 0 14432000>; // 12 bus=1804
+ <26 512 0 400000>, // 1 bus=100
+ <26 512 0 600000>, // 2 bus=150
+ <26 512 0 800000>, // 3 bus=200
+ <26 512 0 1200000>, // 4 bus=300
+ <26 512 0 1648000>, // 5 bus=412
+ <26 512 0 2188000>, // 6 bus=547
+ <26 512 0 2724000>, // 7 bus=681
+ <26 512 0 3072000>, // 8 bus=768
+ <26 512 0 4068000>, // 9 bus=1017
+ <26 512 0 5184000>, // 10 bus=1296
+ <26 512 0 6220000>, // 11 bus=1555
+ <26 512 0 7216000>; // 12 bus=1804
/* GDSC regulator names */
regulator-names = "vddcx", "vdd";
@@ -170,31 +165,65 @@
qcom,gpu-pwrlevel@0 {
reg = <0>;
- qcom,gpu-freq = <280000000>;
- qcom,bus-freq = <4>;
- qcom,bus-min = <3>;
- qcom,bus-max = <5>;
+ qcom,gpu-freq = <600000000>;
+ qcom,bus-freq = <12>;
+ qcom,bus-min = <11>;
+ qcom,bus-max = <12>;
};
qcom,gpu-pwrlevel@1 {
reg = <1>;
- qcom,gpu-freq = <280000000>;
- qcom,bus-freq = <4>;
- qcom,bus-min = <3>;
- qcom,bus-max = <5>;
+ qcom,gpu-freq = <548000000>;
+ qcom,bus-freq = <12>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <12>;
};
qcom,gpu-pwrlevel@2 {
reg = <2>;
+ qcom,gpu-freq = <487000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <11>;
+ };
+
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <425000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <10>;
+ };
+
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <338000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <9>;
+ };
+
+
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
qcom,gpu-freq = <280000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <210000000>;
qcom,bus-freq = <4>;
qcom,bus-min = <3>;
qcom,bus-max = <5>;
};
- qcom,gpu-pwrlevel@3 {
- reg = <3>;
+ qcom,gpu-pwrlevel@7 {
+ reg = <7>;
qcom,gpu-freq = <0>;
qcom,bus-freq = <0>;
qcom,bus-min = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
new file mode 100644
index 0000000..b9e9c34
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
@@ -0,0 +1,393 @@
+/* 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.
+ */
+
+/ {
+ /delete-node/regulator-pm8998-s4;
+};
+
+&dsi_sharp_4k_dsc_video_display {
+ /delete-property/ vddio-supply;
+};
+
+&dsi_sharp_4k_dsc_cmd_display {
+ /delete-property/ vddio-supply;
+};
+
+&dsi_sharp_1080_cmd_display {
+ /delete-property/ vddio-supply;
+};
+
+&dsi_dual_sharp_1080_120hz_cmd_display {
+ /delete-property/ vddio-supply;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
+&dsi_dual_nt35597_truly_cmd_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
+&dsi_nt35597_truly_dsc_cmd_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
+&dsi_nt35597_truly_dsc_video_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
+&sde_dp {
+ status = "disabled";
+ /delete-property/ vdda-1p2-supply;
+ /delete-property/ vdda-0p9-supply;
+ /delete-property/ qcom,dp-usbpd-detection;
+};
+
+&mdss_dp_pll {
+ status = "disabled";
+};
+
+&bluetooth {
+ /delete-property/ qca,bt-vdd-io-supply;
+ /delete-property/ qca,bt-vdd-xtal-supply;
+ /delete-property/ qca,bt-vdd-core-supply;
+ /delete-property/ qca,bt-vdd-pa-supply;
+ /delete-property/ qca,bt-vdd-ldo-supply;
+};
+
+&ufsphy_mem {
+ /delete-property/ vdda-phy-supply;
+ /delete-property/ vdda-pll-supply;
+};
+
+&ufshc_mem {
+ /delete-property/ vcc-supply;
+ /delete-property/ vccq2-supply;
+ /delete-property/ qcom,vddp-ref-clk-supply;
+};
+
+&ufsphy_card {
+ /delete-property/ vdda-phy-supply;
+ /delete-property/ vdda-pll-supply;
+};
+
+&ufshc_card {
+ /delete-property/ vcc-supply;
+ /delete-property/ vccq2-supply;
+ /delete-property/ qcom,vddp-ref-clk-supply;
+};
+
+&sdhc_2 {
+ /delete-property/ vdd-supply;
+ /delete-property/ vdd-io-supply;
+};
+
+&vendor {
+ extcon_usb1 {
+ /delete-property/ id-gpio;
+ /delete-property/ vbus-gpio;
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+ };
+
+ usb1_vbus_vreg {
+ /delete-property/ gpio;
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+ };
+};
+
+&qupv3_se3_i2c {
+ nq@28 {
+ /delete-property/ qcom,nq-clkreq;
+ /* delete "nfc_clk_default" -- PMIC GPIO */
+ pinctrl-0 = <&nfc_int_active &nfc_enable_active>;
+ };
+};
+
+&pcie0 {
+ /delete-property/ vreg-1.8-supply;
+ /delete-property/ vreg-0.9-supply;
+ /delete-property/ vreg-cx-supply;
+};
+
+&cam_csiphy0 {
+ /delete-property/ mipi-csi-vdd-supply;
+};
+
+&cam_csiphy1 {
+ /delete-property/ mipi-csi-vdd-supply;
+};
+
+&cam_csiphy2 {
+ /delete-property/ mipi-csi-vdd-supply;
+};
+
+&led_flash_rear {
+ /delete-property/ flash-source;
+ /delete-property/ torch-source;
+ /delete-property/ switch-source;
+};
+
+&led_flash_front {
+ /delete-property/ flash-source;
+ /delete-property/ torch-source;
+ /delete-property/ switch-source;
+};
+
+&actuator_regulator {
+ /delete-property/ vin-supply;
+};
+
+
+&eeprom_rear {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+};
+
+&eeprom_rear_aux {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+};
+
+&eeprom_front {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+};
+
+&cam_cci {
+ qcom,cam-sensor@0 {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+ };
+
+ qcom,cam-sensor@1 {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+ };
+
+ qcom,cam-sensor@2 {
+ /delete-property/ cam_vio-supply;
+ /delete-property/ cam_vana-supply;
+ };
+};
+
+&clock_gcc {
+ /delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_cx_ao-supply;
+};
+
+&clock_videocc {
+ /delete-property/ vdd_cx-supply;
+};
+
+&clock_camcc {
+ /delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_mx-supply;
+};
+
+&clock_dispcc {
+ /delete-property/ vdd_cx-supply;
+};
+
+&clock_gpucc {
+ /delete-property/ vdd_cx-supply;
+};
+
+&clock_gfx {
+ /delete-property/ vdd_gfx-supply;
+ /delete-property/ vdd_mx-supply;
+};
+
+&pil_modem {
+ /delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_mx-supply;
+};
+
+&gpu_gx_gdsc {
+ /delete-property/ parent-supply;
+};
+
+&soc {
+ /delete-node/ gpio_keys;
+
+ qcom,lpass@17300000 {
+ /delete-property/ vdd_cx-supply;
+ };
+
+ qcom,ssc@5c00000 {
+ /delete-property/ vdd_cx-supply;
+ };
+
+ qcom,spss@1880000 {
+ /delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_mx-supply;
+ };
+
+ qcom,turing@8300000 {
+ /delete-property/ vdd_cx-supply;
+ };
+
+ qcom,qbt1000 {
+ /delete-property/ qcom,finger-detect-gpio;
+ };
+
+ qcom,icnss@18800000 {
+ /delete-property/ vdd-0.8-cx-mx-supply;
+ /delete-property/ vdd-1.8-xo-supply;
+ /delete-property/ vdd-1.3-rfa-supply;
+ /delete-property/ vdd-3.3-ch0-supply;
+ };
+
+ qcom,mdss_dsi_ctrl0@ae94000 {
+ vdda-1p2-supply = <&pm660_l1>;
+ };
+
+ qcom,mdss_dsi_ctrl1@ae96000 {
+ vdda-1p2-supply = <&pm660_l1>;
+ };
+
+ qcom,mdss_dsi_phy0@ae94400 {
+ vdda-0p9-supply = <&pm660l_l1>;
+ };
+
+ qcom,mdss_dsi_phy0@ae96400 {
+ vdda-0p9-supply = <&pm660l_l1>;
+ };
+
+ gpio-regulator@1 {
+ /delete-property/ gpio;
+ /delete-property/ vin-supply;
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+ };
+
+ gpio-regulator@2 {
+ /delete-property/ gpio;
+ /delete-property/ vin-supply;
+ /delete-property/ pinctrl-names;
+ /delete-property/ pinctrl-0;
+ };
+
+ /delete-node/ qcom,spmi-debug@6b22000;
+
+};
+
+&wil6210 {
+ /delete-property/ vdd-supply;
+ /delete-property/ vddio-supply;
+};
+
+&usb0 {
+ /delete-property/ extcon;
+};
+
+&qusb_phy0 {
+ /delete-property/ vdd-supply;
+ /delete-property/ vdda18-supply;
+ /delete-property/ vdda33-supply;
+};
+
+&usb_qmp_dp_phy {
+ /delete-property/ vdd-supply;
+ /delete-property/ core-supply;
+};
+
+&qusb_phy1 {
+ /delete-property/ vdd-supply;
+ /delete-property/ vdda18-supply;
+ /delete-property/ vdda33-supply;
+};
+
+&usb_qmp_phy {
+ /delete-property/ vdd-supply;
+ /delete-property/ core-supply;
+};
+
+&soc {
+ /* Delete all regulators */
+ /delete-node/ cprh-ctrl@17dc0000;
+ /delete-node/ cprh-ctrl@17db0000;
+ /delete-node/ rpmh-regulator-ebilvl;
+ /delete-node/ rpmh-regulator-smpa2;
+ /delete-node/ rpmh-regulator-smpa3;
+ /delete-node/ rpmh-regulator-smpa5;
+ /delete-node/ rpmh-regulator-mxlvl;
+ /delete-node/ rpmh-regulator-smpa7;
+ /delete-node/ rpmh-regulator-cxlvl;
+ /delete-node/ rpmh-regulator-ldoa1;
+ /delete-node/ rpmh-regulator-ldoa2;
+ /delete-node/ rpmh-regulator-ldoa3;
+ /delete-node/ rpmh-regulator-lmxlvl;
+ /delete-node/ rpmh-regulator-ldoa5;
+ /delete-node/ rpmh-regulator-ldoa6;
+ /delete-node/ rpmh-regulator-ldoa7;
+ /delete-node/ rpmh-regulator-ldoa8;
+ /delete-node/ rpmh-regulator-ldoa9;
+ /delete-node/ rpmh-regulator-ldoa10;
+ /delete-node/ rpmh-regulator-ldoa11;
+ /delete-node/ rpmh-regulator-ldoa12;
+ /delete-node/ rpmh-regulator-ldoa13;
+ /delete-node/ rpmh-regulator-ldoa14;
+ /delete-node/ rpmh-regulator-ldoa15;
+ /delete-node/ rpmh-regulator-ldoa16;
+ /delete-node/ rpmh-regulator-ldoa17;
+ /delete-node/ rpmh-regulator-ldoa18;
+ /delete-node/ rpmh-regulator-ldoa19;
+ /delete-node/ rpmh-regulator-ldoa20;
+ /delete-node/ rpmh-regulator-ldoa21;
+ /delete-node/ rpmh-regulator-ldoa22;
+ /delete-node/ rpmh-regulator-ldoa23;
+ /delete-node/ rpmh-regulator-ldoa24;
+ /delete-node/ rpmh-regulator-ldoa25;
+ /delete-node/ rpmh-regulator-ldoa26;
+ /delete-node/ rpmh-regulator-lcxlvl;
+ /delete-node/ rpmh-regulator-ldoa28;
+ /delete-node/ rpmh-regulator-vsa1;
+ /delete-node/ rpmh-regulator-vsa2;
+ /delete-node/ rpmh-regulator-bobb1;
+ /delete-node/ rpmh-regulator-gfxlvl;
+ /delete-node/ rpmh-regulator-msslvl;
+ /delete-node/ rpmh-regulator-smpc3;
+ /delete-node/ ext_5v_boost;
+};
+
+&spmi_bus {
+ /delete-node/ qcom,pm8998@0;
+ /delete-node/ qcom,pm8998@1;
+ /delete-node/ qcom,pmi8998@2;
+ /delete-node/ qcom,pmi8998@3;
+ /delete-node/ qcom,pm8005@4;
+ /delete-node/ qcom,pm8005@5;
+};
+
+
+#include "pm660.dtsi"
+#include "pm660l.dtsi"
+#include "sdm670-regulator.dtsi"
+
+&soc {
+ /delete-node/ thermal-zones;
+};
+
+&pm660l_wled {
+ qcom,led-strings-list = [01 02];
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi
new file mode 100644
index 0000000..f861ca3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi
@@ -0,0 +1,81 @@
+/* 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.
+ */
+
+#include "sdm670-audio.dtsi"
+
+&msm_audio_ion {
+ iommus = <&apps_smmu 0x1821 0x0>;
+ qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+};
+
+&qupv3_se8_spi {
+ status = "okay";
+};
+
+&pm660l_3 {
+ /delete-node/analog-codec;
+};
+
+&soc {
+ /delete-node/msm-sdw-codec@62ec1000;
+ /delete-node/sound;
+ /delete-node/cdc_pdm_pinctrl;
+ /delete-node/wsa_spkr_en1_pinctrl;
+ /delete-node/wsa_spkr_en2_pinctrl;
+ /delete-node/sdw_clk_data_pinctrl;
+};
+
+&msm_audio_ion {
+ iommus = <&apps_smmu 0x1821 0x0>;
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+ qcom,gpio-connect = <&tlmm 54 0>;
+};
+
+&wdsp_mgr {
+ status = "okay";
+};
+
+&wdsp_glink {
+ status = "okay";
+};
+
+&slim_aud {
+ status = "okay";
+};
+
+&dai_slim {
+ status = "okay";
+};
+
+&wcd934x_cdc {
+ status = "okay";
+};
+
+&clock_audio_lnbb {
+ status = "okay";
+};
+
+&wcd_rst_gpio {
+ status = "okay";
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+};
+
+&tavil_snd {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts
new file mode 100644
index 0000000..da59bcf
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts
@@ -0,0 +1,30 @@
+/* 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-interposer-sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v1 Interposer SDM670 CDP";
+ compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <1 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts
new file mode 100644
index 0000000..ebb5e8f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts
@@ -0,0 +1,24 @@
+/* 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-interposer-sdm670.dtsi"
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-interposer-sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM sdm845 v1 Interposer SDM670 CDP";
+ compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
+ qcom,board-id = <1 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi
new file mode 100644
index 0000000..ad15615
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi
@@ -0,0 +1,15 @@
+/* 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.
+ */
+
+#include "sdm845-cdp.dtsi"
+#include "sdm845-interposer-pm660.dtsi"
+#include "sdm845-interposer-sdm670-audio.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts
new file mode 100644
index 0000000..3ca15b9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts
@@ -0,0 +1,30 @@
+/* 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-interposer-sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v1 Interposer SDM670 MTP";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <8 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts
new file mode 100644
index 0000000..39664f1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts
@@ -0,0 +1,24 @@
+/* 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-interposer-sdm670.dtsi"
+#include "sdm845-sde-display.dtsi"
+#include "sdm845-interposer-sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM sdm845 v1 Interposer SDM670 MTP";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ qcom,board-id = <8 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi
new file mode 100644
index 0000000..c709770
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi
@@ -0,0 +1,19 @@
+/* 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.
+ */
+
+#include "sdm845-mtp.dtsi"
+#include "sdm845-interposer-pm660.dtsi"
+#include "sdm845-interposer-sdm670-audio.dtsi"
+
+&qupv3_se10_i2c {
+ /delete-node/ qcom,smb1355@8;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.dts
new file mode 100644
index 0000000..c5e4ae1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.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-interposer-sdm670.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 Interposer SDM670";
+ compatible = "qcom,sdm845";
+ qcom,msm-id = <321 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.dtsi
new file mode 100644
index 0000000..9341507
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670.dtsi
@@ -0,0 +1,20 @@
+/* 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.
+ */
+
+#include "sdm845.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 Interposer SDM670";
+ compatible = "qcom,sdm845";
+ qcom,msm-id = <321 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
index 45941a1..2d1d9b6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
@@ -26,6 +26,6 @@
/ {
model = "Qualcomm Technologies, Inc. SDM845 v1 MTP";
compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <8 0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
index 04f67cd..f691740 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
@@ -1400,6 +1400,90 @@
};
};
+ quat_tdm {
+ quat_tdm_sleep: quat_tdm_sleep {
+ mux {
+ pins = "gpio58", "gpio59";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio58", "gpio59";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+
+ quat_tdm_active: quat_tdm_active {
+ mux {
+ pins = "gpio58", "gpio59";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio58", "gpio59";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ quat_tdm_dout {
+ quat_tdm_dout_sleep: quat_tdm_dout_sleep {
+ mux {
+ pins = "gpio61";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio61";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+
+ quat_tdm_dout_active: quat_tdm_dout_active {
+ mux {
+ pins = "gpio61";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio61";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ quat_tdm_din {
+ quat_tdm_din_sleep: quat_tdm_din_sleep {
+ mux {
+ pins = "gpio60";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio60";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+
+ quat_tdm_din_active: quat_tdm_din_active {
+ mux {
+ pins = "gpio60";
+ function = "qua_mi2s";
+ };
+
+ config {
+ pins = "gpio60";
+ drive-strength = <2>; /* 2 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
/* QUPv3 South SE mappings */
/* SE 0 pin mappings */
qupv3_se0_i2c_pins: qupv3_se0_i2c_pins {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
index 6cead9d..c8136de 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd-overlay.dts
@@ -26,6 +26,6 @@
/ {
model = "Qualcomm Technologies, Inc. SDM845 v1 QRD";
compatible = "qcom,sdm845-qrd", "qcom,sdm845", "qcom,qrd";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
qcom,board-id = <11 0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
index 9b683cc..c0afb74 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
@@ -84,6 +84,7 @@
&pmi8998_fg {
qcom,battery-data = <&qrd_batterydata>;
+ qcom,fg-bmd-en-delay-ms = <300>;
};
&smb1355_charger {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
index 03b9e06..8350d90 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
@@ -854,6 +854,25 @@
qcom,init-voltage = <880000>;
qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
};
+
+ pm8998_l1_ao: regulator-l1-ao {
+ regulator-name = "pm8998_l1_ao";
+ qcom,set = <RPMH_REGULATOR_SET_ACTIVE>;
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ qcom,init-voltage = <880000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ };
+
+ regulator-l1-so {
+ regulator-name = "pm8998_l1_so";
+ qcom,set = <RPMH_REGULATOR_SET_SLEEP>;
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ qcom,init-voltage = <880000>;
+ qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
+ qcom,init-enable = <0>;
+ };
};
rpmh-regulator-ldoa2 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 6fb4f37..21aedbf 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -411,7 +411,17 @@
qcom,dp-usbpd-detection = <&pmi8998_pdphy>;
- qcom,aux-cfg-settings = [00 13 04 00 0a 26 0a 03 bb 03];
+ qcom,aux-cfg0-settings = [20 00];
+ qcom,aux-cfg1-settings = [24 13 23 1d];
+ qcom,aux-cfg2-settings = [28 24];
+ qcom,aux-cfg3-settings = [2c 00];
+ qcom,aux-cfg4-settings = [30 0a];
+ qcom,aux-cfg5-settings = [34 26];
+ qcom,aux-cfg6-settings = [38 0a];
+ qcom,aux-cfg7-settings = [3c 03];
+ qcom,aux-cfg8-settings = [40 bb];
+ qcom,aux-cfg9-settings = [44 03];
+
qcom,max-pclk-frequency-khz = <576000>;
qcom,core-supply-entries {
@@ -472,108 +482,168 @@
};
&dsi_dual_nt35597_truly_video {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0D>;
qcom,mdss-dsi-t-clk-pre = <0x2D>;
- qcom,display-topology = <2 0 2>,
- <1 0 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_dual_nt35597_truly_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0D>;
qcom,mdss-dsi-t-clk-pre = <0x2D>;
- qcom,display-topology = <2 0 2>,
- <1 0 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_nt35597_truly_dsc_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05 05 03 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0b>;
qcom,mdss-dsi-t-clk-pre = <0x23>;
- qcom,display-topology = <1 1 1>,
- <2 2 1>, /* dsc merge */
- <2 1 1>; /* 3d mux */
- qcom,default-topology-index = <1>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
+ 05 03 03 04 00];
+ qcom,display-topology = <1 1 1>,
+ <2 2 1>, /* dsc merge */
+ <2 1 1>; /* 3d mux */
+ qcom,default-topology-index = <1>;
+ };
+ };
};
&dsi_nt35597_truly_dsc_video {
- qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05 05 03 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0b>;
qcom,mdss-dsi-t-clk-pre = <0x23>;
- qcom,display-topology = <1 1 1>,
- <2 2 1>, /* dsc merge */
- <2 1 1>; /* 3d mux */
- qcom,default-topology-index = <1>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
+ 04 03 03 04 00];
+ qcom,display-topology = <1 1 1>,
+ <2 2 1>, /* dsc merge */
+ <2 1 1>; /* 3d mux */
+ qcom,default-topology-index = <1>;
+ };
+ };
};
&dsi_sharp_4k_dsc_video {
- qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06 06 04 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0c>;
qcom,mdss-dsi-t-clk-pre = <0x27>;
- qcom,display-topology = <2 2 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06
+ 06 04 03 04 00];
+ qcom,display-topology = <2 2 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_sharp_4k_dsc_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06 06 04 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0c>;
qcom,mdss-dsi-t-clk-pre = <0x27>;
- qcom,display-topology = <2 2 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06
+ 06 04 03 04 00];
+ qcom,display-topology = <2 2 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_dual_sharp_1080_120hz_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 24 09 09 26 24 09 09 06 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0f>;
qcom,mdss-dsi-t-clk-pre = <0x36>;
- qcom,display-topology = <2 0 2>,
- <1 0 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 24 09 09 26 24 09
+ 09 06 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_sharp_1080_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 1A 06 06 22 20 07 07 04 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0c>;
qcom,mdss-dsi-t-clk-pre = <0x29>;
- qcom,display-topology = <1 0 1>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1A 06 06 22 20 07
+ 07 04 03 04 00];
+ qcom,display-topology = <1 0 1>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_sim_vid {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
- qcom,display-topology = <1 0 1>,
- <2 0 1>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <1 0 1>,
+ <2 0 1>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_dual_sim_vid {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
- qcom,display-topology = <2 0 2>,
- <1 0 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_sim_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
- qcom,display-topology = <1 0 1>,
- <2 0 1>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <1 0 1>,
+ <2 0 1>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
&dsi_dual_sim_cmd {
- qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07 07 05 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x0d>;
qcom,mdss-dsi-t-clk-pre = <0x2d>;
- qcom,display-topology = <2 0 2>,
- <1 0 2>;
- qcom,default-topology-index = <0>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
index 0618f92..121565e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
@@ -14,11 +14,9 @@
mdss_mdp: qcom,mdss_mdp@ae00000 {
compatible = "qcom,sde-kms";
reg = <0x0ae00000 0x81d40>,
- <0x0aeb0000 0x2008>,
- <0x0aeac000 0xf0>;
+ <0x0aeb0000 0x2008>;
reg-names = "mdp_phys",
- "vbif_phys",
- "regdma_phys";
+ "vbif_phys";
clocks =
<&clock_gcc GCC_DISP_AHB_CLK>,
@@ -181,9 +179,6 @@
/* offsets are relative to "mdp_phys + qcom,sde-off */
qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>;
- qcom,sde-reg-dma-off = <0>;
- qcom,sde-reg-dma-version = <0x1>;
- qcom,sde-reg-dma-trigger-off = <0x119c>;
qcom,sde-sspp-vig-blocks {
qcom,sde-vig-csc-off = <0x1a00>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
index 86e97f8..40c677f 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
@@ -21,6 +21,8 @@
reg = <0x0a600000 0xf8c00>,
<0x088ee000 0x400>;
reg-names = "core_base", "ahb2phy_base";
+ iommus = <&apps_smmu 0x740 0x0>;
+ qcom,smmu-s1-bypass;
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -61,7 +63,7 @@
<MSM_BUS_MASTER_USB3 MSM_BUS_SLAVE_IPA_CFG 0 0>,
<MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_USB3 0 0>,
<MSM_BUS_MASTER_USB3
- MSM_BUS_SLAVE_EBI_CH0 240000 800000>,
+ MSM_BUS_SLAVE_EBI_CH0 240000 700000>,
<MSM_BUS_MASTER_USB3
MSM_BUS_SLAVE_IPA_CFG 0 2400>,
<MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_USB3 0 40000>;
@@ -331,6 +333,8 @@
reg = <0x0a800000 0xf8c00>,
<0x088ee000 0x400>;
reg-names = "core_base", "ahb2phy_base";
+ iommus = <&apps_smmu 0x760 0x0>;
+ qcom,smmu-s1-bypass;
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -368,7 +372,7 @@
<MSM_BUS_MASTER_USB3_1 MSM_BUS_SLAVE_EBI_CH0 0 0>,
<MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_USB3_1 0 0>,
<MSM_BUS_MASTER_USB3_1
- MSM_BUS_SLAVE_EBI_CH0 240000 800000>,
+ MSM_BUS_SLAVE_EBI_CH0 240000 700000>,
<MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_USB3_1 0 40000>;
dwc3@a600000 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
index 34f3cb3..761efea 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
@@ -18,11 +18,6 @@
};
&sdhc_2 {
- qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
- 100000000 200000000 4294967295>;
- qcom,clk-rates = <400000 20000000 25000000 50000000
- 100000000 200000000>;
- qcom,devfreq,freq-table = <50000000 200000000>;
/delete-property/ qcom,sdr104-wa;
};
@@ -547,19 +542,19 @@
};
&clock_gcc {
- compatible = "qcom,gcc-sdm845-v2";
+ compatible = "qcom,gcc-sdm845-v2", "syscon";
};
&clock_camcc {
- compatible = "qcom,cam_cc-sdm845-v2";
+ compatible = "qcom,cam_cc-sdm845-v2", "syscon";
};
&clock_dispcc {
- compatible = "qcom,dispcc-sdm845-v2";
+ compatible = "qcom,dispcc-sdm845-v2", "syscon";
};
&clock_gpucc {
- compatible = "qcom,gpucc-sdm845-v2";
+ compatible = "qcom,gpucc-sdm845-v2", "syscon";
};
&clock_gfx {
@@ -567,7 +562,7 @@
};
&clock_videocc {
- compatible = "qcom,video_cc-sdm845-v2";
+ compatible = "qcom,video_cc-sdm845-v2", "syscon";
};
&clock_aop {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 10052da..d4ab8f4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -29,7 +29,7 @@
/ {
model = "Qualcomm Technologies, Inc. SDM845";
compatible = "qcom,sdm845";
- qcom,msm-id = <321 0x0>;
+ qcom,msm-id = <321 0x10000>;
interrupt-parent = <&pdc>;
aliases {
@@ -515,12 +515,17 @@
#size-cells = <2>;
ranges;
- removed_region1: removed_region1@85700000 {
+ hyp_region: hyp_region@85700000 {
no-map;
- reg = <0 0x85700000 0 0x800000>;
+ reg = <0 0x85700000 0 0x600000>;
};
- removed_region2: removed_region2@85fc0000 {
+ xbl_region: xbl_region@85e00000 {
+ no-map;
+ reg = <0 0x85e00000 0 0x100000>;
+ };
+
+ removed_region: removed_region@85fc0000 {
no-map;
reg = <0 0x85fc0000 0 0x2f40000>;
};
@@ -531,64 +536,70 @@
reg = <0 0x8ab00000 0 0x500000>;
};
- pil_modem_mem: modem_region@8b000000 {
+ pil_ipa_fw_mem: pil_ipa_fw_region@8b000000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x8b000000 0 0x7300000>;
+ reg = <0 0x8b000000 0 0x10000>;
};
- pil_video_mem: pil_video_region@92300000 {
+ pil_ipa_gsi_mem: pil_ipa_gsi_region@8b010000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x92300000 0 0x500000>;
+ reg = <0 0x8b010000 0 0x5000>;
};
- pil_cdsp_mem: cdsp_regions@92800000 {
+ pil_gpu_mem: pil_gpu_region@8b015000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x92800000 0 0x800000>;
+ reg = <0 0x8b015000 0 0x1000>;
};
- pil_adsp_mem: pil_adsp_region@93000000 {
+ pil_adsp_mem: pil_adsp_region@8b100000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x93000000 0 0x1a00000>;
+ reg = <0 0x8b100000 0 0x1a00000>;
};
- pil_mba_mem: pil_mba_region@0x94a00000 {
- compatible = "removed-dma-pool";
- no-map;
- reg = <0 0x94a00000 0 0x200000>;
+ wlan_fw_region: wlan_fw_region@8cb00000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x8cb00000 0 0x100000>;
};
- pil_slpi_mem: pil_slpi_region@94c00000 {
+ pil_modem_mem: modem_region@8cc00000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x94c00000 0 0x1400000>;
+ reg = <0 0x8cc00000 0 0x7600000>;
};
- pil_ipa_fw_mem: pil_ipa_fw_region@96000000 {
+ pil_video_mem: pil_video_region@94200000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x96000000 0 0x10000>;
+ reg = <0 0x94200000 0 0x500000>;
};
- pil_ipa_gsi_mem: pil_ipa_gsi_region@96010000 {
+ pil_cdsp_mem: cdsp_regions@94700000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x96010000 0 0x5000>;
+ reg = <0 0x94700000 0 0x800000>;
};
- pil_gpu_mem: pil_gpu_region@96015000 {
+ pil_mba_mem: pil_mba_region@0x94f00000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x96015000 0 0x1000>;
+ reg = <0 0x94f00000 0 0x200000>;
};
- pil_spss_mem: spss_region@96100000 {
+ pil_slpi_mem: pil_slpi_region@95100000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x96100000 0 0x100000>;
+ reg = <0 0x95100000 0 0x1400000>;
+ };
+
+
+ pil_spss_mem: spss_region@96500000 {
+ compatible = "removed-dma-pool";
+ no-map;
+ reg = <0 0x96500000 0 0x100000>;
};
adsp_mem: adsp_region {
@@ -602,7 +613,7 @@
qseecom_mem: qseecom_region {
compatible = "shared-dma-pool";
alloc-ranges = <0 0x00000000 0 0xffffffff>;
- reusable;
+ no-map;
alignment = <0 0x400000>;
size = <0 0x1400000>;
};
@@ -935,10 +946,9 @@
qcom,core-dev-table =
< 300000 762 >,
< 748800 1720 >,
- < 979200 2929 >,
- < 1209600 3879 >,
- < 1516800 4943 >,
- < 1593600 5931 >;
+ < 1132800 2086 >,
+ < 1440000 2929 >,
+ < 1593600 3879 >;
};
devfreq_memlat_4: qcom,cpu4-memlat-mon {
@@ -948,10 +958,12 @@
qcom,cachemiss-ev = <0x2A>;
qcom,core-dev-table =
< 300000 762 >,
+ < 499200 1720 >,
+ < 806400 2086 >,
< 1036800 2929 >,
< 1190400 3879 >,
< 1574400 4943 >,
- < 1804800 5931 >,
+ < 1728000 5931 >,
< 1958400 6881 >;
};
@@ -1337,8 +1349,6 @@
<1000 1000 1000>;
qcom,down-timer =
<100000 100000 100000>;
- qcom,pc-override-index =
- <0 0 0>;
qcom,set-ret-inactive;
qcom,enable-llm-freq-vote;
qcom,llm-freq-up-timer =
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
new file mode 100644
index 0000000..5437417
--- /dev/null
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -0,0 +1,579 @@
+CONFIG_LOCALVERSION="-perf"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_FHANDLE is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_SCHED_WALT=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_NOCB_CPU=y
+CONFIG_RCU_NOCB_CPU_ALL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_BPF=y
+CONFIG_SCHED_CORE_CTL=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_AIO is not set
+# CONFIG_MEMBARRIER is not set
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
+CONFIG_MODULE_SIG_SHA512=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_SDM670=y
+CONFIG_PCI=y
+CONFIG_PCI_MSM=y
+CONFIG_SCHED_MC=y
+CONFIG_NR_CPUS=8
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_CMA=y
+CONFIG_ZSMALLOC=y
+CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_SECCOMP=y
+CONFIG_ARMV8_DEPRECATED=y
+CONFIG_SWP_EMULATION=y
+CONFIG_CP15_BARRIER_EMULATION=y
+CONFIG_SETEND_EMULATION=y
+# CONFIG_ARM64_VHE is not set
+CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_COMPAT=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=y
+CONFIG_NET_EMATCH_NBYTE=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_EMATCH_META=y
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_BT=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+CONFIG_DMA_CMA=y
+CONFIG_ZRAM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_QSEECOM=y
+CONFIG_MEMORY_STATE_TIME=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
+CONFIG_SCSI_UFSHCD_CMD_LOGGING=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=y
+CONFIG_DUMMY=y
+CONFIG_TUN=y
+CONFIG_SKY2=y
+CONFIG_SMSC911X=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_USB_USBNET=y
+CONFIG_WIL6210=m
+# CONFIG_WIL6210_TRACING is not set
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_QPNP_POWER_ON=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_MSM_GENI=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QCOM_GENI=y
+CONFIG_SOUNDWIRE=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
+CONFIG_PINCTRL_SDM670=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_FG_GEN3=y
+CONFIG_SMB1355_SLAVE_CHARGER=y
+CONFIG_QPNP_SMB2=y
+CONFIG_QPNP_QNOVO=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_LOW_LIMITS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_QCOM_SPMI_TEMP_ALARM=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_THERMAL_TSENS=y
+CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_QTI_VIRTUAL_SENSOR=y
+CONFIG_QTI_REG_COOLING_DEVICE=y
+CONFIG_QTI_QMI_COOLING_DEVICE=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_WCD9XXX_CODEC_CORE=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPMH=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SPECTRA_CAMERA=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_VIDC_GOVERNORS=y
+CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_DVB_MPQ=m
+CONFIG_DVB_MPQ_DEMUX=m
+CONFIG_DVB_MPQ_TSPP1=y
+CONFIG_TSPP=m
+CONFIG_QCOM_KGSL=y
+CONFIG_DRM=y
+CONFIG_DRM_SDE_EVTLOG_DEBUG=y
+CONFIG_DRM_SDE_RSC=y
+CONFIG_FB_VIRTUAL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO_QMI=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_PLANTRONICS=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_MSM=y
+CONFIG_USB_ISP1760=y
+CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_PD_POLICY=y
+CONFIG_QPNP_USB_PDPHY=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_QUSB_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_MTP=y
+CONFIG_USB_CONFIGFS_F_PTP=y
+CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_DIAG=y
+CONFIG_USB_CONFIGFS_F_CDEV=y
+CONFIG_USB_CONFIGFS_F_CCID=y
+CONFIG_USB_CONFIGFS_F_GSI=y
+CONFIG_USB_CONFIGFS_F_QDSS=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
+CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_QPNP_HAPTICS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_GPI_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_RMNET_IPA3=y
+CONFIG_RNDIS_IPA=y
+CONFIG_IPA_UT=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_COINCELL=y
+CONFIG_QPNP_REVID=y
+CONFIG_USB_BAM=y
+CONFIG_MSM_11AD=m
+CONFIG_SEEMP_CORE=y
+CONFIG_QCOM_GENI_SE=y
+CONFIG_CLOCK_QPNP_DIV=y
+CONFIG_MSM_CLK_RPMH=y
+CONFIG_CLOCK_CPU_OSM=y
+CONFIG_MSM_CLK_AOP_QMP=y
+CONFIG_QCOM_MDSS_PLL=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_QMP=y
+CONFIG_IOMMU_IO_PGTABLE_FAST=y
+CONFIG_ARM_SMMU=y
+CONFIG_QCOM_LAZY_MAPPING=y
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_DEBUG_TRACKING=y
+CONFIG_IOMMU_TESTS=y
+CONFIG_QCOM_RUN_QUEUE_STATS=y
+CONFIG_QCOM_LLCC=y
+CONFIG_QCOM_SDM670_LLCC=y
+CONFIG_MSM_SERVICE_LOCATOR=y
+CONFIG_MSM_SERVICE_NOTIFIER=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_QCOM_EUD=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_EARLY_RANDOM=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_MSM_GLINK_SPI_XPRT=y
+CONFIG_MSM_SPCOM=y
+CONFIG_MSM_SPSS_UTILS=y
+CONFIG_TRACER_PKT=y
+CONFIG_QTI_RPMH_API=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_ICNSS=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_MSM_PERFORMANCE=y
+CONFIG_MSM_CDSP_LOADER=y
+CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_PM=y
+CONFIG_MSM_QBT1000=y
+CONFIG_APSS_CORE_EA=y
+CONFIG_QTI_RPM_STATS_LOG=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_QCOMCCI_HWMON=y
+CONFIG_QCOM_M4M_HWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_QCOM_RRADC=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_SENSORS_SSC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V2=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=y
+CONFIG_ECRYPT_FS_MESSAGING=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_IPC_LOGGING=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_QCOM_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CORESIGHT_DUMMY=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_CRC32_ARM64=y
+CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index e835d46..0e8aef9 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -51,7 +51,6 @@
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SDM845=y
-CONFIG_ARCH_SDM670=y
CONFIG_PCI=y
CONFIG_PCI_MSM=y
CONFIG_SCHED_MC=y
@@ -309,7 +308,6 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SDM670=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
@@ -531,7 +529,6 @@
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QMP_DEBUGFS_CLIENT=y
-CONFIG_QSEE_IPC_IRQ_BRIDGE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_ARM_MEMLAT_MON=y
CONFIG_QCOMCCI_HWMON=y
@@ -587,6 +584,7 @@
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SMACK=y
CONFIG_CRYPTO_CTR=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index c26a3c4..c516cd3 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -550,7 +550,6 @@
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QMP_DEBUGFS_CLIENT=y
-CONFIG_QSEE_IPC_IRQ_BRIDGE=y
CONFIG_QCOM_BIMC_BWMON=y
CONFIG_ARM_MEMLAT_MON=y
CONFIG_QCOMCCI_HWMON=y
@@ -655,6 +654,7 @@
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SMACK=y
CONFIG_CRYPTO_CTR=y
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 6d22017..ef305f8 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -47,7 +47,7 @@
* If the page is in the bottom half, we have to use the top half. If
* the page is in the top half, we have to use the bottom half:
*
- * T = __virt_to_phys(__hyp_idmap_text_start)
+ * T = __pa_symbol(__hyp_idmap_text_start)
* if (T & BIT(VA_BITS - 1))
* HYP_VA_MIN = 0 //idmap in upper half
* else
@@ -270,7 +270,7 @@
kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
}
-#define kvm_virt_to_phys(x) __virt_to_phys((unsigned long)(x))
+#define kvm_virt_to_phys(x) __pa_symbol(x)
void kvm_set_way_flush(struct kvm_vcpu *vcpu);
void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 53211a0..5edb6ed 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -204,7 +204,8 @@
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
-#define virt_to_pfn(x) __phys_to_pfn(__virt_to_phys(x))
+#define virt_to_pfn(x) __phys_to_pfn(__virt_to_phys((unsigned long)(x)))
+#define sym_to_pfn(x) __phys_to_pfn(__pa_symbol(x))
/*
* virt_to_page(k) convert a _valid_ virtual address to struct page *
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index dc06a33..88025ba 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -51,7 +51,7 @@
*/
static inline void cpu_set_reserved_ttbr0(void)
{
- unsigned long ttbr = virt_to_phys(empty_zero_page);
+ unsigned long ttbr = __pa_symbol(empty_zero_page);
write_sysreg(ttbr, ttbr0_el1);
isb();
@@ -120,7 +120,7 @@
local_flush_tlb_all();
cpu_set_idmap_tcr_t0sz();
- cpu_switch_mm(idmap_pg_dir, &init_mm);
+ cpu_switch_mm(lm_alias(idmap_pg_dir), &init_mm);
}
/*
@@ -135,7 +135,7 @@
phys_addr_t pgd_phys = virt_to_phys(pgd);
- replace_phys = (void *)virt_to_phys(idmap_cpu_replace_ttbr1);
+ replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
cpu_install_idmap();
replace_phys(pgd_phys);
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 3845f33..c05ee84 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -53,7 +53,7 @@
* for zero-mapped memory areas etc..
*/
extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) pfn_to_page(PHYS_PFN(__pa(empty_zero_page)))
+#define ZERO_PAGE(vaddr) phys_to_page(__pa_symbol(empty_zero_page))
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h
index fe5e287..b86a086 100644
--- a/arch/arm64/include/asm/stackprotector.h
+++ b/arch/arm64/include/asm/stackprotector.h
@@ -30,6 +30,7 @@
/* Try to get a semi random initial value. */
get_random_bytes(&canary, sizeof(canary));
canary ^= LINUX_VERSION_CODE;
+ canary &= CANARY_MASK;
current->stack_canary = canary;
__stack_chk_guard = current->stack_canary;
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 2eb714c..d0aa429 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -63,6 +63,11 @@
#define memcpy(dst, src, len) __memcpy(dst, src, len)
#define memmove(dst, src, len) __memmove(dst, src, len)
#define memset(s, c, n) __memset(s, c, n)
+
+#ifndef __NO_FORTIFY
+#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
+#endif
+
#endif
#endif
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 2df5d5f..4d9222a 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -383,9 +383,9 @@
{
unsigned long res = n;
kasan_check_write(to, n);
+ check_object_size(to, n, false);
if (access_ok(VERIFY_READ, from, n)) {
- check_object_size(to, n, false);
res = __arch_copy_from_user(to, from, n);
}
if (unlikely(res))
@@ -396,9 +396,9 @@
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
{
kasan_check_read(from, n);
+ check_object_size(from, n, true);
if (access_ok(VERIFY_WRITE, to, n)) {
- check_object_size(from, n, true);
n = __arch_copy_to_user(to, from, n);
}
return n;
diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c
index a32b401..1f5655c 100644
--- a/arch/arm64/kernel/acpi_parking_protocol.c
+++ b/arch/arm64/kernel/acpi_parking_protocol.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/acpi.h>
+#include <linux/mm.h>
#include <linux/types.h>
#include <asm/cpu_ops.h>
@@ -109,7 +110,7 @@
* that read this address need to convert this address to the
* Boot-Loader's endianness before jumping.
*/
- writeq_relaxed(__pa(secondary_entry), &mailbox->entry_point);
+ writeq_relaxed(__pa_symbol(secondary_entry), &mailbox->entry_point);
writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
index d4e9ecb..6c2b1b4 100644
--- a/arch/arm64/kernel/cpu-reset.h
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -24,7 +24,7 @@
el2_switch = el2_switch && !is_kernel_in_hyp_mode() &&
is_hyp_mode_available();
- restart = (void *)virt_to_phys(__cpu_soft_restart);
+ restart = (void *)__pa_symbol(__cpu_soft_restart);
cpu_install_idmap();
restart(el2_switch, entry, arg0, arg1, arg2);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index af5a1e3..0127e1b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -23,6 +23,7 @@
#include <linux/sort.h>
#include <linux/stop_machine.h>
#include <linux/types.h>
+#include <linux/mm.h>
#include <asm/cpu.h>
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
@@ -737,7 +738,7 @@
static bool hyp_offset_low(const struct arm64_cpu_capabilities *entry,
int __unused)
{
- phys_addr_t idmap_addr = virt_to_phys(__hyp_idmap_text_start);
+ phys_addr_t idmap_addr = __pa_symbol(__hyp_idmap_text_start);
/*
* Activate the lower HYP offset only if:
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index d55a7b0..8bed26a 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -50,9 +50,6 @@
*/
extern int in_suspend;
-/* Find a symbols alias in the linear map */
-#define LMADDR(x) phys_to_virt(virt_to_phys(x))
-
/* Do we need to reset el2? */
#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())
@@ -102,8 +99,8 @@
int pfn_is_nosave(unsigned long pfn)
{
- unsigned long nosave_begin_pfn = virt_to_pfn(&__nosave_begin);
- unsigned long nosave_end_pfn = virt_to_pfn(&__nosave_end - 1);
+ unsigned long nosave_begin_pfn = sym_to_pfn(&__nosave_begin);
+ unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1);
return (pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn);
}
@@ -125,12 +122,12 @@
return -EOVERFLOW;
arch_hdr_invariants(&hdr->invariants);
- hdr->ttbr1_el1 = virt_to_phys(swapper_pg_dir);
+ hdr->ttbr1_el1 = __pa_symbol(swapper_pg_dir);
hdr->reenter_kernel = _cpu_resume;
/* We can't use __hyp_get_vectors() because kvm may still be loaded */
if (el2_reset_needed())
- hdr->__hyp_stub_vectors = virt_to_phys(__hyp_stub_vectors);
+ hdr->__hyp_stub_vectors = __pa_symbol(__hyp_stub_vectors);
else
hdr->__hyp_stub_vectors = 0;
@@ -460,7 +457,6 @@
void *zero_page;
size_t exit_size;
pgd_t *tmp_pg_dir;
- void *lm_restore_pblist;
phys_addr_t phys_hibernate_exit;
void __noreturn (*hibernate_exit)(phys_addr_t, phys_addr_t, void *,
void *, phys_addr_t, phys_addr_t);
@@ -481,12 +477,6 @@
goto out;
/*
- * Since we only copied the linear map, we need to find restore_pblist's
- * linear map address.
- */
- lm_restore_pblist = LMADDR(restore_pblist);
-
- /*
* We need a zero page that is zero before & after resume in order to
* to break before make on the ttbr1 page tables.
*/
@@ -537,7 +527,7 @@
}
hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1,
- resume_hdr.reenter_kernel, lm_restore_pblist,
+ resume_hdr.reenter_kernel, restore_pblist,
resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page));
out:
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 6f2ac4f..f607b38 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -97,7 +97,7 @@
if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
page = vmalloc_to_page(addr);
else if (!module)
- page = pfn_to_page(PHYS_PFN(__pa(addr)));
+ page = phys_to_page(__pa_symbol(addr));
else
return addr;
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 81762dd..716a5c2 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -20,6 +20,7 @@
#include <linux/smp.h>
#include <linux/delay.h>
#include <linux/psci.h>
+#include <linux/mm.h>
#include <uapi/linux/psci.h>
@@ -45,7 +46,7 @@
static int cpu_psci_cpu_boot(unsigned int cpu)
{
- int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry));
+ int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa_symbol(secondary_entry));
if (err)
pr_err("failed to boot CPU%d (%d)\n", cpu, err);
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index ae02756..ba29095 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -44,6 +44,7 @@
#include <linux/psci.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/mm.h>
#include <asm/acpi.h>
#include <asm/fixmap.h>
@@ -212,10 +213,10 @@
struct memblock_region *region;
struct resource *res;
- kernel_code.start = virt_to_phys(_text);
- kernel_code.end = virt_to_phys(__init_begin - 1);
- kernel_data.start = virt_to_phys(_sdata);
- kernel_data.end = virt_to_phys(_end - 1);
+ kernel_code.start = __pa_symbol(_text);
+ kernel_code.end = __pa_symbol(__init_begin - 1);
+ kernel_data.start = __pa_symbol(_sdata);
+ kernel_data.end = __pa_symbol(_end - 1);
for_each_memblock(memory, region) {
res = alloc_bootmem_low(sizeof(*res));
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 9a00eee..9303465 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -21,6 +21,7 @@
#include <linux/of.h>
#include <linux/smp.h>
#include <linux/types.h>
+#include <linux/mm.h>
#include <asm/cacheflush.h>
#include <asm/cpu_ops.h>
@@ -98,7 +99,7 @@
* boot-loader's endianess before jumping. This is mandated by
* the boot protocol.
*/
- writeq_relaxed(__pa(secondary_holding_pen), release_addr);
+ writeq_relaxed(__pa_symbol(secondary_holding_pen), release_addr);
__flush_dcache_area((__force void *)release_addr,
sizeof(*release_addr));
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 4bcfe01..ef3bdfd 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -37,7 +37,7 @@
#include <asm/vdso.h>
#include <asm/vdso_datapage.h>
-extern char vdso_start, vdso_end;
+extern char vdso_start[], vdso_end[];
static unsigned long vdso_pages __ro_after_init;
/*
@@ -123,15 +123,16 @@
{
int i;
struct page **vdso_pagelist;
+ unsigned long pfn;
- if (memcmp(&vdso_start, "\177ELF", 4)) {
+ if (memcmp(vdso_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
- vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
- vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+ vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
@@ -140,11 +141,14 @@
return -ENOMEM;
/* Grab the vDSO data page. */
- vdso_pagelist[0] = pfn_to_page(PHYS_PFN(__pa(vdso_data)));
+ vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
+
/* Grab the vDSO code pages. */
+ pfn = sym_to_pfn(vdso_start);
+
for (i = 0; i < vdso_pages; i++)
- vdso_pagelist[i + 1] = pfn_to_page(PHYS_PFN(__pa(&vdso_start)) + i);
+ vdso_pagelist[i + 1] = pfn_to_page(pfn + i);
vdso_spec[0].pages = &vdso_pagelist[0];
vdso_spec[1].pages = &vdso_pagelist[1];
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index acbe515..7f90b7e 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -157,12 +157,13 @@
dma_addr_t *dma_handle, gfp_t flags,
unsigned long attrs)
{
+ void *addr;
+
if (IS_ENABLED(CONFIG_ZONE_DMA) &&
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
flags |= GFP_DMA;
if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
struct page *page;
- void *addr;
page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
get_order(size));
@@ -172,20 +173,20 @@
*dma_handle = phys_to_dma(dev, page_to_phys(page));
addr = page_address(page);
memset(addr, 0, size);
-
- if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
- (attrs & DMA_ATTR_STRONGLY_ORDERED)) {
- /*
- * flush the caches here because we can't later
- */
- __dma_flush_area(addr, size);
- __dma_remap(page, size, __pgprot(0), true);
- }
-
- return addr;
} else {
- return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
+ addr = swiotlb_alloc_coherent(dev, size, dma_handle, flags);
}
+
+ if (addr && ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
+ (attrs & DMA_ATTR_STRONGLY_ORDERED))) {
+ /*
+ * flush the caches here because we can't later
+ */
+ __dma_flush_area(addr, size);
+ __dma_remap(virt_to_page(addr), size, __pgprot(0), true);
+ }
+
+ return addr;
}
static void __dma_free_coherent(struct device *dev, size_t size,
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 0b9492e..f8ef496 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -36,6 +36,7 @@
#include <linux/efi.h>
#include <linux/swiotlb.h>
#include <linux/vmalloc.h>
+#include <linux/mm.h>
#include <asm/boot.h>
#include <asm/fixmap.h>
@@ -211,8 +212,8 @@
* linear mapping. Take care not to clip the kernel which may be
* high in memory.
*/
- memblock_remove(max_t(u64, memstart_addr + linear_region_size, __pa(_end)),
- ULLONG_MAX);
+ memblock_remove(max_t(u64, memstart_addr + linear_region_size,
+ __pa_symbol(_end)), ULLONG_MAX);
if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
/* ensure that memstart_addr remains sufficiently aligned */
memstart_addr = round_up(memblock_end_of_DRAM() - linear_region_size,
@@ -227,7 +228,7 @@
*/
if (memory_limit != (phys_addr_t)ULLONG_MAX) {
memblock_mem_limit_remove_map(memory_limit);
- memblock_add(__pa(_text), (u64)(_end - _text));
+ memblock_add(__pa_symbol(_text), (u64)(_end - _text));
}
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_start) {
@@ -280,7 +281,7 @@
* Register the kernel text, kernel data, initrd, and initial
* pagetables with memblock.
*/
- memblock_reserve(__pa(_text), _end - _text);
+ memblock_reserve(__pa_symbol(_text), _end - _text);
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
memblock_reserve(initrd_start, initrd_end - initrd_start);
@@ -488,7 +489,8 @@
void free_initmem(void)
{
- free_reserved_area(__va(__pa(__init_begin)), __va(__pa(__init_end)),
+ free_reserved_area(lm_alias(__init_begin),
+ lm_alias(__init_end),
0, "unused kernel");
/*
* Unmap the __init region but leave the VM area in place. This
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 757009d..201d918 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/memblock.h>
#include <linux/start_kernel.h>
+#include <linux/mm.h>
#include <asm/mmu_context.h>
#include <asm/kernel-pgtable.h>
@@ -26,6 +27,13 @@
static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+/*
+ * The p*d_populate functions call virt_to_phys implicitly so they can't be used
+ * directly on kernel symbols (bm_p*d). All the early functions are called too
+ * early to use lm_alias so __p*d_populate functions must be used to populate
+ * with the physical address from __pa_symbol.
+ */
+
static void __init kasan_early_pte_populate(pmd_t *pmd, unsigned long addr,
unsigned long end)
{
@@ -33,12 +41,12 @@
unsigned long next;
if (pmd_none(*pmd))
- pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+ __pmd_populate(pmd, __pa_symbol(kasan_zero_pte), PMD_TYPE_TABLE);
pte = pte_offset_kimg(pmd, addr);
do {
next = addr + PAGE_SIZE;
- set_pte(pte, pfn_pte(virt_to_pfn(kasan_zero_page),
+ set_pte(pte, pfn_pte(sym_to_pfn(kasan_zero_page),
PAGE_KERNEL));
} while (pte++, addr = next, addr != end && pte_none(*pte));
}
@@ -51,7 +59,7 @@
unsigned long next;
if (pud_none(*pud))
- pud_populate(&init_mm, pud, kasan_zero_pmd);
+ __pud_populate(pud, __pa_symbol(kasan_zero_pmd), PMD_TYPE_TABLE);
pmd = pmd_offset_kimg(pud, addr);
do {
@@ -68,7 +76,7 @@
unsigned long next;
if (pgd_none(*pgd))
- pgd_populate(&init_mm, pgd, kasan_zero_pud);
+ __pgd_populate(pgd, __pa_symbol(kasan_zero_pud), PUD_TYPE_TABLE);
pud = pud_offset_kimg(pgd, addr);
do {
@@ -148,7 +156,7 @@
*/
memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
dsb(ishst);
- cpu_replace_ttbr1(tmp_pg_dir);
+ cpu_replace_ttbr1(lm_alias(tmp_pg_dir));
clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
@@ -199,10 +207,10 @@
*/
for (i = 0; i < PTRS_PER_PTE; i++)
set_pte(&kasan_zero_pte[i],
- pfn_pte(virt_to_pfn(kasan_zero_page), PAGE_KERNEL_RO));
+ pfn_pte(sym_to_pfn(kasan_zero_page), PAGE_KERNEL_RO));
memset(kasan_zero_page, 0, PAGE_SIZE);
- cpu_replace_ttbr1(swapper_pg_dir);
+ cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
/* At this point kasan is fully initialized. Enable error messages */
init_task.kasan_depth = 0;
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f70b433..41efd5e 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -32,6 +32,7 @@
#include <linux/stop_machine.h>
#include <linux/dma-contiguous.h>
#include <linux/cma.h>
+#include <linux/mm.h>
#include <asm/barrier.h>
#include <asm/cputype.h>
@@ -357,8 +358,8 @@
static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
{
- unsigned long kernel_start = __pa(_text);
- unsigned long kernel_end = __pa(__init_begin);
+ unsigned long kernel_start = __pa_symbol(_text);
+ unsigned long kernel_end = __pa_symbol(__init_begin);
/*
* Take care not to create a writable alias for the
@@ -425,21 +426,21 @@
unsigned long section_size;
section_size = (unsigned long)_etext - (unsigned long)_text;
- create_mapping_late(__pa(_text), (unsigned long)_text,
+ create_mapping_late(__pa_symbol(_text), (unsigned long)_text,
section_size, PAGE_KERNEL_ROX);
/*
* mark .rodata as read only. Use __init_begin rather than __end_rodata
* to cover NOTES and EXCEPTION_TABLE.
*/
section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
- create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
+ create_mapping_late(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
section_size, PAGE_KERNEL_RO);
}
static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
pgprot_t prot, struct vm_struct *vma)
{
- phys_addr_t pa_start = __pa(va_start);
+ phys_addr_t pa_start = __pa_symbol(va_start);
unsigned long size = va_end - va_start;
BUG_ON(!PAGE_ALIGNED(pa_start));
@@ -487,7 +488,7 @@
*/
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
set_pud(pud_set_fixmap_offset(pgd, FIXADDR_START),
- __pud(__pa(bm_pmd) | PUD_TYPE_TABLE));
+ __pud(__pa_symbol(bm_pmd) | PUD_TYPE_TABLE));
pud_clear_fixmap();
} else {
BUG();
@@ -518,7 +519,7 @@
*/
cpu_replace_ttbr1(__va(pgd_phys));
memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
- cpu_replace_ttbr1(swapper_pg_dir);
+ cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
pgd_clear_fixmap();
memblock_free(pgd_phys, PAGE_SIZE);
@@ -527,7 +528,7 @@
* We only reuse the PGD from the swapper_pg_dir, not the pud + pmd
* allocated with it.
*/
- memblock_free(__pa(swapper_pg_dir) + PAGE_SIZE,
+ memblock_free(__pa_symbol(swapper_pg_dir) + PAGE_SIZE,
SWAPPER_DIR_SIZE - PAGE_SIZE);
}
@@ -638,6 +639,12 @@
return &bm_pte[pte_index(addr)];
}
+/*
+ * The p*d_populate functions call virt_to_phys implicitly so they can't be used
+ * directly on kernel symbols (bm_p*d). This function is called too early to use
+ * lm_alias so __p*d_populate functions must be used to populate with the
+ * physical address from __pa_symbol.
+ */
void __init early_fixmap_init(void)
{
pgd_t *pgd;
@@ -647,7 +654,7 @@
pgd = pgd_offset_k(addr);
if (CONFIG_PGTABLE_LEVELS > 3 &&
- !(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa(bm_pud))) {
+ !(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa_symbol(bm_pud))) {
/*
* We only end up here if the kernel mapping and the fixmap
* share the top level pgd entry, which should only happen on
@@ -656,12 +663,14 @@
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
pud = pud_offset_kimg(pgd, addr);
} else {
- pgd_populate(&init_mm, pgd, bm_pud);
+ if (pgd_none(*pgd))
+ __pgd_populate(pgd, __pa_symbol(bm_pud), PUD_TYPE_TABLE);
pud = fixmap_pud(addr);
}
- pud_populate(&init_mm, pud, bm_pmd);
+ if (pud_none(*pud))
+ __pud_populate(pud, __pa_symbol(bm_pmd), PMD_TYPE_TABLE);
pmd = fixmap_pmd(addr);
- pmd_populate_kernel(&init_mm, pmd, bm_pte);
+ __pmd_populate(pmd, __pa_symbol(bm_pte), PMD_TYPE_TABLE);
/*
* The boot-ioremap range spans multiple pmds, for which
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8f01f21..b4758f5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -84,6 +84,7 @@
select ARCH_MIGHT_HAVE_PC_SERIO
select BINFMT_ELF
select ARCH_HAS_ELF_RANDOMIZE
+ select ARCH_HAS_FORTIFY_SOURCE
select OF
select OF_EARLY_FLATTREE
select OF_RESERVED_MEM
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 0c84d6b..7e2af42 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -97,7 +97,8 @@
(unsigned long)selected_size / SZ_1M);
align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
cma_declare_contiguous(0, selected_size, 0, align_size,
- KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma);
+ KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, "kvm_cma",
+ &kvm_cma);
}
}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..3735222 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -26,6 +26,7 @@
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FAST_MULTIPLIER
+ select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE if X86_64
select ARCH_HAS_KCOV if X86_64
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index c945acd..5955954 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -409,3 +409,8 @@
debug_putstr("done.\nBooting the kernel.\n");
return output;
}
+
+void fortify_panic(const char *name)
+{
+ error("detected buffer overflow");
+}
diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h
index 3d3e835..e9ee848 100644
--- a/arch/x86/include/asm/string_32.h
+++ b/arch/x86/include/asm/string_32.h
@@ -142,7 +142,9 @@
}
#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, size_t);
+#ifndef CONFIG_FORTIFY_SOURCE
#ifdef CONFIG_X86_USE_3DNOW
#include <asm/mmx.h>
@@ -195,11 +197,15 @@
#endif
#endif
+#endif /* !CONFIG_FORTIFY_SOURCE */
#define __HAVE_ARCH_MEMMOVE
void *memmove(void *dest, const void *src, size_t n);
+extern int memcmp(const void *, const void *, size_t);
+#ifndef CONFIG_FORTIFY_SOURCE
#define memcmp __builtin_memcmp
+#endif
#define __HAVE_ARCH_MEMCHR
extern void *memchr(const void *cs, int c, size_t count);
@@ -321,6 +327,8 @@
: __memset_generic((s), (c), (count)))
#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, size_t);
+#ifndef CONFIG_FORTIFY_SOURCE
#if (__GNUC__ >= 4)
#define memset(s, c, count) __builtin_memset(s, c, count)
#else
@@ -330,6 +338,7 @@
(count)) \
: __memset((s), (c), (count)))
#endif
+#endif /* !CONFIG_FORTIFY_SOURCE */
/*
* find the first occurrence of byte 'c', or 1 past the area if none
diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
index a164862..f942deb 100644
--- a/arch/x86/include/asm/string_64.h
+++ b/arch/x86/include/asm/string_64.h
@@ -31,6 +31,7 @@
extern void *memcpy(void *to, const void *from, size_t len);
extern void *__memcpy(void *to, const void *from, size_t len);
+#ifndef CONFIG_FORTIFY_SOURCE
#ifndef CONFIG_KMEMCHECK
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
#define memcpy(dst, src, len) \
@@ -51,6 +52,7 @@
*/
#define memcpy(dst, src, len) __inline_memcpy((dst), (src), (len))
#endif
+#endif /* !CONFIG_FORTIFY_SOURCE */
#define __HAVE_ARCH_MEMSET
void *memset(void *s, int c, size_t n);
@@ -77,6 +79,11 @@
#define memcpy(dst, src, len) __memcpy(dst, src, len)
#define memmove(dst, src, len) __memmove(dst, src, len)
#define memset(s, c, n) __memset(s, c, n)
+
+#ifndef __NO_FORTIFY
+#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
+#endif
+
#endif
__must_check int memcpy_mcsafe_unrolled(void *dst, const void *src, size_t cnt);
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c
index cad1263..2eab7d0 100644
--- a/arch/x86/lib/memcpy_32.c
+++ b/arch/x86/lib/memcpy_32.c
@@ -6,7 +6,7 @@
__visible void *memcpy(void *to, const void *from, size_t n)
{
-#ifdef CONFIG_X86_USE_3DNOW
+#if defined(CONFIG_X86_USE_3DNOW) && !defined(CONFIG_FORTIFY_SOURCE)
return __memcpy3d(to, from, n);
#else
return __memcpy(to, from, n);
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index e167a1e1..4f638ab 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -165,7 +165,8 @@
{
int ret;
- ret = cma_declare_contiguous(base, size, limit, 0, 0, fixed, res_cma);
+ ret = cma_declare_contiguous(base, size, limit, 0, 0, fixed,
+ "reserved", res_cma);
if (ret)
return ret;
@@ -257,7 +258,7 @@
return -EINVAL;
}
- err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
+ err = cma_init_reserved_mem(rmem->base, rmem->size, 0, rmem->name, &cma);
if (err) {
pr_err("Reserved memory: unable to setup CMA region\n");
return err;
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index aa5e22c..7c8f6bf 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -306,7 +306,7 @@
unsigned long vm_flags,
pgprot_t prot, const void *caller)
{
- int i;
+ unsigned long i;
struct page **pages;
void *ptr;
unsigned long pfn;
diff --git a/drivers/bluetooth/btfm_slim_codec.c b/drivers/bluetooth/btfm_slim_codec.c
index b5c42fcc..309648f 100644
--- a/drivers/bluetooth/btfm_slim_codec.c
+++ b/drivers/bluetooth/btfm_slim_codec.c
@@ -26,6 +26,9 @@
#include <sound/tlv.h>
#include <btfm_slim.h>
+static int bt_soc_enable_status;
+
+
static int btfm_slim_codec_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
@@ -38,8 +41,31 @@
return 0;
}
+static int bt_soc_status_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = bt_soc_enable_status;
+ return 1;
+}
+
+static int bt_soc_status_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 1;
+}
+
+static const struct snd_kcontrol_new status_controls[] = {
+ SOC_SINGLE_EXT("BT SOC status", 0, 0, 1, 0,
+ bt_soc_status_get,
+ bt_soc_status_put)
+
+};
+
+
static int btfm_slim_codec_probe(struct snd_soc_codec *codec)
{
+ snd_soc_add_codec_controls(codec, status_controls,
+ ARRAY_SIZE(status_controls));
return 0;
}
@@ -92,9 +118,6 @@
return;
}
- if (dai->id == BTFM_FM_SLIM_TX)
- goto out;
-
/* Search for dai->id matched port handler */
for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
@@ -108,7 +131,6 @@
}
btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
-out:
btfm_slim_hw_deinit(btfmslim);
}
@@ -130,6 +152,7 @@
struct btfmslim *btfmslim = dai->dev->platform_data;
struct btfmslim_ch *ch;
uint8_t rxport, grp = false, nchan = 1;
+ bt_soc_enable_status = 0;
BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
dai->id, dai->rate);
@@ -171,61 +194,10 @@
}
ret = btfm_slim_enable_ch(btfmslim, ch, rxport, dai->rate, grp, nchan);
- return ret;
-}
-static int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int ret = -EINVAL, i;
- struct btfmslim *btfmslim = dai->dev->platform_data;
- struct btfmslim_ch *ch;
- uint8_t rxport, grp = false, nchan = 1;
-
- BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
- dai->id, dai->rate);
-
- switch (dai->id) {
- case BTFM_FM_SLIM_TX:
- grp = true; nchan = 2;
- ch = btfmslim->tx_chs;
- rxport = 0;
- break;
- case BTFM_BT_SCO_SLIM_TX:
- ch = btfmslim->tx_chs;
- rxport = 0;
- break;
- case BTFM_BT_SCO_A2DP_SLIM_RX:
- case BTFM_BT_SPLIT_A2DP_SLIM_RX:
- ch = btfmslim->rx_chs;
- rxport = 1;
- break;
- case BTFM_SLIM_NUM_CODEC_DAIS:
- default:
- BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
- goto out;
- }
-
- if (dai->id != BTFM_FM_SLIM_TX) {
- ret = 0;
- goto out;
- }
-
- /* Search for dai->id matched port handler */
- for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
- (ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
- (ch->id != dai->id); ch++, i++)
- ;
-
- if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
- (ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
- BTFMSLIM_ERR("ch is invalid!!");
- goto out;
- }
-
- btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
-
-out:
+ /* save the enable channel status */
+ if (ret == 0)
+ bt_soc_enable_status = 1;
return ret;
}
@@ -374,7 +346,6 @@
.shutdown = btfm_slim_dai_shutdown,
.hw_params = btfm_slim_dai_hw_params,
.prepare = btfm_slim_dai_prepare,
- .hw_free = btfm_slim_dai_hw_free,
.set_channel_map = btfm_slim_dai_set_channel_map,
.get_channel_map = btfm_slim_dai_get_channel_map,
};
diff --git a/drivers/bluetooth/btfm_slim_wcn3990.c b/drivers/bluetooth/btfm_slim_wcn3990.c
index 77e2973..3d66fff 100644
--- a/drivers/bluetooth/btfm_slim_wcn3990.c
+++ b/drivers/bluetooth/btfm_slim_wcn3990.c
@@ -82,18 +82,18 @@
uint8_t rxport, uint8_t enable)
{
int ret = 0;
- uint8_t reg_val = 0;
+ uint8_t reg_val = 0, en;
uint8_t port_bit = 0;
uint16_t reg;
BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
if (rxport) {
- if (enable && btfmslim->sample_rate == 48000) {
- /* For A2DP Rx */
+ if (enable) {
+ /* For SCO Rx, A2DP Rx */
reg_val = 0x1;
port_bit = port_num - 0x10;
reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(port_bit);
- BTFMSLIM_DBG("writing reg_val (%d) to reg(%x) for A2DP",
+ BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD);
if (ret) {
@@ -137,15 +137,15 @@
reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num);
enable_disable_rxport:
- if (enable) {
- if (is_fm_port(port_num))
- reg_val = CHRK_SB_PGD_PORT_ENABLE |
- CHRK_SB_PGD_PORT_WM_L3;
- else
- reg_val = CHRK_SB_PGD_PORT_ENABLE |
- CHRK_SB_PGD_PORT_WM_LB;
- } else
- reg_val = CHRK_SB_PGD_PORT_DISABLE;
+ if (enable)
+ en = CHRK_SB_PGD_PORT_ENABLE;
+ else
+ en = CHRK_SB_PGD_PORT_DISABLE;
+
+ if (is_fm_port(port_num))
+ reg_val = en | CHRK_SB_PGD_PORT_WM_L8;
+ else
+ reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_LB : en;
ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD);
if (ret)
diff --git a/drivers/bluetooth/btfm_slim_wcn3990.h b/drivers/bluetooth/btfm_slim_wcn3990.h
index 6bbdb6b..b2723ff 100644
--- a/drivers/bluetooth/btfm_slim_wcn3990.h
+++ b/drivers/bluetooth/btfm_slim_wcn3990.h
@@ -68,6 +68,7 @@
#define CHRK_SB_PGD_PORT_WM_L1 (0x1 << 1)
#define CHRK_SB_PGD_PORT_WM_L2 (0x2 << 1)
#define CHRK_SB_PGD_PORT_WM_L3 (0x3 << 1)
+#define CHRK_SB_PGD_PORT_WM_L8 (0x8 << 1)
#define CHRK_SB_PGD_PORT_WM_LB (0xB << 1)
#define CHRK_SB_PGD_PORT_RX_NUM 16
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index d1e01bd..2ede69e 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -2186,9 +2186,11 @@
kref_init(&me->channel[cid].kref);
pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
MAJOR(me->dev_no), cid);
- err = glink_queue_rx_intent(me->channel[cid].chan, NULL, 64);
+ err = glink_queue_rx_intent(me->channel[cid].chan, NULL, 16);
+ err |= glink_queue_rx_intent(me->channel[cid].chan, NULL, 64);
if (err)
- pr_info("adsprpc: initial intent failed for %d\n", cid);
+ pr_warn("adsprpc: initial intent fail for %d err %d\n",
+ cid, err);
if (me->channel[cid].ssrcount !=
me->channel[cid].prevssrcount) {
me->channel[cid].prevssrcount =
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index a0a9ab6..177bbdb 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -69,6 +69,7 @@
"Uses Device Tree: %d\n"
"Apps Supports Separate CMDRSP: %d\n"
"Apps Supports HDLC Encoding: %d\n"
+ "Apps Supports Header Untagging: %d\n"
"Apps Supports Sockets: %d\n"
"Logging Mode: %d\n"
"RSP Buffer is Busy: %d\n"
@@ -83,6 +84,7 @@
driver->use_device_tree,
driver->supports_separate_cmdrsp,
driver->supports_apps_hdlc_encoding,
+ driver->supports_apps_header_untagging,
driver->supports_sockets,
driver->logging_mode,
driver->rsp_buf_busy,
@@ -94,7 +96,7 @@
for (i = 0; i < NUM_PERIPHERALS; i++) {
ret += scnprintf(buf+ret, buf_size-ret,
- "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c|\n",
+ "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c|\n",
PERIPHERAL_STRING(i),
driver->feature[i].feature_mask[0],
driver->feature[i].feature_mask[1],
@@ -105,7 +107,8 @@
driver->feature[i].mask_centralization ? 'M':'m',
driver->feature[i].stm_support ? 'Q':'q',
driver->feature[i].sockets_enabled ? 'S':'s',
- driver->feature[i].sent_feature_mask ? 'T':'t');
+ driver->feature[i].sent_feature_mask ? 'T':'t',
+ driver->feature[i].untag_header ? 'U':'u');
}
#ifdef CONFIG_DIAG_OVER_USB
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 8aefb5a1..d734e29 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -28,7 +28,8 @@
#define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7)))
#define diag_check_update(x) \
- (!info || (info && (info->peripheral_mask & MD_PERIPHERAL_MASK(x)))) \
+ (!info || (info && (info->peripheral_mask & MD_PERIPHERAL_MASK(x))) \
+ || (info && (info->peripheral_mask & MD_PERIPHERAL_PD_MASK(x)))) \
struct diag_mask_info msg_mask;
struct diag_mask_info msg_bt_mask;
@@ -90,8 +91,8 @@
int err = 0;
int send_once = 0;
int header_len = sizeof(struct diag_ctrl_log_mask);
- uint8_t *buf = NULL;
- uint8_t *temp = NULL;
+ uint8_t *buf = NULL, *temp = NULL;
+ uint8_t upd = 0;
uint32_t mask_size = 0;
struct diag_ctrl_log_mask ctrl_pkt;
struct diag_mask_info *mask_info = NULL;
@@ -107,11 +108,25 @@
return;
}
- if (driver->md_session_mask != 0 &&
- driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral))
- mask_info = driver->md_session_map[peripheral]->log_mask;
- else
+ if (driver->md_session_mask != 0) {
+ if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
+ if (driver->md_session_map[peripheral])
+ mask_info =
+ driver->md_session_map[peripheral]->log_mask;
+ } else if (driver->md_session_mask &
+ MD_PERIPHERAL_PD_MASK(peripheral)) {
+ upd = diag_mask_to_pd_value(driver->md_session_mask);
+ if (upd && driver->md_session_map[upd])
+ mask_info =
+ driver->md_session_map[upd]->log_mask;
+ } else {
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "asking for mask update with unknown session mask\n");
+ return;
+ }
+ } else {
mask_info = &log_mask;
+ }
if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
return;
@@ -196,8 +211,8 @@
static void diag_send_event_mask_update(uint8_t peripheral)
{
- uint8_t *buf = NULL;
- uint8_t *temp = NULL;
+ uint8_t *buf = NULL, *temp = NULL;
+ uint8_t upd = 0;
struct diag_ctrl_event_mask header;
struct diag_mask_info *mask_info = NULL;
int num_bytes = EVENT_COUNT_TO_BYTES(driver->last_event_id);
@@ -221,11 +236,25 @@
return;
}
- if (driver->md_session_mask != 0 &&
- (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)))
- mask_info = driver->md_session_map[peripheral]->event_mask;
- else
+ if (driver->md_session_mask != 0) {
+ if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
+ if (driver->md_session_map[peripheral])
+ mask_info =
+ driver->md_session_map[peripheral]->event_mask;
+ } else if (driver->md_session_mask &
+ MD_PERIPHERAL_PD_MASK(peripheral)) {
+ upd = diag_mask_to_pd_value(driver->md_session_mask);
+ if (upd && driver->md_session_map[upd])
+ mask_info =
+ driver->md_session_map[upd]->event_mask;
+ } else {
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "asking for mask update with unknown session mask\n");
+ return;
+ }
+ } else {
mask_info = &event_mask;
+ }
if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
return;
@@ -285,8 +314,8 @@
int err = 0;
int header_len = sizeof(struct diag_ctrl_msg_mask);
int temp_len = 0;
- uint8_t *buf = NULL;
- uint8_t *temp = NULL;
+ uint8_t *buf = NULL, *temp = NULL;
+ uint8_t upd = 0;
uint32_t mask_size = 0;
struct diag_mask_info *mask_info = NULL;
struct diag_msg_mask_t *mask = NULL;
@@ -303,11 +332,25 @@
return;
}
- if (driver->md_session_mask != 0 &&
- (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)))
- mask_info = driver->md_session_map[peripheral]->msg_mask;
- else
+ if (driver->md_session_mask != 0) {
+ if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
+ if (driver->md_session_map[peripheral])
+ mask_info =
+ driver->md_session_map[peripheral]->msg_mask;
+ } else if (driver->md_session_mask &
+ MD_PERIPHERAL_PD_MASK(peripheral)) {
+ upd = diag_mask_to_pd_value(driver->md_session_mask);
+ if (upd && driver->md_session_map[upd])
+ mask_info =
+ driver->md_session_map[upd]->msg_mask;
+ } else {
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "asking for mask update with unknown session mask\n");
+ return;
+ }
+ } else {
mask_info = &msg_mask;
+ }
if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
return;
@@ -466,6 +509,13 @@
DIAG_SET_FEATURE_MASK(F_DIAG_REQ_RSP_SUPPORT);
if (driver->supports_apps_hdlc_encoding)
DIAG_SET_FEATURE_MASK(F_DIAG_APPS_HDLC_ENCODE);
+ if (driver->supports_apps_header_untagging) {
+ if (peripheral == PERIPHERAL_MODEM) {
+ DIAG_SET_FEATURE_MASK(F_DIAG_PKT_HEADER_UNTAG);
+ driver->peripheral_untag[peripheral] =
+ ENABLE_PKT_HEADER_UNTAGGING;
+ }
+ }
DIAG_SET_FEATURE_MASK(F_DIAG_MASK_CENTRALIZATION);
if (driver->supports_sockets)
DIAG_SET_FEATURE_MASK(F_DIAG_SOCKETS_ENABLED);
@@ -1933,17 +1983,27 @@
void diag_send_updates_peripheral(uint8_t peripheral)
{
diag_send_feature_mask_update(peripheral);
- if (driver->time_sync_enabled)
- diag_send_time_sync_update(peripheral);
- mutex_lock(&driver->md_session_lock);
- diag_send_msg_mask_update(peripheral, ALL_SSID, ALL_SSID);
- diag_send_log_mask_update(peripheral, ALL_EQUIP_ID);
- diag_send_event_mask_update(peripheral);
- mutex_unlock(&driver->md_session_lock);
- diag_send_real_time_update(peripheral,
+ /*
+ * Masks (F3, logs and events) will be sent to
+ * peripheral immediately following feature mask update only
+ * if diag_id support is not present or
+ * diag_id support is present and diag_id has been sent to
+ * peripheral.
+ */
+ if (!driver->feature[peripheral].diag_id_support ||
+ driver->diag_id_sent[peripheral]) {
+ if (driver->time_sync_enabled)
+ diag_send_time_sync_update(peripheral);
+ mutex_lock(&driver->md_session_lock);
+ diag_send_msg_mask_update(peripheral, ALL_SSID, ALL_SSID);
+ diag_send_log_mask_update(peripheral, ALL_EQUIP_ID);
+ diag_send_event_mask_update(peripheral);
+ mutex_unlock(&driver->md_session_lock);
+ diag_send_real_time_update(peripheral,
driver->real_time_mode[DIAG_LOCAL_PROC]);
- diag_send_peripheral_buffering_mode(
- &driver->buffering_mode[peripheral]);
+ diag_send_peripheral_buffering_mode(
+ &driver->buffering_mode[peripheral]);
+ }
}
int diag_process_apps_masks(unsigned char *buf, int len,
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index 13ad402..7e3fe90 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -29,6 +29,7 @@
#include "diagmem.h"
#include "diagfwd.h"
#include "diagfwd_peripheral.h"
+#include "diag_ipc_logging.h"
struct diag_md_info diag_md[NUM_DIAG_MD_DEV] = {
{
@@ -132,7 +133,7 @@
uint8_t found = 0;
unsigned long flags;
struct diag_md_info *ch = NULL;
- uint8_t peripheral;
+ int peripheral;
struct diag_md_session_t *session_info = NULL;
if (id < 0 || id >= NUM_DIAG_MD_DEV || id >= DIAG_NUM_PROC)
@@ -141,11 +142,12 @@
if (!buf || len < 0)
return -EINVAL;
- peripheral = GET_BUF_PERIPHERAL(ctx);
- if (peripheral > NUM_PERIPHERALS)
+ peripheral = diag_md_get_peripheral(ctx);
+ if (peripheral < 0)
return -EINVAL;
- session_info = diag_md_session_get_peripheral(peripheral);
+ session_info =
+ diag_md_session_get_peripheral(peripheral);
if (!session_info)
return -EIO;
@@ -214,7 +216,7 @@
struct diag_md_info *ch = NULL;
struct diag_buf_tbl_t *entry = NULL;
uint8_t drain_again = 0;
- uint8_t peripheral = 0;
+ int peripheral = 0;
struct diag_md_session_t *session_info = NULL;
for (i = 0; i < NUM_DIAG_MD_DEV && !err; i++) {
@@ -223,12 +225,15 @@
entry = &ch->tbl[j];
if (entry->len <= 0)
continue;
- peripheral = GET_BUF_PERIPHERAL(entry->ctx);
- /* Account for Apps data as well */
- if (peripheral > NUM_PERIPHERALS)
+
+ peripheral = diag_md_get_peripheral(entry->ctx);
+ if (peripheral < 0)
goto drop_data;
session_info =
diag_md_session_get_peripheral(peripheral);
+ if (!session_info)
+ goto drop_data;
+
if (session_info && info &&
(session_info->pid != info->pid))
continue;
@@ -320,8 +325,15 @@
spin_lock_irqsave(&ch->lock, flags);
for (i = 0; i < ch->num_tbl_entries && !found; i++) {
entry = &ch->tbl[i];
- if (GET_BUF_PERIPHERAL(entry->ctx) != peripheral)
- continue;
+
+ if (peripheral > NUM_PERIPHERALS) {
+ if (GET_PD_CTXT(entry->ctx) != peripheral)
+ continue;
+ } else {
+ if (GET_BUF_PERIPHERAL(entry->ctx) !=
+ peripheral)
+ continue;
+ }
found = 1;
if (ch->ops && ch->ops->write_done) {
ch->ops->write_done(entry->buf, entry->len,
diff --git a/drivers/char/diag/diag_mux.c b/drivers/char/diag/diag_mux.c
index 8f5a002..e65b493 100644
--- a/drivers/char/diag/diag_mux.c
+++ b/drivers/char/diag/diag_mux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -27,7 +27,8 @@
#include "diag_mux.h"
#include "diag_usb.h"
#include "diag_memorydevice.h"
-
+#include "diagfwd_peripheral.h"
+#include "diag_ipc_logging.h"
struct diag_mux_state_t *diag_mux;
static struct diag_logger_t usb_logger;
@@ -141,9 +142,13 @@
if (!diag_mux)
return -EIO;
- peripheral = GET_BUF_PERIPHERAL(ctx);
- if (peripheral > NUM_PERIPHERALS)
+ peripheral = diag_md_get_peripheral(ctx);
+ if (peripheral < 0) {
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag:%s:%d invalid peripheral = %d\n",
+ __func__, __LINE__, peripheral);
return -EINVAL;
+ }
if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask)
logger = diag_mux->md_ptr;
@@ -162,8 +167,13 @@
if (proc < 0 || proc >= NUM_MUX_PROC)
return -EINVAL;
/* Peripheral should account for Apps data as well */
- if (peripheral > NUM_PERIPHERALS)
- return -EINVAL;
+ if (peripheral > NUM_PERIPHERALS) {
+ if (!driver->num_pd_session)
+ return -EINVAL;
+ if (peripheral > NUM_MD_SESSIONS)
+ return -EINVAL;
+ }
+
if (!diag_mux)
return -EIO;
@@ -184,7 +194,8 @@
if (!req_mode)
return -EINVAL;
- if (*peripheral_mask <= 0 || *peripheral_mask > DIAG_CON_ALL) {
+ if (*peripheral_mask <= 0 ||
+ (*peripheral_mask > (DIAG_CON_ALL | DIAG_CON_UPD_ALL))) {
pr_err("diag: mask %d in %s\n", *peripheral_mask, __func__);
return -EINVAL;
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 8051d5d..ac3c1fd 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -58,19 +58,23 @@
#define DIAG_CTRL_MSG_F3_MASK 11
#define CONTROL_CHAR 0x7E
+#define DIAG_ID_ROOT_STRING "root"
+
#define DIAG_CON_APSS (0x0001) /* Bit mask for APSS */
#define DIAG_CON_MPSS (0x0002) /* Bit mask for MPSS */
#define DIAG_CON_LPASS (0x0004) /* Bit mask for LPASS */
#define DIAG_CON_WCNSS (0x0008) /* Bit mask for WCNSS */
#define DIAG_CON_SENSORS (0x0010) /* Bit mask for Sensors */
-#define DIAG_CON_WDSP (0x0020) /* Bit mask for WDSP */
-#define DIAG_CON_CDSP (0x0040)
+#define DIAG_CON_WDSP (0x0020) /* Bit mask for WDSP */
+#define DIAG_CON_CDSP (0x0040) /* Bit mask for CDSP */
+#define DIAG_CON_UPD_WLAN (0x1000) /*Bit mask for WLAN PD*/
#define DIAG_CON_NONE (0x0000) /* Bit mask for No SS*/
#define DIAG_CON_ALL (DIAG_CON_APSS | DIAG_CON_MPSS \
| DIAG_CON_LPASS | DIAG_CON_WCNSS \
| DIAG_CON_SENSORS | DIAG_CON_WDSP \
| DIAG_CON_CDSP)
+#define DIAG_CON_UPD_ALL (DIAG_CON_UPD_WLAN)
#define DIAG_STM_MODEM 0x01
#define DIAG_STM_LPASS 0x02
@@ -165,7 +169,7 @@
#define PKT_ALLOC 1
#define PKT_RESET 2
-#define FEATURE_MASK_LEN 2
+#define FEATURE_MASK_LEN 4
#define DIAG_MD_NONE 0
#define DIAG_MD_PERIPHERAL 1
@@ -209,11 +213,18 @@
#define NUM_PERIPHERALS 6
#define APPS_DATA (NUM_PERIPHERALS)
+#define UPD_WLAN 7
+#define NUM_UPD 1
+#define MAX_PERIPHERAL_UPD 1
/* Number of sessions possible in Memory Device Mode. +1 for Apps data */
-#define NUM_MD_SESSIONS (NUM_PERIPHERALS + 1)
+#define NUM_MD_SESSIONS (NUM_PERIPHERALS \
+ + NUM_UPD + 1)
#define MD_PERIPHERAL_MASK(x) (1 << x)
+#define MD_PERIPHERAL_PD_MASK(x) \
+ ((x == PERIPHERAL_MODEM) ? (1 << UPD_WLAN) : 0)\
+
/*
* Number of stm processors includes all the peripherals and
* apps.Added 1 below to indicate apps
@@ -439,6 +450,7 @@
struct diag_logging_mode_param_t {
uint32_t req_mode;
uint32_t peripheral_mask;
+ uint32_t pd_mask;
uint8_t mode_param;
} __packed;
@@ -485,11 +497,13 @@
uint8_t log_on_demand;
uint8_t separate_cmd_rsp;
uint8_t encode_hdlc;
+ uint8_t untag_header;
uint8_t peripheral_buffering;
uint8_t mask_centralization;
uint8_t stm_support;
uint8_t sockets_enabled;
uint8_t sent_feature_mask;
+ uint8_t diag_id_support;
};
struct diagchar_dev {
@@ -516,6 +530,8 @@
int use_device_tree;
int supports_separate_cmdrsp;
int supports_apps_hdlc_encoding;
+ int supports_apps_header_untagging;
+ int peripheral_untag[NUM_PERIPHERALS];
int supports_sockets;
/* The state requested in the STM command */
int stm_state_requested[NUM_STM_PROCESSORS];
@@ -612,6 +628,10 @@
int in_busy_dcipktdata;
int logging_mode;
int logging_mask;
+ int pd_logging_mode[NUM_UPD];
+ int pd_session_clear[NUM_UPD];
+ int num_pd_session;
+ int diag_id_sent[NUM_PERIPHERALS];
int mask_check;
uint32_t md_session_mask;
uint8_t md_session_mode;
@@ -672,6 +692,7 @@
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
int diag_mask_param(void);
void diag_clear_masks(struct diag_md_session_t *info);
+uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask);
void diag_record_stats(int type, int flag);
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index e4397c5..f0e69ef 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -393,9 +393,28 @@
ret |= DIAG_CON_WDSP;
if (peripheral_mask & MD_PERIPHERAL_MASK(PERIPHERAL_CDSP))
ret |= DIAG_CON_CDSP;
-
+ if (peripheral_mask & MD_PERIPHERAL_MASK(UPD_WLAN))
+ ret |= DIAG_CON_UPD_WLAN;
return ret;
}
+
+uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask)
+{
+ uint8_t upd = 0;
+ uint32_t pd_mask = 0;
+
+ pd_mask = diag_translate_kernel_to_user_mask(peripheral_mask);
+ switch (pd_mask) {
+ case DIAG_CON_UPD_WLAN:
+ upd = UPD_WLAN;
+ break;
+ default:
+ DIAG_LOG(DIAG_DEBUG_MASKS,
+ "asking for mask update with no pd mask set\n");
+ }
+ return upd;
+}
+
int diag_mask_param(void)
{
return diag_mask_clear_param;
@@ -423,8 +442,9 @@
static void diag_close_logging_process(const int pid)
{
- int i;
- int session_peripheral_mask;
+ int i, j;
+ int session_mask;
+ uint32_t p_mask;
struct diag_md_session_t *session_info = NULL;
struct diag_logging_mode_param_t params;
@@ -440,18 +460,33 @@
mutex_unlock(&driver->diag_maskclear_mutex);
mutex_lock(&driver->diagchar_mutex);
- session_peripheral_mask = session_info->peripheral_mask;
+ session_mask = session_info->peripheral_mask;
diag_md_session_close(session_info);
- mutex_unlock(&driver->diagchar_mutex);
+
+ p_mask =
+ diag_translate_kernel_to_user_mask(session_mask);
+
for (i = 0; i < NUM_MD_SESSIONS; i++)
- if (MD_PERIPHERAL_MASK(i) & session_peripheral_mask)
+ if (MD_PERIPHERAL_MASK(i) & session_mask)
diag_mux_close_peripheral(DIAG_LOCAL_PROC, i);
params.req_mode = USB_MODE;
params.mode_param = 0;
- params.peripheral_mask =
- diag_translate_kernel_to_user_mask(session_peripheral_mask);
- mutex_lock(&driver->diagchar_mutex);
+ params.pd_mask = 0;
+ params.peripheral_mask = p_mask;
+
+ if (driver->num_pd_session > 0) {
+ for (i = UPD_WLAN; (i < NUM_MD_SESSIONS); i++) {
+ if (session_mask & MD_PERIPHERAL_MASK(i)) {
+ j = i - UPD_WLAN;
+ driver->pd_session_clear[j] = 1;
+ driver->pd_logging_mode[j] = 0;
+ driver->num_pd_session -= 1;
+ params.pd_mask = p_mask;
+ }
+ }
+ }
+
diag_switch_logging(¶ms);
mutex_unlock(&driver->diagchar_mutex);
}
@@ -654,6 +689,11 @@
driver->polling_reg_flag = 0;
list_for_each_safe(start, temp, &driver->cmd_reg_list) {
item = list_entry(start, struct diag_cmd_reg_t, link);
+ if (&item->entry == NULL) {
+ pr_err("diag: In %s, unable to search command\n",
+ __func__);
+ return;
+ }
polling = diag_cmd_chk_polling(&item->entry);
if (polling == DIAG_CMD_POLLING) {
driver->polling_reg_flag = 1;
@@ -793,6 +833,12 @@
mutex_lock(&driver->cmd_reg_mutex);
list_for_each_safe(start, temp, &driver->cmd_reg_list) {
item = list_entry(start, struct diag_cmd_reg_t, link);
+ if (&item->entry == NULL) {
+ pr_err("diag: In %s, unable to search command\n",
+ __func__);
+ mutex_unlock(&driver->cmd_reg_mutex);
+ return;
+ }
if (item->pid == pid) {
list_del(&item->link);
kfree(item);
@@ -811,6 +857,12 @@
mutex_lock(&driver->cmd_reg_mutex);
list_for_each_safe(start, temp, &driver->cmd_reg_list) {
item = list_entry(start, struct diag_cmd_reg_t, link);
+ if (&item->entry == NULL) {
+ pr_err("diag: In %s, unable to search command\n",
+ __func__);
+ mutex_unlock(&driver->cmd_reg_mutex);
+ return;
+ }
if (item->proc == proc) {
list_del(&item->link);
kfree(item);
@@ -1563,17 +1615,20 @@
ret |= (1 << PERIPHERAL_WDSP);
if (peripheral_mask & DIAG_CON_CDSP)
ret |= (1 << PERIPHERAL_CDSP);
+ if (peripheral_mask & DIAG_CON_UPD_WLAN)
+ ret |= (1 << UPD_WLAN);
return ret;
}
static int diag_switch_logging(struct diag_logging_mode_param_t *param)
{
- int new_mode;
+ int new_mode, i = 0;
int curr_mode;
int err = 0;
uint8_t do_switch = 1;
uint32_t peripheral_mask = 0;
+ uint8_t peripheral, upd;
if (!param)
return -EINVAL;
@@ -1584,8 +1639,41 @@
return -EINVAL;
}
- peripheral_mask = diag_translate_mask(param->peripheral_mask);
- param->peripheral_mask = peripheral_mask;
+ if (param->pd_mask) {
+ switch (param->pd_mask) {
+ case DIAG_CON_UPD_WLAN:
+ peripheral = PERIPHERAL_MODEM;
+ upd = UPD_WLAN;
+ break;
+ default:
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "asking for mode switch with no pd mask set\n");
+ return -EINVAL;
+ }
+
+ if (driver->md_session_map[peripheral] &&
+ (MD_PERIPHERAL_MASK(peripheral) &
+ diag_mux->mux_mask)) {
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "diag_fr: User PD is already logging onto active peripheral logging\n");
+ i = upd - UPD_WLAN;
+ driver->pd_session_clear[i] = 0;
+ return -EINVAL;
+ }
+ peripheral_mask =
+ diag_translate_mask(param->pd_mask);
+ param->peripheral_mask = peripheral_mask;
+ i = upd - UPD_WLAN;
+ if (!driver->pd_session_clear[i]) {
+ driver->pd_logging_mode[i] = 1;
+ driver->num_pd_session += 1;
+ }
+ driver->pd_session_clear[i] = 0;
+ } else {
+ peripheral_mask =
+ diag_translate_mask(param->peripheral_mask);
+ param->peripheral_mask = peripheral_mask;
+ }
switch (param->req_mode) {
case CALLBACK_MODE:
@@ -1605,7 +1693,7 @@
curr_mode = driver->logging_mode;
DIAG_LOG(DIAG_DEBUG_USERSPACE,
- "request to switch logging from %d mask:%0x to %d mask:%0x\n",
+ "request to switch logging from %d mask:%0x to new_mode %d mask:%0x\n",
curr_mode, driver->md_session_mask, new_mode, peripheral_mask);
err = diag_md_session_check(curr_mode, new_mode, param, &do_switch);
@@ -1929,6 +2017,52 @@
return 0;
}
+static int diag_ioctl_query_pd_logging(struct diag_logging_mode_param_t *param)
+{
+ int ret = -EINVAL;
+ int peripheral;
+ char *p_str = NULL;
+
+ if (!param)
+ return -EINVAL;
+
+ if (!param->pd_mask) {
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "query with no pd mask set, returning error\n");
+ return -EINVAL;
+ }
+
+ switch (param->pd_mask) {
+ case DIAG_CON_UPD_WLAN:
+ peripheral = PERIPHERAL_MODEM;
+ p_str = "MODEM";
+ break;
+ default:
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "Invalid pd mask, returning EINVAL\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&driver->diag_cntl_mutex);
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "diag: %s: Untagging support on APPS is %s\n", __func__,
+ ((driver->supports_apps_header_untagging) ?
+ "present" : "absent"));
+
+ DIAG_LOG(DIAG_DEBUG_USERSPACE,
+ "diag: %s: Tagging support on %s is %s\n",
+ __func__, p_str,
+ (driver->feature[peripheral].untag_header ?
+ "present" : "absent"));
+
+ if (driver->supports_apps_header_untagging &&
+ driver->feature[peripheral].untag_header)
+ ret = 0;
+
+ mutex_unlock(&driver->diag_cntl_mutex);
+ return ret;
+}
+
static int diag_ioctl_register_callback(unsigned long ioarg)
{
int err = 0;
@@ -2166,6 +2300,12 @@
case DIAG_IOCTL_HDLC_TOGGLE:
result = diag_ioctl_hdlc_toggle(ioarg);
break;
+ case DIAG_IOCTL_QUERY_PD_LOGGING:
+ if (copy_from_user((void *)&mode_param, (void __user *)ioarg,
+ sizeof(mode_param)))
+ return -EFAULT;
+ result = diag_ioctl_query_pd_logging(&mode_param);
+ break;
}
return result;
}
@@ -2289,6 +2429,12 @@
case DIAG_IOCTL_HDLC_TOGGLE:
result = diag_ioctl_hdlc_toggle(ioarg);
break;
+ case DIAG_IOCTL_QUERY_PD_LOGGING:
+ if (copy_from_user((void *)&mode_param, (void __user *)ioarg,
+ sizeof(mode_param)))
+ return -EFAULT;
+ result = diag_ioctl_query_pd_logging(&mode_param);
+ break;
}
return result;
}
@@ -3342,7 +3488,7 @@
* to be logged to IPC
*/
diag_debug_mask = DIAG_DEBUG_PERIPHERALS | DIAG_DEBUG_DCI |
- DIAG_DEBUG_BRIDGE;
+ DIAG_DEBUG_USERSPACE | DIAG_DEBUG_BRIDGE;
}
#else
static void diag_debug_init(void)
@@ -3472,6 +3618,11 @@
poolsize_usb_apps + 1 + (NUM_PERIPHERALS * 6));
driver->num_clients = max_clients;
driver->logging_mode = DIAG_USB_MODE;
+ for (i = 0; i < NUM_UPD; i++) {
+ driver->pd_logging_mode[i] = 0;
+ driver->pd_session_clear[i] = 0;
+ }
+ driver->num_pd_session = 0;
driver->mask_check = 0;
driver->in_busy_pktdata = 0;
driver->in_busy_dcipktdata = 0;
@@ -3489,8 +3640,10 @@
mutex_init(&apps_data_mutex);
mutex_init(&driver->msg_mask_lock);
mutex_init(&driver->hdlc_recovery_mutex);
- for (i = 0; i < NUM_PERIPHERALS; i++)
+ for (i = 0; i < NUM_PERIPHERALS; i++) {
mutex_init(&driver->diagfwd_channel_mutex[i]);
+ driver->diag_id_sent[i] = 0;
+ }
init_waitqueue_head(&driver->wait_q);
INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
INIT_WORK(&(driver->update_user_clients),
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 3f00a7e..b59f245 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -38,6 +38,7 @@
#include "diag_masks.h"
#include "diag_usb.h"
#include "diag_mux.h"
+#include "diag_ipc_logging.h"
#define STM_CMD_VERSION_OFFSET 4
#define STM_CMD_MASK_OFFSET 5
@@ -1663,6 +1664,9 @@
driver->real_time_mode[i] = 1;
driver->supports_separate_cmdrsp = 1;
driver->supports_apps_hdlc_encoding = 1;
+ driver->supports_apps_header_untagging = 1;
+ for (i = 0; i < NUM_PERIPHERALS; i++)
+ driver->peripheral_untag[i] = 0;
mutex_init(&driver->diag_hdlc_mutex);
mutex_init(&driver->diag_cntl_mutex);
mutex_init(&driver->mode_lock);
@@ -1692,9 +1696,12 @@
driver->feature[i].rcvd_feature_mask = 0;
driver->feature[i].peripheral_buffering = 0;
driver->feature[i].encode_hdlc = 0;
+ driver->feature[i].untag_header =
+ DISABLE_PKT_HEADER_UNTAGGING;
driver->feature[i].mask_centralization = 0;
driver->feature[i].log_on_demand = 0;
driver->feature[i].sent_feature_mask = 0;
+ driver->feature[i].diag_id_support = 0;
driver->buffering_mode[i].peripheral = i;
driver->buffering_mode[i].mode = DIAG_BUFFERING_MODE_STREAMING;
driver->buffering_mode[i].high_wm_val = DEFAULT_HIGH_WM_VAL;
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index 47c8555..677099f 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-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
@@ -19,9 +19,11 @@
*/
#define SET_BUF_CTXT(p, d, n) \
(((p & 0xFF) << 16) | ((d & 0xFF) << 8) | (n & 0xFF))
+#define SET_PD_CTXT(u) ((u & 0xFF) << 24)
#define GET_BUF_PERIPHERAL(p) ((p & 0xFF0000) >> 16)
#define GET_BUF_TYPE(d) ((d & 0x00FF00) >> 8)
#define GET_BUF_NUM(n) ((n & 0x0000FF))
+#define GET_PD_CTXT(u) ((u & 0xFF000000) >> 24)
#define CHK_OVERFLOW(bufStart, start, end, length) \
((((bufStart) <= (start)) && ((end) - (start) >= (length))) ? 1 : 0)
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 5282e02..d7e24fc 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -70,6 +70,7 @@
driver->feature[peripheral].rcvd_feature_mask = 0;
reg_dirty |= PERIPHERAL_MASK(peripheral);
diag_cmd_remove_reg_by_proc(peripheral);
+ driver->diag_id_sent[peripheral] = 0;
driver->feature[peripheral].stm_support = DISABLE_STM;
driver->feature[peripheral].log_on_demand = 0;
driver->stm_state[peripheral] = DISABLE_STM;
@@ -198,6 +199,20 @@
}
}
+static void process_upd_header_untagging_feature(uint8_t peripheral)
+{
+ if (peripheral >= NUM_PERIPHERALS)
+ return;
+
+ if (driver->supports_apps_header_untagging) {
+ driver->feature[peripheral].untag_header =
+ ENABLE_PKT_HEADER_UNTAGGING;
+ } else {
+ driver->feature[peripheral].untag_header =
+ DISABLE_PKT_HEADER_UNTAGGING;
+ }
+}
+
static void process_command_deregistration(uint8_t *buf, uint32_t len,
uint8_t peripheral)
{
@@ -374,6 +389,8 @@
driver->feature[peripheral].separate_cmd_rsp = 1;
if (FEATURE_SUPPORTED(F_DIAG_APPS_HDLC_ENCODE))
process_hdlc_encoding_feature(peripheral);
+ if (FEATURE_SUPPORTED(F_DIAG_PKT_HEADER_UNTAG))
+ process_upd_header_untagging_feature(peripheral);
if (FEATURE_SUPPORTED(F_DIAG_STM))
enable_stm_feature(peripheral);
if (FEATURE_SUPPORTED(F_DIAG_MASK_CENTRALIZATION))
@@ -382,6 +399,8 @@
driver->feature[peripheral].peripheral_buffering = 1;
if (FEATURE_SUPPORTED(F_DIAG_SOCKETS_ENABLED))
enable_socket_feature(peripheral);
+ if (FEATURE_SUPPORTED(F_DIAG_DIAGID_SUPPORT))
+ driver->feature[peripheral].diag_id_support = 1;
}
process_socket_feature(peripheral);
@@ -706,12 +725,24 @@
{
struct diag_ctrl_diagid *header = NULL;
struct diag_ctrl_diagid ctrl_pkt;
+ struct diagfwd_info *fwd_info_data = NULL;
+ struct diagfwd_info *fwd_info_cmd = NULL;
char *process_name = NULL;
int err = 0;
uint8_t local_diag_id = 0;
+ uint8_t new_request = 0;
if (!buf || len == 0 || peripheral >= NUM_PERIPHERALS)
return;
+
+ fwd_info_data = &peripheral_info[TYPE_DATA][peripheral];
+ if (!fwd_info_data)
+ return;
+
+ fwd_info_cmd = &peripheral_info[TYPE_CMD][peripheral];
+ if (!fwd_info_cmd)
+ return;
+
header = (struct diag_ctrl_diagid *)buf;
process_name = (char *)&header->process_name;
if (diag_query_diag_id(process_name, &local_diag_id))
@@ -720,7 +751,27 @@
diag_id++;
diag_add_diag_id_to_list(diag_id, process_name);
ctrl_pkt.diag_id = diag_id;
+ new_request = 1;
}
+
+ if (new_request) {
+ fwd_info_data->num_pd++;
+ fwd_info_cmd->num_pd++;
+ }
+
+ if (strnstr(process_name, DIAG_ID_ROOT_STRING, strlen(process_name))) {
+ fwd_info_cmd->diagid_root = diag_id;
+ fwd_info_data->diagid_root = diag_id;
+ driver->diag_id_sent[peripheral] = 0;
+ } else {
+ fwd_info_cmd->diagid_user[fwd_info_cmd->num_pd - 2] = diag_id;
+ fwd_info_data->diagid_user[fwd_info_data->num_pd - 2] = diag_id;
+ }
+
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag: peripheral = %d: diag_id string = %s,diag_id = %d\n",
+ peripheral, process_name, ctrl_pkt.diag_id);
+
ctrl_pkt.pkt_id = DIAG_CTRL_MSG_DIAGID;
ctrl_pkt.version = 1;
strlcpy((char *)&ctrl_pkt.process_name, process_name,
@@ -730,8 +781,21 @@
err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt, ctrl_pkt.len +
sizeof(ctrl_pkt.pkt_id) + sizeof(ctrl_pkt.len));
if (err && err != -ENODEV) {
- pr_err("diag: Unable to send diag id ctrl packet to peripheral %d, err: %d\n",
+ pr_err("diag: Unable to send diag id ctrl packet to peripheral %d, err: %d\n",
peripheral, err);
+ } else {
+ /*
+ * Masks (F3, logs and events) will be sent to
+ * peripheral immediately following feature mask update only
+ * if diag_id support is not present or
+ * diag_id support is present and diag_id has been sent to
+ * peripheral.
+ * With diag_id being sent now, mask will be updated
+ * to peripherals.
+ */
+ driver->diag_id_sent[peripheral] = 1;
+ diag_send_updates_peripheral(peripheral);
+ diagfwd_buffers_init(fwd_info_data);
}
}
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index 7823040..8b22d7e 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -68,6 +68,7 @@
#define F_DIAG_SOCKETS_ENABLED 13
#define F_DIAG_DCI_EXTENDED_HEADER_SUPPORT 14
#define F_DIAG_DIAGID_SUPPORT 15
+#define F_DIAG_PKT_HEADER_UNTAG 16
#define ENABLE_SEPARATE_CMDRSP 1
#define DISABLE_SEPARATE_CMDRSP 0
@@ -82,6 +83,9 @@
#define ENABLE_APPS_HDLC_ENCODING 1
#define DISABLE_APPS_HDLC_ENCODING 0
+#define ENABLE_PKT_HEADER_UNTAGGING 1
+#define DISABLE_PKT_HEADER_UNTAGGING 0
+
#define DIAG_MODE_PKT_LEN 36
struct diag_ctrl_pkt_header_t {
@@ -279,6 +283,7 @@
void diag_cntl_process_read_data(struct diagfwd_info *p_info, void *buf,
int len);
int diag_send_real_time_update(uint8_t peripheral, int real_time);
+void diag_map_pd_to_diagid(uint8_t pd, uint8_t *diag_id, int *peripheral);
int diag_send_peripheral_buffering_mode(struct diag_buffering_mode_t *params);
void diag_update_proc_vote(uint16_t proc, uint8_t vote, int index);
void diag_update_real_time_vote(uint16_t proc, uint8_t real_time, int index);
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index dd5a552..955d81f 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -45,6 +45,8 @@
static void diagfwd_cntl_close(struct diagfwd_info *fwd_info);
static void diagfwd_dci_open(struct diagfwd_info *fwd_info);
static void diagfwd_dci_close(struct diagfwd_info *fwd_info);
+static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info,
+ unsigned char *buf, int len);
static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,
unsigned char *buf, int len);
static void diagfwd_cntl_read_done(struct diagfwd_info *fwd_info,
@@ -58,7 +60,7 @@
static struct diag_channel_ops data_ch_ops = {
.open = NULL,
.close = NULL,
- .read_done = diagfwd_data_read_done
+ .read_done = diagfwd_data_read_untag_done
};
static struct diag_channel_ops cntl_ch_ops = {
@@ -213,6 +215,317 @@
return buf->len;
}
+int diag_md_get_peripheral(int ctxt)
+{
+ int pd = 0, i = 0;
+ int type = 0, peripheral = -EINVAL;
+ struct diagfwd_info *fwd_info = NULL;
+
+ peripheral = GET_BUF_PERIPHERAL(ctxt);
+ if (peripheral < 0 || peripheral > NUM_PERIPHERALS)
+ return -EINVAL;
+
+ if (peripheral == APPS_DATA)
+ return peripheral;
+
+ type = GET_BUF_TYPE(ctxt);
+ if (type < 0 || type >= NUM_TYPES)
+ return -EINVAL;
+
+ fwd_info = &peripheral_info[type][peripheral];
+ if (!fwd_info)
+ return -EINVAL;
+
+ pd = GET_PD_CTXT(ctxt);
+
+ if (driver->num_pd_session) {
+ if (pd == fwd_info->diagid_root) {
+ if (peripheral > NUM_PERIPHERALS)
+ peripheral = -EINVAL;
+ } else {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
+ if (pd == fwd_info->diagid_user[i]) {
+ switch (peripheral) {
+ case PERIPHERAL_MODEM:
+ if (driver->pd_logging_mode[0])
+ peripheral = UPD_WLAN;
+ break;
+ default:
+ peripheral = -EINVAL;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return peripheral;
+}
+
+static void diagfwd_data_process_done(struct diagfwd_info *fwd_info,
+ struct diagfwd_buf_t *buf, int len)
+{
+ int err = 0;
+ int write_len = 0, peripheral = 0;
+ unsigned char *write_buf = NULL;
+ struct diag_md_session_t *session_info = NULL;
+ uint8_t hdlc_disabled = 0;
+
+ if (!fwd_info || !buf || len <= 0) {
+ diag_ws_release();
+ return;
+ }
+
+ switch (fwd_info->type) {
+ case TYPE_DATA:
+ case TYPE_CMD:
+ break;
+ default:
+ pr_err_ratelimited("diag: In %s, invalid type %d for peripheral %d\n",
+ __func__, fwd_info->type,
+ fwd_info->peripheral);
+ diag_ws_release();
+ return;
+ }
+
+ mutex_lock(&driver->hdlc_disable_mutex);
+ mutex_lock(&fwd_info->data_mutex);
+
+ peripheral =
+ diag_md_get_peripheral(buf->ctxt);
+ if (peripheral < 0) {
+ pr_err("diag:%s:%d invalid peripheral = %d\n",
+ __func__, __LINE__, peripheral);
+ mutex_unlock(&fwd_info->data_mutex);
+ mutex_unlock(&driver->hdlc_disable_mutex);
+ diag_ws_release();
+ return;
+ }
+
+ session_info =
+ diag_md_session_get_peripheral(peripheral);
+ if (session_info)
+ hdlc_disabled = session_info->hdlc_disabled;
+ else
+ hdlc_disabled = driver->hdlc_disabled;
+
+ if (hdlc_disabled) {
+ /* The data is raw and and on APPS side HDLC is disabled */
+ if (!buf) {
+ pr_err("diag: In %s, no match for non encode buffer %pK, peripheral %d, type: %d\n",
+ __func__, buf, fwd_info->peripheral,
+ fwd_info->type);
+ goto end;
+ }
+ if (len > PERIPHERAL_BUF_SZ) {
+ pr_err("diag: In %s, Incoming buffer too large %d, peripheral %d, type: %d\n",
+ __func__, len, fwd_info->peripheral,
+ fwd_info->type);
+ goto end;
+ }
+ write_len = len;
+ if (write_len <= 0)
+ goto end;
+ write_buf = buf->data_raw;
+ } else {
+ if (!buf) {
+ pr_err("diag: In %s, no match for non encode buffer %pK, peripheral %d, type: %d\n",
+ __func__, buf, fwd_info->peripheral,
+ fwd_info->type);
+ goto end;
+ }
+
+ write_len = check_bufsize_for_encoding(buf, len);
+ if (write_len <= 0) {
+ pr_err("diag: error in checking buf for encoding\n");
+ goto end;
+ }
+ write_buf = buf->data;
+ err = diag_add_hdlc_encoding(write_buf, &write_len,
+ buf->data_raw, len);
+ if (err) {
+ pr_err("diag: error in adding hdlc encoding\n");
+ goto end;
+ }
+ }
+
+ if (write_len > 0) {
+ err = diag_mux_write(DIAG_LOCAL_PROC, write_buf, write_len,
+ buf->ctxt);
+ if (err) {
+ pr_err_ratelimited("diag: In %s, unable to write to mux error: %d\n",
+ __func__, err);
+ goto end;
+ }
+ }
+ mutex_unlock(&fwd_info->data_mutex);
+ mutex_unlock(&driver->hdlc_disable_mutex);
+ diagfwd_queue_read(fwd_info);
+ return;
+
+end:
+ diag_ws_release();
+ mutex_unlock(&fwd_info->data_mutex);
+ mutex_unlock(&driver->hdlc_disable_mutex);
+ if (buf) {
+ diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
+ GET_BUF_NUM(buf->ctxt));
+ }
+ diagfwd_queue_read(fwd_info);
+}
+
+static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info,
+ unsigned char *buf, int len)
+{
+ int i = 0;
+ int len_cpd = 0;
+ int ctxt_cpd = 0;
+ int len_upd[MAX_PERIPHERAL_UPD] = {0};
+ int ctxt_upd[MAX_PERIPHERAL_UPD] = {0};
+ int packet_len = 0, processed = 0;
+ unsigned char *temp_buf_main = NULL;
+ unsigned char *temp_buf_cpd = NULL;
+ unsigned char *temp_buf_upd[MAX_PERIPHERAL_UPD] = {NULL};
+ struct diagfwd_buf_t *temp_fwdinfo_cpd = NULL;
+ struct diagfwd_buf_t *temp_fwdinfo_upd = NULL;
+ int flag_buf_1 = 0, flag_buf_2 = 0;
+ uint8_t peripheral;
+
+ if (!fwd_info || !buf || len <= 0) {
+ diag_ws_release();
+ return;
+ }
+
+ switch (fwd_info->type) {
+ case TYPE_DATA:
+ case TYPE_CMD:
+ break;
+ default:
+ pr_err_ratelimited("diag: In %s, invalid type %d for peripheral %d\n",
+ __func__, fwd_info->type,
+ fwd_info->peripheral);
+ diag_ws_release();
+ return;
+ }
+ peripheral = fwd_info->peripheral;
+ if (peripheral >= NUM_PERIPHERALS)
+ return;
+
+ if (driver->feature[peripheral].encode_hdlc &&
+ driver->feature[peripheral].untag_header &&
+ driver->peripheral_untag[peripheral]) {
+ temp_buf_cpd = buf;
+ temp_buf_main = buf;
+ if (fwd_info->buf_1 &&
+ fwd_info->buf_1->data_raw == buf) {
+ flag_buf_1 = 1;
+ temp_fwdinfo_cpd = fwd_info->buf_1;
+ if (fwd_info->type == TYPE_DATA) {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++)
+ temp_buf_upd[i] =
+ fwd_info->buf_upd[i][0]->data_raw;
+ }
+ } else if (fwd_info->buf_2 &&
+ fwd_info->buf_2->data_raw == buf) {
+ flag_buf_2 = 1;
+ temp_fwdinfo_cpd = fwd_info->buf_2;
+ if (fwd_info->type == TYPE_DATA) {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++)
+ temp_buf_upd[i] =
+ fwd_info->buf_upd[i][1]->data_raw;
+ }
+ } else {
+ pr_err("diag: In %s, no match for buffer %pK, peripheral %d, type: %d\n",
+ __func__, buf, peripheral,
+ fwd_info->type);
+ goto end;
+ }
+
+ while (processed < len) {
+ pr_debug("diag_fr:untagged packet buf contents: %02x %02x %02x %02x\n",
+ *temp_buf_main, *(temp_buf_main+1),
+ *(temp_buf_main+2), *(temp_buf_main+3));
+ packet_len =
+ *(uint16_t *) (temp_buf_main + 2);
+ if (packet_len > PERIPHERAL_BUF_SZ)
+ goto end;
+ if ((*temp_buf_main) == fwd_info->diagid_root) {
+ ctxt_cpd = fwd_info->diagid_root;
+ len_cpd += packet_len;
+ if (temp_buf_cpd) {
+ memcpy(temp_buf_cpd,
+ (temp_buf_main + 4), packet_len);
+ temp_buf_cpd += packet_len;
+ }
+ } else {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++)
+ if ((*temp_buf_main) ==
+ fwd_info->diagid_user[i])
+ break;
+ ctxt_upd[i] = fwd_info->diagid_user[i];
+ if (temp_buf_upd[i]) {
+ memcpy(temp_buf_upd[i],
+ (temp_buf_main + 4), packet_len);
+ temp_buf_upd[i] += packet_len;
+ }
+ len_upd[i] += packet_len;
+ }
+ len = len - 4;
+ temp_buf_main += (packet_len + 4);
+ processed += packet_len;
+ }
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
+ if (fwd_info->type == TYPE_DATA && len_upd[i]) {
+ if (flag_buf_1) {
+ fwd_info->upd_len[i][0] = len_upd[i];
+ temp_fwdinfo_upd =
+ fwd_info->buf_upd[i][0];
+ } else {
+ fwd_info->upd_len[i][1] = len_upd[i];
+ temp_fwdinfo_upd =
+ fwd_info->buf_upd[i][1];
+ }
+ temp_fwdinfo_upd->ctxt &= 0x00FFFFFF;
+ temp_fwdinfo_upd->ctxt |=
+ (SET_PD_CTXT(ctxt_upd[i]));
+ atomic_set(&temp_fwdinfo_upd->in_busy, 1);
+ diagfwd_data_process_done(fwd_info,
+ temp_fwdinfo_upd, len_upd[i]);
+ } else {
+ if (flag_buf_1)
+ fwd_info->upd_len[i][0] = 0;
+ if (flag_buf_2)
+ fwd_info->upd_len[i][1] = 0;
+ }
+ }
+ if (len_cpd) {
+ if (flag_buf_1)
+ fwd_info->cpd_len_1 = len_cpd;
+ else
+ fwd_info->cpd_len_2 = len_cpd;
+ temp_fwdinfo_cpd->ctxt &= 0x00FFFFFF;
+ temp_fwdinfo_cpd->ctxt |=
+ (SET_PD_CTXT(ctxt_cpd));
+ diagfwd_data_process_done(fwd_info,
+ temp_fwdinfo_cpd, len_cpd);
+ } else {
+ if (flag_buf_1)
+ fwd_info->cpd_len_1 = 0;
+ if (flag_buf_2)
+ fwd_info->cpd_len_2 = 0;
+ }
+ } else {
+ diagfwd_data_read_done(fwd_info, buf, len);
+ }
+ return;
+end:
+ diag_ws_release();
+ if (temp_fwdinfo_cpd) {
+ diagfwd_write_done(fwd_info->peripheral, fwd_info->type,
+ GET_BUF_NUM(temp_fwdinfo_cpd->ctxt));
+ }
+ diagfwd_queue_read(fwd_info);
+}
+
static void diagfwd_data_read_done(struct diagfwd_info *fwd_info,
unsigned char *buf, int len)
{
@@ -413,6 +726,7 @@
uint8_t peripheral;
uint8_t transport;
uint8_t type;
+ int i = 0;
struct diagfwd_info *fwd_info = NULL;
for (transport = 0; transport < NUM_TRANSPORT; transport++) {
@@ -436,9 +750,20 @@
fwd_info->inited = 1;
fwd_info->read_bytes = 0;
fwd_info->write_bytes = 0;
+ fwd_info->cpd_len_1 = 0;
+ fwd_info->cpd_len_2 = 0;
+ fwd_info->num_pd = 0;
mutex_init(&fwd_info->buf_mutex);
mutex_init(&fwd_info->data_mutex);
spin_lock_init(&fwd_info->write_buf_lock);
+
+ for (i = 0; i < MAX_PERIPHERAL_UPD; i++) {
+ fwd_info->diagid_user[i] = 0;
+ fwd_info->upd_len[i][0] = 0;
+ fwd_info->upd_len[i][1] = 0;
+ fwd_info->buf_upd[i][0] = NULL;
+ fwd_info->buf_upd[i][1] = NULL;
+ }
}
}
@@ -452,9 +777,20 @@
fwd_info->ch_open = 0;
fwd_info->read_bytes = 0;
fwd_info->write_bytes = 0;
+ fwd_info->num_pd = 0;
+ fwd_info->cpd_len_1 = 0;
+ fwd_info->cpd_len_2 = 0;
spin_lock_init(&fwd_info->write_buf_lock);
mutex_init(&fwd_info->buf_mutex);
mutex_init(&fwd_info->data_mutex);
+
+ for (i = 0; i < MAX_PERIPHERAL_UPD; i++) {
+ fwd_info->diagid_user[i] = 0;
+ fwd_info->upd_len[i][0] = 0;
+ fwd_info->upd_len[i][1] = 0;
+ fwd_info->buf_upd[i][0] = NULL;
+ fwd_info->buf_upd[i][1] = NULL;
+ }
/*
* This state shouldn't be set for Control channels
* during initialization. This is set when the feature
@@ -730,6 +1066,16 @@
if (!fwd_info->inited || !atomic_read(&fwd_info->opened))
return -ENODEV;
+ if (type == TYPE_CMD) {
+ if (driver->feature[peripheral].untag_header)
+ if (!fwd_info->diagid_root ||
+ (!driver->diag_id_sent[peripheral])) {
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "diag: diag_id is not assigned yet\n");
+ return 0;
+ }
+ }
+
if (!(fwd_info->p_ops && fwd_info->p_ops->write && fwd_info->ctxt))
return -EIO;
@@ -948,17 +1294,45 @@
void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt)
{
+ int i = 0;
struct diagfwd_info *fwd_info = NULL;
if (peripheral >= NUM_PERIPHERALS || type >= NUM_TYPES)
return;
fwd_info = &peripheral_info[type][peripheral];
- if (ctxt == 1 && fwd_info->buf_1)
+ if (!fwd_info)
+ return;
+
+ if (ctxt == 1 && fwd_info->buf_1) {
+ /* Buffer 1 for core PD is freed */
atomic_set(&fwd_info->buf_1->in_busy, 0);
- else if (ctxt == 2 && fwd_info->buf_2)
+ fwd_info->cpd_len_1 = 0;
+ } else if (ctxt == 2 && fwd_info->buf_2) {
+ /* Buffer 2 for core PD is freed */
atomic_set(&fwd_info->buf_2->in_busy, 0);
- else
+ fwd_info->cpd_len_2 = 0;
+ } else if (ctxt >= 3 && (ctxt % 2)) {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
+ if (fwd_info->buf_upd[i][0]) {
+ /* Buffer 1 for ith user PD is freed */
+ atomic_set(&fwd_info->buf_upd[i][0]->in_busy, 0);
+ fwd_info->upd_len[i][0] = 0;
+ }
+ if (!fwd_info->cpd_len_1)
+ atomic_set(&fwd_info->buf_1->in_busy, 0);
+ }
+ } else if (ctxt >= 4 && !(ctxt % 2)) {
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
+ if (fwd_info->buf_upd[i][1]) {
+ /* Buffer 2 for ith user PD is freed */
+ atomic_set(&fwd_info->buf_upd[i][0]->in_busy, 0);
+ fwd_info->upd_len[i][1] = 0;
+ }
+ if (!fwd_info->cpd_len_2)
+ atomic_set(&fwd_info->buf_2->in_busy, 0);
+ }
+ } else
pr_err("diag: In %s, invalid ctxt %d\n", __func__, ctxt);
diagfwd_queue_read(fwd_info);
@@ -1087,8 +1461,65 @@
fwd_info->p_ops->queue_read(fwd_info->ctxt);
}
+static int diagfwd_buffers_allocate(struct diagfwd_info *fwd_info)
+{
+ int i, j;
+
+ for (i = 0; ((fwd_info->num_pd > 1) &&
+ (i <= (fwd_info->num_pd - 2))); i++) {
+ for (j = 0; j < NUM_WRITE_BUFFERS; j++) {
+ if (!fwd_info->buf_upd[i][j]) {
+ fwd_info->buf_upd[i][j] =
+ kzalloc(sizeof(struct diagfwd_buf_t),
+ GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR(fwd_info->buf_upd[i][j]))
+ return -ENOMEM;
+ kmemleak_not_leak(fwd_info->buf_upd[i][j]);
+ }
+
+ if (fwd_info->buf_upd[i][j] &&
+ !fwd_info->buf_upd[i][j]->data) {
+ fwd_info->buf_upd[i][j]->data =
+ kzalloc(PERIPHERAL_BUF_SZ +
+ APF_DIAG_PADDING,
+ GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR(
+ fwd_info->buf_upd[i][j]->data))
+ return -ENOMEM;
+ fwd_info->buf_upd[i][j]->len =
+ PERIPHERAL_BUF_SZ;
+ kmemleak_not_leak(
+ fwd_info->buf_upd[i][j]->data);
+ fwd_info->buf_upd[i][j]->ctxt =
+ SET_BUF_CTXT(fwd_info->peripheral,
+ fwd_info->type, ((2 * i) + (j + 3)));
+ }
+
+ if (driver->supports_apps_hdlc_encoding) {
+ if (fwd_info->buf_upd[i][j] &&
+ !fwd_info->buf_upd[i][j]->data_raw) {
+ fwd_info->buf_upd[i][j]->data_raw =
+ kzalloc(PERIPHERAL_BUF_SZ +
+ APF_DIAG_PADDING,
+ GFP_KERNEL);
+ if (ZERO_OR_NULL_PTR(
+ fwd_info->buf_upd[i][j]->data_raw))
+ return -ENOMEM;
+ fwd_info->buf_upd[i][j]->len_raw =
+ PERIPHERAL_BUF_SZ;
+ kmemleak_not_leak(
+ fwd_info->buf_upd[i][j]->data_raw);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
void diagfwd_buffers_init(struct diagfwd_info *fwd_info)
{
+ int ret = 0;
+ unsigned char *temp_char_buf;
if (!fwd_info)
return;
@@ -1100,18 +1531,20 @@
}
mutex_lock(&fwd_info->buf_mutex);
+
if (!fwd_info->buf_1) {
fwd_info->buf_1 = kzalloc(sizeof(struct diagfwd_buf_t),
GFP_KERNEL);
- if (!fwd_info->buf_1)
+ if (ZERO_OR_NULL_PTR(fwd_info->buf_1))
goto err;
kmemleak_not_leak(fwd_info->buf_1);
}
+
if (!fwd_info->buf_1->data) {
fwd_info->buf_1->data = kzalloc(PERIPHERAL_BUF_SZ +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!fwd_info->buf_1->data)
+ if (ZERO_OR_NULL_PTR(fwd_info->buf_1->data))
goto err;
fwd_info->buf_1->len = PERIPHERAL_BUF_SZ;
kmemleak_not_leak(fwd_info->buf_1->data);
@@ -1123,7 +1556,7 @@
if (!fwd_info->buf_2) {
fwd_info->buf_2 = kzalloc(sizeof(struct diagfwd_buf_t),
GFP_KERNEL);
- if (!fwd_info->buf_2)
+ if (ZERO_OR_NULL_PTR(fwd_info->buf_2))
goto err;
kmemleak_not_leak(fwd_info->buf_2);
}
@@ -1132,7 +1565,7 @@
fwd_info->buf_2->data = kzalloc(PERIPHERAL_BUF_SZ +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!fwd_info->buf_2->data)
+ if (ZERO_OR_NULL_PTR(fwd_info->buf_2->data))
goto err;
fwd_info->buf_2->len = PERIPHERAL_BUF_SZ;
kmemleak_not_leak(fwd_info->buf_2->data);
@@ -1141,6 +1574,11 @@
fwd_info->type, 2);
}
+ if (driver->feature[fwd_info->peripheral].untag_header)
+ ret = diagfwd_buffers_allocate(fwd_info);
+ if (ret)
+ goto err;
+
if (driver->supports_apps_hdlc_encoding) {
/* In support of hdlc encoding */
if (!fwd_info->buf_1->data_raw) {
@@ -1148,34 +1586,44 @@
kzalloc(PERIPHERAL_BUF_SZ +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!fwd_info->buf_1->data_raw)
+ temp_char_buf =
+ fwd_info->buf_1->data_raw;
+ if (ZERO_OR_NULL_PTR(temp_char_buf))
goto err;
- fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ;
- kmemleak_not_leak(fwd_info->buf_1->data_raw);
+ fwd_info->buf_1->len_raw =
+ PERIPHERAL_BUF_SZ;
+ kmemleak_not_leak(temp_char_buf);
}
+
if (!fwd_info->buf_2->data_raw) {
fwd_info->buf_2->data_raw =
kzalloc(PERIPHERAL_BUF_SZ +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!fwd_info->buf_2->data_raw)
+ temp_char_buf =
+ fwd_info->buf_2->data_raw;
+ if (ZERO_OR_NULL_PTR(temp_char_buf))
goto err;
- fwd_info->buf_2->len_raw = PERIPHERAL_BUF_SZ;
- kmemleak_not_leak(fwd_info->buf_2->data_raw);
+ fwd_info->buf_2->len_raw =
+ PERIPHERAL_BUF_SZ;
+ kmemleak_not_leak(temp_char_buf);
}
}
}
- if (fwd_info->type == TYPE_CMD && driver->supports_apps_hdlc_encoding) {
+ if (fwd_info->type == TYPE_CMD &&
+ driver->supports_apps_hdlc_encoding) {
/* In support of hdlc encoding */
if (!fwd_info->buf_1->data_raw) {
fwd_info->buf_1->data_raw = kzalloc(PERIPHERAL_BUF_SZ +
APF_DIAG_PADDING,
GFP_KERNEL);
- if (!fwd_info->buf_1->data_raw)
+ temp_char_buf =
+ fwd_info->buf_1->data_raw;
+ if (ZERO_OR_NULL_PTR(temp_char_buf))
goto err;
fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ;
- kmemleak_not_leak(fwd_info->buf_1->data_raw);
+ kmemleak_not_leak(temp_char_buf);
}
}
@@ -1185,10 +1633,12 @@
err:
mutex_unlock(&fwd_info->buf_mutex);
diagfwd_buffers_exit(fwd_info);
+ return;
}
static void diagfwd_buffers_exit(struct diagfwd_info *fwd_info)
{
+ int i = 0;
if (!fwd_info)
return;
@@ -1210,6 +1660,24 @@
kfree(fwd_info->buf_2);
fwd_info->buf_2 = NULL;
}
+ for (i = 0; i <= (fwd_info->num_pd - 2); i++) {
+ if (fwd_info->buf_upd[i][0]) {
+ kfree(fwd_info->buf_upd[i][0]->data);
+ fwd_info->buf_upd[i][0]->data = NULL;
+ kfree(fwd_info->buf_upd[i][0]->data_raw);
+ fwd_info->buf_upd[i][0]->data_raw = NULL;
+ kfree(fwd_info->buf_upd[i][0]);
+ fwd_info->buf_upd[i][0] = NULL;
+ }
+ if (fwd_info->buf_upd[i][1]) {
+ kfree(fwd_info->buf_upd[i][1]->data);
+ fwd_info->buf_upd[i][1]->data = NULL;
+ kfree(fwd_info->buf_upd[i][1]->data_raw);
+ fwd_info->buf_upd[i][1]->data_raw = NULL;
+ kfree(fwd_info->buf_upd[i][1]);
+ fwd_info->buf_upd[i][1] = NULL;
+ }
+ }
mutex_unlock(&fwd_info->buf_mutex);
}
diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h
index 5884a12..b16670e 100644
--- a/drivers/char/diag/diagfwd_peripheral.h
+++ b/drivers/char/diag/diagfwd_peripheral.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 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
@@ -68,6 +68,12 @@
uint8_t transport;
uint8_t inited;
uint8_t ch_open;
+ uint8_t num_pd;
+ uint8_t diagid_root;
+ uint8_t diagid_user[MAX_PERIPHERAL_UPD];
+ int cpd_len_1;
+ int cpd_len_2;
+ int upd_len[MAX_PERIPHERAL_UPD][2];
atomic_t opened;
unsigned long read_bytes;
unsigned long write_bytes;
@@ -77,6 +83,7 @@
void *ctxt;
struct diagfwd_buf_t *buf_1;
struct diagfwd_buf_t *buf_2;
+ struct diagfwd_buf_t *buf_upd[MAX_PERIPHERAL_UPD][2];
struct diagfwd_buf_t *buf_ptr[NUM_WRITE_BUFFERS];
struct diag_peripheral_ops *p_ops;
struct diag_channel_ops *c_ops;
@@ -94,6 +101,9 @@
void diagfwd_late_open(struct diagfwd_info *fwd_info);
void diagfwd_close(uint8_t peripheral, uint8_t type);
+
+int diag_md_get_peripheral(int ctxt);
+
int diagfwd_register(uint8_t transport, uint8_t peripheral, uint8_t type,
void *ctxt, struct diag_peripheral_ops *ops,
struct diagfwd_info **fwd_ctxt);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 08d1dd5..ee737ef 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2044,8 +2044,8 @@
struct batched_entropy {
union {
- unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)];
- unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)];
+ u64 entropy_u64[CHACHA20_BLOCK_SIZE / sizeof(u64)];
+ u32 entropy_u32[CHACHA20_BLOCK_SIZE / sizeof(u32)];
};
unsigned int position;
};
@@ -2055,52 +2055,51 @@
* number is either as good as RDRAND or as good as /dev/urandom, with the
* goal of being quite fast and not depleting entropy.
*/
-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long);
-unsigned long get_random_long(void)
+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
+u64 get_random_u64(void)
{
- unsigned long ret;
+ u64 ret;
struct batched_entropy *batch;
- if (arch_get_random_long(&ret))
+#if BITS_PER_LONG == 64
+ if (arch_get_random_long((unsigned long *)&ret))
return ret;
+#else
+ if (arch_get_random_long((unsigned long *)&ret) &&
+ arch_get_random_long((unsigned long *)&ret + 1))
+ return ret;
+#endif
- batch = &get_cpu_var(batched_entropy_long);
- if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) {
- extract_crng((u8 *)batch->entropy_long);
+ batch = &get_cpu_var(batched_entropy_u64);
+ if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
+ extract_crng((u8 *)batch->entropy_u64);
batch->position = 0;
}
- ret = batch->entropy_long[batch->position++];
- put_cpu_var(batched_entropy_long);
+ ret = batch->entropy_u64[batch->position++];
+ put_cpu_var(batched_entropy_u64);
return ret;
}
-EXPORT_SYMBOL(get_random_long);
+EXPORT_SYMBOL(get_random_u64);
-#if BITS_PER_LONG == 32
-unsigned int get_random_int(void)
+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
+u32 get_random_u32(void)
{
- return get_random_long();
-}
-#else
-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int);
-unsigned int get_random_int(void)
-{
- unsigned int ret;
+ u32 ret;
struct batched_entropy *batch;
if (arch_get_random_int(&ret))
return ret;
- batch = &get_cpu_var(batched_entropy_int);
- if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) {
- extract_crng((u8 *)batch->entropy_int);
+ batch = &get_cpu_var(batched_entropy_u32);
+ if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
+ extract_crng((u8 *)batch->entropy_u32);
batch->position = 0;
}
- ret = batch->entropy_int[batch->position++];
- put_cpu_var(batched_entropy_int);
+ ret = batch->entropy_u32[batch->position++];
+ put_cpu_var(batched_entropy_u32);
return ret;
}
-#endif
-EXPORT_SYMBOL(get_random_int);
+EXPORT_SYMBOL(get_random_u32);
/**
* randomize_page - Generate a random, page aligned address
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7cdf45b..5638333 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2631,7 +2631,46 @@
pr_info(fmt, ##__VA_ARGS__); \
} while (0)
-int clock_debug_print_clock(struct clk_core *c, struct seq_file *s)
+/*
+ * clock_debug_print_enabled_debug_suspend() - Print names of enabled clocks
+ * during suspend.
+ */
+static void clock_debug_print_enabled_debug_suspend(struct seq_file *s)
+{
+ struct clk_core *core;
+ int cnt = 0;
+
+ if (!mutex_trylock(&clk_debug_lock))
+ return;
+
+ clock_debug_output(s, 0, "Enabled clocks:\n");
+
+ hlist_for_each_entry(core, &clk_debug_list, debug_node) {
+ if (!core || !core->prepare_count)
+ continue;
+
+ if (core->vdd_class)
+ clock_debug_output(s, 0, " %s:%u:%u [%ld, %d]",
+ core->name, core->prepare_count,
+ core->enable_count, core->rate,
+ clk_find_vdd_level(core, core->rate));
+
+ else
+ clock_debug_output(s, 0, " %s:%u:%u [%ld]",
+ core->name, core->prepare_count,
+ core->enable_count, core->rate);
+ cnt++;
+ }
+
+ mutex_unlock(&clk_debug_lock);
+
+ if (cnt)
+ clock_debug_output(s, 0, "Enabled clock count: %d\n", cnt);
+ else
+ clock_debug_output(s, 0, "No clocks enabled.\n");
+}
+
+static int clock_debug_print_clock(struct clk_core *c, struct seq_file *s)
{
char *start = "";
struct clk *clk;
@@ -3005,7 +3044,7 @@
if (likely(!debug_suspend))
return;
- clock_debug_print_enabled_clocks(NULL);
+ clock_debug_print_enabled_debug_suspend(NULL);
}
EXPORT_SYMBOL_GPL(clock_debug_print_enabled);
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index f0db049..b52aa25 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -10,6 +10,7 @@
*/
struct clk_hw;
+struct clk_core;
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c
index 4158e65..f93aba1 100644
--- a/drivers/clk/qcom/clk-cpu-osm.c
+++ b/drivers/clk/qcom/clk-cpu-osm.c
@@ -66,6 +66,7 @@
#define PERFCL_EFUSE_MASK 0x7
#define ENABLE_REG 0x0
+#define ENABLE_OSM BIT(0)
#define FREQ_REG 0x110
#define VOLT_REG 0x114
#define OVERRIDE_REG 0x118
@@ -2629,7 +2630,7 @@
}
/* Check if OSM has been enabled already by trustzone. */
- if (readl_relaxed(l3_clk.vbases[OSM_BASE] + ENABLE_REG)) {
+ if (readl_relaxed(l3_clk.vbases[OSM_BASE] + ENABLE_REG) & ENABLE_OSM) {
dev_info(&pdev->dev, "OSM has been initialized and enabled by TZ software\n");
osm_tz_enabled = true;
}
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 66bf435..17b2403 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -873,17 +873,6 @@
{ }
};
-static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src_sdm845_v2[] = {
- F(400000, P_BI_TCXO, 12, 1, 4),
- F(9600000, P_BI_TCXO, 2, 0, 0),
- F(19200000, P_BI_TCXO, 1, 0, 0),
- F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
- F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
- F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
- F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
- { }
-};
-
static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
.cmd_rcgr = 0x1400c,
.mnd_width = 8,
@@ -4012,9 +4001,6 @@
50000000;
gcc_qupv3_wrap1_s7_clk_src.clkr.hw.init->rate_max[VDD_CX_NOMINAL] =
128000000;
- gcc_sdcc2_apps_clk_src.freq_tbl = ftbl_gcc_sdcc2_apps_clk_src_sdm845_v2;
- gcc_sdcc2_apps_clk_src.clkr.hw.init->rate_max[VDD_CX_LOW_L1] =
- 200000000;
gcc_ufs_card_axi_clk_src.freq_tbl =
ftbl_gcc_ufs_card_axi_clk_src_sdm845_v2;
gcc_ufs_card_axi_clk_src.clkr.hw.init->rate_max[VDD_CX_HIGH] =
diff --git a/drivers/cpufreq/cpu-boost.c b/drivers/cpufreq/cpu-boost.c
index 07603fe..e67f12b 100644
--- a/drivers/cpufreq/cpu-boost.c
+++ b/drivers/cpufreq/cpu-boost.c
@@ -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
@@ -39,8 +39,8 @@
static unsigned int input_boost_ms = 40;
module_param(input_boost_ms, uint, 0644);
-static bool sched_boost_on_input;
-module_param(sched_boost_on_input, bool, 0644);
+static unsigned int sched_boost_on_input;
+module_param(sched_boost_on_input, uint, 0644);
static bool sched_boost_active;
@@ -209,8 +209,8 @@
update_policy_online();
/* Enable scheduler boost to migrate tasks to big cluster */
- if (sched_boost_on_input) {
- ret = sched_set_boost(1);
+ if (sched_boost_on_input > 0) {
+ ret = sched_set_boost(sched_boost_on_input);
if (ret)
pr_err("cpu-boost: HMP boost enable failed\n");
else
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 8286818..5633a8f 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -55,6 +55,7 @@
#define SCLK_HZ (32768)
#define PSCI_POWER_STATE(reset) (reset << 30)
#define PSCI_AFFINITY_LEVEL(lvl) ((lvl & 0x3) << 24)
+#define BIAS_HYST (bias_hyst * NSEC_PER_MSEC)
enum {
MSM_LPM_LVL_DBG_SUSPEND_LIMITS = BIT(0),
@@ -93,6 +94,9 @@
static uint32_t tmr_add = 100;
module_param_named(tmr_add, tmr_add, uint, 0664);
+static uint32_t bias_hyst;
+module_param_named(bias_hyst, bias_hyst, uint, 0664);
+
struct lpm_history {
uint32_t resi[MAXSAMPLES];
int mode[MAXSAMPLES];
@@ -572,6 +576,17 @@
static void update_history(struct cpuidle_device *dev, int idx);
+static inline bool is_cpu_biased(int cpu)
+{
+ u64 now = sched_clock();
+ u64 last = sched_get_cpu_last_busy_time(cpu);
+
+ if (!last)
+ return false;
+
+ return (now - last) < BIAS_HYST;
+}
+
static int cpu_power_select(struct cpuidle_device *dev,
struct lpm_cpu *cpu)
{
@@ -596,6 +611,11 @@
next_event_us = (uint32_t)(ktime_to_us(get_next_event_time(dev->cpu)));
+ if (is_cpu_biased(dev->cpu)) {
+ best_level = 0;
+ goto done_select;
+ }
+
for (i = 0; i < cpu->nlevels; i++) {
struct lpm_cpu_level *level = &cpu->levels[i];
struct power_params *pwr_params = &level->pwr;
@@ -674,6 +694,7 @@
histtimer_start(htime);
}
+done_select:
trace_cpu_power_select(best_level, sleep_us, latency_us, next_event_us);
trace_cpu_pred_select(idx_restrict_time ? 2 : (predicted ? 1 : 0),
diff --git a/drivers/edac/qcom_llcc_edac.c b/drivers/edac/qcom_llcc_edac.c
index a8ec359..4b89cbf 100644
--- a/drivers/edac/qcom_llcc_edac.c
+++ b/drivers/edac/qcom_llcc_edac.c
@@ -291,7 +291,7 @@
qcom_llcc_clear_errors(err_type, drv);
- errors[err_type].func(edev_ctl, 0, 0, errors[err_type].msg);
+ errors[err_type].func(edev_ctl, 0, bank, errors[err_type].msg);
}
static void qcom_llcc_check_cache_errors
@@ -353,10 +353,26 @@
struct erp_drvdata *drv;
struct edac_device_ctl_info *edev_ctl;
struct device *dev = &pdev->dev;
+ u32 num_banks;
+ struct regmap *llcc_map = NULL;
+
+ llcc_map = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(llcc_map)) {
+ dev_err(dev, "no regmap for syscon llcc parent\n");
+ return -ENOMEM;
+ }
+
+ /* Find the number of LLC banks supported */
+ regmap_read(llcc_map, LLCC_COMMON_STATUS0,
+ &num_banks);
+
+ num_banks &= LLCC_LB_CNT_MASK;
+ num_banks >>= LLCC_LB_CNT_SHIFT;
/* Allocate edac control info */
edev_ctl = edac_device_alloc_ctl_info(sizeof(*drv), "qcom-llcc", 1,
- NULL, 0, 1, NULL, 0, edac_device_alloc_index());
+ "bank", num_banks, 1, NULL, 0,
+ edac_device_alloc_index());
if (!edev_ctl)
return -ENOMEM;
@@ -374,64 +390,59 @@
edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
drv = edev_ctl->pvt_info;
+ drv->num_banks = num_banks;
+ drv->llcc_map = llcc_map;
- drv->llcc_map = syscon_node_to_regmap(dev->parent->of_node);
- if (IS_ERR(drv->llcc_map)) {
- dev_err(dev, "no regmap for syscon llcc parent\n");
- rc = -ENOMEM;
- goto out;
- }
+ rc = edac_device_add_device(edev_ctl);
+ if (rc)
+ goto out_mem;
if (interrupt_mode) {
drv->ecc_irq = platform_get_irq_byname(pdev, "ecc_irq");
if (!drv->ecc_irq) {
rc = -ENODEV;
- goto out;
+ goto out_dev;
}
rc = devm_request_irq(dev, drv->ecc_irq, llcc_ecc_irq_handler,
IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
if (rc) {
dev_err(dev, "failed to request ecc irq\n");
- goto out;
+ goto out_dev;
}
}
- /* Find the number of LLC banks supported */
- regmap_read(drv->llcc_map, LLCC_COMMON_STATUS0,
- &drv->num_banks);
-
- drv->num_banks &= LLCC_LB_CNT_MASK;
- drv->num_banks >>= LLCC_LB_CNT_SHIFT;
-
drv->llcc_banks = devm_kzalloc(&pdev->dev,
sizeof(u32) * drv->num_banks, GFP_KERNEL);
if (!drv->llcc_banks) {
dev_err(dev, "Cannot allocate memory for llcc_banks\n");
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_dev;
}
rc = of_property_read_u32_array(dev->parent->of_node,
"qcom,llcc-banks-off", drv->llcc_banks, drv->num_banks);
if (rc) {
dev_err(dev, "Cannot read llcc-banks-off property\n");
- return -EINVAL;
+ goto out_dev;
}
rc = of_property_read_u32(dev->parent->of_node,
"qcom,llcc-broadcast-off", &drv->b_off);
if (rc) {
dev_err(dev, "Cannot read llcc-broadcast-off property\n");
- return -EINVAL;
+ goto out_dev;
}
platform_set_drvdata(pdev, edev_ctl);
- rc = edac_device_add_device(edev_ctl);
-out:
- if (rc)
- edac_device_free_ctl_info(edev_ctl);
+ return 0;
+
+out_dev:
+ edac_device_del_device(edev_ctl->dev);
+out_mem:
+ edac_device_free_ctl_info(edev_ctl);
return rc;
}
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 5e23e2d..f9a1e98 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -17,6 +17,7 @@
cflags-$(CONFIG_EFI_ARMSTUB) += -I$(srctree)/scripts/dtc/libfdt
KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \
+ -D__NO_FORTIFY \
$(call cc-option,-ffreestanding) \
$(call cc-option,-fno-stack-protector)
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 67c6b2d..9106027 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -28,11 +28,13 @@
struct device *dev;
struct dp_aux dp_aux;
struct dp_catalog_aux *catalog;
+ struct dp_aux_cfg *cfg;
struct mutex mutex;
struct completion comp;
u32 aux_error_num;
+ u32 retry_cnt;
bool cmd_busy;
bool native;
bool read;
@@ -127,7 +129,7 @@
timeout = wait_for_completion_timeout(&aux->comp, aux_timeout_ms);
if (!timeout) {
- pr_err("aux write timeout\n");
+ pr_err("aux %s timeout\n", (aux->read ? "read" : "write"));
return -ETIMEDOUT;
}
@@ -232,6 +234,22 @@
dp_aux_i2c_handler(aux);
}
+static void dp_aux_reconfig(struct dp_aux *dp_aux)
+{
+ struct dp_aux_private *aux;
+
+ if (!dp_aux) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+
+ aux->catalog->update_aux_cfg(aux->catalog,
+ aux->cfg, PHY_AUX_CFG1);
+ aux->catalog->reset(aux->catalog);
+}
+
/*
* This function does the real job to process an AUX transaction.
* It will call aux_reset() function to reset the AUX channel,
@@ -243,6 +261,7 @@
ssize_t ret;
int const aux_cmd_native_max = 16;
int const aux_cmd_i2c_max = 128;
+ int const retry_count = 5;
struct dp_aux_private *aux = container_of(drm_aux,
struct dp_aux_private, drm_aux);
@@ -270,8 +289,14 @@
}
ret = dp_aux_cmd_fifo_tx(aux, msg);
- if (ret < 0) {
- aux->catalog->reset(aux->catalog); /* reset aux */
+ if ((ret < 0) && aux->native) {
+ aux->retry_cnt++;
+ if (!(aux->retry_cnt % retry_count))
+ aux->catalog->update_aux_cfg(aux->catalog,
+ aux->cfg, PHY_AUX_CFG1);
+ aux->catalog->reset(aux->catalog);
+ goto unlock_exit;
+ } else if (ret < 0) {
goto unlock_exit;
}
@@ -289,6 +314,7 @@
/* Return requested size for success or retry */
ret = msg->size;
+ aux->retry_cnt = 0;
unlock_exit:
aux->cmd_busy = false;
@@ -296,11 +322,19 @@
return ret;
}
-static void dp_aux_init(struct dp_aux *dp_aux, u32 *aux_cfg)
+static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
+{
+ int i = 0;
+
+ for (i = 0; i < PHY_AUX_CFG_MAX; i++)
+ aux_cfg[i].current_index = 0;
+}
+
+static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg)
{
struct dp_aux_private *aux;
- if (!dp_aux) {
+ if (!dp_aux || !aux_cfg) {
pr_err("invalid input\n");
return;
}
@@ -309,6 +343,8 @@
aux->catalog->reset(aux->catalog);
aux->catalog->enable(aux->catalog, true);
+ aux->retry_cnt = 0;
+ dp_aux_reset_phy_config_indices(aux_cfg);
aux->catalog->setup(aux->catalog, aux_cfg);
}
@@ -365,13 +401,14 @@
drm_dp_aux_unregister(&aux->drm_aux);
}
-struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog)
+struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
+ struct dp_aux_cfg *aux_cfg)
{
int rc = 0;
struct dp_aux_private *aux;
struct dp_aux *dp_aux;
- if (!catalog) {
+ if (!catalog || !aux_cfg) {
pr_err("invalid input\n");
rc = -ENODEV;
goto error;
@@ -389,13 +426,16 @@
aux->dev = dev;
aux->catalog = catalog;
+ aux->cfg = aux_cfg;
dp_aux = &aux->dp_aux;
+ aux->retry_cnt = 0;
dp_aux->isr = dp_aux_isr;
dp_aux->init = dp_aux_init;
dp_aux->deinit = dp_aux_deinit;
dp_aux->drm_aux_register = dp_aux_register;
dp_aux->drm_aux_deregister = dp_aux_deregister;
+ dp_aux->reconfig = dp_aux_reconfig;
return dp_aux;
error:
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.h b/drivers/gpu/drm/msm/dp/dp_aux.h
index f08c12b..5d96fd9 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.h
+++ b/drivers/gpu/drm/msm/dp/dp_aux.h
@@ -32,11 +32,13 @@
int (*drm_aux_register)(struct dp_aux *aux);
void (*drm_aux_deregister)(struct dp_aux *aux);
void (*isr)(struct dp_aux *aux);
- void (*init)(struct dp_aux *aux, u32 *aux_cfg);
+ void (*init)(struct dp_aux *aux, struct dp_aux_cfg *aux_cfg);
void (*deinit)(struct dp_aux *aux);
+ void (*reconfig)(struct dp_aux *aux);
};
-struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog);
+struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
+ struct dp_aux_cfg *aux_cfg);
void dp_aux_put(struct dp_aux *aux);
#endif /*__DP_AUX_H_*/
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 914c408..95a7dc4 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -175,11 +175,37 @@
dp_write(base + DP_AUX_CTRL, aux_ctrl);
}
-static void dp_catalog_aux_setup(struct dp_catalog_aux *aux, u32 *aux_cfg)
+static void dp_catalog_aux_update_cfg(struct dp_catalog_aux *aux,
+ struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type)
{
struct dp_catalog_private *catalog;
+ u32 new_index = 0, current_index = 0;
- if (!aux || !aux_cfg) {
+ if (!aux || !cfg || (type >= PHY_AUX_CFG_MAX)) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ dp_catalog_get_priv(aux);
+
+ current_index = cfg[type].current_index;
+ new_index = (current_index + 1) % cfg[type].cfg_cnt;
+ pr_debug("Updating %s from 0x%08x to 0x%08x\n",
+ dp_phy_aux_config_type_to_string(type),
+ cfg[type].lut[current_index], cfg[type].lut[new_index]);
+
+ dp_write(catalog->io->phy_io.base + cfg[type].offset,
+ cfg[type].lut[new_index]);
+ cfg[type].current_index = new_index;
+}
+
+static void dp_catalog_aux_setup(struct dp_catalog_aux *aux,
+ struct dp_aux_cfg *cfg)
+{
+ struct dp_catalog_private *catalog;
+ int i = 0;
+
+ if (!aux || !cfg) {
pr_err("invalid input\n");
return;
}
@@ -195,16 +221,13 @@
QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f);
/* DP AUX CFG register programming */
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG0, aux_cfg[0]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG1, aux_cfg[1]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG2, aux_cfg[2]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG3, aux_cfg[3]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG4, aux_cfg[4]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG5, aux_cfg[5]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG6, aux_cfg[6]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG7, aux_cfg[7]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG8, aux_cfg[8]);
- dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG9, aux_cfg[9]);
+ for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
+ pr_debug("%s: offset=0x%08x, value=0x%08x\n",
+ dp_phy_aux_config_type_to_string(i),
+ cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
+ dp_write(catalog->io->phy_io.base + cfg[i].offset,
+ cfg[i].lut[cfg[i].current_index]);
+ }
dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK, 0x1F);
}
@@ -723,6 +746,7 @@
.write_data = dp_catalog_aux_write_data,
.write_trans = dp_catalog_aux_write_trans,
.reset = dp_catalog_aux_reset,
+ .update_aux_cfg = dp_catalog_aux_update_cfg,
.enable = dp_catalog_aux_enable,
.setup = dp_catalog_aux_setup,
.get_irq = dp_catalog_aux_get_irq,
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 2bd6bfd..7fde025 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -43,7 +43,10 @@
int (*write_trans)(struct dp_catalog_aux *aux);
void (*reset)(struct dp_catalog_aux *aux);
void (*enable)(struct dp_catalog_aux *aux, bool enable);
- void (*setup)(struct dp_catalog_aux *aux, u32 *aux_cfg);
+ void (*update_aux_cfg)(struct dp_catalog_aux *aux,
+ struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type);
+ void (*setup)(struct dp_catalog_aux *aux,
+ struct dp_aux_cfg *aux_cfg);
void (*get_irq)(struct dp_catalog_aux *aux, bool cmd_busy);
};
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e191c1a..b4dafe4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -502,13 +502,10 @@
int rc = 0;
u32 max_pclk_from_edid = 0;
- rc = dp->panel->read_dpcd(dp->panel);
+ rc = dp->panel->read_sink_caps(dp->panel, dp->dp_display.connector);
if (rc)
return rc;
- sde_get_edid(dp->dp_display.connector, &dp->aux->drm_aux->ddc,
- (void **)&dp->panel->edid_ctrl);
-
max_pclk_from_edid = dp->panel->get_max_pclk(dp->panel);
dp->dp_display.max_pclk_khz = min(max_pclk_from_edid,
@@ -729,7 +726,7 @@
goto err;
}
- dp->aux = dp_aux_get(dev, &dp->catalog->aux);
+ dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser->aux_cfg);
if (IS_ERR(dp->aux)) {
rc = PTR_ERR(dp->aux);
pr_err("failed to initialize aux, rc = %d\n", rc);
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 91aafdd..c388048 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -296,24 +296,30 @@
return 0;
}
-int dp_connector_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology, u32 max_mixer_width)
+int dp_connector_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info, u32 max_mixer_width)
{
const u32 dual_lm = 2;
const u32 single_lm = 1;
const u32 single_intf = 1;
const u32 no_enc = 0;
+ struct msm_display_topology *topology;
- if (!drm_mode || !topology || !max_mixer_width) {
+ if (!drm_mode || !mode_info || !max_mixer_width) {
pr_err("invalid params\n");
return -EINVAL;
}
+ topology = &mode_info->topology;
topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ?
dual_lm : single_lm;
topology->num_enc = no_enc;
topology->num_intf = single_intf;
+ mode_info->frame_rate = drm_mode->vrefresh;
+ mode_info->vtotal = drm_mode->vtotal;
+ mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
+
return 0;
}
@@ -331,7 +337,6 @@
info->num_of_h_tiles = 1;
info->h_tile_instance[0] = 0;
info->is_connected = display->is_connected;
- info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
info->capabilities = MSM_DISPLAY_CAP_VID_MODE | MSM_DISPLAY_CAP_EDID |
MSM_DISPLAY_CAP_HOT_PLUG;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index bef3758..5918df1 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -74,14 +74,14 @@
void *display);
/**
- * dp_connector_get_topology - retrieve current topology for the mode selected
+ * dp_connector_get_mode_info - retrieve information of the mode selected
* @drm_mode: Display mode set for the display
- * @topology: Out parameter. Topology for the mode.
+ * @mode_info: Out parameter. Information of the mode
* @max_mixer_width: max width supported by HW layer mixer
* Returns: zero on success
*/
-int dp_connector_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology,
+int dp_connector_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info,
u32 max_mixer_width);
int dp_connector_get_info(struct msm_display_info *info, void *display);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index d4e33e9..2e21033 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -28,6 +28,7 @@
struct dp_aux *aux;
struct dp_catalog_panel *catalog;
bool lane_switch_supported;
+ bool aux_cfg_update_done;
};
static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
@@ -80,6 +81,71 @@
return rc;
}
+
+static int dp_panel_read_edid(struct dp_panel *dp_panel,
+ struct drm_connector *connector)
+{
+ int retry_cnt = 0;
+ const int max_retry = 10;
+ struct dp_panel_private *panel;
+
+ if (!dp_panel) {
+ pr_err("invalid input\n");
+ return -EINVAL;
+ }
+
+ panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+ do {
+ sde_get_edid(connector, &panel->aux->drm_aux->ddc,
+ (void **)&dp_panel->edid_ctrl);
+ if (!dp_panel->edid_ctrl->edid) {
+ pr_err("EDID read failed\n");
+ retry_cnt++;
+ panel->aux->reconfig(panel->aux);
+ panel->aux_cfg_update_done = true;
+ } else {
+ return 0;
+ }
+ } while (retry_cnt < max_retry);
+
+ return -EINVAL;
+}
+
+static int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
+ struct drm_connector *connector)
+{
+ int rc = 0;
+ struct dp_panel_private *panel;
+
+ if (!dp_panel || !connector) {
+ pr_err("invalid input\n");
+ return -EINVAL;
+ }
+
+ panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+ rc = dp_panel_read_dpcd(dp_panel);
+ if (rc) {
+ pr_err("panel dpcd read failed\n");
+ return rc;
+ }
+
+ rc = dp_panel_read_edid(dp_panel, connector);
+ if (rc) {
+ pr_err("panel edid read failed\n");
+ return rc;
+ }
+
+ if (panel->aux_cfg_update_done) {
+ pr_debug("read DPCD with updated AUX config\n");
+ dp_panel_read_dpcd(dp_panel);
+ panel->aux_cfg_update_done = false;
+ }
+
+ return 0;
+}
+
static u32 dp_panel_get_max_pclk(struct dp_panel *dp_panel)
{
struct drm_dp_link *link_info;
@@ -290,12 +356,13 @@
panel->catalog = catalog;
dp_panel = &panel->dp_panel;
+ panel->aux_cfg_update_done = false;
dp_panel->sde_edid_register = dp_panel_edid_register;
dp_panel->sde_edid_deregister = dp_panel_edid_deregister;
dp_panel->init_info = dp_panel_init_panel_info;
dp_panel->timing_cfg = dp_panel_timing_cfg;
- dp_panel->read_dpcd = dp_panel_read_dpcd;
+ dp_panel->read_sink_caps = dp_panel_read_sink_caps;
dp_panel->get_min_req_link_rate = dp_panel_get_min_req_link_rate;
dp_panel->get_max_pclk = dp_panel_get_max_pclk;
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 6cca0f1..ab9a451 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -43,6 +43,7 @@
struct drm_dp_link link_info;
struct sde_edid_ctrl *edid_ctrl;
+ struct drm_connector *connector;
struct dp_panel_info pinfo;
u32 vic;
@@ -52,7 +53,8 @@
void (*sde_edid_deregister)(struct dp_panel *dp_panel);
int (*init_info)(struct dp_panel *dp_panel);
int (*timing_cfg)(struct dp_panel *dp_panel);
- int (*read_dpcd)(struct dp_panel *dp_panel);
+ int (*read_sink_caps)(struct dp_panel *dp_panel,
+ struct drm_connector *connector);
u32 (*get_min_req_link_rate)(struct dp_panel *dp_panel);
u32 (*get_max_pclk)(struct dp_panel *dp_panel);
};
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index e81bbb3..c85c2a2 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -101,23 +101,85 @@
return rc;
}
+static const char *dp_get_phy_aux_config_property(u32 cfg_type)
+{
+ switch (cfg_type) {
+ case PHY_AUX_CFG0:
+ return "qcom,aux-cfg0-settings";
+ case PHY_AUX_CFG1:
+ return "qcom,aux-cfg1-settings";
+ case PHY_AUX_CFG2:
+ return "qcom,aux-cfg2-settings";
+ case PHY_AUX_CFG3:
+ return "qcom,aux-cfg3-settings";
+ case PHY_AUX_CFG4:
+ return "qcom,aux-cfg4-settings";
+ case PHY_AUX_CFG5:
+ return "qcom,aux-cfg5-settings";
+ case PHY_AUX_CFG6:
+ return "qcom,aux-cfg6-settings";
+ case PHY_AUX_CFG7:
+ return "qcom,aux-cfg7-settings";
+ case PHY_AUX_CFG8:
+ return "qcom,aux-cfg8-settings";
+ case PHY_AUX_CFG9:
+ return "qcom,aux-cfg9-settings";
+ default:
+ return "unknown";
+ }
+}
+
+static void dp_parser_phy_aux_cfg_reset(struct dp_parser *parser)
+{
+ int i = 0;
+
+ for (i = 0; i < PHY_AUX_CFG_MAX; i++)
+ parser->aux_cfg[i] = (const struct dp_aux_cfg){ 0 };
+}
+
static int dp_parser_aux(struct dp_parser *parser)
{
- int len = 0, i = 0, rc = 0;
struct device_node *of_node = parser->pdev->dev.of_node;
+ int len = 0, i = 0, j = 0, config_count = 0;
const char *data;
+ int const minimum_config_count = 1;
- data = of_get_property(of_node, "qcom,aux-cfg-settings", &len);
- if (!data || (len != AUX_CFG_LEN)) {
- pr_err("Unable to read DP AUX CFG settings\n");
- rc = -EINVAL;
- goto end;
+ for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
+ const char *property = dp_get_phy_aux_config_property(i);
+
+ data = of_get_property(of_node, property, &len);
+ if (!data) {
+ pr_err("Unable to read %s\n", property);
+ goto error;
+ }
+
+ config_count = len - 1;
+ if ((config_count < minimum_config_count) ||
+ (config_count > DP_AUX_CFG_MAX_VALUE_CNT)) {
+ pr_err("Invalid config count (%d) configs for %s\n",
+ config_count, property);
+ goto error;
+ }
+
+ parser->aux_cfg[i].offset = data[0];
+ parser->aux_cfg[i].cfg_cnt = config_count;
+ pr_debug("%s offset=0x%x, cfg_cnt=%d\n",
+ property,
+ parser->aux_cfg[i].offset,
+ parser->aux_cfg[i].cfg_cnt);
+ for (j = 1; j < len; j++) {
+ parser->aux_cfg[i].lut[j - 1] = data[j];
+ pr_debug("%s lut[%d]=0x%x\n",
+ property,
+ i,
+ parser->aux_cfg[i].lut[j - 1]);
+ }
}
+ return 0;
- for (i = 0; i < len; i++)
- parser->aux_cfg[i] = data[i];
-end:
- return rc;
+error:
+ dp_parser_phy_aux_cfg_reset(parser);
+ return -EINVAL;
}
static int dp_parser_misc(struct dp_parser *parser)
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index fdcdd3a..7794da5 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -93,6 +93,66 @@
struct pinctrl_state *state_suspend;
};
+#define DP_ENUM_STR(x) #x
+#define DP_AUX_CFG_MAX_VALUE_CNT 3
+/**
+ * struct dp_aux_cfg - DP's AUX configuration settings
+ *
+ * @cfg_cnt: count of the configurable settings for the AUX register
+ * @current_index: current index of the AUX config lut
+ * @offset: register offset of the AUX config register
+ * @lut: look up table for the AUX config values for this register
+ */
+struct dp_aux_cfg {
+ u32 cfg_cnt;
+ u32 current_index;
+ u32 offset;
+ u32 lut[DP_AUX_CFG_MAX_VALUE_CNT];
+};
+
+/* PHY AUX config registers */
+enum dp_phy_aux_config_type {
+ PHY_AUX_CFG0,
+ PHY_AUX_CFG1,
+ PHY_AUX_CFG2,
+ PHY_AUX_CFG3,
+ PHY_AUX_CFG4,
+ PHY_AUX_CFG5,
+ PHY_AUX_CFG6,
+ PHY_AUX_CFG7,
+ PHY_AUX_CFG8,
+ PHY_AUX_CFG9,
+ PHY_AUX_CFG_MAX,
+};
+
+static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type)
+{
+ switch (cfg_type) {
+ case PHY_AUX_CFG0:
+ return DP_ENUM_STR(PHY_AUX_CFG0);
+ case PHY_AUX_CFG1:
+ return DP_ENUM_STR(PHY_AUX_CFG1);
+ case PHY_AUX_CFG2:
+ return DP_ENUM_STR(PHY_AUX_CFG2);
+ case PHY_AUX_CFG3:
+ return DP_ENUM_STR(PHY_AUX_CFG3);
+ case PHY_AUX_CFG4:
+ return DP_ENUM_STR(PHY_AUX_CFG4);
+ case PHY_AUX_CFG5:
+ return DP_ENUM_STR(PHY_AUX_CFG5);
+ case PHY_AUX_CFG6:
+ return DP_ENUM_STR(PHY_AUX_CFG6);
+ case PHY_AUX_CFG7:
+ return DP_ENUM_STR(PHY_AUX_CFG7);
+ case PHY_AUX_CFG8:
+ return DP_ENUM_STR(PHY_AUX_CFG8);
+ case PHY_AUX_CFG9:
+ return DP_ENUM_STR(PHY_AUX_CFG9);
+ default:
+ return "unknown";
+ }
+}
+
/**
* struct dp_parser - DP parser's data exposed to clients
*
@@ -111,7 +171,7 @@
struct dp_display_data disp_data;
u8 l_map[4];
- u32 aux_cfg[AUX_CFG_LEN];
+ struct dp_aux_cfg aux_cfg[AUX_CFG_LEN];
u32 max_pclk_khz;
int (*parse)(struct dp_parser *parser);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 21ef811..96136ba 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1945,6 +1945,36 @@
spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags);
}
+int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl)
+{
+ if (!dsi_ctrl) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
+ if (dsi_ctrl->hw.ops.host_setup)
+ dsi_ctrl->hw.ops.host_setup(&dsi_ctrl->hw,
+ &dsi_ctrl->host_config.common_config);
+
+ if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE) {
+ if (dsi_ctrl->hw.ops.cmd_engine_setup)
+ dsi_ctrl->hw.ops.cmd_engine_setup(&dsi_ctrl->hw,
+ &dsi_ctrl->host_config.common_config,
+ &dsi_ctrl->host_config.u.cmd_engine);
+
+ if (dsi_ctrl->hw.ops.setup_cmd_stream)
+ dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
+ &dsi_ctrl->host_config.video_timing,
+ dsi_ctrl->host_config.video_timing.h_active * 3,
+ 0x0, NULL);
+ } else {
+ pr_err("invalid panel mode for resolution switch\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* dsi_ctrl_host_init() - Initialize DSI host hardware.
* @dsi_ctrl: DSI controller handle.
@@ -2002,8 +2032,6 @@
dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw, 0x0);
dsi_ctrl->hw.ops.enable_error_interrupts(&dsi_ctrl->hw, 0x0);
- /* Perform a soft reset before enabling dsi controller */
- dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
pr_debug("[DSI_%d]Host initialization complete\n",
dsi_ctrl->cell_index);
dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x1);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index 95dac1c..dff5b02 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -360,6 +360,17 @@
int dsi_ctrl_soft_reset(struct dsi_ctrl *dsi_ctrl);
/**
+ * dsi_ctrl_host_timing_update - reinitialize host with new timing values
+ * @dsi_ctrl: DSI controller handle.
+ *
+ * Reinitialize DSI controller hardware with new display timing values
+ * when resolution is switched dynamically.
+ *
+ * Return: error code
+ */
+int dsi_ctrl_host_timing_update(struct dsi_ctrl *dsi_ctrl);
+
+/**
* dsi_ctrl_host_init() - Initialize DSI host hardware.
* @dsi_ctrl: DSI controller handle.
*
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index 8e8e353..c85d9f4 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -79,7 +79,7 @@
DSI_W32(ctrl, DSI_CLK_CTRL, 0x23F);
/* Setup DSI control register */
- reg_value = 0;
+ reg_value = DSI_R32(ctrl, DSI_CTRL);
reg_value |= (cfg->en_crc_check ? BIT(24) : 0);
reg_value |= (cfg->en_ecc_check ? BIT(20) : 0);
reg_value |= BIT(8); /* Clock lane */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
index 1e6727b..fcc59ef 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
@@ -15,6 +15,7 @@
#define _DSI_DEFS_H_
#include <linux/types.h>
+#include <drm/drm_mipi_dsi.h>
#include "msm_drv.h"
#define DSI_H_TOTAL(t) (((t)->h_active) + ((t)->h_back_porch) + \
@@ -75,11 +76,13 @@
* @DSI_MODE_FLAG_SEAMLESS: Seamless transition requested by user
* @DSI_MODE_FLAG_DFPS: Seamless transition is DynamicFPS
* @DSI_MODE_FLAG_VBLANK_PRE_MODESET: Transition needs VBLANK before Modeset
+ * @DSI_MODE_FLAG_DMS: Seamless transition is dynamic mode switch
*/
enum dsi_mode_flags {
DSI_MODE_FLAG_SEAMLESS = BIT(0),
DSI_MODE_FLAG_DFPS = BIT(1),
- DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2)
+ DSI_MODE_FLAG_VBLANK_PRE_MODESET = BIT(2),
+ DSI_MODE_FLAG_DMS = BIT(3),
};
/**
@@ -214,6 +217,68 @@
};
/**
+ * enum dsi_cmd_set_type - DSI command set type
+ * @DSI_CMD_SET_PRE_ON: Panel pre on
+ * @DSI_CMD_SET_ON: Panel on
+ * @DSI_CMD_SET_POST_ON: Panel post on
+ * @DSI_CMD_SET_PRE_OFF: Panel pre off
+ * @DSI_CMD_SET_OFF: Panel off
+ * @DSI_CMD_SET_POST_OFF: Panel post off
+ * @DSI_CMD_SET_PRE_RES_SWITCH: Pre resolution switch
+ * @DSI_CMD_SET_RES_SWITCH: Resolution switch
+ * @DSI_CMD_SET_POST_RES_SWITCH: Post resolution switch
+ * @DSI_CMD_SET_CMD_TO_VID_SWITCH: Cmd to video mode switch
+ * @DSI_CMD_SET_POST_CMD_TO_VID_SWITCH: Post cmd to vid switch
+ * @DSI_CMD_SET_VID_TO_CMD_SWITCH: Video to cmd mode switch
+ * @DSI_CMD_SET_POST_VID_TO_CMD_SWITCH: Post vid to cmd switch
+ * @DSI_CMD_SET_PANEL_STATUS: Panel status
+ * @DSI_CMD_SET_LP1: Low power mode 1
+ * @DSI_CMD_SET_LP2: Low power mode 2
+ * @DSI_CMD_SET_NOLP: Low power mode disable
+ * @DSI_CMD_SET_PPS: DSC PPS command
+ * @DSI_CMD_SET_ROI: Panel ROI update
+ * @DSI_CMD_SET_TIMING_SWITCH: Timing switch
+ * @DSI_CMD_SET_POST_TIMING_SWITCH: Post timing switch
+ * @DSI_CMD_SET_MAX
+ */
+enum dsi_cmd_set_type {
+ DSI_CMD_SET_PRE_ON = 0,
+ DSI_CMD_SET_ON,
+ DSI_CMD_SET_POST_ON,
+ DSI_CMD_SET_PRE_OFF,
+ DSI_CMD_SET_OFF,
+ DSI_CMD_SET_POST_OFF,
+ DSI_CMD_SET_PRE_RES_SWITCH,
+ DSI_CMD_SET_RES_SWITCH,
+ DSI_CMD_SET_POST_RES_SWITCH,
+ DSI_CMD_SET_CMD_TO_VID_SWITCH,
+ DSI_CMD_SET_POST_CMD_TO_VID_SWITCH,
+ DSI_CMD_SET_VID_TO_CMD_SWITCH,
+ DSI_CMD_SET_POST_VID_TO_CMD_SWITCH,
+ DSI_CMD_SET_PANEL_STATUS,
+ DSI_CMD_SET_LP1,
+ DSI_CMD_SET_LP2,
+ DSI_CMD_SET_NOLP,
+ DSI_CMD_SET_PPS,
+ DSI_CMD_SET_ROI,
+ DSI_CMD_SET_TIMING_SWITCH,
+ DSI_CMD_SET_POST_TIMING_SWITCH,
+ DSI_CMD_SET_MAX
+};
+
+/**
+ * enum dsi_cmd_set_state - command set state
+ * @DSI_CMD_SET_STATE_LP: dsi low power mode
+ * @DSI_CMD_SET_STATE_HS: dsi high speed mode
+ * @DSI_CMD_SET_STATE_MAX
+ */
+enum dsi_cmd_set_state {
+ DSI_CMD_SET_STATE_LP = 0,
+ DSI_CMD_SET_STATE_HS,
+ DSI_CMD_SET_STATE_MAX
+};
+
+/**
* enum dsi_phy_type - DSI phy types
* @DSI_PHY_TYPE_DPHY:
* @DSI_PHY_TYPE_CPHY:
@@ -246,6 +311,34 @@
};
/**
+ * struct dsi_cmd_desc - description of a dsi command
+ * @msg: dsi mipi msg packet
+ * @last_command: indicates whether the cmd is the last one to send
+ * @post_wait_ms: post wait duration
+ */
+struct dsi_cmd_desc {
+ struct mipi_dsi_msg msg;
+ bool last_command;
+ u32 post_wait_ms;
+};
+
+/**
+ * struct dsi_panel_cmd_set - command set of the panel
+ * @type: type of the command
+ * @state: state of the command
+ * @count: number of cmds
+ * @ctrl_idx: index of the dsi control
+ * @cmds: arry of cmds
+ */
+struct dsi_panel_cmd_set {
+ enum dsi_cmd_set_type type;
+ enum dsi_cmd_set_state state;
+ u32 count;
+ u32 ctrl_idx;
+ struct dsi_cmd_desc *cmds;
+};
+
+/**
* struct dsi_mode_info - video mode information dsi frame
* @h_active: Active width of one frame in pixels.
* @h_back_porch: Horizontal back porch in pixels.
@@ -397,18 +490,44 @@
};
/**
+ * struct dsi_display_mode_priv_info - private mode info that will be attached
+ * with each drm mode
+ * @cmd_sets: Command sets of the mode
+ * @phy_timing_val: Phy timing values
+ * @phy_timing_len: Phy timing array length
+ * @panel_jitter: Panel jitter for RSC backoff
+ * @panel_prefill_lines: Panel prefill lines for RSC
+ * @topology: Topology selected for the panel
+ * @dsc: DSC compression info
+ * @dsc_enabled: DSC compression enabled
+ */
+struct dsi_display_mode_priv_info {
+ struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX];
+
+ u32 *phy_timing_val;
+ u32 phy_timing_len;
+
+ u32 panel_jitter_numer;
+ u32 panel_jitter_denom;
+ u32 panel_prefill_lines;
+
+ struct msm_display_topology topology;
+ struct msm_display_dsc_info dsc;
+ bool dsc_enabled;
+};
+
+/**
* struct dsi_display_mode - specifies mode for dsi display
* @timing: Timing parameters for the panel.
* @pixel_clk_khz: Pixel clock in Khz.
- * @panel_mode: Panel operation mode.
* @dsi_mode_flags: Flags to signal other drm components via private flags
+ * @priv_info: Mode private info
*/
struct dsi_display_mode {
struct dsi_mode_info timing;
u32 pixel_clk_khz;
- enum dsi_op_mode panel_mode;
u32 dsi_mode_flags;
- struct msm_mode_info *mode_info;
+ struct dsi_display_mode_priv_info *priv_info;
};
/**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 195584f..547a3e5 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -31,6 +31,7 @@
#define to_dsi_display(x) container_of(x, struct dsi_display, host)
#define INT_BASE_10 10
+#define NO_OVERRIDE -1
#define MISR_BUFF_SIZE 256
@@ -800,29 +801,46 @@
return rc;
}
-static int dsi_display_parse_cmdline_topology(unsigned int display_type)
+static void dsi_display_parse_cmdline_topology(struct dsi_display *display,
+ unsigned int display_type)
{
+ char *boot_str = NULL;
char *str = NULL;
- int top_index = -1;
+ unsigned long value;
if (display_type >= MAX_DSI_ACTIVE_DISPLAY) {
pr_err("display_type=%d not supported\n", display_type);
- return -EINVAL;
+ return;
}
+
if (display_type == DSI_PRIMARY)
- str = strnstr(dsi_display_primary,
- ":config", strlen(dsi_display_primary));
+ boot_str = dsi_display_primary;
else
- str = strnstr(dsi_display_secondary,
- ":config", strlen(dsi_display_secondary));
+ boot_str = dsi_display_secondary;
+
+ str = strnstr(boot_str, ":config", strlen(boot_str));
if (!str)
- return -EINVAL;
+ return;
if (kstrtol(str + strlen(":config"), INT_BASE_10,
- (unsigned long *)&top_index))
- return -EINVAL;
+ (unsigned long *)&value)) {
+ pr_err("invalid config index override: %s\n", boot_str);
+ return;
+ }
+ display->cmdline_topology = value;
- return top_index;
+ str = strnstr(boot_str, ":timing", strlen(boot_str));
+ if (!str)
+ return;
+
+ if (kstrtol(str + strlen(":timing"), INT_BASE_10,
+ (unsigned long *)&value)) {
+ pr_err("invalid timing index override: %s. resetting both timing and config\n",
+ boot_str);
+ display->cmdline_topology = NO_OVERRIDE;
+ return;
+ }
+ display->cmdline_timing = value;
}
/**
@@ -1089,6 +1107,32 @@
return 0;
}
+static int dsi_display_ctrl_update(struct dsi_display *display)
+{
+ int rc = 0;
+ int i;
+ struct dsi_display_ctrl *ctrl;
+
+ for (i = 0 ; i < display->ctrl_count; i++) {
+ ctrl = &display->ctrl[i];
+ rc = dsi_ctrl_host_timing_update(ctrl->ctrl);
+ if (rc) {
+ pr_err("[%s] failed to update host_%d, rc=%d\n",
+ display->name, i, rc);
+ goto error_host_deinit;
+ }
+ }
+
+ return 0;
+error_host_deinit:
+ for (i = i - 1; i >= 0; i--) {
+ ctrl = &display->ctrl[i];
+ (void)dsi_ctrl_host_deinit(ctrl->ctrl);
+ }
+
+ return rc;
+}
+
static int dsi_display_ctrl_init(struct dsi_display *display)
{
int rc = 0;
@@ -2239,17 +2283,6 @@
goto error_ctrl_put;
}
- if (display->panel->phy_timing_len) {
- for (i = 0; i < display->ctrl_count; i++) {
- ctrl = &display->ctrl[i];
- rc = dsi_phy_set_timing_params(ctrl->phy,
- display->panel->phy_timing_val,
- display->panel->phy_timing_len);
- if (rc)
- pr_err("failed to add DSI PHY timing params");
- }
- }
-
rc = dsi_display_parse_lane_map(display);
if (rc) {
pr_err("Lane map not found, rc=%d\n", rc);
@@ -2288,6 +2321,9 @@
dsi_ctrl_put(ctrl->ctrl);
}
+ if (display->panel)
+ dsi_panel_put(display->panel);
+
return rc;
}
@@ -2326,12 +2362,12 @@
{
struct dsi_display_mode *cur;
- if (!display || !tgt) {
+ if (!display || !tgt || !display->panel) {
pr_err("Invalid params\n");
return false;
}
- cur = &display->panel->mode;
+ cur = display->panel->cur_mode;
if (cur->timing.h_active != tgt->timing.h_active) {
pr_debug("timing.h_active differs %d %d\n",
@@ -2410,12 +2446,6 @@
pr_debug("pixel_clk_khz differs %d %d\n",
cur->pixel_clk_khz, tgt->pixel_clk_khz);
- if (cur->panel_mode != tgt->panel_mode) {
- pr_debug("panel_mode differs %d %d\n",
- cur->panel_mode, tgt->panel_mode);
- return false;
- }
-
if (cur->dsi_mode_flags != tgt->dsi_mode_flags)
pr_debug("flags differs %d %d\n",
cur->dsi_mode_flags, tgt->dsi_mode_flags);
@@ -2433,7 +2463,7 @@
int rc = 0;
int i = 0;
- if (!display || !dsi_mode) {
+ if (!display || !dsi_mode || !display->panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
@@ -2476,7 +2506,7 @@
}
}
- panel_mode = &display->panel->mode;
+ panel_mode = display->panel->cur_mode;
memcpy(panel_mode, dsi_mode, sizeof(*panel_mode));
/*
* dsi_mode_flags flags are used to communicate with other drm driver
@@ -2631,6 +2661,14 @@
int rc = 0;
int i;
struct dsi_display_ctrl *ctrl;
+ struct dsi_display_mode_priv_info *priv_info;
+
+ priv_info = mode->priv_info;
+ if (!priv_info) {
+ pr_err("[%s] failed to get private info of the display mode",
+ display->name);
+ return -EINVAL;
+ }
rc = dsi_panel_get_host_cfg_for_mode(display->panel,
mode,
@@ -2663,6 +2701,17 @@
goto error;
}
}
+
+ if (priv_info->phy_timing_len) {
+ for (i = 0; i < display->ctrl_count; i++) {
+ ctrl = &display->ctrl[i];
+ rc = dsi_phy_set_timing_params(ctrl->phy,
+ priv_info->phy_timing_val,
+ priv_info->phy_timing_len);
+ if (rc)
+ pr_err("failed to add DSI PHY timing params");
+ }
+ }
error:
return rc;
}
@@ -2889,19 +2938,10 @@
goto error_host_deinit;
}
- rc = dsi_panel_get_mode_count(display->panel, &display->num_of_modes);
- if (rc) {
- pr_err("[%s] failed to get mode count, rc=%d\n",
- display->name, rc);
- goto error_panel_deinit;
- }
-
pr_info("Successfully bind display panel '%s'\n", display->name);
display->drm_dev = drm;
goto error;
-error_panel_deinit:
- (void)dsi_panel_drv_deinit(display->panel);
error_host_deinit:
(void)dsi_display_mipi_host_deinit(display);
error_clk_client_deinit:
@@ -3018,8 +3058,10 @@
boot_displays_parsed = true;
}
- /* Initialize cmdline_topology to use default topology */
- display->cmdline_topology = -1;
+ /* use default topology of every mode if not overridden */
+ display->cmdline_topology = NO_OVERRIDE;
+ display->cmdline_timing = 0;
+
if ((!display_from_cmdline) &&
(boot_displays[DSI_PRIMARY].boot_disp_en)) {
display->is_active = dsi_display_name_compare(pdev->dev.of_node,
@@ -3045,8 +3087,8 @@
pr_debug("cmdline primary dsi: %s\n",
display->name);
display_from_cmdline = true;
- display->cmdline_topology =
- dsi_display_parse_cmdline_topology(DSI_PRIMARY);
+ dsi_display_parse_cmdline_topology(display,
+ DSI_PRIMARY);
primary_np = pdev->dev.of_node;
}
}
@@ -3061,9 +3103,8 @@
if (primary_np) {
if (validate_dsi_display_selection()) {
display->is_active = true;
- display->cmdline_topology =
dsi_display_parse_cmdline_topology
- (DSI_SECONDARY);
+ (display, DSI_SECONDARY);
} else {
boot_displays[DSI_SECONDARY]
.boot_disp_en = false;
@@ -3264,7 +3305,6 @@
{
struct dsi_display *display;
struct dsi_panel_phy_props phy_props;
- struct dsi_mode_info *timing;
int i, rc;
if (!info || !disp) {
@@ -3288,32 +3328,18 @@
memset(info, 0, sizeof(struct msm_display_info));
info->intf_type = DRM_MODE_CONNECTOR_DSI;
- timing = &display->panel->mode.timing;
-
info->num_of_h_tiles = display->ctrl_count;
for (i = 0; i < info->num_of_h_tiles; i++)
info->h_tile_instance[i] = display->ctrl[i].ctrl->cell_index;
info->is_connected = true;
info->is_primary = true;
- info->frame_rate = timing->refresh_rate;
- info->vtotal = DSI_V_TOTAL(timing);
- info->prefill_lines = display->panel->panel_prefill_lines;
- info->jitter_numer = display->panel->panel_jitter_numer;
- info->jitter_denom = display->panel->panel_jitter_denom;
info->width_mm = phy_props.panel_width_mm;
info->height_mm = phy_props.panel_height_mm;
info->max_width = 1920;
info->max_height = 1080;
- info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
- if (display->panel->dsc_enabled) {
- info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_DSC;
- memcpy(&info->comp_info.dsc_info, &display->panel->dsc,
- sizeof(struct msm_display_dsc_info));
- }
-
- switch (display->panel->mode.panel_mode) {
+ switch (display->panel->panel_mode) {
case DSI_OP_VIDEO_MODE:
info->capabilities |= MSM_DISPLAY_CAP_VID_MODE;
break;
@@ -3324,7 +3350,7 @@
break;
default:
pr_err("unknwown dsi panel mode %d\n",
- display->panel->mode.panel_mode);
+ display->panel->panel_mode);
break;
}
@@ -3336,16 +3362,57 @@
return rc;
}
-int dsi_display_get_modes(struct dsi_display *display,
- struct dsi_display_mode *modes,
- u32 *count)
+int dsi_display_get_mode_count(struct dsi_display *display,
+ u32 *count)
{
- int rc = 0;
- int i;
struct dsi_dfps_capabilities dfps_caps;
- int num_dfps_rates;
+ int num_dfps_rates, rc = 0;
- if (!display || !count) {
+ if (!display || !display->panel) {
+ pr_err("invalid display:%d panel:%d\n", display != NULL,
+ display ? display->panel != NULL : 0);
+ return -EINVAL;
+ }
+
+ mutex_lock(&display->display_lock);
+
+ *count = display->panel->num_timing_nodes;
+
+ rc = dsi_panel_get_dfps_caps(display->panel, &dfps_caps);
+ if (rc) {
+ pr_err("[%s] failed to get dfps caps from panel\n",
+ display->name);
+ goto done;
+ }
+
+ num_dfps_rates = !dfps_caps.dfps_support ? 1 :
+ dfps_caps.max_refresh_rate -
+ dfps_caps.min_refresh_rate + 1;
+
+ /* Inflate num_of_modes by fps in dfps */
+ *count = display->panel->num_timing_nodes * num_dfps_rates;
+
+done:
+ mutex_unlock(&display->display_lock);
+
+ return 0;
+}
+
+void dsi_display_put_mode(struct dsi_display *display,
+ struct dsi_display_mode *mode)
+{
+ dsi_panel_put_mode(mode);
+}
+
+int dsi_display_get_modes(struct dsi_display *display,
+ struct dsi_display_mode *modes)
+{
+ struct dsi_dfps_capabilities dfps_caps;
+ u32 num_dfps_rates, panel_mode_count;
+ u32 mode_idx, array_idx = 0;
+ int i, rc = 0;
+
+ if (!display || !modes) {
pr_err("Invalid params\n");
return -EINVAL;
}
@@ -3363,41 +3430,55 @@
dfps_caps.max_refresh_rate -
dfps_caps.min_refresh_rate + 1;
- if (!modes) {
- /* Inflate num_of_modes by fps in dfps */
- *count = display->num_of_modes * num_dfps_rates;
- goto error;
- }
+ panel_mode_count = display->panel->num_timing_nodes;
- for (i = 0; i < *count; i++) {
- /* Insert the dfps "sub-modes" between main panel modes */
- int panel_mode_idx = i / num_dfps_rates;
+ for (mode_idx = 0; mode_idx < panel_mode_count; mode_idx++) {
+ struct dsi_display_mode panel_mode;
+ int topology_override = NO_OVERRIDE;
- rc = dsi_panel_get_mode(display->panel, panel_mode_idx, modes);
+ if (display->cmdline_timing == mode_idx)
+ topology_override = display->cmdline_topology;
+
+ memset(&panel_mode, 0, sizeof(panel_mode));
+
+ rc = dsi_panel_get_mode(display->panel, mode_idx,
+ &panel_mode, topology_override);
if (rc) {
- pr_err("[%s] failed to get mode from panel\n",
- display->name);
+ pr_err("[%s] failed to get mode idx %d from panel\n",
+ display->name, mode_idx);
goto error;
}
- if (dfps_caps.dfps_support) {
- modes->timing.refresh_rate = dfps_caps.min_refresh_rate
- + (i % num_dfps_rates);
- modes->pixel_clk_khz = (DSI_H_TOTAL(&modes->timing) *
- DSI_V_TOTAL(&modes->timing) *
- modes->timing.refresh_rate) / 1000;
- }
-
if (display->ctrl_count > 1) { /* TODO: remove if */
- modes->timing.h_active *= display->ctrl_count;
- modes->timing.h_front_porch *= display->ctrl_count;
- modes->timing.h_sync_width *= display->ctrl_count;
- modes->timing.h_back_porch *= display->ctrl_count;
- modes->timing.h_skew *= display->ctrl_count;
- modes->pixel_clk_khz *= display->ctrl_count;
+ panel_mode.timing.h_active *= display->ctrl_count;
+ panel_mode.timing.h_front_porch *= display->ctrl_count;
+ panel_mode.timing.h_sync_width *= display->ctrl_count;
+ panel_mode.timing.h_back_porch *= display->ctrl_count;
+ panel_mode.timing.h_skew *= display->ctrl_count;
+ panel_mode.pixel_clk_khz *= display->ctrl_count;
}
- modes++;
+ for (i = 0; i < num_dfps_rates; i++) {
+ struct dsi_display_mode *sub_mode = &modes[array_idx];
+
+ if (!sub_mode) {
+ pr_err("invalid mode data\n");
+ return -EFAULT;
+ }
+
+ memcpy(sub_mode, &panel_mode, sizeof(panel_mode));
+
+ if (dfps_caps.dfps_support) {
+ sub_mode->timing.refresh_rate =
+ dfps_caps.min_refresh_rate +
+ (i % num_dfps_rates);
+ sub_mode->pixel_clk_khz =
+ (DSI_H_TOTAL(&sub_mode->timing) *
+ DSI_V_TOTAL(&sub_mode->timing) *
+ sub_mode->timing.refresh_rate) / 1000;
+ }
+ array_idx++;
+ }
}
error:
@@ -3470,7 +3551,7 @@
int rc = 0;
struct dsi_display_mode adj_mode;
- if (!display || !mode) {
+ if (!display || !mode || !display->panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
@@ -3491,6 +3572,17 @@
pr_err("[%s] failed to set mode\n", display->name);
goto error;
}
+
+ if (!display->panel->cur_mode) {
+ display->panel->cur_mode =
+ kzalloc(sizeof(struct dsi_display_mode), GFP_KERNEL);
+ if (!display->panel->cur_mode) {
+ rc = -ENOMEM;
+ goto error;
+ }
+ }
+
+ memcpy(display->panel->cur_mode, &adj_mode, sizeof(adj_mode));
error:
mutex_unlock(&display->display_lock);
return rc;
@@ -3522,17 +3614,80 @@
return rc;
}
+static int dsi_display_pre_switch(struct dsi_display *display)
+{
+ int rc = 0;
+
+ rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
+ DSI_CORE_CLK, DSI_CLK_ON);
+ if (rc) {
+ pr_err("[%s] failed to enable DSI core clocks, rc=%d\n",
+ display->name, rc);
+ goto error;
+ }
+
+ rc = dsi_display_ctrl_update(display);
+ if (rc) {
+ pr_err("[%s] failed to update DSI controller, rc=%d\n",
+ display->name, rc);
+ goto error_ctrl_clk_off;
+ }
+
+ rc = dsi_display_set_clk_src(display);
+ if (rc) {
+ pr_err("[%s] failed to set DSI link clock source, rc=%d\n",
+ display->name, rc);
+ goto error_ctrl_deinit;
+ }
+
+ rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
+ DSI_LINK_CLK, DSI_CLK_ON);
+ if (rc) {
+ pr_err("[%s] failed to enable DSI link clocks, rc=%d\n",
+ display->name, rc);
+ goto error_ctrl_deinit;
+ }
+
+ goto error;
+
+error_ctrl_deinit:
+ (void)dsi_display_ctrl_deinit(display);
+error_ctrl_clk_off:
+ (void)dsi_display_clk_ctrl(display->dsi_clk_handle,
+ DSI_CORE_CLK, DSI_CLK_OFF);
+error:
+ return rc;
+}
+
int dsi_display_prepare(struct dsi_display *display)
{
int rc = 0;
+ struct dsi_display_mode *mode;
if (!display) {
pr_err("Invalid params\n");
return -EINVAL;
}
+ if (!display->panel->cur_mode) {
+ pr_err("no valid mode set for the display");
+ return -EINVAL;
+ }
+
mutex_lock(&display->display_lock);
+ mode = display->panel->cur_mode;
+
+ if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
+ /* update dsi ctrl for new mode */
+ rc = dsi_display_pre_switch(display);
+ if (rc)
+ pr_err("[%s] panel pre-prepare-res-switch failed, rc=%d\n",
+ display->name, rc);
+
+ goto error;
+ }
+
rc = dsi_panel_pre_prepare(display->panel);
if (rc) {
pr_err("[%s] panel pre-prepare failed, rc=%d\n",
@@ -3561,6 +3716,13 @@
goto error_ctrl_clk_off;
}
+ rc = dsi_display_set_clk_src(display);
+ if (rc) {
+ pr_err("[%s] failed to set DSI link clock source, rc=%d\n",
+ display->name, rc);
+ goto error_phy_disable;
+ }
+
rc = dsi_display_ctrl_init(display);
if (rc) {
pr_err("[%s] failed to setup DSI controller, rc=%d\n",
@@ -3568,10 +3730,10 @@
goto error_phy_disable;
}
- rc = dsi_display_set_clk_src(display);
+ rc = dsi_display_ctrl_host_enable(display);
if (rc) {
- pr_err("[%s] failed to set DSI link clock source, rc=%d\n",
- display->name, rc);
+ pr_err("[%s] failed to enable DSI host, rc=%d\n",
+ display->name, rc);
goto error_ctrl_deinit;
}
@@ -3580,29 +3742,28 @@
if (rc) {
pr_err("[%s] failed to enable DSI link clocks, rc=%d\n",
display->name, rc);
- goto error_ctrl_deinit;
+ goto error_host_engine_off;
}
- rc = dsi_display_ctrl_host_enable(display);
+ rc = dsi_display_soft_reset(display);
if (rc) {
- pr_err("[%s] failed to enable DSI host, rc=%d\n",
- display->name, rc);
+ pr_err("[%s] failed soft reset, rc=%d\n", display->name, rc);
goto error_ctrl_link_off;
}
rc = dsi_panel_prepare(display->panel);
if (rc) {
pr_err("[%s] panel prepare failed, rc=%d\n", display->name, rc);
- goto error_host_engine_off;
+ goto error_ctrl_link_off;
}
goto error;
-error_host_engine_off:
- (void)dsi_display_ctrl_host_disable(display);
error_ctrl_link_off:
(void)dsi_display_clk_ctrl(display->dsi_clk_handle,
DSI_LINK_CLK, DSI_CLK_OFF);
+error_host_engine_off:
+ (void)dsi_display_ctrl_host_disable(display);
error_ctrl_deinit:
(void)dsi_display_ctrl_deinit(display);
error_phy_disable:
@@ -3730,23 +3891,40 @@
int dsi_display_enable(struct dsi_display *display)
{
int rc = 0;
+ struct dsi_display_mode *mode;
- if (!display) {
+ if (!display || !display->panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
+ if (!display->panel->cur_mode) {
+ pr_err("no valid mode set for the display");
+ return -EINVAL;
+ }
+
mutex_lock(&display->display_lock);
- rc = dsi_panel_enable(display->panel);
- if (rc) {
- pr_err("[%s] failed to enable DSI panel, rc=%d\n",
- display->name, rc);
- goto error;
+ mode = display->panel->cur_mode;
+
+ if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
+ rc = dsi_panel_post_switch(display->panel);
+ if (rc) {
+ pr_err("[%s] failed to switch DSI panel mode, rc=%d\n",
+ display->name, rc);
+ goto error;
+ }
+ } else {
+ rc = dsi_panel_enable(display->panel);
+ if (rc) {
+ pr_err("[%s] failed to enable DSI panel, rc=%d\n",
+ display->name, rc);
+ goto error;
+ }
}
- if (display->panel->dsc_enabled) {
- display->panel->dsc.pic_width *= display->ctrl_count;
+ if (mode->priv_info->dsc_enabled) {
+ mode->priv_info->dsc.pic_width *= display->ctrl_count;
rc = dsi_panel_update_pps(display->panel);
if (rc) {
pr_err("[%s] panel pps cmd update failed, rc=%d\n",
@@ -3755,6 +3933,15 @@
}
}
+ if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
+ rc = dsi_panel_switch(display->panel);
+ if (rc)
+ pr_err("[%s] failed to switch DSI panel mode, rc=%d\n",
+ display->name, rc);
+
+ goto error_disable_panel;
+ }
+
if (display->config.panel_mode == DSI_OP_VIDEO_MODE) {
rc = dsi_display_vid_engine_enable(display);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 0ded247..1c30b9c 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -141,8 +141,8 @@
* @clock_info: Clock sourcing for DSI display.
* @config: DSI host configuration information.
* @lane_map: Lane mapping between DSI host and Panel.
- * @num_of_modes: Number of modes supported by display.
* @cmdline_topology: Display topology shared from kernel command line.
+ * @cmdline_timing: Display timing shared from kernel command line.
* @is_tpg_enabled: TPG state.
* @ulps_enabled: ulps state.
* @clamp_enabled: clamp state.
@@ -182,8 +182,8 @@
struct dsi_display_clk_info clock_info;
struct dsi_host_config config;
struct dsi_lane_map lane_map;
- u32 num_of_modes;
int cmdline_topology;
+ int cmdline_timing;
bool is_tpg_enabled;
bool ulps_enabled;
bool clamp_enabled;
@@ -280,21 +280,36 @@
int dsi_display_get_info(struct msm_display_info *info, void *disp);
/**
+ * dsi_display_get_mode_count() - get number of modes supported by the display
+ * @display: Handle to display.
+ * @count: Number of modes supported
+ *
+ * Return: error code.
+ */
+int dsi_display_get_mode_count(struct dsi_display *display, u32 *count);
+
+/**
* dsi_display_get_modes() - get modes supported by display
* @display: Handle to display.
* @modes; Pointer to array of modes. Memory allocated should be
* big enough to store (count * struct dsi_display_mode)
* elements. If modes pointer is NULL, number of modes will
* be stored in the memory pointed to by count.
- * @count: If modes is NULL, number of modes will be stored. If
- * not, mode information will be copied (number of modes
- * copied will be equal to *count).
*
* Return: error code.
*/
int dsi_display_get_modes(struct dsi_display *display,
- struct dsi_display_mode *modes,
- u32 *count);
+ struct dsi_display_mode *modes);
+
+/**
+ * dsi_display_put_mode() - free up mode created for the display
+ * @display: Handle to display.
+ * @mode: Display mode to be freed up
+ *
+ * Return: error code.
+ */
+void dsi_display_put_mode(struct dsi_display *display,
+ struct dsi_display_mode *mode);
/**
* dsi_display_validate_mode() - validates if mode is supported by display
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c
index 93fb041..6e41f36 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display_test.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -34,7 +34,7 @@
test = container_of(work, struct dsi_display_test, test_work);
display = test->display;
- rc = dsi_display_get_modes(display, NULL, &count);
+ rc = dsi_display_get_mode_count(display, &count);
if (rc) {
pr_err("failed to get modes count, rc=%d\n", rc);
goto test_fail;
@@ -47,7 +47,7 @@
goto test_fail;
}
- rc = dsi_display_get_modes(display, modes, &count);
+ rc = dsi_display_get_modes(display, modes);
if (rc) {
pr_err("failed to get modes, rc=%d\n", rc);
goto test_fail_free_modes;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
index b499bd6..30e5f02 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
@@ -49,9 +49,9 @@
dsi_mode->timing.refresh_rate = drm_mode->vrefresh;
dsi_mode->pixel_clk_khz = drm_mode->clock;
- dsi_mode->panel_mode = 0; /* TODO: Panel Mode */
- dsi_mode->mode_info = (struct msm_mode_info *)drm_mode->private;
+ dsi_mode->priv_info =
+ (struct dsi_display_mode_priv_info *)drm_mode->private;
if (msm_is_mode_seamless(drm_mode))
dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_SEAMLESS;
@@ -59,6 +59,8 @@
dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DFPS;
if (msm_needs_vblank_pre_modeset(drm_mode))
dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_VBLANK_PRE_MODESET;
+ if (msm_is_mode_seamless_dms(drm_mode))
+ dsi_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS;
}
static void convert_to_drm_mode(const struct dsi_display_mode *dsi_mode,
@@ -84,7 +86,7 @@
drm_mode->vrefresh = dsi_mode->timing.refresh_rate;
drm_mode->clock = dsi_mode->pixel_clk_khz;
- drm_mode->private = (int *)dsi_mode->mode_info;
+ drm_mode->private = (int *)dsi_mode->priv_info;
if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_SEAMLESS)
drm_mode->flags |= DRM_MODE_FLAG_SEAMLESS;
@@ -92,6 +94,8 @@
drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DYNAMIC_FPS;
if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_VBLANK_PRE_MODESET)
drm_mode->private_flags |= MSM_MODE_FLAG_VBLANK_PRE_MODESET;
+ if (dsi_mode->dsi_mode_flags & DSI_MODE_FLAG_DMS)
+ drm_mode->private_flags |= MSM_MODE_FLAG_SEAMLESS_DMS;
drm_mode_set_name(drm_mode);
}
@@ -237,10 +241,6 @@
memset(&(c_bridge->dsi_mode), 0x0, sizeof(struct dsi_display_mode));
convert_to_dsi_mode(adjusted_mode, &(c_bridge->dsi_mode));
-
- pr_debug("note: using panel cmd/vid mode instead of user val\n");
- c_bridge->dsi_mode.panel_mode =
- c_bridge->display->panel->mode.panel_mode;
}
static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
@@ -248,9 +248,9 @@
struct drm_display_mode *adjusted_mode)
{
int rc = 0;
- bool ret = true;
struct dsi_bridge *c_bridge = to_dsi_bridge(bridge);
struct dsi_display_mode dsi_mode;
+ struct drm_display_mode cur_mode;
if (!bridge || !mode || !adjusted_mode) {
pr_err("Invalid params\n");
@@ -263,31 +263,55 @@
DSI_VALIDATE_FLAG_ALLOW_ADJUST);
if (rc) {
pr_err("[%d] mode is not valid, rc=%d\n", c_bridge->id, rc);
- ret = false;
- } else {
- convert_to_drm_mode(&dsi_mode, adjusted_mode);
+ return false;
}
- return ret;
+ if (bridge->encoder && bridge->encoder->crtc) {
+ cur_mode = bridge->encoder->crtc->mode;
+
+ if (!drm_mode_equal(&cur_mode, adjusted_mode))
+ dsi_mode.dsi_mode_flags |= DSI_MODE_FLAG_DMS;
+ }
+
+ convert_to_drm_mode(&dsi_mode, adjusted_mode);
+
+ return true;
}
-int dsi_conn_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology,
+int dsi_conn_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info,
u32 max_mixer_width)
{
struct dsi_display_mode dsi_mode;
+ struct dsi_mode_info *timing;
- if (!drm_mode || !topology)
+ if (!drm_mode || !mode_info)
return -EINVAL;
convert_to_dsi_mode(drm_mode, &dsi_mode);
- if (!dsi_mode.mode_info)
+ if (!dsi_mode.priv_info)
return -EINVAL;
- memcpy(topology, &dsi_mode.mode_info->topology,
+ memset(mode_info, 0, sizeof(*mode_info));
+
+ timing = &dsi_mode.timing;
+ mode_info->frame_rate = dsi_mode.timing.refresh_rate;
+ mode_info->vtotal = DSI_V_TOTAL(timing);
+ mode_info->prefill_lines = dsi_mode.priv_info->panel_prefill_lines;
+ mode_info->jitter_numer = dsi_mode.priv_info->panel_jitter_numer;
+ mode_info->jitter_denom = dsi_mode.priv_info->panel_jitter_denom;
+
+ memcpy(&mode_info->topology, &dsi_mode.priv_info->topology,
sizeof(struct msm_display_topology));
+ mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
+ if (dsi_mode.priv_info->dsc_enabled) {
+ mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_DSC;
+ memcpy(&mode_info->comp_info.dsc_info, &dsi_mode.priv_info->dsc,
+ sizeof(dsi_mode.priv_info->dsc));
+ }
+
return 0;
}
@@ -343,7 +367,7 @@
panel = dsi_display->panel;
sde_kms_info_add_keystr(info, "panel name", panel->name);
- switch (panel->mode.panel_mode) {
+ switch (panel->panel_mode) {
case DSI_OP_VIDEO_MODE:
sde_kms_info_add_keystr(info, "panel mode", "video");
break;
@@ -353,7 +377,7 @@
panel->cmd_config.mdp_transfer_time_us);
break;
default:
- pr_debug("invalid panel type:%d\n", panel->mode.panel_mode);
+ pr_debug("invalid panel type:%d\n", panel->panel_mode);
break;
}
sde_kms_info_add_keystr(info, "dfps support",
@@ -449,6 +473,21 @@
return status;
}
+void dsi_connector_put_modes(struct drm_connector *connector,
+ void *display)
+{
+ struct drm_display_mode *drm_mode;
+ struct dsi_display_mode dsi_mode;
+
+ if (!connector || !display)
+ return;
+
+ list_for_each_entry(drm_mode, &connector->modes, head) {
+ convert_to_dsi_mode(drm_mode, &dsi_mode);
+ dsi_display_put_mode(display, &dsi_mode);
+ }
+}
+
int dsi_connector_get_modes(struct drm_connector *connector,
void *display)
{
@@ -466,7 +505,7 @@
*/
goto end;
}
- rc = dsi_display_get_modes(display, NULL, &count);
+ rc = dsi_display_get_mode_count(display, &count);
if (rc) {
pr_err("failed to get num of modes, rc=%d\n", rc);
goto error;
@@ -479,7 +518,7 @@
goto end;
}
- rc = dsi_display_get_modes(display, modes, &count);
+ rc = dsi_display_get_modes(display, modes);
if (rc) {
pr_err("failed to get modes, rc=%d\n", rc);
count = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.h b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.h
index 45feec9..793f8f1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.h
@@ -64,15 +64,22 @@
void *display);
/**
- * dsi_conn_get_topology - retrieve current topology for the mode selected
+ * dsi_connector_put_modes - callback to free up drm modes of the connector
+ * @connector: Pointer to drm connector structure
+ * @display: Pointer to private display handle
+ */
+void dsi_connector_put_modes(struct drm_connector *connector,
+ void *display);
+
+/**
+ * dsi_conn_get_mode_info - retrieve information on the mode selected
* @drm_mode: Display mode set for the display
- * @topology: Out parameter. Topology for the mode.
+ * @mode_info: Out parameter. information of the mode.
* @max_mixer_width: max width supported by HW layer mixer
* Returns: Zero on success
*/
-int dsi_conn_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology,
- u32 max_mixer_width);
+int dsi_conn_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info, u32 max_mixer_width);
/**
* dsi_conn_mode_valid - callback to determine if specified mode is valid
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 81da506..f7b0d7f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -471,11 +471,21 @@
{
int rc = 0, i = 0;
ssize_t len;
- struct dsi_cmd_desc *cmds = panel->cmd_sets[type].cmds;
- u32 count = panel->cmd_sets[type].count;
- enum dsi_cmd_set_state state = panel->cmd_sets[type].state;
+ struct dsi_cmd_desc *cmds;
+ u32 count;
+ enum dsi_cmd_set_state state;
+ struct dsi_display_mode *mode;
const struct mipi_dsi_host_ops *ops = panel->host->ops;
+ if (!panel || !panel->cur_mode)
+ return -EINVAL;
+
+ mode = panel->cur_mode;
+
+ cmds = mode->priv_info->cmd_sets[type].cmds;
+ count = mode->priv_info->cmd_sets[type].count;
+ state = mode->priv_info->cmd_sets[type].state;
+
if (count == 0) {
pr_debug("[%s] No commands to be sent for state(%d)\n",
panel->name, type);
@@ -971,7 +981,7 @@
panel->name);
if (rc) {
pr_err("[%s] failed to get pixel format, rc=%d\n",
- panel->name, rc);
+ panel->name, rc);
goto error;
}
@@ -1266,7 +1276,7 @@
}
}
- panel->mode.panel_mode = panel_mode;
+ panel->panel_mode = panel_mode;
error:
return rc;
}
@@ -1338,6 +1348,8 @@
"qcom,mdss-dsi-nolp-command",
"PPS not parsed from DTSI, generated dynamically",
"ROI not parsed from DTSI, generated dynamically",
+ "qcom,mdss-dsi-timing-switch-command",
+ "qcom,mdss-dsi-post-mode-switch-on-command",
};
const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
@@ -1360,6 +1372,8 @@
"qcom,mdss-dsi-nolp-command-state",
"PPS not parsed from DTSI, generated dynamically",
"ROI not parsed from DTSI, generated dynamically",
+ "qcom,mdss-dsi-timing-switch-command-state",
+ "qcom,mdss-dsi-post-mode-switch-on-command-state",
};
static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt)
@@ -1516,29 +1530,34 @@
}
-static int dsi_panel_parse_cmd_sets(struct dsi_panel *panel,
- struct device_node *of_node)
+static int dsi_panel_parse_cmd_sets(
+ struct dsi_display_mode_priv_info *priv_info,
+ struct device_node *of_node)
{
int rc = 0;
struct dsi_panel_cmd_set *set;
u32 i;
+ if (!priv_info) {
+ pr_err("invalid mode priv info\n");
+ return -EINVAL;
+ }
+
for (i = DSI_CMD_SET_PRE_ON; i < DSI_CMD_SET_MAX; i++) {
- set = &panel->cmd_sets[i];
+ set = &priv_info->cmd_sets[i];
set->type = i;
set->count = 0;
if (i == DSI_CMD_SET_PPS) {
rc = dsi_panel_alloc_cmd_packets(set, 1);
if (rc)
- pr_err("[%s] failed to allocate cmd set %d, rc = %d\n",
- panel->name, i, rc);
+ pr_err("failed to allocate cmd set %d, rc = %d\n",
+ i, rc);
set->state = DSI_CMD_SET_STATE_LP;
} else {
rc = dsi_panel_parse_cmd_sets_sub(set, i, of_node);
if (rc)
- pr_debug("[%s] failed to parse set %d\n",
- panel->name, i);
+ pr_debug("failed to parse set %d\n", i);
}
}
@@ -1627,13 +1646,17 @@
return 0;
}
-static int dsi_panel_parse_jitter_config(struct dsi_panel *panel,
- struct device_node *of_node)
+static int dsi_panel_parse_jitter_config(
+ struct dsi_display_mode *mode,
+ struct device_node *of_node)
{
int rc;
+ struct dsi_display_mode_priv_info *priv_info;
u32 jitter[DEFAULT_PANEL_JITTER_ARRAY_SIZE] = {0, 0};
u64 jitter_val = 0;
+ priv_info = mode->priv_info;
+
rc = of_property_read_u32_array(of_node, "qcom,mdss-dsi-panel-jitter",
jitter, DEFAULT_PANEL_JITTER_ARRAY_SIZE);
if (rc) {
@@ -1644,23 +1667,25 @@
}
if (rc || !jitter_val || (jitter_val > MAX_PANEL_JITTER)) {
- panel->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
- panel->panel_jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR;
+ priv_info->panel_jitter_numer = DEFAULT_PANEL_JITTER_NUMERATOR;
+ priv_info->panel_jitter_denom =
+ DEFAULT_PANEL_JITTER_DENOMINATOR;
} else {
- panel->panel_jitter_numer = jitter[0];
- panel->panel_jitter_denom = jitter[1];
+ priv_info->panel_jitter_numer = jitter[0];
+ priv_info->panel_jitter_denom = jitter[1];
}
rc = of_property_read_u32(of_node, "qcom,mdss-dsi-panel-prefill-lines",
- &panel->panel_prefill_lines);
+ &priv_info->panel_prefill_lines);
if (rc) {
pr_debug("panel prefill lines are not defined rc=%d\n", rc);
- panel->panel_prefill_lines = DEFAULT_PANEL_PREFILL_LINES;
- } else if (panel->panel_prefill_lines >=
- DSI_V_TOTAL(&panel->mode.timing)) {
+ priv_info->panel_prefill_lines = DEFAULT_PANEL_PREFILL_LINES;
+ } else if (priv_info->panel_prefill_lines >=
+ DSI_V_TOTAL(&mode->timing)) {
pr_debug("invalid prefill lines config=%d setting to:%d\n",
- panel->panel_prefill_lines, DEFAULT_PANEL_PREFILL_LINES);
- panel->panel_prefill_lines = DEFAULT_PANEL_PREFILL_LINES;
+ priv_info->panel_prefill_lines, DEFAULT_PANEL_PREFILL_LINES);
+
+ priv_info->panel_prefill_lines = DEFAULT_PANEL_PREFILL_LINES;
}
return 0;
@@ -2047,38 +2072,85 @@
return 0;
}
-int dsi_panel_parse_dsc_params(struct dsi_panel *panel,
+
+static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode,
+ struct device_node *of_node)
+{
+ const char *data;
+ u32 len, i;
+ int rc = 0;
+ struct dsi_display_mode_priv_info *priv_info;
+
+ priv_info = mode->priv_info;
+
+ data = of_get_property(of_node,
+ "qcom,mdss-dsi-panel-phy-timings", &len);
+ if (!data) {
+ pr_debug("Unable to read Phy timing settings");
+ } else {
+ priv_info->phy_timing_val =
+ kzalloc((sizeof(u32) * len), GFP_KERNEL);
+ if (!priv_info->phy_timing_val)
+ return -EINVAL;
+
+ for (i = 0; i < len; i++)
+ priv_info->phy_timing_val[i] = data[i];
+
+ priv_info->phy_timing_len = len;
+ };
+
+ mode->pixel_clk_khz = (DSI_H_TOTAL(&mode->timing) *
+ DSI_V_TOTAL(&mode->timing) *
+ mode->timing.refresh_rate) / 1000;
+ return rc;
+}
+
+static int dsi_panel_parse_dsc_params(struct dsi_display_mode *mode,
struct device_node *of_node)
{
u32 data;
int rc = -EINVAL;
int intf_width;
+ const char *compression;
+ struct dsi_display_mode_priv_info *priv_info;
- if (!panel->dsc_enabled)
+ if (!mode || !mode->priv_info)
+ return -EINVAL;
+
+ priv_info = mode->priv_info;
+
+ priv_info->dsc_enabled = false;
+ compression = of_get_property(of_node, "qcom,compression-mode", NULL);
+ if (compression && !strcmp(compression, "dsc"))
+ priv_info->dsc_enabled = true;
+
+ if (!priv_info->dsc_enabled) {
+ pr_debug("dsc compression is not enabled for the mode");
return 0;
+ }
rc = of_property_read_u32(of_node, "qcom,mdss-dsc-slice-height", &data);
if (rc) {
pr_err("failed to parse qcom,mdss-dsc-slice-height\n");
goto error;
}
- panel->dsc.slice_height = data;
+ priv_info->dsc.slice_height = data;
rc = of_property_read_u32(of_node, "qcom,mdss-dsc-slice-width", &data);
if (rc) {
pr_err("failed to parse qcom,mdss-dsc-slice-width\n");
goto error;
}
- panel->dsc.slice_width = data;
+ priv_info->dsc.slice_width = data;
- intf_width = panel->mode.timing.h_active;
- if (intf_width % panel->dsc.slice_width) {
+ intf_width = mode->timing.h_active;
+ if (intf_width % priv_info->dsc.slice_width) {
pr_err("invalid slice width for the panel\n");
goto error;
}
- panel->dsc.pic_width = panel->mode.timing.h_active;
- panel->dsc.pic_height = panel->mode.timing.v_active;
+ priv_info->dsc.pic_width = mode->timing.h_active;
+ priv_info->dsc.pic_height = mode->timing.v_active;
rc = of_property_read_u32(of_node, "qcom,mdss-dsc-slice-per-pkt",
&data);
@@ -2086,7 +2158,7 @@
pr_err("failed to parse qcom,mdss-dsc-slice-per-pkt\n");
goto error;
}
- panel->dsc.slice_per_pkt = data;
+ priv_info->dsc.slice_per_pkt = data;
rc = of_property_read_u32(of_node, "qcom,mdss-dsc-bit-per-component",
&data);
@@ -2094,7 +2166,7 @@
pr_err("failed to parse qcom,mdss-dsc-bit-per-component\n");
goto error;
}
- panel->dsc.bpc = data;
+ priv_info->dsc.bpc = data;
rc = of_property_read_u32(of_node, "qcom,mdss-dsc-bit-per-pixel",
&data);
@@ -2102,16 +2174,16 @@
pr_err("failed to parse qcom,mdss-dsc-bit-per-pixel\n");
goto error;
}
- panel->dsc.bpp = data;
+ priv_info->dsc.bpp = data;
- panel->dsc.block_pred_enable = of_property_read_bool(of_node,
+ priv_info->dsc.block_pred_enable = of_property_read_bool(of_node,
"qcom,mdss-dsc-block-prediction-enable");
- panel->dsc.full_frame_slices = DIV_ROUND_UP(intf_width,
- panel->dsc.slice_width);
+ priv_info->dsc.full_frame_slices = DIV_ROUND_UP(intf_width,
+ priv_info->dsc.slice_width);
- dsi_dsc_populate_static_param(&panel->dsc);
- dsi_dsc_pclk_param_calc(&panel->dsc, intf_width);
+ dsi_dsc_populate_static_param(&priv_info->dsc);
+ dsi_dsc_pclk_param_calc(&priv_info->dsc, intf_width);
error:
return rc;
@@ -2163,9 +2235,9 @@
return 0;
}
-static int dsi_panel_parse_topology(struct dsi_panel *panel,
- struct device_node *of_node,
- int topology_override)
+static int dsi_panel_parse_topology(
+ struct dsi_display_mode_priv_info *priv_info,
+ struct device_node *of_node, int topology_override)
{
struct msm_display_topology *topology;
u32 top_count, top_sel, *array = NULL;
@@ -2236,9 +2308,7 @@
topology[top_sel].num_intf);
parse_done:
- panel->mode.mode_info = kzalloc(sizeof(struct msm_mode_info),
- GFP_KERNEL);
- memcpy(&panel->mode.mode_info->topology, &topology[top_sel],
+ memcpy(&priv_info->topology, &topology[top_sel],
sizeof(struct msm_display_topology));
parse_fail:
kfree(topology);
@@ -2329,14 +2399,40 @@
return rc;
}
+static int dsi_panel_parse_dms_info(struct dsi_panel *panel,
+ struct device_node *of_node)
+{
+ int dms_enabled;
+ const char *data;
+
+ if (!of_node || !panel) {
+ pr_err("invalid params\n");
+ return -EINVAL;
+ }
+
+ panel->dms_mode = DSI_DMS_MODE_DISABLED;
+ dms_enabled = of_property_read_bool(of_node,
+ "qcom,dynamic-mode-switch-enabled");
+ if (!dms_enabled)
+ return 0;
+
+ data = of_get_property(of_node, "qcom,dynamic-mode-switch-type", NULL);
+ if (data && !strcmp(data, "dynamic-resolution-switch-immediate")) {
+ panel->dms_mode = DSI_DMS_MODE_RES_SWITCH_IMMEDIATE;
+ } else {
+ pr_err("[%s] unsupported dynamic switch mode: %s\n",
+ panel->name, data);
+ return -EINVAL;
+ }
+
+ return 0;
+};
+
struct dsi_panel *dsi_panel_get(struct device *parent,
struct device_node *of_node,
int topology_override)
{
struct dsi_panel *panel;
- const char *data;
- const char *compression;
- u32 len = 0;
int rc = 0;
panel = kzalloc(sizeof(*panel), GFP_KERNEL);
@@ -2348,52 +2444,6 @@
if (!panel->name)
panel->name = DSI_PANEL_DEFAULT_LABEL;
- panel->dsc_enabled = false;
- compression = of_get_property(of_node, "qcom,compression-mode", NULL);
- if (compression && !strcmp(compression, "dsc"))
- panel->dsc_enabled = true;
-
- rc = dsi_panel_parse_timing(&panel->mode.timing, of_node);
- if (rc) {
- pr_err("failed to parse panel timing, rc=%d\n", rc);
- goto error;
- }
-
- rc = dsi_panel_parse_dsc_params(panel, of_node);
- if (rc) {
- pr_err("failed to parse dsc params, rc=%d\n", rc);
- goto error;
- }
-
- data = of_get_property(of_node,
- "qcom,mdss-dsi-panel-phy-timings", &len);
- if (!data) {
- pr_debug("%s:%d, Unable to read Phy timing settings",
- __func__, __LINE__);
- } else {
- int i = 0;
-
- panel->phy_timing_val = kzalloc((sizeof(u32) * len),
- GFP_KERNEL);
- if (!panel->phy_timing_val) {
- kfree(panel);
- return ERR_PTR(-ENOMEM);
- }
- for (i = 0; i < len; i++)
- panel->phy_timing_val[i] = data[i];
- }
- panel->phy_timing_len = len;
-
- panel->mode.pixel_clk_khz = (DSI_H_TOTAL(&panel->mode.timing) *
- DSI_V_TOTAL(&panel->mode.timing) *
- panel->mode.timing.refresh_rate) / 1000;
-
- rc = dsi_panel_parse_topology(panel, of_node, topology_override);
- if (rc) {
- pr_err("failed to parse panel topology, rc=%d\n", rc);
- goto error;
- }
-
rc = dsi_panel_parse_host_config(panel, of_node);
if (rc) {
pr_err("failed to parse host configuration, rc=%d\n", rc);
@@ -2416,12 +2466,6 @@
goto error;
}
- rc = dsi_panel_parse_cmd_sets(panel, of_node);
- if (rc) {
- pr_err("failed to parse command sets, rc=%d\n", rc);
- goto error;
- }
-
rc = dsi_panel_parse_power_cfg(parent, panel, of_node);
if (rc)
pr_err("failed to parse power config, rc=%d\n", rc);
@@ -2434,13 +2478,10 @@
if (rc)
pr_err("failed to parse backlight config, rc=%d\n", rc);
- rc = dsi_panel_parse_jitter_config(panel, of_node);
- if (rc)
- pr_err("failed to parse panel jitter config, rc=%d\n", rc);
rc = dsi_panel_parse_misc_features(panel, of_node);
if (rc)
- pr_err("failed to parse panel features, rc=%d\n", rc);
+ pr_err("failed to parse misc features, rc=%d\n", rc);
rc = dsi_panel_parse_hdr_config(panel, of_node);
if (rc)
@@ -2450,6 +2491,16 @@
if (rc)
pr_debug("failed to partial update caps, rc=%d\n", rc);
+ rc = dsi_panel_get_mode_count(panel, of_node);
+ if (rc) {
+ pr_err("failed to get mode count, rc=%d\n", rc);
+ goto error;
+ }
+
+ rc = dsi_panel_parse_dms_info(panel, of_node);
+ if (rc)
+ pr_debug("failed to get dms info, rc=%d\n", rc);
+
panel->panel_of_node = of_node;
drm_panel_init(&panel->drm_panel);
mutex_init(&panel->panel_lock);
@@ -2462,14 +2513,6 @@
void dsi_panel_put(struct dsi_panel *panel)
{
- u32 i;
-
- for (i = 0; i < DSI_CMD_SET_MAX; i++)
- dsi_panel_destroy_cmd_packets(&panel->cmd_sets[i]);
-
- kfree(panel->mode.mode_info);
-
- /* TODO: more free */
kfree(panel);
}
@@ -2582,20 +2625,42 @@
return 0;
}
-int dsi_panel_get_mode_count(struct dsi_panel *panel, u32 *count)
+int dsi_panel_get_mode_count(struct dsi_panel *panel,
+ struct device_node *of_node)
{
- int rc = 0;
+ const u32 SINGLE_MODE_SUPPORT = 1;
+ struct device_node *timings_np;
+ int count, rc = 0;
- if (!panel || !count) {
+ if (!of_node || !panel) {
pr_err("invalid params\n");
return -EINVAL;
}
- mutex_lock(&panel->panel_lock);
- /* TODO: DT format has not been decided for multiple modes. */
- *count = 1;
+ panel->num_timing_nodes = 0;
- mutex_unlock(&panel->panel_lock);
+ timings_np = of_get_child_by_name(of_node,
+ "qcom,mdss-dsi-display-timings");
+ if (!timings_np) {
+ pr_err("no display timing nodes defined\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ count = of_get_child_count(timings_np);
+ if (!count || count > DSI_MODE_MAX) {
+ pr_err("invalid count of timing nodes: %d\n", count);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ /* No multiresolution support is available for video mode panels */
+ if (panel->panel_mode != DSI_OP_CMD_MODE)
+ count = SINGLE_MODE_SUPPORT;
+
+ panel->num_timing_nodes = count;
+
+error:
return rc;
}
@@ -2635,11 +2700,27 @@
return rc;
}
-int dsi_panel_get_mode(struct dsi_panel *panel,
- u32 index,
- struct dsi_display_mode *mode)
+void dsi_panel_put_mode(struct dsi_display_mode *mode)
{
- int rc = 0;
+ int i;
+
+ if (!mode->priv_info)
+ return;
+
+ for (i = 0; i < DSI_CMD_SET_MAX; i++)
+ dsi_panel_destroy_cmd_packets(&mode->priv_info->cmd_sets[i]);
+
+ kfree(mode->priv_info);
+}
+
+int dsi_panel_get_mode(struct dsi_panel *panel,
+ u32 index, struct dsi_display_mode *mode,
+ int topology_override)
+{
+ struct device_node *timings_np, *child_np;
+ struct dsi_display_mode_priv_info *prv_info;
+ u32 child_idx = 0;
+ int rc = 0, num_timings;
if (!panel || !mode) {
pr_err("invalid params\n");
@@ -2647,11 +2728,77 @@
}
mutex_lock(&panel->panel_lock);
- if (index != 0)
- rc = -ENOTSUPP; /* TODO: Support more than one mode */
- else
- memcpy(mode, &panel->mode, sizeof(*mode));
+ mode->priv_info = kzalloc(sizeof(*mode->priv_info), GFP_KERNEL);
+ if (!mode->priv_info) {
+ rc = -ENOMEM;
+ goto done;
+ }
+
+ prv_info = mode->priv_info;
+
+ timings_np = of_get_child_by_name(panel->panel_of_node,
+ "qcom,mdss-dsi-display-timings");
+ if (!timings_np) {
+ pr_err("no display timing nodes defined\n");
+ rc = -EINVAL;
+ goto parse_fail;
+ }
+
+ num_timings = of_get_child_count(timings_np);
+ if (!num_timings || num_timings > DSI_MODE_MAX) {
+ pr_err("invalid count of timing nodes: %d\n", num_timings);
+ rc = -EINVAL;
+ goto parse_fail;
+ }
+
+ for_each_child_of_node(timings_np, child_np) {
+ if (index != child_idx++)
+ continue;
+
+ rc = dsi_panel_parse_timing(&mode->timing, child_np);
+ if (rc) {
+ pr_err("failed to parse panel timing, rc=%d\n", rc);
+ goto parse_fail;
+ }
+
+ rc = dsi_panel_parse_dsc_params(mode, child_np);
+ if (rc) {
+ pr_err("failed to parse dsc params, rc=%d\n", rc);
+ goto parse_fail;
+ }
+
+ rc = dsi_panel_parse_topology(prv_info, child_np,
+ topology_override);
+ if (rc) {
+ pr_err("failed to parse panel topology, rc=%d\n", rc);
+ goto parse_fail;
+ }
+
+ rc = dsi_panel_parse_cmd_sets(prv_info, child_np);
+ if (rc) {
+ pr_err("failed to parse command sets, rc=%d\n", rc);
+ goto parse_fail;
+ }
+
+ rc = dsi_panel_parse_jitter_config(mode, child_np);
+ if (rc)
+ pr_err(
+ "failed to parse panel jitter config, rc=%d\n", rc);
+
+ rc = dsi_panel_parse_phy_timing(mode, child_np);
+ if (rc) {
+ pr_err(
+ "failed to parse panel phy timings, rc=%d\n", rc);
+ goto parse_fail;
+ }
+ }
+ goto done;
+
+parse_fail:
+ kfree(mode->priv_info);
+ mode->priv_info = NULL;
+done:
mutex_unlock(&panel->panel_lock);
return rc;
}
@@ -2669,11 +2816,11 @@
mutex_lock(&panel->panel_lock);
- config->panel_mode = panel->mode.panel_mode;
+ config->panel_mode = panel->panel_mode;
memcpy(&config->common_config, &panel->host_config,
sizeof(config->common_config));
- if (mode->panel_mode == DSI_OP_VIDEO_MODE) {
+ if (panel->panel_mode == DSI_OP_VIDEO_MODE) {
memcpy(&config->u.video_engine, &panel->video_config,
sizeof(config->u.video_engine));
} else {
@@ -2683,8 +2830,8 @@
memcpy(&config->video_timing, &mode->timing,
sizeof(config->video_timing));
- config->video_timing.dsc_enabled = panel->dsc_enabled;
- config->video_timing.dsc = &panel->dsc;
+ config->video_timing.dsc_enabled = mode->priv_info->dsc_enabled;
+ config->video_timing.dsc = &mode->priv_info->dsc;
config->esc_clk_rate_hz = 19200000;
mutex_unlock(&panel->panel_lock);
@@ -2721,17 +2868,20 @@
{
int rc = 0;
struct dsi_panel_cmd_set *set = NULL;
+ struct dsi_display_mode_priv_info *priv_info = NULL;
- if (!panel) {
+ if (!panel || !panel->cur_mode) {
pr_err("invalid params\n");
return -EINVAL;
}
mutex_lock(&panel->panel_lock);
- set = &panel->cmd_sets[DSI_CMD_SET_PPS];
+ priv_info = panel->cur_mode->priv_info;
- dsi_dsc_create_pps_buf_cmd(&panel->dsc, panel->dsc_pps_cmd, 0);
+ set = &priv_info->cmd_sets[DSI_CMD_SET_PPS];
+
+ dsi_dsc_create_pps_buf_cmd(&priv_info->dsc, panel->dsc_pps_cmd, 0);
rc = dsi_panel_create_cmd_packets(panel->dsc_pps_cmd,
DSI_CMD_PPS_SIZE, 1, set->cmds);
if (rc) {
@@ -2837,11 +2987,11 @@
return rc;
}
-static int dsi_panel_roi_prepare_dcs_cmds(struct dsi_panel *panel,
+static int dsi_panel_roi_prepare_dcs_cmds(struct dsi_panel_cmd_set *set,
struct dsi_rect *roi, int ctrl_idx, int unicast)
{
static const int ROI_CMD_LEN = 5;
- struct dsi_panel_cmd_set *set = &panel->cmd_sets[DSI_CMD_SET_ROI];
+
int rc = 0;
/* DTYPE_DCS_LWRITE */
@@ -2916,13 +3066,18 @@
struct dsi_rect *roi)
{
int rc = 0;
+ struct dsi_panel_cmd_set *set;
+ struct dsi_display_mode_priv_info *priv_info;
- if (!panel) {
+ if (!panel || !panel->cur_mode) {
pr_err("Invalid params\n");
return -EINVAL;
}
- rc = dsi_panel_roi_prepare_dcs_cmds(panel, roi, ctrl_idx, true);
+ priv_info = panel->cur_mode->priv_info;
+ set = &priv_info->cmd_sets[DSI_CMD_SET_ROI];
+
+ rc = dsi_panel_roi_prepare_dcs_cmds(set, roi, ctrl_idx, true);
if (rc) {
pr_err("[%s] failed to prepare DSI_CMD_SET_ROI cmds, rc=%d\n",
panel->name, rc);
@@ -2940,11 +3095,51 @@
mutex_unlock(&panel->panel_lock);
- dsi_panel_destroy_cmd_packets(&panel->cmd_sets[DSI_CMD_SET_ROI]);
+ dsi_panel_destroy_cmd_packets(set);
return rc;
}
+int dsi_panel_switch(struct dsi_panel *panel)
+{
+ int rc = 0;
+
+ if (!panel) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&panel->panel_lock);
+
+ rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_TIMING_SWITCH);
+ if (rc)
+ pr_err("[%s] failed to send DSI_CMD_SET_TIMING_SWITCH cmds, rc=%d\n",
+ panel->name, rc);
+
+ mutex_unlock(&panel->panel_lock);
+ return rc;
+}
+
+int dsi_panel_post_switch(struct dsi_panel *panel)
+{
+ int rc = 0;
+
+ if (!panel) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&panel->panel_lock);
+
+ rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_TIMING_SWITCH);
+ if (rc)
+ pr_err("[%s] failed to send DSI_CMD_SET_POST_TIMING_SWITCH cmds, rc=%d\n",
+ panel->name, rc);
+
+ mutex_unlock(&panel->panel_lock);
+ return rc;
+}
+
int dsi_panel_enable(struct dsi_panel *panel)
{
int rc = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
index ef9bb0c..0ee23f3 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/leds.h>
#include <drm/drm_panel.h>
-#include <drm/drm_mipi_dsi.h>
#include <drm/msm_drm.h>
#include "dsi_defs.h"
@@ -33,6 +32,8 @@
#define MAX_BL_LEVEL 4096
#define DSI_CMD_PPS_SIZE 135
+#define DSI_MODE_MAX 5
+
enum dsi_panel_rotation {
DSI_PANEL_ROTATE_NONE = 0,
DSI_PANEL_ROTATE_HV_FLIP,
@@ -40,35 +41,6 @@
DSI_PANEL_ROTATE_V_FLIP
};
-enum dsi_cmd_set_type {
- DSI_CMD_SET_PRE_ON = 0,
- DSI_CMD_SET_ON,
- DSI_CMD_SET_POST_ON,
- DSI_CMD_SET_PRE_OFF,
- DSI_CMD_SET_OFF,
- DSI_CMD_SET_POST_OFF,
- DSI_CMD_SET_PRE_RES_SWITCH,
- DSI_CMD_SET_RES_SWITCH,
- DSI_CMD_SET_POST_RES_SWITCH,
- DSI_CMD_SET_CMD_TO_VID_SWITCH,
- DSI_CMD_SET_POST_CMD_TO_VID_SWITCH,
- DSI_CMD_SET_VID_TO_CMD_SWITCH,
- DSI_CMD_SET_POST_VID_TO_CMD_SWITCH,
- DSI_CMD_SET_PANEL_STATUS,
- DSI_CMD_SET_LP1,
- DSI_CMD_SET_LP2,
- DSI_CMD_SET_NOLP,
- DSI_CMD_SET_PPS,
- DSI_CMD_SET_ROI,
- DSI_CMD_SET_MAX
-};
-
-enum dsi_cmd_set_state {
- DSI_CMD_SET_STATE_LP = 0,
- DSI_CMD_SET_STATE_HS,
- DSI_CMD_SET_STATE_MAX
-};
-
enum dsi_backlight_type {
DSI_BACKLIGHT_PWM = 0,
DSI_BACKLIGHT_WLED,
@@ -85,6 +57,11 @@
MODE_GPIO_LOW,
};
+enum dsi_dms_mode {
+ DSI_DMS_MODE_DISABLED = 0,
+ DSI_DMS_MODE_RES_SWITCH_IMMEDIATE,
+};
+
struct dsi_dfps_capabilities {
bool dfps_support;
enum dsi_dfps_type type;
@@ -104,20 +81,6 @@
enum dsi_panel_rotation rotation;
};
-struct dsi_cmd_desc {
- struct mipi_dsi_msg msg;
- bool last_command;
- u32 post_wait_ms;
-};
-
-struct dsi_panel_cmd_set {
- enum dsi_cmd_set_type type;
- enum dsi_cmd_set_state state;
- u32 count;
- int ctrl_idx;
- struct dsi_cmd_desc *cmds;
-};
-
struct dsi_backlight_config {
enum dsi_backlight_type type;
@@ -165,19 +128,17 @@
struct dsi_host_common_cfg host_config;
struct dsi_video_engine_cfg video_config;
struct dsi_cmd_engine_cfg cmd_config;
+ enum dsi_op_mode panel_mode;
struct dsi_dfps_capabilities dfps_caps;
struct msm_roi_caps roi_caps;
- struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX];
struct dsi_panel_phy_props phy_props;
- u32 *phy_timing_val;
- u32 phy_timing_len;
+ struct dsi_display_mode *cur_mode;
+ u32 num_timing_nodes;
struct dsi_regulator_info power_info;
- struct dsi_display_mode mode;
-
struct dsi_backlight_config bl_config;
struct dsi_panel_reset_config reset_config;
struct dsi_pinctrl_info pinctrl;
@@ -187,15 +148,11 @@
bool ulps_enabled;
bool allow_phy_power_off;
- u32 panel_jitter_numer;
- u32 panel_jitter_denom;
- u32 panel_prefill_lines;
bool panel_initialized;
bool te_using_watchdog_timer;
- bool dsc_enabled;
char dsc_pps_cmd[DSI_CMD_PPS_SIZE];
- struct msm_display_dsc_info dsc;
+ enum dsi_dms_mode dms_mode;
};
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
@@ -211,17 +168,26 @@
struct dsi_panel *dsi_panel_get(struct device *parent,
struct device_node *of_node,
int topology_override);
+
void dsi_panel_put(struct dsi_panel *panel);
int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);
+
int dsi_panel_drv_deinit(struct dsi_panel *panel);
-int dsi_panel_get_mode_count(struct dsi_panel *panel, u32 *count);
+int dsi_panel_get_mode_count(struct dsi_panel *panel,
+ struct device_node *of_node);
+
+void dsi_panel_put_mode(struct dsi_display_mode *mode);
+
int dsi_panel_get_mode(struct dsi_panel *panel,
u32 index,
- struct dsi_display_mode *mode);
+ struct dsi_display_mode *mode,
+ int topology_override);
+
int dsi_panel_validate_mode(struct dsi_panel *panel,
struct dsi_display_mode *mode);
+
int dsi_panel_get_host_cfg_for_mode(struct dsi_panel *panel,
struct dsi_display_mode *mode,
struct dsi_host_config *config);
@@ -260,6 +226,10 @@
int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx,
struct dsi_rect *roi);
+int dsi_panel_switch(struct dsi_panel *panel);
+
+int dsi_panel_post_switch(struct dsi_panel *panel);
+
void dsi_dsc_pclk_param_calc(struct msm_display_dsc_info *dsc, int intf_width);
#endif /* _DSI_PANEL_H_ */
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index efeea31..5a48aae 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -131,6 +131,10 @@
&connector->encoder->crtc->state->mode))
continue;
+ if (msm_is_mode_seamless_dms(
+ &connector->encoder->crtc->state->adjusted_mode))
+ continue;
+
funcs = encoder->helper_private;
DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
@@ -166,6 +170,9 @@
if (msm_is_mode_seamless(&crtc->state->mode))
continue;
+ if (msm_is_mode_seamless_dms(&crtc->state->adjusted_mode))
+ continue;
+
funcs = crtc->helper_private;
DRM_DEBUG_ATOMIC("disabling [CRTC:%d]\n",
@@ -303,6 +310,13 @@
if (msm_is_mode_seamless(&crtc->state->mode))
continue;
+ /**
+ * On DMS switch, wait for ping pong done to ensure the current
+ * frame transfer is complete.
+ */
+ if (msm_is_mode_seamless_dms(&crtc->state->adjusted_mode))
+ kms->funcs->wait_for_tx_complete(kms, crtc);
+
funcs = crtc->helper_private;
if (crtc->state->enable) {
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 5b8a6b8..2f665a4 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -387,10 +387,22 @@
/**
* struct msm_mode_info - defines all msm custom mode info
- * @topology - supported topology for the mode
+ * @frame_rate: frame_rate of the mode
+ * @vtotal: vtotal calculated for the mode
+ * @prefill_lines: prefill lines based on porches.
+ * @jitter_numer: display panel jitter numerator configuration
+ * @jitter_denom: display panel jitter denominator configuration
+ * @topology: supported topology for the mode
+ * @comp_info: compression info supported
*/
struct msm_mode_info {
+ uint32_t frame_rate;
+ uint32_t vtotal;
+ uint32_t prefill_lines;
+ uint32_t jitter_numer;
+ uint32_t jitter_denom;
struct msm_display_topology topology;
+ struct msm_compression_info comp_info;
};
/**
@@ -410,12 +422,6 @@
* @is_primary: Set to true if display is primary display
* @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is
* used instead of panel TE in cmd mode panels
- * @frame_rate: Display frame rate
- * @prefill_lines: prefill lines based on porches.
- * @vtotal: display vertical total
- * @jitter_numer: display panel jitter numerator configuration
- * @jitter_denom: display panel jitter denominator configuration
- * @comp_info: Compression supported by the display
* @roi_caps: Region of interest capability info
*/
struct msm_display_info {
@@ -435,13 +441,6 @@
bool is_primary;
bool is_te_using_watchdog_timer;
- uint32_t frame_rate;
- uint32_t prefill_lines;
- uint32_t vtotal;
- uint32_t jitter_numer;
- uint32_t jitter_denom;
-
- struct msm_compression_info comp_info;
struct msm_roi_caps roi_caps;
};
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 8d727fe..c695dda 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -31,11 +31,14 @@
#define BO_PINNED 0x2000
static struct msm_gem_submit *submit_create(struct drm_device *dev,
- struct msm_gpu *gpu, int nr_bos, int nr_cmds)
+ struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds)
{
struct msm_gem_submit *submit;
- int sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) +
- (nr_cmds * sizeof(*submit->cmd));
+ uint64_t sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) +
+ (nr_cmds * sizeof(submit->cmd[0]));
+
+ if (sz > SIZE_MAX)
+ return NULL;
submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
if (!submit)
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 0375979..e7fae38 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -34,6 +34,8 @@
#define MSM_MODE_FLAG_SEAMLESS_DYNAMIC_FPS (1<<0)
/* Transition to new mode requires a wait-for-vblank before the modeset */
#define MSM_MODE_FLAG_VBLANK_PRE_MODESET (1<<1)
+/* Request to switch the connector mode */
+#define MSM_MODE_FLAG_SEAMLESS_DMS (1<<2)
/* As there are different display controller blocks depending on the
* snapdragon version, the kms support is split out and the appropriate
@@ -146,6 +148,12 @@
return (mode->flags & DRM_MODE_FLAG_SEAMLESS);
}
+static inline bool msm_is_mode_seamless_dms(const struct drm_display_mode *mode)
+{
+ return mode ? (mode->private_flags & MSM_MODE_FLAG_SEAMLESS_DMS)
+ : false;
+}
+
static inline bool msm_is_mode_dynamic_fps(const struct drm_display_mode *mode)
{
return ((mode->flags & DRM_MODE_FLAG_SEAMLESS) &&
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index f5e2ada..3af8278 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -427,6 +427,9 @@
c_conn = to_sde_connector(connector);
+ if (c_conn->ops.put_modes)
+ c_conn->ops.put_modes(connector, c_conn->display);
+
if (c_conn->blob_caps)
drm_property_unreference_blob(c_conn->blob_caps);
if (c_conn->blob_hdr)
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 1b594cd..4747d3a 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -65,6 +65,14 @@
void *display);
/**
+ * put_modes - free up drm modes of the connector
+ * @connector: Pointer to drm connector structure
+ * @display: Pointer to private display handle
+ */
+ void (*put_modes)(struct drm_connector *connector,
+ void *display);
+
+ /**
* update_pps - update pps command for the display panel
* @pps_cmd: Pointer to pps command
* @display: Pointer to private display handle
@@ -122,14 +130,14 @@
int (*get_info)(struct msm_display_info *info, void *display);
/**
- * get_topology - retrieve current topology for the mode selected
+ * get_mode_info - retrieve mode information
* @drm_mode: Display mode set for the display
- * @topology: Out parameter. Topology for the mode.
+ * @mode_info: Out parameter. information of the display mode
* @max_mixer_width: max width supported by HW layer mixer
* Returns: Zero on success
*/
- int (*get_topology)(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology,
+ int (*get_mode_info)(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info,
u32 max_mixer_width);
/**
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index d41ddec..4ba2b75 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -160,6 +160,7 @@
* @rsc_client: rsc client pointer
* @rsc_state_init: boolean to indicate rsc config init
* @disp_info: local copy of msm_display_info struct
+ * @mode_info: local copy of msm_mode_info struct
* @misr_enable: misr enable/disable status
* @idle_pc_supported: indicate if idle power collaps is supported
* @rc_lock: resource control mutex lock to protect
@@ -203,6 +204,7 @@
struct sde_rsc_client *rsc_client;
bool rsc_state_init;
struct msm_display_info disp_info;
+ struct msm_mode_info mode_info;
bool misr_enable;
bool idle_pc_supported;
@@ -229,7 +231,7 @@
return false;
sde_enc = to_sde_encoder_virt(drm_enc);
- comp_info = &sde_enc->disp_info.comp_info;
+ comp_info = &sde_enc->mode_info.comp_info;
return (comp_info->comp_type == MSM_DISPLAY_COMPRESSION_DSC);
}
@@ -512,7 +514,7 @@
phys->ops.get_hw_resources(phys, hw_res, conn_state);
}
- hw_res->topology = sde_enc->topology;
+ hw_res->topology = sde_enc->mode_info.topology;
}
void sde_encoder_destroy(struct drm_encoder *drm_enc)
@@ -636,7 +638,7 @@
cur_mode->hdisplay == adj_mode->hdisplay &&
cur_mode->vrefresh == adj_mode->vrefresh) {
adj_mode->private = cur_mode->private;
- adj_mode->private_flags = cur_mode->private_flags;
+ adj_mode->private_flags |= cur_mode->private_flags;
}
}
}
@@ -874,7 +876,7 @@
struct sde_encoder_phys *enc_master = sde_enc->cur_master;
const struct sde_rect *roi = &sde_enc->cur_conn_roi;
struct msm_display_dsc_info *dsc =
- &sde_enc->disp_info.comp_info.dsc_info;
+ &sde_enc->mode_info.comp_info.dsc_info;
if (dsc == NULL || hw_dsc == NULL || hw_pp == NULL || !enc_master) {
SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n");
@@ -939,8 +941,8 @@
if (enc_master->intf_mode == INTF_MODE_VIDEO)
dsc_common_mode |= DSC_MODE_VIDEO;
- memcpy(&dsc[0], &sde_enc->disp_info.comp_info.dsc_info, sizeof(dsc[0]));
- memcpy(&dsc[1], &sde_enc->disp_info.comp_info.dsc_info, sizeof(dsc[1]));
+ memcpy(&dsc[0], &sde_enc->mode_info.comp_info.dsc_info, sizeof(dsc[0]));
+ memcpy(&dsc[1], &sde_enc->mode_info.comp_info.dsc_info, sizeof(dsc[1]));
/*
* Since both DSC use same pic dimension, set same pic dimension
@@ -1004,7 +1006,7 @@
struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
struct msm_display_dsc_info *dsc =
- &sde_enc->disp_info.comp_info.dsc_info;
+ &sde_enc->mode_info.comp_info.dsc_info;
bool half_panel_partial_update;
int i;
@@ -1140,6 +1142,7 @@
struct sde_kms *sde_kms;
struct sde_hw_mdp *hw_mdptop;
struct drm_encoder *drm_enc;
+ struct msm_mode_info *mode_info;
int i;
if (!sde_enc || !disp_info) {
@@ -1169,13 +1172,19 @@
return;
}
+ mode_info = &sde_enc->mode_info;
+ if (!mode_info) {
+ SDE_ERROR("invalid mode info\n");
+ return;
+ }
+
if (hw_mdptop->ops.setup_vsync_source &&
disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) {
for (i = 0; i < sde_enc->num_phys_encs; i++)
vsync_cfg.ppnumber[i] = sde_enc->hw_pp[i]->idx;
vsync_cfg.pp_count = sde_enc->num_phys_encs;
- vsync_cfg.frame_rate = sde_enc->disp_info.frame_rate;
+ vsync_cfg.frame_rate = mode_info->frame_rate;
if (is_dummy)
vsync_cfg.vsync_source = SDE_VSYNC_SOURCE_WD_TIMER_1;
else if (disp_info->is_te_using_watchdog_timer)
@@ -1197,6 +1206,7 @@
struct sde_rsc_cmd_config rsc_config;
int ret;
struct msm_display_info *disp_info;
+ struct msm_mode_info *mode_info;
if (!drm_enc) {
SDE_ERROR("invalid encoder\n");
@@ -1205,6 +1215,7 @@
sde_enc = to_sde_encoder_virt(drm_enc);
disp_info = &sde_enc->disp_info;
+ mode_info = &sde_enc->mode_info;
if (!sde_enc->rsc_client) {
SDE_DEBUG("rsc client not created\n");
@@ -1227,11 +1238,11 @@
if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_init
&& disp_info->is_primary) {
- rsc_config.fps = disp_info->frame_rate;
- rsc_config.vtotal = disp_info->vtotal;
- rsc_config.prefill_lines = disp_info->prefill_lines;
- rsc_config.jitter_numer = disp_info->jitter_numer;
- rsc_config.jitter_denom = disp_info->jitter_denom;
+ rsc_config.fps = mode_info->frame_rate;
+ rsc_config.vtotal = mode_info->vtotal;
+ rsc_config.prefill_lines = mode_info->prefill_lines;
+ rsc_config.jitter_numer = mode_info->jitter_numer;
+ rsc_config.jitter_denom = mode_info->jitter_denom;
rsc_config.prefill_lines += config ?
config->inline_rotate_prefill : 0;
/* update it only once */
@@ -1647,7 +1658,7 @@
sde_conn = to_sde_connector(conn);
if (sde_conn) {
- ret = sde_conn->ops.get_topology(adj_mode, &sde_enc->topology,
+ ret = sde_conn->ops.get_mode_info(adj_mode, &sde_enc->mode_info,
sde_kms->catalog->max_mixer_width);
if (ret) {
SDE_ERROR_ENC(sde_enc,
@@ -1764,16 +1775,21 @@
{
struct sde_encoder_virt *sde_enc = NULL;
int i, ret = 0;
+ struct msm_compression_info *comp_info = NULL;
+ struct drm_display_mode *cur_mode = NULL;
if (!drm_enc) {
SDE_ERROR("invalid encoder\n");
return;
}
sde_enc = to_sde_encoder_virt(drm_enc);
+ comp_info = &sde_enc->mode_info.comp_info;
SDE_DEBUG_ENC(sde_enc, "\n");
SDE_EVT32(DRMID(drm_enc));
+ cur_mode = &sde_enc->base.crtc->state->adjusted_mode;
+
sde_enc->cur_master = NULL;
for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
@@ -1800,11 +1816,28 @@
for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
- if (phys && (phys != sde_enc->cur_master) && phys->ops.enable)
- phys->ops.enable(phys);
+ if (!phys)
+ continue;
+
+ phys->comp_type = comp_info->comp_type;
+ if (phys != sde_enc->cur_master) {
+ /**
+ * on DMS request, the encoder will be enabled
+ * already. Invoke restore to reconfigure the
+ * new mode.
+ */
+ if (msm_is_mode_seamless_dms(cur_mode) &&
+ phys->ops.restore)
+ phys->ops.restore(phys);
+ else if (phys->ops.enable)
+ phys->ops.enable(phys);
+ }
}
- if (sde_enc->cur_master->ops.enable)
+ if (msm_is_mode_seamless_dms(cur_mode) &&
+ sde_enc->cur_master->ops.restore)
+ sde_enc->cur_master->ops.restore(sde_enc->cur_master);
+ else if (sde_enc->cur_master->ops.enable)
sde_enc->cur_master->ops.enable(sde_enc->cur_master);
_sde_encoder_virt_enable_helper(drm_enc);
@@ -3000,8 +3033,6 @@
SDE_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles);
- phys_params.comp_type = disp_info->comp_info.comp_type;
-
if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
sde_enc->idle_pc_supported = sde_kms->catalog->has_idle_pc;
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 ad00a7f..fc723a6 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -722,6 +722,9 @@
tc_cfg.vsync_count = vsync_hz / (mode->vtotal * mode->vrefresh);
+ /* enable external TE after kickoff to avoid premature autorefresh */
+ tc_cfg.hw_vsync_mode = 0;
+
/*
* By setting sync_cfg_height to near max register value, we essentially
* disable sde hw generated TE signal, since hw TE will arrive first.
@@ -733,7 +736,6 @@
tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE;
tc_cfg.start_pos = mode->vdisplay;
tc_cfg.rd_ptr_irq = mode->vdisplay + 1;
- tc_cfg.hw_vsync_mode = true;
SDE_DEBUG_CMDENC(cmd_enc,
"tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n",
@@ -862,6 +864,17 @@
return cfg.enable;
}
+static void _sde_encoder_phys_cmd_connect_te(
+ struct sde_encoder_phys *phys_enc, bool enable)
+{
+ if (!phys_enc || !phys_enc->hw_pp ||
+ !phys_enc->hw_pp->ops.connect_external_te)
+ return;
+
+ SDE_EVT32(DRMID(phys_enc->parent), enable);
+ phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
+}
+
static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_cmd *cmd_enc =
@@ -1132,6 +1145,19 @@
SDE_DEBUG_CMDENC(cmd_enc, "disabled autorefresh\n");
}
+static void sde_encoder_phys_cmd_handle_post_kickoff(
+ struct sde_encoder_phys *phys_enc)
+{
+ if (!phys_enc)
+ return;
+
+ /**
+ * re-enable external TE, either for the first time after enabling
+ * or if disabled for Autorefresh
+ */
+ _sde_encoder_phys_cmd_connect_te(phys_enc, true);
+}
+
static void sde_encoder_phys_cmd_trigger_start(
struct sde_encoder_phys *phys_enc)
{
@@ -1175,6 +1201,7 @@
ops->restore = sde_encoder_phys_cmd_enable_helper;
ops->is_autorefresh_enabled =
sde_encoder_phys_cmd_is_autorefresh_enabled;
+ ops->handle_post_kickoff = sde_encoder_phys_cmd_handle_post_kickoff;
}
struct sde_encoder_phys *sde_encoder_phys_cmd_init(
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
index e844bc0..e88f40f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
@@ -231,6 +231,29 @@
return 0;
}
+static int sde_hw_pp_connect_external_te(struct sde_hw_pingpong *pp,
+ bool enable_external_te)
+{
+ struct sde_hw_blk_reg_map *c = &pp->hw;
+ u32 cfg;
+ int orig;
+
+ if (!pp)
+ return -EINVAL;
+
+ c = &pp->hw;
+ cfg = SDE_REG_READ(c, PP_SYNC_CONFIG_VSYNC);
+ orig = (bool)(cfg & BIT(20));
+ if (enable_external_te)
+ cfg |= BIT(20);
+ else
+ cfg &= ~BIT(20);
+ SDE_REG_WRITE(c, PP_SYNC_CONFIG_VSYNC, cfg);
+ SDE_EVT32(pp->idx - PINGPONG_0, cfg);
+
+ return orig;
+}
+
static int sde_hw_pp_get_vsync_info(struct sde_hw_pingpong *pp,
struct sde_hw_pp_vsync_info *info)
{
@@ -257,6 +280,7 @@
ops->setup_tearcheck = sde_hw_pp_setup_te_config;
ops->enable_tearcheck = sde_hw_pp_enable_te;
+ ops->connect_external_te = sde_hw_pp_connect_external_te;
ops->get_vsync_info = sde_hw_pp_get_vsync_info;
ops->setup_autorefresh = sde_hw_pp_setup_autorefresh_config;
ops->setup_dsc = sde_hw_pp_setup_dsc;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
index 4f27ff5..f0a2054 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
@@ -80,6 +80,13 @@
bool enable);
/**
+ * read, modify, write to either set or clear listening to external TE
+ * @Return: 1 if TE was originally connected, 0 if not, or -ERROR
+ */
+ int (*connect_external_te)(struct sde_hw_pingpong *pp,
+ bool enable_external_te);
+
+ /**
* provides the programmed and current
* line_count
*/
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 8747288..8dd6448 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -635,6 +635,7 @@
.post_init = dsi_conn_post_init,
.detect = dsi_conn_detect,
.get_modes = dsi_connector_get_modes,
+ .put_modes = dsi_connector_put_modes,
.mode_valid = dsi_conn_mode_valid,
.get_info = dsi_display_get_info,
.set_backlight = dsi_display_set_backlight,
@@ -642,8 +643,8 @@
.pre_kickoff = dsi_conn_pre_kickoff,
.clk_ctrl = dsi_display_clk_ctrl,
.set_power = dsi_display_set_power,
- .get_topology = dsi_conn_get_topology,
- .get_dst_format = dsi_display_get_dst_format
+ .get_mode_info = dsi_conn_get_mode_info,
+ .get_dst_format = dsi_display_get_dst_format,
};
static const struct sde_connector_ops wb_ops = {
.post_init = sde_wb_connector_post_init,
@@ -652,7 +653,7 @@
.set_property = sde_wb_connector_set_property,
.get_info = sde_wb_get_info,
.soft_reset = NULL,
- .get_topology = sde_wb_get_topology,
+ .get_mode_info = sde_wb_get_mode_info,
.get_dst_format = NULL
};
static const struct sde_connector_ops dp_ops = {
@@ -661,7 +662,7 @@
.get_modes = dp_connector_get_modes,
.mode_valid = dp_connector_mode_valid,
.get_info = dp_connector_get_info,
- .get_topology = dp_connector_get_topology,
+ .get_mode_info = dp_connector_get_mode_info,
};
struct msm_display_info info;
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.c b/drivers/gpu/drm/msm/sde/sde_wb.c
index ceda16e..145acea 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_wb.c
@@ -283,28 +283,31 @@
wb_dev->wb_cfg->sblk->maxlinewidth :
SDE_WB_MODE_MAX_WIDTH;
info->max_height = SDE_WB_MODE_MAX_HEIGHT;
- info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
return 0;
}
-int sde_wb_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology, u32 max_mixer_width)
+int sde_wb_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info, u32 max_mixer_width)
{
const u32 dual_lm = 2;
const u32 single_lm = 1;
const u32 single_intf = 1;
const u32 no_enc = 0;
+ struct msm_display_topology *topology;
- if (!drm_mode || !topology || !max_mixer_width) {
+ if (!drm_mode || !mode_info || !max_mixer_width) {
pr_err("invalid params\n");
return -EINVAL;
}
+ topology = &mode_info->topology;
topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ?
dual_lm : single_lm;
topology->num_enc = no_enc;
topology->num_intf = single_intf;
+ mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE;
+
return 0;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.h b/drivers/gpu/drm/msm/sde/sde_wb.h
index 205ff24..aa57d3e 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.h
+++ b/drivers/gpu/drm/msm/sde/sde_wb.h
@@ -186,15 +186,14 @@
int sde_wb_get_info(struct msm_display_info *info, void *display);
/**
- * sde_wb_get_topology - retrieve current topology for the mode selected
+ * sde_wb_get_mode_info - retrieve information of the mode selected
* @drm_mode: Display mode set for the display
- * @topology: Out parameter. Topology for the mode.
+ * @mode_info: Out parameter. information of the mode.
* @max_mixer_width: max width supported by HW layer mixer
* Returns: zero on success
*/
-int sde_wb_get_topology(const struct drm_display_mode *drm_mode,
- struct msm_display_topology *topology,
- u32 max_mixer_width);
+int sde_wb_get_mode_info(const struct drm_display_mode *drm_mode,
+ struct msm_mode_info *mode_info, u32 max_mixer_width);
/**
* sde_wb_connector_get_wb - retrieve writeback device of the given connector
diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h
index 368207d..431a67e 100644
--- a/drivers/gpu/msm/a6xx_reg.h
+++ b/drivers/gpu/msm/a6xx_reg.h
@@ -816,6 +816,7 @@
#define A6XX_GMU_DCVS_PERF_SETTING 0x1CBFD
#define A6XX_GMU_DCVS_BW_SETTING 0x1CBFE
#define A6XX_GMU_DCVS_RETURN 0x1CBFF
+#define A6XX_GMU_SYS_BUS_CONFIG 0x1F40F
#define A6XX_GMU_CM3_SYSRESET 0x1F800
#define A6XX_GMU_CM3_BOOT_CONFIG 0x1F801
#define A6XX_GMU_CM3_FW_BUSY 0x1F81A
@@ -874,11 +875,46 @@
#define A6XX_GMU_HOST2GMU_INTR_INFO_1 0x1F99C
#define A6XX_GMU_HOST2GMU_INTR_INFO_2 0x1F99D
#define A6XX_GMU_HOST2GMU_INTR_INFO_3 0x1F99E
+#define A6XX_GMU_GENERAL_1 0x1F9C6
#define A6XX_GMU_GENERAL_7 0x1F9CC
/* ISENSE registers */
#define A6XX_GMU_ISENSE_CTRL 0x1F95D
#define A6XX_GPU_CS_ENABLE_REG 0x23120
+#define A6XX_GPU_GMU_CX_GMU_ISENSE_CTRL 0x1f95d
+#define A6XX_GPU_CS_AMP_CALIBRATION_CONTROL3 0x22d78
+#define A6XX_GPU_CS_AMP_CALIBRATION_CONTROL2 0x22d58
+#define A6XX_GPU_CS_A_SENSOR_CTRL_0 0x22d80
+#define A6XX_GPU_CS_A_SENSOR_CTRL_2 0x422da
+#define A6XX_GPU_CS_SENSOR_GENERAL_STATUS 0x2301a
+#define A6XX_GPU_CS_AMP_CALIBRATION_CONTROL1 0x23157
+#define A6XX_GPU_CS_SENSOR_GENERAL_STATUS 0x2301a
+#define A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_0 0x2301d
+#define A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_2 0x2301f
+#define A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_4 0x23021
+#define A6XX_GPU_CS_AMP_CALIBRATION_DONE 0x23165
+#define A6XX_GPU_CS_AMP_PERIOD_CTRL 0x2316d
+#define A6XX_GPU_CS_AMP_CALIBRATION_DONE 0x23165
+
+#define CS_PWR_ON_STATUS (10)
+#define AMP_SW_WRM_TRIM_START (24)
+#define AMP_TRIM_TIMER (6)
+#define AMP_SW_TRIM_START (0)
+#define SS_AMPTRIM_DONE (11)
+#define AMP_OFFSET_CHECK_MIN_ERR (1)
+#define AMP_OFFSET_CHECK_MAX_ERR (2)
+#define AMP_OUT_OF_RANGE_ERR (4)
+#define TRIM_CNT_VALUE (1)
+#define RUNTIME_CNT_VALUE (16)
+#define TRIM_ENABLE (0)
+
+#define AMP_ERR (BIT(AMP_OFFSET_CHECK_MIN_ERR) || \
+ BIT(AMP_OFFSET_CHECK_MAX_ERR) || \
+ BIT(AMP_OUT_OF_RANGE_ERR))
+
+/* LM registers */
+#define A6XX_GPU_GMU_CX_GMU_PWR_THRESHOLD 0x1F94D
+
#define A6XX_GMU_AO_INTERRUPT_EN 0x23B03
#define A6XX_GMU_AO_HOST_INTERRUPT_CLR 0x23B04
@@ -905,6 +941,7 @@
/* GPUCC registers */
#define A6XX_GPU_CC_GX_GDSCR 0x24403
+#define A6XX_GPU_CC_GX_DOMAIN_MISC 0x24542
/* GPU RSC sequencer registers */
#define A6XX_RSCC_PDC_SEQ_START_ADDR 0x23408
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index f8bf780..7dda62a 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -327,7 +327,7 @@
.minor = 0,
.patchid = ANY_ID,
.features = ADRENO_64BIT | ADRENO_RPMH |
- ADRENO_GPMU | ADRENO_CONTENT_PROTECTION,
+ ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_LM,
.sqefw_name = "a630_sqe.fw",
.zap_name = "a630_zap",
.gpudev = &adreno_a6xx_gpudev,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 4900b3a..01b877f 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -642,6 +642,8 @@
ADRENO_REG_GMU_HOST2GMU_INTR_SET,
ADRENO_REG_GMU_HOST2GMU_INTR_CLR,
ADRENO_REG_GMU_HOST2GMU_INTR_RAW_INFO,
+ ADRENO_REG_GMU_NMI_CONTROL_STATUS,
+ ADRENO_REG_GMU_CM3_CFG,
ADRENO_REG_GPMU_POWER_COUNTER_ENABLE,
ADRENO_REG_REGISTER_MAX,
};
diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h
index 08fd16a..3d89d73 100644
--- a/drivers/gpu/msm/adreno_a5xx.h
+++ b/drivers/gpu/msm/adreno_a5xx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 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
@@ -151,24 +151,6 @@
#define GPMU_ISENSE_STATUS GENMASK(3, 0)
#define GPMU_ISENSE_END_POINT_CAL_ERR BIT(0)
-/* A5XX_GPU_CS_AMP_CALIBRATION_CONTROL1 */
-#define AMP_SW_TRIM_START BIT(0)
-
-/* A5XX_GPU_CS_SENSOR_GENERAL_STATUS */
-#define SS_AMPTRIM_DONE BIT(11)
-#define CS_PWR_ON_STATUS BIT(10)
-
-/* A5XX_GPU_CS_AMP_CALIBRATION_STATUS*_* */
-#define AMP_OUT_OF_RANGE_ERR BIT(4)
-#define AMP_OFFSET_CHECK_MAX_ERR BIT(2)
-#define AMP_OFFSET_CHECK_MIN_ERR BIT(1)
-
-/* A5XX_GPU_CS_AMP_CALIBRATION_DONE */
-#define SW_OPAMP_CAL_DONE BIT(0)
-
-#define AMP_CALIBRATION_ERR (AMP_OFFSET_CHECK_MIN_ERR | \
- AMP_OFFSET_CHECK_MAX_ERR | AMP_OUT_OF_RANGE_ERR)
-
#define AMP_CALIBRATION_RETRY_CNT 3
#define AMP_CALIBRATION_TIMEOUT 6
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index c1d2407..5551cea 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -357,7 +357,22 @@
/* enable top level HWCG */
kgsl_regwrite(device, A6XX_RBBM_CLOCK_CNTL, on ? 0x8AA8AA02 : 0);
- kgsl_regwrite(device, A5XX_RBBM_ISDB_CNT, on ? 0x00000182 : 0x00000180);
+}
+
+#define LM_DEFAULT_LIMIT 6000
+
+static uint32_t lm_limit(struct adreno_device *adreno_dev)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+
+ if (adreno_dev->lm_limit)
+ return adreno_dev->lm_limit;
+
+ if (of_property_read_u32(device->pdev->dev.of_node, "qcom,lm-limit",
+ &adreno_dev->lm_limit))
+ adreno_dev->lm_limit = LM_DEFAULT_LIMIT;
+
+ return adreno_dev->lm_limit;
}
/*
@@ -379,6 +394,9 @@
/* enable hardware clockgating */
a6xx_hwcg_set(adreno_dev, true);
+ if (ADRENO_FEATURE(adreno_dev, ADRENO_LM))
+ adreno_dev->lm_threshold_count = A6XX_GMU_GENERAL_1;
+
adreno_vbif_start(adreno_dev, a6xx_vbif_platforms,
ARRAY_SIZE(a6xx_vbif_platforms));
@@ -904,6 +922,9 @@
/* Configure registers for idle setting. The setting is cumulative */
+ /* Disable GMU WB/RB buffer */
+ kgsl_gmu_regwrite(device, A6XX_GMU_SYS_BUS_CONFIG, 0x1);
+
kgsl_gmu_regwrite(device,
A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9C40400);
@@ -935,7 +956,8 @@
}
/* ACD feature enablement */
- if (ADRENO_FEATURE(adreno_dev, ADRENO_LM))
+ if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
+ test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
kgsl_gmu_regrmw(device, A6XX_GMU_BOOT_KMD_LM_HANDSHAKE, 0,
BIT(10));
@@ -943,9 +965,6 @@
if (ADRENO_FEATURE(adreno_dev, ADRENO_RPMH))
kgsl_gmu_regrmw(device, A6XX_GMU_RPMH_CTRL, 0,
RPMH_ENABLE_MASK);
-
- /* Disable reference bandgap voltage */
- kgsl_gmu_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1);
}
/*
@@ -1132,62 +1151,6 @@
dev_err(&gmu->pdev->dev, "power off SPTPRAC fail\n");
}
-/*
- * a6xx_hm_enable() - Power on HM and turn on clock
- * @adreno_dev: Pointer to Adreno device
- */
-static int a6xx_hm_enable(struct adreno_device *adreno_dev)
-{
- int ret;
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- struct kgsl_pwrctrl *pwr = &device->pwrctrl;
- struct gmu_device *gmu = &device->gmu;
-
- if (regulator_is_enabled(gmu->gx_gdsc))
- return 0;
-
- ret = regulator_enable(gmu->gx_gdsc);
- if (ret) {
- dev_err(&gmu->pdev->dev,
- "Failed to turn on GPU HM HS\n");
- return ret;
- }
-
- ret = clk_set_rate(pwr->grp_clks[0],
- pwr->pwrlevels[pwr->default_pwrlevel].
- gpu_freq);
- if (ret)
- return ret;
-
- return clk_prepare_enable(pwr->grp_clks[0]);
-}
-
-/*
- * a6xx_hm_disable() - Turn off HM clock and power off
- * @adreno_dev: Pointer to Adreno device
- */
-static int a6xx_hm_disable(struct adreno_device *adreno_dev)
-{
- struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
- struct kgsl_pwrctrl *pwr = &device->pwrctrl;
- struct gmu_device *gmu = &device->gmu;
-
- if (!regulator_is_enabled(gmu->gx_gdsc))
- return 0;
-
- /* Ensure that retention is on */
- kgsl_gmu_regrmw(device, A6XX_GPU_CC_GX_GDSCR, 0,
- A6XX_RETAIN_FF_ENABLE_ENABLE_MASK);
-
- clk_disable_unprepare(pwr->grp_clks[0]);
-
- clk_set_rate(pwr->grp_clks[0],
- pwr->pwrlevels[pwr->num_pwrlevels - 1].
- gpu_freq);
-
- return regulator_disable(gmu->gx_gdsc);
-}
-
#define SPTPRAC_POWER_OFF BIT(2)
#define SP_CLK_OFF BIT(4)
#define GX_GDSC_POWER_OFF BIT(6)
@@ -1239,62 +1202,6 @@
}
/*
- * a6xx_hm_sptprac_enable() - Turn on HM and SPTPRAC
- * @device: Pointer to KGSL device
- */
-static int a6xx_hm_sptprac_enable(struct kgsl_device *device)
-{
- int ret = 0;
- struct gmu_device *gmu = &device->gmu;
-
- /* If GMU does not control HM we must */
- if (gmu->idle_level < GPU_HW_IFPC) {
-
- ret = a6xx_hm_enable(ADRENO_DEVICE(device));
- if (ret) {
- dev_err(&gmu->pdev->dev, "Failed to power on GPU HM\n");
- return ret;
- }
-
-
- }
-
- /* If GMU does not control SPTPRAC we must */
- if (gmu->idle_level < GPU_HW_SPTP_PC) {
- ret = a6xx_sptprac_enable(ADRENO_DEVICE(device));
- if (ret) {
- a6xx_hm_disable(ADRENO_DEVICE(device));
- return ret;
- }
- }
-
- return ret;
-}
-
-/*
- * a6xx_hm_sptprac_disable() - Turn off SPTPRAC and HM
- * @device: Pointer to KGSL device
- */
-static int a6xx_hm_sptprac_disable(struct kgsl_device *device)
-{
- int ret = 0;
- struct gmu_device *gmu = &device->gmu;
-
- /* If GMU does not control SPTPRAC we must */
- if (gmu->idle_level < GPU_HW_SPTP_PC)
- a6xx_sptprac_disable(ADRENO_DEVICE(device));
-
- /* If GMU does not control HM we must */
- if (gmu->idle_level < GPU_HW_IFPC) {
- ret = a6xx_hm_disable(ADRENO_DEVICE(device));
- if (ret)
- dev_err(&gmu->pdev->dev, "Failed to power off GPU HM\n");
- }
-
- return ret;
-}
-
-/*
* a6xx_gfx_rail_on() - request GMU to power GPU at given OPP.
* @device: Pointer to KGSL device
*
@@ -1344,6 +1251,9 @@
/* Disable the power counter so that the GMU is not busy */
kgsl_gmu_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0);
+ /* Turn off SPTPRAC before GMU turns off GX */
+ a6xx_sptprac_disable(adreno_dev);
+
if (!ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG)) {
ret = hfi_notify_slumber(gmu, perf_idx, bus_level);
return ret;
@@ -1379,7 +1289,10 @@
{
struct gmu_device *gmu = &device->gmu;
struct device *dev = &gmu->pdev->dev;
- int ret = 0;
+ int val;
+
+ kgsl_gmu_regread(device, A6XX_GPU_CC_GX_DOMAIN_MISC, &val);
+ WARN_ON(!(val & 0x1));
/* RSC wake sequence */
kgsl_gmu_regwrite(device, A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));
@@ -1405,25 +1318,20 @@
kgsl_gmu_regwrite(device, A6XX_GMU_RSCC_CONTROL_REQ, 0);
- /* Turn on the HM and SPTP head switches */
- ret = a6xx_hm_sptprac_enable(device);
-
/* Enable the power counter because it was disabled before slumber */
kgsl_gmu_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1);
- return ret;
+ return 0;
error_rsc:
dev_err(dev, "GPU RSC sequence stuck in waking up GPU\n");
- return -EINVAL;
+ return -EINVAL;
}
static int a6xx_rpmh_power_off_gpu(struct kgsl_device *device)
{
struct gmu_device *gmu = &device->gmu;
- int val, ret = 0;
-
- /* Turn off the SPTP and HM head switches */
- ret = a6xx_hm_sptprac_disable(device);
+ const struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ int val;
/* RSC sleep sequence */
kgsl_gmu_regwrite(device, A6XX_RSCC_TIMESTAMP_UNIT1_EN_DRV0, 1);
@@ -1446,13 +1354,87 @@
&val);
kgsl_gmu_regwrite(device, A6XX_GMU_RSCC_CONTROL_REQ, 0);
- kgsl_gmu_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 0);
+ if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
+ test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
+ kgsl_gmu_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 0);
/* FIXME: v2 has different procedure to trigger sequence */
- return ret;
+ return 0;
}
+#define KMASK(start, n) (GENMASK((start + n), (start)))
+
+static void isense_cold_trimm(struct kgsl_device *device)
+{
+ unsigned int reg;
+ struct gmu_device *gmu = &device->gmu;
+
+ kgsl_gmu_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_AMP_CALIBRATION_DONE, 0);
+
+ kgsl_gmu_regwrite(device, A6XX_GPU_GMU_CX_GMU_ISENSE_CTRL, 0x1);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_AMP_CALIBRATION_CONTROL3,
+ 0x00000F8F);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_AMP_CALIBRATION_CONTROL2,
+ 0x00705161);
+ udelay(10);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_ENABLE_REG, 0x3);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_A_SENSOR_CTRL_0, 0x10040a);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_A_SENSOR_CTRL_2, 0x10040a);
+
+ kgsl_gmu_regread(device, A6XX_GPU_CS_SENSOR_GENERAL_STATUS, ®);
+ if ((reg & BIT(CS_PWR_ON_STATUS)) != (1 << CS_PWR_ON_STATUS)) {
+ dev_err(&gmu->pdev->dev, "ERROR - ISENSE power-up\n");
+ return;
+ }
+
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_CALIBRATION_CONTROL1,
+ KMASK(AMP_TRIM_TIMER, 15), 70 << AMP_TRIM_TIMER);
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_CALIBRATION_CONTROL1,
+ KMASK(AMP_SW_TRIM_START, 1), 0 << AMP_SW_TRIM_START);
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_CALIBRATION_CONTROL1,
+ KMASK(AMP_SW_TRIM_START, 1), 1 << AMP_SW_TRIM_START);
+
+ if (timed_poll_check(device, A6XX_GPU_CS_SENSOR_GENERAL_STATUS,
+ BIT(SS_AMPTRIM_DONE), GMU_START_TIMEOUT,
+ BIT(SS_AMPTRIM_DONE))) {
+ dev_err(&gmu->pdev->dev, "ISENSE SS_AMPTRIM failure\n");
+ return;
+ }
+
+ kgsl_gmu_regread(device, A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_0, ®);
+ if (reg & AMP_ERR) {
+ kgsl_gmu_regread(device, A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_0,
+ ®);
+ dev_err(&gmu->pdev->dev,
+ "ISENSE ERROR:trimming GX 0x%08x\n", reg);
+ return;
+ }
+
+ kgsl_gmu_regread(device, A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_2, ®);
+ if (reg & AMP_ERR) {
+ kgsl_gmu_regread(device, A6XX_GPU_CS_AMP_CALIBRATION_STATUS1_2,
+ ®);
+ dev_err(&gmu->pdev->dev,
+ "ISENSE ERROR:trimming SPTPRAC 0x%08x\n", reg);
+ return;
+ }
+
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_AMP_CALIBRATION_DONE, 1);
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_PERIOD_CTRL,
+ KMASK(TRIM_CNT_VALUE, 13), 20 << TRIM_CNT_VALUE);
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_PERIOD_CTRL,
+ KMASK(RUNTIME_CNT_VALUE, 9), 50 << RUNTIME_CNT_VALUE);
+
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_PERIOD_CTRL,
+ KMASK(TRIM_ENABLE, 1), 1 << TRIM_ENABLE);
+ udelay(4);
+ kgsl_gmu_regrmw(device, A6XX_GPU_CS_AMP_PERIOD_CTRL,
+ KMASK(TRIM_ENABLE, 1), 0 << TRIM_ENABLE);
+ kgsl_gmu_regwrite(device, A6XX_GPU_CS_AMP_CALIBRATION_DONE, 1);
+
+}
/*
* a6xx_gmu_fw_start() - set up GMU and start FW
* @device: Pointer to KGSL device
@@ -1470,25 +1452,12 @@
case GMU_RESET:
/* fall through */
case GMU_COLD_BOOT:
- /* Turn on the HM and SPTP head switches */
- ret = a6xx_hm_sptprac_enable(device);
- if (ret)
- return ret;
-
/* Turn on TCM retention */
kgsl_gmu_regwrite(device, A6XX_GMU_GENERAL_7, 1);
- if (!test_and_set_bit(GMU_BOOT_INIT_DONE, &gmu->flags)) {
+ if (!test_and_set_bit(GMU_BOOT_INIT_DONE, &gmu->flags))
_load_gmu_rpmh_ucode(device);
- /* Turn on the HM and SPTP head switches */
- ret = a6xx_hm_sptprac_enable(device);
- if (ret)
- return ret;
- } else if (boot_state == GMU_RESET) {
- ret = a6xx_hm_sptprac_enable(device);
- if (ret)
- return ret;
- } else {
+ else if (boot_state != GMU_RESET) {
ret = a6xx_rpmh_power_on_gpu(device);
if (ret)
return ret;
@@ -1530,6 +1499,13 @@
kgsl_gmu_regwrite(device, A6XX_GMU_AHB_FENCE_RANGE_0,
FENCE_RANGE_MASK);
+ if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
+ test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) {
+ kgsl_gmu_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_THRESHOLD,
+ lm_limit(adreno_dev));
+ isense_cold_trimm(device);
+ }
+
/* Configure power control and bring the GMU out of reset */
a6xx_gmu_power_config(device);
ret = a6xx_gmu_start(device);
@@ -1545,6 +1521,12 @@
}
}
+ if (gmu->idle_level < GPU_HW_SPTP_PC) {
+ ret = a6xx_sptprac_enable(adreno_dev);
+ if (ret)
+ return ret;
+ }
+
ret = a6xx_gmu_hfi_start(device);
if (ret)
return ret;
@@ -1759,7 +1741,8 @@
unsigned int val;
const struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM))
+ if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
+ !test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
return;
kgsl_gmu_regread(device, A6XX_GPU_CS_ENABLE_REG, &val);
@@ -1775,7 +1758,8 @@
const struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct gmu_device *gmu = &device->gmu;
- if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM))
+ if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
+ !test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
return 0;
kgsl_gmu_regread(device, A6XX_GMU_LLM_GLM_SLEEP_CTRL, &val);
@@ -1794,6 +1778,19 @@
return 0;
}
+
+static void a6xx_count_throttles(struct adreno_device *adreno_dev,
+ uint64_t adj)
+{
+ if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
+ !test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
+ return;
+
+ kgsl_gmu_regread(KGSL_DEVICE(adreno_dev),
+ adreno_dev->lm_threshold_count,
+ &adreno_dev->lm_threshold_cross);
+}
+
static int a6xx_complete_rpmh_votes(struct kgsl_device *device)
{
int ret = 0;
@@ -1837,13 +1834,7 @@
/* Check no outstanding RPMh voting */
a6xx_complete_rpmh_votes(device);
- if (gmu->idle_level < GPU_HW_IFPC) {
- /* HM GDSC is controlled by KGSL */
- ret = a6xx_hm_disable(ADRENO_DEVICE(device));
- if (ret)
- dev_err(&gmu->pdev->dev,
- "suspend: fail: power off GPU HM\n");
- } else if (gmu->gx_gdsc) {
+ if (gmu->gx_gdsc) {
if (regulator_is_enabled(gmu->gx_gdsc)) {
/* Switch gx gdsc control from GMU to CPU
* force non-zero reference count in clk driver
@@ -2184,6 +2175,14 @@
return uche_client[uche_client_id & A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK];
}
+static void a6xx_cp_callback(struct adreno_device *adreno_dev, int bit)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+
+ a6xx_preemption_trigger(adreno_dev);
+ adreno_dispatcher_schedule(device);
+}
+
#define A6XX_INT_MASK \
((1 << A6XX_INT_CP_AHB_ERROR) | \
(1 << A6XX_INT_ATB_ASYNCFIFO_OVERFLOW) | \
@@ -2221,7 +2220,7 @@
ADRENO_IRQ_CALLBACK(NULL), /* 17 - CP_RB_DONE_TS */
ADRENO_IRQ_CALLBACK(NULL), /* 18 - CP_WT_DONE_TS */
ADRENO_IRQ_CALLBACK(NULL), /* 19 - UNUSED */
- ADRENO_IRQ_CALLBACK(adreno_cp_callback), /* 20 - CP_CACHE_FLUSH_TS */
+ ADRENO_IRQ_CALLBACK(a6xx_cp_callback), /* 20 - CP_CACHE_FLUSH_TS */
ADRENO_IRQ_CALLBACK(NULL), /* 21 - UNUSED */
ADRENO_IRQ_CALLBACK(a6xx_err_callback), /* 22 - RBBM_ATB_BUS_OVERFLOW */
/* 23 - MISC_HANG_DETECT */
@@ -2672,9 +2671,9 @@
if (!device->gmu.pdev)
return -ENODEV;
- kgsl_regwrite(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0);
+ kgsl_regwrite(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xFF000000);
kgsl_regrmw(device,
- A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xFF, 0x20);
+ A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xFF, 0x20);
kgsl_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0x1);
return 0;
@@ -2775,6 +2774,10 @@
A6XX_GMU_HOST2GMU_INTR_CLR),
ADRENO_REG_DEFINE(ADRENO_REG_GMU_HOST2GMU_INTR_RAW_INFO,
A6XX_GMU_HOST2GMU_INTR_RAW_INFO),
+ ADRENO_REG_DEFINE(ADRENO_REG_GMU_NMI_CONTROL_STATUS,
+ A6XX_GMU_NMI_CONTROL_STATUS),
+ ADRENO_REG_DEFINE(ADRENO_REG_GMU_CM3_CFG,
+ A6XX_GMU_CM3_CFG),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SECVID_TRUST_CONTROL,
A6XX_RBBM_SECVID_TRUST_CNTL),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SECVID_TSB_TRUSTED_BASE,
@@ -2807,6 +2810,7 @@
.regulator_disable = a6xx_sptprac_disable,
.perfcounters = &a6xx_perfcounters,
.enable_pwr_counters = a6xx_enable_pwr_counters,
+ .count_throttles = a6xx_count_throttles,
.microcode_read = a6xx_microcode_read,
.enable_64bit = a6xx_enable_64bit,
.llc_configure_gpu_scid = a6xx_llc_configure_gpu_scid,
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 70afc91..e1f1595 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -231,9 +231,9 @@
0x1F980, 0x1F986, 0x1F990, 0x1F99E, 0x1F9C0, 0x1F9C0, 0x1F9C5, 0x1F9CC,
0x1F9E0, 0x1F9E2, 0x1F9F0, 0x1F9F0, 0x1FA00, 0x1FA03,
/* GPU RSCC */
- 0x23740, 0x23742, 0x23744, 0x23747, 0x2374C, 0x23787, 0x237EC, 0x237EF,
- 0x237F4, 0x2382F, 0x23894, 0x23897, 0x2389C, 0x238D7, 0x2393C, 0x2393F,
- 0x23944, 0x2397F,
+ 0x2348C, 0x2348C, 0x23501, 0x23502, 0x23740, 0x23742, 0x23744, 0x23747,
+ 0x2374C, 0x23787, 0x237EC, 0x237EF, 0x237F4, 0x2382F, 0x23894, 0x23897,
+ 0x2389C, 0x238D7, 0x2393C, 0x2393F, 0x23944, 0x2397F,
/* GMU AO */
0x23B00, 0x23B16, 0x23C00, 0x23C00,
/* GPU CC */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 9ae3cbd..9968d8c 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1926,12 +1926,13 @@
return ret;
}
-static void gpuobj_free_fence_func(void *priv)
+static bool gpuobj_free_fence_func(void *priv)
{
struct kgsl_mem_entry *entry = priv;
INIT_WORK(&entry->work, _deferred_put);
queue_work(kgsl_driver.mem_workqueue, &entry->work);
+ return true;
}
static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 4aaea80..6bad70b 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -669,9 +669,14 @@
static inline int kgsl_state_is_awake(struct kgsl_device *device)
{
+ struct gmu_device *gmu = &device->gmu;
+
if (device->state == KGSL_STATE_ACTIVE ||
device->state == KGSL_STATE_AWARE)
return true;
+ else if (kgsl_gmu_isenabled(device) &&
+ test_bit(GMU_CLK_ON, &gmu->flags))
+ return true;
else
return false;
}
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index bca3d57..3dbaea4 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -158,10 +158,13 @@
}
/*
- * a generic function to retire a pending sync event and (possibly)
- * kick the dispatcher
+ * a generic function to retire a pending sync event and (possibly) kick the
+ * dispatcher.
+ * Returns false if the event was already marked for cancellation in another
+ * thread. This function should return true if this thread is responsible for
+ * freeing up the memory, and the event will not be cancelled.
*/
-static void drawobj_sync_expire(struct kgsl_device *device,
+static bool drawobj_sync_expire(struct kgsl_device *device,
struct kgsl_drawobj_sync_event *event)
{
struct kgsl_drawobj_sync *syncobj = event->syncobj;
@@ -170,7 +173,7 @@
* leave without doing anything useful
*/
if (!test_and_clear_bit(event->id, &syncobj->pending))
- return;
+ return false;
/*
* If no more pending events, delete the timer and schedule the command
@@ -183,6 +186,7 @@
device->ftbl->drawctxt_sched(device,
event->syncobj->base.context);
}
+ return true;
}
/*
@@ -228,18 +232,23 @@
static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
{
struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj);
- unsigned long pending;
+ unsigned long pending = 0;
unsigned int i;
/* Zap the canary timer */
del_timer_sync(&syncobj->timer);
/*
- * Copy off the pending list and clear all pending events - this will
- * render any subsequent asynchronous callback harmless
+ * Copy off the pending list and clear each pending event atomically -
+ * this will render any subsequent asynchronous callback harmless.
+ * This marks each event for deletion. If any pending fence callbacks
+ * run between now and the actual cancel, the associated structures
+ * are kfreed only in the cancel call.
*/
- bitmap_copy(&pending, &syncobj->pending, KGSL_MAX_SYNCPOINTS);
- bitmap_zero(&syncobj->pending, KGSL_MAX_SYNCPOINTS);
+ for_each_set_bit(i, &syncobj->pending, KGSL_MAX_SYNCPOINTS) {
+ if (test_and_clear_bit(i, &syncobj->pending))
+ __set_bit(i, &pending);
+ }
/*
* Clear all pending events - this will render any subsequent async
@@ -259,8 +268,8 @@
drawobj_sync_func, event);
break;
case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
- if (kgsl_sync_fence_async_cancel(event->handle))
- kgsl_drawobj_put(drawobj);
+ kgsl_sync_fence_async_cancel(event->handle);
+ kgsl_drawobj_put(drawobj);
break;
}
}
@@ -320,15 +329,21 @@
}
EXPORT_SYMBOL(kgsl_drawobj_destroy);
-static void drawobj_sync_fence_func(void *priv)
+static bool drawobj_sync_fence_func(void *priv)
{
struct kgsl_drawobj_sync_event *event = priv;
trace_syncpoint_fence_expire(event->syncobj, event->fence_name);
- drawobj_sync_expire(event->device, event);
-
- kgsl_drawobj_put(&event->syncobj->base);
+ /*
+ * Only call kgsl_drawobj_put() if it's not marked for cancellation
+ * in another thread.
+ */
+ if (drawobj_sync_expire(event->device, event)) {
+ kgsl_drawobj_put(&event->syncobj->base);
+ return true;
+ }
+ return false;
}
/* drawobj_add_sync_fence() - Add a new sync fence syncpoint
diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c
index dff46d2..36fdd51 100644
--- a/drivers/gpu/msm/kgsl_gmu.c
+++ b/drivers/gpu/msm/kgsl_gmu.c
@@ -505,7 +505,11 @@
}
cmd_db_get_aux_data(res_id, (uint8_t *)arc->val, len);
- arc->num = len >> 1;
+ for (arc->num = 1; arc->num <= MAX_GX_LEVELS; arc->num++) {
+ if (arc->num == MAX_GX_LEVELS ||
+ arc->val[arc->num - 1] >= arc->val[arc->num])
+ break;
+ }
return 0;
}
@@ -528,35 +532,42 @@
{
int i, j, k;
uint16_t cur_vlvl;
+ bool found_match;
/* i tracks current KGSL GPU frequency table entry
* j tracks second rail voltage table entry
* k tracks primary rail voltage table entry
*/
- for (i = 0, k = 0; i < num_entries; k++) {
- if (pri_rail->val[k] != vlvl[i]) {
- if (k >= pri_rail->num)
- return -EINVAL;
- continue;
- }
- votes[i].pri_idx = k;
- votes[i].vlvl = vlvl[i];
- cur_vlvl = vlvl[i];
+ for (i = 0; i < num_entries; i++) {
+ found_match = false;
- /* find index of second rail vlvl array element that
- * its vlvl >= current vlvl of primary rail
- */
- for (j = 0; j < sec_rail->num; j++) {
- if (sec_rail->val[j] >= cur_vlvl) {
- votes[i].sec_idx = j;
+ /* Look for a primary rail voltage that matches a VLVL level */
+ for (k = 0; k < pri_rail->num; k++) {
+ if (pri_rail->val[k] == vlvl[i]) {
+ votes[i].pri_idx = k;
+ votes[i].vlvl = vlvl[i];
+ cur_vlvl = vlvl[i];
+ found_match = true;
break;
}
}
- if (j == sec_rail->num)
- votes[i].sec_idx = j;
+ /* If we did not find a matching VLVL level then abort */
+ if (!found_match)
+ return -EINVAL;
- i++;
+ /*
+ * Look for a secondary rail index whose VLVL value
+ * is greater than or equal to the VLVL value of the
+ * corresponding index of the primary rail
+ */
+ for (j = 0; j < sec_rail->num; j++) {
+ if (sec_rail->val[j] >= cur_vlvl ||
+ j + 1 == sec_rail->num) {
+ votes[i].sec_idx = j;
+ break;
+ }
+ }
}
return 0;
}
@@ -575,26 +586,25 @@
struct rpmh_arc_vals *sec_rail,
unsigned int type)
{
+ struct device *dev;
+ struct kgsl_device *device = container_of(gmu, struct kgsl_device, gmu);
unsigned int num_freqs;
struct arc_vote_desc *votes;
unsigned int vlvl_tbl[MAX_GX_LEVELS];
unsigned int *freq_tbl;
int i, ret;
- /*
- * FIXME: remove below two arrays after OPP VLVL query API ready
- * struct dev_pm_opp *opp;
- */
- uint16_t gpu_vlvl[] = {0, 128, 256, 384};
- uint16_t cx_vlvl[] = {0, 48, 256};
+ struct dev_pm_opp *opp;
if (type == GPU_ARC_VOTE) {
num_freqs = gmu->num_gpupwrlevels;
votes = gmu->rpmh_votes.gx_votes;
- freq_tbl = gmu->gmu_freqs;
+ freq_tbl = gmu->gpu_freqs;
+ dev = &device->pdev->dev;
} else if (type == GMU_ARC_VOTE) {
num_freqs = gmu->num_gmupwrlevels;
votes = gmu->rpmh_votes.cx_votes;
- freq_tbl = gmu->gpu_freqs;
+ freq_tbl = gmu->gmu_freqs;
+ dev = &gmu->pdev->dev;
} else {
return -EINVAL;
}
@@ -606,26 +616,25 @@
return -EINVAL;
}
- /*
- * FIXME: Find a core's voltage VLVL value based on its frequency
- * using OPP framework, waiting for David Colin, ETA Jan.
- */
+ memset(vlvl_tbl, 0, sizeof(vlvl_tbl));
for (i = 0; i < num_freqs; i++) {
- /*
- * opp = dev_pm_opp_find_freq_exact(&gmu->pdev->dev,
- * freq_tbl[i], true);
- * if (IS_ERR(opp)) {
- * dev_err(&gmu->pdev->dev,
- * "Failed to find opp freq %d of %s\n",
- * freq_tbl[i], debug_strs[type]);
- * return PTR_ERR(opp);
- * }
- * vlvl_tbl[i] = dev_pm_opp_get_voltage(opp);
- */
- if (type == GPU_ARC_VOTE)
- vlvl_tbl[i] = gpu_vlvl[i];
- else
- vlvl_tbl[i] = cx_vlvl[i];
+ /* Hardcode VLVL for 0 because it is not registered in OPP */
+ if (freq_tbl[i] == 0) {
+ vlvl_tbl[i] = 0;
+ continue;
+ }
+
+ /* Otherwise get the value from the OPP API */
+ opp = dev_pm_opp_find_freq_exact(dev, freq_tbl[i], true);
+ if (IS_ERR(opp)) {
+ dev_err(&gmu->pdev->dev,
+ "Failed to find opp freq %d of %s\n",
+ freq_tbl[i], debug_strs[type]);
+ return PTR_ERR(opp);
+ }
+
+ /* Values from OPP framework are offset by 1 */
+ vlvl_tbl[i] = dev_pm_opp_get_voltage(opp) - 1;
}
ret = setup_volt_dependency_tbl(votes,
@@ -1130,6 +1139,7 @@
goto error;
gmu->num_gpupwrlevels = pwr->num_pwrlevels;
+ gmu->wakeup_pwrlevel = pwr->default_pwrlevel;
for (i = 0; i < gmu->num_gpupwrlevels; i++) {
int j = gmu->num_gpupwrlevels - 1 - i;
@@ -1166,6 +1176,8 @@
else
gmu->idle_level = GPU_HW_ACTIVE;
+ /* disable LM during boot time */
+ clear_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
return 0;
error:
@@ -1206,20 +1218,11 @@
static int gmu_disable_clks(struct gmu_device *gmu)
{
- int ret, j = 0;
- unsigned int gmu_freq;
+ int j = 0;
if (IS_ERR_OR_NULL(gmu->clks[0]))
return 0;
- gmu_freq = gmu->gmu_freqs[gmu->num_gmupwrlevels - 1];
- ret = clk_set_rate(gmu->clks[0], gmu_freq);
- if (ret) {
- dev_err(&gmu->pdev->dev, "fail to reset GMU clk freq %d\n",
- gmu_freq);
- return ret;
- }
-
while ((j < MAX_GMU_CLKS) && gmu->clks[j]) {
clk_disable_unprepare(gmu->clks[j]);
j++;
@@ -1332,15 +1335,44 @@
return 0;
}
+static void gmu_snapshot(struct kgsl_device *device)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct gmu_device *gmu = &device->gmu;
+
+ if (!test_and_set_bit(GMU_FAULT, &gmu->flags)) {
+ /* Mask so there's no interrupt caused by NMI */
+ adreno_write_gmureg(adreno_dev,
+ ADRENO_REG_GMU_GMU2HOST_INTR_MASK, 0xFFFFFFFF);
+
+ /* Make sure the interrupt is masked before causing it */
+ wmb();
+ adreno_write_gmureg(adreno_dev,
+ ADRENO_REG_GMU_NMI_CONTROL_STATUS, 0);
+ adreno_write_gmureg(adreno_dev,
+ ADRENO_REG_GMU_CM3_CFG, (1 << 9));
+
+ /* Wait for the NMI to be handled */
+ wmb();
+ udelay(100);
+ kgsl_device_snapshot(device, NULL);
+
+ adreno_write_gmureg(adreno_dev,
+ ADRENO_REG_GMU_GMU2HOST_INTR_CLR, 0xFFFFFFFF);
+ adreno_write_gmureg(adreno_dev,
+ ADRENO_REG_GMU_GMU2HOST_INTR_MASK,
+ (unsigned int) ~HFI_IRQ_MASK);
+ }
+}
+
/* To be called to power on both GPU and GMU */
int gmu_start(struct kgsl_device *device)
{
- int ret = 0, perf_idx;
+ int ret = 0;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
struct gmu_device *gmu = &device->gmu;
- int bus_level = pwr->pwrlevels[pwr->default_pwrlevel].bus_freq;
switch (device->state) {
case KGSL_STATE_INIT:
@@ -1349,13 +1381,9 @@
gmu_enable_gdsc(gmu);
gmu_enable_clks(gmu);
- /* Convert to RPMh frequency index */
- perf_idx = gmu->num_gpupwrlevels -
- pwr->default_pwrlevel - 1;
-
/* Vote for 300MHz DDR for GMU to init */
ret = msm_bus_scale_client_update_request(gmu->pcl,
- bus_level);
+ pwr->pwrlevels[pwr->default_pwrlevel].bus_freq);
if (ret) {
dev_err(&gmu->pdev->dev,
"Failed to allocate gmu b/w\n");
@@ -1374,7 +1402,8 @@
goto error_gpu;
/* Send default DCVS level */
- ret = gmu_dcvs_set(gmu, perf_idx, bus_level);
+ ret = gmu_dcvs_set(gmu, pwr->default_pwrlevel,
+ pwr->pwrlevels[pwr->default_pwrlevel].bus_freq);
if (ret)
goto error_gpu;
@@ -1386,8 +1415,6 @@
gmu_enable_gdsc(gmu);
gmu_enable_clks(gmu);
- perf_idx = gmu->num_gpupwrlevels - gmu->wakeup_pwrlevel - 1;
-
ret = gpudev->rpmh_gpu_pwrctrl(adreno_dev, GMU_FW_START,
GMU_WARM_BOOT, 0);
if (ret)
@@ -1399,12 +1426,12 @@
if (ret)
goto error_gpu;
- if (gmu->wakeup_pwrlevel != pwr->default_pwrlevel) {
- ret = gmu_dcvs_set(gmu, perf_idx, bus_level);
- if (ret)
- goto error_gpu;
- gmu->wakeup_pwrlevel = pwr->default_pwrlevel;
- }
+ ret = gmu_dcvs_set(gmu, gmu->wakeup_pwrlevel,
+ pwr->pwrlevels[gmu->wakeup_pwrlevel].bus_freq);
+ if (ret)
+ goto error_gpu;
+
+ gmu->wakeup_pwrlevel = pwr->default_pwrlevel;
break;
case KGSL_STATE_RESET:
@@ -1413,11 +1440,6 @@
gmu_enable_gdsc(gmu);
gmu_enable_clks(gmu);
- perf_idx = gmu->num_gpupwrlevels -
- pwr->active_pwrlevel - 1;
-
- bus_level =
- pwr->pwrlevels[pwr->active_pwrlevel].bus_freq;
ret = gpudev->rpmh_gpu_pwrctrl(
adreno_dev, GMU_FW_START, GMU_RESET, 0);
if (ret)
@@ -1430,7 +1452,9 @@
goto error_gpu;
/* Send DCVS level prior to reset*/
- ret = gmu_dcvs_set(gmu, perf_idx, bus_level);
+ ret = gmu_dcvs_set(gmu, pwr->active_pwrlevel,
+ pwr->pwrlevels[pwr->active_pwrlevel]
+ .bus_freq);
if (ret)
goto error_gpu;
@@ -1439,19 +1463,13 @@
OOB_CPINIT_CHECK_MASK,
OOB_CPINIT_CLEAR_MASK);
- } else {
+ } else
gmu_fast_boot(device);
- }
break;
default:
break;
}
- /*
- * OOB to enable power management of GMU.
- * In v2, this function call shall move ahead
- * of hfi_start() to save power.
- */
if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
gpudev->oob_clear(adreno_dev,
OOB_BOOT_SLUMBER_CLEAR_MASK);
@@ -1459,15 +1477,17 @@
return ret;
error_gpu:
+ gmu_snapshot(device);
hfi_stop(gmu);
gmu_irq_disable(device);
- if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
- gpudev->oob_clear(adreno_dev,
- OOB_BOOT_SLUMBER_CLEAR_MASK);
+ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
+ gpudev->oob_clear(adreno_dev,
+ OOB_BOOT_SLUMBER_CLEAR_MASK);
gpudev->rpmh_gpu_pwrctrl(adreno_dev, GMU_FW_STOP, 0, 0);
error_bus:
- msm_bus_scale_client_update_request(gmu->pcl, 0);
+ msm_bus_scale_client_update_request(gmu->pcl, 0);
error_clks:
+ gmu_snapshot(device);
gmu_disable_clks(gmu);
gmu_disable_gdsc(gmu);
return ret;
diff --git a/drivers/gpu/msm/kgsl_gmu.h b/drivers/gpu/msm/kgsl_gmu.h
index a741beb..63ca028 100644
--- a/drivers/gpu/msm/kgsl_gmu.h
+++ b/drivers/gpu/msm/kgsl_gmu.h
@@ -82,6 +82,7 @@
GMU_BOOT_INIT_DONE = 0,
GMU_CLK_ON = 1,
GMU_HFI_ON = 2,
+ GMU_FAULT = 3
};
/**
diff --git a/drivers/gpu/msm/kgsl_hfi.c b/drivers/gpu/msm/kgsl_hfi.c
index cc878aa..68e0f3a 100644
--- a/drivers/gpu/msm/kgsl_hfi.c
+++ b/drivers/gpu/msm/kgsl_hfi.c
@@ -602,15 +602,23 @@
if (result)
return result;
- /*
- * FW is not ready for LM configuration
- * without powering on GPU.
- */
- /*
- * result = hfi_send_lmconfig(gmu);
- * if (result)
- * return result;
- */
+ if (ADRENO_FEATURE(adreno_dev, ADRENO_LM) &&
+ test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) {
+ gmu->lm_config.lm_type = 1;
+ gmu->lm_config.lm_sensor_type = 1;
+ gmu->lm_config.throttle_config = 1;
+ gmu->lm_config.idle_throttle_en = 0;
+ gmu->lm_config.acd_en = 0;
+ gmu->bcl_config = 0;
+ gmu->lm_dcvs_level = 0;
+
+ result = hfi_send_lmconfig(gmu);
+ if (result) {
+ dev_err(dev, "Failire enabling limits management (%d)\n",
+ result);
+ return result;
+ }
+ }
set_bit(GMU_HFI_ON, &gmu->flags);
return 0;
diff --git a/drivers/gpu/msm/kgsl_pool.c b/drivers/gpu/msm/kgsl_pool.c
index c31a85b..685ce3e 100644
--- a/drivers/gpu/msm/kgsl_pool.c
+++ b/drivers/gpu/msm/kgsl_pool.c
@@ -65,26 +65,19 @@
/* Map the page into kernel and zero it out */
static void
-_kgsl_pool_zero_page(struct page *p, unsigned int pool_order)
+_kgsl_pool_zero_page(struct page *p)
{
- int i;
+ void *addr = kmap_atomic(p);
- for (i = 0; i < (1 << pool_order); i++) {
- struct page *page = nth_page(p, i);
- void *addr = kmap_atomic(page);
-
- memset(addr, 0, PAGE_SIZE);
- dmac_flush_range(addr, addr + PAGE_SIZE);
- kunmap_atomic(addr);
- }
+ memset(addr, 0, PAGE_SIZE);
+ dmac_flush_range(addr, addr + PAGE_SIZE);
+ kunmap_atomic(addr);
}
/* Add a page to specified pool */
static void
_kgsl_pool_add_page(struct kgsl_page_pool *pool, struct page *p)
{
- _kgsl_pool_zero_page(p, pool->pool_order);
-
spin_lock(&pool->list_lock);
list_add_tail(&p->lru, &pool->page_list);
pool->page_count++;
@@ -329,7 +322,6 @@
} else
return -ENOMEM;
}
- _kgsl_pool_zero_page(page, order);
goto done;
}
@@ -349,7 +341,6 @@
page = alloc_pages(gfp_mask, order);
if (page == NULL)
return -ENOMEM;
- _kgsl_pool_zero_page(page, order);
goto done;
}
}
@@ -379,13 +370,12 @@
} else
return -ENOMEM;
}
-
- _kgsl_pool_zero_page(page, order);
}
done:
for (j = 0; j < (*page_size >> PAGE_SHIFT); j++) {
p = nth_page(page, j);
+ _kgsl_pool_zero_page(p);
pages[pcount] = p;
pcount++;
}
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 613fce9..6fd6a05 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -253,23 +253,30 @@
{
struct gmu_device *gmu = &device->gmu;
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+ struct kgsl_pwrlevel *pl = &pwr->pwrlevels[pwrlevel];
int ret = 0;
/* GMU scales GPU freq */
if (kgsl_gmu_isenabled(device)) {
/* If GMU has not been started, save it */
if (!(gmu->flags & GMU_HFI_ON)) {
+ /* In slumber the clock is off so we are done */
+ if (pwrlevel == (gmu->num_gpupwrlevels - 1))
+ return 0;
+
gmu->wakeup_pwrlevel = pwrlevel;
return 0;
}
+ /* If the GMU is on we cannot vote for the lowest level */
+ if (pwrlevel == (gmu->num_gpupwrlevels - 1)) {
+ WARN(1, "Cannot set 0 GPU frequency with GMU\n");
+ return -EINVAL;
+ }
ret = gmu_dcvs_set(gmu, pwrlevel, INVALID_DCVS_IDX);
- } else {
+ } else
/* Linux clock driver scales GPU freq */
- struct kgsl_pwrlevel *Pl = &pwr->pwrlevels[pwrlevel];
-
- ret = clk_set_rate(pwr->grp_clks[0], Pl->gpu_freq);
- }
+ ret = clk_set_rate(pwr->grp_clks[0], pl->gpu_freq);
if (ret)
KGSL_PWR_ERR(device, "GPU clk freq set failure\n");
@@ -1785,8 +1792,6 @@
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
- if (kgsl_gmu_isenabled(device))
- return;
if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->ctrl_flags))
return;
@@ -2470,8 +2475,13 @@
kgsl_pwrctrl_pwrlevel_change(device, level);
- if (kgsl_gmu_isenabled(device))
- return gmu_start(device);
+ if (kgsl_gmu_isenabled(device)) {
+ int ret = gmu_start(device);
+
+ if (!ret)
+ kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
+ return ret;
+ }
/* Order pwrrail/clk sequence based upon platform */
status = kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON);
@@ -2484,8 +2494,10 @@
static void kgsl_pwrctrl_disable(struct kgsl_device *device)
{
- if (kgsl_gmu_isenabled(device))
+ if (kgsl_gmu_isenabled(device)) {
+ kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
return gmu_stop(device);
+ }
/* Order pwrrail/clk sequence based upon platform */
device->ftbl->regulator_disable(device);
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 817a6b1..8f8e3e9 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -427,9 +427,14 @@
{
struct kgsl_sync_fence_cb *kcb = (struct kgsl_sync_fence_cb *)cb;
- kcb->func(kcb->priv);
- fence_put(kcb->fence);
- kfree(kcb);
+ /*
+ * If the callback is marked for cancellation in a separate thread,
+ * let the other thread do the cleanup.
+ */
+ if (kcb->func(kcb->priv)) {
+ fence_put(kcb->fence);
+ kfree(kcb);
+ }
}
static void kgsl_get_fence_name(struct fence *fence,
@@ -452,7 +457,7 @@
}
struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
- void (*func)(void *priv), void *priv, char *fence_name, int name_len)
+ bool (*func)(void *priv), void *priv, char *fence_name, int name_len)
{
struct kgsl_sync_fence_cb *kcb;
struct fence *fence;
@@ -492,17 +497,24 @@
return kcb;
}
-int kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb)
+/*
+ * Cancel the fence async callback and do the cleanup. The caller must make
+ * sure that the callback (if run before cancelling) returns false, so that
+ * no other thread frees the pointer.
+ */
+void kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb)
{
if (kcb == NULL)
- return 0;
+ return;
- if (fence_remove_callback(kcb->fence, &kcb->fence_cb)) {
- fence_put(kcb->fence);
- kfree(kcb);
- return 1;
- }
- return 0;
+ /*
+ * After fence_remove_callback() returns, the fence callback is
+ * either not called at all, or completed without freeing kcb.
+ * This thread can then put the fence refcount and free kcb.
+ */
+ fence_remove_callback(kcb->fence, &kcb->fence_cb);
+ fence_put(kcb->fence);
+ kfree(kcb);
}
struct kgsl_syncsource {
diff --git a/drivers/gpu/msm/kgsl_sync.h b/drivers/gpu/msm/kgsl_sync.h
index 99fe0e1..d58859d 100644
--- a/drivers/gpu/msm/kgsl_sync.h
+++ b/drivers/gpu/msm/kgsl_sync.h
@@ -68,13 +68,14 @@
* fence_cb: Fence callback struct
* fence: Pointer to the fence for which the callback is done
* priv: Private data for the callback
- * func: Pointer to the kgsl function to call
+ * func: Pointer to the kgsl function to call. This function should return
+ * false if the sync callback is marked for cancellation in a separate thread.
*/
struct kgsl_sync_fence_cb {
struct fence_cb fence_cb;
struct fence *fence;
void *priv;
- void (*func)(void *priv);
+ bool (*func)(void *priv);
};
struct kgsl_syncsource;
@@ -91,10 +92,10 @@
void kgsl_sync_timeline_put(struct kgsl_sync_timeline *ktimeline);
struct kgsl_sync_fence_cb *kgsl_sync_fence_async_wait(int fd,
- void (*func)(void *priv), void *priv,
+ bool (*func)(void *priv), void *priv,
char *fence_name, int name_len);
-int kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb);
+void kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb);
long kgsl_ioctl_syncsource_create(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data);
@@ -143,10 +144,9 @@
return NULL;
}
-static inline int
+static inline void
kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_cb *kcb)
{
- return 1;
}
static inline long
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 1767810..c7690a1 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -820,14 +820,14 @@
TRACE_EVENT(kgsl_mmu_pagefault,
- TP_PROTO(struct kgsl_device *device, unsigned int page,
+ TP_PROTO(struct kgsl_device *device, unsigned long page,
unsigned int pt, const char *op),
TP_ARGS(device, page, pt, op),
TP_STRUCT__entry(
__string(device_name, device->name)
- __field(unsigned int, page)
+ __field(unsigned long, page)
__field(unsigned int, pt)
__string(op, op)
),
@@ -840,7 +840,7 @@
),
TP_printk(
- "d_name=%s page=0x%08x pt=%u op=%s",
+ "d_name=%s page=0x%lx pt=%u op=%s",
__get_str(device_name), __entry->page, __entry->pt,
__get_str(op)
)
diff --git a/drivers/hwtracing/coresight/coresight-ost.c b/drivers/hwtracing/coresight/coresight-ost.c
index 63fea00..3399c27 100644
--- a/drivers/hwtracing/coresight/coresight-ost.c
+++ b/drivers/hwtracing/coresight/coresight-ost.c
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/bitmap.h>
+#include <linux/io.h>
#include "coresight-ost.h"
#define STM_USERSPACE_HEADER_SIZE (8)
@@ -54,19 +55,40 @@
return ch;
}
-static int stm_ost_send(void *addr, const void *data, uint32_t count)
+static int stm_ost_send(void __iomem *addr, const void *data, uint32_t size)
{
- struct stm_drvdata *drvdata = stmdrvdata;
- const unsigned char *p = data;
- size_t pos;
- ssize_t sz;
+ uint32_t len = size;
- for (pos = 0, p = data; count > pos; pos += sz, p += sz) {
- sz = min_t(unsigned int, count - pos, drvdata->write_bytes);
- stm_send(addr, p, sz, drvdata->write_bytes);
+ if (((unsigned long)data & 0x1) && (size >= 1)) {
+ writeb_relaxed_no_log(*(uint8_t *)data, addr);
+ data++;
+ size--;
+ }
+ if (((unsigned long)data & 0x2) && (size >= 2)) {
+ writew_relaxed_no_log(*(uint16_t *)data, addr);
+ data += 2;
+ size -= 2;
}
- return count;
+ /* now we are 32bit aligned */
+ while (size >= 4) {
+ writel_relaxed_no_log(*(uint32_t *)data, addr);
+ data += 4;
+ size -= 4;
+ }
+
+ if (size >= 2) {
+ writew_relaxed_no_log(*(uint16_t *)data, addr);
+ data += 2;
+ size -= 2;
+ }
+ if (size >= 1) {
+ writeb_relaxed_no_log(*(uint8_t *)data, addr);
+ data++;
+ size--;
+ }
+
+ return len;
}
static void stm_channel_free(uint32_t ch)
@@ -76,10 +98,10 @@
clear_bit(ch, drvdata->chs.bitmap);
}
-static int stm_trace_ost_header(unsigned long ch_addr, uint32_t flags,
+static int stm_trace_ost_header(void __iomem *ch_addr, uint32_t flags,
uint8_t entity_id, uint8_t proto_id)
{
- void *addr;
+ void __iomem *addr;
uint32_t header;
char *hdr;
@@ -93,12 +115,13 @@
/* header is expected to be D32M type */
flags |= STM_FLAG_MARKED;
flags &= ~STM_FLAG_TIMESTAMPED;
- addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, flags));
+ addr = (void __iomem *)(ch_addr +
+ stm_channel_off(STM_PKT_TYPE_DATA, flags));
return stm_ost_send(addr, &header, sizeof(header));
}
-static int stm_trace_data_header(void *addr)
+static int stm_trace_data_header(void __iomem *addr)
{
char hdr[16];
int len = 0;
@@ -114,14 +137,15 @@
return len;
}
-static int stm_trace_data(unsigned long ch_addr, uint32_t flags,
+static int stm_trace_data(void __iomem *ch_addr, uint32_t flags,
const void *data, uint32_t size)
{
- void *addr;
+ void __iomem *addr;
int len = 0;
flags &= ~STM_FLAG_TIMESTAMPED;
- addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, flags));
+ addr = (void __iomem *)(ch_addr +
+ stm_channel_off(STM_PKT_TYPE_DATA, flags));
/* send the data header */
len += stm_trace_data_header(addr);
@@ -131,12 +155,13 @@
return len;
}
-static int stm_trace_ost_tail(unsigned long ch_addr, uint32_t flags)
+static int stm_trace_ost_tail(void __iomem *ch_addr, uint32_t flags)
{
- void *addr;
+ void __iomem *addr;
uint32_t tail = 0x0;
- addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_FLAG, flags));
+ addr = (void __iomem *)(ch_addr +
+ stm_channel_off(STM_PKT_TYPE_FLAG, flags));
return stm_ost_send(addr, &tail, sizeof(tail));
}
@@ -147,7 +172,7 @@
struct stm_drvdata *drvdata = stmdrvdata;
int len = 0;
uint32_t ch;
- unsigned long ch_addr;
+ void __iomem *ch_addr;
/* allocate channel and get the channel address */
ch = stm_channel_alloc();
@@ -159,7 +184,7 @@
return 0;
}
- ch_addr = (unsigned long)stm_channel_addr(drvdata, ch);
+ ch_addr = (void __iomem *)stm_channel_addr(drvdata, ch);
/* send the ost header */
len += stm_trace_ost_header(ch_addr, flags, entity_id,
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 3234928..eb355f4 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -905,8 +905,10 @@
if (val != CS_MODE_DISABLED) {
if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
__tmc_etr_disable_to_bam(drvdata);
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
tmc_etr_bam_disable(drvdata);
usb_qdss_close(drvdata->usbch);
+ goto out;
} else {
tmc_etr_disable_hw(drvdata);
}
@@ -918,6 +920,7 @@
coresight_cti_unmap_trigin(drvdata->cti_reset, 2, 0);
coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0);
}
+out:
mutex_unlock(&drvdata->mem_lock);
dev_info(drvdata->dev, "TMC-ETR disabled\n");
}
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index ccf6247..4d2a346 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -980,7 +980,9 @@
free_rd_atomic_resource(qp, res);
rxe_advance_resp_resource(qp);
- memcpy(SKB_TO_PKT(skb), &ack_pkt, sizeof(skb->cb));
+ memcpy(SKB_TO_PKT(skb), &ack_pkt, sizeof(ack_pkt));
+ memset((unsigned char *)SKB_TO_PKT(skb) + sizeof(ack_pkt), 0,
+ sizeof(skb->cb) - sizeof(ack_pkt));
res->type = RXE_ATOMIC_MASK;
res->atomic.skb = skb;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 142357e..bf93b91 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -389,6 +389,7 @@
/* Protects clock_refs_count */
spinlock_t clock_refs_lock;
int clock_refs_count;
+ int regulator_defer;
};
struct arm_smmu_device {
@@ -789,6 +790,35 @@
WARN_ON(msm_bus_scale_client_update_request(pwr->bus_client, 0));
}
+static int arm_smmu_disable_regulators(struct arm_smmu_power_resources *pwr)
+{
+ struct regulator_bulk_data *consumers;
+ int i;
+ int num_consumers, ret, r;
+
+ num_consumers = pwr->num_gdscs;
+ consumers = pwr->gdscs;
+ for (i = num_consumers - 1; i >= 0; --i) {
+ ret = regulator_disable_deferred(consumers[i].consumer,
+ pwr->regulator_defer);
+ if (ret != 0)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
+ for (++i; i < num_consumers; ++i) {
+ r = regulator_enable(consumers[i].consumer);
+ if (r != 0)
+ pr_err("Failed to reename %s: %d\n",
+ consumers[i].supply, r);
+ }
+
+ return ret;
+}
+
/* Clocks must be prepared before this (arm_smmu_prepare_clocks) */
static int arm_smmu_power_on_atomic(struct arm_smmu_power_resources *pwr)
{
@@ -884,7 +914,7 @@
}
arm_smmu_unprepare_clocks(pwr);
- regulator_bulk_disable(pwr->num_gdscs, pwr->gdscs);
+ arm_smmu_disable_regulators(pwr);
arm_smmu_unrequest_bus(pwr);
pwr->power_count = 0;
mutex_unlock(&pwr->power_lock);
@@ -3175,6 +3205,11 @@
u32 sctlr, sctlr_orig, fsr;
void __iomem *cb_base;
+ if (smmu->model == QCOM_SMMUV2) {
+ dev_err(smmu->dev, "ATOS support is disabled\n");
+ return 0;
+ }
+
ret = arm_smmu_power_on(smmu_domain->smmu->pwr);
if (ret)
return ret;
@@ -3534,6 +3569,12 @@
if (!pwr->gdscs)
return -ENOMEM;
+ if (!of_property_read_u32(dev->of_node,
+ "qcom,deferred-regulator-disable-delay",
+ &(pwr->regulator_defer)))
+ dev_info(dev, "regulator defer delay %d\n",
+ pwr->regulator_defer);
+
i = 0;
of_property_for_each_string(dev->of_node, "qcom,regulator-names",
prop, cname)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 2ef496d..dde2876 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -760,16 +760,7 @@
if (!iopte_tblcnt(*ptep)) {
/* no valid mappings left under this table. free it. */
__arm_lpae_set_pte(ptep, 0, &iop->cfg);
- io_pgtable_tlb_add_flush(iop, iova,
- entries * entry_size,
- ARM_LPAE_GRANULE(data),
- false);
__arm_lpae_free_pgtable(data, lvl + 1, table_base);
- } else {
- io_pgtable_tlb_add_flush(iop, iova,
- entries * entry_size,
- ARM_LPAE_GRANULE(data),
- true);
}
return entries * entry_size;
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index cb19cef..f18022b 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -160,18 +160,19 @@
#define QPNP_WLED_MOD_EN_SHFT 7
#define QPNP_WLED_MOD_EN 1
#define QPNP_WLED_GATE_DRV_MASK 0xFE
-#define QPNP_WLED_SYNC_DLY_MASK 0xF8
+#define QPNP_WLED_SYNC_DLY_MASK GENMASK(2, 0)
#define QPNP_WLED_SYNC_DLY_MIN_US 0
#define QPNP_WLED_SYNC_DLY_MAX_US 1400
#define QPNP_WLED_SYNC_DLY_STEP_US 200
#define QPNP_WLED_DEF_SYNC_DLY_US 400
-#define QPNP_WLED_FS_CURR_MASK 0xF0
+#define QPNP_WLED_FS_CURR_MASK GENMASK(3, 0)
#define QPNP_WLED_FS_CURR_MIN_UA 0
#define QPNP_WLED_FS_CURR_MAX_UA 30000
#define QPNP_WLED_FS_CURR_STEP_UA 2500
-#define QPNP_WLED_CABC_MASK 0x7F
+#define QPNP_WLED_CABC_MASK 0x80
#define QPNP_WLED_CABC_SHIFT 7
#define QPNP_WLED_CURR_SINK_SHIFT 4
+#define QPNP_WLED_CURR_SINK_MASK GENMASK(7, 4)
#define QPNP_WLED_BRIGHT_LSB_MASK 0xFF
#define QPNP_WLED_BRIGHT_MSB_SHIFT 8
#define QPNP_WLED_BRIGHT_MSB_MASK 0x0F
@@ -208,12 +209,14 @@
#define QPNP_WLED_SEC_UNLOCK 0xA5
#define QPNP_WLED_MAX_STRINGS 4
+#define QPNP_PM660_WLED_MAX_STRINGS 3
#define WLED_MAX_LEVEL_4095 4095
#define QPNP_WLED_RAMP_DLY_MS 20
#define QPNP_WLED_TRIGGER_NONE "none"
#define QPNP_WLED_STR_SIZE 20
#define QPNP_WLED_MIN_MSLEEP 20
#define QPNP_WLED_SC_DLY_MS 20
+#define QPNP_WLED_SOFT_START_DLY_US 10000
#define NUM_SUPPORTED_AVDD_VOLTAGES 6
#define QPNP_WLED_DFLT_AVDD_MV 7600
@@ -381,6 +384,8 @@
u16 ramp_ms;
u16 ramp_step;
u16 cons_sync_write_delay_us;
+ u16 auto_calibration_ovp_count;
+ u16 max_strings;
u8 strings[QPNP_WLED_MAX_STRINGS];
u8 num_strings;
u8 loop_auto_gm_thresh;
@@ -396,6 +401,9 @@
bool en_ext_pfet_sc_pro;
bool prev_state;
bool ovp_irq_disabled;
+ bool auto_calib_enabled;
+ bool auto_calib_done;
+ ktime_t start_ovp_fault_time;
};
/* helper to read a pmic register */
@@ -531,7 +539,7 @@
u8 reg;
/* set brightness registers */
- for (i = 0; i < wled->num_strings; i++) {
+ for (i = 0; i < wled->max_strings; i++) {
reg = level & QPNP_WLED_BRIGHT_LSB_MASK;
rc = qpnp_wled_write_reg(wled,
QPNP_WLED_BRIGHT_LSB_REG(wled->sink_base,
@@ -600,7 +608,8 @@
* OVP interrupt disabled when the module is disabled.
*/
if (state) {
- usleep_range(10000, 11000);
+ usleep_range(QPNP_WLED_SOFT_START_DLY_US,
+ QPNP_WLED_SOFT_START_DLY_US + 1000);
rc = qpnp_wled_psm_config(wled, false);
if (rc < 0)
return rc;
@@ -873,32 +882,25 @@
struct device_attribute *attr, const char *buf, size_t count)
{
struct qpnp_wled *wled = dev_get_drvdata(dev);
- int data, i, rc, temp;
+ int data, i, rc;
u8 reg;
rc = kstrtoint(buf, 10, &data);
if (rc)
return rc;
- for (i = 0; i < wled->num_strings; i++) {
+ for (i = 0; i < wled->max_strings; i++) {
if (data < QPNP_WLED_FS_CURR_MIN_UA)
data = QPNP_WLED_FS_CURR_MIN_UA;
else if (data > QPNP_WLED_FS_CURR_MAX_UA)
data = QPNP_WLED_FS_CURR_MAX_UA;
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]), ®);
+ reg = data / QPNP_WLED_FS_CURR_STEP_UA;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_FS_CURR_REG(wled->sink_base, i),
+ QPNP_WLED_FS_CURR_MASK, reg);
if (rc < 0)
return rc;
- reg &= QPNP_WLED_FS_CURR_MASK;
- temp = data / QPNP_WLED_FS_CURR_STEP_UA;
- reg |= temp;
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]), reg);
- if (rc)
- return rc;
}
wled->fs_curr_ua = data;
@@ -1090,6 +1092,229 @@
return 0;
}
+#define AUTO_CALIB_BRIGHTNESS 16
+static int wled_auto_calibrate(struct qpnp_wled *wled)
+{
+ int rc = 0, i;
+ u8 reg = 0, sink_config = 0, sink_test = 0, sink_valid = 0, int_sts;
+
+ mutex_lock(&wled->lock);
+
+ /* disable OVP IRQ */
+ if (wled->ovp_irq > 0 && !wled->ovp_irq_disabled) {
+ disable_irq_nosync(wled->ovp_irq);
+ wled->ovp_irq_disabled = true;
+ }
+
+ /* read configured sink configuration */
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), &sink_config);
+ if (rc < 0) {
+ pr_err("Failed to read SINK configuration rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* disable the module before starting calibration */
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK, 0);
+ if (rc < 0) {
+ pr_err("Failed to disable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* set low brightness across all sinks */
+ rc = qpnp_wled_set_level(wled, AUTO_CALIB_BRIGHTNESS);
+ if (rc < 0) {
+ pr_err("Failed to set brightness for calibration rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* disable all sinks */
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), 0);
+ if (rc < 0) {
+ pr_err("Failed to disable all sinks rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK,
+ QPNP_WLED_MODULE_EN_MASK);
+ if (rc < 0) {
+ pr_err("Failed to enable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
+ /*
+ * Delay for the WLED soft-start, check the OVP status
+ * only after soft-start is complete
+ */
+ usleep_range(QPNP_WLED_SOFT_START_DLY_US,
+ QPNP_WLED_SOFT_START_DLY_US + 1000);
+
+ /* iterate through the strings one by one */
+ for (i = 0; i < wled->max_strings; i++) {
+ sink_test = 1 << (QPNP_WLED_CURR_SINK_SHIFT + i);
+
+ /* Enable feedback control */
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_FDBK_OP_REG(wled->ctrl_base),
+ i + 1);
+ if (rc < 0) {
+ pr_err("Failed to enable feedback for SINK %d rc = %d\n",
+ i + 1, rc);
+ goto failed_calib;
+ }
+
+ /* enable the sink */
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), sink_test);
+ if (rc < 0) {
+ pr_err("Failed to configure SINK %d rc=%d\n",
+ i + 1, rc);
+ goto failed_calib;
+ }
+
+ /* delay for WLED soft-start */
+ usleep_range(QPNP_WLED_SOFT_START_DLY_US,
+ QPNP_WLED_SOFT_START_DLY_US + 1000);
+
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_INT_RT_STS(wled->ctrl_base), &int_sts);
+ if (rc < 0) {
+ pr_err("Error in reading WLED_INT_RT_STS rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ if (int_sts & QPNP_WLED_OVP_FAULT_BIT)
+ pr_debug("WLED OVP fault detected with SINK %d\n",
+ i + 1);
+ else
+ sink_valid |= sink_test;
+ }
+
+ if (sink_valid == sink_config) {
+ pr_debug("WLED auto-calibration complete, default sink-config=%x OK!\n",
+ sink_config);
+ } else {
+ pr_warn("Invalid WLED default sink config=%x changing it to=%x\n",
+ sink_config, sink_valid);
+ sink_config = sink_valid;
+ }
+
+ if (!sink_config) {
+ pr_warn("No valid WLED sinks found\n");
+ goto failed_calib;
+ }
+
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK, 0);
+ if (rc < 0) {
+ pr_err("Failed to disable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* write the new sink configuration */
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), sink_config);
+ if (rc < 0) {
+ pr_err("Failed to reconfigure the default sink rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* MODULATOR_EN setting for valid sinks */
+ for (i = 0; i < wled->max_strings; i++) {
+ if (sink_config & (1 << (QPNP_WLED_CURR_SINK_SHIFT + i)))
+ reg = (QPNP_WLED_MOD_EN << QPNP_WLED_MOD_EN_SHFT);
+ else
+ reg = 0x0; /* disable modulator_en for unused sink */
+
+ if (wled->dim_mode == QPNP_WLED_DIM_HYBRID)
+ reg &= QPNP_WLED_GATE_DRV_MASK;
+ else
+ reg |= ~QPNP_WLED_GATE_DRV_MASK;
+
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_MOD_EN_REG(wled->sink_base, i), reg);
+ if (rc < 0) {
+ pr_err("Failed to configure MODULATOR_EN rc=%d\n", rc);
+ goto failed_calib;
+ }
+ }
+
+ /* restore the feedback setting */
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_FDBK_OP_REG(wled->ctrl_base),
+ wled->fdbk_op);
+ if (rc < 0) {
+ pr_err("Failed to restore feedback setting rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* restore brightness */
+ rc = qpnp_wled_set_level(wled, wled->cdev.brightness);
+ if (rc < 0) {
+ pr_err("Failed to set brightness after calibration rc=%d\n",
+ rc);
+ goto failed_calib;
+ }
+
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK,
+ QPNP_WLED_MODULE_EN_MASK);
+ if (rc < 0) {
+ pr_err("Failed to enable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
+
+ /* delay for WLED soft-start */
+ usleep_range(QPNP_WLED_SOFT_START_DLY_US,
+ QPNP_WLED_SOFT_START_DLY_US + 1000);
+
+failed_calib:
+ if (wled->ovp_irq > 0 && wled->ovp_irq_disabled) {
+ enable_irq(wled->ovp_irq);
+ wled->ovp_irq_disabled = false;
+ }
+ mutex_unlock(&wled->lock);
+ return rc;
+}
+
+#define WLED_AUTO_CAL_OVP_COUNT 5
+#define WLED_AUTO_CAL_CNT_DLY_US 1000000 /* 1 second */
+static bool qpnp_wled_auto_cal_required(struct qpnp_wled *wled)
+{
+ s64 elapsed_time_us;
+
+ /*
+ * Check if the OVP fault was an occasional one
+ * or if its firing continuously, the latter qualifies
+ * for an auto-calibration check.
+ */
+ if (!wled->auto_calibration_ovp_count) {
+ wled->start_ovp_fault_time = ktime_get();
+ wled->auto_calibration_ovp_count++;
+ } else {
+ elapsed_time_us = ktime_us_delta(ktime_get(),
+ wled->start_ovp_fault_time);
+ if (elapsed_time_us > WLED_AUTO_CAL_CNT_DLY_US)
+ wled->auto_calibration_ovp_count = 0;
+ else
+ wled->auto_calibration_ovp_count++;
+
+ if (wled->auto_calibration_ovp_count >=
+ WLED_AUTO_CAL_OVP_COUNT) {
+ wled->auto_calibration_ovp_count = 0;
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* ovp irq handler */
static irqreturn_t qpnp_wled_ovp_irq_handler(int irq, void *_wled)
{
@@ -1114,6 +1339,21 @@
if (fault_sts & (QPNP_WLED_OVP_FAULT_BIT | QPNP_WLED_ILIM_FAULT_BIT))
pr_err("WLED OVP fault detected, int_sts=%x fault_sts= %x\n",
int_sts, fault_sts);
+
+ if (fault_sts & QPNP_WLED_OVP_FAULT_BIT) {
+ if (wled->auto_calib_enabled && !wled->auto_calib_done) {
+ if (qpnp_wled_auto_cal_required(wled)) {
+ rc = wled_auto_calibrate(wled);
+ if (rc < 0) {
+ pr_err("Failed auto-calibration rc=%d\n",
+ rc);
+ return IRQ_HANDLED;
+ }
+ wled->auto_calib_done = true;
+ }
+ }
+ }
+
return IRQ_HANDLED;
}
@@ -1423,7 +1663,7 @@
static int qpnp_wled_config(struct qpnp_wled *wled)
{
int rc, i, temp;
- u8 reg = 0;
+ u8 reg = 0, sink_en = 0, mask;
/* Configure display type */
rc = qpnp_wled_set_disp(wled, wled->ctrl_base);
@@ -1622,16 +1862,50 @@
rc = qpnp_wled_write_reg(wled, QPNP_WLED_CURR_SINK_REG(wled->sink_base),
reg);
+ for (i = 0; i < wled->max_strings; i++) {
+ /* SYNC DELAY */
+ if (wled->sync_dly_us > QPNP_WLED_SYNC_DLY_MAX_US)
+ wled->sync_dly_us = QPNP_WLED_SYNC_DLY_MAX_US;
+
+ reg = wled->sync_dly_us / QPNP_WLED_SYNC_DLY_STEP_US;
+ mask = QPNP_WLED_SYNC_DLY_MASK;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_SYNC_DLY_REG(wled->sink_base, i),
+ mask, reg);
+ if (rc < 0)
+ return rc;
+
+ /* FULL SCALE CURRENT */
+ if (wled->fs_curr_ua > QPNP_WLED_FS_CURR_MAX_UA)
+ wled->fs_curr_ua = QPNP_WLED_FS_CURR_MAX_UA;
+
+ reg = wled->fs_curr_ua / QPNP_WLED_FS_CURR_STEP_UA;
+ mask = QPNP_WLED_FS_CURR_MASK;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_FS_CURR_REG(wled->sink_base, i),
+ mask, reg);
+ if (rc < 0)
+ return rc;
+
+ /* CABC */
+ reg = wled->en_cabc ? (1 << QPNP_WLED_CABC_SHIFT) : 0;
+ mask = QPNP_WLED_CABC_MASK;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_CABC_REG(wled->sink_base, i),
+ mask, reg);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* Settings specific to valid sinks */
for (i = 0; i < wled->num_strings; i++) {
- if (wled->strings[i] >= QPNP_WLED_MAX_STRINGS) {
+ if (wled->strings[i] >= wled->max_strings) {
dev_err(&wled->pdev->dev, "Invalid string number\n");
return -EINVAL;
}
-
/* MODULATOR */
rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_MOD_EN_REG(wled->sink_base,
- wled->strings[i]), ®);
+ QPNP_WLED_MOD_EN_REG(wled->sink_base, i), ®);
if (rc < 0)
return rc;
reg &= QPNP_WLED_MOD_EN_MASK;
@@ -1643,72 +1917,22 @@
reg |= ~QPNP_WLED_GATE_DRV_MASK;
rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_MOD_EN_REG(wled->sink_base,
- wled->strings[i]), reg);
+ QPNP_WLED_MOD_EN_REG(wled->sink_base, i), reg);
if (rc)
return rc;
- /* SYNC DELAY */
- if (wled->sync_dly_us > QPNP_WLED_SYNC_DLY_MAX_US)
- wled->sync_dly_us = QPNP_WLED_SYNC_DLY_MAX_US;
-
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
- wled->strings[i]), ®);
- if (rc < 0)
- return rc;
- reg &= QPNP_WLED_SYNC_DLY_MASK;
- temp = wled->sync_dly_us / QPNP_WLED_SYNC_DLY_STEP_US;
- reg |= temp;
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
- wled->strings[i]), reg);
- if (rc)
- return rc;
-
- /* FULL SCALE CURRENT */
- if (wled->fs_curr_ua > QPNP_WLED_FS_CURR_MAX_UA)
- wled->fs_curr_ua = QPNP_WLED_FS_CURR_MAX_UA;
-
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]), ®);
- if (rc < 0)
- return rc;
- reg &= QPNP_WLED_FS_CURR_MASK;
- temp = wled->fs_curr_ua / QPNP_WLED_FS_CURR_STEP_UA;
- reg |= temp;
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]), reg);
- if (rc)
- return rc;
-
- /* CABC */
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_CABC_REG(wled->sink_base,
- wled->strings[i]), ®);
- if (rc < 0)
- return rc;
- reg &= QPNP_WLED_CABC_MASK;
- reg |= (wled->en_cabc << QPNP_WLED_CABC_SHIFT);
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_CABC_REG(wled->sink_base,
- wled->strings[i]), reg);
- if (rc)
- return rc;
-
- /* Enable CURRENT SINK */
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_CURR_SINK_REG(wled->sink_base), ®);
- if (rc < 0)
- return rc;
+ /* SINK EN */
temp = wled->strings[i] + QPNP_WLED_CURR_SINK_SHIFT;
- reg |= (1 << temp);
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_CURR_SINK_REG(wled->sink_base), reg);
- if (rc)
- return rc;
+ sink_en |= (1 << temp);
+ }
+ mask = QPNP_WLED_CURR_SINK_MASK;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base),
+ mask, sink_en);
+ if (rc < 0) {
+ dev_err(&wled->pdev->dev,
+ "Failed to enable WLED sink config rc = %d\n", rc);
+ return rc;
}
rc = qpnp_wled_sync_reg_toggle(wled);
@@ -1728,8 +1952,13 @@
wled->ovp_irq, rc);
return rc;
}
- disable_irq(wled->ovp_irq);
- wled->ovp_irq_disabled = true;
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base), ®);
+ /* disable the OVP irq only if the module is not enabled */
+ if (!rc && !(reg & QPNP_WLED_MODULE_EN_MASK)) {
+ disable_irq(wled->ovp_irq);
+ wled->ovp_irq_disabled = true;
+ }
}
if (wled->sc_irq >= 0) {
@@ -2091,11 +2320,16 @@
wled->en_cabc = of_property_read_bool(pdev->dev.of_node,
"qcom,en-cabc");
+ if (wled->pmic_rev_id->pmic_subtype == PM660L_SUBTYPE)
+ wled->max_strings = QPNP_PM660_WLED_MAX_STRINGS;
+ else
+ wled->max_strings = QPNP_WLED_MAX_STRINGS;
+
prop = of_find_property(pdev->dev.of_node,
"qcom,led-strings-list", &temp_val);
if (!prop || !temp_val || temp_val > QPNP_WLED_MAX_STRINGS) {
dev_err(&pdev->dev, "Invalid strings info, use default");
- wled->num_strings = QPNP_WLED_MAX_STRINGS;
+ wled->num_strings = wled->max_strings;
for (i = 0; i < wled->num_strings; i++)
wled->strings[i] = i;
} else {
@@ -2118,6 +2352,9 @@
wled->lcd_psm_ctrl = of_property_read_bool(pdev->dev.of_node,
"qcom,lcd-psm-ctrl");
+
+ wled->auto_calib_enabled = of_property_read_bool(pdev->dev.of_node,
+ "qcom,auto-calibration-enable");
return 0;
}
@@ -2186,13 +2423,13 @@
}
mutex_init(&wled->bus_lock);
+ mutex_init(&wled->lock);
rc = qpnp_wled_config(wled);
if (rc) {
dev_err(&pdev->dev, "wled config failed\n");
return rc;
}
- mutex_init(&wled->lock);
INIT_WORK(&wled->work, qpnp_wled_work);
wled->ramp_ms = QPNP_WLED_RAMP_DLY_MS;
wled->ramp_step = 1;
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index e868f92..f2d39a9 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -448,7 +448,7 @@
bytes_read = 0;
}
} else {
- if (bytes_read)
+ if (bytes_read) {
/*
* data was read beyond the non-data event,
* making it not relevant anymore
@@ -459,6 +459,7 @@
if (!(events->event_mask.no_wakeup_mask &
event->type))
events->wakeup_events_counter--;
+ }
}
events->read_index = events->notified_index;
diff --git a/drivers/media/platform/msm/broadcast/tspp.c b/drivers/media/platform/msm/broadcast/tspp.c
index 44193f5..2c90e47 100644
--- a/drivers/media/platform/msm/broadcast/tspp.c
+++ b/drivers/media/platform/msm/broadcast/tspp.c
@@ -47,6 +47,7 @@
#include <linux/msm-bus.h>
#include <linux/interrupt.h> /* tasklet */
#include <asm/arch_timer.h> /* Timer */
+#include <linux/dma-buf.h>
/*
* General defines
@@ -495,7 +496,6 @@
struct tspp_pinctrl pinctrl;
unsigned int tts_source; /* Time stamp source type LPASS timer/TCR */
struct dma_iommu_mapping *iommu_mapping;
- bool bypass_s1_smmu;
struct dentry *dent;
struct dentry *debugfs_regs[ARRAY_SIZE(debugfs_tspp_regs)];
@@ -1068,7 +1068,6 @@
static int tspp_iommu_init(struct tspp_device *device)
{
struct dma_iommu_mapping *iommu_map;
- int s1_bypass = 1;
iommu_map = arm_iommu_create_mapping(&platform_bus_type,
TSPP_SMMU_IOVA_START,
@@ -1077,12 +1076,6 @@
dev_err(&device->pdev->dev, "iommu_create_mapping failure\n");
return PTR_ERR(iommu_map);
}
- if (iommu_domain_set_attr(iommu_map->domain,
- DOMAIN_ATTR_S1_BYPASS, &s1_bypass)) {
- dev_err(&device->pdev->dev, "Can't bypass s1 translation\n");
- arm_iommu_release_mapping(iommu_map);
- return -EIO;
- }
if (arm_iommu_attach_device(&device->pdev->dev, iommu_map)) {
dev_err(&device->pdev->dev, "can't arm_iommu_attach_device\n");
arm_iommu_release_mapping(iommu_map);
@@ -1095,7 +1088,7 @@
static void tspp_iommu_release_iomapping(struct tspp_device *device)
{
- if (device->bypass_s1_smmu && device->iommu_mapping)
+ if (device->iommu_mapping)
arm_iommu_release_mapping(device->iommu_mapping);
device->iommu_mapping = NULL;
@@ -1113,7 +1106,7 @@
if (alloc) {
TSPP_DEBUG("tspp using alloc function");
desc->virt_base = alloc(channel_id, size,
- &desc->phys_base, user);
+ &desc->phys_base, &desc->dma_base, user);
} else {
if (!dma_pool)
desc->virt_base = dma_alloc_coherent(NULL, size,
@@ -2605,7 +2598,8 @@
desc->next = channel->data;
/* prepare the sps descriptor */
- desc->sps.phys_base = desc->desc.phys_base;
+ desc->sps.phys_base = ((alloc != NULL) ? desc->desc.dma_base :
+ desc->desc.phys_base);
desc->sps.base = desc->desc.virt_base;
desc->sps.size = desc->desc.size;
@@ -2643,6 +2637,121 @@
}
EXPORT_SYMBOL(tspp_allocate_buffers);
+/**
+ * tspp_attach_ion_dma_buff- attach ion dma buffer to TSPP device
+ * It will attach the DMA buffer to TSPP device to go through SMMU.
+ *
+ * @dev: TSPP device (up to TSPP_MAX_DEVICES)
+ * @ion_dma_buf: It contains required members for ION buffer dma mapping.
+ *
+ * Return error status
+ *
+ */
+int tspp_attach_ion_dma_buff(u32 dev, struct tspp_ion_dma_buf_info *ion_dma_buf)
+{
+ struct tspp_device *pdev;
+ int dir = DMA_FROM_DEVICE;
+ int ret = -1;
+
+ if (NULL == ion_dma_buf || NULL == ion_dma_buf->dbuf) {
+ pr_err("tspp: invalid input argument");
+ return -EINVAL;
+ }
+
+ if (dev >= TSPP_MAX_DEVICES) {
+ pr_err("tspp: device id out of range");
+ return -ENODEV;
+ }
+
+ pdev = tspp_find_by_id(dev);
+ if (!pdev) {
+ pr_err("tspp: can't find device %i", dev);
+ return -ENODEV;
+ }
+
+ ion_dma_buf->attach = dma_buf_attach(ion_dma_buf->dbuf,
+ &pdev->pdev->dev);
+ if (IS_ERR_OR_NULL(ion_dma_buf->attach)) {
+ dev_err(&pdev->pdev->dev, "%s: dma_buf_attach fail", __func__);
+ return -ENODEV;
+ }
+ ion_dma_buf->table = dma_buf_map_attachment(ion_dma_buf->attach, dir);
+ if (IS_ERR_OR_NULL(ion_dma_buf->table)) {
+ dev_err(&pdev->pdev->dev, "dma_buf_map_attachment fail");
+ dma_buf_detach(ion_dma_buf->dbuf, ion_dma_buf->attach);
+ return -ENODEV;
+ }
+ ret = dma_map_sg(&pdev->pdev->dev, ion_dma_buf->table->sgl,
+ ion_dma_buf->table->nents, dir);
+ if (ret <= 0) {
+ dev_err(&pdev->pdev->dev, "dma_map_sg failed! ret=%d\n", ret);
+ goto unmap_attachment;
+ }
+ if (ion_dma_buf->table->nents > 1) {
+ dev_err(&pdev->pdev->dev, "no of sg table entries %d > 1\n",
+ ion_dma_buf->table->nents);
+ goto unmap_attachment;
+ }
+
+ ion_dma_buf->dma_map_base = sg_dma_address(ion_dma_buf->table->sgl);
+ ion_dma_buf->smmu_map = true;
+ return 0;
+
+unmap_attachment:
+ dma_buf_unmap_attachment(ion_dma_buf->attach, ion_dma_buf->table, dir);
+ dma_buf_detach(ion_dma_buf->dbuf, ion_dma_buf->attach);
+ dma_buf_put(ion_dma_buf->dbuf);
+
+ return ret;
+}
+EXPORT_SYMBOL(tspp_attach_ion_dma_buff);
+
+/**
+ * tspp_detach_ion_dma_buff - detach the mapped ion dma buffer from TSPP device
+ * It will detach previously mapped DMA buffer from TSPP device.
+ *
+ * @dev: TSPP device (up to TSPP_MAX_DEVICES)
+ * @ion_dma_buf: It contains required members for ION buffer dma mapping.
+ *
+ * Return error status
+ *
+ */
+int tspp_detach_ion_dma_buff(u32 dev, struct tspp_ion_dma_buf_info *ion_dma_buf)
+{
+ struct tspp_device *pdev;
+ int dir = DMA_FROM_DEVICE;
+
+ if (ion_dma_buf == NULL || ion_dma_buf->dbuf == NULL ||
+ ion_dma_buf->table == NULL || ion_dma_buf->table->sgl == NULL ||
+ ion_dma_buf->smmu_map == false) {
+ pr_err("tspp: invalid input argument");
+ return -EINVAL;
+ }
+
+ if (dev >= TSPP_MAX_DEVICES) {
+ pr_err("tspp: device id out of range");
+ return -ENODEV;
+ }
+
+ pdev = tspp_find_by_id(dev);
+ if (!pdev) {
+ pr_err("tspp: can't find device %i", dev);
+ return -ENODEV;
+ }
+
+
+ dma_unmap_sg(&pdev->pdev->dev, ion_dma_buf->table->sgl,
+ ion_dma_buf->table->nents, dir);
+ dma_buf_unmap_attachment(ion_dma_buf->attach, ion_dma_buf->table, dir);
+ dma_buf_detach(ion_dma_buf->dbuf, ion_dma_buf->attach);
+ dma_buf_put(ion_dma_buf->dbuf);
+
+ ion_dma_buf->smmu_map = false;
+ return 0;
+}
+EXPORT_SYMBOL(tspp_detach_ion_dma_buff);
+
+
/*** debugfs ***/
static int debugfs_iomem_x32_set(void *data, u64 val)
{
@@ -3002,12 +3111,9 @@
goto err_irq;
device->req_irqs = false;
- if (of_property_read_bool(pdev->dev.of_node, "qcom,smmu-s1-bypass")) {
- device->bypass_s1_smmu = true;
- if (tspp_iommu_init(device)) {
- dev_err(&pdev->dev, "iommu init failed");
- goto err_iommu;
- }
+ if (tspp_iommu_init(device)) {
+ dev_err(&pdev->dev, "iommu init failed");
+ goto err_iommu;
}
device->tts_source = TSIF_TTS_TCR;
@@ -3152,6 +3258,9 @@
if (device->tsif_vreg)
regulator_disable(device->tsif_vreg);
+ tspp_iommu_release_iomapping(device);
+ arm_iommu_detach_device(&pdev->dev);
+
pm_runtime_disable(&pdev->dev);
kfree(device);
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 a430466..1ee82b5 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
@@ -34,6 +34,11 @@
struct cam_hw_done_event_data *done =
(struct cam_hw_done_event_data *)done_event_data;
+ if (!ctx || !done) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, done);
+ return -EINVAL;
+ }
+
if (list_empty(&ctx->active_req_list)) {
CAM_ERR(CAM_CTXT, "no active request");
return -EIO;
@@ -78,6 +83,12 @@
struct cam_ctx_request *req;
struct cam_hw_config_args cfg;
+ if (!ctx || !apply) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, apply);
+ rc = -EINVAL;
+ goto end;
+ }
+
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
rc = -EFAULT;
@@ -119,6 +130,11 @@
struct cam_ctx_request *req = NULL;
struct cam_req_mgr_apply_request apply;
+ if (!ctx) {
+ CAM_ERR(CAM_CTXT, "Invalid input param");
+ return;
+ }
+
spin_lock(&ctx->lock);
if (!list_empty(&ctx->pending_req_list))
req = list_first_entry(&ctx->pending_req_list,
@@ -144,6 +160,11 @@
struct cam_hw_release_args arg;
struct cam_ctx_request *req;
+ if (!ctx) {
+ CAM_ERR(CAM_CTXT, "Invalid input param");
+ return -EINVAL;
+ }
+
if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
return -EINVAL;
@@ -209,6 +230,12 @@
size_t len = 0;
int32_t i = 0;
+ if (!ctx || !cmd) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+ rc = -EINVAL;
+ goto end;
+ }
+
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
rc = -EFAULT;
@@ -304,6 +331,12 @@
struct cam_create_dev_hdl req_hdl_param;
struct cam_hw_release_args release;
+ if (!ctx || !cmd) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+ rc = -EINVAL;
+ goto end;
+ }
+
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
rc = -EFAULT;
@@ -377,6 +410,12 @@
int rc = 0;
struct cam_hw_start_args arg;
+ if (!ctx || !cmd) {
+ CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+ rc = -EINVAL;
+ goto end;
+ }
+
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
rc = -EFAULT;
@@ -392,6 +431,7 @@
}
if (ctx->hw_mgr_intf->hw_start) {
+ arg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
&arg);
if (rc) {
@@ -412,6 +452,12 @@
struct cam_hw_stop_args stop;
struct cam_ctx_request *req;
+ if (!ctx) {
+ CAM_ERR(CAM_CTXT, "Invalid input param");
+ rc = -EINVAL;
+ goto end;
+ }
+
if (!ctx->hw_mgr_intf) {
CAM_ERR(CAM_CTXT, "HW interface is not ready");
rc = -EFAULT;
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c
index 32ef2e4..d9133b9 100644
--- a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c
+++ b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c
@@ -20,6 +20,7 @@
#include "cam_io_util.h"
#include "cam_cpas_soc.h"
#include "cpastop100.h"
+#include "cpastop_v170_110.h"
struct cam_camnoc_info *camnoc_info;
@@ -420,6 +421,10 @@
(hw_caps->cpas_version.minor == 0) &&
(hw_caps->cpas_version.incr == 0)) {
camnoc_info = &cam170_cpas100_camnoc_info;
+ } else if ((hw_caps->cpas_version.major == 1) &&
+ (hw_caps->cpas_version.minor == 1) &&
+ (hw_caps->cpas_version.incr == 0)) {
+ camnoc_info = &cam170_cpas110_camnoc_info;
} else {
CAM_ERR(CAM_CPAS, "CPAS Version not supported %d.%d.%d",
hw_caps->cpas_version.major,
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop_v170_110.h b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop_v170_110.h
new file mode 100644
index 0000000..f4d0e36
--- /dev/null
+++ b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop_v170_110.h
@@ -0,0 +1,542 @@
+/* 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.
+ */
+
+#ifndef _CPASTOP_V170_110_H_
+#define _CPASTOP_V170_110_H_
+
+#define TEST_IRQ_ENABLE 0
+
+static struct cam_camnoc_irq_sbm cam_cpas110_irq_sbm = {
+ .sbm_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2040, /* SBM_FAULTINEN0_LOW */
+ .value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
+ 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
+ 0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
+ 0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
+ 0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
+ 0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
+ (TEST_IRQ_ENABLE ?
+ 0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
+ 0x0),
+ },
+ .sbm_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
+ },
+ .sbm_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
+ .value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
+ }
+};
+
+static struct cam_camnoc_irq_err
+ cam_cpas110_irq_err[] = {
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
+ .enable = true,
+ .sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x1190,
+ /* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
+ .enable = true,
+ .sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
+ .enable = TEST_IRQ_ENABLE ? true : false,
+ .sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x5,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+};
+
+static struct cam_camnoc_specific
+ cam_cpas110_camnoc_specific[] = {
+ {
+ .port_type = CAM_CAMNOC_CDM,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
+ .mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
+ .shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
+ .value = 0,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE02,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
+ .value = 0x3,
+ },
+ .ubwc_ctl = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x588, /* SPECIFIC_IFE02_ENCCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE13,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
+ .value = 0x3,
+ },
+ .ubwc_ctl = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x988, /* SPECIFIC_IFE13_ENCCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
+ .mask = 0x7,
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
+ .shift = 0x0,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_JPEG,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
+ .value = 0x22,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_FD,
+ .enable = false,
+ },
+ {
+ .port_type = CAM_CAMNOC_ICP,
+ .enable = false,
+ }
+};
+
+static uint32_t cam_cpas110_slave_error_logger[] = {
+ 0x2700, /* ERRLOGGER_SWID_LOW */
+ 0x2704, /* ERRLOGGER_SWID_HIGH */
+ 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
+ 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
+ 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
+ 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
+ 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
+ 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
+ 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
+ 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
+};
+
+static struct cam_cpas_hw_errata_wa_list cam170_cpas110_errata_wa_list = {
+ .camnoc_flush_slave_pending_trans = {
+ .enable = true,
+ .data.reg_info = {
+ .access_type = CAM_REG_TYPE_READ,
+ .offset = 0x2100, /* SidebandManager_SenseIn0_Low */
+ .mask = 0xE0000, /* Bits 17, 18, 19 */
+ .value = 0, /* expected to be 0 */
+ },
+ },
+};
+
+static struct cam_camnoc_info cam170_cpas110_camnoc_info = {
+ .specific = &cam_cpas110_camnoc_specific[0],
+ .specific_size = sizeof(cam_cpas110_camnoc_specific) /
+ sizeof(cam_cpas110_camnoc_specific[0]),
+ .irq_sbm = &cam_cpas110_irq_sbm,
+ .irq_err = &cam_cpas110_irq_err[0],
+ .irq_err_size = sizeof(cam_cpas110_irq_err) /
+ sizeof(cam_cpas110_irq_err[0]),
+ .error_logger = &cam_cpas110_slave_error_logger[0],
+ .error_logger_size = sizeof(cam_cpas110_slave_error_logger) /
+ sizeof(cam_cpas110_slave_error_logger[0]),
+ .errata_wa_list = &cam170_cpas110_errata_wa_list,
+};
+
+#endif /* _CPASTOP_V170_110_H_ */
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 f37ec38..5d7a1b9 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
@@ -650,6 +650,8 @@
switch (out_fmt) {
case CAM_FORMAT_NV21:
case CAM_FORMAT_NV12:
+ case CAM_FORMAT_UBWC_NV12:
+ case CAM_FORMAT_UBWC_NV12_4R:
return PACKER_FMT_PLAIN_8_LSB_MSB_10;
case CAM_FORMAT_PLAIN64:
return PACKER_FMT_PLAIN_64;
@@ -660,10 +662,6 @@
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_PLAIN8:
case CAM_FORMAT_PLAIN16_8:
@@ -675,6 +673,9 @@
case CAM_FORMAT_PD8:
case CAM_FORMAT_PD10:
return PACKER_FMT_PLAIN_128;
+ case CAM_FORMAT_UBWC_TP10:
+ case CAM_FORMAT_TP10:
+ return PACKER_FMT_TP_10;
default:
return PACKER_FMT_MAX;
}
@@ -721,6 +722,7 @@
rsrc_data->height = out_port_info->height;
if (rsrc_data->index < 3) {
+ /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
rsrc_data->height = 0;
rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
@@ -728,50 +730,59 @@
rsrc_data->en_cfg = 0x3;
} else if (rsrc_data->index < 5 ||
rsrc_data->index == 7 || rsrc_data->index == 8) {
- switch (plane) {
- case PLANE_Y:
- switch (rsrc_data->format) {
- case CAM_FORMAT_UBWC_NV12:
- case CAM_FORMAT_UBWC_NV12_4R:
- case CAM_FORMAT_UBWC_TP10:
- rsrc_data->en_ubwc = 1;
+ /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
+ switch (rsrc_data->format) {
+ case CAM_FORMAT_UBWC_NV12:
+ case CAM_FORMAT_UBWC_NV12_4R:
+ rsrc_data->en_ubwc = 1;
+ /* Fall through for NV12 */
+ case CAM_FORMAT_NV21:
+ case CAM_FORMAT_NV12:
+ switch (plane) {
+ case PLANE_C:
+ rsrc_data->height /= 2;
+ break;
+ case PLANE_Y:
break;
default:
- break;
+ CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+ return -EINVAL;
}
break;
- case PLANE_C:
- switch (rsrc_data->format) {
- case CAM_FORMAT_NV21:
- case CAM_FORMAT_NV12:
+ case CAM_FORMAT_UBWC_TP10:
+ rsrc_data->en_ubwc = 1;
+ /* Fall through for LINEAR TP10 */
+ case CAM_FORMAT_TP10:
+ rsrc_data->width = rsrc_data->width * 4 / 3;
+ switch (plane) {
+ case PLANE_C:
rsrc_data->height /= 2;
break;
- case CAM_FORMAT_UBWC_NV12:
- case CAM_FORMAT_UBWC_NV12_4R:
- case CAM_FORMAT_UBWC_TP10:
- rsrc_data->height /= 2;
- rsrc_data->en_ubwc = 1;
+ case PLANE_Y:
break;
default:
- break;
+ CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
+ return -EINVAL;
}
break;
default:
- CAM_ERR(CAM_ISP, "Invalid plane type %d", plane);
+ CAM_ERR(CAM_ISP, "Invalid format %d\n",
+ rsrc_data->format);
return -EINVAL;
}
rsrc_data->en_cfg = 0x1;
} else if (rsrc_data->index >= 11) {
+ /* Write master 11-19 stats */
rsrc_data->width = 0;
rsrc_data->height = 0;
rsrc_data->stride = 1;
rsrc_data->en_cfg = 0x3;
} else {
+ /* Write master 5-6 DS ports , 9 - Raw dump , 10 PDAF */
rsrc_data->width = rsrc_data->width * 4;
rsrc_data->height = rsrc_data->height / 2;
rsrc_data->en_cfg = 0x1;
}
-
if (vfe_out_res_id >= CAM_ISP_IFE_OUT_RES_RDI_0 &&
vfe_out_res_id <= CAM_ISP_IFE_OUT_RES_RDI_3)
rsrc_data->frame_based = 1;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
index c69eeaa..975b301 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -145,13 +145,13 @@
void __iomem *base = soc_info->reg_map[0].mem_base;
if (!cci_dev) {
- CAM_ERR(CAM_CCI, "%s: failed %d");
+ CAM_ERR(CAM_CCI, "Failed");
return -EINVAL;
}
rc = cam_cci_validate_queue(cci_dev, 1, master, queue);
if (rc < 0) {
- CAM_ERR(CAM_CCI, "Failed %d");
+ CAM_ERR(CAM_CCI, "Failed %d", rc);
return rc;
}
CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x",
@@ -184,42 +184,43 @@
uint32_t reg_offset = 0;
/* CCI Top Registers */
- CCI_DBG(" **** %s : %d CCI TOP Registers ****");
+ CAM_DBG(CAM_CCI, "****CCI TOP Registers ****");
for (i = 0; i < DEBUG_TOP_REG_COUNT; i++) {
reg_offset = DEBUG_TOP_REG_START + i * 4;
read_val = cam_io_r_mb(cci_dev->base + reg_offset);
- CCI_DBG("offset = 0x%X value = 0x%X",
+ CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
reg_offset, read_val);
}
/* CCI Master registers */
- CCI_DBG(" ****CCI MASTER %d Registers ****",
+ CAM_DBG(CAM_CCI, "****CCI MASTER %d Registers ****",
master);
for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) {
if (i == 6)
continue;
reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4;
read_val = cam_io_r_mb(cci_dev->base + reg_offset);
- CCI_DBG("offset = 0x%X value = 0x%X", reg_offset, read_val);
+ CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
+ reg_offset, read_val);
}
/* CCI Master Queue registers */
- CCI_DBG(" **** CCI MASTER%d QUEUE%d Registers ****",
+ CAM_DBG(CAM_CCI, " **** CCI MASTER%d QUEUE%d Registers ****",
master, queue);
for (i = 0; i < DEBUG_MASTER_QUEUE_REG_COUNT; i++) {
reg_offset = DEBUG_MASTER_QUEUE_REG_START + master*0x200 +
queue*0x100 + i * 4;
read_val = cam_io_r_mb(cci_dev->base + reg_offset);
- CCI_DBG("offset = 0x%X value = 0x%X",
+ CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
reg_offset, read_val);
}
/* CCI Interrupt registers */
- CCI_DBG(" ****CCI Interrupt Registers ****");
+ CAM_DBG(CAM_CCI, " ****CCI Interrupt Registers ****");
for (i = 0; i < DEBUG_INTR_REG_COUNT; i++) {
reg_offset = DEBUG_INTR_REG_START + i * 4;
read_val = cam_io_r_mb(cci_dev->base + reg_offset);
- CCI_DBG("offset = 0x%X value = 0x%X",
+ CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
reg_offset, read_val);
}
}
@@ -449,8 +450,7 @@
}
if (len > cci_dev->payload_size) {
- CAM_ERR(CAM_CCI, "%s: %d Len error: %d",
- len);
+ CAM_ERR(CAM_CCI, "Len error: %d", len);
return -EINVAL;
}
@@ -660,7 +660,7 @@
rc = cam_cci_lock_queue(cci_dev, master, queue, 1);
if (rc < 0) {
- CAM_ERR(CAM_CCI, "%s failed line %d");
+ CAM_ERR(CAM_CCI, "failed line %d", rc);
return rc;
}
@@ -670,7 +670,7 @@
len = cam_cci_calc_cmd_len(cci_dev, c_ctrl, cmd_size,
i2c_cmd, &pack);
if (len <= 0) {
- CAM_ERR(CAM_CCI, "%s failed line %d");
+ CAM_ERR(CAM_CCI, "failed");
return -EINVAL;
}
@@ -918,7 +918,7 @@
val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR
+ master * 0x200 + queue * 0x100);
- CAM_DBG(CAM_CCI, "%s cur word cnt 0x%x", val);
+ CAM_DBG(CAM_CCI, "cur word cnt 0x%x", val);
cam_io_w_mb(val, base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR
+ master * 0x200 + queue * 0x100);
@@ -989,7 +989,7 @@
cci_dev = v4l2_get_subdevdata(sd);
if (cci_dev->cci_state != CCI_STATE_ENABLED) {
- CAM_ERR(CAM_CCI, "%s invalid cci state %d",
+ CAM_ERR(CAM_CCI, "invalid cci state %d",
cci_dev->cci_state);
return -EINVAL;
}
@@ -1013,8 +1013,8 @@
cci_dev->cci_i2c_queue_info[master][queue].max_queue_size-1,
master, queue);
if (rc < 0) {
- CAM_ERR(CAM_CCI, "%s:%d Initial validataion failed rc %d",
- rc);
+ CAM_ERR(CAM_CCI, "Initial validataion failed rc %d",
+ rc);
return rc;
}
if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
index ea6b7c8..a79e0d4 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
@@ -14,6 +14,29 @@
#include "cam_csiphy_core.h"
#include "include/cam_csiphy_1_0_hwreg.h"
+#ifdef CAM_CSIPHY_MEM_DMP
+int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
+{
+ int32_t rc = 0;
+ resource_size_t size = 0;
+ void __iomem *addr = NULL;
+
+ if (!soc_info) {
+ rc = -EINVAL;
+ CAM_ERR(CAM_CSIPHY, "invalid input %d", rc);
+ return rc;
+ }
+ addr = soc_info->reg_map[0].mem_base;
+ size = resource_size(soc_info->mem_block[0]);
+ rc = cam_io_dump(addr, 0, (size >> 2));
+ if (rc < 0) {
+ CAM_ERR(CAM_CSIPHY, "generating dump failed %d", rc);
+ return rc;
+ }
+ return rc;
+}
+#endif
+
int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
{
int32_t rc = 0;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
index 94ec79f..4430489 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
@@ -67,4 +67,12 @@
*/
int cam_csiphy_disable_hw(struct csiphy_device *csiphy_dev);
+/**
+ * @soc_info: Soc info of cam hw driver module
+ *
+ * This API dumps memory for the entire mapped region
+ * (needs to be macro enabled before use)
+ */
+int cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info);
+
#endif /* _CAM_CSIPHY_SOC_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c
index 1453fb3..40cf689 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c
@@ -27,7 +27,7 @@
rc = cam_sensor_driver_cmd(s_ctrl, arg);
break;
default:
- CAM_ERR(CAM_SENSOR, " Invalid ioctl cmd: %d", cmd);
+ CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
rc = -EINVAL;
break;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c
index c2f1b4d..c10d634 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_soc.c
@@ -218,7 +218,6 @@
/* Initialize mutex */
mutex_init(&(s_ctrl->cam_sensor_mutex));
- CAM_DBG(CAM_SENSOR, "%s: %d");
/* Initialize default parameters */
for (i = 0; i < soc_info->num_clk; i++) {
soc_info->clk[i] = devm_clk_get(&soc_info->pdev->dev,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c
index 915e2f7..ca648f01 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c
@@ -206,7 +206,6 @@
int32_t rc = 0;
struct cam_cci_ctrl cci_ctrl;
- CAM_DBG(CAM_SENSOR, "%s line %d");
cci_ctrl.cmd = cci_cmd;
cci_ctrl.cci_info = cci_client;
rc = v4l2_subdev_call(cci_client->cci_subdev,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
index 9e38e1a..154f4ad 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
@@ -10,14 +10,9 @@
* GNU General Public License for more details.
*/
-#define pr_fmt(fmt) "CAM-SENSOR_IO %s:%d " fmt, __func__, __LINE__
-
#include "cam_sensor_io.h"
#include "cam_sensor_i2c.h"
-#undef CDBG
-#define CDBG(fmt, args...) pr_debug(fmt, ##args)
-
int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
uint32_t addr, uint16_t data, uint32_t data_mask,
enum camera_sensor_i2c_type data_type,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c
index b64e0d0..72e51ee 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c
@@ -40,7 +40,7 @@
};
rc = i2c_transfer(dev_client->adapter, msgs, 2);
if (rc < 0)
- CAM_ERR(CAM_SENSOR, "%s:failed 0x%x", saddr);
+ CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr);
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
index e0b737e..4011aa0 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_spi.c
@@ -220,7 +220,7 @@
msleep(client->spi_client->retry_delay);
}
if (rc < 0) {
- pr_err("%s: failed %d\n", __func__, rc);
+ CAM_ERR(CAM_SENSOR, "failed %d", rc);
goto out;
}
if (data && num_byte && !rx)
@@ -248,7 +248,7 @@
&client->spi_client->cmd_tbl.read, addr, &temp[0],
data_type, NULL, NULL);
if (rc < 0) {
- pr_err("%s: failed %d\n", __func__, rc);
+ CAM_ERR(CAM_SENSOR, "failed %d", rc);
return rc;
}
@@ -257,7 +257,7 @@
else
*data = (temp[0] << BITS_PER_BYTE) | temp[1];
- CAM_DBG(CAM_SENSOR, "addr 0x%x, data %u\n", addr, *data);
+ CAM_DBG(CAM_SENSOR, "addr 0x%x, data %u", addr, *data);
return rc;
}
@@ -276,8 +276,8 @@
&client->spi_client->cmd_tbl.read_status;
if (rs->addr_len != 0) {
- pr_err("%s: not implemented yet\n", __func__);
- return -EINVAL;
+ CAM_ERR(CAM_SENSOR, "not implemented yet");
+ return -ENXIO;
}
return cam_spi_tx_helper(client, rs, 0, status, 1, NULL, NULL);
}
@@ -290,7 +290,7 @@
rc = cam_spi_read_status_reg(client, &st);
if (rc < 0) {
- pr_err("%s: failed to read status reg\n", __func__);
+ CAM_ERR(CAM_SENSOR, "failed to read status reg");
return rc;
}
*busy = st & client->spi_client->busy_mask;
@@ -314,7 +314,7 @@
CAM_DBG(CAM_SENSOR, "op 0x%x wait", inst->opcode);
}
if (i > inst->delay_count) {
- pr_err("%s: op %x timed out\n", __func__, inst->opcode);
+ CAM_ERR(CAM_SENSOR, "op %x timed out", inst->opcode);
return -ETIMEDOUT;
}
CAM_DBG(CAM_SENSOR, "op %x finished", inst->opcode);
@@ -331,12 +331,12 @@
if (we->opcode == 0)
return 0;
if (we->addr_len != 0) {
- pr_err("%s: not implemented yet\n", __func__);
+ CAM_ERR(CAM_SENSOR, "not implemented yet");
return -EINVAL;
}
rc = cam_spi_tx_helper(client, we, 0, NULL, 0, NULL, NULL);
if (rc < 0)
- pr_err("%s: write enable failed\n", __func__);
+ CAM_ERR(CAM_SENSOR, "write enable failed");
return rc;
}
@@ -372,7 +372,7 @@
tx[0] = pg->opcode;
cam_set_addr(addr, pg->addr_len, addr_type, tx + 1);
memcpy(tx + header_len, data, len);
- CAM_DBG(CAM_SENSOR, "tx(%u): %02x %02x %02x %02x\n",
+ CAM_DBG(CAM_SENSOR, "tx(%u): %02x %02x %02x %02x",
len, tx[0], tx[1], tx[2], tx[3]);
while ((rc = spi_write(spi, tx, len + header_len)) && retries) {
rc = cam_spi_wait(client, pg);
@@ -380,7 +380,7 @@
retries--;
}
if (rc < 0) {
- pr_err("%s: failed %d\n", __func__, rc);
+ CAM_ERR(CAM_SENSOR, "failed %d", rc);
return rc;
}
rc = cam_spi_wait(client, pg);
@@ -422,10 +422,10 @@
goto ERROR;
goto OUT;
NOMEM:
- pr_err("%s: memory allocation failed\n", __func__);
+ CAM_ERR(CAM_SENSOR, "memory allocation failed");
return -ENOMEM;
ERROR:
- pr_err("%s: error write\n", __func__);
+ CAM_ERR(CAM_SENSOR, "error write");
OUT:
kfree(tx);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index 06590e4..b1698ca 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -903,7 +903,7 @@
gconf->cam_gpio_common_tbl[val].gpio;
gpio_num_info->valid[SENSOR_VANA] = 1;
- CAM_DBG(CAM_SENSOR, "%s:%d gpio-vana %d",
+ CAM_DBG(CAM_SENSOR, "gpio-vana %d",
gpio_num_info->gpio_num[SENSOR_VANA]);
}
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_io_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_io_util.c
index ec08c3c..c1fbb2a 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_io_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_io_util.c
@@ -262,11 +262,11 @@
if (i % NUM_REGISTER_PER_LINE == 0) {
snprintf(p_str, 12, "0x%08x: ",
REG_OFFSET(start_offset, i));
- p_str += 12;
+ p_str += 11;
}
data = readl_relaxed(base_addr + REG_OFFSET(start_offset, i));
snprintf(p_str, 9, "%08x ", data);
- p_str += 9;
+ p_str += 8;
if ((i + 1) % NUM_REGISTER_PER_LINE == 0) {
CAM_ERR(CAM_UTIL, "%s", line_str);
line_str[0] = '\0';
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 1990230..e5c7dbb 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
@@ -128,6 +128,30 @@
return 0;
}
+long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
+ uint32_t clk_index, unsigned long clk_rate)
+{
+ if (!soc_info || (clk_index >= soc_info->num_clk) || (clk_rate == 0)) {
+ CAM_ERR(CAM_UTIL, "Invalid input params %pK, %d %lld",
+ soc_info, clk_index, clk_rate);
+ return clk_rate;
+ }
+
+ return clk_round_rate(soc_info->clk[clk_index], clk_rate);
+}
+
+int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info,
+ uint32_t clk_index, unsigned long flags)
+{
+ if (!soc_info || (clk_index >= soc_info->num_clk)) {
+ CAM_ERR(CAM_UTIL, "Invalid input params %pK, %d",
+ soc_info, clk_index);
+ return -EINVAL;
+ }
+
+ return clk_set_flags(soc_info->clk[clk_index], flags);
+}
+
int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
int32_t clk_rate)
{
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
index 7eb7578..ae92cab 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/clk/qcom.h>
#include "cam_io_util.h"
@@ -328,6 +329,35 @@
bool disable_clocks, bool disable_irq);
/**
+ * cam_soc_util_get_clk_round_rate()
+ *
+ * @brief: Get the rounded clock rate for the given clock's
+ * clock rate value
+ *
+ * @soc_info: Device soc information
+ * @clk_index: Clock index in soc_info for which round rate is needed
+ * @clk_rate: Input clock rate for which rounded rate is needed
+ *
+ * @return: Rounded clock rate
+ */
+long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
+ uint32_t clk_index, unsigned long clk_rate);
+
+/**
+ * cam_soc_util_set_clk_flags()
+ *
+ * @brief: Camera SOC util to set the flags for a specified clock
+ *
+ * @soc_info: Device soc information
+ * @clk_index: Clock index in soc_info for which flags are to be set
+ * @flags: Flags to set
+ *
+ * @return: Success or Failure
+ */
+int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info,
+ uint32_t clk_index, unsigned long flags);
+
+/**
* cam_soc_util_set_clk_rate()
*
* @brief: Set the rate on a given clock.
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
index da7ecce..a075ed9 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/vmalloc.h>
+#include <linux/dma-buf.h>
#include <linux/qcom_tspp.h>
#include "mpq_dvb_debug.h"
#include "mpq_dmx_plugin_common.h"
@@ -189,6 +190,10 @@
/* Mutex protecting the data-structure */
struct mutex mutex;
+
+ /* ion dma buffer mapping structure */
+ struct tspp_ion_dma_buf_info ch_ion_dma_buf;
+
} tsif[TSIF_COUNT];
/* ION client used for TSPP data buffer allocation */
@@ -196,7 +201,8 @@
} mpq_dmx_tspp_info;
static void *tspp_mem_allocator(int channel_id, u32 size,
- phys_addr_t *phys_base, void *user)
+ phys_addr_t *phys_base, dma_addr_t *dma_base,
+ void *user)
{
void *virt_addr = NULL;
int i = TSPP_GET_TSIF_NUM(channel_id);
@@ -213,6 +219,10 @@
(mpq_dmx_tspp_info.tsif[i].ch_mem_heap_phys_base +
(mpq_dmx_tspp_info.tsif[i].buff_index * size));
+ *dma_base =
+ (mpq_dmx_tspp_info.tsif[i].ch_ion_dma_buf.dma_map_base +
+ (mpq_dmx_tspp_info.tsif[i].buff_index * size));
+
mpq_dmx_tspp_info.tsif[i].buff_index++;
return virt_addr;
@@ -539,6 +549,9 @@
mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_virt_base = NULL;
mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle = NULL;
+
+ tspp_detach_ion_dma_buff(0,
+ &mpq_dmx_tspp_info.tsif[tsif].ch_ion_dma_buf);
}
/**
@@ -589,6 +602,24 @@
return -ENOMEM;
}
+ mpq_dmx_tspp_info.tsif[tsif].ch_ion_dma_buf.dbuf = ion_share_dma_buf(
+ mpq_dmx_tspp_info.ion_client,
+ mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_handle);
+ if (IS_ERR_OR_NULL(mpq_dmx_tspp_info.tsif[tsif].ch_ion_dma_buf.dbuf)) {
+ MPQ_DVB_ERR_PRINT("%s: ion_share_dma_buf failed\n", __func__);
+ mpq_dmx_channel_mem_free(tsif);
+ return -ENOMEM;
+ }
+
+ result = tspp_attach_ion_dma_buff(0,
+ &mpq_dmx_tspp_info.tsif[tsif].ch_ion_dma_buf);
+ if (result) {
+ MPQ_DVB_ERR_PRINT("%s: tspp_attach_ion_dma_buff failed\n",
+ __func__);
+ mpq_dmx_channel_mem_free(tsif);
+ return result;
+ }
+
return 0;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 9d10b06..5db8de7 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -341,8 +341,6 @@
if (!on) {
mgr->minimum_bw_vote = 0;
sde_rotator_update_perf(mgr);
- } else {
- sde_mdp_init_vbif();
}
mgr->regulator_enable = on;
@@ -426,6 +424,9 @@
if (ret)
goto error_rot_sub;
+ /* reinitialize static vbif setting */
+ sde_mdp_init_vbif();
+
/* Active+Sleep */
msm_bus_scale_client_update_context(
mgr->data_bus.bus_hdl, false,
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 32e79f2..e49ea72 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1238,10 +1238,8 @@
pkt->rg_property_data[1] = HFI_RATE_CONTROL_CBR_VFR;
break;
case HAL_RATE_CONTROL_VBR_CFR:
- pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_CFR;
- break;
case HAL_RATE_CONTROL_VBR_VFR:
- pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_VFR;
+ pkt->rg_property_data[1] = HFI_RATE_CONTROL_VBR_CFR;
break;
case HAL_RATE_CONTROL_MBR_CFR:
pkt->rg_property_data[1] = HFI_RATE_CONTROL_MBR_CFR;
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index a08f282..efe4ca3 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -775,6 +775,47 @@
return size;
}
+static int copy_profile_caps_to_sessions(struct hfi_profile_level *prof,
+ u32 profile_count, struct msm_vidc_capability *capabilities,
+ u32 num_sessions, u32 codecs, u32 domain)
+{
+ u32 i = 0, j = 0;
+ struct msm_vidc_capability *capability;
+ u32 sess_codec;
+ u32 sess_domain;
+
+ /*
+ * iterate over num_sessions and copy all the profile capabilities
+ * to matching sessions.
+ */
+ for (i = 0; i < num_sessions; i++) {
+ sess_codec = 0;
+ sess_domain = 0;
+ capability = &capabilities[i];
+
+ if (capability->codec)
+ sess_codec =
+ vidc_get_hfi_codec(capability->codec);
+ if (capability->domain)
+ sess_domain =
+ vidc_get_hfi_domain(capability->domain);
+
+ if (!(sess_codec & codecs && sess_domain & domain))
+ continue;
+
+ capability->profile_level.profile_count = profile_count;
+ for (j = 0; j < profile_count; j++) {
+ /* HFI and HAL follow same enums, hence no conversion */
+ capability->profile_level.profile_level[j].profile =
+ prof[j].profile;
+ capability->profile_level.profile_level[j].level =
+ prof[j].level;
+ }
+ }
+
+ return 0;
+}
+
static int copy_caps_to_sessions(struct hfi_capability_supported *cap,
u32 num_caps, struct msm_vidc_capability *capabilities,
u32 num_sessions, u32 codecs, u32 domain)
@@ -914,38 +955,25 @@
}
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
{
- struct msm_vidc_capability capability;
- char *ptr = NULL;
- u32 count = 0;
- u32 prof_count = 0;
- struct hfi_profile_level *prof_level;
struct hfi_profile_level_supported *prop =
(struct hfi_profile_level_supported *)
(data_ptr + next_offset);
- ptr = (char *) &prop->rg_profile_level[0];
- prof_count = prop->profile_count;
- next_offset += sizeof(u32);
+ next_offset += sizeof(u32) +
+ prop->profile_count *
+ sizeof(struct hfi_profile_level);
- if (prof_count > MAX_PROFILE_COUNT) {
- prof_count = MAX_PROFILE_COUNT;
+ if (prop->profile_count > MAX_PROFILE_COUNT) {
+ prop->profile_count = MAX_PROFILE_COUNT;
dprintk(VIDC_WARN,
"prop count exceeds max profile count\n");
break;
}
- while (prof_count) {
- prof_level = (struct hfi_profile_level *)ptr;
- capability.
- profile_level.profile_level[count].profile
- = prof_level->profile;
- capability.
- profile_level.profile_level[count].level
- = prof_level->level;
- prof_count--;
- count++;
- ptr += sizeof(struct hfi_profile_level);
- next_offset += sizeof(struct hfi_profile_level);
- }
+
+ copy_profile_caps_to_sessions(
+ &prop->rg_profile_level[0],
+ prop->profile_count, capabilities,
+ num_sessions, codecs, domain);
num_properties--;
break;
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index de45678..69070d5 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1599,7 +1599,7 @@
break;
case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME:
property_id = HAL_CONFIG_VENC_USELTRFRAME;
- use_ltr.ref_ltr = ctrl->val;
+ use_ltr.ref_ltr = 0x1 << ctrl->val;
use_ltr.use_constraint = false;
use_ltr.frames = 0;
pdata = &use_ltr;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 854aa0a..971e57a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -140,7 +140,8 @@
int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
{
struct msm_vidc_inst *inst = instance;
- int rc = 0;
+ struct hal_profile_level_supported *prof_level_supported;
+ int rc = 0, i = 0, profile_mask = 0, v4l2_prof_value = 0, max_level = 0;
if (!inst || !ctrl)
return -EINVAL;
@@ -178,6 +179,43 @@
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_bytes);
break;
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
+ case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
+ {
+ prof_level_supported = &inst->capability.profile_level;
+ for (i = 0; i < prof_level_supported->profile_count; i++) {
+ v4l2_prof_value = msm_comm_hal_to_v4l2(ctrl->id,
+ prof_level_supported->profile_level[i].profile);
+ if (v4l2_prof_value == -EINVAL) {
+ dprintk(VIDC_WARN, "Invalid profile");
+ rc = -EINVAL;
+ }
+ profile_mask |= (1 << v4l2_prof_value);
+ }
+ ctrl->flags = profile_mask;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
+ case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
+ case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
+ {
+ prof_level_supported = &inst->capability.profile_level;
+ for (i = 0; i < prof_level_supported->profile_count; i++) {
+ if (max_level < prof_level_supported->
+ profile_level[i].level) {
+ max_level = prof_level_supported->
+ profile_level[i].level;
+ }
+ }
+ ctrl->maximum = msm_comm_hal_to_v4l2(ctrl->id, max_level);
+ if (ctrl->maximum == -EINVAL) {
+ dprintk(VIDC_WARN, "Invalid max level");
+ rc = -EINVAL;
+ }
+ break;
+ }
default:
rc = -EINVAL;
}
@@ -426,6 +464,12 @@
if (vb2->type != type || vb2->index != index)
continue;
+ if (mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING) {
+ print_vidc_buffer(VIDC_DBG,
+ "skip rel buf (rbr pending)", inst, mbuf);
+ continue;
+ }
+
print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf);
msm_comm_unmap_vidc_buffer(inst, mbuf);
list_del(&mbuf->list);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 8074c05..51023f0 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -190,7 +190,7 @@
&inst->registeredbufs.list, list) {
if (temp->vvb.vb2_buf.type ==
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
- temp->deferred) {
+ temp->flags & MSM_VIDC_FLAG_DEFERRED) {
filled_len = max(filled_len,
temp->vvb.vb2_buf.planes[0].bytesused);
device_addr = temp->smem[0].device_addr;
@@ -676,7 +676,7 @@
list_for_each_entry_safe(temp, next, &inst->registeredbufs.list, list) {
if (temp->vvb.vb2_buf.type ==
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
- temp->deferred) {
+ temp->flags & MSM_VIDC_FLAG_DEFERRED) {
filled_len = max(filled_len,
temp->vvb.vb2_buf.planes[0].bytesused);
device_addr = temp->smem[0].device_addr;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 1b8e438..e72c099 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1426,6 +1426,15 @@
print_cap("max_work_modes", &inst->capability.max_work_modes);
print_cap("ubwc_cr_stats", &inst->capability.ubwc_cr_stats);
+ dprintk(VIDC_DBG, "profile count : %u",
+ inst->capability.profile_level.profile_count);
+ for (i = 0; i < inst->capability.profile_level.profile_count; i++) {
+ dprintk(VIDC_DBG, "profile : %u ", inst->capability.
+ profile_level.profile_level[i].profile);
+ dprintk(VIDC_DBG, "level : %u ", inst->capability.
+ profile_level.profile_level[i].level);
+ }
+
signal_session_msg_receipt(cmd, inst);
/*
@@ -3830,7 +3839,7 @@
continue;
/* count only deferred buffers */
- if (!mbuf->deferred)
+ if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED))
continue;
++count;
@@ -3858,7 +3867,7 @@
continue;
/* count only deferred buffers */
- if (!mbuf->deferred)
+ if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED))
continue;
++count;
@@ -3906,6 +3915,41 @@
}
}
+static int msm_comm_qbuf_rbr(struct msm_vidc_inst *inst,
+ struct msm_vidc_buffer *mbuf)
+{
+ int rc = 0;
+ struct hfi_device *hdev;
+ struct vidc_frame_data frame_data = {0};
+
+ if (!inst || !inst->core || !inst->core->device || !mbuf) {
+ dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
+ return -EINVAL;
+ }
+
+ hdev = inst->core->device;
+
+ if (inst->state == MSM_VIDC_CORE_INVALID) {
+ dprintk(VIDC_ERR, "%s: inst is in bad state\n", __func__);
+ return -EINVAL;
+ }
+
+ rc = msm_comm_scale_clocks_and_bus(inst);
+ populate_frame_data(&frame_data, mbuf, inst);
+
+ rc = call_hfi_op(hdev, session_ftb, inst->session, &frame_data);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to issue ftb: %d\n", rc);
+ goto err_bad_input;
+ }
+
+ log_frame(inst, &frame_data, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+err_bad_input:
+ return rc;
+}
+
+
/*
* Attempts to queue `vb` to hardware. If, for various reasons, the buffer
* cannot be queued to hardware, the buffer will be staged for commit in the
@@ -3937,10 +3981,6 @@
return -EINVAL;
}
- /* initially assume every buffer is going to be deferred */
- if (mbuf)
- mbuf->deferred = true;
-
batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
== V4L2_VIDC_QBUF_BATCHED;
capture_count = (batch_mode ? &count_single_batch : &count_buffers)
@@ -3968,7 +4008,7 @@
if (defer) {
if (mbuf) {
- mbuf->deferred = true;
+ mbuf->flags |= MSM_VIDC_FLAG_DEFERRED;
print_vidc_buffer(VIDC_DBG, "deferred qbuf",
inst, mbuf);
}
@@ -4009,7 +4049,7 @@
list_for_each_entry_safe(temp, next, &inst->registeredbufs.list, list) {
struct vidc_frame_data *frame_data = NULL;
- if (!temp->deferred)
+ if (!(temp->flags & MSM_VIDC_FLAG_DEFERRED))
continue;
switch (temp->vvb.vb2_buf.type) {
@@ -4031,7 +4071,7 @@
populate_frame_data(frame_data, temp, inst);
/* this buffer going to be queued (not deferred) */
- temp->deferred = false;
+ temp->flags &= ~MSM_VIDC_FLAG_DEFERRED;
print_vidc_buffer(VIDC_DBG, "qbuf", inst, temp);
}
@@ -4807,10 +4847,16 @@
&inst->bufq[port].vb2_bufq.queued_list) {
struct vb2_buffer *vb = container_of(ptr,
struct vb2_buffer, queued_entry);
- vb->planes[0].bytesused = 0;
- print_vb2_buffer(VIDC_ERR, "flush in invalid",
- inst, vb);
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ if (vb->state == VB2_BUF_STATE_ACTIVE) {
+ vb->planes[0].bytesused = 0;
+ print_vb2_buffer(VIDC_ERR, "flush in invalid",
+ inst, vb);
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ } else {
+ dprintk(VIDC_WARN,
+ "%s VB is in state %d not in ACTIVE state\n"
+ , __func__, vb->state);
+ }
}
mutex_unlock(&inst->bufq[port].lock);
}
@@ -4820,7 +4866,7 @@
int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
{
- int rc = 0;
+ int i, rc = 0;
bool ip_flush = false;
bool op_flush = false;
struct msm_vidc_buffer *mbuf, *next;
@@ -4845,8 +4891,6 @@
return 0;
}
- /* Finish FLUSH As Soon As Possible. */
-
msm_clock_data_reset(inst);
if (inst->state == MSM_VIDC_CORE_INVALID) {
@@ -4859,22 +4903,41 @@
mutex_lock(&inst->registeredbufs.lock);
list_for_each_entry_safe(mbuf, next, &inst->registeredbufs.list, list) {
- /* flush only deferred buffers (which are not queued yet) */
- if (!mbuf->deferred)
- continue;
-
- /* don't flush input buffers if flush not requested on it */
+ /* don't flush input buffers if input flush is not requested */
if (!ip_flush && mbuf->vvb.vb2_buf.type ==
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
continue;
+ /* flush only deferred or rbr pending buffers */
+ if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED ||
+ mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING))
+ continue;
+
+ /*
+ * flush buffers which are queued by client already,
+ * the refcount will be two or more for those buffers.
+ */
+ if (!(mbuf->smem[0].refcount >= 2))
+ continue;
+
print_vidc_buffer(VIDC_DBG, "flush buf", inst, mbuf);
msm_comm_flush_vidc_buffer(inst, mbuf);
- msm_comm_unmap_vidc_buffer(inst, mbuf);
- /* remove from list */
- list_del(&mbuf->list);
- kref_put_mbuf(mbuf);
+ for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
+ if (msm_smem_unmap_dma_buf(inst, &mbuf->smem[i]))
+ print_vidc_buffer(VIDC_ERR,
+ "dqbuf: unmap failed.", inst, mbuf);
+ if (msm_smem_unmap_dma_buf(inst, &mbuf->smem[i]))
+ print_vidc_buffer(VIDC_ERR,
+ "dqbuf: unmap failed..", inst, mbuf);
+ }
+ if (!mbuf->smem[0].refcount) {
+ list_del(&mbuf->list);
+ kref_put_mbuf(mbuf);
+ } else {
+ /* buffer is no more a deferred buffer */
+ mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
+ }
}
mutex_unlock(&inst->registeredbufs.lock);
@@ -5750,27 +5813,27 @@
if (vb2->num_planes == 1)
dprintk(tag,
- "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d\n",
+ "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x\n",
str, vb2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
"OUTPUT" : "CAPTURE", hash32_ptr(inst->session),
vb2->index, vb2->planes[0].m.fd,
vb2->planes[0].data_offset, mbuf->smem[0].device_addr,
vb2->planes[0].length, vb2->planes[0].bytesused,
mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp,
- mbuf->smem[0].refcount);
+ mbuf->smem[0].refcount, mbuf->flags);
else
dprintk(tag,
- "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n",
+ "%s: %s: %x : idx %2d fd %d off %d daddr %x size %d filled %d flags 0x%x ts %lld refcnt %d mflags 0x%x, extradata: fd %d off %d daddr %x size %d filled %d refcnt %d\n",
str, vb2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
"OUTPUT" : "CAPTURE", hash32_ptr(inst->session),
vb2->index, vb2->planes[0].m.fd,
vb2->planes[0].data_offset, mbuf->smem[0].device_addr,
vb2->planes[0].length, vb2->planes[0].bytesused,
mbuf->vvb.flags, mbuf->vvb.vb2_buf.timestamp,
- mbuf->smem[0].refcount, vb2->planes[1].m.fd,
- vb2->planes[1].data_offset, mbuf->smem[1].device_addr,
- vb2->planes[1].length, vb2->planes[1].bytesused,
- mbuf->smem[1].refcount);
+ mbuf->smem[0].refcount, mbuf->flags,
+ vb2->planes[1].m.fd, vb2->planes[1].data_offset,
+ mbuf->smem[1].device_addr, vb2->planes[1].length,
+ vb2->planes[1].bytesused, mbuf->smem[1].refcount);
}
void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
@@ -5789,13 +5852,14 @@
vb2->planes[0].bytesused);
else
dprintk(tag,
- "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d\n",
+ "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n",
str, vb2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
"OUTPUT" : "CAPTURE", hash32_ptr(inst->session),
vb2->index, vb2->planes[0].m.fd,
vb2->planes[0].data_offset, vb2->planes[0].length,
vb2->planes[0].bytesused, vb2->planes[1].m.fd,
- vb2->planes[1].data_offset, vb2->planes[1].length);
+ vb2->planes[1].data_offset, vb2->planes[1].length,
+ vb2->planes[1].bytesused);
}
void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
@@ -5815,7 +5879,7 @@
v4l2->m.planes[0].bytesused);
else
dprintk(tag,
- "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d\n",
+ "%s: %s: %x : idx %2d fd %d off %d size %d filled %d, extradata: fd %d off %d size %d filled %d\n",
str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
"OUTPUT" : "CAPTURE", hash32_ptr(inst->session),
v4l2->index, v4l2->m.planes[0].m.fd,
@@ -5824,7 +5888,8 @@
v4l2->m.planes[0].bytesused,
v4l2->m.planes[1].m.fd,
v4l2->m.planes[1].data_offset,
- v4l2->m.planes[1].length);
+ v4l2->m.planes[1].length,
+ v4l2->m.planes[1].bytesused);
}
bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst,
@@ -6042,6 +6107,9 @@
kref_init(&mbuf->kref);
}
+ /* Initially assume all the buffer are going to be deferred */
+ mbuf->flags |= MSM_VIDC_FLAG_DEFERRED;
+
vbuf = to_vb2_v4l2_buffer(vb2);
memcpy(&mbuf->vvb, vbuf, sizeof(struct vb2_v4l2_buffer));
vb = &mbuf->vvb.vb2_buf;
@@ -6088,6 +6156,16 @@
if (found_plane0)
rc = -EEXIST;
}
+ /*
+ * If RBR pending on this buffer then enable RBR_PENDING flag
+ * and clear the DEFERRED flag to avoid this buffer getting
+ * queued to video hardware in msm_comm_qbuf() which tries to
+ * queue all the DEFERRED buffers.
+ */
+ if (rc == -EEXIST) {
+ mbuf->flags |= MSM_VIDC_FLAG_RBR_PENDING;
+ mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
+ }
}
/* add the new buffer to list */
@@ -6184,10 +6262,14 @@
}
}
if (found) {
+ /* send RBR event to client */
msm_vidc_queue_rbr_event(inst,
mbuf->vvb.vb2_buf.planes[0].m.fd,
mbuf->vvb.vb2_buf.planes[0].data_offset);
+ /* clear RBR_PENDING flag */
+ mbuf->flags &= ~MSM_VIDC_FLAG_RBR_PENDING;
+
for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
if (msm_smem_unmap_dma_buf(inst, &mbuf->smem[i]))
print_vidc_buffer(VIDC_ERR,
@@ -6223,7 +6305,7 @@
if (!found)
goto unlock;
- /* found means client queued the buffer already */
+ /* buffer found means client queued the buffer already */
if (inst->in_reconfig || inst->in_flush) {
print_vidc_buffer(VIDC_DBG, "rbr flush buf", inst, mbuf);
msm_comm_flush_vidc_buffer(inst, mbuf);
@@ -6235,12 +6317,16 @@
/* don't queue the buffer */
found = false;
}
+ /* clear DEFERRED flag, if any, as the buffer is going to be queued */
+ if (found)
+ mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
+
unlock:
mutex_unlock(&inst->registeredbufs.lock);
if (found) {
print_vidc_buffer(VIDC_DBG, "rbr qbuf", inst, mbuf);
- rc = msm_comm_qbuf(inst, mbuf);
+ rc = msm_comm_qbuf_rbr(inst, mbuf);
if (rc)
print_vidc_buffer(VIDC_ERR,
"rbr qbuf failed", inst, mbuf);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 57dfd52..195410d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -399,12 +399,17 @@
int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type);
+enum msm_vidc_flags {
+ MSM_VIDC_FLAG_DEFERRED = BIT(0),
+ MSM_VIDC_FLAG_RBR_PENDING = BIT(1),
+};
+
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;
+ enum msm_vidc_flags flags;
};
void msm_comm_handle_thermal_event(void);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index a522918..6a239b3 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -81,6 +81,7 @@
#define HFI_VIDEO_CODEC_VP8 0x00001000
#define HFI_VIDEO_CODEC_HEVC 0x00002000
#define HFI_VIDEO_CODEC_VP9 0x00004000
+#define HFI_VIDEO_CODEC_TME 0x00008000
#define HFI_PROFILE_UNKNOWN 0x00000000
#define HFI_H264_PROFILE_BASELINE 0x00000001
@@ -150,6 +151,13 @@
#define HFI_HEVC_TIER_MAIN 0x1
#define HFI_HEVC_TIER_HIGH0 0x2
+#define HFI_TME_PROFILE_DEFAULT 0x00000001
+#define HFI_TME_PROFILE_FRC 0x00000002
+#define HFI_TME_PROFILE_ASW 0x00000004
+#define HFI_TME_PROFILE_DFS_BOKEH 0x00000008
+
+#define HFI_TME_LEVEL_INTEGER 0x00000001
+
#define HFI_BUFFER_INPUT (HFI_COMMON_BASE + 0x1)
#define HFI_BUFFER_OUTPUT (HFI_COMMON_BASE + 0x2)
#define HFI_BUFFER_OUTPUT2 (HFI_COMMON_BASE + 0x3)
@@ -229,6 +237,8 @@
(HFI_PROPERTY_PARAM_COMMON_START + 0x011)
#define HFI_PROPERTY_PARAM_WORK_MODE \
(HFI_PROPERTY_PARAM_COMMON_START + 0x015)
+#define HFI_PROPERTY_TME_VERSION_SUPPORTED \
+ (HFI_PROPERTY_PARAM_COMMON_START + 0x016)
#define HFI_PROPERTY_CONFIG_COMMON_START \
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x2000)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index c2ee6e3..252ab99 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1992,6 +1992,9 @@
if (!found)
return -ENOENT;
+ if (ctrl->info.size < mapping->size)
+ return -EINVAL;
+
if (mutex_lock_interruptible(&chain->ctrl_mutex))
return -ERESTARTSYS;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 232c290..a12d5ca 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1280,6 +1280,10 @@
ret = -EINVAL;
goto err_codec;
}
+
+ if (pdata->has_buck_vsel_gpio)
+ msm_cdc_pinctrl_select_active_state(pdata->buck_vsel_ctl_np);
+
device_id = slim_get_device_id(slim);
if (!device_id) {
dev_err(&slim->dev, "%s: Error, no device id\n", __func__);
diff --git a/drivers/mfd/wcd9xxx-utils.c b/drivers/mfd/wcd9xxx-utils.c
index 8d3d4ad..f72585a 100644
--- a/drivers/mfd/wcd9xxx-utils.c
+++ b/drivers/mfd/wcd9xxx-utils.c
@@ -342,6 +342,19 @@
goto err_parse_dt_prop;
}
+ pdata->has_buck_vsel_gpio = of_property_read_bool(dev->of_node,
+ "qcom,has-buck-vsel-gpio");
+ if (pdata->has_buck_vsel_gpio) {
+ pdata->buck_vsel_ctl_np = of_parse_phandle(dev->of_node,
+ "qcom,buck-vsel-gpio-node", 0);
+ if (!pdata->buck_vsel_ctl_np) {
+ dev_err(dev, "%s No entry for %s property in node %s\n",
+ __func__, "qcom,buck-vsel-gpio-node",
+ dev->of_node->full_name);
+ goto err_parse_dt_prop;
+ }
+ }
+
if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate",
&prop_val)))
pdata->mclk_rate = prop_val;
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h
index fdf954c..cfa1039 100644
--- a/drivers/misc/lkdtm.h
+++ b/drivers/misc/lkdtm.h
@@ -21,6 +21,8 @@
void lkdtm_HUNG_TASK(void);
void lkdtm_ATOMIC_UNDERFLOW(void);
void lkdtm_ATOMIC_OVERFLOW(void);
+void lkdtm_CORRUPT_LIST_ADD(void);
+void lkdtm_CORRUPT_LIST_DEL(void);
/* lkdtm_heap.c */
void lkdtm_OVERWRITE_ALLOCATION(void);
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c
index 182ae18..bb3bb8e 100644
--- a/drivers/misc/lkdtm_bugs.c
+++ b/drivers/misc/lkdtm_bugs.c
@@ -5,8 +5,13 @@
* test source files.
*/
#include "lkdtm.h"
+#include <linux/list.h>
#include <linux/sched.h>
+struct lkdtm_list {
+ struct list_head node;
+};
+
/*
* Make sure our attempts to over run the kernel stack doesn't trigger
* a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
@@ -75,12 +80,18 @@
(void) recursive_loop(recur_count);
}
+static noinline void __lkdtm_CORRUPT_STACK(void *stack)
+{
+ memset(stack, 'a', 64);
+}
+
noinline void lkdtm_CORRUPT_STACK(void)
{
/* Use default char array length that triggers stack protection. */
char data[8];
+ __lkdtm_CORRUPT_STACK(&data);
- memset((void *)data, 0, 64);
+ pr_info("Corrupted stack with '%16s'...\n", data);
}
void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void)
@@ -146,3 +157,66 @@
pr_info("attempting bad atomic overflow\n");
atomic_inc(&over);
}
+
+void lkdtm_CORRUPT_LIST_ADD(void)
+{
+ /*
+ * Initially, an empty list via LIST_HEAD:
+ * test_head.next = &test_head
+ * test_head.prev = &test_head
+ */
+ LIST_HEAD(test_head);
+ struct lkdtm_list good, bad;
+ void *target[2] = { };
+ void *redirection = ⌖
+
+ pr_info("attempting good list addition\n");
+
+ /*
+ * Adding to the list performs these actions:
+ * test_head.next->prev = &good.node
+ * good.node.next = test_head.next
+ * good.node.prev = test_head
+ * test_head.next = good.node
+ */
+ list_add(&good.node, &test_head);
+
+ pr_info("attempting corrupted list addition\n");
+ /*
+ * In simulating this "write what where" primitive, the "what" is
+ * the address of &bad.node, and the "where" is the address held
+ * by "redirection".
+ */
+ test_head.next = redirection;
+ list_add(&bad.node, &test_head);
+
+ if (target[0] == NULL && target[1] == NULL)
+ pr_err("Overwrite did not happen, but no BUG?!\n");
+ else
+ pr_err("list_add() corruption not detected!\n");
+}
+
+void lkdtm_CORRUPT_LIST_DEL(void)
+{
+ LIST_HEAD(test_head);
+ struct lkdtm_list item;
+ void *target[2] = { };
+ void *redirection = ⌖
+
+ list_add(&item.node, &test_head);
+
+ pr_info("attempting good list removal\n");
+ list_del(&item.node);
+
+ pr_info("attempting corrupted list removal\n");
+ list_add(&item.node, &test_head);
+
+ /* As with the list_add() test above, this corrupts "next". */
+ item.node.next = redirection;
+ list_del(&item.node);
+
+ if (target[0] == NULL && target[1] == NULL)
+ pr_err("Overwrite did not happen, but no BUG?!\n");
+ else
+ pr_err("list_del() corruption not detected!\n");
+}
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c
index f9154b8..7eeb71a 100644
--- a/drivers/misc/lkdtm_core.c
+++ b/drivers/misc/lkdtm_core.c
@@ -197,6 +197,8 @@
CRASHTYPE(EXCEPTION),
CRASHTYPE(LOOP),
CRASHTYPE(OVERFLOW),
+ CRASHTYPE(CORRUPT_LIST_ADD),
+ CRASHTYPE(CORRUPT_LIST_DEL),
CRASHTYPE(CORRUPT_STACK),
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
CRASHTYPE(OVERWRITE_ALLOCATION),
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index bb36fe5..70379c8 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -965,6 +965,9 @@
wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
len, true);
+ if (len < sizeof(struct ieee80211_hdr_3addr))
+ return -EINVAL;
+
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
if (!cmd) {
rc = -ENOMEM;
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 0ac657d..a0a676b 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -799,8 +799,12 @@
struct wireless_dev *wdev = wil_to_wdev(wil);
struct cfg80211_mgmt_tx_params params;
int rc;
- void *frame = kmalloc(len, GFP_KERNEL);
+ void *frame;
+ if (!len)
+ return -EINVAL;
+
+ frame = kmalloc(len, GFP_KERNEL);
if (!frame)
return -ENOMEM;
diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c
index 11f954e..39c35b7 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpi.c
@@ -26,7 +26,7 @@
#include "../core.h"
#include "../pinctrl-utils.h"
-#define LPI_ADDRESS_SIZE 0xC000
+#define LPI_ADDRESS_SIZE 0x20000
#define LPI_GPIO_REG_VAL_CTL 0x00
#define LPI_GPIO_REG_DIR_CTL 0x04
@@ -109,35 +109,35 @@
0x00000000,
0x00001000,
0x00002000,
- 0x00002010,
0x00003000,
- 0x00003010,
0x00004000,
- 0x00004010,
0x00005000,
- 0x00005010,
- 0x00005020,
- 0x00005030,
0x00006000,
- 0x00006010,
0x00007000,
- 0x00007010,
- 0x00005040,
- 0x00005050,
0x00008000,
- 0x00008010,
- 0x00008020,
- 0x00008030,
- 0x00008040,
- 0x00008050,
- 0x00008060,
- 0x00008070,
0x00009000,
- 0x00009010,
0x0000A000,
- 0x0000A010,
0x0000B000,
- 0x0000B010,
+ 0x0000C000,
+ 0x0000D000,
+ 0x0000E000,
+ 0x0000F000,
+ 0x00010000,
+ 0x00011000,
+ 0x00012000,
+ 0x00013000,
+ 0x00014000,
+ 0x00015000,
+ 0x00016000,
+ 0x00017000,
+ 0x00018000,
+ 0x00019000,
+ 0x0001A000,
+ 0x0001B000,
+ 0x0001C000,
+ 0x0001D000,
+ 0x0001E000,
+ 0x0001F000,
};
static const char *const lpi_gpio_functions[] = {
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm670.c b/drivers/pinctrl/qcom/pinctrl-sdm670.c
index 4334779..b454cc442 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm670.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm670.c
@@ -1585,6 +1585,74 @@
[157] = UFS_RESET(ufs_reset, 0x99f000),
};
+static const struct msm_dir_conn sdm670_dir_conn[] = {
+ {1, 510},
+ {3, 511},
+ {5, 512},
+ {10, 513},
+ {11, 514},
+ {20, 515},
+ {22, 516},
+ {24, 517},
+ {26, 518},
+ {30, 519},
+ {31, 639},
+ {32, 521},
+ {34, 522},
+ {36, 523},
+ {37, 524},
+ {38, 525},
+ {39, 526},
+ {40, 527},
+ {41, 637},
+ {43, 529},
+ {44, 530},
+ {46, 531},
+ {48, 532},
+ {49, 640},
+ {52, 534},
+ {53, 535},
+ {54, 536},
+ {56, 537},
+ {57, 538},
+ {66, 546},
+ {68, 547},
+ {77, 550},
+ {78, 551},
+ {79, 552},
+ {80, 553},
+ {84, 554},
+ {85, 555},
+ {86, 556},
+ {88, 557},
+ {89, 638},
+ {91, 559},
+ {92, 560},
+ {95, 561},
+ {96, 562},
+ {97, 563},
+ {101, 564},
+ {103, 565},
+ {115, 570},
+ {116, 571},
+ {117, 572},
+ {118, 573},
+ {119, 609},
+ {120, 610},
+ {121, 611},
+ {122, 612},
+ {123, 613},
+ {124, 614},
+ {125, 615},
+ {127, 617},
+ {128, 618},
+ {129, 619},
+ {130, 620},
+ {132, 621},
+ {133, 622},
+ {145, 623},
+};
+
static const struct msm_pinctrl_soc_data sdm670_pinctrl = {
.pins = sdm670_pins,
.npins = ARRAY_SIZE(sdm670_pins),
@@ -1593,6 +1661,8 @@
.groups = sdm670_groups,
.ngroups = ARRAY_SIZE(sdm670_groups),
.ngpios = 150,
+ .dir_conn = sdm670_dir_conn,
+ .n_dir_conns = ARRAY_SIZE(sdm670_dir_conn),
.tile_offsets = sdm670_tile_offsets,
.n_tile_offsets = ARRAY_SIZE(sdm670_tile_offsets),
.pin_base = sdm670_pin_base,
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
index c8663c9..d4e39d7 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
@@ -649,8 +649,7 @@
return 0;
ipa_insert_failed:
- if (offset)
- list_move(&offset->link,
+ list_move(&offset->link,
&htbl->head_free_offset_list[offset->bin]);
entry->offset_entry = NULL;
list_del(&entry->link);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 52d244d..50930d3 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -1395,7 +1395,7 @@
{
struct ipa_rt_tbl *entry;
enum ipa_ip_type ip = IPA_IP_MAX;
- int result;
+ int result = 0;
mutex_lock(&ipa_ctx->lock);
entry = ipa_id_find(rt_tbl_hdl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 018467a..02c5991 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -2574,6 +2574,7 @@
WARN_ON(1);
return;
}
+ spin_lock_bh(&sys->spinlock);
rx_pkt_expected = list_first_entry(&sys->head_desc_list,
struct ipa3_rx_pkt_wrapper,
link);
@@ -2581,6 +2582,7 @@
sys->len--;
if (size)
rx_pkt_expected->len = size;
+ spin_unlock_bh(&sys->spinlock);
rx_skb = rx_pkt_expected->data.skb;
dma_unmap_single(ipa3_ctx->pdev, rx_pkt_expected->data.dma_addr,
sys->rx_buff_sz, DMA_FROM_DEVICE);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index da7bcd0..122c541 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -424,8 +424,7 @@
return 0;
ipa_insert_failed:
- if (offset)
- list_move(&offset->link,
+ list_move(&offset->link,
&htbl->head_free_offset_list[offset->bin]);
entry->offset_entry = NULL;
list_del(&entry->link);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 1190beb..ef0158e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -1476,7 +1476,7 @@
{
struct ipa3_rt_tbl *entry;
enum ipa_ip_type ip = IPA_IP_MAX;
- int result;
+ int result = 0;
mutex_lock(&ipa3_ctx->lock);
entry = ipa3_id_find(rt_tbl_hdl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index e999896..8fe15bc 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4062,7 +4062,7 @@
IPAHAL_FULL_PIPELINE_CLEAR;
reg_write_agg_close.offset =
ipahal_get_reg_ofst(IPA_AGGR_FORCE_CLOSE);
- ipahal_get_aggr_force_close_valmask(1<<i, &valmask);
+ ipahal_get_aggr_force_close_valmask(i, &valmask);
reg_write_agg_close.value = valmask.val;
reg_write_agg_close.value_mask = valmask.mask;
cmd_pyld = ipahal_construct_imm_cmd(IPA_IMM_CMD_REGISTER_WRITE,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 8609476..dc71414 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1925,6 +1925,11 @@
IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_BMSK_V4_0;
}
+ if (ep_idx > (sizeof(valmask->val) * 8 - 1)) {
+ IPAHAL_ERR("too big ep_idx %d\n", ep_idx);
+ ipa_assert();
+ return;
+ }
IPA_SETFIELD_IN_REG(valmask->val, 1 << ep_idx, shft, bmsk);
valmask->mask = bmsk << shft;
}
diff --git a/drivers/platform/msm/qcom-geni-se.c b/drivers/platform/msm/qcom-geni-se.c
index 7c77280..c1e77aa 100644
--- a/drivers/platform/msm/qcom-geni-se.c
+++ b/drivers/platform/msm/qcom-geni-se.c
@@ -691,7 +691,7 @@
struct se_geni_rsc *rsc)
{
unsigned long flags;
- struct se_geni_rsc *tmp;
+ struct se_geni_rsc *tmp = NULL;
struct list_head *ins_list_head;
bool bus_bw_update = false;
int ret = 0;
@@ -709,7 +709,7 @@
list_add(&rsc->ib_list, ins_list_head);
/* Currently inserted node has greater average BW value */
if (ins_list_head == &geni_se_dev->ib_list_head)
- geni_se_dev->cur_ib = tmp->ib;
+ geni_se_dev->cur_ib = rsc->ib;
bus_bw_update = geni_se_check_bus_bw(geni_se_dev);
spin_unlock_irqrestore(&geni_se_dev->ab_ib_lock, flags);
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.c b/drivers/platform/msm/seemp_core/seemp_logk.c
index 204142b..a23f069 100644
--- a/drivers/platform/msm/seemp_core/seemp_logk.c
+++ b/drivers/platform/msm/seemp_core/seemp_logk.c
@@ -30,6 +30,7 @@
#define YEAR_BASE 1900
#define EL2_SCM_ID 0x02001902
+#define KP_EL2_REPORT_REVISION 0x01000101
static struct seemp_logk_dev *slogk_dev;
@@ -610,6 +611,9 @@
/ sizeof(struct el2_report_data_t);
header = (struct el2_report_header_t *) el2_shared_mem;
+ if (header->report_version < KP_EL2_REPORT_REVISION)
+ return -EINVAL;
+
while (!kthread_should_stop()) {
for (i = 1; i < num_entries + 1; i++) {
struct el2_report_data_t *report;
@@ -628,7 +632,8 @@
|| report->sequence_number >
last_sequence_number)) {
seemp_logk_rtic(report->report_type,
- report->actor,
+ ((struct task_struct *) report->actor)
+ ->pid,
/* leave this empty until
* asset id is provided
*/
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index c77b808..dd5f78f 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -278,6 +278,7 @@
int slope_limit_temp;
int esr_pulse_thresh_ma;
int esr_meas_curr_ma;
+ int bmd_en_delay_ms;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
diff --git a/drivers/power/supply/qcom/pmic-voter.c b/drivers/power/supply/qcom/pmic-voter.c
index 10a1c54..e0a5150 100644
--- a/drivers/power/supply/qcom/pmic-voter.c
+++ b/drivers/power/supply/qcom/pmic-voter.c
@@ -438,12 +438,14 @@
int rerun_election(struct votable *votable)
{
int rc = 0;
+ int effective_result;
lock_votable(votable);
+ effective_result = get_effective_result_locked(votable);
if (votable->callback)
rc = votable->callback(votable,
- votable->data,
- votable->effective_result,
+ votable->data,
+ effective_result,
get_client_str(votable, votable->effective_client_id));
unlock_votable(votable);
return rc;
@@ -519,11 +521,10 @@
lock_votable(votable);
- seq_printf(m, "Votable %s:\n", votable->name);
- seq_puts(m, "clients:\n");
for (i = 0; i < votable->num_clients; i++) {
if (votable->client_strs[i]) {
- seq_printf(m, "%-15s:\t\ten=%d\t\tv=%d\n",
+ seq_printf(m, "%s: %s:\t\t\ten=%d v=%d\n",
+ votable->name,
votable->client_strs[i],
votable->votes[i].enabled,
votable->votes[i].value);
@@ -542,11 +543,11 @@
break;
}
- seq_printf(m, "type: %s\n", type_str);
- seq_puts(m, "Effective:\n");
effective_client_str = get_effective_client_locked(votable);
- seq_printf(m, "%-15s:\t\tv=%d\n",
+ seq_printf(m, "%s: effective=%s type=%s v=%d\n",
+ votable->name,
effective_client_str ? effective_client_str : "none",
+ type_str,
get_effective_result_locked(votable));
unlock_votable(votable);
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index d522926..7c94744 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -75,6 +75,8 @@
#define ESR_TIMER_CHG_MAX_OFFSET 0
#define ESR_TIMER_CHG_INIT_WORD 18
#define ESR_TIMER_CHG_INIT_OFFSET 2
+#define ESR_EXTRACTION_ENABLE_WORD 19
+#define ESR_EXTRACTION_ENABLE_OFFSET 0
#define PROFILE_LOAD_WORD 24
#define PROFILE_LOAD_OFFSET 0
#define ESR_RSLOW_DISCHG_WORD 34
@@ -892,8 +894,8 @@
goto out;
}
- /* Wait for 200ms before enabling BMD again */
- msleep(200);
+ /* Wait for BATT_ID to settle down before enabling BMD again */
+ msleep(chip->dt.bmd_en_delay_ms);
fg_dbg(chip, FG_STATUS, "batt_id: %d\n", batt_id);
chip->batt_id_ohms = batt_id;
@@ -3033,6 +3035,89 @@
return 0;
}
+static int fg_force_esr_meas(struct fg_chip *chip)
+{
+ int rc;
+ int esr_uohms;
+
+ /* force esr extraction enable */
+ rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
+ ESR_EXTRACTION_ENABLE_OFFSET, BIT(0), BIT(0),
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("failed to enable esr extn rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
+ LD_REG_CTRL_BIT, 0);
+ if (rc < 0) {
+ pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
+ ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT,
+ ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT);
+ if (rc < 0) {
+ pr_err("Error in configuring force ESR rc=%d\n", rc);
+ return rc;
+ }
+
+ /* wait 1.5 seconds for hw to measure ESR */
+ msleep(1500);
+ rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
+ ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT,
+ 0);
+ if (rc < 0) {
+ pr_err("Error in restoring force ESR rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
+ LD_REG_CTRL_BIT, LD_REG_CTRL_BIT);
+ if (rc < 0) {
+ pr_err("Error in restoring qnovo_cfg rc=%d\n", rc);
+ return rc;
+ }
+
+ /* force esr extraction disable */
+ rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
+ ESR_EXTRACTION_ENABLE_OFFSET, BIT(0), 0,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("failed to disable esr extn rc=%d\n", rc);
+ return rc;
+ }
+
+ fg_get_battery_resistance(chip, &esr_uohms);
+ fg_dbg(chip, FG_STATUS, "ESR uohms = %d\n", esr_uohms);
+
+ return rc;
+}
+
+static int fg_prepare_for_qnovo(struct fg_chip *chip, int qnovo_enable)
+{
+ int rc;
+
+ /* force esr extraction disable when qnovo enables */
+ rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
+ ESR_EXTRACTION_ENABLE_OFFSET,
+ BIT(0), qnovo_enable ? 0 : BIT(0),
+ FG_IMA_DEFAULT);
+ if (rc < 0)
+ pr_err("Error in configuring esr extraction rc=%d\n", rc);
+
+ rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
+ LD_REG_CTRL_BIT,
+ qnovo_enable ? LD_REG_CTRL_BIT : 0);
+ if (rc < 0) {
+ pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
+ return rc;
+ }
+ fg_dbg(chip, FG_STATUS, "Prepared for Qnovo\n");
+ return 0;
+}
/* PSY CALLBACKS STAY HERE */
static int fg_psy_get_property(struct power_supply *psy,
@@ -3141,6 +3226,12 @@
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
rc = fg_set_constant_chg_voltage(chip, pval->intval);
break;
+ case POWER_SUPPLY_PROP_RESISTANCE:
+ rc = fg_force_esr_meas(chip);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE:
+ rc = fg_prepare_for_qnovo(chip, pval->intval);
+ break;
default:
break;
}
@@ -4036,6 +4127,7 @@
#define DEFAULT_ESR_CLAMP_MOHMS 20
#define DEFAULT_ESR_PULSE_THRESH_MA 110
#define DEFAULT_ESR_MEAS_CURR_MA 120
+#define DEFAULT_BMD_EN_DELAY_MS 200
static int fg_parse_dt(struct fg_chip *chip)
{
struct device_node *child, *revid_node, *node = chip->dev->of_node;
@@ -4382,6 +4474,13 @@
chip->dt.esr_meas_curr_ma = temp;
}
+ chip->dt.bmd_en_delay_ms = DEFAULT_BMD_EN_DELAY_MS;
+ rc = of_property_read_u32(node, "qcom,fg-bmd-en-delay-ms", &temp);
+ if (!rc) {
+ if (temp > DEFAULT_BMD_EN_DELAY_MS)
+ chip->dt.bmd_en_delay_ms = temp;
+ }
+
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-qnovo.c b/drivers/power/supply/qcom/qpnp-qnovo.c
index eb97eb0..cf90f90 100644
--- a/drivers/power/supply/qcom/qpnp-qnovo.c
+++ b/drivers/power/supply/qcom/qpnp-qnovo.c
@@ -20,6 +20,7 @@
#include <linux/of_irq.h>
#include <linux/qpnp/qpnp-revid.h>
#include <linux/pmic-voter.h>
+#include <linux/delay.h>
#define QNOVO_REVISION1 0x00
#define QNOVO_REVISION2 0x01
@@ -114,6 +115,17 @@
#define OK_TO_QNOVO_VOTER "ok_to_qnovo_voter"
#define QNOVO_VOTER "qnovo_voter"
+#define FG_AVAILABLE_VOTER "FG_AVAILABLE_VOTER"
+#define QNOVO_OVERALL_VOTER "QNOVO_OVERALL_VOTER"
+#define QNI_PT_VOTER "QNI_PT_VOTER"
+#define ESR_VOTER "ESR_VOTER"
+
+#define HW_OK_TO_QNOVO_VOTER "HW_OK_TO_QNOVO_VOTER"
+#define CHG_READY_VOTER "CHG_READY_VOTER"
+#define USB_READY_VOTER "USB_READY_VOTER"
+#define DC_READY_VOTER "DC_READY_VOTER"
+
+#define PT_RESTART_VOTER "PT_RESTART_VOTER"
struct qnovo_dt_props {
bool external_rsense;
@@ -127,6 +139,10 @@
struct qnovo_dt_props dt;
struct device *dev;
struct votable *disable_votable;
+ struct votable *pt_dis_votable;
+ struct votable *not_ok_to_qnovo_votable;
+ struct votable *chg_ready_votable;
+ struct votable *awake_votable;
struct class qnovo_class;
struct pmic_revid_data *pmic_rev_id;
u32 wa_flags;
@@ -138,10 +154,18 @@
s64 v_gain_mega;
struct notifier_block nb;
struct power_supply *batt_psy;
+ struct power_supply *bms_psy;
+ struct power_supply *usb_psy;
+ struct power_supply *dc_psy;
struct work_struct status_change_work;
int fv_uV_request;
int fcc_uA_request;
- bool ok_to_qnovo;
+ int usb_present;
+ int dc_present;
+ struct delayed_work usb_debounce_work;
+ struct delayed_work dc_debounce_work;
+
+ struct delayed_work ptrain_restart_work;
};
static int debug_mask;
@@ -229,6 +253,39 @@
return true;
}
+static bool is_fg_available(struct qnovo *chip)
+{
+ if (!chip->bms_psy)
+ chip->bms_psy = power_supply_get_by_name("bms");
+
+ if (!chip->bms_psy)
+ return false;
+
+ return true;
+}
+
+static bool is_usb_available(struct qnovo *chip)
+{
+ if (!chip->usb_psy)
+ chip->usb_psy = power_supply_get_by_name("usb");
+
+ if (!chip->usb_psy)
+ return false;
+
+ return true;
+}
+
+static bool is_dc_available(struct qnovo *chip)
+{
+ if (!chip->dc_psy)
+ chip->dc_psy = power_supply_get_by_name("dc");
+
+ if (!chip->dc_psy)
+ return false;
+
+ return true;
+}
+
static int qnovo_batt_psy_update(struct qnovo *chip, bool disable)
{
union power_supply_propval pval = {0};
@@ -281,10 +338,86 @@
return -EINVAL;
}
+ /*
+ * fg must be available for enable FG_AVAILABLE_VOTER
+ * won't enable it otherwise
+ */
+
+ if (is_fg_available(chip))
+ power_supply_set_property(chip->bms_psy,
+ POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE,
+ &pval);
+
+ vote(chip->pt_dis_votable, QNOVO_OVERALL_VOTER, disable, 0);
rc = qnovo_batt_psy_update(chip, disable);
return rc;
}
+static int pt_dis_votable_cb(struct votable *votable, void *data, int disable,
+ const char *client)
+{
+ struct qnovo *chip = data;
+ int rc;
+
+ if (disable) {
+ cancel_delayed_work_sync(&chip->ptrain_restart_work);
+ vote(chip->awake_votable, PT_RESTART_VOTER, false, 0);
+ }
+
+ rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
+ (bool)disable ? 0 : QNOVO_PTRAIN_EN_BIT);
+ if (rc < 0) {
+ dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n",
+ (bool)disable ? "disable" : "enable", rc);
+ return rc;
+ }
+
+ if (!disable) {
+ vote(chip->awake_votable, PT_RESTART_VOTER, true, 0);
+ schedule_delayed_work(&chip->ptrain_restart_work,
+ msecs_to_jiffies(20));
+ }
+
+ return 0;
+}
+
+static int not_ok_to_qnovo_cb(struct votable *votable, void *data,
+ int not_ok_to_qnovo,
+ const char *client)
+{
+ struct qnovo *chip = data;
+
+ vote(chip->disable_votable, OK_TO_QNOVO_VOTER, not_ok_to_qnovo, 0);
+ if (not_ok_to_qnovo)
+ vote(chip->disable_votable, USER_VOTER, true, 0);
+
+ kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
+ return 0;
+}
+
+static int chg_ready_cb(struct votable *votable, void *data, int ready,
+ const char *client)
+{
+ struct qnovo *chip = data;
+
+ vote(chip->not_ok_to_qnovo_votable, CHG_READY_VOTER, !ready, 0);
+
+ return 0;
+}
+
+static int awake_cb(struct votable *votable, void *data, int awake,
+ const char *client)
+{
+ struct qnovo *chip = data;
+
+ if (awake)
+ pm_stay_awake(chip->dev);
+ else
+ pm_relax(chip->dev);
+
+ return 0;
+}
+
static int qnovo_parse_dt(struct qnovo *chip)
{
struct device_node *node = chip->dev->of_node;
@@ -626,8 +759,9 @@
char *buf)
{
struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
+ int val = get_effective_result(chip->not_ok_to_qnovo_votable);
- return snprintf(buf, PAGE_SIZE, "%d\n", chip->ok_to_qnovo);
+ return snprintf(buf, PAGE_SIZE, "%d\n", !val);
}
static ssize_t qnovo_enable_show(struct class *c, struct class_attribute *attr,
@@ -656,21 +790,10 @@
static ssize_t pt_enable_show(struct class *c, struct class_attribute *attr,
char *ubuf)
{
- int i = attr - qnovo_attributes;
struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
- u8 buf[2] = {0, 0};
- u16 regval;
- int rc;
+ int val = get_effective_result(chip->pt_dis_votable);
- rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
- if (rc < 0) {
- pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
- return -EINVAL;
- }
- regval = buf[1] << 8 | buf[0];
-
- return snprintf(ubuf, PAGE_SIZE, "%d\n",
- (int)(regval & QNOVO_PTRAIN_EN_BIT));
+ return snprintf(ubuf, PAGE_SIZE, "%d\n", !val);
}
static ssize_t pt_enable_store(struct class *c, struct class_attribute *attr,
@@ -678,21 +801,12 @@
{
struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
unsigned long val;
- int rc = 0;
-
- if (get_effective_result(chip->disable_votable))
- return -EINVAL;
if (kstrtoul(ubuf, 0, &val))
return -EINVAL;
- rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
- (bool)val ? QNOVO_PTRAIN_EN_BIT : 0);
- if (rc < 0) {
- dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n",
- (bool)val ? "enable" : "disable", rc);
- return rc;
- }
+ /* val being 0, userspace wishes to disable pt so vote true */
+ vote(chip->pt_dis_votable, QNI_PT_VOTER, val ? false : true, 0);
return count;
}
@@ -1116,41 +1230,146 @@
{
u8 val = 0;
int rc;
- bool ok_to_qnovo;
- bool changed = false;
+ bool hw_ok_to_qnovo;
rc = qnovo_read(chip, QNOVO_ERROR_STS2, &val, 1);
if (rc < 0) {
pr_err("Couldn't read error sts rc = %d\n", rc);
- ok_to_qnovo = false;
+ hw_ok_to_qnovo = false;
} else {
/*
* For CV mode keep qnovo enabled, userspace is expected to
* disable it after few runs
*/
- ok_to_qnovo = (val == ERR_CV_MODE || val == 0) ? true : false;
+ hw_ok_to_qnovo = (val == ERR_CV_MODE || val == 0) ?
+ true : false;
}
- if (chip->ok_to_qnovo ^ ok_to_qnovo) {
-
- vote(chip->disable_votable, OK_TO_QNOVO_VOTER, !ok_to_qnovo, 0);
- if (!ok_to_qnovo)
- vote(chip->disable_votable, USER_VOTER, true, 0);
-
- chip->ok_to_qnovo = ok_to_qnovo;
- changed = true;
- }
-
- return changed;
+ vote(chip->not_ok_to_qnovo_votable, HW_OK_TO_QNOVO_VOTER,
+ !hw_ok_to_qnovo, 0);
+ return 0;
}
+static void usb_debounce_work(struct work_struct *work)
+{
+ struct qnovo *chip = container_of(work,
+ struct qnovo, usb_debounce_work.work);
+
+ vote(chip->chg_ready_votable, USB_READY_VOTER, true, 0);
+ vote(chip->awake_votable, USB_READY_VOTER, false, 0);
+}
+
+static void dc_debounce_work(struct work_struct *work)
+{
+ struct qnovo *chip = container_of(work,
+ struct qnovo, dc_debounce_work.work);
+
+ vote(chip->chg_ready_votable, DC_READY_VOTER, true, 0);
+ vote(chip->awake_votable, DC_READY_VOTER, false, 0);
+}
+
+#define DEBOUNCE_MS 15000 /* 15 seconds */
static void status_change_work(struct work_struct *work)
{
struct qnovo *chip = container_of(work,
struct qnovo, status_change_work);
+ union power_supply_propval pval;
+ bool usb_present = false, dc_present = false;
+ int rc;
- if (qnovo_update_status(chip))
- kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
+ if (is_fg_available(chip))
+ vote(chip->disable_votable, FG_AVAILABLE_VOTER, false, 0);
+
+ if (is_usb_available(chip)) {
+ rc = power_supply_get_property(chip->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+ usb_present = (rc < 0) ? 0 : pval.intval;
+ }
+
+ if (chip->usb_present && !usb_present) {
+ /* removal */
+ chip->usb_present = 0;
+ cancel_delayed_work_sync(&chip->usb_debounce_work);
+ vote(chip->awake_votable, USB_READY_VOTER, false, 0);
+ vote(chip->chg_ready_votable, USB_READY_VOTER, false, 0);
+ } else if (!chip->usb_present && usb_present) {
+ /* insertion */
+ chip->usb_present = 1;
+ vote(chip->awake_votable, USB_READY_VOTER, true, 0);
+ schedule_delayed_work(&chip->usb_debounce_work,
+ msecs_to_jiffies(DEBOUNCE_MS));
+ }
+
+ if (is_dc_available(chip)) {
+ rc = power_supply_get_property(chip->dc_psy,
+ POWER_SUPPLY_PROP_PRESENT,
+ &pval);
+ dc_present = (rc < 0) ? 0 : pval.intval;
+ }
+
+ if (usb_present)
+ dc_present = 0;
+
+ if (chip->dc_present && !dc_present) {
+ /* removal */
+ chip->dc_present = 0;
+ cancel_delayed_work_sync(&chip->dc_debounce_work);
+ vote(chip->awake_votable, DC_READY_VOTER, false, 0);
+ vote(chip->chg_ready_votable, DC_READY_VOTER, false, 0);
+ } else if (!chip->dc_present && dc_present) {
+ /* insertion */
+ chip->dc_present = 1;
+ vote(chip->awake_votable, DC_READY_VOTER, true, 0);
+ schedule_delayed_work(&chip->dc_debounce_work,
+ msecs_to_jiffies(DEBOUNCE_MS));
+ }
+
+ qnovo_update_status(chip);
+}
+
+static void ptrain_restart_work(struct work_struct *work)
+{
+ struct qnovo *chip = container_of(work,
+ struct qnovo, ptrain_restart_work.work);
+ u8 pt_t1, pt_t2;
+ int rc;
+
+ rc = qnovo_read(chip, QNOVO_PTTIME_STS, &pt_t1, 1);
+ if (rc < 0) {
+ dev_err(chip->dev, "Couldn't read QNOVO_PTTIME_STS rc = %d\n",
+ rc);
+ goto clean_up;
+ }
+
+ /* pttime increments every 2 seconds */
+ msleep(2100);
+
+ rc = qnovo_read(chip, QNOVO_PTTIME_STS, &pt_t2, 1);
+ if (rc < 0) {
+ dev_err(chip->dev, "Couldn't read QNOVO_PTTIME_STS rc = %d\n",
+ rc);
+ goto clean_up;
+ }
+
+ if (pt_t1 != pt_t2)
+ goto clean_up;
+
+ /* Toggle pt enable to restart pulse train */
+ rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT, 0);
+ if (rc < 0) {
+ dev_err(chip->dev, "Couldn't disable pulse train rc=%d\n", rc);
+ goto clean_up;
+ }
+ msleep(1000);
+ rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
+ QNOVO_PTRAIN_EN_BIT);
+ if (rc < 0) {
+ dev_err(chip->dev, "Couldn't enable pulse train rc=%d\n", rc);
+ goto clean_up;
+ }
+
+clean_up:
+ vote(chip->awake_votable, PT_RESTART_VOTER, false, 0);
}
static int qnovo_notifier_call(struct notifier_block *nb,
@@ -1162,7 +1381,10 @@
if (ev != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
- if (strcmp(psy->desc->name, "battery") == 0)
+ if (strcmp(psy->desc->name, "battery") == 0
+ || strcmp(psy->desc->name, "bms") == 0
+ || strcmp(psy->desc->name, "usb") == 0
+ || strcmp(psy->desc->name, "dc") == 0)
schedule_work(&chip->status_change_work);
return NOTIFY_OK;
@@ -1171,7 +1393,23 @@
static irqreturn_t handle_ptrain_done(int irq, void *data)
{
struct qnovo *chip = data;
+ union power_supply_propval pval = {0};
+ /*
+ * hw resets pt_en bit once ptrain_done triggers.
+ * vote on behalf of QNI to disable it such that
+ * once QNI enables it, the votable state changes
+ * and the callback that sets it is indeed invoked
+ */
+ vote(chip->pt_dis_votable, QNI_PT_VOTER, true, 0);
+
+ vote(chip->pt_dis_votable, ESR_VOTER, true, 0);
+ if (is_fg_available(chip))
+ power_supply_set_property(chip->bms_psy,
+ POWER_SUPPLY_PROP_RESISTANCE,
+ &pval);
+
+ vote(chip->pt_dis_votable, ESR_VOTER, false, 0);
qnovo_update_status(chip);
kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
return IRQ_HANDLED;
@@ -1186,6 +1424,11 @@
u8 val;
vote(chip->disable_votable, USER_VOTER, true, 0);
+ vote(chip->disable_votable, FG_AVAILABLE_VOTER, true, 0);
+
+ vote(chip->pt_dis_votable, QNI_PT_VOTER, true, 0);
+ vote(chip->pt_dis_votable, QNOVO_OVERALL_VOTER, true, 0);
+ vote(chip->pt_dis_votable, ESR_VOTER, false, 0);
val = 0;
rc = qnovo_write(chip, QNOVO_STRM_CTRL, &val, 1);
@@ -1349,12 +1592,45 @@
goto cleanup;
}
+ chip->pt_dis_votable = create_votable("QNOVO_PT_DIS", VOTE_SET_ANY,
+ pt_dis_votable_cb, chip);
+ if (IS_ERR(chip->pt_dis_votable)) {
+ rc = PTR_ERR(chip->pt_dis_votable);
+ goto destroy_disable_votable;
+ }
+
+ chip->not_ok_to_qnovo_votable = create_votable("QNOVO_NOT_OK",
+ VOTE_SET_ANY,
+ not_ok_to_qnovo_cb, chip);
+ if (IS_ERR(chip->not_ok_to_qnovo_votable)) {
+ rc = PTR_ERR(chip->not_ok_to_qnovo_votable);
+ goto destroy_pt_dis_votable;
+ }
+
+ chip->chg_ready_votable = create_votable("QNOVO_CHG_READY",
+ VOTE_SET_ANY,
+ chg_ready_cb, chip);
+ if (IS_ERR(chip->chg_ready_votable)) {
+ rc = PTR_ERR(chip->chg_ready_votable);
+ goto destroy_not_ok_to_qnovo_votable;
+ }
+
+ chip->awake_votable = create_votable("QNOVO_AWAKE", VOTE_SET_ANY,
+ awake_cb, chip);
+ if (IS_ERR(chip->awake_votable)) {
+ rc = PTR_ERR(chip->awake_votable);
+ goto destroy_chg_ready_votable;
+ }
+
INIT_WORK(&chip->status_change_work, status_change_work);
+ INIT_DELAYED_WORK(&chip->dc_debounce_work, dc_debounce_work);
+ INIT_DELAYED_WORK(&chip->usb_debounce_work, usb_debounce_work);
+ INIT_DELAYED_WORK(&chip->ptrain_restart_work, ptrain_restart_work);
rc = qnovo_hw_init(chip);
if (rc < 0) {
pr_err("Couldn't initialize hardware rc=%d\n", rc);
- goto destroy_votable;
+ goto destroy_awake_votable;
}
rc = qnovo_register_notifier(chip);
@@ -1390,7 +1666,15 @@
unreg_notifier:
power_supply_unreg_notifier(&chip->nb);
-destroy_votable:
+destroy_awake_votable:
+ destroy_votable(chip->awake_votable);
+destroy_chg_ready_votable:
+ destroy_votable(chip->chg_ready_votable);
+destroy_not_ok_to_qnovo_votable:
+ destroy_votable(chip->not_ok_to_qnovo_votable);
+destroy_pt_dis_votable:
+ destroy_votable(chip->pt_dis_votable);
+destroy_disable_votable:
destroy_votable(chip->disable_votable);
cleanup:
platform_set_drvdata(pdev, NULL);
@@ -1403,6 +1687,9 @@
class_unregister(&chip->qnovo_class);
power_supply_unreg_notifier(&chip->nb);
+ destroy_votable(chip->chg_ready_votable);
+ destroy_votable(chip->not_ok_to_qnovo_votable);
+ destroy_votable(chip->pt_dis_votable);
destroy_votable(chip->disable_votable);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 5605c8a..b3de8d0 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -210,6 +210,9 @@
chg->step_chg_enabled = of_property_read_bool(node,
"qcom,step-charging-enable");
+ chg->sw_jeita_enabled = of_property_read_bool(node,
+ "qcom,sw-jeita-enable");
+
rc = of_property_read_u32(node, "qcom,wd-bark-time-secs",
&chip->dt.wd_bark_time);
if (rc < 0 || chip->dt.wd_bark_time < MIN_WD_BARK_TIME)
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 57a85de..5ae653e 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -1570,8 +1570,8 @@
union power_supply_propval *val)
{
union power_supply_propval pval = {0, };
- bool usb_online, dc_online;
- u8 stat;
+ bool usb_online, dc_online, qnovo_en;
+ u8 stat, pt_en_cmd;
int rc;
rc = smblib_get_prop_usb_online(chg, &pval);
@@ -1639,11 +1639,22 @@
smblib_err(chg, "Couldn't read BATTERY_CHARGER_STATUS_2 rc=%d\n",
rc);
return rc;
- }
+ }
stat &= ENABLE_TRICKLE_BIT | ENABLE_PRE_CHARGING_BIT |
ENABLE_FAST_CHARGING_BIT | ENABLE_FULLON_MODE_BIT;
- if (!stat)
+
+ rc = smblib_read(chg, QNOVO_PT_ENABLE_CMD_REG, &pt_en_cmd);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read QNOVO_PT_ENABLE_CMD_REG rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ qnovo_en = (bool)(pt_en_cmd & QNOVO_PT_ENABLE_CMD_BIT);
+
+ /* ignore stat7 when qnovo is enabled */
+ if (!qnovo_en && !stat)
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
return 0;
@@ -2370,16 +2381,9 @@
int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
union power_supply_propval *val)
{
- const struct apsd_result *apsd_result = smblib_get_apsd_result(chg);
int rc, pulses;
- val->intval = MICRO_5V;
- if (apsd_result == NULL) {
- smblib_err(chg, "APSD result is NULL\n");
- return 0;
- }
-
- switch (apsd_result->pst) {
+ switch (chg->real_charger_type) {
case POWER_SUPPLY_TYPE_USB_HVDCP_3:
rc = smblib_get_pulse_cnt(chg, &pulses);
if (rc < 0) {
@@ -2389,6 +2393,9 @@
}
val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses;
break;
+ case POWER_SUPPLY_TYPE_USB_PD:
+ val->intval = chg->voltage_min_uv;
+ break;
default:
val->intval = MICRO_5V;
break;
@@ -2636,6 +2643,7 @@
}
chg->voltage_min_uv = min_uv;
+ power_supply_changed(chg->usb_main_psy);
return rc;
}
@@ -4083,7 +4091,7 @@
if (rc < 0)
smblib_err(chg, "Couldn't pet the dog rc=%d\n", rc);
- if (chg->step_chg_enabled)
+ if (chg->step_chg_enabled || chg->sw_jeita_enabled)
power_supply_changed(chg->batt_psy);
return IRQ_HANDLED;
@@ -4721,7 +4729,8 @@
return rc;
}
- rc = qcom_step_chg_init(chg->step_chg_enabled);
+ rc = qcom_step_chg_init(chg->step_chg_enabled,
+ chg->sw_jeita_enabled);
if (rc < 0) {
smblib_err(chg, "Couldn't init qcom_step_chg_init rc=%d\n",
rc);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 4ffbeb6..5b59597 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -308,6 +308,7 @@
int dcp_icl_ua;
int fake_capacity;
bool step_chg_enabled;
+ bool sw_jeita_enabled;
bool is_hdc;
bool chg_done;
bool micro_usb_mode;
diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c
index a2c08be..053aac3 100644
--- a/drivers/power/supply/qcom/step-chg-jeita.c
+++ b/drivers/power/supply/qcom/step-chg-jeita.c
@@ -20,7 +20,7 @@
#define MAX_STEP_CHG_ENTRIES 8
#define STEP_CHG_VOTER "STEP_CHG_VOTER"
-#define STATUS_CHANGE_VOTER "STATUS_CHANGE_VOTER"
+#define JEITA_VOTER "JEITA_VOTER"
#define is_between(left, right, value) \
(((left) >= (right) && (left) >= (value) \
@@ -28,23 +28,44 @@
|| ((left) <= (right) && (left) <= (value) \
&& (value) <= (right)))
-struct step_chg_data {
- u32 vbatt_soc_low;
- u32 vbatt_soc_high;
- u32 fcc_ua;
+struct range_data {
+ u32 low_threshold;
+ u32 high_threshold;
+ u32 value;
};
struct step_chg_cfg {
- u32 psy_prop;
- char *prop_name;
- struct step_chg_data cfg[MAX_STEP_CHG_ENTRIES];
+ u32 psy_prop;
+ char *prop_name;
+ int hysteresis;
+ struct range_data fcc_cfg[MAX_STEP_CHG_ENTRIES];
+};
+
+struct jeita_fcc_cfg {
+ u32 psy_prop;
+ char *prop_name;
+ int hysteresis;
+ struct range_data fcc_cfg[MAX_STEP_CHG_ENTRIES];
+};
+
+struct jeita_fv_cfg {
+ u32 psy_prop;
+ char *prop_name;
+ int hysteresis;
+ struct range_data fv_cfg[MAX_STEP_CHG_ENTRIES];
};
struct step_chg_info {
- ktime_t last_update_time;
+ ktime_t step_last_update_time;
+ ktime_t jeita_last_update_time;
bool step_chg_enable;
+ bool sw_jeita_enable;
+ int jeita_fcc_index;
+ int jeita_fv_index;
+ int step_index;
struct votable *fcc_votable;
+ struct votable *fv_votable;
struct wakeup_source *step_chg_ws;
struct power_supply *batt_psy;
struct delayed_work status_change_work;
@@ -53,32 +74,70 @@
static struct step_chg_info *the_chip;
+#define STEP_CHG_HYSTERISIS_DELAY_US 5000000 /* 5 secs */
+
/*
* Step Charging Configuration
* Update the table based on the battery profile
* Supports VBATT and SOC based source
+ * range data must be in increasing ranges and shouldn't overlap
*/
static struct step_chg_cfg step_chg_config = {
- .psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW,
- .prop_name = "VBATT",
- .cfg = {
+ .psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ .prop_name = "VBATT",
+ .hysteresis = 100000, /* 100mV */
+ .fcc_cfg = {
/* VBAT_LOW VBAT_HIGH FCC */
{3600000, 4000000, 3000000},
- {4000000, 4200000, 2800000},
- {4200000, 4400000, 2000000},
+ {4001000, 4200000, 2800000},
+ {4201000, 4400000, 2000000},
},
+ /*
+ * SOC STEP-CHG configuration example.
+ *
+ * .psy_prop = POWER_SUPPLY_PROP_CAPACITY,
+ * .prop_name = "SOC",
+ * .fcc_cfg = {
+ * //SOC_LOW SOC_HIGH FCC
+ * {20, 70, 3000000},
+ * {70, 90, 2750000},
+ * {90, 100, 2500000},
+ * },
+ */
+};
+
/*
- * SOC STEP-CHG configuration example.
- *
- * .psy_prop = POWER_SUPPLY_PROP_CAPACITY,
- * .prop_name = "SOC",
- * .cfg = {
- * //SOC_LOW SOC_HIGH FCC
- * {20, 70, 3000000},
- * {70, 90, 2750000},
- * {90, 100, 2500000},
- * },
+ * Jeita Charging Configuration
+ * Update the table based on the battery profile
+ * Please ensure that the TEMP ranges are programmed in the hw so that
+ * an interrupt is issued and a consequent psy changed will cause us to
+ * react immediately.
+ * range data must be in increasing ranges and shouldn't overlap.
+ * Gaps are okay
*/
+static struct jeita_fcc_cfg jeita_fcc_config = {
+ .psy_prop = POWER_SUPPLY_PROP_TEMP,
+ .prop_name = "BATT_TEMP",
+ .hysteresis = 10, /* 1degC hysteresis */
+ .fcc_cfg = {
+ /* TEMP_LOW TEMP_HIGH FCC */
+ {0, 100, 600000},
+ {101, 200, 2000000},
+ {201, 450, 3000000},
+ {451, 550, 600000},
+ },
+};
+
+static struct jeita_fv_cfg jeita_fv_config = {
+ .psy_prop = POWER_SUPPLY_PROP_TEMP,
+ .prop_name = "BATT_TEMP",
+ .hysteresis = 10, /* 1degC hysteresis */
+ .fv_cfg = {
+ /* TEMP_LOW TEMP_HIGH FCC */
+ {0, 100, 4200000},
+ {101, 450, 4400000},
+ {451, 550, 4200000},
+ },
};
static bool is_batt_available(struct step_chg_info *chip)
@@ -92,22 +151,67 @@
return true;
}
-static int get_fcc(int threshold)
+static int get_val(struct range_data *range, int hysteresis, int current_index,
+ int threshold,
+ int *new_index, int *val)
{
int i;
+ *new_index = -EINVAL;
+ /* first find the matching index without hysteresis */
for (i = 0; i < MAX_STEP_CHG_ENTRIES; i++)
- if (is_between(step_chg_config.cfg[i].vbatt_soc_low,
- step_chg_config.cfg[i].vbatt_soc_high, threshold))
- return step_chg_config.cfg[i].fcc_ua;
+ if (is_between(range[i].low_threshold,
+ range[i].high_threshold, threshold)) {
+ *new_index = i;
+ *val = range[i].value;
+ }
- return -ENODATA;
+ /* if nothing was found, return -ENODATA */
+ if (*new_index == -EINVAL)
+ return -ENODATA;
+ /*
+ * If we don't have a current_index return this
+ * newfound value. There is no hysterisis from out of range
+ * to in range transition
+ */
+ if (current_index == -EINVAL)
+ return 0;
+
+ /*
+ * Check for hysteresis if it in the neighbourhood
+ * of our current index.
+ */
+ if (*new_index == current_index + 1) {
+ if (threshold < range[*new_index].low_threshold + hysteresis) {
+ /*
+ * Stay in the current index, threshold is not higher
+ * by hysteresis amount
+ */
+ *new_index = current_index;
+ *val = range[current_index].value;
+ }
+ } else if (*new_index == current_index - 1) {
+ if (threshold > range[*new_index].high_threshold - hysteresis) {
+ /*
+ * stay in the current index, threshold is not lower
+ * by hysteresis amount
+ */
+ *new_index = current_index;
+ *val = range[current_index].value;
+ }
+ }
+ return 0;
}
static int handle_step_chg_config(struct step_chg_info *chip)
{
union power_supply_propval pval = {0, };
int rc = 0, fcc_ua = 0;
+ u64 elapsed_us;
+
+ elapsed_us = ktime_us_delta(ktime_get(), chip->step_last_update_time);
+ if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US)
+ goto reschedule;
rc = power_supply_get_property(chip->batt_psy,
POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED, &pval);
@@ -119,7 +223,7 @@
if (!chip->step_chg_enable) {
if (chip->fcc_votable)
vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
- return 0;
+ goto update_time;
}
rc = power_supply_get_property(chip->batt_psy,
@@ -130,48 +234,144 @@
return rc;
}
- chip->fcc_votable = find_votable("FCC");
+ rc = get_val(step_chg_config.fcc_cfg, step_chg_config.hysteresis,
+ chip->step_index,
+ pval.intval,
+ &chip->step_index,
+ &fcc_ua);
+ if (rc < 0) {
+ /* remove the vote if no step-based fcc is found */
+ if (chip->fcc_votable)
+ vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
+ goto update_time;
+ }
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
if (!chip->fcc_votable)
return -EINVAL;
- fcc_ua = get_fcc(pval.intval);
- if (fcc_ua < 0) {
- /* remove the vote if no step-based fcc is found */
- vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
- return 0;
- }
-
vote(chip->fcc_votable, STEP_CHG_VOTER, true, fcc_ua);
pr_debug("%s = %d Step-FCC = %duA\n",
step_chg_config.prop_name, pval.intval, fcc_ua);
+update_time:
+ chip->step_last_update_time = ktime_get();
return 0;
+
+reschedule:
+ /* reschedule 1000uS after the remaining time */
+ return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000);
}
-#define STEP_CHG_HYSTERISIS_DELAY_US 5000000 /* 5 secs */
+static int handle_jeita(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0, fcc_ua = 0, fv_uv = 0;
+ u64 elapsed_us;
+
+ if (!chip->sw_jeita_enable) {
+ if (chip->fcc_votable)
+ vote(chip->fcc_votable, JEITA_VOTER, false, 0);
+ if (chip->fv_votable)
+ vote(chip->fv_votable, JEITA_VOTER, false, 0);
+ return 0;
+ }
+
+ elapsed_us = ktime_us_delta(ktime_get(), chip->jeita_last_update_time);
+ if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US)
+ goto reschedule;
+
+ rc = power_supply_get_property(chip->batt_psy,
+ jeita_fcc_config.psy_prop, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't read %s property rc=%d\n",
+ step_chg_config.prop_name, rc);
+ return rc;
+ }
+
+ rc = get_val(jeita_fcc_config.fcc_cfg, jeita_fcc_config.hysteresis,
+ chip->jeita_fcc_index,
+ pval.intval,
+ &chip->jeita_fcc_index,
+ &fcc_ua);
+ if (rc < 0) {
+ /* remove the vote if no step-based fcc is found */
+ if (chip->fcc_votable)
+ vote(chip->fcc_votable, JEITA_VOTER, false, 0);
+ goto update_time;
+ }
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable)
+ /* changing FCC is a must */
+ return -EINVAL;
+
+ vote(chip->fcc_votable, JEITA_VOTER, true, fcc_ua);
+
+ rc = get_val(jeita_fv_config.fv_cfg, jeita_fv_config.hysteresis,
+ chip->jeita_fv_index,
+ pval.intval,
+ &chip->jeita_fv_index,
+ &fv_uv);
+ if (rc < 0) {
+ /* remove the vote if no step-based fcc is found */
+ if (chip->fv_votable)
+ vote(chip->fv_votable, JEITA_VOTER, false, 0);
+ goto update_time;
+ }
+
+ chip->fv_votable = find_votable("FV");
+ if (!chip->fv_votable)
+ goto update_time;
+
+ vote(chip->fv_votable, JEITA_VOTER, true, fv_uv);
+
+ pr_debug("%s = %d FCC = %duA FV = %duV\n",
+ step_chg_config.prop_name, pval.intval, fcc_ua, fv_uv);
+
+update_time:
+ chip->jeita_last_update_time = ktime_get();
+ return 0;
+
+reschedule:
+ /* reschedule 1000uS after the remaining time */
+ return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000);
+}
+
static void status_change_work(struct work_struct *work)
{
struct step_chg_info *chip = container_of(work,
struct step_chg_info, status_change_work.work);
int rc = 0;
- u64 elapsed_us;
-
- elapsed_us = ktime_us_delta(ktime_get(), chip->last_update_time);
- if (elapsed_us < STEP_CHG_HYSTERISIS_DELAY_US)
- goto release_ws;
+ int reschedule_us;
+ int reschedule_jeita_work_us = 0;
+ int reschedule_step_work_us = 0;
if (!is_batt_available(chip))
- goto release_ws;
+ return;
+
+ /* skip elapsed_us debounce for handling battery temperature */
+ rc = handle_jeita(chip);
+ if (rc > 0)
+ reschedule_jeita_work_us = rc;
+ else if (rc < 0)
+ pr_err("Couldn't handle sw jeita rc = %d\n", rc);
rc = handle_step_chg_config(chip);
+ if (rc > 0)
+ reschedule_step_work_us = rc;
if (rc < 0)
- goto release_ws;
+ pr_err("Couldn't handle step rc = %d\n", rc);
- chip->last_update_time = ktime_get();
-
-release_ws:
- __pm_relax(chip->step_chg_ws);
+ reschedule_us = min(reschedule_jeita_work_us, reschedule_step_work_us);
+ if (reschedule_us == 0)
+ __pm_relax(chip->step_chg_ws);
+ else
+ schedule_delayed_work(&chip->status_change_work,
+ usecs_to_jiffies(reschedule_us));
}
static int step_chg_notifier_call(struct notifier_block *nb,
@@ -205,7 +405,7 @@
return 0;
}
-int qcom_step_chg_init(bool step_chg_enable)
+int qcom_step_chg_init(bool step_chg_enable, bool sw_jeita_enable)
{
int rc;
struct step_chg_info *chip;
@@ -226,12 +426,34 @@
}
chip->step_chg_enable = step_chg_enable;
+ chip->sw_jeita_enable = sw_jeita_enable;
+
+ chip->step_index = -EINVAL;
+ chip->jeita_fcc_index = -EINVAL;
+ chip->jeita_fv_index = -EINVAL;
if (step_chg_enable && (!step_chg_config.psy_prop ||
!step_chg_config.prop_name)) {
/* fail if step-chg configuration is invalid */
pr_err("Step-chg configuration not defined - fail\n");
- return -ENODATA;
+ rc = -ENODATA;
+ goto release_wakeup_source;
+ }
+
+ if (sw_jeita_enable && (!jeita_fcc_config.psy_prop ||
+ !jeita_fcc_config.prop_name)) {
+ /* fail if step-chg configuration is invalid */
+ pr_err("Jeita TEMP configuration not defined - fail\n");
+ rc = -ENODATA;
+ goto release_wakeup_source;
+ }
+
+ if (sw_jeita_enable && (!jeita_fv_config.psy_prop ||
+ !jeita_fv_config.prop_name)) {
+ /* fail if step-chg configuration is invalid */
+ pr_err("Jeita TEMP configuration not defined - fail\n");
+ rc = -ENODATA;
+ goto release_wakeup_source;
}
INIT_DELAYED_WORK(&chip->status_change_work, status_change_work);
diff --git a/drivers/power/supply/qcom/step-chg-jeita.h b/drivers/power/supply/qcom/step-chg-jeita.h
index 236877a..5bb2b99 100644
--- a/drivers/power/supply/qcom/step-chg-jeita.h
+++ b/drivers/power/supply/qcom/step-chg-jeita.h
@@ -12,6 +12,6 @@
#ifndef __STEP_CHG_H__
#define __STEP_CHG_H__
-int qcom_step_chg_init(bool step_chg_enable);
+int qcom_step_chg_init(bool step_chg_enable, bool sw_jeita_enable);
void qcom_step_chg_deinit(void);
#endif /* __STEP_CHG_H__ */
diff --git a/drivers/regulator/rpmh-regulator.c b/drivers/regulator/rpmh-regulator.c
index 1ba8926..562b05a 100644
--- a/drivers/regulator/rpmh-regulator.c
+++ b/drivers/regulator/rpmh-regulator.c
@@ -433,6 +433,7 @@
bool sleep_set_differs = aggr_vreg->sleep_request_sent;
bool wait_for_ack = aggr_vreg->always_wait_for_ack
|| aggr_vreg->next_wait_for_ack;
+ bool resend_active = false;
int i, j, max_reg_index, rc;
enum rpmh_state state;
u32 sent_mask;
@@ -471,6 +472,12 @@
if ((req_active.reg[i] != req_sleep.reg[i])
&& (req_sleep.valid & BIT(i))) {
sleep_set_differs = true;
+ /*
+ * Resend full active set request so that
+ * all parameters are specified in the wake-only
+ * state request.
+ */
+ resend_active = !aggr_vreg->use_awake_state;
break;
}
}
@@ -523,7 +530,7 @@
if ((req_active.valid & BIT(i))
&& (!(aggr_vreg->aggr_req_active.valid & BIT(i))
|| aggr_vreg->aggr_req_active.reg[i]
- != req_active.reg[i])) {
+ != req_active.reg[i] || resend_active)) {
cmd[j].addr = aggr_vreg->addr + i * 4;
cmd[j].data = req_active.reg[i];
j++;
diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c
index 5a578f1..557ca19 100644
--- a/drivers/scsi/ufs/ufs-debugfs.c
+++ b/drivers/scsi/ufs/ufs-debugfs.c
@@ -1469,6 +1469,11 @@
hba->debugfs_files.err_occurred = true;
}
+void ufsdbg_clr_err_state(struct ufs_hba *hba)
+{
+ hba->debugfs_files.err_occurred = false;
+}
+
DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_err_state,
ufsdbg_read_err_state,
ufsdbg_clear_err_state,
diff --git a/drivers/scsi/ufs/ufs-debugfs.h b/drivers/scsi/ufs/ufs-debugfs.h
index 13848e8..8ae5eb4 100644
--- a/drivers/scsi/ufs/ufs-debugfs.h
+++ b/drivers/scsi/ufs/ufs-debugfs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -38,6 +38,7 @@
void ufsdbg_pr_buf_to_std(struct ufs_hba *hba, int offset, int num_regs,
char *str, void *priv);
void ufsdbg_set_err_state(struct ufs_hba *hba);
+void ufsdbg_clr_err_state(struct ufs_hba *hba);
#else
static inline void ufsdbg_add_debugfs(struct ufs_hba *hba)
{
@@ -52,6 +53,9 @@
void ufsdbg_set_err_state(struct ufs_hba *hba)
{
}
+void ufsdbg_clr_err_state(struct ufs_hba *hba)
+{
+}
#endif
#ifdef CONFIG_UFS_FAULT_INJECTION
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index f85a67d..0ae51b9 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -65,6 +65,9 @@
#define UFS_MAX_LUNS (SCSI_W_LUN_BASE + UFS_UPIU_MAX_UNIT_NUM_ID)
#define UFS_UPIU_WLUN_ID (1 << 7)
#define UFS_UPIU_MAX_GENERAL_LUN 8
+#define UFS_MAX_WLUS 4
+#define UFS_MAX_LUS (UFS_UPIU_MAX_GENERAL_LUN + UFS_MAX_WLUS)
+
#define QUERY_DESC_IDN_CONFIGURATION QUERY_DESC_IDN_CONFIGURAION
/* Well known logical unit id in LUN field of UPIU */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a43c18f..c132dbc 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -331,6 +331,26 @@
return ufs_pm_lvl_states[lvl].link_state;
}
+static inline void ufshcd_set_card_online(struct ufs_hba *hba)
+{
+ atomic_set(&hba->card_state, UFS_CARD_STATE_ONLINE);
+}
+
+static inline void ufshcd_set_card_offline(struct ufs_hba *hba)
+{
+ atomic_set(&hba->card_state, UFS_CARD_STATE_OFFLINE);
+}
+
+static inline bool ufshcd_is_card_online(struct ufs_hba *hba)
+{
+ return (atomic_read(&hba->card_state) == UFS_CARD_STATE_ONLINE);
+}
+
+static inline bool ufshcd_is_card_offline(struct ufs_hba *hba)
+{
+ return (atomic_read(&hba->card_state) == UFS_CARD_STATE_OFFLINE);
+}
+
static inline enum ufs_pm_level
ufs_get_desired_pm_lvl_for_dev_link_state(enum ufs_dev_pwr_mode dev_state,
enum uic_link_state link_state)
@@ -384,6 +404,7 @@
unsigned long *freq, u32 flags);
static int ufshcd_devfreq_get_dev_status(struct device *dev,
struct devfreq_dev_status *stat);
+static void __ufshcd_shutdown_clkscaling(struct ufs_hba *hba);
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
static struct devfreq_simple_ondemand_data ufshcd_ondemand_data = {
@@ -2983,6 +3004,12 @@
has_read_lock = true;
}
+ /*
+ * err might be non-zero here but logic later in this function
+ * assumes that err is set to 0.
+ */
+ err = 0;
+
spin_lock_irqsave(hba->host->host_lock, flags);
/* if error handling is in progress, return host busy */
@@ -2991,6 +3018,12 @@
goto out_unlock;
}
+ if (hba->extcon && ufshcd_is_card_offline(hba)) {
+ set_host_byte(cmd, DID_BAD_TARGET);
+ cmd->scsi_done(cmd);
+ goto out_unlock;
+ }
+
switch (hba->ufshcd_state) {
case UFSHCD_STATE_OPERATIONAL:
break;
@@ -5152,6 +5185,14 @@
out:
if (ret)
dev_err(hba->dev, "link startup failed %d\n", ret);
+ /*
+ * For some external cards, link startup succeeds only after few link
+ * startup attempts and err_state may get set in this case.
+ * But as the link startup has finally succeded, we are clearing the
+ * error state.
+ */
+ else if (hba->extcon)
+ ufsdbg_clr_err_state(hba);
return ret;
}
@@ -5596,8 +5637,15 @@
__func__, (intr_status & UIC_HIBERNATE_ENTER) ?
"Enter" : "Exit",
intr_status, ufshcd_get_upmcrs(hba));
- __ufshcd_print_host_regs(hba, true);
- ufshcd_print_host_state(hba);
+ /*
+ * It is possible to see auto-h8 errors during card
+ * removal, so set this flag and let the error handler
+ * decide if this error is seen while card was present
+ * or due to card removal.
+ * If error is seen during card removal, we don't want
+ * to printout the debug messages.
+ */
+ hba->auto_h8_err = true;
schedule_work(&hba->eh_work);
retval = IRQ_HANDLED;
}
@@ -6197,6 +6245,32 @@
hba = container_of(work, struct ufs_hba, eh_work);
spin_lock_irqsave(hba->host->host_lock, flags);
+ if (hba->extcon) {
+ if (ufshcd_is_card_online(hba)) {
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+ /*
+ * TODO: need better way to ensure that this delay is
+ * more than extcon's debounce-ms
+ */
+ msleep(300);
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ }
+
+ /*
+ * ignore error if card was online and offline/removed now or
+ * card was already offline.
+ */
+ if (ufshcd_is_card_offline(hba)) {
+ hba->saved_err = 0;
+ hba->saved_uic_err = 0;
+ hba->saved_ce_err = 0;
+ hba->auto_h8_err = false;
+ hba->force_host_reset = false;
+ hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
+ goto out;
+ }
+ }
+
ufsdbg_set_err_state(hba);
if (hba->ufshcd_state == UFSHCD_STATE_RESET)
@@ -6241,7 +6315,8 @@
* Dump controller state before resetting. Transfer requests state
* will be dump as part of the request completion.
*/
- if (hba->saved_err & (INT_FATAL_ERRORS | UIC_ERROR)) {
+ if ((hba->saved_err & (INT_FATAL_ERRORS | UIC_ERROR)) ||
+ hba->auto_h8_err) {
dev_err(hba->dev, "%s: saved_err 0x%x saved_uic_err 0x%x",
__func__, hba->saved_err, hba->saved_uic_err);
if (!hba->silence_err_logs) {
@@ -6254,6 +6329,7 @@
ufshcd_print_cmd_log(hba);
spin_lock_irqsave(hba->host->host_lock, flags);
}
+ hba->auto_h8_err = false;
}
if ((hba->saved_err & INT_FATAL_ERRORS)
@@ -6492,7 +6568,10 @@
queue_eh_work = true;
}
- if (queue_eh_work) {
+ if (hba->extcon && ufshcd_is_card_offline(hba)) {
+ /* ignore UIC errors if card is offline */
+ retval |= IRQ_HANDLED;
+ } else if (queue_eh_work) {
/*
* update the transfer error masks to sticky bits, let's do this
* irrespective of current ufshcd_state.
@@ -7838,6 +7917,13 @@
if (ret) {
ufshcd_set_ufs_dev_poweroff(hba);
ufshcd_set_link_off(hba);
+ if (hba->extcon) {
+ if (!ufshcd_is_card_online(hba))
+ ufsdbg_clr_err_state(hba);
+ ufshcd_set_card_offline(hba);
+ }
+ } else if (hba->extcon) {
+ ufshcd_set_card_online(hba);
}
/*
@@ -7853,22 +7939,60 @@
return ret;
}
+static void ufshcd_remove_device(struct ufs_hba *hba)
+{
+ struct scsi_device *sdev;
+ struct scsi_device *sdev_cache[UFS_MAX_LUS];
+ int sdev_count = 0, i;
+ unsigned long flags;
+
+ ufshcd_hold_all(hba);
+ /* Reset the host controller */
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->silence_err_logs = true;
+ ufshcd_hba_stop(hba, false);
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ ufshcd_set_ufs_dev_poweroff(hba);
+ ufshcd_set_link_off(hba);
+ __ufshcd_shutdown_clkscaling(hba);
+
+ /* Complete requests that have door-bell cleared by h/w */
+ ufshcd_complete_requests(hba);
+
+ /* remove all scsi devices */
+ list_for_each_entry(sdev, &hba->host->__devices, siblings) {
+ if (sdev_count < UFS_MAX_LUS) {
+ sdev_cache[sdev_count] = sdev;
+ sdev_count++;
+ }
+ }
+
+ for (i = 0; i < sdev_count; i++)
+ scsi_remove_device(sdev_cache[i]);
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->silence_err_logs = false;
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ ufshcd_release_all(hba);
+}
+
static void ufshcd_card_detect_handler(struct work_struct *work)
{
struct ufs_hba *hba;
hba = container_of(work, struct ufs_hba, card_detect_work);
- if (hba->card_detect_event &&
- (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL)) {
- dev_dbg(hba->dev, "%s: card detect notification received\n",
- __func__);
+
+ if (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device) {
pm_runtime_get_sync(hba->dev);
ufshcd_detect_device(hba);
/* ufshcd_probe_hba() calls pm_runtime_put_sync() on exit */
- } else {
- dev_dbg(hba->dev, "%s: card removed notification received\n",
- __func__);
- /* TODO: remove the scsi device instances */
+ } else if (ufshcd_is_card_offline(hba) && hba->sdev_ufs_device) {
+ pm_runtime_get_sync(hba->dev);
+ ufshcd_remove_device(hba);
+ pm_runtime_put_sync(hba->dev);
+ ufsdbg_clr_err_state(hba);
}
}
@@ -7877,9 +8001,23 @@
{
struct ufs_hba *hba = container_of(nb, struct ufs_hba, card_detect_nb);
- hba->card_detect_event = event;
- schedule_work(&hba->card_detect_work);
+ if (event)
+ ufshcd_set_card_online(hba);
+ else
+ ufshcd_set_card_offline(hba);
+ if (ufshcd_is_card_offline(hba) && !hba->sdev_ufs_device)
+ goto out;
+
+ /*
+ * card insertion/removal are very infrequent events and having this
+ * message helps if there is some issue with card detection/removal.
+ */
+ dev_info(hba->dev, "%s: card %s notification rcvd\n",
+ __func__, ufshcd_is_card_online(hba) ? "inserted" : "removed");
+
+ schedule_work(&hba->card_detect_work);
+out:
return NOTIFY_DONE;
}
@@ -9158,7 +9296,9 @@
if (ret)
goto disable_vreg;
- if (ufshcd_is_link_off(hba))
+ if (hba->extcon &&
+ (ufshcd_is_card_offline(hba) ||
+ (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device)))
goto skip_dev_ops;
if (ufshcd_is_link_hibern8(hba)) {
@@ -9517,7 +9657,7 @@
ufshcd_add_spm_lvl_sysfs_nodes(hba);
}
-static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba)
+static void __ufshcd_shutdown_clkscaling(struct ufs_hba *hba)
{
bool suspend = false;
unsigned long flags;
@@ -9534,7 +9674,6 @@
* doesn't race with shutdown
*/
if (ufshcd_is_clkscaling_supported(hba)) {
- device_remove_file(hba->dev, &hba->clk_scaling.enable_attr);
cancel_work_sync(&hba->clk_scaling.suspend_work);
cancel_work_sync(&hba->clk_scaling.resume_work);
if (suspend)
@@ -9542,8 +9681,16 @@
}
/* Unregister so that devfreq_monitor can't race with shutdown */
- if (hba->devfreq)
+ if (hba->devfreq) {
devfreq_remove_device(hba->devfreq);
+ hba->devfreq = NULL;
+ }
+}
+
+static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba)
+{
+ __ufshcd_shutdown_clkscaling(hba);
+ device_remove_file(hba->dev, &hba->clk_scaling.enable_attr);
}
/**
@@ -9878,6 +10025,9 @@
{
int ret = 0;
+ if (hba->extcon && ufshcd_is_card_offline(hba))
+ return 0;
+
/* let's not get into low power until clock scaling is completed */
hba->ufs_stats.clk_hold.ctx = CLK_SCALE_WORK;
ufshcd_hold_all(hba);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index eaed1b3..fc855db 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -688,6 +688,13 @@
u32 seq_num;
};
+/* UFS card state - hotplug state */
+enum ufshcd_card_state {
+ UFS_CARD_STATE_UNKNOWN = 0,
+ UFS_CARD_STATE_ONLINE = 1,
+ UFS_CARD_STATE_OFFLINE = 2,
+};
+
/**
* struct ufs_hba - per adapter private structure
* @mmio_base: UFSHCI base register address
@@ -737,7 +744,7 @@
* @extcon: pointer to external connector device
* @card_detect_nb: card detector notifier registered with @extcon
* @card_detect_work: work to exectute the card detect function
- * @card_detect_event: card detect event, 0 = removed, 1 = inserted
+ * @card_state: card state event, enum ufshcd_card_state defines possible states
* @vreg_info: UFS device voltage regulator information
* @clk_list_head: UFS host controller clocks list node head
* @pwr_info: holds current power mode
@@ -875,6 +882,7 @@
u32 saved_ce_err;
bool silence_err_logs;
bool force_host_reset;
+ bool auto_h8_err;
/* Device management request data */
struct ufs_dev_cmd dev_cmd;
@@ -914,7 +922,7 @@
struct extcon_dev *extcon;
struct notifier_block card_detect_nb;
struct work_struct card_detect_work;
- unsigned long card_detect_event;
+ atomic_t card_state;
struct ufs_pa_layer_attr pwr_info;
struct ufs_pwr_mode_info max_pwr_info;
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index fa8191e..a2ab266 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -266,7 +266,6 @@
struct icnss_event_pd_service_down_data {
bool crashed;
bool fw_rejuvenate;
- bool wdog_bite;
};
struct icnss_driver_event {
@@ -291,7 +290,6 @@
ICNSS_PD_RESTART,
ICNSS_MSA0_ASSIGNED,
ICNSS_WLFW_EXISTS,
- ICNSS_WDOG_BITE,
ICNSS_SHUTDOWN_DONE,
ICNSS_HOST_TRIGGERED_PDR,
};
@@ -2149,10 +2147,7 @@
icnss_pm_relax(priv);
- if (test_bit(ICNSS_WDOG_BITE, &priv->state)) {
- icnss_call_driver_shutdown(priv);
- clear_bit(ICNSS_WDOG_BITE, &priv->state);
- }
+ icnss_call_driver_shutdown(priv);
clear_bit(ICNSS_PD_RESTART, &priv->state);
@@ -2302,8 +2297,7 @@
static int icnss_fw_crashed(struct icnss_priv *priv,
struct icnss_event_pd_service_down_data *event_data)
{
- icnss_pr_dbg("FW crashed, state: 0x%lx, wdog_bite: %d\n",
- priv->state, event_data->wdog_bite);
+ icnss_pr_dbg("FW crashed, state: 0x%lx\n", priv->state);
set_bit(ICNSS_PD_RESTART, &priv->state);
clear_bit(ICNSS_FW_READY, &priv->state);
@@ -2313,17 +2307,9 @@
if (test_bit(ICNSS_DRIVER_PROBED, &priv->state))
icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_CRASHED, NULL);
- if (event_data->wdog_bite) {
- set_bit(ICNSS_WDOG_BITE, &priv->state);
- goto out;
- }
-
- icnss_call_driver_shutdown(priv);
-
if (event_data->fw_rejuvenate)
wlfw_rejuvenate_ack_send_sync_msg(priv);
-out:
return 0;
}
@@ -2520,9 +2506,6 @@
event_data->crashed = notif->crashed;
- if (notif->crashed == CRASH_STATUS_WDOG_BITE)
- event_data->wdog_bite = true;
-
fw_down_data.crashed = !!notif->crashed;
icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data);
@@ -2612,7 +2595,6 @@
switch (*state) {
case ROOT_PD_WDOG_BITE:
- event_data->wdog_bite = true;
priv->stats.recovery.root_pd_crash++;
break;
case ROOT_PD_SHUTDOWN:
@@ -3846,9 +3828,6 @@
case ICNSS_WLFW_EXISTS:
seq_puts(s, "WLAN FW EXISTS");
continue;
- case ICNSS_WDOG_BITE:
- seq_puts(s, "MODEM WDOG BITE");
- continue;
case ICNSS_SHUTDOWN_DONE:
seq_puts(s, "SHUTDOWN DONE");
continue;
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_dbg.c b/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
index 015edb3..df29233 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_dbg.c
@@ -38,6 +38,7 @@
static struct dentry *clients;
static struct dentry *dir;
static DEFINE_MUTEX(msm_bus_dbg_fablist_lock);
+static DEFINE_RT_MUTEX(msm_bus_dbg_cllist_lock);
struct msm_bus_dbg_state {
uint32_t cl;
uint8_t enable;
@@ -289,7 +290,9 @@
struct msm_bus_cldata *cldata = NULL;
const struct msm_bus_client_handle *handle = file->private_data;
int found = 0;
+ ssize_t ret;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if ((cldata->clid == cl) ||
(cldata->handle && (cldata->handle == handle))) {
@@ -298,12 +301,17 @@
}
}
- if (!found)
+ if (!found) {
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
+ }
bsize = cldata->size;
- return simple_read_from_buffer(buf, count, ppos,
+ ret = simple_read_from_buffer(buf, count, ppos,
cldata->buffer, bsize);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+
+ return ret;
}
static int client_data_open(struct inode *inode, struct file *file)
@@ -339,7 +347,9 @@
return -ENOMEM;
}
cldata->handle = pdata;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}
@@ -352,6 +362,7 @@
bool found = false;
char *buf = NULL;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
found = true;
@@ -359,12 +370,15 @@
}
}
- if (!found)
+ if (!found) {
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
+ }
if (cldata->file == NULL) {
if (pdata->name == NULL) {
MSM_BUS_DBG("Client doesn't have a name\n");
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -EINVAL;
}
cldata->file = debugfs_create_file(pdata->name, S_IRUGO,
@@ -393,6 +407,7 @@
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", ib);
i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
cldata->size = i;
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec,
pdata->name, pdata->mas, pdata->slv, ab, ib);
@@ -404,6 +419,7 @@
{
struct msm_bus_cldata *cldata = NULL;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->handle == pdata) {
debugfs_remove(cldata->file);
@@ -412,6 +428,7 @@
break;
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}
static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
@@ -429,7 +446,9 @@
cldata->clid = clid;
cldata->file = file;
cldata->size = 0;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_add_tail(&cldata->list, &cl_list);
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return 0;
}
@@ -437,13 +456,16 @@
{
struct msm_bus_cldata *cldata = NULL;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
+ debugfs_remove(cldata->file);
list_del(&cldata->list);
kfree(cldata);
break;
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
}
static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
@@ -455,6 +477,7 @@
struct timespec ts;
int found = 0;
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->clid == clid) {
found = 1;
@@ -462,11 +485,14 @@
}
}
- if (!found)
+ if (!found) {
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
return -ENOENT;
+ }
if (cldata->file == NULL) {
if (pdata->name == NULL) {
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
MSM_BUS_DBG("Client doesn't have a name\n");
return -EINVAL;
}
@@ -514,21 +540,11 @@
cldata->index = index;
cldata->size = i;
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+
return i;
}
-static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
-{
- int ret = 0;
-
- if ((index < 0) || (index > cldata->pdata->num_usecases)) {
- MSM_BUS_DBG("Invalid index!\n");
- return -EINVAL;
- }
- ret = msm_bus_scale_client_update_request(cldata->clid, index);
- return ret;
-}
-
static ssize_t msm_bus_dbg_update_request_write(struct file *file,
const char __user *ubuf, size_t cnt, loff_t *ppos)
{
@@ -538,19 +554,26 @@
char *chid;
char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL);
int found = 0;
+ uint32_t clid;
+ ssize_t res = cnt;
if (!buf || IS_ERR(buf)) {
MSM_BUS_ERR("Memory allocation for buffer failed\n");
return -ENOMEM;
}
- if (cnt == 0)
- return 0;
- if (copy_from_user(buf, ubuf, cnt))
- return -EFAULT;
+ if (cnt == 0) {
+ res = 0;
+ goto out;
+ }
+ if (copy_from_user(buf, ubuf, cnt)) {
+ res = -EFAULT;
+ goto out;
+ }
buf[cnt] = '\0';
chid = buf;
MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf));
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (strnstr(chid, cldata->pdata->name, cnt)) {
found = 1;
@@ -559,23 +582,37 @@
if (chid) {
ret = kstrtoul(chid, 10, &index);
if (ret) {
- MSM_BUS_DBG("Index conversion failed\n"
- );
- return -EFAULT;
+ MSM_BUS_DBG("Index conversion\n"
+ " failed\n");
+ rt_mutex_unlock(
+ &msm_bus_dbg_cllist_lock);
+ res = -EFAULT;
+ goto out;
}
} else {
- MSM_BUS_DBG("Error parsing input.\n"
- "Index not found\n");
+ MSM_BUS_DBG("Error parsing input. Index not\n"
+ " found\n");
found = 0;
}
+ if ((index < 0) ||
+ (index > cldata->pdata->num_usecases)) {
+ MSM_BUS_DBG("Invalid index!\n");
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+ res = -EINVAL;
+ goto out;
+ }
+ clid = cldata->clid;
break;
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
if (found)
- msm_bus_dbg_update_request(cldata, index);
+ msm_bus_scale_client_update_request(clid, index);
+
+out:
kfree(buf);
- return cnt;
+ return res;
}
/**
@@ -598,8 +635,10 @@
break;
}
}
- if (!found)
+ if (!found) {
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
+ }
bsize = fablist->size;
ret = simple_read_from_buffer(buf, count, ppos,
fablist->buffer, bsize);
@@ -689,8 +728,10 @@
break;
}
}
- if (!found)
+ if (!found) {
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
return -ENOENT;
+ }
if (fablist->file == NULL) {
MSM_BUS_DBG("Fabric dbg entry does not exist\n");
@@ -741,6 +782,8 @@
"\nDumping curent client votes to trace log\n");
if (*ppos)
goto exit_dump_clients_read;
+
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (IS_ERR_OR_NULL(cldata->pdata))
continue;
@@ -756,6 +799,7 @@
cldata->pdata->active_only);
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
exit_dump_clients_read:
return simple_read_from_buffer(buf, count, ppos, msg, cnt);
}
@@ -880,6 +924,7 @@
goto err;
}
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry(cldata, &cl_list, list) {
if (cldata->pdata) {
if (cldata->pdata->name == NULL) {
@@ -899,6 +944,7 @@
&client_data_fops);
}
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
if (debugfs_create_file("dump_clients", S_IRUGO | S_IWUSR,
clients, NULL, &msm_bus_dbg_dump_clients_fops) == NULL)
@@ -911,6 +957,7 @@
if (fablist->file == NULL) {
MSM_BUS_DBG("Cannot create files for commit data\n");
kfree(rules_buf);
+ mutex_unlock(&msm_bus_dbg_fablist_lock);
goto err;
}
}
@@ -930,10 +977,14 @@
struct msm_bus_cldata *cldata = NULL, *cldata_temp;
debugfs_remove_recursive(dir);
+
+ rt_mutex_lock(&msm_bus_dbg_cllist_lock);
list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) {
list_del(&cldata->list);
kfree(cldata);
}
+ rt_mutex_unlock(&msm_bus_dbg_cllist_lock);
+
mutex_lock(&msm_bus_dbg_fablist_lock);
list_for_each_entry_safe(fablist, fablist_temp, &fabdata_list, list) {
list_del(&fablist->list);
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 185d862..007b353 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
@@ -624,16 +624,25 @@
MSM_BUS_ERR("%s: Error invalidating mbox: %d\n",
__func__, ret);
- if (cur_rsc->rscdev->req_state == RPMH_AWAKE_STATE)
+ if (cur_rsc->rscdev->req_state == RPMH_AWAKE_STATE) {
ret = rpmh_write(cur_mbox, cur_rsc->rscdev->req_state,
cmdlist_active, cnt_active);
- else
+ /*
+ * Ignore -EBUSY from rpmh_write if it's an AWAKE_STATE
+ * request since AWAKE requests are invalid when
+ * the display RSC is in solver mode and the bus driver
+ * does not know the current state of the display RSC.
+ */
+ if (ret && ret != -EBUSY)
+ MSM_BUS_ERR("%s: error sending active/awake sets: %d\n",
+ __func__, ret);
+ } else {
ret = rpmh_write_passthru(cur_mbox, cur_rsc->rscdev->req_state,
cmdlist_active, n_active);
- if (ret)
- MSM_BUS_ERR("%s: error sending active/awake sets: %d\n",
+ if (ret)
+ MSM_BUS_ERR("%s: error sending active/awake sets: %d\n",
__func__, ret);
-
+ }
ret = rpmh_write_passthru(cur_mbox, RPMH_WAKE_ONLY_STATE,
cmdlist_wake, n_wake);
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index 67a5e05..e4ada03 100644
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -342,6 +342,13 @@
goto end;
}
+ if (strcmp(app.name, FP_APP_NAME)) {
+ dev_err(drvdata->dev, "%s: Invalid app name\n",
+ __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+
if (drvdata->app_handle) {
dev_err(drvdata->dev, "%s: LOAD app already loaded, unloading first\n",
__func__);
@@ -388,9 +395,7 @@
pr_debug("app %s load after\n", app.name);
- if (!strcmp(app.name, FP_APP_NAME))
- drvdata->fp_app_handle = drvdata->app_handle;
-
+ drvdata->fp_app_handle = drvdata->app_handle;
break;
}
case QBT1000_UNLOAD_APP:
diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index 68ddd1f..ac5cc54 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -397,18 +397,22 @@
__asmeq("%1", R1_STR)
__asmeq("%2", R2_STR)
__asmeq("%3", R3_STR)
- __asmeq("%4", R0_STR)
- __asmeq("%5", R1_STR)
- __asmeq("%6", R2_STR)
- __asmeq("%7", R3_STR)
- __asmeq("%8", R4_STR)
- __asmeq("%9", R5_STR)
- __asmeq("%10", R6_STR)
+ __asmeq("%4", R4_STR)
+ __asmeq("%5", R5_STR)
+ __asmeq("%6", R6_STR)
+ __asmeq("%7", R0_STR)
+ __asmeq("%8", R1_STR)
+ __asmeq("%9", R2_STR)
+ __asmeq("%10", R3_STR)
+ __asmeq("%11", R4_STR)
+ __asmeq("%12", R5_STR)
+ __asmeq("%13", R6_STR)
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0\n"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+ : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3),
+ "=r" (r4), "=r" (r5), "=r" (r6)
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
"r" (r5), "r" (r6)
: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
@@ -442,18 +446,22 @@
__asmeq("%1", R1_STR)
__asmeq("%2", R2_STR)
__asmeq("%3", R3_STR)
- __asmeq("%4", R0_STR)
- __asmeq("%5", R1_STR)
- __asmeq("%6", R2_STR)
- __asmeq("%7", R3_STR)
- __asmeq("%8", R4_STR)
- __asmeq("%9", R5_STR)
- __asmeq("%10", R6_STR)
+ __asmeq("%4", R4_STR)
+ __asmeq("%5", R5_STR)
+ __asmeq("%6", R6_STR)
+ __asmeq("%7", R0_STR)
+ __asmeq("%8", R1_STR)
+ __asmeq("%9", R2_STR)
+ __asmeq("%10", R3_STR)
+ __asmeq("%11", R4_STR)
+ __asmeq("%12", R5_STR)
+ __asmeq("%13", R6_STR)
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0\n"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+ : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3),
+ "=r" (r4), "=r" (r5), "=r" (r6)
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
"r" (r5), "r" (r6)
: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
@@ -490,18 +498,22 @@
__asmeq("%1", R1_STR)
__asmeq("%2", R2_STR)
__asmeq("%3", R3_STR)
- __asmeq("%4", R0_STR)
- __asmeq("%5", R1_STR)
- __asmeq("%6", R2_STR)
- __asmeq("%7", R3_STR)
- __asmeq("%8", R4_STR)
- __asmeq("%9", R5_STR)
- __asmeq("%10", R6_STR)
+ __asmeq("%4", R4_STR)
+ __asmeq("%5", R5_STR)
+ __asmeq("%6", R6_STR)
+ __asmeq("%7", R0_STR)
+ __asmeq("%8", R1_STR)
+ __asmeq("%9", R2_STR)
+ __asmeq("%10", R3_STR)
+ __asmeq("%11", R4_STR)
+ __asmeq("%12", R5_STR)
+ __asmeq("%13", R6_STR)
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0\n"
- : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
+ : "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3),
+ "=r" (r4), "=r" (r5), "=r" (r6)
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
"r" (r5), "r" (r6));
@@ -731,10 +743,6 @@
x0 = fn_id | BIT(SMC_ATOMIC_SYSCALL) | scm_version_mask;
- pr_debug("scm_call: func id %#llx, args: %#x, %#llx, %#llx, %#llx, %#llx\n",
- x0, desc->arginfo, desc->args[0], desc->args[1],
- desc->args[2], desc->x5);
-
if (scm_version == SCM_ARMV8_64)
ret = __scm_call_armv8_64(x0, desc->arginfo, desc->args[0],
desc->args[1], desc->args[2],
@@ -746,9 +754,8 @@
desc->x5, &desc->ret[0],
&desc->ret[1], &desc->ret[2]);
if (ret < 0)
- pr_err("scm_call failed: func id %#llx, arginfo: %#x, args: %#llx, %#llx, %#llx, %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n",
- x0, desc->arginfo, desc->args[0], desc->args[1],
- desc->args[2], desc->x5, ret, desc->ret[0],
+ pr_err("scm_call failed: func id %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n",
+ x0, ret, desc->ret[0],
desc->ret[1], desc->ret[2]);
if (arglen > N_REGISTER_ARGS)
diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c
index 1c7c4a1..806b756 100644
--- a/drivers/soc/qcom/spcom.c
+++ b/drivers/soc/qcom/spcom.c
@@ -93,8 +93,6 @@
/* SPCOM driver name */
#define DEVICE_NAME "spcom"
-#define SPCOM_MAX_CHANNELS 0x20
-
/* maximum ION buffers should be >= SPCOM_MAX_CHANNELS */
#define SPCOM_MAX_ION_BUF_PER_CH (SPCOM_MAX_CHANNELS + 4)
@@ -195,6 +193,7 @@
* glink state: CONNECTED / LOCAL_DISCONNECTED, REMOTE_DISCONNECTED
*/
unsigned int glink_state;
+ bool is_closing;
/* Events notification */
struct completion connect;
@@ -244,7 +243,7 @@
int channel_count;
/* private */
- struct mutex lock;
+ struct mutex cmd_lock;
/* Link state */
struct completion link_state_changed;
@@ -483,7 +482,17 @@
switch (event) {
case GLINK_CONNECTED:
pr_debug("GLINK_CONNECTED, ch name [%s].\n", ch->name);
+ mutex_lock(&ch->lock);
+
+ if (ch->is_closing) {
+ pr_err("Unexpected CONNECTED while closing [%s].\n",
+ ch->name);
+ mutex_unlock(&ch->lock);
+ return;
+ }
+
ch->glink_state = event;
+
/*
* if spcom_notify_state() is called within glink_open()
* then ch->glink_handle is not updated yet.
@@ -493,17 +502,28 @@
ch->glink_handle = handle;
}
- /* prepare default rx buffer after connected */
+ /* signal before unlock mutex & before calling glink */
+ complete_all(&ch->connect);
+
+ /*
+ * Prepare default rx buffer.
+ * glink_queue_rx_intent() can be called only AFTER connected.
+ * We do it here, ASAP, to allow rx data.
+ */
+
+ pr_debug("call glink_queue_rx_intent() ch [%s].\n", ch->name);
ret = glink_queue_rx_intent(ch->glink_handle,
ch, ch->rx_buf_size);
if (ret) {
pr_err("glink_queue_rx_intent() err [%d]\n", ret);
} else {
- pr_debug("rx buf is ready, size [%zu].\n",
+ pr_debug("rx buf is ready, size [%zu]\n",
ch->rx_buf_size);
ch->rx_buf_ready = true;
}
- complete_all(&ch->connect);
+
+ pr_debug("GLINK_CONNECTED, ch name [%s] done.\n", ch->name);
+ mutex_unlock(&ch->lock);
break;
case GLINK_LOCAL_DISCONNECTED:
/*
@@ -556,9 +576,7 @@
static bool spcom_notify_rx_intent_req(void *handle, const void *priv,
size_t req_size)
{
- struct spcom_channel *ch = (struct spcom_channel *) priv;
-
- pr_err("Unexpected intent request for ch [%s].\n", ch->name);
+ pr_err("Unexpected intent request\n");
return false;
}
@@ -670,6 +688,13 @@
ch->glink_state = GLINK_LOCAL_DISCONNECTED;
ch->actual_rx_size = 0;
ch->rx_buf_size = SPCOM_RX_BUF_SIZE;
+ ch->is_closing = false;
+ ch->glink_handle = NULL;
+ ch->ref_count = 0;
+ ch->rx_abort = false;
+ ch->tx_abort = false;
+ ch->txn_id = INITIAL_TXN_ID; /* use non-zero nonce for debug */
+ ch->pid = 0;
return 0;
}
@@ -739,6 +764,8 @@
/* init completion before calling glink_open() */
reinit_completion(&ch->connect);
+ ch->is_closing = false;
+
handle = glink_open(&cfg);
if (IS_ERR_OR_NULL(handle)) {
pr_err("glink_open failed.\n");
@@ -753,6 +780,8 @@
ch->pid = current_pid();
ch->txn_id = INITIAL_TXN_ID;
+ mutex_unlock(&ch->lock);
+
pr_debug("Wait for connection on channel [%s] timeout_msec [%d].\n",
name, timeout_msec);
@@ -769,8 +798,6 @@
pr_debug("Channel [%s] opened, no timeout.\n", name);
}
- mutex_unlock(&ch->lock);
-
return 0;
exit_err:
mutex_unlock(&ch->lock);
@@ -797,6 +824,8 @@
return 0;
}
+ ch->is_closing = true;
+
ret = glink_close(ch->glink_handle);
if (ret)
pr_err("glink_close() fail, ret [%d].\n", ret);
@@ -812,6 +841,7 @@
ch->pid = 0;
pr_debug("Channel closed [%s].\n", ch->name);
+
mutex_unlock(&ch->lock);
return 0;
@@ -1090,12 +1120,12 @@
if (!spcom_is_ready()) {
pr_err("spcom is not ready.\n");
- return NULL;
+ return NULL;
}
if (!info) {
pr_err("Invalid parameter.\n");
- return NULL;
+ return NULL;
}
name = info->ch_name;
@@ -1924,18 +1954,6 @@
}
/**
- * spcom_handle_fake_ssr_command() - Handle fake ssr command from user space.
- */
-static int spcom_handle_fake_ssr_command(struct spcom_channel *ch, int arg)
-{
- pr_debug("Start Fake glink SSR subsystem [%s].\n", spcom_edge);
- glink_ssr(spcom_edge);
- pr_debug("Fake glink SSR subsystem [%s] done.\n", spcom_edge);
-
- return 0;
-}
-
-/**
* spcom_handle_write() - Handle user space write commands.
*
* @buf: command buffer.
@@ -1964,6 +1982,8 @@
swap_id = htonl(cmd->cmd_id);
memcpy(cmd_name, &swap_id, sizeof(int));
+ mutex_lock(&spcom_dev->cmd_lock);
+
pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name);
switch (cmd_id) {
@@ -1979,17 +1999,16 @@
case SPCOM_CMD_UNLOCK_ION_BUF:
ret = spcom_handle_unlock_ion_buf_command(ch, buf, buf_size);
break;
- case SPCOM_CMD_FSSR:
- ret = spcom_handle_fake_ssr_command(ch, cmd->arg);
- break;
case SPCOM_CMD_CREATE_CHANNEL:
ret = spcom_handle_create_channel_command(buf, buf_size);
break;
default:
pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id);
- return -EINVAL;
+ ret = -EINVAL;
}
+ mutex_unlock(&spcom_dev->cmd_lock);
+
return ret;
}
@@ -2690,7 +2709,7 @@
return -ENOMEM;
spcom_dev = dev;
- mutex_init(&dev->lock);
+ mutex_init(&spcom_dev->cmd_lock);
init_completion(&dev->link_state_changed);
spcom_dev->link_state = GLINK_LINK_STATE_DOWN;
@@ -2763,7 +2782,7 @@
{
int ret;
- pr_info("spcom driver Ver 1.0 23-Nov-2015.\n");
+ pr_info("spcom driver version 1.1 17-July-2017.\n");
ret = platform_driver_register(&spcom_driver);
if (ret)
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index f8f6829..01eb260 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -795,6 +795,33 @@
return rc;
}
+static int pil_deinit_image_trusted(struct pil_desc *pil)
+{
+ struct pil_tz_data *d = desc_to_data(pil);
+ u32 proc, scm_ret = 0;
+ int rc;
+ struct scm_desc desc = {0};
+
+ if (d->subsys_desc.no_auth)
+ return 0;
+
+ desc.args[0] = proc = d->pas_id;
+ desc.arginfo = SCM_ARGS(1);
+
+ if (!is_scm_armv8()) {
+ rc = scm_call(SCM_SVC_PIL, PAS_SHUTDOWN_CMD, &proc,
+ sizeof(proc), &scm_ret, sizeof(scm_ret));
+ } else {
+ rc = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL, PAS_SHUTDOWN_CMD),
+ &desc);
+ scm_ret = desc.ret[0];
+ }
+
+ if (rc)
+ return rc;
+ return scm_ret;
+}
+
static struct pil_reset_ops pil_ops_trusted = {
.init_image = pil_init_image_trusted,
.mem_setup = pil_mem_setup_trusted,
@@ -802,6 +829,7 @@
.shutdown = pil_shutdown_trusted,
.proxy_vote = pil_make_proxy_vote,
.proxy_unvote = pil_remove_proxy_vote,
+ .deinit_image = pil_deinit_image_trusted,
};
static void log_failure_reason(const struct pil_tz_data *d)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index ad3eb187..37766d29 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -23,7 +23,6 @@
#define SPI_NUM_CHIPSELECT (4)
#define SPI_XFER_TIMEOUT_MS (250)
-#define SPI_OVERSAMPLING (2)
/* SPI SE specific registers */
#define SE_SPI_CPHA (0x224)
#define SE_SPI_LOOPBACK (0x22C)
@@ -100,6 +99,7 @@
struct spi_transfer *cur_xfer;
struct completion xfer_done;
struct device *wrapper_dev;
+ int oversampling;
};
static struct spi_master *get_spi_master(struct device *dev)
@@ -123,7 +123,8 @@
clk_sel &= ~CLK_SEL_MSK;
m_clk_cfg &= ~CLK_DIV_MSK;
- ret = geni_se_clk_freq_match(&mas->spi_rsc, speed_hz, &idx,
+ ret = geni_se_clk_freq_match(&mas->spi_rsc,
+ (speed_hz * mas->oversampling), &idx,
&sclk_freq, true);
if (ret) {
dev_err(mas->dev, "%s: Failed(%d) to find src clk for 0x%x\n",
@@ -131,17 +132,23 @@
return ret;
}
- div = ((sclk_freq / SPI_OVERSAMPLING) / speed_hz);
- if (!div)
+ div = ((sclk_freq / mas->oversampling) / speed_hz);
+ if (!div) {
+ dev_err(mas->dev, "%s:Err:sclk:%lu oversampling:%d speed:%u\n",
+ __func__, sclk_freq, mas->oversampling, speed_hz);
return -EINVAL;
+ }
dev_dbg(mas->dev, "%s: req %u sclk %lu, idx %d, div %d\n", __func__,
speed_hz, sclk_freq, idx, div);
clk_sel |= (idx & CLK_SEL_MSK);
m_clk_cfg |= ((div << CLK_DIV_SHFT) | SER_CLK_EN);
ret = clk_set_rate(rsc->se_clk, sclk_freq);
- if (ret)
+ if (ret) {
+ dev_err(mas->dev, "%s: clk_set_rate failed %d\n",
+ __func__, ret);
return ret;
+ }
geni_write_reg(clk_sel, mas->base, SE_GENI_CLK_SEL);
geni_write_reg(m_clk_cfg, mas->base, GENI_SER_M_CLK_CFG);
@@ -238,6 +245,10 @@
if (unlikely(!mas->setup)) {
int proto = get_se_proto(mas->base);
+ unsigned int major;
+ unsigned int minor;
+ unsigned int step;
+ int hw_ver;
if (unlikely(proto != SPI)) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
@@ -248,12 +259,24 @@
mas->tx_fifo_depth = get_tx_fifo_depth(mas->base);
mas->rx_fifo_depth = get_rx_fifo_depth(mas->base);
mas->tx_fifo_width = get_tx_fifo_width(mas->base);
+ mas->oversampling = 1;
/* Transmit an entire FIFO worth of data per IRQ */
mas->tx_wm = 1;
dev_dbg(mas->dev, "tx_fifo %d rx_fifo %d tx_width %d\n",
mas->tx_fifo_depth, mas->rx_fifo_depth,
mas->tx_fifo_width);
mas->setup = true;
+ hw_ver = geni_se_qupv3_hw_version(mas->wrapper_dev, &major,
+ &minor, &step);
+ if (hw_ver)
+ dev_err(mas->dev, "%s:Err getting HW version %d\n",
+ __func__, hw_ver);
+ else {
+ dev_dbg(mas->dev, "%s:Major:%d Minor:%d step:%d\n",
+ __func__, major, minor, step);
+ if ((major == 1) && (minor == 0))
+ mas->oversampling = 2;
+ }
}
exit_prepare_transfer_hardware:
return ret;
diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger.c b/drivers/staging/android/fiq_debugger/fiq_debugger.c
index 675b974..ce9dc7e 100644
--- a/drivers/staging/android/fiq_debugger/fiq_debugger.c
+++ b/drivers/staging/android/fiq_debugger/fiq_debugger.c
@@ -30,6 +30,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp.h>
+#include <linux/sysrq.h>
#include <linux/timer.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -400,7 +401,7 @@
cmd += 6;
while (*cmd == ' ')
cmd++;
- if (cmd != '\0')
+ if ((cmd != '\0') && sysrq_on())
kernel_restart(cmd);
else
kernel_restart(NULL);
@@ -430,29 +431,39 @@
static void fiq_debugger_help(struct fiq_debugger_state *state)
{
fiq_debugger_printf(&state->output,
- "FIQ Debugger commands:\n"
- " pc PC status\n"
- " regs Register dump\n"
- " allregs Extended Register dump\n"
- " bt Stack trace\n"
- " reboot [<c>] Reboot with command <c>\n"
- " reset [<c>] Hard reset with command <c>\n"
- " irqs Interupt status\n"
- " kmsg Kernel log\n"
- " version Kernel version\n");
+ "FIQ Debugger commands:\n");
+ if (sysrq_on()) {
+ fiq_debugger_printf(&state->output,
+ " pc PC status\n"
+ " regs Register dump\n"
+ " allregs Extended Register dump\n"
+ " bt Stack trace\n");
+ fiq_debugger_printf(&state->output,
+ " reboot [<c>] Reboot with command <c>\n"
+ " reset [<c>] Hard reset with command <c>\n"
+ " irqs Interrupt status\n"
+ " kmsg Kernel log\n"
+ " version Kernel version\n");
+ fiq_debugger_printf(&state->output,
+ " cpu Current CPU\n"
+ " cpu <number> Switch to CPU<number>\n"
+ " sysrq sysrq options\n"
+ " sysrq <param> Execute sysrq with <param>\n");
+ } else {
+ fiq_debugger_printf(&state->output,
+ " reboot Reboot\n"
+ " reset Hard reset\n"
+ " irqs Interrupt status\n");
+ }
fiq_debugger_printf(&state->output,
- " sleep Allow sleep while in FIQ\n"
- " nosleep Disable sleep while in FIQ\n"
- " console Switch terminal to console\n"
- " cpu Current CPU\n"
- " cpu <number> Switch to CPU<number>\n");
- fiq_debugger_printf(&state->output,
- " ps Process list\n"
- " sysrq sysrq options\n"
- " sysrq <param> Execute sysrq with <param>\n");
+ " sleep Allow sleep while in FIQ\n"
+ " nosleep Disable sleep while in FIQ\n"
+ " console Switch terminal to console\n"
+ " ps Process list\n");
#ifdef CONFIG_KGDB
- fiq_debugger_printf(&state->output,
- " kgdb Enter kernel debugger\n");
+ if (fiq_kgdb_enable) {
+ fiq_debugger_printf(&state->output,
+ " kgdb Enter kernel debugger\n");
#endif
}
@@ -484,18 +495,23 @@
if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) {
fiq_debugger_help(state);
} else if (!strcmp(cmd, "pc")) {
- fiq_debugger_dump_pc(&state->output, regs);
+ if (sysrq_on())
+ fiq_debugger_dump_pc(&state->output, regs);
} else if (!strcmp(cmd, "regs")) {
- fiq_debugger_dump_regs(&state->output, regs);
+ if (sysrq_on())
+ fiq_debugger_dump_regs(&state->output, regs);
} else if (!strcmp(cmd, "allregs")) {
- fiq_debugger_dump_allregs(&state->output, regs);
+ if (sysrq_on())
+ fiq_debugger_dump_allregs(&state->output, regs);
} else if (!strcmp(cmd, "bt")) {
- fiq_debugger_dump_stacktrace(&state->output, regs, 100, svc_sp);
+ if (sysrq_on())
+ fiq_debugger_dump_stacktrace(&state->output, regs,
+ 100, svc_sp);
} else if (!strncmp(cmd, "reset", 5)) {
cmd += 5;
while (*cmd == ' ')
cmd++;
- if (*cmd) {
+ if (*cmd && sysrq_on()) {
char tmp_cmd[32];
strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd));
machine_restart(tmp_cmd);
@@ -505,9 +521,12 @@
} else if (!strcmp(cmd, "irqs")) {
fiq_debugger_dump_irqs(state);
} else if (!strcmp(cmd, "kmsg")) {
- fiq_debugger_dump_kernel_log(state);
+ if (sysrq_on())
+ fiq_debugger_dump_kernel_log(state);
} else if (!strcmp(cmd, "version")) {
- fiq_debugger_printf(&state->output, "%s\n", linux_banner);
+ if (sysrq_on())
+ fiq_debugger_printf(&state->output, "%s\n",
+ linux_banner);
} else if (!strcmp(cmd, "sleep")) {
state->no_sleep = false;
fiq_debugger_printf(&state->output, "enabling sleep\n");
@@ -519,14 +538,17 @@
fiq_debugger_uart_flush(state);
state->console_enable = true;
} else if (!strcmp(cmd, "cpu")) {
- fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
- } else if (!strncmp(cmd, "cpu ", 4)) {
+ if (sysrq_on())
+ fiq_debugger_printf(&state->output, "cpu %d\n",
+ state->current_cpu);
+ } else if (!strncmp(cmd, "cpu ", 4) && sysrq_on()) {
unsigned long cpu = 0;
if (kstrtoul(cmd + 4, 10, &cpu) == 0)
fiq_debugger_switch_cpu(state, cpu);
else
fiq_debugger_printf(&state->output, "invalid cpu\n");
- fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
+ fiq_debugger_printf(&state->output, "cpu %d\n",
+ state->current_cpu);
} else {
if (state->debug_busy) {
fiq_debugger_printf(&state->output,
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 4082a7d..168383ec 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -16,6 +16,7 @@
*
*/
+#include <linux/atomic.h>
#include <linux/err.h>
#include <linux/file.h>
#include <linux/freezer.h>
@@ -264,7 +265,7 @@
mutex_lock(&dev->buffer_lock);
ion_buffer_add(dev, buffer);
mutex_unlock(&dev->buffer_lock);
- atomic_add(len, &heap->total_allocated);
+ atomic_long_add(len, &heap->total_allocated);
return buffer;
err:
@@ -282,7 +283,7 @@
buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
buffer->heap->ops->unmap_dma(buffer->heap, buffer);
- atomic_sub(buffer->size, &buffer->heap->total_allocated);
+ atomic_long_sub(buffer->size, &buffer->heap->total_allocated);
buffer->heap->ops->free(buffer);
vfree(buffer->pages);
kfree(buffer);
@@ -320,7 +321,7 @@
{
mutex_lock(&buffer->lock);
if (buffer->handle_count == 0)
- atomic_add(buffer->size, &buffer->heap->total_handles);
+ atomic_long_add(buffer->size, &buffer->heap->total_handles);
buffer->handle_count++;
mutex_unlock(&buffer->lock);
@@ -346,7 +347,7 @@
task = current->group_leader;
get_task_comm(buffer->task_comm, task);
buffer->pid = task_pid_nr(task);
- atomic_sub(buffer->size, &buffer->heap->total_handles);
+ atomic_long_sub(buffer->size, &buffer->heap->total_handles);
}
mutex_unlock(&buffer->lock);
}
@@ -402,6 +403,15 @@
kref_get(&handle->ref);
}
+/* Must hold the client lock */
+static struct ion_handle* ion_handle_get_check_overflow(struct ion_handle *handle)
+{
+ if (atomic_read(&handle->ref.refcount) + 1 == 0)
+ return ERR_PTR(-EOVERFLOW);
+ ion_handle_get(handle);
+ return handle;
+}
+
static int ion_handle_put_nolock(struct ion_handle *handle)
{
int ret;
@@ -448,9 +458,9 @@
handle = idr_find(&client->idr, id);
if (handle)
- ion_handle_get(handle);
+ return ion_handle_get_check_overflow(handle);
- return handle ? handle : ERR_PTR(-EINVAL);
+ return ERR_PTR(-EINVAL);
}
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
@@ -1394,7 +1404,7 @@
/* if a handle exists for this buffer just take a reference to it */
handle = ion_handle_lookup(client, buffer);
if (!IS_ERR(handle)) {
- ion_handle_get(handle);
+ handle = ion_handle_get_check_overflow(handle);
mutex_unlock(&client->lock);
goto end;
}
@@ -1838,10 +1848,10 @@
"Total orphaned size");
pr_info("---------------------------------\n");
plist_for_each_entry(heap, &dev->heaps, node) {
- pr_info("%16.s 0x%16.x 0x%16.x\n",
- heap->name, atomic_read(&heap->total_allocated),
- atomic_read(&heap->total_allocated) -
- atomic_read(&heap->total_handles));
+ pr_info("%16.s 0x%16.lx 0x%16.lx\n",
+ heap->name, atomic_long_read(&heap->total_allocated),
+ atomic_long_read(&heap->total_allocated) -
+ atomic_long_read(&heap->total_handles));
if (heap->debug_show)
heap->debug_show(heap, NULL, 0);
}
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index fbf7542..b264ec2 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -276,7 +276,7 @@
}
for_each_sg(sgt->sgl, sg, sgt->nents, i)
- ClearPagePrivate(sg_page(sgt->sgl));
+ ClearPagePrivate(sg_page(sg));
ion_cma_free(buffer);
out_free_source:
@@ -345,7 +345,7 @@
/* Set the private bit to indicate that we've secured this */
for_each_sg(sgt->sgl, sg, sgt->nents, i)
- SetPagePrivate(sg_page(sgt->sgl));
+ SetPagePrivate(sg_page(sg));
kfree(dest_vm_list);
kfree(dest_perms);
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index aa2d2d7..bb119cc 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -216,8 +216,8 @@
struct task_struct *task;
int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *);
- atomic_t total_allocated;
- atomic_t total_handles;
+ atomic_long_t total_allocated;
+ atomic_long_t total_handles;
};
/**
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index a9731d6..616375a 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -51,6 +51,7 @@
#define CREATE_TRACE_POINTS
#include <trace/events/almk.h>
+#include <linux/show_mem_notifier.h>
#ifdef CONFIG_HIGHMEM
#define _ZONE ZONE_HIGHMEM
@@ -552,6 +553,7 @@
if (lowmem_debug_level >= 2 && selected_oom_score_adj == 0) {
show_mem(SHOW_MEM_FILTER_NODES);
+ show_mem_call_notifiers();
dump_tasks(NULL, NULL);
}
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
index becb4bb..01438fa 100644
--- a/drivers/staging/rts5208/rtsx_scsi.c
+++ b/drivers/staging/rts5208/rtsx_scsi.c
@@ -536,7 +536,7 @@
if (sendbytes > 8) {
memcpy(buf, inquiry_buf, 8);
- memcpy(buf + 8, inquiry_string, sendbytes - 8);
+ strncpy(buf + 8, inquiry_string, sendbytes - 8);
if (pro_formatter_flag) {
/* Additional Length */
buf[4] = 0x33;
diff --git a/drivers/thermal/qcom/msm_lmh_dcvs.c b/drivers/thermal/qcom/msm_lmh_dcvs.c
index 4284b6c..d590d24 100644
--- a/drivers/thermal/qcom/msm_lmh_dcvs.c
+++ b/drivers/thermal/qcom/msm_lmh_dcvs.c
@@ -26,6 +26,7 @@
#include <linux/pm_opp.h>
#include <linux/cpu_cooling.h>
#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
@@ -102,10 +103,12 @@
unsigned long max_freq;
unsigned long min_freq;
unsigned long hw_freq_limit;
+ struct device_attribute lmh_freq_attr;
struct list_head list;
atomic_t is_irq_enabled;
struct mutex access_lock;
struct __limits_cdev_data *cdev_data;
+ struct regulator *isens_reg;
};
LIST_HEAD(lmh_dcvs_hw_list);
@@ -430,6 +433,60 @@
return 0;
}
+static void limits_isens_vref_ldo_init(struct platform_device *pdev,
+ struct limits_dcvs_hw *hw)
+{
+ int ret = 0;
+ uint32_t settings[3];
+
+ hw->isens_reg = devm_regulator_get(&pdev->dev, "isens_vref");
+ if (IS_ERR_OR_NULL(hw->isens_reg)) {
+ if (PTR_ERR(hw->isens_reg) == -ENODEV)
+ return;
+
+ pr_err("Regulator:isens_vref init error:%ld\n",
+ PTR_ERR(hw->isens_reg));
+ return;
+ }
+ ret = of_property_read_u32_array(pdev->dev.of_node,
+ "isens-vref-settings",
+ settings, 3);
+ if (ret) {
+ pr_err("Regulator:isens_vref settings read error:%d\n",
+ ret);
+ devm_regulator_put(hw->isens_reg);
+ return;
+ }
+ ret = regulator_set_voltage(hw->isens_reg, settings[0], settings[1]);
+ if (ret) {
+ pr_err("Regulator:isens_vref set voltage error:%d\n", ret);
+ devm_regulator_put(hw->isens_reg);
+ return;
+ }
+ ret = regulator_set_load(hw->isens_reg, settings[2]);
+ if (ret) {
+ pr_err("Regulator:isens_vref set load error:%d\n", ret);
+ devm_regulator_put(hw->isens_reg);
+ return;
+ }
+ if (regulator_enable(hw->isens_reg)) {
+ pr_err("Failed to enable regulator:isens_vref\n");
+ devm_regulator_put(hw->isens_reg);
+ return;
+ }
+}
+
+static ssize_t
+lmh_freq_limit_show(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct limits_dcvs_hw *hw = container_of(devattr,
+ struct limits_dcvs_hw,
+ lmh_freq_attr);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", hw->hw_freq_limit);
+}
+
static int limits_dcvs_probe(struct platform_device *pdev)
{
int ret;
@@ -585,6 +642,11 @@
ret = 0;
goto probe_exit;
}
+ limits_isens_vref_ldo_init(pdev, hw);
+ hw->lmh_freq_attr.attr.name = "lmh_freq_limit";
+ hw->lmh_freq_attr.show = lmh_freq_limit_show;
+ hw->lmh_freq_attr.attr.mode = 0444;
+ device_create_file(&pdev->dev, &hw->lmh_freq_attr);
probe_exit:
mutex_lock(&lmh_dcvs_list_access);
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 95ef027..2bfe1b5 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -477,6 +477,7 @@
* So, start monitoring again.
*/
monitor_thermal_zone(tz);
+ trace_thermal_handle_trip(tz, trip);
}
/**
@@ -567,6 +568,7 @@
ret = tz->ops->set_trips(tz, low, high);
if (ret)
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
+ trace_thermal_set_trip(tz);
exit:
mutex_unlock(&tz->lock);
@@ -621,6 +623,7 @@
if (!tz->ops->get_temp)
return;
+ trace_thermal_device_update(tz, event);
update_temperature(tz);
thermal_zone_set_trips(tz);
@@ -1934,6 +1937,7 @@
current_target = instance->target;
}
}
+ trace_cdev_update_start(cdev);
cdev->ops->set_cur_state(cdev, current_target);
if (cdev->ops->set_min_state)
cdev->ops->set_min_state(cdev, min_target);
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 17cdac4..11b4958 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -26,6 +26,7 @@
#include <linux/qcom-geni-se.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
+#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -107,9 +108,12 @@
#define UART_CORE2X_VOTE (10000)
#define WAKEBYTE_TIMEOUT_MSEC (2000)
-#define IPC_LOG_PWR_PAGES (2)
-#define IPC_LOG_MISC_PAGES (2)
-#define IPC_LOG_TX_RX_PAGES (3)
+#define WAIT_XFER_MAX_ITER (50)
+#define WAIT_XFER_MAX_TIMEOUT_US (10000)
+#define WAIT_XFER_MIN_TIMEOUT_US (9000)
+#define IPC_LOG_PWR_PAGES (6)
+#define IPC_LOG_MISC_PAGES (6)
+#define IPC_LOG_TX_RX_PAGES (8)
#define DATA_BYTES_PER_LINE (32)
#define IPC_LOG_MSG(ctx, x...) do { \
@@ -117,6 +121,7 @@
ipc_log_string(ctx, x); \
} while (0)
+#define DMA_RX_BUF_SIZE (512)
struct msm_geni_serial_port {
struct uart_port uport;
char name[20];
@@ -136,6 +141,10 @@
unsigned int rx_last);
struct device *wrapper_dev;
struct se_geni_rsc serial_rsc;
+ dma_addr_t tx_dma;
+ unsigned int xmit_size;
+ void *rx_buf;
+ dma_addr_t rx_dma;
int loopback;
int wakeup_irq;
unsigned char wakeup_byte;
@@ -146,6 +155,7 @@
void *ipc_log_misc;
unsigned int cur_baud;
int ioctl_count;
+ int edge_count;
};
static const struct uart_ops msm_geni_serial_pops;
@@ -221,27 +231,66 @@
(unsigned int)addr, size, buf);
}
-static bool check_tx_active(struct uart_port *uport)
+static bool check_transfers_inflight(struct uart_port *uport)
{
- /*
- * Poll if the GENI STATUS bit for TX is cleared. If the bit is
- * clear (poll condition met), return false, meaning tx isn't active
- * else return true. So return not of the poll return.
- */
- return !msm_geni_serial_poll_bit(uport, SE_GENI_STATUS,
- M_GENI_CMD_ACTIVE, false);
+ bool xfer_on = false;
+ bool tx_active = false;
+ bool tx_empty = false;
+ bool m_cmd_active = false;
+ bool rx_active = false;
+ u32 rx_fifo_status = 0;
+ u32 geni_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_STATUS);
+ /* Possible stop tx is called multiple times. */
+ m_cmd_active = geni_status & M_GENI_CMD_ACTIVE;
+ tx_empty = msm_geni_serial_tx_empty(uport);
+ tx_active = m_cmd_active || !tx_empty;
+ rx_fifo_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_RX_FIFO_STATUS);
+ if (rx_fifo_status)
+ rx_active = true;
+
+ if (rx_active || tx_active)
+ xfer_on = true;
+
+ return xfer_on;
+}
+
+static void wait_for_transfers_inflight(struct uart_port *uport)
+{
+ int iter = 0;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
+
+ while (iter < WAIT_XFER_MAX_ITER) {
+ if (check_transfers_inflight(uport)) {
+ usleep_range(WAIT_XFER_MIN_TIMEOUT_US,
+ WAIT_XFER_MAX_TIMEOUT_US);
+ iter++;
+ } else {
+ break;
+ }
+ }
+ if (check_transfers_inflight(uport)) {
+ u32 geni_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_STATUS);
+ u32 geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
+ u32 rx_fifo_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_RX_FIFO_STATUS);
+
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s IOS 0x%x geni status 0x%x rx fifo 0x%x\n",
+ __func__, geni_ios, geni_status, rx_fifo_status);
+ }
}
static int vote_clock_on(struct uart_port *uport)
{
- int ret = 0;
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- int usage_count = atomic_read(&uport->dev->power.usage_count);
+ int ret = 0;
if (!pm_runtime_enabled(uport->dev)) {
dev_err(uport->dev, "RPM not available.Can't enable clocks\n");
- ret = -EPERM;
- return ret;
+ return -EPERM;
}
ret = msm_geni_serial_power_on(uport);
if (ret) {
@@ -249,39 +298,31 @@
return ret;
}
port->ioctl_count++;
- __pm_relax(&port->geni_wake);
- IPC_LOG_MSG(port->ipc_log_pwr, "%s rpm %d ioctl %d\n",
- __func__, usage_count, port->ioctl_count);
+ IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d\n", __func__,
+ current->comm, port->ioctl_count);
return 0;
}
static int vote_clock_off(struct uart_port *uport)
{
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- int ret = 0;
- int usage_count = atomic_read(&uport->dev->power.usage_count);
if (!pm_runtime_enabled(uport->dev)) {
dev_err(uport->dev, "RPM not available.Can't enable clocks\n");
- ret = -EPERM;
- return ret;
+ return -EPERM;
}
- /* Check on going Tx. Don't block on this for now. */
- if (check_tx_active(uport))
- dev_warn(uport->dev, "%s: Vote off called during active Tx",
- __func__);
if (!port->ioctl_count) {
dev_warn(uport->dev, "%s:Imbalanced vote off ioctl %d\n",
- __func__, usage_count);
+ __func__, port->ioctl_count);
IPC_LOG_MSG(port->ipc_log_pwr,
- "%s:Imbalanced vote_off from userspace rpm%d",
- __func__, usage_count);
- return 0;
+ "%s:Imbalanced vote_off from userspace. %d",
+ __func__, port->ioctl_count);
+ return -EPERM;
}
port->ioctl_count--;
msm_geni_serial_power_off(uport);
- IPC_LOG_MSG(port->ipc_log_pwr, "%s rpm %d ioctl %d\n",
- __func__, usage_count, port->ioctl_count);
+ IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d\n", __func__,
+ current->comm, port->ioctl_count);
return 0;
};
@@ -311,14 +352,11 @@
static void msm_geni_serial_break_ctl(struct uart_port *uport, int ctl)
{
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
- dev_err(uport->dev, "%s Device suspended,vote clocks on.\n",
- __func__);
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
return;
- }
if (ctl) {
- check_tx_active(uport);
+ wait_for_transfers_inflight(uport);
geni_setup_m_cmd(uport->membase, UART_START_BREAK, 0);
} else {
geni_setup_m_cmd(uport->membase, UART_STOP_BREAK, 0);
@@ -357,11 +395,8 @@
{
u32 uart_manual_rfr = 0;
- if (pm_runtime_status_suspended(uport->dev)) {
- dev_info(uport->dev, "%sDevice suspended,vote clocks on\n",
- __func__);
+ if (pm_runtime_status_suspended(uport->dev))
return;
- }
if (!(mctrl & TIOCM_RTS))
uart_manual_rfr |= (UART_MANUAL_RFR_EN | UART_RFR_NOT_READY);
geni_write_reg_nolog(uart_manual_rfr, uport->membase,
@@ -396,9 +431,12 @@
static int msm_geni_serial_power_on(struct uart_port *uport)
{
int ret = 0;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
ret = pm_runtime_get_sync(uport->dev);
if (ret < 0) {
+ IPC_LOG_MSG(port->ipc_log_pwr, "%s Err\n", __func__);
+ WARN_ON_ONCE(1);
pm_runtime_put_noidle(uport->dev);
pm_runtime_set_suspended(uport->dev);
return ret;
@@ -685,32 +723,98 @@
#endif /* (CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)) */
+static int msm_geni_serial_prep_dma_tx(struct uart_port *uport)
+{
+ struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
+ struct circ_buf *xmit = &uport->state->xmit;
+ unsigned int xmit_size;
+ int ret = 0;
+
+ xmit_size = uart_circ_chars_pending(xmit);
+ if (xmit_size < WAKEUP_CHARS)
+ uart_write_wakeup(uport);
+
+ if (xmit_size > (UART_XMIT_SIZE - xmit->tail))
+ xmit_size = UART_XMIT_SIZE - xmit->tail;
+
+ if (!xmit_size)
+ return ret;
+
+ dump_ipc(msm_port->ipc_log_tx, "DMA Tx",
+ (char *)&xmit->buf[xmit->tail], 0, xmit_size);
+ msm_geni_serial_setup_tx(uport, xmit_size);
+ ret = geni_se_tx_dma_prep(msm_port->wrapper_dev, uport->membase,
+ &xmit->buf[xmit->tail], xmit_size, &msm_port->tx_dma);
+ if (!ret) {
+ msm_port->xmit_size = xmit_size;
+ } else {
+ geni_write_reg_nolog(0, uport->membase,
+ SE_UART_TX_TRANS_LEN);
+ geni_cancel_m_cmd(uport->membase);
+ if (!msm_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+ M_CMD_CANCEL_EN, true)) {
+ geni_abort_m_cmd(uport->membase);
+ msm_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+ M_CMD_ABORT_EN, true);
+ geni_write_reg_nolog(M_CMD_ABORT_EN, uport->membase,
+ SE_GENI_M_IRQ_CLEAR);
+ }
+ geni_write_reg_nolog(M_CMD_CANCEL_EN, uport->membase,
+ SE_GENI_M_IRQ_CLEAR);
+ IPC_LOG_MSG(msm_port->ipc_log_tx, "%s: DMA map failure %d\n",
+ __func__, ret);
+ msm_port->tx_dma = (dma_addr_t)NULL;
+ msm_port->xmit_size = 0;
+ }
+ return ret;
+}
+
static void msm_geni_serial_start_tx(struct uart_port *uport)
{
unsigned int geni_m_irq_en;
struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
unsigned int geni_status;
+ unsigned int geni_ios;
if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ IPC_LOG_MSG(msm_port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
}
- geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
- if (geni_status & M_GENI_CMD_ACTIVE)
- return;
+ if (msm_port->xfer_mode == FIFO_MODE) {
+ geni_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_STATUS);
+ if (geni_status & M_GENI_CMD_ACTIVE)
+ goto check_flow_ctrl;
- if (!msm_geni_serial_tx_empty(uport))
- return;
+ if (!msm_geni_serial_tx_empty(uport))
+ goto check_flow_ctrl;
- geni_m_irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
- geni_m_irq_en |= (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN);
+ geni_m_irq_en = geni_read_reg_nolog(uport->membase,
+ SE_GENI_M_IRQ_EN);
+ geni_m_irq_en |= (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN);
- geni_write_reg_nolog(msm_port->tx_wm, uport->membase,
+ geni_write_reg_nolog(msm_port->tx_wm, uport->membase,
SE_GENI_TX_WATERMARK_REG);
- geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
- /* Geni command setup/irq enables should complete before returning.*/
- mb();
+ geni_write_reg_nolog(geni_m_irq_en, uport->membase,
+ SE_GENI_M_IRQ_EN);
+ /* Geni command setup should complete before returning.*/
+ mb();
+ } else if (msm_port->xfer_mode == SE_DMA) {
+ if (msm_port->tx_dma)
+ goto check_flow_ctrl;
+
+ msm_geni_serial_prep_dma_tx(uport);
+ }
+ IPC_LOG_MSG(msm_port->ipc_log_misc, "%s\n", __func__);
+ return;
+check_flow_ctrl:
+ geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
+ if (!(geni_ios & IO2_DATA_IN))
+ IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: ios: 0x%08x\n",
+ __func__, geni_ios);
}
static void msm_geni_serial_stop_tx(struct uart_port *uport)
@@ -719,12 +823,30 @@
unsigned int geni_status;
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
+ }
geni_m_irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
- geni_m_irq_en &= ~(M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN);
- geni_write_reg_nolog(0, uport->membase, SE_GENI_TX_WATERMARK_REG);
+ geni_m_irq_en &= ~M_CMD_DONE_EN;
+ if (port->xfer_mode == FIFO_MODE) {
+ geni_m_irq_en &= ~M_TX_FIFO_WATERMARK_EN;
+ geni_write_reg_nolog(0, uport->membase,
+ SE_GENI_TX_WATERMARK_REG);
+ } else if (port->xfer_mode == SE_DMA) {
+ if (port->tx_dma) {
+ geni_write_reg_nolog(1, uport->membase,
+ SE_DMA_TX_FSM_RST);
+ geni_se_tx_dma_unprep(port->wrapper_dev, port->tx_dma,
+ port->xmit_size);
+ port->tx_dma = (dma_addr_t)NULL;
+ }
+ }
+ port->xmit_size = 0;
+
geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
geni_status = geni_read_reg_nolog(uport->membase,
@@ -754,26 +876,57 @@
unsigned int rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT;
unsigned int geni_status;
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
+ int ret;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
+ }
geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
if (geni_status & S_GENI_CMD_ACTIVE)
msm_geni_serial_abort_rx(uport);
- geni_s_irq_en = geni_read_reg_nolog(uport->membase,
- SE_GENI_S_IRQ_EN);
- geni_m_irq_en = geni_read_reg_nolog(uport->membase,
- SE_GENI_M_IRQ_EN);
- geni_s_irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
- geni_m_irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
+
se_get_packing_config(8, 4, false, &cfg0, &cfg1);
geni_write_reg_nolog(cfg0, uport->membase, SE_GENI_RX_PACKING_CFG0);
geni_write_reg_nolog(cfg1, uport->membase, SE_GENI_RX_PACKING_CFG1);
geni_write_reg_nolog(rxstale, uport->membase, SE_UART_RX_STALE_CNT);
geni_setup_s_cmd(uport->membase, UART_START_READ, 0);
- geni_write_reg_nolog(geni_s_irq_en, uport->membase, SE_GENI_S_IRQ_EN);
- geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
+
+ if (port->xfer_mode == FIFO_MODE) {
+ geni_s_irq_en = geni_read_reg_nolog(uport->membase,
+ SE_GENI_S_IRQ_EN);
+ geni_m_irq_en = geni_read_reg_nolog(uport->membase,
+ SE_GENI_M_IRQ_EN);
+
+ geni_s_irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
+ geni_m_irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
+
+ geni_write_reg_nolog(geni_s_irq_en, uport->membase,
+ SE_GENI_S_IRQ_EN);
+ geni_write_reg_nolog(geni_m_irq_en, uport->membase,
+ SE_GENI_M_IRQ_EN);
+ } else if (port->xfer_mode == SE_DMA) {
+ port->rx_buf = kzalloc(DMA_RX_BUF_SIZE, GFP_KERNEL);
+ if (!port->rx_buf) {
+ dev_err(uport->dev, "%s: kzalloc failed\n",
+ __func__);
+ msm_geni_serial_abort_rx(uport);
+ return;
+ }
+
+ ret = geni_se_rx_dma_prep(port->wrapper_dev, uport->membase,
+ port->rx_buf, DMA_RX_BUF_SIZE, &port->rx_dma);
+ if (ret) {
+ dev_err(uport->dev, "%s: RX Prep dma failed %d\n",
+ __func__, ret);
+ kfree(port->rx_buf);
+ msm_geni_serial_abort_rx(uport);
+ return;
+ }
+ }
/*
* Ensure the writes to the secondary sequencer and interrupt enables
* go through.
@@ -787,25 +940,42 @@
unsigned int geni_s_irq_en;
unsigned int geni_m_irq_en;
unsigned int geni_status;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
+ }
- geni_s_irq_en = geni_read_reg_nolog(uport->membase,
- SE_GENI_S_IRQ_EN);
- geni_m_irq_en = geni_read_reg_nolog(uport->membase,
- SE_GENI_M_IRQ_EN);
- geni_s_irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
- geni_m_irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+ if (port->xfer_mode == FIFO_MODE) {
+ geni_s_irq_en = geni_read_reg_nolog(uport->membase,
+ SE_GENI_S_IRQ_EN);
+ geni_m_irq_en = geni_read_reg_nolog(uport->membase,
+ SE_GENI_M_IRQ_EN);
+ geni_s_irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+ geni_m_irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
- geni_write_reg_nolog(geni_s_irq_en, uport->membase, SE_GENI_S_IRQ_EN);
- geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
+ geni_write_reg_nolog(geni_s_irq_en, uport->membase,
+ SE_GENI_S_IRQ_EN);
+ geni_write_reg_nolog(geni_m_irq_en, uport->membase,
+ SE_GENI_M_IRQ_EN);
+ } else if (port->xfer_mode == SE_DMA && port->rx_dma) {
+ geni_write_reg_nolog(1, uport->membase, SE_DMA_RX_FSM_RST);
+ geni_se_rx_dma_unprep(port->wrapper_dev, port->rx_dma,
+ DMA_RX_BUF_SIZE);
+ kfree(port->rx_buf);
+ port->rx_buf = NULL;
+ port->rx_dma = (dma_addr_t)NULL;
+ }
geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
/* Possible stop rx is called multiple times. */
if (!(geni_status & S_GENI_CMD_ACTIVE))
return;
msm_geni_serial_abort_rx(uport);
+ IPC_LOG_MSG(port->ipc_log_misc, "%s\n", __func__);
}
static int handle_rx_hs(struct uart_port *uport,
@@ -878,6 +1048,8 @@
(uart_console(uport) ? 1 : (msm_port->tx_fifo_width >> 3));
unsigned int geni_m_irq_en;
+ xmit->tail = (xmit->tail + msm_port->xmit_size) & (UART_XMIT_SIZE - 1);
+ msm_port->xmit_size = 0;
tx_fifo_status = geni_read_reg_nolog(uport->membase,
SE_GENI_TX_FIFO_STATUS);
if (uart_circ_empty(xmit) && !tx_fifo_status) {
@@ -914,15 +1086,16 @@
while (i < xmit_size) {
unsigned int tx_bytes;
unsigned int buf = 0;
+ int temp_tail;
int c;
tx_bytes = ((bytes_remaining < fifo_width_bytes) ?
bytes_remaining : fifo_width_bytes);
+ temp_tail = (xmit->tail + i) & (UART_XMIT_SIZE - 1);
for (c = 0; c < tx_bytes ; c++)
- buf |= (xmit->buf[xmit->tail + c] << (c * 8));
+ buf |= (xmit->buf[temp_tail + c] << (c * 8));
geni_write_reg_nolog(buf, uport->membase, SE_GENI_TX_FIFOn);
- xmit->tail = (xmit->tail + tx_bytes) & (UART_XMIT_SIZE - 1);
i += tx_bytes;
uport->icount.tx += tx_bytes;
bytes_remaining -= tx_bytes;
@@ -930,48 +1103,137 @@
wmb();
}
msm_geni_serial_poll_cancel_tx(uport);
+ if (uart_console(uport))
+ xmit->tail = (xmit->tail + xmit_size) & (UART_XMIT_SIZE - 1);
+ else
+ msm_port->xmit_size = xmit_size;
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(uport);
exit_handle_tx:
return ret;
}
+static int msm_geni_serial_handle_dma_rx(struct uart_port *uport)
+{
+ struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
+ unsigned int rx_bytes = 0;
+ struct tty_port *tport;
+ int ret;
+ unsigned int geni_status;
+
+ geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
+ /* Possible stop rx is called */
+ if (!(geni_status & S_GENI_CMD_ACTIVE))
+ return 0;
+
+ geni_se_rx_dma_unprep(msm_port->wrapper_dev, msm_port->rx_dma,
+ DMA_RX_BUF_SIZE);
+ rx_bytes = geni_read_reg_nolog(uport->membase, SE_DMA_RX_LEN_IN);
+ if (unlikely(!msm_port->rx_buf || !rx_bytes)) {
+ IPC_LOG_MSG(msm_port->ipc_log_rx, "%s: Rx_buf %pK Size %d\n",
+ __func__, msm_port->rx_buf, rx_bytes);
+ return 0;
+ }
+
+ tport = &uport->state->port;
+ ret = tty_insert_flip_string(tport, (unsigned char *)(msm_port->rx_buf),
+ rx_bytes);
+ if (ret != rx_bytes) {
+ dev_err(uport->dev, "%s: ret %d rx_bytes %d\n", __func__,
+ ret, rx_bytes);
+ WARN_ON(1);
+ }
+ uport->icount.rx += ret;
+ tty_flip_buffer_push(tport);
+ dump_ipc(msm_port->ipc_log_rx, "DMA Rx", (char *)msm_port->rx_buf, 0,
+ rx_bytes);
+ ret = geni_se_rx_dma_prep(msm_port->wrapper_dev, uport->membase,
+ msm_port->rx_buf, DMA_RX_BUF_SIZE, &msm_port->rx_dma);
+ if (ret)
+ IPC_LOG_MSG(msm_port->ipc_log_rx, "%s: %d\n", __func__, ret);
+ return ret;
+}
+
+static int msm_geni_serial_handle_dma_tx(struct uart_port *uport)
+{
+ struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
+ struct circ_buf *xmit = &uport->state->xmit;
+
+ xmit->tail = (xmit->tail + msm_port->xmit_size) & (UART_XMIT_SIZE - 1);
+ geni_se_tx_dma_unprep(msm_port->wrapper_dev, msm_port->tx_dma,
+ msm_port->xmit_size);
+ uport->icount.tx += msm_port->xmit_size;
+ msm_port->tx_dma = (dma_addr_t)NULL;
+ msm_port->xmit_size = 0;
+
+ if (!uart_circ_empty(xmit))
+ msm_geni_serial_prep_dma_tx(uport);
+ else
+ uart_write_wakeup(uport);
+ return 0;
+}
+
static irqreturn_t msm_geni_serial_isr(int isr, void *dev)
{
unsigned int m_irq_status;
unsigned int s_irq_status;
+ unsigned int dma;
+ unsigned int dma_tx_status;
+ unsigned int dma_rx_status;
struct uart_port *uport = dev;
unsigned long flags;
unsigned int m_irq_en;
+ struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
spin_lock_irqsave(&uport->lock, flags);
if (uart_console(uport) && uport->suspended)
goto exit_geni_serial_isr;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ IPC_LOG_MSG(msm_port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
goto exit_geni_serial_isr;
+ }
m_irq_status = geni_read_reg_nolog(uport->membase,
SE_GENI_M_IRQ_STATUS);
s_irq_status = geni_read_reg_nolog(uport->membase,
SE_GENI_S_IRQ_STATUS);
- geni_write_reg_nolog(m_irq_status, uport->membase,
- SE_GENI_M_IRQ_CLEAR);
- geni_write_reg_nolog(s_irq_status, uport->membase,
- SE_GENI_S_IRQ_CLEAR);
m_irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
+ dma = geni_read_reg_nolog(uport->membase, SE_GENI_DMA_MODE_EN);
+ dma_tx_status = geni_read_reg_nolog(uport->membase, SE_DMA_TX_IRQ_STAT);
+ dma_rx_status = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_STAT);
+
+ geni_write_reg_nolog(m_irq_status, uport->membase, SE_GENI_M_IRQ_CLEAR);
+ geni_write_reg_nolog(s_irq_status, uport->membase, SE_GENI_S_IRQ_CLEAR);
if ((m_irq_status & M_ILLEGAL_CMD_EN)) {
WARN_ON(1);
goto exit_geni_serial_isr;
}
- if ((s_irq_status & S_RX_FIFO_WATERMARK_EN) ||
- (s_irq_status & S_RX_FIFO_LAST_EN)) {
- msm_geni_serial_handle_rx(uport);
- }
+ if (!dma) {
+ if ((s_irq_status & S_RX_FIFO_WATERMARK_EN) ||
+ (s_irq_status & S_RX_FIFO_LAST_EN))
+ msm_geni_serial_handle_rx(uport);
- if ((m_irq_status & m_irq_en) &
- (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
- msm_geni_serial_handle_tx(uport);
+ if ((m_irq_status & m_irq_en) &
+ (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
+ msm_geni_serial_handle_tx(uport);
+ } else {
+ if (dma_tx_status) {
+ geni_write_reg_nolog(dma_tx_status, uport->membase,
+ SE_DMA_TX_IRQ_CLR);
+ if (dma_tx_status & TX_DMA_DONE)
+ msm_geni_serial_handle_dma_tx(uport);
+ }
+
+ if (dma_rx_status) {
+ geni_write_reg_nolog(dma_rx_status, uport->membase,
+ SE_DMA_RX_IRQ_CLR);
+ if (dma_rx_status & RX_DMA_DONE)
+ msm_geni_serial_handle_dma_rx(uport);
+ }
+ }
exit_geni_serial_isr:
spin_unlock_irqrestore(&uport->lock, flags);
@@ -986,16 +1248,19 @@
unsigned long flags;
spin_lock_irqsave(&uport->lock, flags);
- if (port->wakeup_byte) {
+ IPC_LOG_MSG(port->ipc_log_rx, "%s: Edge-Count %d\n", __func__,
+ port->edge_count);
+ if (port->wakeup_byte && (port->edge_count == 2)) {
tty = uport->state->port.tty;
tty_insert_flip_char(tty->port, port->wakeup_byte, TTY_NORMAL);
IPC_LOG_MSG(port->ipc_log_rx, "%s: Inject 0x%x\n",
__func__, port->wakeup_byte);
+ port->edge_count = 0;
tty_flip_buffer_push(tty->port);
+ __pm_wakeup_event(&port->geni_wake, WAKEBYTE_TIMEOUT_MSEC);
+ } else if (port->edge_count < 2) {
+ port->edge_count++;
}
- __pm_wakeup_event(&port->geni_wake, WAKEBYTE_TIMEOUT_MSEC);
- IPC_LOG_MSG(port->ipc_log_misc, "%s:Holding Wake Lock for %d ms\n",
- __func__, WAKEBYTE_TIMEOUT_MSEC);
spin_unlock_irqrestore(&uport->lock, flags);
return IRQ_HANDLED;
}
@@ -1052,25 +1317,29 @@
unsigned long flags;
/* Stop the console before stopping the current tx */
- if (uart_console(uport))
+ if (uart_console(uport)) {
console_stop(uport->cons);
+ } else {
+ msm_geni_serial_power_on(uport);
+ wait_for_transfers_inflight(uport);
+ }
+ disable_irq(uport->irq);
+ free_irq(uport->irq, msm_port);
spin_lock_irqsave(&uport->lock, flags);
msm_geni_serial_stop_tx(uport);
msm_geni_serial_stop_rx(uport);
spin_unlock_irqrestore(&uport->lock, flags);
- disable_irq(uport->irq);
- free_irq(uport->irq, msm_port);
if (uart_console(uport)) {
se_geni_resources_off(&msm_port->serial_rsc);
} else {
+ msm_geni_serial_power_off(uport);
if (msm_port->wakeup_irq > 0) {
+ irq_set_irq_wake(msm_port->wakeup_irq, 0);
disable_irq(msm_port->wakeup_irq);
free_irq(msm_port->wakeup_irq, msm_port);
}
- __pm_relax(&msm_port->geni_wake);
- msm_geni_serial_power_off(uport);
}
IPC_LOG_MSG(msm_port->ipc_log_misc, "%s\n", __func__);
}
@@ -1085,7 +1354,7 @@
set_rfr_wm(msm_port);
if (!uart_console(uport)) {
/* For now only assume FIFO mode. */
- msm_port->xfer_mode = FIFO_MODE;
+ msm_port->xfer_mode = SE_DMA;
se_get_packing_config(8, 4, false, &cfg0, &cfg1);
geni_write_reg_nolog(cfg0, uport->membase,
SE_GENI_TX_PACKING_CFG0);
@@ -1183,8 +1452,11 @@
if (likely(!uart_console(uport))) {
ret = msm_geni_serial_power_on(&msm_port->uport);
- if (ret)
- goto exit_startup;
+ if (ret) {
+ dev_err(uport->dev, "%s:Failed to power on %d\n",
+ __func__, ret);
+ return ret;
+ }
}
if (unlikely(get_se_proto(uport->membase) != UART)) {
@@ -1217,8 +1489,7 @@
}
if (msm_port->wakeup_irq > 0) {
- ret = request_threaded_irq(msm_port->wakeup_irq, NULL,
- msm_geni_wakeup_isr,
+ ret = request_irq(msm_port->wakeup_irq, msm_geni_wakeup_isr,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"hs_uart_wakeup", uport);
if (unlikely(ret)) {
@@ -1227,9 +1498,17 @@
goto exit_startup;
}
disable_irq(msm_port->wakeup_irq);
+ ret = irq_set_irq_wake(msm_port->wakeup_irq, 1);
+ if (unlikely(ret)) {
+ dev_err(uport->dev, "%s:Failed to set IRQ wake:%d\n",
+ __func__, ret);
+ goto exit_startup;
+ }
}
IPC_LOG_MSG(msm_port->ipc_log_misc, "%s\n", __func__);
exit_startup:
+ if (likely(!uart_console(uport)))
+ msm_geni_serial_power_off(&msm_port->uport);
return ret;
}
@@ -1316,6 +1595,11 @@
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
unsigned long clk_rate;
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ IPC_LOG_MSG(port->ipc_log_pwr,
+ "%s Device suspended,vote clocks on.\n", __func__);
+ return;
+ }
/* baud rate */
baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
port->cur_baud = baud;
@@ -1412,15 +1696,81 @@
{
unsigned int tx_fifo_status;
unsigned int is_tx_empty = 1;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- tx_fifo_status = geni_read_reg_nolog(uport->membase,
- SE_GENI_TX_FIFO_STATUS);
+ if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ IPC_LOG_MSG(port->ipc_log_pwr,
+ "%s Device suspended,vote clocks on.\n", __func__);
+ return 1;
+ }
+
+ if (port->xfer_mode == SE_DMA)
+ tx_fifo_status = port->tx_dma ? 1 : 0;
+ else
+ tx_fifo_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_TX_FIFO_STATUS);
if (tx_fifo_status)
is_tx_empty = 0;
return is_tx_empty;
}
+static ssize_t msm_geni_serial_xfer_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
+ ssize_t ret = 0;
+
+ if (port->xfer_mode == FIFO_MODE)
+ ret = snprintf(buf, sizeof("FIFO\n"), "FIFO\n");
+ else if (port->xfer_mode == SE_DMA)
+ ret = snprintf(buf, sizeof("SE_DMA\n"), "SE_DMA\n");
+
+ return ret;
+}
+
+static ssize_t msm_geni_serial_xfer_mode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t size)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
+ struct uart_port *uport = &port->uport;
+ int xfer_mode = port->xfer_mode;
+ unsigned long flags;
+
+ if (uart_console(uport))
+ return -EOPNOTSUPP;
+
+ if (strnstr(buf, "FIFO", strlen("FIFO"))) {
+ xfer_mode = FIFO_MODE;
+ } else if (strnstr(buf, "SE_DMA", strlen("SE_DMA"))) {
+ xfer_mode = SE_DMA;
+ } else {
+ dev_err(dev, "%s: Invalid input %s\n", __func__, buf);
+ return -EINVAL;
+ }
+
+ if (xfer_mode == port->xfer_mode)
+ return size;
+
+ msm_geni_serial_power_on(uport);
+ spin_lock_irqsave(&uport->lock, flags);
+ msm_geni_serial_stop_tx(uport);
+ msm_geni_serial_stop_rx(uport);
+ port->xfer_mode = xfer_mode;
+ geni_se_select_mode(uport->membase, port->xfer_mode);
+ spin_unlock_irqrestore(&uport->lock, flags);
+ msm_geni_serial_start_rx(uport);
+ msm_geni_serial_power_off(uport);
+
+ return size;
+}
+
+static DEVICE_ATTR(xfer_mode, 0644, msm_geni_serial_xfer_mode_show,
+ msm_geni_serial_xfer_mode_store);
+
#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
static int __init msm_geni_console_setup(struct console *co, char *options)
{
@@ -1671,6 +2021,7 @@
bool is_console = false;
struct platform_device *wrapper_pdev;
struct device_node *wrapper_ph_node;
+ u32 wake_char = 0;
id = of_match_device(msm_geni_device_tbl, &pdev->dev);
if (id) {
@@ -1733,9 +2084,14 @@
if (ret)
goto exit_geni_serial_probe;
- if (of_property_read_u8(pdev->dev.of_node, "qcom,wakeup-byte",
- &dev_port->wakeup_byte))
- dev_info(&pdev->dev, "No Wakeup byte specified\n");
+ if (of_property_read_u32(pdev->dev.of_node, "qcom,wakeup-byte",
+ &wake_char)) {
+ dev_dbg(&pdev->dev, "No Wakeup byte specified\n");
+ } else {
+ dev_port->wakeup_byte = (u8)wake_char;
+ dev_info(&pdev->dev, "Wakeup byte 0x%x\n",
+ dev_port->wakeup_byte);
+ }
dev_port->serial_rsc.se_clk = devm_clk_get(&pdev->dev, "se-clk");
if (IS_ERR(dev_port->serial_rsc.se_clk)) {
@@ -1830,6 +2186,7 @@
dev_info(&pdev->dev, "Serial port%d added.FifoSize %d is_console%d\n",
line, uport->fifosize, is_console);
device_create_file(uport->dev, &dev_attr_loopback);
+ device_create_file(uport->dev, &dev_attr_xfer_mode);
msm_geni_serial_debug_init(uport);
dev_port->port_setup = false;
return uart_add_one_port(drv, uport);
@@ -1857,14 +2214,28 @@
struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
int ret = 0;
+ wait_for_transfers_inflight(&port->uport);
ret = se_geni_resources_off(&port->serial_rsc);
if (ret) {
dev_err(dev, "%s: Error ret %d\n", __func__, ret);
goto exit_runtime_suspend;
}
- if (port->wakeup_irq > 0)
+ disable_irq(port->uport.irq);
+ if (port->wakeup_irq > 0) {
+ struct se_geni_rsc *rsc = &port->serial_rsc;
+
+ port->edge_count = 0;
+ ret = pinctrl_select_state(rsc->geni_pinctrl,
+ rsc->geni_gpio_active);
+ if (ret) {
+ dev_err(dev, "%s: Error %d pinctrl_select_state\n",
+ __func__, ret);
+ goto exit_runtime_suspend;
+ }
enable_irq(port->wakeup_irq);
+ }
IPC_LOG_MSG(port->ipc_log_pwr, "%s:\n", __func__);
+ __pm_relax(&port->geni_wake);
exit_runtime_suspend:
return ret;
}
@@ -1875,13 +2246,21 @@
struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
int ret = 0;
+ /*
+ * Do an unconditional relax followed by a stay awake in case the
+ * wake source is activated by the wakeup isr.
+ */
+ __pm_relax(&port->geni_wake);
+ __pm_stay_awake(&port->geni_wake);
if (port->wakeup_irq > 0)
disable_irq(port->wakeup_irq);
ret = se_geni_resources_on(&port->serial_rsc);
if (ret) {
dev_err(dev, "%s: Error ret %d\n", __func__, ret);
+ __pm_relax(&port->geni_wake);
goto exit_runtime_resume;
}
+ enable_irq(port->uport.irq);
IPC_LOG_MSG(port->ipc_log_pwr, "%s:\n", __func__);
exit_runtime_resume:
return ret;
@@ -1897,10 +2276,20 @@
uart_suspend_port((struct uart_driver *)uport->private_data,
uport);
} else {
+ struct uart_state *state = uport->state;
+ struct tty_port *tty_port = &state->port;
+
+ mutex_lock(&tty_port->mutex);
if (!pm_runtime_status_suspended(dev)) {
- dev_info(dev, "%s: Is still active\n", __func__);
+ dev_err(dev, "%s:Active userspace vote; ioctl_cnt %d\n",
+ __func__, port->ioctl_count);
+ IPC_LOG_MSG(port->ipc_log_pwr,
+ "%s:Active userspace vote; ioctl_cnt %d\n",
+ __func__, port->ioctl_count);
+ mutex_unlock(&tty_port->mutex);
return -EBUSY;
}
+ mutex_unlock(&tty_port->mutex);
}
return 0;
}
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 701c085..94c3718 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -55,10 +55,11 @@
static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
static bool __read_mostly sysrq_always_enabled;
-static bool sysrq_on(void)
+bool sysrq_on(void)
{
return sysrq_enabled || sysrq_always_enabled;
}
+EXPORT_SYMBOL(sysrq_on);
/*
* A value of 1 means 'all', other nonzero values are an op mask:
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 0dc81d2..69d617f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -55,6 +55,8 @@
#include "debug.h"
#include "xhci.h"
+#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */
+
/* time out to wait for USB cable status notification (in ms)*/
#define SM_INIT_TIMEOUT 30000
@@ -262,6 +264,7 @@
int pm_qos_latency;
struct pm_qos_request pm_qos_req_dma;
struct delayed_work perf_vote_work;
+ struct delayed_work sdp_check;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@@ -2818,6 +2821,25 @@
return NOTIFY_DONE;
}
+
+static void check_for_sdp_connection(struct work_struct *w)
+{
+ struct dwc3_msm *mdwc =
+ container_of(w, struct dwc3_msm, sdp_check.work);
+ struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
+
+ if (!mdwc->vbus_active)
+ return;
+
+ /* floating D+/D- lines detected */
+ if (dwc->gadget.state < USB_STATE_DEFAULT &&
+ dwc3_gadget_get_link_state(dwc) != DWC3_LINK_STATE_CMPLY) {
+ mdwc->vbus_active = 0;
+ dbg_event(0xFF, "Q RW SPD CHK", mdwc->vbus_active);
+ queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
+ }
+}
+
static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
unsigned long event, void *ptr)
{
@@ -3104,6 +3126,7 @@
INIT_WORK(&mdwc->vbus_draw_work, dwc3_msm_vbus_draw_work);
INIT_DELAYED_WORK(&mdwc->sm_work, dwc3_otg_sm_work);
INIT_DELAYED_WORK(&mdwc->perf_vote_work, msm_dwc3_perf_vote_work);
+ INIT_DELAYED_WORK(&mdwc->sdp_check, check_for_sdp_connection);
mdwc->dwc3_wq = alloc_ordered_workqueue("dwc3_wq", 0);
if (!mdwc->dwc3_wq) {
@@ -3859,34 +3882,46 @@
return 0;
}
-static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA)
+static int get_psy_type(struct dwc3_msm *mdwc)
{
union power_supply_propval pval = {0};
- int ret;
if (mdwc->charging_disabled)
- return 0;
-
- if (mdwc->max_power == mA)
- return 0;
+ return -EINVAL;
if (!mdwc->usb_psy) {
mdwc->usb_psy = power_supply_get_by_name("usb");
if (!mdwc->usb_psy) {
- dev_warn(mdwc->dev, "Could not get usb power_supply\n");
+ dev_err(mdwc->dev, "Could not get usb psy\n");
return -ENODEV;
}
}
- power_supply_get_property(mdwc->usb_psy,
- POWER_SUPPLY_PROP_REAL_TYPE, &pval);
- if (pval.intval != POWER_SUPPLY_TYPE_USB)
+ power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE,
+ &pval);
+
+ return pval.intval;
+}
+
+static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA)
+{
+ union power_supply_propval pval = {0};
+ int ret, psy_type;
+
+ if (mdwc->max_power == mA)
return 0;
- dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);
+ psy_type = get_psy_type(mdwc);
+ if (psy_type == POWER_SUPPLY_TYPE_USB) {
+ dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);
+ /* Set max current limit in uA */
+ pval.intval = 1000 * mA;
+ } else if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
+ pval.intval = -ETIMEDOUT;
+ } else {
+ return 0;
+ }
- /* Set max current limit in uA */
- pval.intval = 1000 * mA;
ret = power_supply_set_property(mdwc->usb_psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
if (ret) {
@@ -3957,6 +3992,10 @@
work = 1;
} else if (test_bit(B_SESS_VLD, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "b_sess_vld\n");
+ if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_FLOAT)
+ queue_delayed_work(mdwc->dwc3_wq,
+ &mdwc->sdp_check,
+ msecs_to_jiffies(SDP_CONNETION_CHECK_TIME));
/*
* Increment pm usage count upon cable connect. Count
* is decremented in OTG_STATE_B_PERIPHERAL state on
@@ -3979,6 +4018,7 @@
!test_bit(ID, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "!id || !bsv\n");
mdwc->otg_state = OTG_STATE_B_IDLE;
+ cancel_delayed_work_sync(&mdwc->sdp_check);
dwc3_otg_start_peripheral(mdwc, 0);
/*
* Decrement pm usage count upon cable disconnect
@@ -4011,6 +4051,7 @@
if (!test_bit(B_SESS_VLD, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "BSUSP: !bsv\n");
mdwc->otg_state = OTG_STATE_B_IDLE;
+ cancel_delayed_work_sync(&mdwc->sdp_check);
dwc3_otg_start_peripheral(mdwc, 0);
} else if (!test_bit(B_SUSPEND, &mdwc->inputs)) {
dev_dbg(mdwc->dev, "BSUSP !susp\n");
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 5396557..f910990 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -138,21 +138,28 @@
struct list_head list;
};
+#define MAX_USB_STRING_LEN 126
+#define MAX_USB_STRING_WITH_NULL_LEN (MAX_USB_STRING_LEN+1)
+
static int usb_string_copy(const char *s, char **s_copy)
{
int ret;
char *str;
char *copy = *s_copy;
ret = strlen(s);
- if (ret > 126)
+ if (ret > MAX_USB_STRING_LEN)
return -EOVERFLOW;
- str = kstrdup(s, GFP_KERNEL);
- if (!str)
- return -ENOMEM;
+ if (copy) {
+ str = copy;
+ } else {
+ str = kmalloc(MAX_USB_STRING_WITH_NULL_LEN, GFP_KERNEL);
+ if (!str)
+ return -ENOMEM;
+ }
+ strncpy(str, s, MAX_USB_STRING_WITH_NULL_LEN);
if (str[ret - 1] == '\n')
str[ret - 1] = '\0';
- kfree(copy);
*s_copy = str;
return 0;
}
diff --git a/drivers/usb/gadget/function/f_ccid.c b/drivers/usb/gadget/function/f_ccid.c
index 1801a6c..7817f1c 100644
--- a/drivers/usb/gadget/function/f_ccid.c
+++ b/drivers/usb/gadget/function/f_ccid.c
@@ -26,7 +26,7 @@
#include "f_ccid.h"
#define BULK_IN_BUFFER_SIZE sizeof(struct ccid_bulk_in_header)
-#define BULK_OUT_BUFFER_SIZE sizeof(struct ccid_bulk_out_header)
+#define BULK_OUT_BUFFER_SIZE 1024
#define CTRL_BUF_SIZE 4
#define FUNCTION_NAME "ccid"
#define MAX_INST_NAME_LEN 40
@@ -629,14 +629,14 @@
struct f_ccid *ccid_dev = fp->private_data;
struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
struct usb_request *req;
- int r = count, xfer;
+ int r = count, xfer, len;
int ret;
unsigned long flags;
pr_debug("ccid_bulk_read(%zu)\n", count);
if (count > BULK_OUT_BUFFER_SIZE) {
- pr_err("%s: max_buffer_size:%zu given_pkt_size:%zu\n",
+ pr_err("%s: max_buffer_size:%d given_pkt_size:%zu\n",
__func__, BULK_OUT_BUFFER_SIZE, count);
return -ENOMEM;
}
@@ -647,6 +647,7 @@
goto done;
}
+ len = ALIGN(count, ccid_dev->out->maxpacket);
requeue_req:
spin_lock_irqsave(&ccid_dev->lock, flags);
if (!atomic_read(&ccid_dev->online)) {
@@ -655,7 +656,7 @@
}
/* queue a request */
req = bulk_dev->rx_req;
- req->length = count;
+ req->length = len;
bulk_dev->rx_done = 0;
spin_unlock_irqrestore(&ccid_dev->lock, flags);
ret = usb_ep_queue(ccid_dev->out, req, GFP_KERNEL);
@@ -688,6 +689,9 @@
spin_unlock_irqrestore(&ccid_dev->lock, flags);
goto requeue_req;
}
+ if (req->actual > count)
+ pr_err("%s More data received(%d) than required(%zu)\n",
+ __func__, req->actual, count);
xfer = (req->actual < count) ? req->actual : count;
atomic_set(&bulk_dev->rx_req_busy, 1);
spin_unlock_irqrestore(&ccid_dev->lock, flags);
@@ -875,7 +879,8 @@
count = CTRL_BUF_SIZE;
ret = wait_event_interruptible(ctrl_dev->tx_wait_q,
- ctrl_dev->tx_ctrl_done);
+ ctrl_dev->tx_ctrl_done ||
+ !atomic_read(&ccid_dev->online));
if (ret < 0)
return ret;
ctrl_dev->tx_ctrl_done = 0;
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index 102003d..ca8ed69 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -137,6 +137,7 @@
} perf[MAX_ITERATION];
unsigned int dbg_read_index;
unsigned int dbg_write_index;
+ struct mutex read_mutex;
};
static struct usb_interface_descriptor mtp_interface_desc = {
@@ -626,11 +627,18 @@
dev->state = STATE_BUSY;
spin_unlock_irq(&dev->lock);
+ mutex_lock(&dev->read_mutex);
+ if (dev->state == STATE_OFFLINE) {
+ r = -EIO;
+ mutex_unlock(&dev->read_mutex);
+ goto done;
+ }
requeue_req:
/* queue a request */
req = dev->rx_req[0];
req->length = len;
dev->rx_done = 0;
+ mutex_unlock(&dev->read_mutex);
ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
if (ret < 0) {
r = -EIO;
@@ -656,6 +664,7 @@
usb_ep_dequeue(dev->ep_out, req);
goto done;
}
+ mutex_lock(&dev->read_mutex);
if (dev->state == STATE_BUSY) {
/* If we got a 0-len packet, throw it back and try again. */
if (req->actual == 0)
@@ -669,6 +678,7 @@
} else
r = -EIO;
+ mutex_unlock(&dev->read_mutex);
done:
spin_lock_irq(&dev->lock);
if (dev->state == STATE_CANCELED)
@@ -920,6 +930,12 @@
while (count > 0 || write_req) {
if (count > 0) {
+ mutex_lock(&dev->read_mutex);
+ if (dev->state == STATE_OFFLINE) {
+ r = -EIO;
+ mutex_unlock(&dev->read_mutex);
+ break;
+ }
/* queue a request */
read_req = dev->rx_req[cur_buf];
cur_buf = (cur_buf + 1) % RX_REQ_MAX;
@@ -928,6 +944,7 @@
read_req->length = mtp_rx_req_len;
dev->rx_done = 0;
+ mutex_unlock(&dev->read_mutex);
ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
if (ret < 0) {
r = -EIO;
@@ -940,15 +957,23 @@
if (write_req) {
DBG(cdev, "rx %p %d\n", write_req, write_req->actual);
start_time = ktime_get();
+ mutex_lock(&dev->read_mutex);
+ if (dev->state == STATE_OFFLINE) {
+ r = -EIO;
+ mutex_unlock(&dev->read_mutex);
+ break;
+ }
ret = vfs_write(filp, write_req->buf, write_req->actual,
&offset);
DBG(cdev, "vfs_write %d\n", ret);
if (ret != write_req->actual) {
r = -EIO;
+ mutex_unlock(&dev->read_mutex);
if (dev->state != STATE_OFFLINE)
dev->state = STATE_ERROR;
break;
}
+ mutex_unlock(&dev->read_mutex);
dev->perf[dev->dbg_write_index].vfs_wtime =
ktime_to_us(ktime_sub(ktime_get(), start_time));
dev->perf[dev->dbg_write_index].vfs_wbytes = ret;
@@ -976,6 +1001,13 @@
r = read_req->status;
break;
}
+
+ mutex_lock(&dev->read_mutex);
+ if (dev->state == STATE_OFFLINE) {
+ r = -EIO;
+ mutex_unlock(&dev->read_mutex);
+ break;
+ }
/* Check if we aligned the size due to MTU constraint */
if (count < read_req->length)
read_req->actual = (read_req->actual > count ?
@@ -996,6 +1028,7 @@
write_req = read_req;
read_req = NULL;
+ mutex_unlock(&dev->read_mutex);
}
}
@@ -1446,12 +1479,14 @@
int i;
mtp_string_defs[INTERFACE_STRING_INDEX].id = 0;
+ mutex_lock(&dev->read_mutex);
while ((req = mtp_req_get(dev, &dev->tx_idle)))
mtp_request_free(req, dev->ep_in);
for (i = 0; i < RX_REQ_MAX; i++)
mtp_request_free(dev->rx_req[i], dev->ep_out);
while ((req = mtp_req_get(dev, &dev->intr_idle)))
mtp_request_free(req, dev->ep_intr);
+ mutex_unlock(&dev->read_mutex);
dev->state = STATE_OFFLINE;
kfree(f->os_desc_table);
f->os_desc_n = 0;
@@ -1791,6 +1826,8 @@
usb_os_desc_prepare_interf_dir(&fi_mtp->func_inst.group, 1,
descs, names, THIS_MODULE);
+ mutex_init(&fi_mtp->dev->read_mutex);
+
return &fi_mtp->func_inst;
}
EXPORT_SYMBOL_GPL(alloc_inst_mtp_ptp);
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 141b916..dca4811 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -377,6 +377,8 @@
struct list_head svid_handlers;
struct list_head instance;
+
+ u16 ss_lane_svid;
};
static LIST_HEAD(_usbpd); /* useful for debugging */
@@ -445,6 +447,47 @@
extcon_set_state_sync(pd->extcon, EXTCON_USB, 1);
}
+/**
+ * This API allows client driver to request for releasing SS lanes. It should
+ * not be called from atomic context.
+ *
+ * @pd - USBPD handler
+ * @hdlr - client's handler
+ *
+ * @returns int - Success - 0, else negative error code
+ */
+static int usbpd_release_ss_lane(struct usbpd *pd,
+ struct usbpd_svid_handler *hdlr)
+{
+ int ret = 0;
+
+ if (!hdlr || !pd)
+ return -EINVAL;
+
+ usbpd_dbg(&pd->dev, "hdlr:%pK svid:%d", hdlr, hdlr->svid);
+ /*
+ * If USB SS lanes are already used by one client, and other client is
+ * requesting for same or same client requesting again, return -EBUSY.
+ */
+ if (pd->ss_lane_svid) {
+ usbpd_dbg(&pd->dev, "-EBUSY: ss_lanes are already used by(%d)",
+ pd->ss_lane_svid);
+ ret = -EBUSY;
+ goto err_exit;
+ }
+
+ ret = extcon_blocking_sync(pd->extcon, EXTCON_USB_HOST, 0);
+ if (ret) {
+ usbpd_err(&pd->dev, "err(%d) for releasing ss lane", ret);
+ goto err_exit;
+ }
+
+ pd->ss_lane_svid = hdlr->svid;
+
+err_exit:
+ return ret;
+}
+
static int set_power_role(struct usbpd *pd, enum power_role pr)
{
union power_supply_propval val = {0};
@@ -764,6 +807,7 @@
if (pd->current_dr == DR_NONE) {
pd->current_dr = DR_DFP;
start_usb_host(pd, true);
+ pd->ss_lane_svid = 0x0;
}
dual_role_instance_changed(pd->dual_role);
@@ -926,6 +970,7 @@
if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP ||
+ pd->psy_type == POWER_SUPPLY_TYPE_USB_FLOAT ||
usb_compliance_mode)
start_usb_peripheral(pd);
}
@@ -1083,6 +1128,7 @@
usbpd_dbg(&pd->dev, "registered handler for SVID 0x%04x\n", hdlr->svid);
list_add_tail(&hdlr->entry, &pd->svid_handlers);
+ hdlr->request_usb_ss_lane = usbpd_release_ss_lane;
/* already connected with this SVID discovered? */
if (pd->vdm_state >= DISCOVERED_SVIDS) {
@@ -2468,6 +2514,16 @@
if (pd->current_pr == PR_SINK)
return 0;
+ /*
+ * Unexpected if not in PR swap; need to force disconnect from
+ * source so we can turn off VBUS, Vconn, PD PHY etc.
+ */
+ if (pd->current_pr == PR_SRC) {
+ usbpd_info(&pd->dev, "Forcing disconnect from source mode\n");
+ pd->current_pr = PR_NONE;
+ break;
+ }
+
pd->current_pr = PR_SINK;
break;
diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c
index 8061d8e..75b2f0b 100644
--- a/drivers/video/adf/adf_client.c
+++ b/drivers/video/adf/adf_client.c
@@ -305,8 +305,10 @@
}
done:
- if (ret < 0)
+ if (ret < 0) {
adf_buffer_mapping_cleanup(mapping, buf);
+ memset(mapping, 0, sizeof(*mapping));
+ }
return ret;
}
diff --git a/include/linux/cma.h b/include/linux/cma.h
index 29f9e77..d04f178 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -18,13 +18,15 @@
extern unsigned long totalcma_pages;
extern phys_addr_t cma_get_base(const struct cma *cma);
extern unsigned long cma_get_size(const struct cma *cma);
+extern const char *cma_get_name(const struct cma *cma);
extern int __init cma_declare_contiguous(phys_addr_t base,
phys_addr_t size, phys_addr_t limit,
phys_addr_t alignment, unsigned int order_per_bit,
- bool fixed, struct cma **res_cma);
+ bool fixed, const char *name, struct cma **res_cma);
extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
unsigned int order_per_bit,
+ const char *name,
struct cma **res_cma);
extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align);
extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 9f93d18..edf88bd 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -40,6 +40,7 @@
CPUHP_SLAB_PREPARE,
CPUHP_MD_RAID5_PREPARE,
CPUHP_RCUTREE_PREP,
+ CPUHP_CORE_CTL_ISOLATION_DEAD,
CPUHP_CPUIDLE_COUPLED_PREPARE,
CPUHP_POWERPC_PMAC_PREPARE,
CPUHP_POWERPC_MMU_CTX_PREPARE,
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 1731c3a..95fe239 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -65,6 +65,7 @@
#define DIAG_IOCTL_PERIPHERAL_BUF_DRAIN 36
#define DIAG_IOCTL_REGISTER_CALLBACK 37
#define DIAG_IOCTL_HDLC_TOGGLE 38
+#define DIAG_IOCTL_QUERY_PD_LOGGING 39
/* PC Tools IDs */
#define APQ8060_TOOLS_ID 4062
diff --git a/include/linux/ipc_router.h b/include/linux/ipc_router.h
index 767551e..c18290f 100644
--- a/include/linux/ipc_router.h
+++ b/include/linux/ipc_router.h
@@ -144,6 +144,7 @@
uint32_t num_rx;
unsigned long num_tx_bytes;
unsigned long num_rx_bytes;
+ uint32_t last_served_svc_id;
void *priv;
};
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 558adfa..8f5af30 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1921,6 +1921,13 @@
}
#endif /* CONFIG_SECURITY_SELINUX_DISABLE */
+/* Currently required to handle SELinux runtime hook disable. */
+#ifdef CONFIG_SECURITY_WRITABLE_HOOKS
+#define __lsm_ro_after_init
+#else
+#define __lsm_ro_after_init __ro_after_init
+#endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
+
extern int __init security_module_enable(const char *module);
extern void __init capability_add_hooks(void);
#ifdef CONFIG_SECURITY_YAMA
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index f188e85..cfe4724 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -179,6 +179,8 @@
int irq_base;
int num_irqs;
int reset_gpio;
+ bool has_buck_vsel_gpio;
+ struct device_node *buck_vsel_ctl_np;
struct device_node *wcd_rst_np;
struct wcd9xxx_amic amic_settings;
struct slim_device slimbus_slave_device;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2b423f7..9b21e2a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -76,6 +76,10 @@
#define page_to_virt(x) __va(PFN_PHYS(page_to_pfn(x)))
#endif
+#ifndef lm_alias
+#define lm_alias(x) __va(__pa_symbol(x))
+#endif
+
/*
* To prevent common memory management code establishing
* a zero page mapping on a read fault.
diff --git a/include/linux/qcom_tspp.h b/include/linux/qcom_tspp.h
index 1b34c38..7a9e569 100644
--- a/include/linux/qcom_tspp.h
+++ b/include/linux/qcom_tspp.h
@@ -16,6 +16,7 @@
struct tspp_data_descriptor {
void *virt_base; /* logical address of the actual data */
phys_addr_t phys_base; /* physical address of the actual data */
+ dma_addr_t dma_base; /* DMA address of the actual data */
u32 size; /* size of buffer in bytes */
int id; /* unique identifier */
void *user; /* user-defined data */
@@ -75,9 +76,17 @@
TSIF_TTS_LPASS_TIMER /* Time stamps from AV/Qtimer Timer */
};
+struct tspp_ion_dma_buf_info {
+ struct dma_buf *dbuf;
+ struct dma_buf_attachment *attach;
+ struct sg_table *table;
+ bool smmu_map;
+ dma_addr_t dma_map_base;
+};
+
typedef void (tspp_notifier)(int channel_id, void *user);
typedef void* (tspp_allocator)(int channel_id, u32 size,
- phys_addr_t *phys_base, void *user);
+ phys_addr_t *phys_base, dma_addr_t *dma_base, void *user);
typedef void (tspp_memfree)(int channel_id, u32 size,
void *virt_base, phys_addr_t phys_base, void *user);
@@ -105,4 +114,9 @@
int tspp_get_lpass_time_counter(u32 dev, enum tspp_source source,
u64 *lpass_time_counter);
+int tspp_attach_ion_dma_buff(u32 dev,
+ struct tspp_ion_dma_buf_info *ion_dma_buf);
+
+int tspp_detach_ion_dma_buff(u32 dev,
+ struct tspp_ion_dma_buf_info *ion_dma_buf);
#endif /* _MSM_TSPP_H_ */
diff --git a/include/linux/random.h b/include/linux/random.h
index 16ab429..1fa0dc8 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -42,8 +42,42 @@
extern const struct file_operations random_fops, urandom_fops;
#endif
-unsigned int get_random_int(void);
-unsigned long get_random_long(void);
+u32 get_random_u32(void);
+u64 get_random_u64(void);
+static inline unsigned int get_random_int(void)
+{
+ return get_random_u32();
+}
+static inline unsigned long get_random_long(void)
+{
+#if BITS_PER_LONG == 64
+ return get_random_u64();
+#else
+ return get_random_u32();
+#endif
+}
+
+/*
+ * On 64-bit architectures, protect against non-terminated C string overflows
+ * by zeroing out the first byte of the canary; this leaves 56 bits of entropy.
+ */
+#ifdef CONFIG_64BIT
+# ifdef __LITTLE_ENDIAN
+# define CANARY_MASK 0xffffffffffffff00UL
+# else /* big endian, 64 bits: */
+# define CANARY_MASK 0x00ffffffffffffffUL
+# endif
+#else /* 32 bits: */
+# define CANARY_MASK 0xffffffffUL
+#endif
+
+static inline unsigned long get_random_canary(void)
+{
+ unsigned long val = get_random_long();
+
+ return val & CANARY_MASK;
+}
+
unsigned long randomize_page(unsigned long start, unsigned long range);
u32 prandom_u32(void);
diff --git a/include/linux/seemp_instrumentation.h b/include/linux/seemp_instrumentation.h
index ff09bd2..1db7a44 100644
--- a/include/linux/seemp_instrumentation.h
+++ b/include/linux/seemp_instrumentation.h
@@ -69,7 +69,7 @@
seemp_logk_kernel_end(blck);
}
-static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20],
+static inline void seemp_logk_rtic(__u8 type, pid_t pid, __u8 asset_id[0x20],
__u8 asset_category, __u8 response)
{
char *buf = NULL;
@@ -80,8 +80,8 @@
return;
SEEMP_LOGK_RECORD(SEEMP_API_kernel__rtic,
- "app_pid=%llu,rtic_type=%u,asset_id=%s,asset_category=%u,response=%u",
- actor, type, asset_id, asset_category, response);
+ "app_pid=%d,rtic_type=%u,asset_id=%s,asset_category=%u,response=%u",
+ pid, type, asset_id, asset_category, response);
seemp_logk_kernel_end(blck);
}
diff --git a/include/linux/string.h b/include/linux/string.h
index 26b6f6a..4e510df 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -169,4 +169,204 @@
return tail ? tail + 1 : path;
}
+#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
+#define __RENAME(x) __asm__(#x)
+
+void fortify_panic(const char *name) __noreturn __cold;
+void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
+void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
+void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
+
+#if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
+__FORTIFY_INLINE char *strcpy(char *p, const char *q)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (p_size == (size_t)-1 && q_size == (size_t)-1)
+ return __builtin_strcpy(p, q);
+ if (strscpy(p, q, p_size < q_size ? p_size : q_size) < 0)
+ fortify_panic(__func__);
+ return p;
+}
+
+__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __write_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __builtin_strncpy(p, q, size);
+}
+
+__FORTIFY_INLINE char *strcat(char *p, const char *q)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (p_size == (size_t)-1)
+ return __builtin_strcat(p, q);
+ if (strlcat(p, q, p_size) >= p_size)
+ fortify_panic(__func__);
+ return p;
+}
+
+__FORTIFY_INLINE __kernel_size_t strlen(const char *p)
+{
+ __kernel_size_t ret;
+ size_t p_size = __builtin_object_size(p, 0);
+ if (p_size == (size_t)-1)
+ return __builtin_strlen(p);
+ ret = strnlen(p, p_size);
+ if (p_size <= ret)
+ fortify_panic(__func__);
+ return ret;
+}
+
+extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
+__FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
+ if (p_size <= ret && maxlen != ret)
+ fortify_panic(__func__);
+ return ret;
+}
+
+/* defined after fortified strlen to reuse it */
+extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
+__FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
+{
+ size_t ret;
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (p_size == (size_t)-1 && q_size == (size_t)-1)
+ return __real_strlcpy(p, q, size);
+ ret = strlen(q);
+ if (size) {
+ size_t len = (ret >= size) ? size - 1 : ret;
+ if (__builtin_constant_p(len) && len >= p_size)
+ __write_overflow();
+ if (len >= p_size)
+ fortify_panic(__func__);
+ __builtin_memcpy(p, q, len);
+ p[len] = '\0';
+ }
+ return ret;
+}
+
+/* defined after fortified strlen and strnlen to reuse them */
+__FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
+{
+ size_t p_len, copy_len;
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (p_size == (size_t)-1 && q_size == (size_t)-1)
+ return __builtin_strncat(p, q, count);
+ p_len = strlen(p);
+ copy_len = strnlen(q, count);
+ if (p_size < p_len + copy_len + 1)
+ fortify_panic(__func__);
+ __builtin_memcpy(p + p_len, q, copy_len);
+ p[p_len + copy_len] = '\0';
+ return p;
+}
+
+__FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __write_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __builtin_memset(p, c, size);
+}
+
+__FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (__builtin_constant_p(size)) {
+ if (p_size < size)
+ __write_overflow();
+ if (q_size < size)
+ __read_overflow2();
+ }
+ if (p_size < size || q_size < size)
+ fortify_panic(__func__);
+ return __builtin_memcpy(p, q, size);
+}
+
+__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (__builtin_constant_p(size)) {
+ if (p_size < size)
+ __write_overflow();
+ if (q_size < size)
+ __read_overflow2();
+ }
+ if (p_size < size || q_size < size)
+ fortify_panic(__func__);
+ return __builtin_memmove(p, q, size);
+}
+
+extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
+__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __read_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __real_memscan(p, c, size);
+}
+
+__FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (__builtin_constant_p(size)) {
+ if (p_size < size)
+ __read_overflow();
+ if (q_size < size)
+ __read_overflow2();
+ }
+ if (p_size < size || q_size < size)
+ fortify_panic(__func__);
+ return __builtin_memcmp(p, q, size);
+}
+
+__FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __read_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __builtin_memchr(p, c, size);
+}
+
+void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
+__FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __read_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __real_memchr_inv(p, c, size);
+}
+
+extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
+__FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ if (__builtin_constant_p(size) && p_size < size)
+ __read_overflow();
+ if (p_size < size)
+ fortify_panic(__func__);
+ return __real_kmemdup(p, size, gfp);
+}
+#endif
+
#endif /* _LINUX_STRING_H_ */
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 387fa7d..d802692 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -42,6 +42,7 @@
* are available -- else NULL's).
*/
+bool sysrq_on(void);
void handle_sysrq(int key);
void __handle_sysrq(int key, bool check_mask);
int register_sysrq_key(int key, struct sysrq_key_op *op);
diff --git a/include/linux/usb/usbpd.h b/include/linux/usb/usbpd.h
index 3566a7a..4dbd91f 100644
--- a/include/linux/usb/usbpd.h
+++ b/include/linux/usb/usbpd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 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
@@ -46,6 +46,10 @@
void (*connect)(struct usbpd_svid_handler *hdlr);
void (*disconnect)(struct usbpd_svid_handler *hdlr);
+ /* DP driver -> PE driver for requesting USB SS lanes */
+ int (*request_usb_ss_lane)(struct usbpd *pd,
+ struct usbpd_svid_handler *hdlr);
+
/* Unstructured VDM */
void (*vdm_received)(struct usbpd_svid_handler *hdlr, u32 vdm_hdr,
const u32 *vdos, int num_vdos);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b99b80a..82b4b53 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -45,6 +45,9 @@
/* Indicate backport support for FILS SK offload in cfg80211 */
#define CFG80211_FILS_SK_OFFLOAD_SUPPORT 1
+/* Indicate support for including KEK length in rekey data */
+#define CFG80211_REKEY_DATA_KEK_LEN 1
+
/**
* DOC: Introduction
*
@@ -2112,9 +2115,14 @@
* have to be updated as part of update_connect_params() call.
*
* @UPDATE_ASSOC_IES: Indicates whether association request IEs are updated
+ * @UPDATE_FILS_ERP_INFO: Indicates that FILS connection parameters (realm,
+ * username, erp sequence number and rrk) are updated
+ * @UPDATE_AUTH_TYPE: Indicates that Authentication type is updated
*/
enum cfg80211_connect_params_changed {
UPDATE_ASSOC_IES = BIT(0),
+ UPDATE_FILS_ERP_INFO = BIT(1),
+ UPDATE_AUTH_TYPE = BIT(2),
};
/**
@@ -2336,12 +2344,14 @@
/**
* struct cfg80211_gtk_rekey_data - rekey data
- * @kek: key encryption key (NL80211_KEK_LEN bytes)
+ * @kek: key encryption key
* @kck: key confirmation key (NL80211_KCK_LEN bytes)
* @replay_ctr: replay counter (NL80211_REPLAY_CTR_LEN bytes)
+ * @kek_len: Length of @kek in octets
*/
struct cfg80211_gtk_rekey_data {
const u8 *kek, *kck, *replay_ctr;
+ size_t kek_len;
};
/**
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 14f6445..aa95178 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -8537,6 +8537,8 @@
#define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E
#define VSS_ICOMMON_RSP_GET_PARAM 0x00011008
+#define VSS_MAX_AVCS_NUM_SERVICES 25
+
/* ID of the Bass Boost module.
* This module supports the following parameter IDs:
* - #AUDPROC_PARAM_ID_BASS_BOOST_ENABLE
@@ -9197,6 +9199,74 @@
*/
} __packed;
+/* Q6Core Specific */
+#define AVCS_CMD_GET_FWK_VERSION (0x0001292C)
+#define AVCS_CMDRSP_GET_FWK_VERSION (0x0001292D)
+
+#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF)
+#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB)
+
+struct avcs_get_fwk_version {
+ /*
+ * Indicates the major version of the AVS build.
+ * This value is incremented on chipset family boundaries.
+ */
+ uint32_t build_major_version;
+
+ /*
+ * Minor version of the AVS build.
+ * This value represents the mainline to which the AVS build belongs.
+ */
+ uint32_t build_minor_version;
+
+ /* Indicates the AVS branch version to which the image belongs. */
+ uint32_t build_branch_version;
+
+ /* Indicates the AVS sub-branch or customer product line information. */
+ uint32_t build_subbranch_version;
+
+ /* Number of supported AVS services in the current build. */
+ uint32_t num_services;
+};
+
+struct avs_svc_api_info {
+ /*
+ * APRV2 service IDs for the individual static services.
+ *
+ * @values
+ * - APRV2_IDS_SERVICE_ID_ADSP_CORE_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_AFE_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_ASM_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_ADM_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_MVM_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_CVS_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_CVP_V
+ * - APRV2_IDS_SERVICE_ID_ADSP_LSM_V
+ */
+ uint32_t service_id;
+
+ /*
+ * Indicates the API version of the service.
+ *
+ * Each new API update that warrants a change on the HLOS side triggers
+ * an increment in the version.
+ */
+ uint32_t api_version;
+
+ /*
+ * Indicates the API increments on a sub-branch (not on the mainline).
+ *
+ * API branch version numbers can increment independently on different
+ * sub-branches.
+ */
+ uint32_t api_branch_version;
+};
+
+struct avcs_fwk_ver_info {
+ struct avcs_get_fwk_version avcs_fwk_version;
+ struct avs_svc_api_info *services;
+} __packed;
+
/* LSM Specific */
#define VW_FEAT_DIM (39)
diff --git a/include/sound/q6core.h b/include/sound/q6core.h
index 0b8309a..111af67 100644
--- a/include/sound/q6core.h
+++ b/include/sound/q6core.h
@@ -13,6 +13,7 @@
#ifndef __Q6CORE_H__
#define __Q6CORE_H__
#include <linux/qdsp6v2/apr.h>
+#include <sound/apr_audio-v2.h>
@@ -21,6 +22,11 @@
bool q6core_is_adsp_ready(void);
+int q6core_get_service_version(uint32_t service_id,
+ struct avcs_fwk_ver_info *ver_info,
+ size_t size);
+size_t q6core_get_avcs_service_size(uint32_t service_id);
+
#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
#define DTS_EAGLE_LICENSE_ID 0x00028346
struct adsp_dts_eagle {
diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h
index 031ae49..c0475a2 100644
--- a/include/trace/events/thermal.h
+++ b/include/trace/events/thermal.h
@@ -45,6 +45,23 @@
__entry->temp)
);
+TRACE_EVENT(cdev_update_start,
+
+ TP_PROTO(struct thermal_cooling_device *cdev),
+
+ TP_ARGS(cdev),
+
+ TP_STRUCT__entry(
+ __string(type, cdev->type)
+ ),
+
+ TP_fast_assign(
+ __assign_str(type, cdev->type);
+ ),
+
+ TP_printk("type=%s update start", __get_str(type))
+);
+
TRACE_EVENT(cdev_update,
TP_PROTO(struct thermal_cooling_device *cdev, unsigned long target,
@@ -98,6 +115,75 @@
show_tzt_type(__entry->trip_type))
);
+TRACE_EVENT(thermal_handle_trip,
+
+ TP_PROTO(struct thermal_zone_device *tz, int trip),
+
+ TP_ARGS(tz, trip),
+
+ TP_STRUCT__entry(
+ __string(thermal_zone, tz->type)
+ __field(int, id)
+ __field(int, trip)
+ ),
+
+ TP_fast_assign(
+ __assign_str(thermal_zone, tz->type);
+ __entry->id = tz->id;
+ __entry->trip = trip;
+ ),
+
+ TP_printk("thermal_zone=%s id=%d handle trip=%d",
+ __get_str(thermal_zone), __entry->id, __entry->trip)
+);
+
+TRACE_EVENT(thermal_device_update,
+
+ TP_PROTO(struct thermal_zone_device *tz, int event),
+
+ TP_ARGS(tz, event),
+
+ TP_STRUCT__entry(
+ __string(thermal_zone, tz->type)
+ __field(int, id)
+ __field(int, event)
+ ),
+
+ TP_fast_assign(
+ __assign_str(thermal_zone, tz->type);
+ __entry->id = tz->id;
+ __entry->event = event;
+ ),
+
+ TP_printk("thermal_zone=%s id=%d received event:%d",
+ __get_str(thermal_zone), __entry->id, __entry->event)
+);
+
+TRACE_EVENT(thermal_set_trip,
+
+ TP_PROTO(struct thermal_zone_device *tz),
+
+ TP_ARGS(tz),
+
+ TP_STRUCT__entry(
+ __string(thermal_zone, tz->type)
+ __field(int, id)
+ __field(int, low)
+ __field(int, high)
+ ),
+
+ TP_fast_assign(
+ __assign_str(thermal_zone, tz->type);
+ __entry->id = tz->id;
+ __entry->low = tz->prev_low_trip;
+ __entry->high = tz->prev_high_trip;
+ ),
+
+ TP_printk("thermal_zone=%s id=%d low trip=%d high trip=%d",
+ __get_str(thermal_zone), __entry->id, __entry->low,
+ __entry->high)
+);
+
TRACE_EVENT(thermal_power_cpu_get_power,
TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load,
size_t load_len, u32 dynamic_power, u32 static_power),
diff --git a/include/uapi/linux/spcom.h b/include/uapi/linux/spcom.h
index 9b6b9b7..39b1be0 100644
--- a/include/uapi/linux/spcom.h
+++ b/include/uapi/linux/spcom.h
@@ -30,6 +30,12 @@
* with special size SPCOM_GET_NEXT_REQUEST_SIZE.
*/
+/*
+ * Maximum number of channel between Secure Processor and HLOS.
+ * including predefined channels, like "sp_kernel".
+ */
+#define SPCOM_MAX_CHANNELS 0x20
+
/* Maximum size (including null) for channel names */
#define SPCOM_CHANNEL_NAME_SIZE 32
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index c0644f4..7bb21fd 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -6616,7 +6616,7 @@
struct task_struct *task;
int count = 0;
- seq_printf(seq, "css_set %p\n", cset);
+ seq_printf(seq, "css_set %pK\n", cset);
list_for_each_entry(task, &cset->tasks, cg_list) {
if (count++ > MAX_TASKS_SHOWN_PER_CSS)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2ac75e2..d1bed63 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -358,6 +358,32 @@
EVENT_ALL = EVENT_FLEXIBLE | EVENT_PINNED,
};
+/* The shared events struct. */
+#define SHARED_EVENTS_MAX 7
+
+struct shared_events_str {
+ /*
+ * Mutex to serialize access to shared list. Needed for the
+ * read/modify/write sequences.
+ */
+ struct mutex list_mutex;
+
+ /*
+ * A 1 bit for an index indicates that the slot is being used for
+ * an event. A 0 means that the slot can be used.
+ */
+ DECLARE_BITMAP(used_mask, SHARED_EVENTS_MAX);
+
+ /*
+ * The kernel events that are shared for a cpu;
+ */
+ struct perf_event *events[SHARED_EVENTS_MAX];
+ struct perf_event_attr attr[SHARED_EVENTS_MAX];
+ atomic_t refcount[SHARED_EVENTS_MAX];
+};
+
+static struct shared_events_str __percpu *shared_events;
+
/*
* perf_sched_events : >0 events exist
* perf_cgroup_events: >0 per-cpu cgroup events exist on this cpu
@@ -4079,6 +4105,35 @@
static void perf_addr_filters_splice(struct perf_event *event,
struct list_head *head);
+static int
+perf_event_delete_kernel_shared(struct perf_event *event)
+{
+ int rc = -1, cpu = event->cpu;
+ struct shared_events_str *shrd_events;
+ unsigned long idx;
+
+ if (!shared_events || (u32)cpu >= nr_cpu_ids)
+ return 0;
+
+ shrd_events = per_cpu_ptr(shared_events, cpu);
+
+ mutex_lock(&shrd_events->list_mutex);
+
+ for_each_set_bit(idx, shrd_events->used_mask, SHARED_EVENTS_MAX) {
+ if (shrd_events->events[idx] == event) {
+ if (atomic_dec_and_test(&shrd_events->refcount[idx])) {
+ clear_bit(idx, shrd_events->used_mask);
+ shrd_events->events[idx] = NULL;
+ }
+ rc = (int)atomic_read(&shrd_events->refcount[idx]);
+ break;
+ }
+ }
+
+ mutex_unlock(&shrd_events->list_mutex);
+ return rc;
+}
+
static void _free_event(struct perf_event *event)
{
irq_work_sync(&event->pending);
@@ -4216,8 +4271,12 @@
goto no_ctx;
}
- if (!is_kernel_event(event))
+ if (!is_kernel_event(event)) {
perf_remove_from_owner(event);
+ } else {
+ if (perf_event_delete_kernel_shared(event) > 0)
+ return 0;
+ }
ctx = perf_event_ctx_lock(event);
WARN_ON_ONCE(ctx->parent_ctx);
@@ -10043,6 +10102,103 @@
return err;
}
+static struct perf_event *
+perf_event_create_kernel_shared_check(struct perf_event_attr *attr, int cpu,
+ struct task_struct *task,
+ perf_overflow_handler_t overflow_handler,
+ void *context)
+{
+ unsigned long idx;
+ struct perf_event *event;
+ struct shared_events_str *shrd_events;
+
+ /*
+ * Have to be per cpu events for sharing
+ */
+ if (!shared_events || (u32)cpu >= nr_cpu_ids)
+ return NULL;
+
+ /*
+ * Can't handle these type requests for sharing right now.
+ */
+ if (task || context || overflow_handler ||
+ (attr->type != PERF_TYPE_HARDWARE &&
+ attr->type != PERF_TYPE_RAW))
+ return NULL;
+
+ /*
+ * Using per_cpu_ptr (or could do cross cpu call which is what most of
+ * perf does to access per cpu data structures
+ */
+ shrd_events = per_cpu_ptr(shared_events, cpu);
+
+ mutex_lock(&shrd_events->list_mutex);
+
+ event = NULL;
+ for_each_set_bit(idx, shrd_events->used_mask, SHARED_EVENTS_MAX) {
+ if (memcmp(attr, &shrd_events->attr[idx],
+ sizeof(shrd_events->attr[idx])) == 0) {
+ atomic_inc(&shrd_events->refcount[idx]);
+ event = shrd_events->events[idx];
+ break;
+ }
+ }
+ mutex_unlock(&shrd_events->list_mutex);
+ return event;
+}
+
+static void
+perf_event_create_kernel_shared_add(struct perf_event_attr *attr, int cpu,
+ struct task_struct *task,
+ perf_overflow_handler_t overflow_handler,
+ void *context,
+ struct perf_event *event)
+{
+ unsigned long idx;
+ struct shared_events_str *shrd_events;
+
+ /*
+ * Have to be per cpu events for sharing
+ */
+ if (!shared_events || (u32)cpu >= nr_cpu_ids)
+ return;
+
+ /*
+ * Can't handle these type requests for sharing right now.
+ */
+ if (task || context || overflow_handler ||
+ (attr->type != PERF_TYPE_HARDWARE &&
+ attr->type != PERF_TYPE_RAW))
+ return;
+
+ /*
+ * Using per_cpu_ptr (or could do cross cpu call which is what most of
+ * perf does to access per cpu data structures
+ */
+ shrd_events = per_cpu_ptr(shared_events, cpu);
+
+ mutex_lock(&shrd_events->list_mutex);
+
+ /*
+ * If we are in this routine, we know that this event isn't already in
+ * the shared list. Check if slot available in shared list
+ */
+ idx = find_first_zero_bit(shrd_events->used_mask, SHARED_EVENTS_MAX);
+
+ if (idx >= SHARED_EVENTS_MAX)
+ goto out;
+
+ /*
+ * The event isn't in the list and there is an empty slot so add it.
+ */
+ shrd_events->attr[idx] = *attr;
+ shrd_events->events[idx] = event;
+ set_bit(idx, shrd_events->used_mask);
+ atomic_set(&shrd_events->refcount[idx], 1);
+out:
+ mutex_unlock(&shrd_events->list_mutex);
+}
+
/**
* perf_event_create_kernel_counter
*
@@ -10061,6 +10217,14 @@
int err;
/*
+ * Check if the requested attributes match a shared event
+ */
+ event = perf_event_create_kernel_shared_check(attr, cpu,
+ task, overflow_handler, context);
+ if (event)
+ return event;
+
+ /*
* Get the target context (task or percpu):
*/
@@ -10096,6 +10260,11 @@
perf_unpin_context(ctx);
mutex_unlock(&ctx->mutex);
+ /*
+ * Check if can add event to shared list
+ */
+ perf_event_create_kernel_shared_add(attr, cpu,
+ task, overflow_handler, context, event);
return event;
err_unlock:
@@ -10919,10 +11088,21 @@
void __init perf_event_init(void)
{
- int ret;
+ int ret, cpu;
idr_init(&pmu_idr);
+ shared_events = alloc_percpu(struct shared_events_str);
+ if (!shared_events) {
+ WARN(1, "alloc_percpu failed for shared_events struct");
+ } else {
+ for_each_possible_cpu(cpu) {
+ struct shared_events_str *shrd_events =
+ per_cpu_ptr(shared_events, cpu);
+
+ mutex_init(&shrd_events->list_mutex);
+ }
+ }
perf_event_init_all_cpus();
init_srcu_struct(&pmus_srcu);
perf_pmu_register(&perf_swevent, "software", PERF_TYPE_SOFTWARE);
diff --git a/kernel/fork.c b/kernel/fork.c
index 52e5505..39c0709 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1517,6 +1517,18 @@
if (!p)
goto fork_out;
+ /*
+ * This _must_ happen before we call free_task(), i.e. before we jump
+ * to any of the bad_fork_* labels. This is to avoid freeing
+ * p->set_child_tid which is (ab)used as a kthread's data pointer for
+ * kernel threads (PF_KTHREAD).
+ */
+ p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
+ /*
+ * Clear TID on mm_release()?
+ */
+ p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr : NULL;
+
ftrace_graph_init_task(p);
rt_mutex_init_task(p);
@@ -1678,11 +1690,6 @@
}
}
- p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
- /*
- * Clear TID on mm_release()?
- */
- p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr : NULL;
#ifdef CONFIG_BLOCK
p->plug = NULL;
#endif
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 037c321..38f7665 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -25,13 +25,6 @@
#include <linux/vmalloc.h>
#include "kexec_internal.h"
-/*
- * Declare these symbols weak so that if architecture provides a purgatory,
- * these will be overridden.
- */
-char __weak kexec_purgatory[0];
-size_t __weak kexec_purgatory_size = 0;
-
static int kexec_calculate_store_digests(struct kimage *image);
/* Architectures can provide this probe function */
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 0a52315..f95fd2c 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -37,6 +37,8 @@
};
void kimage_file_post_load_cleanup(struct kimage *image);
+extern char kexec_purgatory[];
+extern size_t kexec_purgatory_size;
#else /* CONFIG_KEXEC_FILE */
static inline void kimage_file_post_load_cleanup(struct kimage *image) { }
#endif /* CONFIG_KEXEC_FILE */
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index 4c3bf526..e56af41 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -13,7 +13,6 @@
#define pr_fmt(fmt) "core_ctl: " fmt
#include <linux/init.h>
-#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpufreq.h>
@@ -877,21 +876,18 @@
return 0;
}
-static int __ref cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
+static int isolation_cpuhp_state(unsigned int cpu, bool online)
{
- uint32_t cpu = (uintptr_t)hcpu;
struct cpu_data *state = &per_cpu(cpu_state, cpu);
struct cluster_data *cluster = state->cluster;
unsigned int need;
- bool do_wakeup, unisolated = false;
+ bool do_wakeup = false, unisolated = false;
unsigned long flags;
if (unlikely(!cluster || !cluster->inited))
- return NOTIFY_DONE;
+ return 0;
- switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_ONLINE:
+ if (online) {
cluster->active_cpus = get_active_cpu_count(cluster);
/*
@@ -901,9 +897,7 @@
* reject trying to online CPUs.
*/
move_cpu_lru(state);
- break;
-
- case CPU_DEAD:
+ } else {
/*
* We don't want to have a CPU both offline and isolated.
* So unisolate a CPU that went down if it was isolated by us.
@@ -919,9 +913,6 @@
state->busy = 0;
cluster->active_cpus = get_active_cpu_count(cluster);
- break;
- default:
- return NOTIFY_DONE;
}
need = apply_limits(cluster, cluster->need_cpus);
@@ -933,12 +924,18 @@
if (do_wakeup)
wake_up_core_ctl_thread(cluster);
- return NOTIFY_OK;
+ return 0;
}
-static struct notifier_block __refdata cpu_notifier = {
- .notifier_call = cpu_callback,
-};
+static int core_ctl_isolation_online_cpu(unsigned int cpu)
+{
+ return isolation_cpuhp_state(cpu, true);
+}
+
+static int core_ctl_isolation_dead_cpu(unsigned int cpu)
+{
+ return isolation_cpuhp_state(cpu, false);
+}
/* ============================ init code ============================== */
@@ -1068,7 +1065,13 @@
if (should_skip(cpu_possible_mask))
return 0;
- register_cpu_notifier(&cpu_notifier);
+ cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "core_ctl/isolation:online",
+ core_ctl_isolation_online_cpu, NULL);
+
+ cpuhp_setup_state_nocalls(CPUHP_CORE_CTL_ISOLATION_DEAD,
+ "core_ctl/isolation:dead",
+ NULL, core_ctl_isolation_dead_cpu);
for_each_cpu(cpu, &cpus) {
int ret;
diff --git a/lib/string.c b/lib/string.c
index ed83562..ccabe16 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -952,3 +952,10 @@
return s;
}
EXPORT_SYMBOL(strreplace);
+
+void fortify_panic(const char *name)
+{
+ pr_emerg("detected buffer overflow in %s\n", name);
+ BUG();
+}
+EXPORT_SYMBOL(fortify_panic);
diff --git a/mm/cma.c b/mm/cma.c
index 3322b30..2984dac 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -36,6 +36,7 @@
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/show_mem_notifier.h>
#include <trace/events/cma.h>
#include "cma.h"
@@ -54,6 +55,11 @@
return cma->count << PAGE_SHIFT;
}
+const char *cma_get_name(const struct cma *cma)
+{
+ return cma->name ? cma->name : "(undefined)";
+}
+
static unsigned long cma_bitmap_aligned_mask(const struct cma *cma,
int align_order)
{
@@ -95,6 +101,29 @@
mutex_unlock(&cma->lock);
}
+static int cma_showmem_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ int i;
+ unsigned long used;
+ struct cma *cma;
+
+ for (i = 0; i < cma_area_count; i++) {
+ cma = &cma_areas[i];
+ used = bitmap_weight(cma->bitmap,
+ (int)cma_bitmap_maxno(cma));
+ used <<= cma->order_per_bit;
+ pr_info("cma-%d pages: => %lu used of %lu total pages\n",
+ i, used, cma->count);
+ }
+
+ return 0;
+}
+
+static struct notifier_block cma_nb = {
+ .notifier_call = cma_showmem_notifier,
+};
+
static int __init cma_activate_area(struct cma *cma)
{
int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
@@ -158,6 +187,8 @@
return ret;
}
+ show_mem_notifier_register(&cma_nb);
+
return 0;
}
core_initcall(cma_init_reserved_areas);
@@ -173,6 +204,7 @@
*/
int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
unsigned int order_per_bit,
+ const char *name,
struct cma **res_cma)
{
struct cma *cma;
@@ -203,6 +235,13 @@
* subsystems (like slab allocator) are available.
*/
cma = &cma_areas[cma_area_count];
+ if (name) {
+ cma->name = name;
+ } else {
+ cma->name = kasprintf(GFP_KERNEL, "cma%d\n", cma_area_count);
+ if (!cma->name)
+ return -ENOMEM;
+ }
cma->base_pfn = PFN_DOWN(base);
cma->count = size >> PAGE_SHIFT;
cma->order_per_bit = order_per_bit;
@@ -234,7 +273,7 @@
int __init cma_declare_contiguous(phys_addr_t base,
phys_addr_t size, phys_addr_t limit,
phys_addr_t alignment, unsigned int order_per_bit,
- bool fixed, struct cma **res_cma)
+ bool fixed, const char *name, struct cma **res_cma)
{
phys_addr_t memblock_end = memblock_end_of_DRAM();
phys_addr_t highmem_start;
@@ -345,7 +384,7 @@
base = addr;
}
- ret = cma_init_reserved_mem(base, size, order_per_bit, res_cma);
+ ret = cma_init_reserved_mem(base, size, order_per_bit, name, res_cma);
if (ret)
goto err;
@@ -358,6 +397,32 @@
return ret;
}
+#ifdef CONFIG_CMA_DEBUG
+static void cma_debug_show_areas(struct cma *cma)
+{
+ unsigned long next_zero_bit, next_set_bit;
+ unsigned long start = 0;
+ unsigned int nr_zero, nr_total = 0;
+
+ mutex_lock(&cma->lock);
+ pr_info("number of available pages: ");
+ for (;;) {
+ next_zero_bit = find_next_zero_bit(cma->bitmap, cma->count, start);
+ if (next_zero_bit >= cma->count)
+ break;
+ next_set_bit = find_next_bit(cma->bitmap, cma->count, next_zero_bit);
+ nr_zero = next_set_bit - next_zero_bit;
+ pr_cont("%s%u@%lu", nr_total ? "+" : "", nr_zero, next_zero_bit);
+ nr_total += nr_zero;
+ start = next_zero_bit + nr_zero;
+ }
+ pr_cont("=> %u free of %lu total pages\n", nr_total, cma->count);
+ mutex_unlock(&cma->lock);
+}
+#else
+static inline void cma_debug_show_areas(struct cma *cma) { }
+#endif
+
/**
* cma_alloc() - allocate pages from contiguous area
* @cma: Contiguous memory region for which the allocation is performed.
@@ -374,8 +439,8 @@
unsigned long start = 0;
unsigned long bitmap_maxno, bitmap_no, bitmap_count;
struct page *page = NULL;
- int ret;
int retry_after_sleep = 0;
+ int ret = -ENOMEM;
if (!cma || !cma->count)
return NULL;
@@ -452,6 +517,12 @@
trace_cma_alloc(pfn, page, count, align);
+ if (ret) {
+ pr_info("%s: alloc failed, req-size: %zu pages, ret: %d\n",
+ __func__, count, ret);
+ cma_debug_show_areas(cma);
+ }
+
pr_debug("%s(): returned %p\n", __func__, page);
return page;
}
diff --git a/mm/cma.h b/mm/cma.h
index 17c75a4..4986128 100644
--- a/mm/cma.h
+++ b/mm/cma.h
@@ -11,6 +11,7 @@
struct hlist_head mem_head;
spinlock_t mem_head_lock;
#endif
+ const char *name;
};
extern struct cma cma_areas[MAX_CMA_AREAS];
diff --git a/mm/cma_debug.c b/mm/cma_debug.c
index f8e4b60..3f7f84c 100644
--- a/mm/cma_debug.c
+++ b/mm/cma_debug.c
@@ -167,7 +167,7 @@
char name[16];
int u32s;
- sprintf(name, "cma-%d", idx);
+ scnprintf(name, sizeof(name), "cma-%s", cma->name);
tmp = debugfs_create_dir(name, cma_debugfs_root);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 2efa9c9..3a22b14 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -37,6 +37,7 @@
#include <linux/ratelimit.h>
#include <linux/kthread.h>
#include <linux/init.h>
+#include <linux/show_mem_notifier.h>
#include <asm/tlb.h>
#include "internal.h"
@@ -416,8 +417,11 @@
dump_stack();
if (oc->memcg)
mem_cgroup_print_oom_info(oc->memcg, p);
- else
+ else {
show_mem(SHOW_MEM_FILTER_NODES);
+ show_mem_call_notifiers();
+ }
+
if (sysctl_oom_dump_tasks)
dump_tasks(oc->memcg, oc->nodemask);
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bdd2bea..44085b2 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -64,6 +64,7 @@
#include <linux/page_owner.h>
#include <linux/kthread.h>
#include <linux/memcontrol.h>
+#include <linux/show_mem_notifier.h>
#include <asm/sections.h>
#include <asm/tlbflush.h>
@@ -3130,8 +3131,10 @@
pr_cont(", mode:%#x(%pGg)\n", gfp_mask, &gfp_mask);
dump_stack();
- if (!should_suppress_show_mem())
+ if (!should_suppress_show_mem()) {
show_mem(filter);
+ show_mem_call_notifiers();
+ }
}
static inline struct page *
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 7c8af29f..a28b1af 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -363,6 +363,8 @@
svc_id = rport_ptr->server->name.service;
svc_ins = rport_ptr->server->name.instance;
port_type = CLIENT_PORT;
+ port_ptr->last_served_svc_id =
+ rport_ptr->server->name.service;
} else if (port_ptr && (port_ptr->type == SERVER_PORT)) {
svc_id = port_ptr->port_name.service;
svc_ins = port_ptr->port_name.instance;
@@ -1330,8 +1332,9 @@
mutex_init(&port_ptr->port_rx_q_lock_lhc3);
init_waitqueue_head(&port_ptr->port_rx_wait_q);
snprintf(port_ptr->rx_ws_name, MAX_WS_NAME_SZ,
- "ipc%08x_%s",
+ "ipc%08x_%d_%s",
port_ptr->this_port.port_id,
+ task_pid_nr(current),
current->comm);
port_ptr->port_rx_ws = wakeup_source_register(port_ptr->rx_ws_name);
if (!port_ptr->port_rx_ws) {
@@ -3847,15 +3850,18 @@
int j;
struct msm_ipc_port *port_ptr;
- seq_printf(s, "%-11s|%-11s|\n", "Node_id", "Port_id");
+ seq_printf(s, "%-11s|%-11s|%-32s|%-11s|\n",
+ "Node_id", "Port_id", "Wakelock", "Last SVCID");
seq_puts(s, "------------------------------------------------------------\n");
down_read(&local_ports_lock_lhc2);
for (j = 0; j < LP_HASH_SIZE; j++) {
list_for_each_entry(port_ptr, &local_ports[j], list) {
mutex_lock(&port_ptr->port_lock_lhc3);
- seq_printf(s, "0x%08x |0x%08x |\n",
+ seq_printf(s, "0x%08x |0x%08x |%-32s|0x%08x |\n",
port_ptr->this_port.node_id,
- port_ptr->this_port.port_id);
+ port_ptr->this_port.port_id,
+ port_ptr->rx_ws_name,
+ port_ptr->last_served_svc_id);
mutex_unlock(&port_ptr->port_lock_lhc3);
}
}
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index a2dff71..413deff 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -538,6 +538,12 @@
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
+country GI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
+
country GL: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
@@ -678,10 +684,6 @@
(5170 - 5330 @ 160), (23)
(5735 - 5835 @ 80), (30)
-country IR:
- (2402 - 2482 @ 40), (20)
- (5735 - 5835 @ 80), (30)
-
country IS: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
@@ -764,19 +766,12 @@
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (20), AUTO-BW
(5250 - 5330 @ 80), (20), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
(5735 - 5835 @ 80), (30)
# 60 GHz band channels 1-4,
# ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99
(57240 - 65880 @ 2160), (43)
-country KP: DFS-ETSI
- (2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (20)
- (5250 - 5330 @ 80), (20), DFS
- (5490 - 5630 @ 80), (30), DFS
- (5735 - 5815 @ 80), (30)
-
country KW: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
@@ -1022,7 +1017,7 @@
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
(5735 - 5835 @ 80), (33)
country NG: DFS-ETSI
@@ -1338,9 +1333,6 @@
(5250 - 5330 @ 20), (23), DFS
(5735 - 5835 @ 20), (30)
-country SY:
- (2402 - 2482 @ 40), (20)
-
country TC: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (24), AUTO-BW
@@ -1426,7 +1418,7 @@
country US: DFS-FCC
(2402 - 2472 @ 40), (30)
- (5170 - 5250 @ 80), (24), AUTO-BW
+ (5170 - 5250 @ 80), (30), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
@@ -1467,7 +1459,7 @@
(5490 - 5710 @ 160), (30), DFS
country VE: DFS-FCC
- (2402 - 2482 @ 40), (30)
+ (2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5735 - 5835 @ 80), (30)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 01324d2..ebd9a4b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -499,7 +499,8 @@
/* policy for GTK rekey offload attributes */
static const struct nla_policy
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
- [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
+ [NL80211_REKEY_DATA_KEK] = { .type = NLA_BINARY,
+ .len = FILS_MAX_KEK_LEN },
[NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
[NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
};
@@ -8882,6 +8883,45 @@
changed |= UPDATE_ASSOC_IES;
}
+ if (wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
+ info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+ connect.fils_erp_username =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+ connect.fils_erp_username_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+ connect.fils_erp_realm =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+ connect.fils_erp_realm_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+ connect.fils_erp_next_seq_num =
+ nla_get_u16(
+ info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
+ connect.fils_erp_rrk =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+ connect.fils_erp_rrk_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+ changed |= UPDATE_FILS_ERP_INFO;
+ } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+ return -EINVAL;
+ }
+
+ if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+ u32 auth_type =
+ nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+ if (!nl80211_valid_auth_type(rdev, auth_type,
+ NL80211_CMD_CONNECT))
+ return -EINVAL;
+ connect.auth_type = auth_type;
+ changed |= UPDATE_AUTH_TYPE;
+ }
+
wdev_lock(dev->ieee80211_ptr);
if (!wdev->current_bss)
ret = -ENOLINK;
@@ -10569,15 +10609,27 @@
if (err)
return err;
+ if (!tb[NL80211_REKEY_DATA_KEK] || !tb[NL80211_REKEY_DATA_REPLAY_CTR] ||
+ (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
+ !wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_FILS_STA) &&
+ !tb[NL80211_REKEY_DATA_KCK]))
+ return -EINVAL;
+
if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
return -ERANGE;
- if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
+ if (nla_len(tb[NL80211_REKEY_DATA_KEK]) < NL80211_KEK_LEN)
return -ERANGE;
- if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
+ if (tb[NL80211_REKEY_DATA_KCK] &&
+ nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
return -ERANGE;
+ memset(&rekey_data, 0, sizeof(rekey_data));
rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
- rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
+ rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
+ if (tb[NL80211_REKEY_DATA_KCK])
+ rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
wdev_lock(wdev);
diff --git a/security/Kconfig b/security/Kconfig
index 59aea7d..5693989 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -40,6 +40,11 @@
If you are unsure how to answer this question, answer N.
+config SECURITY_WRITABLE_HOOKS
+ depends on SECURITY
+ bool
+ default n
+
config SECURITYFS
bool "Enable the securityfs filesystem"
help
@@ -167,6 +172,13 @@
been removed. This config is intended to be used only while
trying to find such users.
+config FORTIFY_SOURCE
+ bool "Harden common str/mem functions against buffer overflows"
+ depends on ARCH_HAS_FORTIFY_SOURCE
+ help
+ Detect overflows of buffers in common string and memory functions
+ where the compiler can determine and validate the buffer sizes.
+
source security/selinux/Kconfig
source security/smack/Kconfig
source security/tomoyo/Kconfig
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 41b8cb1..57bc405 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -584,7 +584,7 @@
return error;
}
-static struct security_hook_list apparmor_hooks[] = {
+static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
LSM_HOOK_INIT(capget, apparmor_capget),
diff --git a/security/commoncap.c b/security/commoncap.c
index a8e4aac..3e44d01 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1081,7 +1081,7 @@
#ifdef CONFIG_SECURITY
-struct security_hook_list capability_hooks[] = {
+struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(capable, cap_capable),
LSM_HOOK_INIT(settime, cap_settime),
LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index 89a46f1..afd4ab9 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -174,7 +174,7 @@
return 0;
}
-static struct security_hook_list loadpin_hooks[] = {
+static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security),
LSM_HOOK_INIT(kernel_read_file, loadpin_read_file),
};
diff --git a/security/security.c b/security/security.c
index 1ba5274..6a7b359 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1590,7 +1590,7 @@
}
#endif /* CONFIG_AUDIT */
-struct security_hook_heads security_hook_heads = {
+struct security_hook_heads security_hook_heads __lsm_ro_after_init = {
.binder_set_context_mgr =
LIST_HEAD_INIT(security_hook_heads.binder_set_context_mgr),
.binder_transaction =
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index ea7e3ef..8af7a69 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -40,6 +40,7 @@
config SECURITY_SELINUX_DISABLE
bool "NSA SELinux runtime disable"
depends on SECURITY_SELINUX
+ select SECURITY_WRITABLE_HOOKS
default n
help
This option enables writing to a selinuxfs node 'disable', which
@@ -50,6 +51,11 @@
portability across platforms where boot parameters are difficult
to employ.
+ NOTE: selecting this option will disable the '__ro_after_init'
+ kernel hardening feature for security hooks. Please consider
+ using the selinux=0 boot parameter instead of enabling this
+ option.
+
If you are unsure how to answer this question, answer N.
config SECURITY_SELINUX_DEVELOP
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 20b2e7d..e26ecb0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6079,7 +6079,7 @@
#endif
-static struct security_hook_list selinux_hooks[] = {
+static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 1cb0602..b75c31a 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4611,7 +4611,7 @@
return 0;
}
-static struct security_hook_list smack_hooks[] = {
+static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
LSM_HOOK_INIT(syslog, smack_syslog),
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 75c9987..f1dce33 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -496,7 +496,7 @@
* tomoyo_security_ops is a "struct security_operations" which is used for
* registering TOMOYO.
*/
-static struct security_hook_list tomoyo_hooks[] = {
+static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(cred_alloc_blank, tomoyo_cred_alloc_blank),
LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
LSM_HOOK_INIT(cred_transfer, tomoyo_cred_transfer),
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 0309f21..70aa64c 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -414,7 +414,7 @@
return rc;
}
-static struct security_hook_list yama_hooks[] = {
+static struct security_hook_list yama_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),
LSM_HOOK_INIT(task_prctl, yama_task_prctl),
diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
index 34227a0..a253aea 100644
--- a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
+++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
@@ -1376,15 +1376,19 @@
struct snd_info_entry *version_entry;
struct msm_sdw_priv *msm_sdw;
struct snd_soc_card *card;
+ char name[80];
if (!codec_root || !codec)
return -EINVAL;
msm_sdw = snd_soc_codec_get_drvdata(codec);
card = codec->component.card;
+
+ snprintf(name, sizeof(name), "%x.%s", (u32)msm_sdw->sdw_base_addr,
+ "msm-sdw-codec");
msm_sdw->entry = snd_info_create_subdir(codec_root->module,
- "152c1000.msm-sdw-codec",
- codec_root);
+ (const char *)name,
+ codec_root);
if (!msm_sdw->entry) {
dev_err(codec->dev, "%s: failed to create msm_sdw entry\n",
__func__);
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index a6d46ae..6cc9f8c 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -417,22 +417,23 @@
/* Go through the list of segments and download one by one */
list_for_each_entry(seg, wdsp->seg_list, list) {
ret = wdsp_load_each_segment(wdsp, seg);
- if (ret < 0) {
- wdsp_broadcast_event_downseq(wdsp,
- WDSP_EVENT_DLOAD_FAILED,
- NULL);
+ if (ret)
goto dload_error;
- }
}
+ /* Flush the list before setting status and notifying components */
+ wdsp_flush_segment_list(wdsp->seg_list);
+
WDSP_SET_STATUS(wdsp, status);
/* Notify all components that image is downloaded */
wdsp_broadcast_event_downseq(wdsp, post, NULL);
+done:
+ return ret;
dload_error:
wdsp_flush_segment_list(wdsp->seg_list);
-done:
+ wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL);
return ret;
}
@@ -486,10 +487,14 @@
/* Make sure wdsp is in good state */
if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) {
WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
+ /*
+ * Acquire SSR mutex lock to make sure enablement of DSP
+ * does not race with SSR handling.
+ */
+ WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
/* Download the read-write sections of image */
ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE);
if (ret < 0) {
@@ -510,6 +515,7 @@
wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL);
WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED);
done:
+ WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
return ret;
}
diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
index 8da0425..b62f26c 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
+++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
@@ -763,10 +763,6 @@
case WDSP_EVENT_DLOAD_FAILED:
case WDSP_EVENT_POST_SHUTDOWN:
- if (event == WDSP_EVENT_POST_DLOAD_CODE)
- /* Mark DSP online since code download is complete */
- wcd_cntl_change_online_state(cntl, 1);
-
/* Disable CPAR */
wcd_cntl_cpar_ctrl(cntl, false);
/* Disable all the clocks */
@@ -775,6 +771,10 @@
dev_err(codec->dev,
"%s: Failed to disable clocks, err = %d\n",
__func__, ret);
+
+ if (event == WDSP_EVENT_POST_DLOAD_CODE)
+ /* Mark DSP online since code download is complete */
+ wcd_cntl_change_online_state(cntl, 1);
break;
case WDSP_EVENT_PRE_DLOAD_DATA:
diff --git a/sound/soc/codecs/wsa881x.h b/sound/soc/codecs/wsa881x.h
index be234ac..fbc60d8 100644
--- a/sound/soc/codecs/wsa881x.h
+++ b/sound/soc/codecs/wsa881x.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 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
@@ -20,9 +20,10 @@
#define WSA881X_MAX_SWR_PORTS 4
+#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
- u8 num_port, unsigned int *ch_mask,
- unsigned int *ch_rate);
+ u8 num_port, unsigned int *ch_mask,
+ unsigned int *ch_rate);
extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE];
extern struct regmap_config wsa881x_regmap_config;
@@ -31,4 +32,25 @@
struct snd_soc_codec *codec);
void wsa881x_regmap_defaults(struct regmap *regmap, u8 version);
+#else
+extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
+ u8 num_port, unsigned int *ch_mask,
+ unsigned int *ch_rate)
+{
+ return 0;
+}
+
+extern int wsa881x_codec_info_create_codec_entry(
+ struct snd_info_entry *codec_root,
+ struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+void wsa881x_regmap_defaults(struct regmap *regmap, u8 version)
+{
+}
+
+#endif
+
#endif /* _WSA881X_H */
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 30a4d59..89a9cc2 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -2376,8 +2376,20 @@
.rate_min = 8000,
.rate_max = 384000,
},
+ .capture = {
+ .stream_name = "MultiMedia10 Capture",
+ .aif_name = "MM_UL10",
+ .rates = (SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
.ops = &msm_fe_Multimedia_dai_ops,
- .compress_new = snd_soc_new_compress,
.name = "MultiMedia10",
.probe = fe_dai_probe,
},
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index 174db28..05b7d30 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -5036,12 +5036,13 @@
.id = MSM_FRONTEND_DAI_MULTIMEDIA7,
},
{
- .name = MSM_DAILINK_NAME(Compress3),
- .stream_name = "Compress3",
+ .name = MSM_DAILINK_NAME(MultiMedia10),
+ .stream_name = "MultiMedia10",
.cpu_dai_name = "MultiMedia10",
- .platform_name = "msm-compress-dsp",
+ .platform_name = "msm-pcm-dsp.1",
.dynamic = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
index 9f08222..9b845ee 100644
--- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
@@ -154,7 +154,7 @@
MAX_INBAND_PARAM_SZ,
"VIRT ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -182,7 +182,7 @@
MAX_INBAND_PARAM_SZ,
"VIRT STRENGTH", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -210,7 +210,7 @@
MAX_INBAND_PARAM_SZ,
"VIRT OUT_TYPE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -238,7 +238,7 @@
MAX_INBAND_PARAM_SZ,
"VIRT GAIN_ADJUST", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_VIRTUALIZER;
*updt_params++ =
@@ -316,7 +316,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -344,7 +344,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_MODE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -372,7 +372,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_PRESET", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -400,7 +400,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_WET_MIX", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -428,7 +428,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_GAIN_ADJUST", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -456,7 +456,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -484,7 +484,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_ROOM_HF_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -512,7 +512,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_TIME", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -540,7 +540,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_DECAY_HF_RATIO", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -568,7 +568,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -596,7 +596,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_REFLECTIONS_DELAY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -624,7 +624,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_LEVEL", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -652,7 +652,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_DELAY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -680,7 +680,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_DIFFUSION", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -708,7 +708,7 @@
MAX_INBAND_PARAM_SZ,
"REVERB_DENSITY", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_REVERB;
*updt_params++ =
@@ -787,7 +787,7 @@
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -815,7 +815,7 @@
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_MODE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -843,7 +843,7 @@
MAX_INBAND_PARAM_SZ,
"BASS_BOOST_STRENGTH", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_BASS_BOOST;
*updt_params++ =
@@ -920,7 +920,7 @@
MAX_INBAND_PARAM_SZ,
"PBE_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@@ -946,7 +946,7 @@
MAX_INBAND_PARAM_SZ,
"PBE_PARAM", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_PBE;
*updt_params++ =
@@ -1031,7 +1031,7 @@
MAX_INBAND_PARAM_SZ,
"EQ_ENABLE", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1099,7 +1099,7 @@
MAX_INBAND_PARAM_SZ,
"EQ_CONFIG", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1150,7 +1150,7 @@
MAX_INBAND_PARAM_SZ,
"EQ_BAND_INDEX", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1182,7 +1182,7 @@
MAX_INBAND_PARAM_SZ,
"EQ_SINGLE_BAND_FREQ", rc);
if (rc != 0)
- break;
+ goto invalid_config;
*updt_params++ =
AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
*updt_params++ =
@@ -1271,7 +1271,7 @@
"VOLUME/VOLUME2_GAIN_2CH",
rc);
if (rc != 0)
- break;
+ goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;
@@ -1320,7 +1320,7 @@
"VOLUME/VOLUME2_GAIN_MASTER",
rc);
if (rc != 0)
- break;
+ goto invalid_config;
if (instance == SOFT_VOLUME_INSTANCE_2)
*updt_params++ =
ASM_MODULE_ID_VOL_CTRL2;
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index 3a6cbe6..ef3475c 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -1682,7 +1682,7 @@
dev_err(rtd->dev,
"%s REG_SND_MODEL failed err %d\n",
__func__, err);
- return err;
+ goto done;
}
break;
case SNDRV_LSM_SET_PARAMS: {
@@ -1852,13 +1852,15 @@
dev_err(rtd->dev,
"%s: Invalid params event_status_v3\n",
__func__);
- return -EINVAL;
+ err = -EINVAL;
+ goto done;
}
if (copy_from_user(&userarg, arg, sizeof(userarg))) {
dev_err(rtd->dev,
"%s: err copyuser event_status_v3\n",
__func__);
- return -EFAULT;
+ err = -EFAULT;
+ goto done;
}
if (userarg.payload_size >
@@ -1866,7 +1868,8 @@
pr_err("%s: payload_size %d is invalid, max allowed = %d\n",
__func__, userarg.payload_size,
LISTEN_MAX_STATUS_PAYLOAD_SIZE);
- return -EINVAL;
+ err = -EINVAL;
+ goto done;
}
size = sizeof(struct snd_lsm_event_status_v3) +
@@ -1876,7 +1879,8 @@
dev_err(rtd->dev,
"%s: Allocation failed event status size %d\n",
__func__, size);
- return -EFAULT;
+ err = -EFAULT;
+ goto done;
}
user->payload_size = userarg.payload_size;
err = msm_lsm_ioctl_shared(substream, cmd, user);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index ef50d92..16f82ce 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1093,7 +1093,7 @@
port_type = MSM_AFE_PORT_TYPE_RX;
} else if (stream_type == SNDRV_PCM_STREAM_CAPTURE) {
session_type = SESSION_TYPE_TX;
- if (passthr_mode != LEGACY_PCM)
+ if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN))
path_type = ADM_PATH_COMPRESSED_TX;
else
path_type = ADM_PATH_LIVE_REC;
@@ -3645,6 +3645,11 @@
msm_route_ec_ref_rx_enum[0],
msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+static const struct snd_kcontrol_new ext_ec_ref_mux_ul10 =
+ SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL10 MUX Mux",
+ msm_route_ec_ref_rx_enum[0],
+ msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+
static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 =
SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux",
msm_route_ec_ref_rx_enum[0],
@@ -7251,6 +7256,59 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new mmul10_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
@@ -11489,6 +11547,7 @@
SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0),
@@ -12225,6 +12284,8 @@
mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0,
mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)),
+ SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0,
+ mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0,
mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0,
@@ -12557,6 +12618,8 @@
&ext_ec_ref_mux_ul8),
SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0,
&ext_ec_ref_mux_ul9),
+ SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0,
+ &ext_ec_ref_mux_ul10),
SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0,
&ext_ec_ref_mux_ul16),
SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0,
@@ -12810,9 +12873,11 @@
{"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
+ {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -13379,6 +13444,7 @@
{"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"},
+ {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
@@ -13395,17 +13461,21 @@
{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
{"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
{"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"},
{"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"},
+ {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"},
{"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
{"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"},
{"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"},
{"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"},
{"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"},
+ {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"},
{"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"},
{"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"},
{"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"},
+ {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"},
{"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"},
{"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"},
@@ -13418,13 +13488,16 @@
{"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
{"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
{"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
+ {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
{"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"},
{"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
@@ -13559,6 +13632,14 @@
{"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
+ {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
+ {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
+ {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"},
+ {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
{"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -13586,6 +13667,7 @@
{"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
{"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
{"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
+ {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
{"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -13682,6 +13764,7 @@
{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
@@ -13701,6 +13784,7 @@
{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"},
@@ -13716,6 +13800,7 @@
{"MM_UL6", NULL, "MultiMedia6 Mixer"},
{"MM_UL8", NULL, "MultiMedia8 Mixer"},
{"MM_UL9", NULL, "MultiMedia9 Mixer"},
+ {"MM_UL10", NULL, "MultiMedia10 Mixer"},
{"MM_UL16", NULL, "MultiMedia16 Mixer"},
{"MM_UL17", NULL, "MultiMedia17 Mixer"},
{"MM_UL18", NULL, "MultiMedia18 Mixer"},
@@ -14104,6 +14189,16 @@
{"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"},
+ {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"},
+ {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"},
+ {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"},
+ {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -14127,6 +14222,7 @@
{"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"},
{"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"},
{"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"},
+ {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"},
{"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"},
{"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"},
{"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"},
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 3aaaa35..4c3a3a1 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -21,6 +21,8 @@
#include <linux/qdsp6v2/apr.h>
#include <sound/q6core.h>
#include <sound/audio_cal_utils.h>
+#include <sound/adsp_err.h>
+#include <sound/apr_audio-v2.h>
#define TIMEOUT_MS 1000
/*
@@ -36,16 +38,30 @@
CORE_MAX_CAL
};
+enum ver_query_status {
+ VER_QUERY_UNATTEMPTED,
+ VER_QUERY_UNSUPPORTED,
+ VER_QUERY_SUPPORTED
+};
+
+struct q6core_avcs_ver_info {
+ enum ver_query_status status;
+ struct avcs_fwk_ver_info ver_info;
+};
+
struct q6core_str {
struct apr_svc *core_handle_q;
wait_queue_head_t bus_bw_req_wait;
wait_queue_head_t cmd_req_wait;
+ wait_queue_head_t avcs_fwk_ver_req_wait;
u32 bus_bw_resp_received;
enum cmd_flags {
FLAG_NONE,
FLAG_CMDRSP_LICENSE_RESULT
} cmd_resp_received_flag;
+ u32 avcs_fwk_ver_resp_received;
struct mutex cmd_lock;
+ struct mutex ver_lock;
union {
struct avcs_cmdrsp_get_license_validation_result
cmdrsp_license_result;
@@ -54,6 +70,7 @@
struct cal_type_data *cal_data[CORE_MAX_CAL];
uint32_t mem_map_cal_handle;
int32_t adsp_status;
+ struct q6core_avcs_ver_info q6core_avcs_ver_info;
};
static struct q6core_str q6core_lcl;
@@ -65,9 +82,61 @@
};
static struct generic_get_data_ *generic_get_data;
+static int parse_fwk_version_info(uint32_t *payload)
+{
+ size_t fwk_ver_size;
+ size_t svc_size;
+ int num_services;
+ int ret = 0;
+
+ pr_debug("%s: Payload info num services %d\n",
+ __func__, payload[4]);
+ /*
+ * payload1[4] is the number of services running on DSP
+ * Based on this info, we copy the payload into core
+ * avcs version info structure.
+ */
+ num_services = payload[4];
+ q6core_lcl.q6core_avcs_ver_info.ver_info.avcs_fwk_version.
+ num_services = num_services;
+ if (num_services > VSS_MAX_AVCS_NUM_SERVICES) {
+ pr_err("%s: num_services: %d greater than max services: %d\n",
+ __func__, num_services, VSS_MAX_AVCS_NUM_SERVICES);
+ ret = -EINVAL;
+ goto done;
+ }
+ fwk_ver_size = sizeof(struct avcs_get_fwk_version);
+ svc_size = num_services * sizeof(struct avs_svc_api_info);
+ /*
+ * Dynamically allocate memory for all
+ * the services based on num_services
+ */
+ q6core_lcl.q6core_avcs_ver_info.ver_info.services = NULL;
+ q6core_lcl.q6core_avcs_ver_info.ver_info.services =
+ kzalloc(svc_size, GFP_ATOMIC);
+ if (q6core_lcl.q6core_avcs_ver_info.ver_info.services == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ /*
+ * memcpy is done twice because the memory allocated for
+ * q6core_lcl.q6core_avcs_ver_info.ver_info is not
+ * contiguous.
+ */
+ memcpy(&q6core_lcl.q6core_avcs_ver_info.ver_info,
+ (uint8_t *)payload, fwk_ver_size);
+ memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info.services,
+ (uint8_t *)&payload[sizeof(struct avcs_get_fwk_version)/
+ sizeof(uint32_t)], svc_size);
+ ret = 0;
+done:
+ return ret;
+}
+
static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
{
uint32_t *payload1;
+ int ret = 0;
if (data == NULL) {
pr_err("%s: data argument is null\n", __func__);
@@ -118,6 +187,17 @@
q6core_lcl.bus_bw_resp_received = 1;
wake_up(&q6core_lcl.bus_bw_req_wait);
break;
+ case AVCS_CMD_GET_FWK_VERSION:
+ pr_debug("%s: Cmd = AVCS_CMD_GET_FWK_VERSION status[%s]\n",
+ __func__, adsp_err_get_err_str(payload1[1]));
+ /* ADSP status to match Linux error standard */
+ q6core_lcl.adsp_status = -payload1[1];
+ if (payload1[1] == ADSP_EUNSUPPORTED)
+ q6core_lcl.q6core_avcs_ver_info.status =
+ VER_QUERY_UNSUPPORTED;
+ q6core_lcl.avcs_fwk_ver_resp_received = 1;
+ wake_up(&q6core_lcl.avcs_fwk_ver_req_wait);
+ break;
default:
pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n",
__func__,
@@ -130,7 +210,7 @@
case RESET_EVENTS:{
pr_debug("%s: Reset event received in Core service\n",
__func__);
- apr_reset(q6core_lcl.core_handle_q);
+ /* no reset done as the data will not change after SSR*/
q6core_lcl.core_handle_q = NULL;
break;
}
@@ -161,6 +241,18 @@
q6core_lcl.cmd_resp_received_flag = FLAG_CMDRSP_LICENSE_RESULT;
wake_up(&q6core_lcl.cmd_req_wait);
break;
+ case AVCS_CMDRSP_GET_FWK_VERSION:
+ pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n",
+ __func__);
+ payload1 = data->payload;
+ q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED;
+ q6core_lcl.avcs_fwk_ver_resp_received = 1;
+ ret = parse_fwk_version_info(payload1);
+ if (ret < 0)
+ pr_err("%s: Failed to parse payload:%d\n",
+ __func__, ret);
+ wake_up(&q6core_lcl.avcs_fwk_ver_req_wait);
+ break;
default:
pr_err("%s: Message id from adsp core svc: 0x%x\n",
__func__, data->opcode);
@@ -217,6 +309,157 @@
return NULL;
}
+static int q6core_send_get_avcs_fwk_ver_cmd(void)
+{
+ struct apr_hdr avcs_ver_cmd;
+ int ret;
+
+ avcs_ver_cmd.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ avcs_ver_cmd.pkt_size = sizeof(struct apr_hdr);
+ avcs_ver_cmd.src_port = 0;
+ avcs_ver_cmd.dest_port = 0;
+ avcs_ver_cmd.token = 0;
+ avcs_ver_cmd.opcode = AVCS_CMD_GET_FWK_VERSION;
+
+ q6core_lcl.adsp_status = 0;
+ q6core_lcl.avcs_fwk_ver_resp_received = 0;
+
+ ret = apr_send_pkt(q6core_lcl.core_handle_q,
+ (uint32_t *) &avcs_ver_cmd);
+ if (ret < 0) {
+ pr_err("%s: failed to send apr packet, ret=%d\n", __func__,
+ ret);
+ goto done;
+ }
+
+ ret = wait_event_timeout(q6core_lcl.avcs_fwk_ver_req_wait,
+ (q6core_lcl.avcs_fwk_ver_resp_received == 1),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout for AVCS fwk version info\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (q6core_lcl.adsp_status < 0) {
+ /*
+ * adsp_err_get_err_str expects a positive value but we store
+ * the DSP error as negative to match the Linux error standard.
+ * Pass in the negated value so adsp_err_get_err_str returns
+ * the correct string.
+ */
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(-q6core_lcl.adsp_status));
+ ret = adsp_err_get_lnx_err_code(q6core_lcl.adsp_status);
+ goto done;
+ }
+
+ ret = 0;
+
+done:
+ return ret;
+}
+
+int q6core_get_service_version(uint32_t service_id,
+ struct avcs_fwk_ver_info *ver_info,
+ size_t size)
+{
+ int i;
+ uint32_t num_services;
+ size_t svc_size;
+
+ svc_size = q6core_get_avcs_service_size(service_id);
+ if (svc_size != size) {
+ pr_err("%s: Expected size: %ld, Provided size: %ld",
+ __func__, svc_size, size);
+ return -EINVAL;
+ }
+
+ num_services =
+ q6core_lcl.q6core_avcs_ver_info.ver_info.
+ avcs_fwk_version.num_services;
+
+ if (ver_info == NULL) {
+ pr_err("%s: NULL parameter ver_info\n", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(ver_info, &q6core_lcl.q6core_avcs_ver_info.
+ ver_info.avcs_fwk_version, sizeof(struct avcs_get_fwk_version));
+
+ if (service_id == AVCS_SERVICE_ID_ALL) {
+ memcpy(&ver_info->services[0], &q6core_lcl.
+ q6core_avcs_ver_info.ver_info.services[0],
+ (num_services * sizeof(struct avs_svc_api_info)));
+ } else {
+ for (i = 0; i < num_services; i++) {
+ if (q6core_lcl.q6core_avcs_ver_info.
+ ver_info.services[i].service_id == service_id) {
+ memcpy(&ver_info->services[0],
+ &q6core_lcl.q6core_avcs_ver_info.
+ ver_info.services[i], size);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(q6core_get_service_version);
+
+size_t q6core_get_avcs_service_size(uint32_t service_id)
+{
+ int ret = 0;
+ uint32_t num_services;
+
+ num_services =
+ q6core_lcl.q6core_avcs_ver_info.ver_info.
+ avcs_fwk_version.num_services;
+
+ mutex_lock(&(q6core_lcl.ver_lock));
+ pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__,
+ q6core_lcl.q6core_avcs_ver_info.status);
+
+ switch (q6core_lcl.q6core_avcs_ver_info.status) {
+ case VER_QUERY_SUPPORTED:
+ pr_debug("%s: AVCS FWK version query already attempted\n",
+ __func__);
+ ret = num_services * sizeof(struct avs_svc_api_info);
+ break;
+ case VER_QUERY_UNSUPPORTED:
+ ret = -EOPNOTSUPP;
+ break;
+ case VER_QUERY_UNATTEMPTED:
+ pr_debug("%s: Attempting AVCS FWK version query\n", __func__);
+ if (q6core_is_adsp_ready()) {
+ ret = q6core_send_get_avcs_fwk_ver_cmd();
+ if (ret == 0)
+ ret = num_services *
+ sizeof(struct avs_svc_api_info);
+ } else {
+ pr_err("%s: ADSP is not ready to query version\n",
+ __func__);
+ ret = -ENODEV;
+ }
+ break;
+ default:
+ pr_err("%s: Invalid version query status %d\n", __func__,
+ q6core_lcl.q6core_avcs_ver_info.status);
+ ret = -EINVAL;
+ break;
+ }
+ mutex_unlock(&(q6core_lcl.ver_lock));
+
+ if (service_id != AVCS_SERVICE_ID_ALL)
+ return sizeof(struct avs_svc_api_info);
+
+ return ret;
+}
+EXPORT_SYMBOL(q6core_get_avcs_service_size);
+
int32_t core_set_license(uint32_t key, uint32_t module_id)
{
struct avcs_cmd_set_license *cmd_setl = NULL;
@@ -827,18 +1070,16 @@
static int __init core_init(void)
{
+ memset(&q6core_lcl, 0, sizeof(struct q6core_str));
init_waitqueue_head(&q6core_lcl.bus_bw_req_wait);
- q6core_lcl.bus_bw_resp_received = 0;
-
- q6core_lcl.core_handle_q = NULL;
-
init_waitqueue_head(&q6core_lcl.cmd_req_wait);
+ init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait);
q6core_lcl.cmd_resp_received_flag = FLAG_NONE;
mutex_init(&q6core_lcl.cmd_lock);
- q6core_lcl.mem_map_cal_handle = 0;
- q6core_lcl.adsp_status = 0;
+ mutex_init(&q6core_lcl.ver_lock);
q6core_init_cal_data();
+
return 0;
}
module_init(core_init);
@@ -846,6 +1087,7 @@
static void __exit core_exit(void)
{
mutex_destroy(&q6core_lcl.cmd_lock);
+ mutex_destroy(&q6core_lcl.ver_lock);
q6core_delete_cal_data();
}
module_exit(core_exit);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 15c9e13..0d444d0 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -21,6 +21,7 @@
#include <soc/qcom/socinfo.h>
#include <linux/qdsp6v2/apr_tal.h>
+#include "sound/q6core.h"
#include "sound/q6audio-v2.h"
#include "sound/apr_audio-v2.h"
#include "sound/q6afe-v2.h"
@@ -33,6 +34,9 @@
#define CMD_STATUS_SUCCESS 0
#define CMD_STATUS_FAIL 1
+#define NUM_CHANNELS_MONO 1
+#define NUM_CHANNELS_STEREO 2
+#define CVP_VERSION_2 2
enum {
VOC_TOKEN_NONE,
@@ -83,6 +87,11 @@
static int voice_send_cvp_media_format_cmd(struct voice_data *v,
uint32_t param_type);
static int voice_send_cvp_topology_commit_cmd(struct voice_data *v);
+static int voice_send_cvp_channel_info_cmd(struct voice_data *v);
+static int voice_send_cvp_channel_info_v2(struct voice_data *v,
+ uint32_t param_type);
+static int voice_get_avcs_version_per_service(uint32_t service_id);
+
static int voice_cvs_stop_playback(struct voice_data *v);
static int voice_cvs_start_playback(struct voice_data *v);
@@ -3793,6 +3802,295 @@
return result;
}
+static int voice_send_cvp_channel_info_v2(struct voice_data *v,
+ uint32_t param_type)
+{
+ int ret;
+ struct cvp_set_channel_info_cmd_v2 cvp_set_channel_info_cmd;
+ void *apr_cvp;
+ u16 cvp_handle;
+ struct vss_icommon_param_data_channel_info_v2_t
+ *channel_info_param_data =
+ &cvp_set_channel_info_cmd.
+ cvp_set_ch_info_param_v2.param_data;
+ struct vss_param_vocproc_dev_channel_info_t *channel_info =
+ &channel_info_param_data->channel_info;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ apr_cvp = common.apr_q6_cvp;
+ if (!apr_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cvp_handle = voice_get_cvp_handle(v);
+ memset(&cvp_set_channel_info_cmd, 0, sizeof(cvp_set_channel_info_cmd));
+
+ cvp_set_channel_info_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ cvp_set_channel_info_cmd.hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_set_channel_info_cmd) - APR_HDR_SIZE);
+ cvp_set_channel_info_cmd.hdr.src_svc = 0;
+ cvp_set_channel_info_cmd.hdr.src_domain = APR_DOMAIN_APPS;
+ cvp_set_channel_info_cmd.hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ cvp_set_channel_info_cmd.hdr.dest_svc = 0;
+ cvp_set_channel_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
+ cvp_set_channel_info_cmd.hdr.dest_port = cvp_handle;
+ cvp_set_channel_info_cmd.hdr.token = 0;
+ cvp_set_channel_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
+
+ cvp_set_channel_info_cmd.cvp_set_ch_info_param_v2.mem_size =
+ sizeof(struct vss_icommon_param_data_channel_info_v2_t);
+
+ channel_info_param_data->module_id = VSS_MODULE_CVD_GENERIC;
+ channel_info_param_data->param_size =
+ sizeof(struct vss_param_vocproc_dev_channel_info_t);
+
+ /* Device specific data */
+ switch (param_type) {
+ case RX_PATH:
+ channel_info_param_data->param_id =
+ VSS_PARAM_VOCPROC_RX_CHANNEL_INFO;
+ channel_info->num_channels = v->dev_rx.no_of_channels;
+ channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
+ break;
+
+ case TX_PATH:
+ channel_info_param_data->param_id =
+ VSS_PARAM_VOCPROC_TX_CHANNEL_INFO;
+ channel_info->num_channels = v->dev_tx.no_of_channels;
+ channel_info->bits_per_sample = v->dev_tx.bits_per_sample;
+ break;
+
+ case EC_REF_PATH:
+ channel_info_param_data->param_id =
+ VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO;
+ channel_info->num_channels = v->dev_rx.no_of_channels;
+ channel_info->bits_per_sample = v->dev_rx.bits_per_sample;
+ break;
+ default:
+ pr_err("%s: Invalid param type\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (channel_info->num_channels == NUM_CHANNELS_MONO) {
+ channel_info->channel_mapping[0] = PCM_CHANNEL_FC;
+ } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) {
+ channel_info->channel_mapping[0] = PCM_CHANNEL_FL;
+ channel_info->channel_mapping[1] = PCM_CHANNEL_FR;
+ } else {
+ pr_err("%s: Unsupported num channels: %d\n",
+ __func__, channel_info->num_channels);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_channel_info_cmd);
+ if (ret < 0) {
+ pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2\n",
+ __func__);
+ goto done;
+ }
+
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
+ adsp_err_get_err_str(v->async_err), cvp_handle);
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+ ret = 0;
+done:
+ return ret;
+}
+
+static int voice_send_cvp_channel_info_cmd(struct voice_data *v)
+{
+ int ret = 0;
+
+ ret = voice_send_cvp_channel_info_v2(v, RX_PATH);
+ if (ret < 0) {
+ pr_err("%s: Error in sending cvp_channel_info RX: %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = voice_send_cvp_channel_info_v2(v, TX_PATH);
+ if (ret < 0) {
+ pr_err("%s: Error in sending cvp_channel_info TX: %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = voice_send_cvp_channel_info_v2(v, EC_REF_PATH);
+ if (ret < 0) {
+ pr_err("%s: Error in sending cvp_channel_info EC Ref: %d\n",
+ __func__, ret);
+ goto done;
+ }
+done:
+ return ret;
+}
+
+static int voice_send_cvp_mfc_config_v2(struct voice_data *v)
+{
+ int ret;
+ struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd;
+ void *apr_cvp;
+ u16 cvp_handle;
+ struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data =
+ &cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data;
+ struct vss_param_mfc_config_info_t *mfc_config_info =
+ &cvp_config_param_data->mfc_config_info;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ apr_cvp = common.apr_q6_cvp;
+ if (!apr_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cvp_handle = voice_get_cvp_handle(v);
+ memset(&cvp_set_mfc_config_cmd, 0, sizeof(cvp_set_mfc_config_cmd));
+
+ cvp_set_mfc_config_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ cvp_set_mfc_config_cmd.hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_set_mfc_config_cmd) - APR_HDR_SIZE);
+ cvp_set_mfc_config_cmd.hdr.src_svc = 0;
+ cvp_set_mfc_config_cmd.hdr.src_domain = APR_DOMAIN_APPS;
+ cvp_set_mfc_config_cmd.hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ cvp_set_mfc_config_cmd.hdr.dest_svc = 0;
+ cvp_set_mfc_config_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
+ cvp_set_mfc_config_cmd.hdr.dest_port = cvp_handle;
+ cvp_set_mfc_config_cmd.hdr.token = 0;
+ cvp_set_mfc_config_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
+ cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.mem_size =
+ sizeof(struct vss_icommon_param_data_mfc_config_v2_t);
+
+ cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC;
+ cvp_config_param_data->param_id =
+ AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
+ cvp_config_param_data->param_size =
+ sizeof(struct vss_param_mfc_config_info_t);
+
+ mfc_config_info->num_channels = v->dev_rx.no_of_channels;
+ mfc_config_info->bits_per_sample = 16;
+ mfc_config_info->sample_rate = v->dev_rx.sample_rate;
+
+ if (mfc_config_info->num_channels == NUM_CHANNELS_MONO) {
+ mfc_config_info->channel_type[0] = PCM_CHANNEL_FC;
+ } else if (mfc_config_info->num_channels == NUM_CHANNELS_STEREO) {
+ mfc_config_info->channel_type[0] = PCM_CHANNEL_FL;
+ mfc_config_info->channel_type[1] = PCM_CHANNEL_FR;
+ } else {
+ pr_err("%s: Unsupported num channels: %d\n",
+ __func__, mfc_config_info->num_channels);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_mfc_config_cmd);
+ if (ret < 0) {
+ pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n",
+ __func__, ret);
+ goto done;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
+ adsp_err_get_err_str(v->async_err), cvp_handle);
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+ ret = 0;
+done:
+ return ret;
+}
+
+static int voice_send_cvp_mfc_config_cmd(struct voice_data *v)
+{
+ int ret = 0;
+
+ if (common.cvp_version >= CVP_VERSION_2) {
+ ret = voice_send_cvp_mfc_config_v2(v);
+ } else {
+ pr_warn("%s: CVP Version not supported\n", __func__);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int voice_get_avcs_version_per_service(uint32_t service_id)
+{
+ int ret = 0;
+ size_t svc_size;
+ struct avcs_fwk_ver_info ver_info = {{0}, NULL};
+
+ if (service_id == AVCS_SERVICE_ID_ALL) {
+ pr_err("%s: Invalid service id: %d", __func__,
+ AVCS_SERVICE_ID_ALL);
+ return -EINVAL;
+ }
+
+ svc_size = sizeof(struct avs_svc_api_info);
+ ver_info.services = kzalloc(svc_size, GFP_KERNEL);
+ if (ver_info.services == NULL)
+ return -ENOMEM;
+
+ ret = q6core_get_service_version(service_id, &ver_info, svc_size);
+ if (ret < 0)
+ goto done;
+
+ ret = ver_info.services[0].api_version;
+ common.is_avcs_version_queried = true;
+done:
+ kfree(ver_info.services);
+ return ret;
+}
+
static int voice_setup_vocproc(struct voice_data *v)
{
int ret = 0;
@@ -3803,6 +4101,18 @@
goto fail;
}
+ if (common.is_avcs_version_queried == false)
+ common.cvp_version = voice_get_avcs_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_CVP_V);
+
+ if (common.cvp_version < 0) {
+ pr_err("%s: Invalid CVP version %d\n",
+ __func__, common.cvp_version);
+ ret = -EINVAL;
+ goto fail;
+ }
+ pr_debug("%s: CVP Version %d\n", __func__, common.cvp_version);
+
ret = voice_send_cvp_media_fmt_info_cmd(v);
if (ret < 0) {
pr_err("%s: Set media format info failed err:%d\n", __func__,
@@ -3817,6 +4127,15 @@
goto fail;
}
+ /* Send MFC config only when the no of channels are more than 1 */
+ if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
+ ret = voice_send_cvp_mfc_config_cmd(v);
+ if (ret < 0) {
+ pr_warn("%s: Set mfc config failed err:%d\n",
+ __func__, ret);
+ }
+ }
+
voice_send_cvs_register_cal_cmd(v);
voice_send_cvp_register_dev_cfg_cmd(v);
voice_send_cvp_register_cal_cmd(v);
@@ -3962,11 +4281,18 @@
static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
{
- int ret;
+ int ret = 0;
- ret = voice_send_cvp_device_channels_cmd(v);
- if (ret < 0)
+ if (common.cvp_version < CVP_VERSION_2)
+ ret = voice_send_cvp_device_channels_cmd(v);
+ else
+ ret = voice_send_cvp_channel_info_cmd(v);
+
+ if (ret < 0) {
+ pr_err("%s: Set channel info failed err: %d\n", __func__,
+ ret);
goto done;
+ }
if (voice_get_cvd_int_version(common.cvd_version) >=
CVD_INT_VERSION_2_3) {
@@ -3994,7 +4320,7 @@
void *apr_cvp;
u16 cvp_handle;
struct vss_icommon_param_data_t *media_fmt_param_data =
- &cvp_set_media_format_cmd.cvp_set_param_v2.param_data;
+ &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data;
struct vss_param_endpoint_media_format_info_t *media_fmt_info =
&media_fmt_param_data->media_format_info;
@@ -4032,7 +4358,7 @@
cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
/* Fill param data */
- cvp_set_media_format_cmd.cvp_set_param_v2.mem_size =
+ cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size =
sizeof(struct vss_icommon_param_data_t);
media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC;
media_fmt_param_data->param_size =
@@ -6197,6 +6523,15 @@
goto done;
}
+ /* Send MFC config only when the no of channels are > 1 */
+ if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) {
+ ret = voice_send_cvp_mfc_config_cmd(v);
+ if (ret < 0) {
+ pr_warn("%s: Set mfc config failed err: %d\n",
+ __func__, ret);
+ }
+ }
+
voice_send_cvp_register_dev_cfg_cmd(v);
voice_send_cvp_register_cal_cmd(v);
voice_send_cvp_register_vol_cal_cmd(v);
@@ -7054,7 +7389,8 @@
case VSS_ICOMMON_CMD_SET_PARAM_V2:
switch (data->token) {
case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN:
- pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n",
+ case VOC_GENERIC_SET_PARAM_TOKEN:
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n",
__func__);
v->cvp_state = CMD_STATUS_SUCCESS;
v->async_err = ptr[1];
@@ -8566,7 +8902,8 @@
common.default_vol_step_val = 0;
common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
-
+ common.cvp_version = 0;
+ common.is_avcs_version_queried = false;
/* Initialize EC Ref media format info */
common.ec_ref_ext = false;
common.ec_media_fmt_info.port_id = AFE_PORT_INVALID;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 74d80be..db48091 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -124,7 +124,7 @@
};
enum {
- VOC_NO_SET_PARAM_TOKEN = 0,
+ VOC_GENERIC_SET_PARAM_TOKEN = 0,
VOC_RTAC_SET_PARAM_TOKEN,
VOC_SET_MEDIA_FORMAT_PARAM_TOKEN,
VOC_SET_PARAM_TOKEN_MAX
@@ -239,6 +239,19 @@
uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
} __packed;
+struct vss_param_vocproc_dev_channel_info_t {
+ uint32_t num_channels;
+ uint32_t bits_per_sample;
+ uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX];
+} __packed;
+
+struct vss_param_mfc_config_info_t {
+ uint32_t sample_rate;
+ uint16_t bits_per_sample;
+ uint16_t num_channels;
+ uint16_t channel_type[VSS_NUM_CHANNELS_MAX];
+} __packed;
+
struct vss_icommon_param_data_t {
/* Valid ID of the module. */
uint32_t module_id;
@@ -260,6 +273,88 @@
};
} __packed;
+struct vss_icommon_param_data_channel_info_v2_t {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+ /*
+ * Data size of the structure relating to the param_id/module_id
+ * combination in uint8_t bytes.
+ */
+ uint16_t param_size;
+ /* This field must be set to zero. */
+ uint16_t reserved;
+ struct vss_param_vocproc_dev_channel_info_t channel_info;
+} __packed;
+
+struct vss_icommon_cmd_set_param_channel_info_v2_t {
+ /*
+ * Pointer to the unique identifier for an address (physical/virtual).
+ *
+ * If the parameter data payload is within the message payload
+ * (in-band), set this field to 0. The parameter data begins at the
+ * specified data payload address.
+ *
+ * If the parameter data is out-of-band, this field is the handle to
+ * the physical address in the shared memory that holds the parameter
+ * data.
+ */
+ uint32_t mem_handle;
+ /*
+ * Location of the parameter data payload.
+ *
+ * The payload is an array of vss_icommon_param_data_t. If the
+ * mem_handle is 0, this field is ignored.
+ */
+ uint64_t mem_address;
+ /* Size of the parameter data payload in bytes. */
+ uint32_t mem_size;
+ struct vss_icommon_param_data_channel_info_v2_t param_data;
+} __packed;
+
+struct vss_icommon_param_data_mfc_config_v2_t {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+ /*
+ * Data size of the structure relating to the param_id/module_id
+ * combination in uint8_t bytes.
+ */
+ uint16_t param_size;
+ /* This field must be set to zero. */
+ uint16_t reserved;
+ struct vss_param_mfc_config_info_t mfc_config_info;
+} __packed;
+
+struct vss_icommon_cmd_set_param_mfc_config_v2_t {
+ /*
+ * Pointer to the unique identifier for an address (physical/virtual).
+ *
+ * If the parameter data payload is within the message payload
+ * (in-band), set this field to 0. The parameter data begins at the
+ * specified data payload address.
+ *
+ * If the parameter data is out-of-band, this field is the handle to
+ * the physical address in the shared memory that holds the parameter
+ * data.
+ */
+
+ uint32_t mem_handle;
+ /*
+ * Location of the parameter data payload.
+ *
+ * The payload is an array of vss_icommon_param_data_t. If the
+ * mem_handle is 0, this field is ignored.
+ */
+ uint64_t mem_address;
+ /* Size of the parameter data payload in bytes. */
+ uint32_t mem_size;
+
+ struct vss_icommon_param_data_mfc_config_v2_t param_data;
+} __packed;
+
/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */
struct vss_icommon_cmd_set_param_v2_t {
/*
@@ -674,6 +769,12 @@
#define VSS_IRECORD_MODE_TX_RX_MIXING 0x00010F7B
/* Select mixed Tx and Rx paths. */
+#define VSS_PARAM_VOCPROC_TX_CHANNEL_INFO 0x0001328E
+
+#define VSS_PARAM_VOCPROC_RX_CHANNEL_INFO 0x0001328F
+
+#define VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO 0x00013290
+
#define VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO 0x00013253
#define VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO 0x00013254
@@ -1485,7 +1586,18 @@
struct cvp_set_media_format_cmd {
struct apr_hdr hdr;
- struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2;
+ struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2;
+} __packed;
+
+struct cvp_set_channel_info_cmd_v2 {
+ struct apr_hdr hdr;
+ struct vss_icommon_cmd_set_param_channel_info_v2_t
+ cvp_set_ch_info_param_v2;
+} __packed;
+
+struct cvp_set_mfc_config_cmd_v2 {
+ struct apr_hdr hdr;
+ struct vss_icommon_cmd_set_param_mfc_config_v2_t cvp_set_mfc_param_v2;
} __packed;
struct cvp_set_vp3_data_cmd {
@@ -1756,6 +1868,8 @@
bool srvcc_rec_flag;
bool is_destroy_cvd;
char cvd_version[CVD_VERSION_STRING_MAX_SIZE];
+ int cvp_version;
+ bool is_avcs_version_queried;
bool is_per_vocoder_cal_enabled;
bool is_sound_focus_resp_success;
bool is_source_tracking_resp_success;
diff --git a/sound/soc/msm/sdm660-ext-dai-links.c b/sound/soc/msm/sdm660-ext-dai-links.c
index 34a6626..68a0f37 100644
--- a/sound/soc/msm/sdm660-ext-dai-links.c
+++ b/sound/soc/msm/sdm660-ext-dai-links.c
@@ -997,13 +997,14 @@
.id = MSM_FRONTEND_DAI_MULTIMEDIA7,
},
{/* hw:x,16 */
- .name = MSM_DAILINK_NAME(Compress3),
- .stream_name = "Compress3",
+ .name = MSM_DAILINK_NAME(MultiMedia10),
+ .stream_name = "MultiMedia10",
.cpu_dai_name = "MultiMedia10",
- .platform_name = "msm-compress-dsp",
+ .platform_name = "msm-pcm-dsp.1",
.dynamic = 1,
.dpcm_capture = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c
index 1402154..14e7308 100644
--- a/sound/soc/msm/sdm660-internal.c
+++ b/sound/soc/msm/sdm660-internal.c
@@ -1915,13 +1915,14 @@
.id = MSM_FRONTEND_DAI_MULTIMEDIA7,
},
{/* hw:x,16 */
- .name = MSM_DAILINK_NAME(Compress3),
- .stream_name = "Compress3",
+ .name = MSM_DAILINK_NAME(MultiMedia10),
+ .stream_name = "MultiMedia10",
.cpu_dai_name = "MultiMedia10",
- .platform_name = "msm-compress-dsp",
+ .platform_name = "msm-pcm-dsp.1",
.dynamic = 1,
.dpcm_capture = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
diff --git a/sound/soc/msm/sdm845.c b/sound/soc/msm/sdm845.c
index 838771c..7a5ccd8 100644
--- a/sound/soc/msm/sdm845.c
+++ b/sound/soc/msm/sdm845.c
@@ -5126,12 +5126,13 @@
.id = MSM_FRONTEND_DAI_MULTIMEDIA7,
},
{
- .name = MSM_DAILINK_NAME(Compress3),
- .stream_name = "Compress3",
+ .name = MSM_DAILINK_NAME(MultiMedia10),
+ .stream_name = "MultiMedia10",
.cpu_dai_name = "MultiMedia10",
- .platform_name = "msm-compress-dsp",
+ .platform_name = "msm-pcm-dsp.1",
.dynamic = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
@@ -6696,16 +6697,18 @@
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,wsa-max-devs", &wsa_max_devs);
if (ret) {
- dev_dbg(&pdev->dev,
+ dev_info(&pdev->dev,
"%s: wsa-max-devs property missing in DT %s, ret = %d\n",
__func__, pdev->dev.of_node->full_name, ret);
- goto err;
+ card->num_aux_devs = 0;
+ return 0;
}
if (wsa_max_devs == 0) {
dev_warn(&pdev->dev,
"%s: Max WSA devices is 0 for this target?\n",
__func__);
- goto err;
+ card->num_aux_devs = 0;
+ return 0;
}
/* Get count of WSA device phandles for this platform */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6b23bf5..4f6c777 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3326,7 +3326,8 @@
*/
void snd_soc_card_change_online_state(struct snd_soc_card *soc_card, int online)
{
- snd_card_change_online_state(soc_card->snd_card, online);
+ if (soc_card && soc_card->snd_card)
+ snd_card_change_online_state(soc_card->snd_card, online);
}
EXPORT_SYMBOL(snd_soc_card_change_online_state);