* Re: [PATCH 1/3] arm64: defconfig: Enable Qualcomm GENI based I2C controller
From: Bjorn Andersson @ 2019-09-03 3:21 UTC (permalink / raw)
To: Lee Jones
Cc: arnd, catalin.marinas, linux-kernel, olof, will, linux-arm-kernel
In-Reply-To: <20190902130724.12030-1-lee.jones@linaro.org>
On Mon 02 Sep 06:07 PDT 2019, Lee Jones wrote:
> Tested on the Lenovo Yoga C630 where this patch enables the
> keyboard, touchpad and touchscreen.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> arch/arm64/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index facf19cc275d..0fe943ac53b5 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -366,6 +366,7 @@ CONFIG_I2C_IMX_LPI2C=y
> CONFIG_I2C_MESON=y
> CONFIG_I2C_MV64XXX=y
> CONFIG_I2C_PXA=y
> +CONFIG_I2C_QCOM_GENI=m
> CONFIG_I2C_QUP=y
> CONFIG_I2C_RK3X=y
> CONFIG_I2C_SH_MOBILE=y
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/3] arm64: defconfig: Enable the EFI Framebuffer
From: Bjorn Andersson @ 2019-09-03 3:22 UTC (permalink / raw)
To: Lee Jones
Cc: arnd, catalin.marinas, linux-kernel, olof, will, linux-arm-kernel
In-Reply-To: <20190902130724.12030-2-lee.jones@linaro.org>
On Mon 02 Sep 06:07 PDT 2019, Lee Jones wrote:
> Tested on the Lenovo Yoga C630 where this patch enables the
> framebuffer (screen/monitor). Without it the device appears
> not to boot.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> arch/arm64/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 0fe943ac53b5..af7ca722b519 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -540,6 +540,7 @@ CONFIG_DRM_LIMA=m
> CONFIG_DRM_PANFROST=m
> CONFIG_FB=y
> CONFIG_FB_MODE_HELPERS=y
> +CONFIG_FB_EFI=y
> CONFIG_BACKLIGHT_GENERIC=m
> CONFIG_BACKLIGHT_PWM=m
> CONFIG_BACKLIGHT_LP855X=m
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 3/3] arm64: defconfig: Enable Qualcomm QUSB2 PHY
From: Bjorn Andersson @ 2019-09-03 3:22 UTC (permalink / raw)
To: Lee Jones
Cc: arnd, catalin.marinas, linux-kernel, olof, will, linux-arm-kernel
In-Reply-To: <20190902130724.12030-3-lee.jones@linaro.org>
On Mon 02 Sep 06:07 PDT 2019, Lee Jones wrote:
> Tested on the Lenovo Yoga C630 where this patch enables USB.
> Without it USB devices are not enumerated.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> arch/arm64/configs/defconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index af7ca722b519..a94d002182ee 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -770,6 +770,7 @@ CONFIG_PHY_HISTB_COMBPHY=y
> CONFIG_PHY_HISI_INNO_USB2=y
> CONFIG_PHY_MVEBU_CP110_COMPHY=y
> CONFIG_PHY_QCOM_QMP=m
> +CONFIG_PHY_QCOM_QUSB2=m
> CONFIG_PHY_QCOM_USB_HS=y
> CONFIG_PHY_RCAR_GEN3_PCIE=y
> CONFIG_PHY_RCAR_GEN3_USB2=y
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 5/7] arm64: tegra: Add Memory controller DT node on T194
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Add Memory controller DT node on T194 and enable it.
This patch is a prerequisite for SMMU enable on T194.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 4 ++++
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 7 +++++++
2 files changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index 62e07e11..4b3441b 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -47,6 +47,10 @@
};
};
+ memory-controller@2c00000 {
+ status = "okay";
+ };
+
serial@3110000 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index adebbbf..d906958 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/reset/tegra194-reset.h>
#include <dt-bindings/power/tegra194-powergate.h>
#include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
+#include <dt-bindings/memory/tegra186-mc.h>
/ {
compatible = "nvidia,tegra194";
@@ -130,6 +131,12 @@
};
};
+ memory-controller@2c00000 {
+ compatible = "nvidia,tegra186-mc";
+ reg = <0x02c00000 0xb0000>;
+ status = "disabled";
+ };
+
uarta: serial@3100000 {
compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
reg = <0x03100000 0x40>;
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 0/7] Nvidia Arm SMMUv2 Implementation
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
Changes in v2:
- Prepare arm_smu_flush_ops for override.
- Remove NVIDIA_SMMUv2 and use ARM_SMMUv2 model as T194 SMMU hasn't modified ARM MMU-500.
- Add T194 specific compatible string - "nvidia,tegra194-smmu"
- Remove tlb_sync hook added in v1 and Override arm_smmu_flush_ops->tlb_sync() from implementation.
- Register implementation specific context/global fault hooks directly for irq handling.
- Update global/context interrupt list in DT and releant fault handling code in arm-smmu-nvidia.c.
- Implement reset hook in arm-smmu-nvidia.c to clear irq status and sync tlb.
v1 - https://lkml.org/lkml/2019/8/29/1588
Krishna Reddy (7):
iommu/arm-smmu: prepare arm_smmu_flush_ops for override
iommu/arm-smmu: add NVIDIA implementation for dual ARM MMU-500 usage
dt-bindings: arm-smmu: Add binding for Tegra194 SMMU
iommu/arm-smmu: Add global/context fault implementation hooks
arm64: tegra: Add Memory controller DT node on T194
arm64: tegra: Add DT node for T194 SMMU
arm64: tegra: enable SMMU for SDHCI and EQOS on T194
.../devicetree/bindings/iommu/arm,smmu.txt | 4 +
MAINTAINERS | 2 +
arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 4 +
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 88 +++++++
drivers/iommu/Makefile | 2 +-
drivers/iommu/arm-smmu-impl.c | 3 +
drivers/iommu/arm-smmu-nvidia.c | 287 +++++++++++++++++++++
drivers/iommu/arm-smmu.c | 27 +-
drivers/iommu/arm-smmu.h | 8 +-
9 files changed, 413 insertions(+), 12 deletions(-)
create mode 100644 drivers/iommu/arm-smmu-nvidia.c
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 1/7] iommu/arm-smmu: prepare arm_smmu_flush_ops for override
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Remove const keyword for arm_smmu_flush_ops in arm_smmu_domain
and replace direct references to arm_smmu_tlb_sync* functions with
arm_smmu_flush_ops->tlb_sync().
This is necessary for vendor specific implementations that
need to override arm_smmu_flush_ops in part or full.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
drivers/iommu/arm-smmu.c | 16 ++++++++--------
drivers/iommu/arm-smmu.h | 4 +++-
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5b93c79..16b5c54 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -52,9 +52,6 @@
*/
#define QCOM_DUMMY_VAL -1
-#define TLB_LOOP_TIMEOUT 1000000 /* 1s! */
-#define TLB_SPIN_COUNT 10
-
#define MSI_IOVA_BASE 0x8000000
#define MSI_IOVA_LENGTH 0x100000
@@ -290,6 +287,8 @@ static void arm_smmu_tlb_sync_vmid(void *cookie)
static void arm_smmu_tlb_inv_context_s1(void *cookie)
{
struct arm_smmu_domain *smmu_domain = cookie;
+ const struct arm_smmu_flush_ops *ops = smmu_domain->flush_ops;
+
/*
* The TLBI write may be relaxed, so ensure that PTEs cleared by the
* current CPU are visible beforehand.
@@ -297,18 +296,19 @@ static void arm_smmu_tlb_inv_context_s1(void *cookie)
wmb();
arm_smmu_cb_write(smmu_domain->smmu, smmu_domain->cfg.cbndx,
ARM_SMMU_CB_S1_TLBIASID, smmu_domain->cfg.asid);
- arm_smmu_tlb_sync_context(cookie);
+ ops->tlb_sync(cookie);
}
static void arm_smmu_tlb_inv_context_s2(void *cookie)
{
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_device *smmu = smmu_domain->smmu;
+ const struct arm_smmu_flush_ops *ops = smmu_domain->flush_ops;
/* See above */
wmb();
arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIVMID, smmu_domain->cfg.vmid);
- arm_smmu_tlb_sync_global(smmu);
+ ops->tlb_sync(cookie);
}
static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size,
@@ -410,7 +410,7 @@ static void arm_smmu_tlb_add_page(struct iommu_iotlb_gather *gather,
ops->tlb_inv_range(iova, granule, granule, true, cookie);
}
-static const struct arm_smmu_flush_ops arm_smmu_s1_tlb_ops = {
+static struct arm_smmu_flush_ops arm_smmu_s1_tlb_ops = {
.tlb = {
.tlb_flush_all = arm_smmu_tlb_inv_context_s1,
.tlb_flush_walk = arm_smmu_tlb_inv_walk,
@@ -421,7 +421,7 @@ static const struct arm_smmu_flush_ops arm_smmu_s1_tlb_ops = {
.tlb_sync = arm_smmu_tlb_sync_context,
};
-static const struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v2 = {
+static struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v2 = {
.tlb = {
.tlb_flush_all = arm_smmu_tlb_inv_context_s2,
.tlb_flush_walk = arm_smmu_tlb_inv_walk,
@@ -432,7 +432,7 @@ static const struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v2 = {
.tlb_sync = arm_smmu_tlb_sync_context,
};
-static const struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v1 = {
+static struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v1 = {
.tlb = {
.tlb_flush_all = arm_smmu_tlb_inv_context_s2,
.tlb_flush_walk = arm_smmu_tlb_inv_walk,
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index b19b6ca..b2d6c7f 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -207,6 +207,8 @@ enum arm_smmu_cbar_type {
/* Maximum number of context banks per SMMU */
#define ARM_SMMU_MAX_CBS 128
+#define TLB_LOOP_TIMEOUT 1000000 /* 1s! */
+#define TLB_SPIN_COUNT 10
/* Shared driver definitions */
enum arm_smmu_arch_version {
@@ -314,7 +316,7 @@ struct arm_smmu_flush_ops {
struct arm_smmu_domain {
struct arm_smmu_device *smmu;
struct io_pgtable_ops *pgtbl_ops;
- const struct arm_smmu_flush_ops *flush_ops;
+ struct arm_smmu_flush_ops *flush_ops;
struct arm_smmu_cfg cfg;
enum arm_smmu_domain_stage stage;
bool non_strict;
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 3/7] dt-bindings: arm-smmu: Add binding for Tegra194 SMMU
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Add binding for NVIDIA's Tegra194 Soc SMMU that is based
on ARM MMU-500.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
Documentation/devicetree/bindings/iommu/arm,smmu.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 3133f3b..1d72fac 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -31,6 +31,10 @@ conditions.
as below, SoC-specific compatibles:
"qcom,sdm845-smmu-500", "arm,mmu-500"
+ NVIDIA SoCs that use more than one ARM MMU-500 together
+ needs following SoC-specific compatibles along with "arm,mmu-500":
+ "nvidia,tegra194-smmu"
+
- reg : Base address and size of the SMMU.
- #global-interrupts : The number of global interrupts exposed by the
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 6/7] arm64: tegra: Add DT node for T194 SMMU
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Add DT node for T194 SMMU to enable SMMU support.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 77 ++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index d906958..5ae3bbf 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -1401,6 +1401,83 @@
0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
};
+ smmu: iommu@12000000 {
+ compatible = "arm,mmu-500","nvidia,tegra194-smmu";
+ reg = <0 0x12000000 0 0x800000>,
+ <0 0x11000000 0 0x800000>,
+ <0 0x10000000 0 0x800000>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ stream-match-mask = <0x7f80>;
+ #global-interrupts = <3>;
+ #iommu-cells = <1>;
+ };
+
sysram@40000000 {
compatible = "nvidia,tegra194-sysram", "mmio-sram";
reg = <0x0 0x40000000 0x0 0x50000>;
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 4/7] iommu/arm-smmu: Add global/context fault implementation hooks
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Add global/context fault hooks to allow NVIDIA SMMU implementation
handle faults across multiple SMMUs.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
drivers/iommu/arm-smmu-nvidia.c | 100 ++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.c | 11 ++++-
drivers/iommu/arm-smmu.h | 3 ++
3 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm-smmu-nvidia.c b/drivers/iommu/arm-smmu-nvidia.c
index ca871dc..2a19d41 100644
--- a/drivers/iommu/arm-smmu-nvidia.c
+++ b/drivers/iommu/arm-smmu-nvidia.c
@@ -143,6 +143,104 @@ static int nsmmu_init_context(struct arm_smmu_domain *smmu_domain)
return 0;
}
+static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
+{
+ return container_of(dom, struct arm_smmu_domain, domain);
+}
+
+static irqreturn_t nsmmu_global_fault_inst(int irq,
+ struct arm_smmu_device *smmu,
+ int inst)
+{
+ u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
+
+ gfsr = readl_relaxed(nsmmu_page(smmu, inst, 0) + ARM_SMMU_GR0_sGFSR);
+ gfsynr0 = readl_relaxed(nsmmu_page(smmu, inst, 0) +
+ ARM_SMMU_GR0_sGFSYNR0);
+ gfsynr1 = readl_relaxed(nsmmu_page(smmu, inst, 0) +
+ ARM_SMMU_GR0_sGFSYNR1);
+ gfsynr2 = readl_relaxed(nsmmu_page(smmu, inst, 0) +
+ ARM_SMMU_GR0_sGFSYNR2);
+
+ if (!gfsr)
+ return IRQ_NONE;
+
+ dev_err_ratelimited(smmu->dev,
+ "Unexpected global fault, this could be serious\n");
+ dev_err_ratelimited(smmu->dev,
+ "\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
+ gfsr, gfsynr0, gfsynr1, gfsynr2);
+
+ writel_relaxed(gfsr, nsmmu_page(smmu, inst, 0) + ARM_SMMU_GR0_sGFSR);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t nsmmu_global_fault(int irq, void *dev)
+{
+ int inst;
+ irqreturn_t irq_ret = IRQ_NONE;
+ struct arm_smmu_device *smmu = dev;
+
+ for (inst = 0; inst < to_nvidia_smmu(smmu)->num_inst; inst++) {
+ irq_ret = nsmmu_global_fault_inst(irq, smmu, inst);
+ if (irq_ret == IRQ_HANDLED)
+ return irq_ret;
+ }
+
+ return irq_ret;
+}
+
+static irqreturn_t nsmmu_context_fault_bank(int irq,
+ struct arm_smmu_device *smmu,
+ int idx, int inst)
+{
+ u32 fsr, fsynr, cbfrsynra;
+ unsigned long iova;
+
+ fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+ if (!(fsr & FSR_FAULT))
+ return IRQ_NONE;
+
+ fsynr = readl_relaxed(nsmmu_page(smmu, inst, smmu->numpage + idx) +
+ ARM_SMMU_CB_FSYNR0);
+ iova = readq_relaxed(nsmmu_page(smmu, inst, smmu->numpage + idx) +
+ ARM_SMMU_CB_FAR);
+ cbfrsynra = readl_relaxed(nsmmu_page(smmu, inst, 1) +
+ ARM_SMMU_GR1_CBFRSYNRA(idx));
+
+ dev_err_ratelimited(smmu->dev,
+ "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n",
+ fsr, iova, fsynr, cbfrsynra, idx);
+
+ writel_relaxed(fsr, nsmmu_page(smmu, inst, smmu->numpage + idx) +
+ ARM_SMMU_CB_FSR);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t nsmmu_context_fault(int irq, void *dev)
+{
+ int inst, idx;
+ irqreturn_t irq_ret = IRQ_NONE;
+ struct iommu_domain *domain = dev;
+ struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+
+ for (inst = 0; inst < to_nvidia_smmu(smmu)->num_inst; inst++) {
+ /* Interrupt line shared between all context faults.
+ * Check for faults across all contexts.
+ */
+ for (idx = 0; idx < smmu->num_context_banks; idx++) {
+ irq_ret = nsmmu_context_fault_bank(irq, smmu,
+ idx, inst);
+
+ if (irq_ret == IRQ_HANDLED)
+ return irq_ret;
+ }
+ }
+
+ return irq_ret;
+}
+
static const struct arm_smmu_impl nvidia_smmu_impl = {
.read_reg = nsmmu_read_reg,
.write_reg = nsmmu_write_reg,
@@ -150,6 +248,8 @@ static const struct arm_smmu_impl nvidia_smmu_impl = {
.write_reg64 = nsmmu_write_reg64,
.reset = nsmmu_reset,
.init_context = nsmmu_init_context,
+ .global_fault = nsmmu_global_fault,
+ .context_fault = nsmmu_context_fault,
};
struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 16b5c54..7811e7d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -635,6 +635,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
enum io_pgtable_fmt fmt;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ irqreturn_t (*context_fault)(int irq, void *dev);
mutex_lock(&smmu_domain->init_mutex);
if (smmu_domain->smmu)
@@ -797,7 +798,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
* handler seeing a half-initialised domain state.
*/
irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
- ret = devm_request_irq(smmu->dev, irq, arm_smmu_context_fault,
+ context_fault = (smmu->impl && smmu->impl->context_fault) ?
+ smmu->impl->context_fault : arm_smmu_context_fault;
+ ret = devm_request_irq(smmu->dev, irq, context_fault,
IRQF_SHARED, "arm-smmu-context-fault", domain);
if (ret < 0) {
dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
@@ -2012,6 +2015,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
int num_irqs, i, err;
+ irqreturn_t (*global_fault)(int irq, void *dev);
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
if (!smmu) {
@@ -2100,9 +2104,12 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
smmu->num_context_irqs = smmu->num_context_banks;
}
+ global_fault = (smmu->impl && smmu->impl->global_fault) ?
+ smmu->impl->global_fault : arm_smmu_global_fault;
+
for (i = 0; i < smmu->num_global_irqs; ++i) {
err = devm_request_irq(smmu->dev, smmu->irqs[i],
- arm_smmu_global_fault,
+ global_fault,
IRQF_SHARED,
"arm-smmu global fault",
smmu);
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 4520ef7..cfd5f22 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -17,6 +17,7 @@
#include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/io-pgtable.h>
#include <linux/iommu.h>
+#include <linux/irqreturn.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -337,6 +338,8 @@ struct arm_smmu_impl {
int (*cfg_probe)(struct arm_smmu_device *smmu);
int (*reset)(struct arm_smmu_device *smmu);
int (*init_context)(struct arm_smmu_domain *smmu_domain);
+ irqreturn_t (*global_fault)(int irq, void *dev);
+ irqreturn_t (*context_fault)(int irq, void *dev);
};
static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 2/7] iommu/arm-smmu: add NVIDIA implementation for dual ARM MMU-500 usage
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
NVIDIA's Tegra194 soc uses two ARM MMU-500s together to interleave
IOVA accesses across them.
Add NVIDIA implementation for dual ARM MMU-500s and add new compatible
string for Tegra194 soc.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
MAINTAINERS | 2 +
drivers/iommu/Makefile | 2 +-
drivers/iommu/arm-smmu-impl.c | 3 +
drivers/iommu/arm-smmu-nvidia.c | 187 ++++++++++++++++++++++++++++++++++++++++
drivers/iommu/arm-smmu.h | 1 +
5 files changed, 194 insertions(+), 1 deletion(-)
create mode 100644 drivers/iommu/arm-smmu-nvidia.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 74e9d9c..c9b802a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15807,9 +15807,11 @@ F: drivers/i2c/busses/i2c-tegra.c
TEGRA IOMMU DRIVERS
M: Thierry Reding <thierry.reding@gmail.com>
+R: Krishna Reddy <vdumpa@nvidia.com>
L: linux-tegra@vger.kernel.org
S: Supported
F: drivers/iommu/tegra*
+F: drivers/iommu/arm-smmu-nvidia.c
TEGRA KBC DRIVER
M: Laxman Dewangan <ldewangan@nvidia.com>
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 7caad48..556b94c 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
-obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
obj-$(CONFIG_DMAR_TABLE) += dmar.o
obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index 5c87a38..1a19687 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -158,6 +158,9 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
*/
switch (smmu->model) {
case ARM_MMU500:
+ if (of_device_is_compatible(smmu->dev->of_node,
+ "nvidia,tegra194-smmu"))
+ return nvidia_smmu_impl_init(smmu);
smmu->impl = &arm_mmu500_impl;
break;
case CAVIUM_SMMUV2:
diff --git a/drivers/iommu/arm-smmu-nvidia.c b/drivers/iommu/arm-smmu-nvidia.c
new file mode 100644
index 0000000..ca871dc
--- /dev/null
+++ b/drivers/iommu/arm-smmu-nvidia.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Nvidia ARM SMMU v2 implementation quirks
+// Copyright (C) 2019 NVIDIA CORPORATION. All rights reserved.
+
+#define pr_fmt(fmt) "nvidia-smmu: " fmt
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "arm-smmu.h"
+
+/* Tegra194 has three ARM MMU-500 Instances.
+ * Two of them are used together for Interleaved IOVA accesses and
+ * used by Non-Isochronous Hw devices for SMMU translations.
+ * Third one is used for SMMU translations from Isochronous HW devices.
+ * It is possible to use this Implementation to program either
+ * all three or two of the instances identically as desired through
+ * DT node.
+ *
+ * Programming all the three instances identically comes with redundant tlb
+ * invalidations as all three never need to be tlb invalidated for a HW device.
+ *
+ * When Linux Kernel supports multiple SMMU devices, The SMMU device used for
+ * Isochornous HW devices should be added as a separate ARM MMU-500 device
+ * in DT and be programmed independently for efficient tlb invalidates.
+ *
+ */
+#define MAX_SMMU_INSTANCES 3
+
+struct nvidia_smmu {
+ struct arm_smmu_device smmu;
+ unsigned int num_inst;
+ void __iomem *bases[MAX_SMMU_INSTANCES];
+};
+
+#define to_nvidia_smmu(s) container_of(s, struct nvidia_smmu, smmu)
+
+#define nsmmu_page(smmu, inst, page) \
+ (((inst) ? to_nvidia_smmu(smmu)->bases[(inst)] : smmu->base) + \
+ ((page) << smmu->pgshift))
+
+static u32 nsmmu_read_reg(struct arm_smmu_device *smmu,
+ int page, int offset)
+{
+ return readl_relaxed(nsmmu_page(smmu, 0, page) + offset);
+}
+
+static void nsmmu_write_reg(struct arm_smmu_device *smmu,
+ int page, int offset, u32 val)
+{
+ unsigned int i;
+
+ for (i = 0; i < to_nvidia_smmu(smmu)->num_inst; i++)
+ writel_relaxed(val, nsmmu_page(smmu, i, page) + offset);
+}
+
+static u64 nsmmu_read_reg64(struct arm_smmu_device *smmu,
+ int page, int offset)
+{
+ return readq_relaxed(nsmmu_page(smmu, 0, page) + offset);
+}
+
+static void nsmmu_write_reg64(struct arm_smmu_device *smmu,
+ int page, int offset, u64 val)
+{
+ unsigned int i;
+
+ for (i = 0; i < to_nvidia_smmu(smmu)->num_inst; i++)
+ writeq_relaxed(val, nsmmu_page(smmu, i, page) + offset);
+}
+
+static void nsmmu_tlb_sync(struct arm_smmu_device *smmu, int page,
+ int sync, int status)
+{
+ u32 reg;
+ unsigned int i;
+ unsigned int spin_cnt, delay;
+
+ arm_smmu_writel(smmu, page, sync, 0);
+
+ for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) {
+ for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) {
+ reg = 0;
+ for (i = 0; i < to_nvidia_smmu(smmu)->num_inst; i++) {
+ reg |= readl_relaxed(
+ nsmmu_page(smmu, i, page) + status);
+ }
+ if (!(reg & sTLBGSTATUS_GSACTIVE))
+ return;
+ cpu_relax();
+ }
+ udelay(delay);
+ }
+ dev_err_ratelimited(smmu->dev,
+ "TLB sync timed out -- SMMU may be deadlocked\n");
+}
+
+static void nsmmu_tlb_sync_context(void *cookie)
+{
+ struct arm_smmu_domain *smmu_domain = cookie;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ unsigned long flags;
+
+ spin_lock_irqsave(&smmu_domain->cb_lock, flags);
+ nsmmu_tlb_sync(smmu, ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx),
+ ARM_SMMU_CB_TLBSYNC, ARM_SMMU_CB_TLBSTATUS);
+ spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
+}
+
+static void nsmmu_tlb_sync_global(struct arm_smmu_device *smmu)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&smmu->global_sync_lock, flags);
+ nsmmu_tlb_sync(smmu, ARM_SMMU_GR0, ARM_SMMU_GR0_sTLBGSYNC,
+ ARM_SMMU_GR0_sTLBGSTATUS);
+ spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
+}
+
+static int nsmmu_reset(struct arm_smmu_device *smmu)
+{
+ u32 reg;
+ unsigned int i;
+
+ for (i = 0; i < to_nvidia_smmu(smmu)->num_inst; i++) {
+ /* clear global FSR */
+ reg = readl_relaxed(nsmmu_page(smmu, i, ARM_SMMU_GR0) +
+ ARM_SMMU_GR0_sGFSR);
+ writel_relaxed(reg, nsmmu_page(smmu, i, ARM_SMMU_GR0) +
+ ARM_SMMU_GR0_sGFSR);
+ }
+
+ nsmmu_tlb_sync_global(smmu);
+ return 0;
+}
+
+static int nsmmu_init_context(struct arm_smmu_domain *smmu_domain)
+{
+ smmu_domain->flush_ops->tlb_sync = nsmmu_tlb_sync_context;
+ return 0;
+}
+
+static const struct arm_smmu_impl nvidia_smmu_impl = {
+ .read_reg = nsmmu_read_reg,
+ .write_reg = nsmmu_write_reg,
+ .read_reg64 = nsmmu_read_reg64,
+ .write_reg64 = nsmmu_write_reg64,
+ .reset = nsmmu_reset,
+ .init_context = nsmmu_init_context,
+};
+
+struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+ unsigned int i;
+ struct nvidia_smmu *nsmmu;
+ struct resource *res;
+ struct device *dev = smmu->dev;
+ struct platform_device *pdev = to_platform_device(smmu->dev);
+
+ nsmmu = devm_kzalloc(smmu->dev, sizeof(*nsmmu), GFP_KERNEL);
+ if (!nsmmu)
+ return ERR_PTR(-ENOMEM);
+
+ nsmmu->smmu = *smmu;
+ /* Instance 0 is ioremapped by arm-smmu.c */
+ nsmmu->num_inst = 1;
+
+ for (i = 1; i < MAX_SMMU_INSTANCES; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ break;
+ nsmmu->bases[i] = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nsmmu->bases[i]))
+ return (struct arm_smmu_device *)nsmmu->bases[i];
+ nsmmu->num_inst++;
+ }
+
+ nsmmu->smmu.impl = &nvidia_smmu_impl;
+ devm_kfree(smmu->dev, smmu);
+ pr_info("NVIDIA ARM SMMU Implementation, Instances=%d\n",
+ nsmmu->num_inst);
+
+ return &nsmmu->smmu;
+}
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index b2d6c7f..4520ef7 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -400,5 +400,6 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
arm_smmu_writeq((s), ARM_SMMU_CB((s), (n)), (o), (v))
struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu);
+struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu);
#endif /* _ARM_SMMU_H */
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 7/7] arm64: tegra: enable SMMU for SDHCI and EQOS on T194
From: Krishna Reddy @ 2019-09-03 3:32 UTC (permalink / raw)
Cc: snikam, thomasz, jtukkinen, mperttunen, will, joro, linux-kernel,
praithatha, talho, olof, iommu, linux-tegra, yhsu, treding,
robin.murphy, avanbrunt, linux-arm-kernel
In-Reply-To: <1567481528-31163-1-git-send-email-vdumpa@nvidia.com>
Enable SMMU translations for SDHCI and EQOS transactions on T194.
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 5ae3bbf..cac3462 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -51,6 +51,7 @@
clock-names = "master_bus", "slave_bus", "rx", "tx", "ptp_ref";
resets = <&bpmp TEGRA194_RESET_EQOS>;
reset-names = "eqos";
+ iommus = <&smmu TEGRA186_SID_EQOS>;
status = "disabled";
snps,write-requests = <1>;
@@ -381,6 +382,7 @@
clock-names = "sdhci";
resets = <&bpmp TEGRA194_RESET_SDMMC1>;
reset-names = "sdhci";
+ iommus = <&smmu TEGRA186_SID_SDMMC1>;
nvidia,pad-autocal-pull-up-offset-3v3-timeout =
<0x07>;
nvidia,pad-autocal-pull-down-offset-3v3-timeout =
@@ -403,6 +405,7 @@
clock-names = "sdhci";
resets = <&bpmp TEGRA194_RESET_SDMMC3>;
reset-names = "sdhci";
+ iommus = <&smmu TEGRA186_SID_SDMMC3>;
nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>;
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7a>;
nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
@@ -430,6 +433,7 @@
<&bpmp TEGRA194_CLK_PLLC4>;
resets = <&bpmp TEGRA194_RESET_SDMMC4>;
reset-names = "sdhci";
+ iommus = <&smmu TEGRA186_SID_SDMMC4>;
nvidia,pad-autocal-pull-up-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-down-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
--
2.1.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] arm64: dts: lx2160a: add tmu device node
From: Yuantian Tang @ 2019-09-03 3:31 UTC (permalink / raw)
To: shawnguo
Cc: mark.rutland, devicetree, Yuantian Tang, linux-kernel, leoyang.li,
robh+dt, linux-arm-kernel
Add the TMU (Thermal Monitoring Unit) device node to enable
TMU feature.
Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
---
.../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 108 +++++++++++++++---
1 file changed, 92 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 39d497df769e..e70ddd01cd84 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
/memreserve/ 0x80000000 0x00010000;
@@ -24,7 +25,7 @@
#size-cells = <0>;
// 8 clusters having 2 Cortex-A72 cores each
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -38,9 +39,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster0_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@1 {
+ cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -54,9 +56,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster0_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@100 {
+ cpu100: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -70,9 +73,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster1_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@101 {
+ cpu101: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -86,9 +90,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster1_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@200 {
+ cpu200: cpu@200 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -102,9 +107,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster2_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@201 {
+ cpu201: cpu@201 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -118,9 +124,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster2_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@300 {
+ cpu300: cpu@300 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -134,9 +141,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster3_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@301 {
+ cpu301: cpu@301 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -150,9 +158,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster3_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@400 {
+ cpu400: cpu@400 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -166,9 +175,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster4_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@401 {
+ cpu401: cpu@401 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -182,9 +192,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster4_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@500 {
+ cpu500: cpu@500 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -198,9 +209,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster5_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@501 {
+ cpu501: cpu@501 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -214,9 +226,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster5_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@600 {
+ cpu600: cpu@600 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -230,9 +243,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster6_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@601 {
+ cpu601: cpu@601 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -246,9 +260,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster6_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@700 {
+ cpu700: cpu@700 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -262,9 +277,10 @@
i-cache-sets = <192>;
next-level-cache = <&cluster7_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
- cpu@701 {
+ cpu701: cpu@701 {
device_type = "cpu";
compatible = "arm,cortex-a72";
enable-method = "psci";
@@ -278,6 +294,7 @@
i-cache-sets = <192>;
next-level-cache = <&cluster7_l2>;
cpu-idle-states = <&cpu_pw20>;
+ #cooling-cells = <2>;
};
cluster0_l2: l2-cache0 {
@@ -422,6 +439,51 @@
clock-output-names = "sysclk";
};
+ thermal-zones {
+ core_thermal1: core-thermal1 {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&tmu 0>;
+
+ trips {
+ core_cluster_alert: core-cluster-alert {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ core_cluster_crit: core-cluster-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&core_cluster_alert>;
+ cooling-device =
+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu200 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu201 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu300 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu301 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu400 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu401 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu500 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu501 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu600 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu601 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu700 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu701 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -689,6 +751,20 @@
status = "disabled";
};
+ tmu: tmu@1f80000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0x0 0x1f80000 0x0 0x10000>;
+ interrupts = <0 23 0x4>;
+ fsl,tmu-range = <0x800000E6 0x8001017D>;
+ fsl,tmu-calibration =
+ /* Calibration data group 1 */
+ <0x00000000 0x00000035
+ /* Calibration data group 2 */
+ 0x00010001 0x00000154>;
+ little-endian;
+ #thermal-sensor-cells = <1>;
+ };
+
uart0: serial@21c0000 {
compatible = "arm,sbsa-uart","arm,pl011";
reg = <0x0 0x21c0000 0x0 0x1000>;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* RE: [PATCH v3 01/11] PCI: designware-ep: Add multiple PFs support for DWC
From: Xiaowei Bao @ 2019-09-03 3:43 UTC (permalink / raw)
To: Andrew Murray
Cc: mark.rutland@arm.com, Roy Zang, lorenzo.pieralisi@arm.com,
arnd@arndb.de, devicetree@vger.kernel.org, jingoohan1@gmail.com,
Z.q. Hou, linuxppc-dev@lists.ozlabs.org,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
kishon@ti.com, M.h. Lian, robh+dt@kernel.org,
gregkh@linuxfoundation.org, linux-arm-kernel@lists.infradead.org,
gustavo.pimentel@synopsys.com, Leo Li, shawnguo@kernel.org,
Mingkai Hu
In-Reply-To: <20190902162608.GP9720@e119886-lin.cambridge.arm.com>
> -----Original Message-----
> From: Andrew Murray <andrew.murray@arm.com>
> Sent: 2019年9月3日 0:26
> To: Xiaowei Bao <xiaowei.bao@nxp.com>
> Cc: robh+dt@kernel.org; mark.rutland@arm.com; shawnguo@kernel.org; Leo
> Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; M.h.
> Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy
> Zang <roy.zang@nxp.com>; jingoohan1@gmail.com;
> gustavo.pimentel@synopsys.com; linux-pci@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org;
> gregkh@linuxfoundation.org; Z.q. Hou <zhiqiang.hou@nxp.com>;
> arnd@arndb.de
> Subject: Re: [PATCH v3 01/11] PCI: designware-ep: Add multiple PFs support
> for DWC
>
> On Mon, Sep 02, 2019 at 11:17:06AM +0800, Xiaowei Bao wrote:
> > Add multiple PFs support for DWC, different PF have different config
> > space we use pf-offset property which get from the DTS to access the
> > different pF
>
> This needs to be updated as this no longer comes from the DT.
Yes, thanks
Thanks
Xiaowei
>
> > config space.
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
>
>
> We're assuming:
>
> - The offset address (func_offset) between PF's in the memory map can be
> different between different DWC implementations. And also that it's
> possible for DWC implementations to address PFs without using an offset.
>
> - The current approach is preferable to adding DWC EP driver callbacks
> for writing to the EP config space (e.g. a variant of dw_pcie_writew_dbi
> that takes a func number).
Even if use the a variant of dw_pcie_writew_dbi, we also need a offset value form
different platform, due to the different platform may be have different implement
about this, so I am not sure how to implement the variant of dw_pcie_writew_dbi?
>
> I'm keen to hear feedback from Jingoo/Gustavo on this.
OK, expect the feedback.
Thanks
Xiaowei
>
> Thanks,
>
> Andrew Murray
>
> > ---
> > v2:
> > - Remove duplicate redundant code.
> > - Reimplement the PF config space access way.
> > v3:
> > - Integrate duplicate code for func_select.
> > - Move PCIE_ATU_FUNC_NUM(pf) (pf << 20) to ((pf) << 20).
> > - Add the comments for func_conf_select function.
> >
> > drivers/pci/controller/dwc/pcie-designware-ep.c | 123
> ++++++++++++++++--------
> > drivers/pci/controller/dwc/pcie-designware.c | 59 ++++++++----
> > drivers/pci/controller/dwc/pcie-designware.h | 18 +++-
> > 3 files changed, 142 insertions(+), 58 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 65f4792..eb851c2 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -19,12 +19,26 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> > pci_epc_linkup(epc);
> > }
> >
> > -static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno
> bar,
> > - int flags)
> > +static unsigned int dw_pcie_ep_func_select(struct dw_pcie_ep *ep, u8
> > +func_no) {
> > + unsigned int func_offset = 0;
> > +
> > + if (ep->ops->func_conf_select)
> > + func_offset = ep->ops->func_conf_select(ep, func_no);
> > +
> > + return func_offset;
> > +}
> > +
> > +static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
> > + enum pci_barno bar, int flags)
> > {
> > u32 reg;
> > + unsigned int func_offset = 0;
> > + struct dw_pcie_ep *ep = &pci->ep;
> > +
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> >
> > - reg = PCI_BASE_ADDRESS_0 + (4 * bar);
> > + reg = func_offset + PCI_BASE_ADDRESS_0 + (4 * bar);
> > dw_pcie_dbi_ro_wr_en(pci);
> > dw_pcie_writel_dbi2(pci, reg, 0x0);
> > dw_pcie_writel_dbi(pci, reg, 0x0);
> > @@ -37,7 +51,12 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie
> > *pci, enum pci_barno bar,
> >
> > void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) {
> > - __dw_pcie_ep_reset_bar(pci, bar, 0);
> > + u8 func_no, funcs;
> > +
> > + funcs = pci->ep.epc->max_functions;
> > +
> > + for (func_no = 0; func_no < funcs; func_no++)
> > + __dw_pcie_ep_reset_bar(pci, func_no, bar, 0);
> > }
> >
> > static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
> > @@ -45,28 +64,31 @@ static int dw_pcie_ep_write_header(struct pci_epc
> > *epc, u8 func_no, {
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > + unsigned int func_offset = 0;
> > +
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> >
> > dw_pcie_dbi_ro_wr_en(pci);
> > - dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
> > - dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
> > - dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
> > - dw_pcie_writeb_dbi(pci, PCI_CLASS_PROG, hdr->progif_code);
> > - dw_pcie_writew_dbi(pci, PCI_CLASS_DEVICE,
> > + dw_pcie_writew_dbi(pci, func_offset + PCI_VENDOR_ID, hdr->vendorid);
> > + dw_pcie_writew_dbi(pci, func_offset + PCI_DEVICE_ID, hdr->deviceid);
> > + dw_pcie_writeb_dbi(pci, func_offset + PCI_REVISION_ID, hdr->revid);
> > + dw_pcie_writeb_dbi(pci, func_offset + PCI_CLASS_PROG,
> hdr->progif_code);
> > + dw_pcie_writew_dbi(pci, func_offset + PCI_CLASS_DEVICE,
> > hdr->subclass_code | hdr->baseclass_code << 8);
> > - dw_pcie_writeb_dbi(pci, PCI_CACHE_LINE_SIZE,
> > + dw_pcie_writeb_dbi(pci, func_offset + PCI_CACHE_LINE_SIZE,
> > hdr->cache_line_size);
> > - dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_VENDOR_ID,
> > + dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_VENDOR_ID,
> > hdr->subsys_vendor_id);
> > - dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
> > - dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
> > + dw_pcie_writew_dbi(pci, func_offset + PCI_SUBSYSTEM_ID,
> hdr->subsys_id);
> > + dw_pcie_writeb_dbi(pci, func_offset + PCI_INTERRUPT_PIN,
> > hdr->interrupt_pin);
> > dw_pcie_dbi_ro_wr_dis(pci);
> >
> > return 0;
> > }
> >
> > -static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum
> pci_barno bar,
> > - dma_addr_t cpu_addr,
> > +static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no,
> > + enum pci_barno bar, dma_addr_t cpu_addr,
> > enum dw_pcie_as_type as_type)
> > {
> > int ret;
> > @@ -79,7 +101,7 @@ static int dw_pcie_ep_inbound_atu(struct
> dw_pcie_ep *ep, enum pci_barno bar,
> > return -EINVAL;
> > }
> >
> > - ret = dw_pcie_prog_inbound_atu(pci, free_win, bar, cpu_addr,
> > + ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, bar,
> > +cpu_addr,
> > as_type);
> > if (ret < 0) {
> > dev_err(pci->dev, "Failed to program IB window\n"); @@ -92,7
> +114,8
> > @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum
> pci_barno bar,
> > return 0;
> > }
> >
> > -static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t
> > phys_addr,
> > +static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
> > + phys_addr_t phys_addr,
> > u64 pci_addr, size_t size)
> > {
> > u32 free_win;
> > @@ -104,8 +127,8 @@ static int dw_pcie_ep_outbound_atu(struct
> dw_pcie_ep *ep, phys_addr_t phys_addr,
> > return -EINVAL;
> > }
> >
> > - dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
> > - phys_addr, pci_addr, size);
> > + dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win,
> PCIE_ATU_TYPE_MEM,
> > + phys_addr, pci_addr, size);
> >
> > set_bit(free_win, ep->ob_window_map);
> > ep->outbound_addr[free_win] = phys_addr; @@ -121,7 +144,7 @@
> static
> > void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
> > enum pci_barno bar = epf_bar->barno;
> > u32 atu_index = ep->bar_to_atu[bar];
> >
> > - __dw_pcie_ep_reset_bar(pci, bar, epf_bar->flags);
> > + __dw_pcie_ep_reset_bar(pci, func_no, bar, epf_bar->flags);
> >
> > dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
> > clear_bit(atu_index, ep->ib_window_map); @@ -137,14 +160,20 @@
> > static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
> > size_t size = epf_bar->size;
> > int flags = epf_bar->flags;
> > enum dw_pcie_as_type as_type;
> > - u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
> > + u32 reg;
> > + unsigned int func_offset = 0;
> > +
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = PCI_BASE_ADDRESS_0 + (4 * bar) + func_offset;
> >
> > if (!(flags & PCI_BASE_ADDRESS_SPACE))
> > as_type = DW_PCIE_AS_MEM;
> > else
> > as_type = DW_PCIE_AS_IO;
> >
> > - ret = dw_pcie_ep_inbound_atu(ep, bar, epf_bar->phys_addr, as_type);
> > + ret = dw_pcie_ep_inbound_atu(ep, func_no, bar,
> > + epf_bar->phys_addr, as_type);
> > if (ret)
> > return ret;
> >
> > @@ -202,7 +231,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc
> *epc, u8 func_no,
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> >
> > - ret = dw_pcie_ep_outbound_atu(ep, addr, pci_addr, size);
> > + ret = dw_pcie_ep_outbound_atu(ep, func_no, addr, pci_addr, size);
> > if (ret) {
> > dev_err(pci->dev, "Failed to enable address\n");
> > return ret;
> > @@ -216,11 +245,14 @@ static int dw_pcie_ep_get_msi(struct pci_epc
> *epc, u8 func_no)
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > u32 val, reg;
> > + unsigned int func_offset = 0;
> >
> > if (!ep->msi_cap)
> > return -EINVAL;
> >
> > - reg = ep->msi_cap + PCI_MSI_FLAGS;
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
> > val = dw_pcie_readw_dbi(pci, reg);
> > if (!(val & PCI_MSI_FLAGS_ENABLE))
> > return -EINVAL;
> > @@ -235,11 +267,14 @@ static int dw_pcie_ep_set_msi(struct pci_epc
> *epc, u8 func_no, u8 interrupts)
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > u32 val, reg;
> > + unsigned int func_offset = 0;
> >
> > if (!ep->msi_cap)
> > return -EINVAL;
> >
> > - reg = ep->msi_cap + PCI_MSI_FLAGS;
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
> > val = dw_pcie_readw_dbi(pci, reg);
> > val &= ~PCI_MSI_FLAGS_QMASK;
> > val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK; @@ -255,11 +290,14
> > @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > u32 val, reg;
> > + unsigned int func_offset = 0;
> >
> > if (!ep->msix_cap)
> > return -EINVAL;
> >
> > - reg = ep->msix_cap + PCI_MSIX_FLAGS;
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = ep->msix_cap + func_offset + PCI_MSIX_FLAGS;
> > val = dw_pcie_readw_dbi(pci, reg);
> > if (!(val & PCI_MSIX_FLAGS_ENABLE))
> > return -EINVAL;
> > @@ -274,11 +312,14 @@ static int dw_pcie_ep_set_msix(struct pci_epc
> *epc, u8 func_no, u16 interrupts)
> > struct dw_pcie_ep *ep = epc_get_drvdata(epc);
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > u32 val, reg;
> > + unsigned int func_offset = 0;
> >
> > if (!ep->msix_cap)
> > return -EINVAL;
> >
> > - reg = ep->msix_cap + PCI_MSIX_FLAGS;
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = ep->msix_cap + func_offset + PCI_MSIX_FLAGS;
> > val = dw_pcie_readw_dbi(pci, reg);
> > val &= ~PCI_MSIX_FLAGS_QSIZE;
> > val |= interrupts;
> > @@ -365,6 +406,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep
> *ep, u8 func_no,
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > struct pci_epc *epc = ep->epc;
> > unsigned int aligned_offset;
> > + unsigned int func_offset = 0;
> > u16 msg_ctrl, msg_data;
> > u32 msg_addr_lower, msg_addr_upper, reg;
> > u64 msg_addr;
> > @@ -374,20 +416,22 @@ int dw_pcie_ep_raise_msi_irq(struct
> dw_pcie_ep *ep, u8 func_no,
> > if (!ep->msi_cap)
> > return -EINVAL;
> >
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
> > - reg = ep->msi_cap + PCI_MSI_FLAGS;
> > + reg = ep->msi_cap + func_offset + PCI_MSI_FLAGS;
> > msg_ctrl = dw_pcie_readw_dbi(pci, reg);
> > has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
> > - reg = ep->msi_cap + PCI_MSI_ADDRESS_LO;
> > + reg = ep->msi_cap + func_offset + PCI_MSI_ADDRESS_LO;
> > msg_addr_lower = dw_pcie_readl_dbi(pci, reg);
> > if (has_upper) {
> > - reg = ep->msi_cap + PCI_MSI_ADDRESS_HI;
> > + reg = ep->msi_cap + func_offset + PCI_MSI_ADDRESS_HI;
> > msg_addr_upper = dw_pcie_readl_dbi(pci, reg);
> > - reg = ep->msi_cap + PCI_MSI_DATA_64;
> > + reg = ep->msi_cap + func_offset + PCI_MSI_DATA_64;
> > msg_data = dw_pcie_readw_dbi(pci, reg);
> > } else {
> > msg_addr_upper = 0;
> > - reg = ep->msi_cap + PCI_MSI_DATA_32;
> > + reg = ep->msi_cap + func_offset + PCI_MSI_DATA_32;
> > msg_data = dw_pcie_readw_dbi(pci, reg);
> > }
> > aligned_offset = msg_addr_lower & (epc->mem->page_size - 1); @@
> > -406,11 +450,12 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep,
> > u8 func_no, }
> >
> > int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> > - u16 interrupt_num)
> > + u16 interrupt_num)
> > {
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > struct pci_epc *epc = ep->epc;
> > u16 tbl_offset, bir;
> > + unsigned int func_offset = 0;
> > u32 bar_addr_upper, bar_addr_lower;
> > u32 msg_addr_upper, msg_addr_lower;
> > u32 reg, msg_data, vec_ctrl;
> > @@ -418,12 +463,14 @@ int dw_pcie_ep_raise_msix_irq(struct
> dw_pcie_ep *ep, u8 func_no,
> > void __iomem *msix_tbl;
> > int ret;
> >
> > - reg = ep->msix_cap + PCI_MSIX_TABLE;
> > + func_offset = dw_pcie_ep_func_select(ep, func_no);
> > +
> > + reg = ep->msix_cap + func_offset + PCI_MSIX_TABLE;
> > tbl_offset = dw_pcie_readl_dbi(pci, reg);
> > bir = (tbl_offset & PCI_MSIX_TABLE_BIR);
> > tbl_offset &= PCI_MSIX_TABLE_OFFSET;
> >
> > - reg = PCI_BASE_ADDRESS_0 + (4 * bir);
> > + reg = PCI_BASE_ADDRESS_0 + func_offset + (4 * bir);
> > bar_addr_upper = 0;
> > bar_addr_lower = dw_pcie_readl_dbi(pci, reg);
> > reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK);
> @@
> > -559,13 +606,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> > ep->epc = epc;
> > epc_set_drvdata(epc, ep);
> >
> > - if (ep->ops->ep_init)
> > - ep->ops->ep_init(ep);
> > -
> > ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
> > if (ret < 0)
> > epc->max_functions = 1;
> >
> > + if (ep->ops->ep_init)
> > + ep->ops->ep_init(ep);
> > +
> > ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
> > ep->page_size);
> > if (ret < 0) {
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c
> > b/drivers/pci/controller/dwc/pcie-designware.c
> > index 143cb6c..ede2e75 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -238,9 +238,10 @@ static void dw_pcie_writel_ob_unroll(struct
> dw_pcie *pci, u32 index, u32 reg,
> > dw_pcie_writel_atu(pci, offset + reg, val); }
> >
> > -static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int
> index,
> > - int type, u64 cpu_addr,
> > - u64 pci_addr, u32 size)
> > +static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8
> func_no,
> > + int index, int type,
> > + u64 cpu_addr, u64 pci_addr,
> > + u32 size)
> > {
> > u32 retries, val;
> >
> > @@ -255,7 +256,7 @@ static void
> dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
> > dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
> > upper_32_bits(pci_addr));
> > dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
> > - type);
> > + type | PCIE_ATU_FUNC_NUM(func_no));
> > dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
> > PCIE_ATU_ENABLE);
> >
> > @@ -274,8 +275,9 @@ static void
> dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
> > dev_err(pci->dev, "Outbound iATU is not being enabled\n"); }
> >
> > -void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> > - u64 cpu_addr, u64 pci_addr, u32 size)
> > +static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8
> func_no,
> > + int index, int type, u64 cpu_addr,
> > + u64 pci_addr, u32 size)
> > {
> > u32 retries, val;
> >
> > @@ -283,8 +285,8 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie
> *pci, int index, int type,
> > cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
> >
> > if (pci->iatu_unroll_enabled) {
> > - dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
> > - pci_addr, size);
> > + dw_pcie_prog_outbound_atu_unroll(pci, func_no, index, type,
> > + cpu_addr, pci_addr, size);
> > return;
> > }
> >
> > @@ -300,7 +302,8 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie
> *pci, int index, int type,
> > lower_32_bits(pci_addr));
> > dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
> > upper_32_bits(pci_addr));
> > - dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
> > + dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type |
> > + PCIE_ATU_FUNC_NUM(func_no));
> > dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
> >
> > /*
> > @@ -317,6 +320,21 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie
> *pci, int index, int type,
> > dev_err(pci->dev, "Outbound iATU is not being enabled\n"); }
> >
> > +void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> > + u64 cpu_addr, u64 pci_addr, u32 size) {
> > + __dw_pcie_prog_outbound_atu(pci, 0, index, type,
> > + cpu_addr, pci_addr, size);
> > +}
> > +
> > +void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int
> index,
> > + int type, u64 cpu_addr, u64 pci_addr,
> > + u32 size)
> > +{
> > + __dw_pcie_prog_outbound_atu(pci, func_no, index, type,
> > + cpu_addr, pci_addr, size);
> > +}
> > +
> > static u32 dw_pcie_readl_ib_unroll(struct dw_pcie *pci, u32 index,
> > u32 reg) {
> > u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
> > @@ -332,8 +350,8 @@ static void dw_pcie_writel_ib_unroll(struct dw_pcie
> *pci, u32 index, u32 reg,
> > dw_pcie_writel_atu(pci, offset + reg, val); }
> >
> > -static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
> > - int bar, u64 cpu_addr,
> > +static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, u8
> func_no,
> > + int index, int bar, u64 cpu_addr,
> > enum dw_pcie_as_type as_type) {
> > int type;
> > @@ -355,8 +373,10 @@ static int dw_pcie_prog_inbound_atu_unroll(struct
> dw_pcie *pci, int index,
> > return -EINVAL;
> > }
> >
> > - dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
> type);
> > + dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
> type |
> > + PCIE_ATU_FUNC_NUM(func_no));
> > dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
> > + PCIE_ATU_FUNC_NUM_MATCH_EN |
> > PCIE_ATU_ENABLE |
> > PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
> >
> > @@ -377,14 +397,15 @@ static int
> dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
> > return -EBUSY;
> > }
> >
> > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
> > - u64 cpu_addr, enum dw_pcie_as_type as_type)
> > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > + int bar, u64 cpu_addr,
> > + enum dw_pcie_as_type as_type)
> > {
> > int type;
> > u32 retries, val;
> >
> > if (pci->iatu_unroll_enabled)
> > - return dw_pcie_prog_inbound_atu_unroll(pci, index, bar,
> > + return dw_pcie_prog_inbound_atu_unroll(pci, func_no, index, bar,
> > cpu_addr, as_type);
> >
> > dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
> PCIE_ATU_REGION_INBOUND |
> > @@ -403,9 +424,11 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie
> *pci, int index, int bar,
> > return -EINVAL;
> > }
> >
> > - dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
> > - dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE
> > - | PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
> > + dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type |
> > + PCIE_ATU_FUNC_NUM(func_no));
> > + dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE |
> > + PCIE_ATU_FUNC_NUM_MATCH_EN |
> > + PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
> >
> > /*
> > * Make sure ATU enable takes effect before any subsequent config
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h
> > b/drivers/pci/controller/dwc/pcie-designware.h
> > index 5a18e94..6aca0bb 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -71,9 +71,11 @@
> > #define PCIE_ATU_TYPE_IO 0x2
> > #define PCIE_ATU_TYPE_CFG0 0x4
> > #define PCIE_ATU_TYPE_CFG1 0x5
> > +#define PCIE_ATU_FUNC_NUM(pf) ((pf) << 20)
> > #define PCIE_ATU_CR2 0x908
> > #define PCIE_ATU_ENABLE BIT(31)
> > #define PCIE_ATU_BAR_MODE_ENABLE BIT(30)
> > +#define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19)
> > #define PCIE_ATU_LOWER_BASE 0x90C
> > #define PCIE_ATU_UPPER_BASE 0x910
> > #define PCIE_ATU_LIMIT 0x914
> > @@ -206,6 +208,14 @@ struct dw_pcie_ep_ops {
> > int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
> > enum pci_epc_irq_type type, u16 interrupt_num);
> > const struct pci_epc_features* (*get_features)(struct dw_pcie_ep
> > *ep);
> > + /*
> > + * Provide a method to implement the different func config space
> > + * access for different platform, if different func have different
> > + * offset, return the offset of func. if use write a register way
> > + * return a 0, and implement code in callback function of platform
> > + * driver.
> > + */
> > + unsigned int (*func_conf_select)(struct dw_pcie_ep *ep, u8 func_no);
> > };
> >
> > struct dw_pcie_ep {
> > @@ -277,8 +287,12 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci);
> > void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
> > int type, u64 cpu_addr, u64 pci_addr,
> > u32 size);
> > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
> > - u64 cpu_addr, enum dw_pcie_as_type as_type);
> > +void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int
> index,
> > + int type, u64 cpu_addr, u64 pci_addr,
> > + u32 size);
> > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > + int bar, u64 cpu_addr,
> > + enum dw_pcie_as_type as_type);
> > void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
> > enum dw_pcie_region_type type);
> > void dw_pcie_setup(struct dw_pcie *pci);
> > --
> > 2.9.5
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists
> > .infradead.org%2Fmailman%2Flistinfo%2Flinux-arm-kernel&data=02%
> 7C0
> >
> 1%7Cxiaowei.bao%40nxp.com%7C99eef14a525040ed3eab08d72fc244f1%7C
> 686ea1d
> >
> 3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637030383769341270&sd
> ata=ck2EC
> > %2FJYCjWErvbUM%2FT%2BoVMANMwyLRI4gVRssdnd04w%3D&reser
> ved=0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] media: i2c: dw9768: Add DW9768 VCM driver
From: Tomasz Figa @ 2019-09-03 3:50 UTC (permalink / raw)
To: Dongchun Zhu
Cc: Mark Rutland, devicetree, srv_heupstream, shengnan.wang,
Louis Kuo, Sj Huang, Rob Herring,
moderated list:ARM/Mediatek SoC support, Sakari Ailus,
Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Linux Media Mailing List
In-Reply-To: <1567436507.21623.83.camel@mhfsdcap03>
Hi Dongchun,
On Tue, Sep 3, 2019 at 12:02 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
>
> Hi Tomasz,
>
> On Fri, 2019-08-23 at 17:17 +0900, Tomasz Figa wrote:
> > Hi Dongchun,
> >
> > On Mon, Jul 08, 2019 at 06:06:41PM +0800, dongchun.zhu@mediatek.com wrote:
> > > From: Dongchun Zhu <dongchun.zhu@mediatek.com>
> > >
> > > This patch adds a V4L2 sub-device driver for DW9768 lens voice coil,
> > > and provides control to set the desired focus.
> > >
> > > The DW9807 is a 10 bit DAC from Dongwoon, designed for linear
> > > control of voice coil motor.
> > >
> > > Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
> > > ---
> > > MAINTAINERS | 1 +
> > > drivers/media/i2c/Kconfig | 10 +
> > > drivers/media/i2c/Makefile | 1 +
> > > drivers/media/i2c/dw9768.c | 458 +++++++++++++++++++++++++++++++++++++++++++++
> > > 4 files changed, 470 insertions(+)
> > > create mode 100644 drivers/media/i2c/dw9768.c
> > >
> >
> > Thanks for the patch! Please see my comments inline.
> >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 8f6ac93..17152d7 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -4877,6 +4877,7 @@ M: Dongchun Zhu <dongchun.zhu@mediatek.com>
> > > L: linux-media@vger.kernel.org
> > > T: git git://linuxtv.org/media_tree.git
> > > S: Maintained
> > > +F: drivers/media/i2c/dw9768.c
> > > F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.txt
> > >
> > > DONGWOON DW9807 LENS VOICE COIL DRIVER
> > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > > index 7793358..8ff6c95 100644
> > > --- a/drivers/media/i2c/Kconfig
> > > +++ b/drivers/media/i2c/Kconfig
> > > @@ -1014,6 +1014,16 @@ config VIDEO_DW9714
> > > capability. This is designed for linear control of
> > > voice coil motors, controlled via I2C serial interface.
> > >
> > > +config VIDEO_DW9768
> > > + tristate "DW9768 lens voice coil support"
> > > + depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
> > > + depends on VIDEO_V4L2_SUBDEV_API
> > > + help
> > > + This is a driver for the DW9768 camera lens voice coil.
> > > + DW9768 is a 10 bit DAC with 100mA output current sink
> > > + capability. This is designed for linear control of
> > > + voice coil motors, controlled via I2C serial interface.
> > > +
> > > config VIDEO_DW9807_VCM
> > > tristate "DW9807 lens voice coil support"
> > > depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
> > > diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> > > index d8ad9da..944fbf6 100644
> > > --- a/drivers/media/i2c/Makefile
> > > +++ b/drivers/media/i2c/Makefile
> > > @@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
> > > obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
> > > obj-$(CONFIG_VIDEO_AK7375) += ak7375.o
> > > obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
> > > +obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> > > obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> > > obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
> > > obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
> > > diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
> > > new file mode 100644
> > > index 0000000..f5b5591
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/dw9768.c
> > > @@ -0,0 +1,458 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (c) 2018 MediaTek Inc.
> > > + */
> > > +
> > > +#include <linux/delay.h>
> > > +#include <linux/i2c.h>
> > > +#include <linux/module.h>
> > > +#include <linux/regulator/consumer.h>
> > > +#include <linux/pm_runtime.h>
> > > +#include <media/v4l2-ctrls.h>
> > > +#include <media/v4l2-device.h>
> > > +#include <media/v4l2-subdev.h>
> > > +
> > > +#define DW9768_VOLTAGE_ANALOG 2800000
> >
> > This is a platform detail and should be defined in the platform data, for
> > example DTS on platforms using DT.
> >
>
> Thanks for your reminder.
> This would be fixed in next release.
>
> > > +#define DW9768_NAME "dw9768"
> >
> > The chip we seem to be using this driver for is called gt9769. Shouldn't we
> > call the driver the same?
> >
>
> It is also called DW9768 from camera module specification, which was
> initially confirmed with vendor.
>
Okay, thanks for clarifying.
Best regards,
Tomasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH ARM64 v4.4 V3 44/44] arm64: futex: Mask __user pointers prior to dereference
From: Viresh Kumar @ 2019-09-03 5:15 UTC (permalink / raw)
To: Mark Rutland
Cc: Julien Thierry, Marc Zyngier, Catalin Marinas, Will Deacon,
stable, mark.brown, Russell King, linux-arm-kernel
In-Reply-To: <20190830094249.GL46475@lakrids.cambridge.arm.com>
On 30-08-19, 10:42, Mark Rutland wrote:
> On Thu, Aug 29, 2019 at 05:04:29PM +0530, Viresh Kumar wrote:
> > From: Will Deacon <will.deacon@arm.com>
> >
> > commit 91b2d3442f6a44dce875670d702af22737ad5eff upstream.
> >
> > The arm64 futex code has some explicit dereferencing of user pointers
> > where performing atomic operations in response to a futex command. This
> > patch uses masking to limit any speculative futex operations to within
> > the user address space.
> >
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>
> This would have made more sense immediately following patch 11, as in
> mainline and the v4.9 backport. Having things applied in the same order
> makes it much easier to compare and verify.
Ahh, indeed the order was that way in the arm64/kpti branch, but not
in the stable branch where it got applied at the end and I followed
that order :(
Fixed the ordering now. Thanks.
--
viresh
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH V2 4/4] platform: mtk-isp: Add Mediatek FD driver
From: Tomasz Figa @ 2019-09-03 5:19 UTC (permalink / raw)
To: Jerry-ch Chen
Cc: devicetree@vger.kernel.org, Sean Cheng (鄭昇弘),
laurent.pinchart+renesas@ideasonboard.com,
Rynn Wu (吳育恩), srv_heupstream,
Po-Yang Huang (黃柏陽), mchehab@kernel.org,
suleiman@chromium.org, shik@chromium.org,
Jungo Lin (林明俊),
Sj Huang (黃信璋), yuzhao@chromium.org,
linux-mediatek@lists.infradead.org, zwisler@chromium.org,
matthias.bgg@gmail.com, Christie Yu (游雅惠),
Frederic Chen (陳俊元), hans.verkuil@cisco.com,
linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org
In-Reply-To: <1567424859.18318.32.camel@mtksdccf07>
On Mon, Sep 2, 2019 at 8:47 PM Jerry-ch Chen <Jerry-ch.Chen@mediatek.com> wrote:
>
> Hi Tomasz,
>
> On Fri, 2019-08-30 at 16:33 +0800, Tomasz Figa wrote:
> > On Wed, Aug 28, 2019 at 11:00 AM Jerry-ch Chen
> > <Jerry-ch.Chen@mediatek.com> wrote:
> > >
> > > Hi Tomasz,
> > >
> > > On Mon, 2019-08-26 at 14:36 +0800, Tomasz Figa wrote:
> > > > Hi Jerry,
> > > >
> > > > On Sun, Aug 25, 2019 at 6:18 PM Jerry-ch Chen
> > > > <Jerry-ch.Chen@mediatek.com> wrote:
> > > > >
> > > > > Hi Tomasz,
> > > > >
> > > > > On Fri, 2019-08-02 at 16:28 +0800, Tomasz Figa wrote:
> > > > > > Hi Jerry,
> > > > > >
> > > > > > On Tue, Jul 09, 2019 at 04:41:12PM +0800, Jerry-ch Chen wrote:
[snip]
> > > static int mtk_fd_vb2_queue_setup(struct vb2_queue *vq,
> > > unsigned int *num_buffers,
> > > unsigned int *num_planes,
> > > unsigned int sizes[],
> > > struct device *alloc_devs[])
> > > {
> > > struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> > > struct device *dev = ctx->dev;
> > > unsigned int size[2];
> > >
> > > switch (vq->type) {
> > > case V4L2_BUF_TYPE_META_CAPTURE:
> > > size[0] = ctx->dst_fmt.buffersize;
> > > break;
> > > case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> > > size[0] = ctx->src_fmt.plane_fmt[0].sizeimage;
> > > if (*num_planes == 2)
> > > size[1] = ctx->src_fmt.plane_fmt[1].sizeimage;
> > > break;
> > > }
> > >
> > > if (*num_planes == 1) {
> > > if (sizes[0] < size[0])
> > > return -EINVAL;
> > > } else if (*num_planes == 2) {
> > > if ((sizes[0] < size[0]) && (sizes[1] < size[1]))
> > > return -EINVAL;
> >
> > Can we just use a loop here and combine the 2 cases above?
> >
> > Also, we need to fail with -EINVAL if *num_planes is > 2.
> >
> > > } else {
> > > *num_planes = 1;
> > > sizes[0] = size[0];
> >
> > This should be the case if *num_planes == 0 and the number of planes
> > and sizes should match the currently active format.
> >
> I appreciate your comments,
>
> Ok, I will update as following:
> static int mtk_fd_vb2_queue_setup(struct vb2_queue *vq,
> unsigned int *num_buffers,
> unsigned int *num_planes,
> unsigned int sizes[],
> struct device *alloc_devs[])
> {
> struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> unsigned int size[2];
> unsigned int plane;
>
> switch (vq->type) {
> case V4L2_BUF_TYPE_META_CAPTURE:
> size[0] = ctx->dst_fmt.buffersize;
> break;
> case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> size[0] = ctx->src_fmt.plane_fmt[0].sizeimage;
> if (*num_planes == 2)
> size[1] = ctx->src_fmt.plane_fmt[1].sizeimage;
> break;
> }
>
> if (*num_planes > 2)
> return -EINVAL;
> if (*num_planes == 0) {
> if (vq->type == V4L2_BUF_TYPE_META_CAPTURE) {
> sizes[0] = ctx->dst_fmt.buffersize;
> *num_planes = 1;
> return 0;
> }
>
> *num_planes = ctx->src_fmt.num_planes;
> for (plane = 0; plane < *num_planes; plane++)
> sizes[plane] = ctx->src_fmt.plane_fmt[plane].sizeimage;
> return 0;
> }
>
> for (plane = 0; plane < *num_planes; plane++) {
> if(sizes[plane] < size[plane])
> return -EINVAL;
> }
> return 0;
> }
>
Looks good, thanks!
> > > }
> > >
> > > return 0;
> > > }
> > >
> > > > [snip]
> > > >
> > > > > > > +static void mtk_fd_vb2_stop_streaming(struct vb2_queue *vq)
> > > > > > > +{
> > > > > > > + struct mtk_fd_ctx *ctx = vb2_get_drv_priv(vq);
> > > > > > > + struct vb2_buffer *vb;
> > > > > >
> > > > > > How do we guarantee here that the hardware isn't still accessing the buffers
> > > > > > removed below?
> > > > > >
> > > > > Maybe we can check the driver state flag and aborting the unfinished
> > > > > jobs?
> > > > > (fd_hw->state == FD_ENQ)
> > > > >
> > > >
> > > > Yes, we need to either cancel or wait for the currently processing
> > > > job. It depends on hardware capabilities, but cancelling is generally
> > > > preferred for the lower latency.
> > > >
> > > Ok, it the state is ENQ, then we can disable the FD hw by controlling
> > > the registers.
> > >
> > > for example:
> > > writel(0x0, fd->fd_base + FD_HW_ENABLE);
> > > writel(0x0, fd->fd_base + FD_INT_EN);
> > >
> >
> > What's exactly the effect of writing 0 to FD_HW_ENABLE?
> >
> Sorry, my last reply didn't solve the question,
> we should implement a mtk_fd_job_abort() for v4l2_m2m_ops().
>
> which is able to readl_poll_timeout_atomic()
> and check the HW busy bits in the register FD_INT_EN;
>
> if they are not cleared until timeout, we could handle the last
> processing job.
> Otherwise, the FD irq handler should have handled the last processing
> job and we could continue the stop_streaming().
>
> For job_abort():
> static void mtk_fd_job_abort(void *priv)
> {
> struct mtk_fd_ctx *ctx = priv;
> struct mtk_fd_dev *fd = ctx->fd_dev;
> u32 val;
> u32 ret;
>
> ret = readl_poll_timeout_atomic(fd->fd_base + MTK_FD_REG_OFFSET_INT_EN,
> val,
> (val & MTK_FD_HW_BUSY_MASK) ==
> MTK_FD_HW_STATE_IS_BUSY,
> USEC_PER_MSEC, MTK_FD_STOP_HW_TIMEOUT);
Hmm, would it be possible to avoid the busy wait by having a
completion that could be signalled from the interrupt handler?
Best regards,
Tomasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 0/3] spi: uniphier: introduce polling mode and fix bug
From: Keiji Hayashibara @ 2019-09-03 5:30 UTC (permalink / raw)
To: broonie, yamada.masahiro, linux-spi, linux-arm-kernel
Cc: jaswinder.singh, linux-kernel, masami.hiramatsu,
hayashibara.keiji
This series introduces new polling mode and fixes bug.
- Introduce new polling mode for short size transfer. Either the estimated
transfer time is estimated to exceed 200us, or polling loop actually exceeds
200us, it switches to irq mode.
- Fix a bug of register overwrite.
- Minor corrections.
Keiji Hayashibara (3):
spi: uniphier: fix wrong register overwrite
spi: uniphier: remove unnecessary code
spi: uniphier: introduce polling mode
drivers/spi/spi-uniphier.c | 85 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 68 insertions(+), 17 deletions(-)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/3] spi: uniphier: fix wrong register overwrite
From: Keiji Hayashibara @ 2019-09-03 5:30 UTC (permalink / raw)
To: broonie, yamada.masahiro, linux-spi, linux-arm-kernel
Cc: jaswinder.singh, linux-kernel, masami.hiramatsu,
hayashibara.keiji
In-Reply-To: <1567488661-11428-1-git-send-email-hayashibara.keiji@socionext.com>
When it changes the spi mode, the register is overwritten incorrectly.
This commit fixes this register overwrite.
Signed-off-by: Keiji Hayashibara <hayashibara.keiji@socionext.com>
---
drivers/spi/spi-uniphier.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index c1e6f32..e6ebbb1 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -214,6 +214,7 @@ static void uniphier_spi_setup_transfer(struct spi_device *spi,
if (!priv->is_save_param || priv->mode != spi->mode) {
uniphier_spi_set_mode(spi);
priv->mode = spi->mode;
+ priv->is_save_param = false;
}
if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/3] spi: uniphier: remove unnecessary code
From: Keiji Hayashibara @ 2019-09-03 5:31 UTC (permalink / raw)
To: broonie, yamada.masahiro, linux-spi, linux-arm-kernel
Cc: jaswinder.singh, linux-kernel, masami.hiramatsu,
hayashibara.keiji
In-Reply-To: <1567488661-11428-1-git-send-email-hayashibara.keiji@socionext.com>
This commit removed if() because priv->is_save_param is always true.
Signed-off-by: Keiji Hayashibara <hayashibara.keiji@socionext.com>
---
drivers/spi/spi-uniphier.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index e6ebbb1..d40ad93 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -227,8 +227,7 @@ static void uniphier_spi_setup_transfer(struct spi_device *spi,
priv->speed_hz = t->speed_hz;
}
- if (!priv->is_save_param)
- priv->is_save_param = true;
+ priv->is_save_param = true;
/* reset FIFOs */
val = SSI_FC_TXFFL | SSI_FC_RXFFL;
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 3/3] spi: uniphier: introduce polling mode
From: Keiji Hayashibara @ 2019-09-03 5:31 UTC (permalink / raw)
To: broonie, yamada.masahiro, linux-spi, linux-arm-kernel
Cc: jaswinder.singh, linux-kernel, masami.hiramatsu,
hayashibara.keiji
In-Reply-To: <1567488661-11428-1-git-send-email-hayashibara.keiji@socionext.com>
Introduce new polling mode for short size transfer. Either the estimated
transfer time is estimated to exceed 200us, or polling loop actually exceeds
200us, it switches to irq mode.
Signed-off-by: Keiji Hayashibara <hayashibara.keiji@socionext.com>
---
drivers/spi/spi-uniphier.c | 81 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 66 insertions(+), 15 deletions(-)
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index d40ad93..6b83b25 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -7,6 +7,7 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -16,6 +17,7 @@
#include <asm/unaligned.h>
#define SSI_TIMEOUT_MS 2000
+#define SSI_POLL_TIMEOUT_US 200
#define SSI_MAX_CLK_DIVIDER 254
#define SSI_MIN_CLK_DIVIDER 4
@@ -290,21 +292,23 @@ static void uniphier_spi_recv(struct uniphier_spi_priv *priv)
static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv)
{
- unsigned int tx_count;
+ unsigned int fifo_threshold, fill_bytes;
u32 val;
- tx_count = DIV_ROUND_UP(priv->tx_bytes,
+ fifo_threshold = DIV_ROUND_UP(priv->rx_bytes,
bytes_per_word(priv->bits_per_word));
- tx_count = min(tx_count, SSI_FIFO_DEPTH);
+ fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH);
+
+ fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes);
/* set fifo threshold */
val = readl(priv->base + SSI_FC);
val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
- val |= FIELD_PREP(SSI_FC_TXFTH_MASK, tx_count);
- val |= FIELD_PREP(SSI_FC_RXFTH_MASK, tx_count);
+ val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold);
+ val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold);
writel(val, priv->base + SSI_FC);
- while (tx_count--)
+ while (fill_bytes--)
uniphier_spi_send(priv);
}
@@ -323,20 +327,14 @@ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
writel(val, priv->base + SSI_FPS);
}
-static int uniphier_spi_transfer_one(struct spi_master *master,
- struct spi_device *spi,
- struct spi_transfer *t)
+static int uniphier_spi_transfer_one_irq(struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *t)
{
struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
struct device *dev = master->dev.parent;
unsigned long time_left;
- /* Terminate and return success for 0 byte length transfer */
- if (!t->len)
- return 0;
-
- uniphier_spi_setup_transfer(spi, t);
-
reinit_completion(&priv->xfer_done);
uniphier_spi_fill_tx_fifo(priv);
@@ -356,6 +354,59 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
return priv->error;
}
+static int uniphier_spi_transfer_one_poll(struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+ int loop = SSI_POLL_TIMEOUT_US * 10;
+
+ while (priv->tx_bytes) {
+ uniphier_spi_fill_tx_fifo(priv);
+
+ while ((priv->rx_bytes - priv->tx_bytes) > 0) {
+ while (!(readl(priv->base + SSI_SR) & SSI_SR_RNE)
+ && loop--)
+ ndelay(100);
+
+ if (loop == -1)
+ goto irq_transfer;
+
+ uniphier_spi_recv(priv);
+ }
+ }
+
+ return 0;
+
+irq_transfer:
+ return uniphier_spi_transfer_one_irq(master, spi, t);
+}
+
+static int uniphier_spi_transfer_one(struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+ unsigned long threshold;
+
+ /* Terminate and return success for 0 byte length transfer */
+ if (!t->len)
+ return 0;
+
+ uniphier_spi_setup_transfer(spi, t);
+
+ /*
+ * If the transfer operation will take longer than
+ * SSI_POLL_TIMEOUT_US, it should use irq.
+ */
+ threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz,
+ USEC_PER_SEC * BITS_PER_BYTE);
+ if (t->len > threshold)
+ return uniphier_spi_transfer_one_irq(master, spi, t);
+ else
+ return uniphier_spi_transfer_one_poll(master, spi, t);
+}
+
static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master)
{
struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] ACPI: support for NXP i2c controller
From: Oleksij Rempel @ 2019-09-03 5:41 UTC (permalink / raw)
To: Andy Shevchenko, Rafael J. Wysocki
Cc: Wolfram Sang, Sascha Hauer, Udit Kumar, Rafael J. Wysocki,
Linux Kernel Mailing List, Leo Li, ACPI Devel Maling List,
Meenakshi Aggarwal, linux-i2c, Chuanhua Han, Shawn Guo, Linux ARM,
Len Brown
In-Reply-To: <CAHp75VfFtMMQhetRFHrx=Ft7OWwyMqLrwP3sPjT6YVtr8xCHoQ@mail.gmail.com>
Hi,
On 02.09.19 23:16, Andy Shevchenko wrote:
> On Mon, Sep 2, 2019 at 11:58 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
>>
>> On Thu, Jul 11, 2019 at 12:35 PM Chuanhua Han <chuanhua.han@nxp.com> wrote:
>>>
>>> Enable NXP i2c controller to boot with ACPI
>>>
>>> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
>>> Signed-off-by: Udit Kumar <udit.kumar@nxp.com>
>>> Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com>
>>
>> Wolfram, any objections to this from the i2c side?
>
> May I propose amendment(s)?
>
>>> @@ -44,6 +44,7 @@
>>> #include <linux/pm_runtime.h>
>>> #include <linux/sched.h>
>>> #include <linux/slab.h>
>
>>> +#include <linux/acpi.h>
>
> If it's kept in order, better to go with it. (Yes, it is as I have checked)
> However, property.h should be included instead, see below.
>
>>> const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
>>> &pdev->dev);
>>> + const struct acpi_device_id *acpi_id =
>>> + acpi_match_device(i2c_imx_acpi_ids,
>>> + &pdev->dev);
>
>
>>> if (of_id)
>>> i2c_imx->hwdata = of_id->data;
>>> + else if (acpi_id)
>>> + i2c_imx->hwdata = (struct imx_i2c_hwdata *)
>>> + acpi_id->driver_data;
>
>
> The above altogher may be replaced with
>
> const struct imx_i2c_hwdata *match;
> ...
> match = device_get_match_data(&pdev->dev);
> if (match)
> i2c_imx->hwdata = match;
> else
> ...
Instead of "may be replaced", I would say: it should be replaced :)
>>> + .acpi_match_table = ACPI_PTR(i2c_imx_acpi_ids),
>
> Since there is no #ifdef guard no need to use ACPI_PTR().
>
What iMX/(other NXP?) SoCs are with ACPI support? Where I can get one? I would like to
know more about it.
Kind regards,
Oleksij Rempel
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/1] arm64: dts: qcom: Add Lenovo Yoga C630
From: Bjorn Andersson @ 2019-09-03 5:44 UTC (permalink / raw)
To: Lee Jones
Cc: mark.rutland, devicetree, linux-arm-msm, linux-kernel, robh+dt,
agross, linux-arm-kernel
In-Reply-To: <20190902132400.14084-1-lee.jones@linaro.org>
On Mon 02 Sep 06:24 PDT 2019, Lee Jones wrote:
> From: Bjorn Andersson <bjorn.andersson@linaro.org>
>
> The Lenovo Yoga C630 is built on the SDM850 from Qualcomm, but this seem
> to be similar enough to the SDM845 that we can reuse the sdm845.dtsi.
>
> Supported by this patch is: keyboard, battery monitoring, UFS storage,
> USB host and Bluetooth.
Applied this to next-20190829 and booted it, got a little bit of EFI FB,
then the screen goes blank and after a while I'm back in GRUB.
I've not been able to figure out what's causing this though.
Regards,
Bjorn
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 1 +
> .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 450 ++++++++++++++++++
> 2 files changed, 451 insertions(+)
> create mode 100644 arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
>
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index 0a7e5dfce6f7..670c6c65f9e9 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -12,5 +12,6 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r2.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
> dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb
> dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
> diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
> new file mode 100644
> index 000000000000..3177b054035f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
> @@ -0,0 +1,450 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Lenovo Yoga C630
> + *
> + * Copyright (c) 2019, Linaro Ltd.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
> +#include "sdm845.dtsi"
> +#include "pm8998.dtsi"
> +
> +/ {
> + model = "Lenovo Yoga C630";
> + compatible = "lenovo,yoga-c630", "qcom,sdm845";
> +
> + aliases {
> + hsuart0 = &uart6;
> + };
> +};
> +
> +&apps_rsc {
> + pm8998-rpmh-regulators {
> + compatible = "qcom,pm8998-rpmh-regulators";
> + qcom,pmic-id = "a";
> +
> + vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
> + vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
> +
> + vreg_s2a_1p125: smps2 {
> + };
> +
> + vreg_s3a_1p35: smps3 {
> + regulator-min-microvolt = <1352000>;
> + regulator-max-microvolt = <1352000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_s4a_1p8: smps4 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_s5a_2p04: smps5 {
> + regulator-min-microvolt = <2040000>;
> + regulator-max-microvolt = <2040000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_s7a_1p025: smps7 {
> + };
> +
> + vdd_qusb_hs0:
> + vdda_hp_pcie_core:
> + vdda_mipi_csi0_0p9:
> + vdda_mipi_csi1_0p9:
> + vdda_mipi_csi2_0p9:
> + vdda_mipi_dsi0_pll:
> + vdda_mipi_dsi1_pll:
> + vdda_qlink_lv:
> + vdda_qlink_lv_ck:
> + vdda_qrefs_0p875:
> + vdda_pcie_core:
> + vdda_pll_cc_ebi01:
> + vdda_pll_cc_ebi23:
> + vdda_sp_sensor:
> + vdda_ufs1_core:
> + vdda_ufs2_core:
> + vdda_usb1_ss_core:
> + vdda_usb2_ss_core:
> + vreg_l1a_0p875: ldo1 {
> + regulator-min-microvolt = <880000>;
> + regulator-max-microvolt = <880000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vddpx_10:
> + vreg_l2a_1p2: ldo2 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + regulator-always-on;
> + };
> +
> + vreg_l3a_1p0: ldo3 {
> + };
> +
> + vdd_wcss_cx:
> + vdd_wcss_mx:
> + vdda_wcss_pll:
> + vreg_l5a_0p8: ldo5 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <800000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vddpx_13:
> + vreg_l6a_1p8: ldo6 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l7a_1p8: ldo7 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l8a_1p2: ldo8 {
> + };
> +
> + vreg_l9a_1p8: ldo9 {
> + };
> +
> + vreg_l10a_1p8: ldo10 {
> + };
> +
> + vreg_l11a_1p0: ldo11 {
> + };
> +
> + vdd_qfprom:
> + vdd_qfprom_sp:
> + vdda_apc1_cs_1p8:
> + vdda_gfx_cs_1p8:
> + vdda_qrefs_1p8:
> + vdda_qusb_hs0_1p8:
> + vddpx_11:
> + vreg_l12a_1p8: ldo12 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vddpx_2:
> + vreg_l13a_2p95: ldo13 {
> + };
> +
> + vreg_l14a_1p88: ldo14 {
> + regulator-min-microvolt = <1880000>;
> + regulator-max-microvolt = <1880000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l15a_1p8: ldo15 {
> + };
> +
> + vreg_l16a_2p7: ldo16 {
> + };
> +
> + vreg_l17a_1p3: ldo17 {
> + regulator-min-microvolt = <1304000>;
> + regulator-max-microvolt = <1304000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l18a_2p7: ldo18 {
> + };
> +
> + vreg_l19a_3p0: ldo19 {
> + regulator-min-microvolt = <3100000>;
> + regulator-max-microvolt = <3108000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l20a_2p95: ldo20 {
> + regulator-min-microvolt = <2960000>;
> + regulator-max-microvolt = <2960000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l21a_2p95: ldo21 {
> + };
> +
> + vreg_l22a_2p85: ldo22 {
> + };
> +
> + vreg_l23a_3p3: ldo23 {
> + };
> +
> + vdda_qusb_hs0_3p1:
> + vreg_l24a_3p075: ldo24 {
> + regulator-min-microvolt = <3075000>;
> + regulator-max-microvolt = <3083000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l25a_3p3: ldo25 {
> + regulator-min-microvolt = <3104000>;
> + regulator-max-microvolt = <3112000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vdda_hp_pcie_1p2:
> + vdda_hv_ebi0:
> + vdda_hv_ebi1:
> + vdda_hv_ebi2:
> + vdda_hv_ebi3:
> + vdda_mipi_csi_1p25:
> + vdda_mipi_dsi0_1p2:
> + vdda_mipi_dsi1_1p2:
> + vdda_pcie_1p2:
> + vdda_ufs1_1p2:
> + vdda_ufs2_1p2:
> + vdda_usb1_ss_1p2:
> + vdda_usb2_ss_1p2:
> + vreg_l26a_1p2: ldo26 {
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1208000>;
> + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
> + };
> +
> + vreg_l28a_3p0: ldo28 {
> + };
> +
> + vreg_lvs1a_1p8: lvs1 {
> + };
> +
> + vreg_lvs2a_1p8: lvs2 {
> + };
> + };
> +};
> +
> +&apps_smmu {
> + /* TODO: Figure out how to survive booting with this enabled */
> + status = "disabled";
> +};
> +
> +&gcc {
> + protected-clocks = <GCC_QSPI_CORE_CLK>,
> + <GCC_QSPI_CORE_CLK_SRC>,
> + <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
> +};
> +
> +&i2c1 {
> + status = "okay";
> + clock-frequency = <400000>;
> +
> + battery@70 {
> + compatible = "some,battery";
> + reg = <0x70>;
> + };
> +};
> +
> +&i2c3 {
> + status = "okay";
> + clock-frequency = <400000>;
> +
> + hid@15 {
> + compatible = "hid-over-i2c";
> + reg = <0x15>;
> + hid-descr-addr = <0x1>;
> +
> + interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>;
> + };
> +
> + hid@2c {
> + compatible = "hid-over-i2c";
> + reg = <0x2c>;
> + hid-descr-addr = <0x20>;
> +
> + interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>;
> +
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c2_hid_active>;
> + };
> +};
> +
> +&i2c5 {
> + status = "okay";
> + clock-frequency = <400000>;
> +
> + hid@10 {
> + compatible = "hid-over-i2c";
> + reg = <0x10>;
> + hid-descr-addr = <0x1>;
> +
> + interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>;
> +
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c6_hid_active>;
> + };
> +};
> +
> +&i2c11 {
> + status = "okay";
> + clock-frequency = <400000>;
> +
> + hid@5c {
> + compatible = "hid-over-i2c";
> + reg = <0x5c>;
> + hid-descr-addr = <0x1>;
> +
> + interrupts-extended = <&tlmm 92 IRQ_TYPE_LEVEL_LOW>;
> +
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c12_hid_active>;
> + };
> +};
> +
> +&qupv3_id_0 {
> + status = "okay";
> +};
> +
> +&qupv3_id_1 {
> + status = "okay";
> +};
> +
> +&tlmm {
> + gpio-reserved-ranges = <0 4>, <81 4>;
> +
> + i2c2_hid_active: i2c2-hid-active {
> + pins = <37>;
> + function = "gpio";
> +
> + input-enable;
> + bias-pull-up;
> + drive-strength = <2>;
> + };
> +
> + i2c6_hid_active: i2c6-hid-active {
> + pins = <125>;
> + function = "gpio";
> +
> + input-enable;
> + bias-pull-up;
> + drive-strength = <2>;
> + };
> +
> + i2c12_hid_active: i2c12-hid-active {
> + pins = <92>;
> + function = "gpio";
> +
> + input-enable;
> + bias-pull-up;
> + drive-strength = <2>;
> + };
> +};
> +
> +&uart6 {
> + status = "okay";
> +
> + bluetooth {
> + compatible = "qcom,wcn3990-bt";
> +
> + vddio-supply = <&vreg_s4a_1p8>;
> + vddxo-supply = <&vreg_l7a_1p8>;
> + vddrf-supply = <&vreg_l17a_1p3>;
> + vddch0-supply = <&vreg_l25a_3p3>;
> + max-speed = <3200000>;
> + };
> +};
> +
> +&ufs_mem_hc {
> + status = "okay";
> +
> + vcc-supply = <&vreg_l20a_2p95>;
> + vcc-max-microamp = <600000>;
> +};
> +
> +&ufs_mem_phy {
> + status = "okay";
> +
> + vdda-phy-supply = <&vdda_ufs1_core>;
> + vdda-pll-supply = <&vdda_ufs1_1p2>;
> +};
> +
> +&usb_1 {
> + status = "okay";
> +};
> +
> +&usb_1_dwc3 {
> + dr_mode = "host";
> +};
> +
> +&usb_1_hsphy {
> + status = "okay";
> +
> + vdd-supply = <&vdda_usb1_ss_core>;
> + vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
> + vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
> +
> + qcom,imp-res-offset-value = <8>;
> + qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
> + qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
> + qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
> +};
> +
> +&usb_1_qmpphy {
> + status = "okay";
> +
> + vdda-phy-supply = <&vdda_usb1_ss_1p2>;
> + vdda-pll-supply = <&vdda_usb1_ss_core>;
> +};
> +
> +&usb_2 {
> + status = "okay";
> +};
> +
> +&usb_2_dwc3 {
> + dr_mode = "host";
> +};
> +
> +&usb_2_hsphy {
> + status = "okay";
> +
> + vdd-supply = <&vdda_usb2_ss_core>;
> + vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
> + vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
> +
> + qcom,imp-res-offset-value = <8>;
> + qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_22_8_MA>;
> +};
> +
> +&usb_2_qmpphy {
> + status = "okay";
> +
> + vdda-phy-supply = <&vdda_usb2_ss_1p2>;
> + vdda-pll-supply = <&vdda_usb2_ss_core>;
> +};
> +
> +&qup_i2c12_default {
> + drive-strength = <2>;
> + bias-disable;
> +};
> +
> +&qup_uart6_default {
> + pinmux {
> + pins = "gpio45", "gpio46", "gpio47", "gpio48";
> + function = "qup6";
> + };
> +
> + cts {
> + pins = "gpio45";
> + bias-pull-down;
> + };
> +
> + rts-tx {
> + pins = "gpio46", "gpio47";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +
> + rx {
> + pins = "gpio48";
> + bias-pull-up;
> + };
> +};
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] drm: bridge/dw_hdmi: add audio sample channel status setting
From: Cheng-Yi Chiang @ 2019-09-03 5:51 UTC (permalink / raw)
To: linux-kernel
Cc: alsa-devel, tzungbi, zhengxing, kuninori.morimoto.gx, a.hajda,
airlied, kuankuan.y, jeffy.chen, dianders, dri-devel, cain.cai,
linux-rockchip, eddie.cai, Laurent.pinchart, daniel, Yakir Yang,
enric.balletbo, dgreid, sam, linux-arm-kernel, cychiang
From: Yakir Yang <ykk@rock-chips.com>
When transmitting IEC60985 linear PCM audio, we configure the
Audio Sample Channel Status information of all the channel
status bits in the IEC60958 frame.
Refer to 60958-3 page 10 for frequency, original frequency, and
wordlength setting.
This fix the issue that audio does not come out on some monitors
(e.g. LG 22CV241)
Signed-off-by: Yakir Yang <ykk@rock-chips.com>
Signed-off-by: Cheng-Yi Chiang <cychiang@chromium.org>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 59 +++++++++++++++++++++++
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 20 ++++++++
2 files changed, 79 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bd65d0479683..34d46e25d610 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -582,6 +582,63 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
return n;
}
+static void hdmi_set_schnl(struct dw_hdmi *hdmi)
+{
+ u8 aud_schnl_samplerate;
+ u8 aud_schnl_8;
+
+ /* These registers are on RK3288 using version 2.0a. */
+ if (hdmi->version != 0x200a)
+ return;
+
+ switch (hdmi->sample_rate) {
+ case 32000:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_32K;
+ break;
+ case 44100:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_44K1;
+ break;
+ case 48000:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_48K;
+ break;
+ case 88200:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_88K2;
+ break;
+ case 96000:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_96K;
+ break;
+ case 176400:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_176K4;
+ break;
+ case 192000:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_192K;
+ break;
+ case 768000:
+ aud_schnl_samplerate = HDMI_FC_AUDSCHNLS7_SMPRATE_768K;
+ break;
+ default:
+ dev_warn(hdmi->dev, "Unsupported audio sample rate (%u)\n",
+ hdmi->sample_rate);
+ return;
+ }
+
+ /* set channel status register */
+ hdmi_modb(hdmi, aud_schnl_samplerate, HDMI_FC_AUDSCHNLS7_SMPRATE_MASK,
+ HDMI_FC_AUDSCHNLS7);
+
+ /*
+ * Set original frequency to be the same as frequency.
+ * Use one-complement value as stated in IEC60958-3 page 13.
+ */
+ aud_schnl_8 = (~aud_schnl_samplerate) <<
+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET;
+
+ /* This means word length is 16 bit. Refer to IEC60958-3 page 12. */
+ aud_schnl_8 |= 2 << HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET;
+
+ hdmi_writeb(hdmi, aud_schnl_8, HDMI_FC_AUDSCHNLS8);
+}
+
static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
unsigned long pixel_clk, unsigned int sample_rate)
{
@@ -620,6 +677,8 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
hdmi->audio_cts = cts;
hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0);
spin_unlock_irq(&hdmi->audio_lock);
+
+ hdmi_set_schnl(hdmi);
}
static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index 6988f12d89d9..619ebc1c8354 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -158,6 +158,17 @@
#define HDMI_FC_SPDDEVICEINF 0x1062
#define HDMI_FC_AUDSCONF 0x1063
#define HDMI_FC_AUDSSTAT 0x1064
+#define HDMI_FC_AUDSV 0x1065
+#define HDMI_FC_AUDSU 0x1066
+#define HDMI_FC_AUDSCHNLS0 0x1067
+#define HDMI_FC_AUDSCHNLS1 0x1068
+#define HDMI_FC_AUDSCHNLS2 0x1069
+#define HDMI_FC_AUDSCHNLS3 0x106a
+#define HDMI_FC_AUDSCHNLS4 0x106b
+#define HDMI_FC_AUDSCHNLS5 0x106c
+#define HDMI_FC_AUDSCHNLS6 0x106d
+#define HDMI_FC_AUDSCHNLS7 0x106e
+#define HDMI_FC_AUDSCHNLS8 0x106f
#define HDMI_FC_DATACH0FILL 0x1070
#define HDMI_FC_DATACH1FILL 0x1071
#define HDMI_FC_DATACH2FILL 0x1072
@@ -706,6 +717,15 @@ enum {
/* HDMI_FC_AUDSCHNLS7 field values */
HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_192K = 0xe,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_176K4 = 0xc,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_96K = 0xa,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_768K = 0x9,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_88K2 = 0x8,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_32K = 0x3,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_48K = 0x2,
+ HDMI_FC_AUDSCHNLS7_SMPRATE_44K1 = 0x0,
/* HDMI_FC_AUDSCHNLS8 field values */
HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
--
2.23.0.187.g17f5b7556c-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* RE: FYI: imx-sdma firmware is not compatible with SLUB slab allocator
From: Robin Gong @ 2019-09-03 5:57 UTC (permalink / raw)
To: Jurgen Lambrecht, Leonard Crestez
Cc: Aisheng Dong, dl-linux-imx, linux-arm-kernel@lists.infradead.org
In-Reply-To: <f68d8972-7471-6544-d50f-55267e6790a7@televic.com>
On 2019-8-29 14:24, Jurgen Lambrecht wrote:
> On 8/28/19 4:05 PM, Robin Gong wrote:
> > Could you help check if below commit in your side?
> > commit ebb853b1bd5f659b92c71dc6a9de44cfc37c78c0
> > Author: Lucas Stach<l.stach@pengutronix.de>
> > Date: Tue Nov 6 03:40:28 2018 +0000
>
> yes, it's in.
>
> Also the 2 follow-up commits of Lucas Stach:
> 9063f5a99ea76f85935e3e453422d15e7be89b9e and
> 374f384bc66f7a928f11eb20c0518f0f3fc1ffd6.
>
> And that are the last commits on drivers/dma/imx-sdma.c for my 4.19.x+fslc
> branch. But I have already tried 5.1.x+fslc, and it also got stuck.
Sorry, I can't reproduce your issue on Linux 5.3-rc6 with 'CONFIG_SLOB=y' and
SDMA firmware built in kernel, Could you have a try on our imx6ul-14x14-evk
board with Linux 5.3-rc6 directly(no any patch needed)?
root@imx6ul7d:~# dmesg | grep dma
[ 0.991928] mxs-dma 1804000.dma-apbh: initialized
[ 4.162199] imx-sdma 20ec000.sdma: loaded firmware 3.5
>
> Kind regards,
>
> Jürgen
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clocksource: atmel-st: Variable sr in at91rm9200_timer_interrupt() could be uninitialized
From: Yizhuo Zhai @ 2019-09-03 5:56 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Chengyu Song, Daniel Lezcano, Zhiyun Qian, linux-kernel,
Ludovic Desroches, Thomas Gleixner, linux-arm-kernel
In-Reply-To: <20190902223650.GJ21922@piout.net>
In function regmap_read(), there're two places which could make the read fail.
First, if "reg" and "map->reg_stride" are not aligned, then remap_read() will
return -EINVAL without initialize variable "val".
Second, _regmap_read() could also fail and return error code if "val" is not
initialized. The caller remap_read() returns the same error code, but
at91rm9200_timer_interrupt() does not use this information.
On Mon, Sep 2, 2019 at 3:37 PM Alexandre Belloni
<alexandre.belloni@bootlin.com> wrote:
>
> On 02/09/2019 15:29:46-0700, Yizhuo wrote:
> > Inside function at91rm9200_timer_interrupt(), variable sr could
> > be uninitialized if regmap_read() fails. However, sr is used
>
> Could you elaborate on how this could fail?
>
> > to decide the control flow later in the if statement, which is
> > potentially unsafe. We could check the return value of
> > regmap_read() and print an error here.
> >
> > Signed-off-by: Yizhuo <yzhai003@ucr.edu>
> > ---
> > drivers/clocksource/timer-atmel-st.c | 8 +++++++-
> > 1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
> > index ab0aabfae5f0..061a3f27847e 100644
> > --- a/drivers/clocksource/timer-atmel-st.c
> > +++ b/drivers/clocksource/timer-atmel-st.c
> > @@ -48,8 +48,14 @@ static inline unsigned long read_CRTR(void)
> > static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
> > {
> > u32 sr;
> > + int ret;
> > +
> > + ret = regmap_read(regmap_st, AT91_ST_SR, &sr);
> > + if (ret) {
> > + pr_err("Fail to read AT91_ST_SR.\n");
> > + return ret;
> > + }
> >
> > - regmap_read(regmap_st, AT91_ST_SR, &sr);
> > sr &= irqmask;
> >
> > /*
> > --
> > 2.17.1
> >
>
> --
> Alexandre Belloni, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
Kind Regards,
Yizhuo Zhai
Computer Science, Graduate Student
University of California, Riverside
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox