* [PATCH v2] i2c: stm32: Fix copyrights
From: Wolfram Sang @ 2017-12-07 13:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9fe6a754-b4fe-970b-c4dd-23b0687b9207@st.com>
> I take over ownership of this driver from now on.
>
> Acked-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
Ok. Thanks! Can you create a MAINTAINERS entry so you will get
automatically CCed on patches touching your driver?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171207/f3e7f150/attachment.sig>
^ permalink raw reply
* [PATCH] arm64: allwinner: a64: orangepi-zero-plus2: add usb otg
From: Maxime Ripard @ 2017-12-07 13:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512644748-14491-1-git-send-email-jagan@amarulasolutions.com>
Hi,
On Thu, Dec 07, 2017 at 04:35:48PM +0530, Jagan Teki wrote:
> Add usb otg support for orangepi-zero-plus2 board:
> - Add usb_otg node with dr_mode as 'otg'
> - USB0-IDDET connected to PA21
> - VBUS connected through DCIN which always on
>
> Tested mass storage function.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Did you test the OTG or peripheral modes?
> Note: Anyone please check vbus connection [1]
> Since it is connected through DCIN of vcc-5v, I've added vcc-5v0
> regulator for the same and attached to usb0_vbus-supply but it is
> disabling during kernel boot.
> [ 1.887854] vcc5v0: disabling
VBUS is the power line that is provided on the USB connector. In
peripheral, that power is provided by the host, therefore it needs to
be shutdown on the peripheral end. This is the expected behaviour.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20171207/372d069a/attachment.sig>
^ permalink raw reply
* [PATCH] perf: qcom_l2_pmu: don't allow guest access
From: Will Deacon @ 2017-12-07 13:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <bc650fac-702c-e554-43ca-9cd3cfed9696@codeaurora.org>
On Wed, Dec 06, 2017 at 04:19:24PM -0500, Leeder, Neil wrote:
> On 12/6/2017 11:11 AM, Mark Rutland wrote:
> > On Wed, Dec 06, 2017 at 10:55:33AM -0500, Neil Leeder wrote:
> >> Guests cannot access IMPDEF system registers, which are used
> >> by this driver. Disable the driver if it's running in a guest VM.
> >>
> >> Signed-off-by: Neil Leeder <nleeder@codeaurora.org>
> >> ---
> >> drivers/perf/qcom_l2_pmu.c | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >
> > I'm a little confused by this. Why is this hypervisor providing a
> > QCOM8130 device to the guest that it cannot use?
> >
> > Could you elaborate on what's going on?
> >
>
> While there's an argument that the guest shouldn't be loading the driver
> in the first place, we can't control everyone's guest configuration or what
> their hypervisor does.
Ok, but why is the hypervisor advertising a device that effectively doesn't
exist? Most drivers trust the firmware tables they are given, so this makes
it sound like we should start annotating all drivers for devices that we
don't expect to see in a guest with is_hyp_mode_available() checks.
That doesn't feel quite right to me.
Will
^ permalink raw reply
* [PATCH v2] i2c: stm32: Fix copyrights
From: Pierre Yves MORDRET @ 2017-12-07 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207133114.yma62uhgk6apny3c@ninjato>
Ok. will do
~PYM~
On 12/07/2017 02:31 PM, Wolfram Sang wrote:
>
>> I take over ownership of this driver from now on.
>>
>> Acked-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
>
> Ok. Thanks! Can you create a MAINTAINERS entry so you will get
> automatically CCed on patches touching your driver?
>
^ permalink raw reply
* [PATCH v2 0/7] Add CPU Frequency scaling support on Armada 37xx
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This is the second version of a series adding the CPU Frequency
support on Armada 37xx using DVFS. It is based on the initial work of
Evan Wang and Victor Gu.
The main change since the first version was a bug fixed in the
"cpufreq: Add DVFS support for Armada 37xx" patch which was preventing
to register the opp. An other noticeable change is the 4th patch which
is new adding the use of dev_pm_opp_remove and removing an comment
became wrong. The other changes are described in the change log.
DVFS control is done by a set of registers from the North Bridge Power
Management block. The binding for this block is documented in patch 1.
While adding a new cpufreq driver I found that the Kconfig and
Makefile were no more in order, so it is fixed by patch 2 and 3.
The 5th patch is just about updating the MAINTAINERS file with the new
driver.
The next patch is the real purpose of the series. The main goal of
this driver is to setup the CPU load level in the hardware to
associate them to CPU frequencies and register a standard cpufreq
driver. Note that the hardware also capable of doing AVS (Adaptive
Voltage Scaling), by associating a voltage on each level beside the
CPU frequency. However, this support is not yet ready, so it is not
part of this series.
Finally, the last patch is for arm-soc the arm-soc subsystem through
mvebu and update the device tree to support the CPU frequency scaling.
An update on the CPU clock driver is needed in order to take into
account the DVFS setting. It's the purpose of an other series already
sent, but is no dependencies between the series (for building or at
runtime).
Thanks,
Gregory
Changelog:
v1 -> v2:
- using syscon instead of nb_pm for the binding of the North bridge
power management unit: reported by Rob Herring
- fix sorting inside the big LITTLE section for the Kconfig: reported
by Viresh Kumar
- fix the bogus freq calculation in armada37xx_cpufreq_driver_init,
bug reported by Andre Heider
- use dev_pm_opp_remove() on the previous opp if dev_pm_opp_add()
failed, reported by Viresh Kumar
- add the Tested-by flag from Andre Heider on "cpufreq: Add DVFS
support for Armada 37xx" patch
Gregory CLEMENT (7):
dt-bindings: marvell: Add documentation for the North Bridge PM on
Armada 37xx
cpufreq: ARM: sort the Kconfig menu
cpufreq: sort the drivers in ARM part
cpufreq: mvebu: Use dev_pm_opp_remove()
MAINTAINERS: add new entries for Armada 37xx cpufreq driver
cpufreq: Add DVFS support for Armada 37xx
arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support
.../bindings/arm/marvell/armada-37xx.txt | 19 ++
MAINTAINERS | 1 +
arch/arm64/boot/dts/marvell/armada-372x.dtsi | 1 +
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 7 +
drivers/cpufreq/Kconfig.arm | 89 ++++----
drivers/cpufreq/Makefile | 9 +-
drivers/cpufreq/armada-37xx-cpufreq.c | 241 +++++++++++++++++++++
drivers/cpufreq/mvebu-cpufreq.c | 11 +-
8 files changed, 327 insertions(+), 51 deletions(-)
create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c
--
2.15.0
^ permalink raw reply
* [PATCH v2 1/7] dt-bindings: marvell: Add documentation for the North Bridge PM on Armada 37xx
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
Extend the documentation of the Armada 37xx SoC with the the North
Bridge Power Management component.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/arm/marvell/armada-37xx.txt | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
index 51336e5fc761..35c3c3460d17 100644
--- a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
@@ -14,3 +14,22 @@ following property before the previous one:
Example:
compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710";
+
+
+Power management
+----------------
+
+For power management (particularly DVFS and AVS), the North Bridge
+Power Management component is needed:
+
+Required properties:
+- compatible : should contain "marvell,armada-3700-nb-pm", "syscon";
+- reg : the register start and length for the North Bridge
+ Power Management
+
+Example:
+
+nb_pm: syscon at 14000 {
+ compatible = "marvell,armada-3700-nb-pm", "syscon";
+ reg = <0x14000 0x60>;
+}
--
2.15.0
^ permalink raw reply related
* [PATCH v2 2/7] cpufreq: ARM: sort the Kconfig menu
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
Group all the related big LITTLE configuration together and sort the
other entries in alphabetic order.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/cpufreq/Kconfig.arm | 82 ++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 41 deletions(-)
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index bdce4488ded1..0baf43837b51 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -2,6 +2,23 @@
# ARM CPU Frequency scaling drivers
#
+config ACPI_CPPC_CPUFREQ
+ tristate "CPUFreq driver based on the ACPI CPPC spec"
+ depends on ACPI_PROCESSOR
+ select ACPI_CPPC_LIB
+ default n
+ help
+ This adds a CPUFreq driver which uses CPPC methods
+ as described in the ACPIv5.1 spec. CPPC stands for
+ Collaborative Processor Performance Controls. It
+ is based on an abstract continuous scale of CPU
+ performance values which allows the remote power
+ processor to flexibly optimize for power and
+ performance. CPPC relies on power management firmware
+ support for its operation.
+
+ If in doubt, say N.
+
# big LITTLE core layer and glue drivers
config ARM_BIG_LITTLE_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver"
@@ -12,6 +29,30 @@ config ARM_BIG_LITTLE_CPUFREQ
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
+config ARM_DT_BL_CPUFREQ
+ tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
+ depends on ARM_BIG_LITTLE_CPUFREQ && OF
+ help
+ This enables probing via DT for Generic CPUfreq driver for ARM
+ big.LITTLE platform. This gets frequency tables from DT.
+
+config ARM_SCPI_CPUFREQ
+ tristate "SCPI based CPUfreq driver"
+ depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
+ help
+ This adds the CPUfreq driver support for ARM big.LITTLE platforms
+ using SCPI protocol for CPU power management.
+
+ This driver uses SCPI Message Protocol driver to interact with the
+ firmware providing the CPU DVFS functionality.
+
+config ARM_VEXPRESS_SPC_CPUFREQ
+ tristate "Versatile Express SPC based CPUfreq driver"
+ depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
+ help
+ This add the CPUfreq driver support for Versatile Express
+ big.LITTLE platforms using SPC for power management.
+
config ARM_BRCMSTB_AVS_CPUFREQ
tristate "Broadcom STB AVS CPUfreq driver"
depends on ARCH_BRCMSTB || COMPILE_TEST
@@ -33,20 +74,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
If in doubt, say N.
-config ARM_DT_BL_CPUFREQ
- tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
- depends on ARM_BIG_LITTLE_CPUFREQ && OF
- help
- This enables probing via DT for Generic CPUfreq driver for ARM
- big.LITTLE platform. This gets frequency tables from DT.
-
-config ARM_VEXPRESS_SPC_CPUFREQ
- tristate "Versatile Express SPC based CPUfreq driver"
- depends on ARM_BIG_LITTLE_CPUFREQ && ARCH_VEXPRESS_SPC
- help
- This add the CPUfreq driver support for Versatile Express
- big.LITTLE platforms using SPC for power management.
-
config ARM_EXYNOS5440_CPUFREQ
tristate "SAMSUNG EXYNOS5440"
depends on SOC_EXYNOS5440
@@ -205,16 +232,6 @@ config ARM_SA1100_CPUFREQ
config ARM_SA1110_CPUFREQ
bool
-config ARM_SCPI_CPUFREQ
- tristate "SCPI based CPUfreq driver"
- depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
- help
- This adds the CPUfreq driver support for ARM big.LITTLE platforms
- using SCPI protocol for CPU power management.
-
- This driver uses SCPI Message Protocol driver to interact with the
- firmware providing the CPU DVFS functionality.
-
config ARM_SPEAR_CPUFREQ
bool "SPEAr CPUFreq support"
depends on PLAT_SPEAR
@@ -275,20 +292,3 @@ config ARM_PXA2xx_CPUFREQ
This add the CPUFreq driver support for Intel PXA2xx SOCs.
If in doubt, say N.
-
-config ACPI_CPPC_CPUFREQ
- tristate "CPUFreq driver based on the ACPI CPPC spec"
- depends on ACPI_PROCESSOR
- select ACPI_CPPC_LIB
- default n
- help
- This adds a CPUFreq driver which uses CPPC methods
- as described in the ACPIv5.1 spec. CPPC stands for
- Collaborative Processor Performance Controls. It
- is based on an abstract continuous scale of CPU
- performance values which allows the remote power
- processor to flexibly optimize for power and
- performance. CPPC relies on power management firmware
- support for its operation.
-
- If in doubt, say N.
--
2.15.0
^ permalink raw reply related
* [PATCH v2 3/7] cpufreq: sort the drivers in ARM part
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
Keep the driver files alphabetically sorted.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/cpufreq/Makefile | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 812f9e0d01a3..d762e76887e7 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -53,22 +53,24 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o
+obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
+obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
-obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o
-obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o
obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o
obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
obj-$(CONFIG_ARM_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o
obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o
@@ -81,8 +83,6 @@ obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o
obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o
obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
-obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
-obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
##################################################################################
--
2.15.0
^ permalink raw reply related
* [PATCH v2 4/7] cpufreq: mvebu: Use dev_pm_opp_remove()
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
Since the introduction of this driver, the dev_pm_opp_remove() was
added. So stop claiming we can't remove opp and use it in case of
failure.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/cpufreq/mvebu-cpufreq.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/cpufreq/mvebu-cpufreq.c b/drivers/cpufreq/mvebu-cpufreq.c
index ed915ee85dd9..419c2b01a44c 100644
--- a/drivers/cpufreq/mvebu-cpufreq.c
+++ b/drivers/cpufreq/mvebu-cpufreq.c
@@ -76,12 +76,6 @@ static int __init armada_xp_pmsu_cpufreq_init(void)
return PTR_ERR(clk);
}
- /*
- * In case of a failure of dev_pm_opp_add(), we don't
- * bother with cleaning up the registered OPP (there's
- * no function to do so), and simply cancel the
- * registration of the cpufreq device.
- */
ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk), 0);
if (ret) {
clk_put(clk);
@@ -90,6 +84,11 @@ static int __init armada_xp_pmsu_cpufreq_init(void)
ret = dev_pm_opp_add(cpu_dev, clk_get_rate(clk) / 2, 0);
if (ret) {
+ /*
+ * The second opp failed to be added, remove
+ * the first one before exiting.
+ */
+ dev_pm_opp_remove(cpu_dev, clk_get_rate(clk));
clk_put(clk);
return ret;
}
--
2.15.0
^ permalink raw reply related
* [PATCH v2 5/7] MAINTAINERS: add new entries for Armada 37xx cpufreq driver
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
This new driver belongs to the mvebu family, update the MAINTAINER file
to document it.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index aa71ab52fd76..98dcee849481 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1582,6 +1582,7 @@ F: arch/arm/boot/dts/kirkwood*
F: arch/arm/configs/mvebu_*_defconfig
F: arch/arm/mach-mvebu/
F: arch/arm64/boot/dts/marvell/armada*
+F: drivers/cpufreq/armada-37xx-cpufreq.c
F: drivers/cpufreq/mvebu-cpufreq.c
F: drivers/irqchip/irq-armada-370-xp.c
F: drivers/irqchip/irq-mvebu-*
--
2.15.0
^ permalink raw reply related
* [PATCH v2 6/7] cpufreq: Add DVFS support for Armada 37xx
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
This patch adds DVFS support for the Armada 37xx SoCs
There are up to four CPU frequency loads for Armada 37xx controlled by
the hardware.
This driver associates the CPU load level to a frequency, then the
hardware will switch while selecting a load level.
The hardware also can associate a voltage for each level (AVS support)
but it is not yet supported
Tested-by: Andre Heider <a.heider@gmail.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/cpufreq/Kconfig.arm | 7 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++
3 files changed, 249 insertions(+)
create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 0baf43837b51..93c2987da83b 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -19,6 +19,13 @@ config ACPI_CPPC_CPUFREQ
If in doubt, say N.
+config ARM_ARMADA_37XX_CPUFREQ
+ tristate "Armada 37xx CPUFreq support"
+ depends on ARCH_MVEBU
+ help
+ This adds the CPUFreq driver support for Marvell Armada 37xx SoCs.
+ The Armada 37xx PMU supports 4 frequency and VDD levels.
+
# big LITTLE core layer and glue drivers
config ARM_BIG_LITTLE_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index d762e76887e7..e07715ce8844 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
# LITTLE drivers, so that it is probed last.
obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
+obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o
obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) += brcmstb-avs-cpufreq.o
obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
new file mode 100644
index 000000000000..3cd74384d03d
--- /dev/null
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CPU frequency scaling support for Armada 37xx platform.
+ *
+ * Copyright (C) 2017 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* Power management in North Bridge register set */
+#define ARMADA_37XX_NB_L0L1 0x18
+#define ARMADA_37XX_NB_L2L3 0x1C
+#define ARMADA_37XX_NB_TBG_DIV_OFF 13
+#define ARMADA_37XX_NB_TBG_DIV_MASK 0x7
+#define ARMADA_37XX_NB_CLK_SEL_OFF 11
+#define ARMADA_37XX_NB_CLK_SEL_MASK 0x1
+#define ARMADA_37XX_NB_CLK_SEL_TBG 0x1
+#define ARMADA_37XX_NB_TBG_SEL_OFF 9
+#define ARMADA_37XX_NB_TBG_SEL_MASK 0x3
+#define ARMADA_37XX_NB_VDD_SEL_OFF 6
+#define ARMADA_37XX_NB_VDD_SEL_MASK 0x3
+#define ARMADA_37XX_NB_CONFIG_SHIFT 16
+#define ARMADA_37XX_NB_DYN_MOD 0x24
+#define ARMADA_37XX_NB_CLK_SEL_EN BIT(26)
+#define ARMADA_37XX_NB_TBG_EN BIT(28)
+#define ARMADA_37XX_NB_DIV_EN BIT(29)
+#define ARMADA_37XX_NB_VDD_EN BIT(30)
+#define ARMADA_37XX_NB_DFS_EN BIT(31)
+#define ARMADA_37XX_NB_CPU_LOAD 0x30
+#define ARMADA_37XX_NB_CPU_LOAD_MASK 0x3
+#define ARMADA_37XX_DVFS_LOAD_0 0
+#define ARMADA_37XX_DVFS_LOAD_1 1
+#define ARMADA_37XX_DVFS_LOAD_2 2
+#define ARMADA_37XX_DVFS_LOAD_3 3
+
+/*
+ * On Armada 37xx the Power management manages 4 level of CPU load,
+ * each level can be associated with a CPU clock source, a CPU
+ * divider, a VDD level, etc...
+ */
+#define LOAD_LEVEL_NR 4
+
+struct armada_37xx_dvfs {
+ u32 cpu_freq_max;
+ u8 divider[LOAD_LEVEL_NR];
+};
+
+static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
+ {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
+ {.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
+ {.cpu_freq_max = 800*1000*1000, .divider = {1, 2, 3, 4} },
+ {.cpu_freq_max = 600*1000*1000, .divider = {2, 4, 5, 6} },
+};
+
+static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) {
+ if (freq == armada_37xx_dvfs[i].cpu_freq_max)
+ return &armada_37xx_dvfs[i];
+ }
+
+ pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000);
+ return NULL;
+}
+
+/*
+ * Setup the four level managed by the hardware. Once the four level
+ * will be configured then the DVFS will be enabled.
+ */
+static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
+ struct clk *clk, u8 *divider)
+{
+ int load_lvl;
+ struct clk *parent;
+
+ for (load_lvl = 0; load_lvl < LOAD_LEVEL_NR; load_lvl++) {
+ unsigned int reg, mask, val, offset = 0;
+
+ if (load_lvl <= ARMADA_37XX_DVFS_LOAD_1)
+ reg = ARMADA_37XX_NB_L0L1;
+ else
+ reg = ARMADA_37XX_NB_L2L3;
+
+ if (load_lvl == ARMADA_37XX_DVFS_LOAD_0 ||
+ load_lvl == ARMADA_37XX_DVFS_LOAD_2)
+ offset += ARMADA_37XX_NB_CONFIG_SHIFT;
+
+ /* Set cpu clock source, for all the level we use TBG */
+ val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF;
+ mask = (ARMADA_37XX_NB_CLK_SEL_MASK
+ << ARMADA_37XX_NB_CLK_SEL_OFF);
+
+ /*
+ * Set cpu divider based on the pre-computed array in
+ * order to have balanced step.
+ */
+ val |= divider[load_lvl] << ARMADA_37XX_NB_TBG_DIV_OFF;
+ mask |= (ARMADA_37XX_NB_TBG_DIV_MASK
+ << ARMADA_37XX_NB_TBG_DIV_OFF);
+
+ /* Set VDD divider which is actually the load level. */
+ val |= load_lvl << ARMADA_37XX_NB_VDD_SEL_OFF;
+ mask |= (ARMADA_37XX_NB_VDD_SEL_MASK
+ << ARMADA_37XX_NB_VDD_SEL_OFF);
+
+ val <<= offset;
+ mask <<= offset;
+
+ regmap_update_bits(base, reg, mask, val);
+ }
+
+ /*
+ * Set cpu clock source, for all the level we keep the same
+ * clock source that the one already configured. For this one
+ * we need to use the clock framework
+ */
+ parent = clk_get_parent(clk);
+ clk_set_parent(clk, parent);
+}
+
+static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base)
+{
+ unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
+ mask = ARMADA_37XX_NB_DFS_EN;
+
+ regmap_update_bits(base, reg, mask, 0);
+}
+
+static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
+{
+ unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD,
+ mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
+
+ /* Start with the highest load (0) */
+ val = ARMADA_37XX_DVFS_LOAD_0;
+ regmap_update_bits(base, reg, mask, val);
+
+ /* Now enable DVFS for the CPUs */
+ reg = ARMADA_37XX_NB_DYN_MOD;
+ mask = ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN |
+ ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN |
+ ARMADA_37XX_NB_DFS_EN;
+
+ regmap_update_bits(base, reg, mask, mask);
+}
+
+static int __init armada37xx_cpufreq_driver_init(void)
+{
+ struct armada_37xx_dvfs *dvfs;
+ struct platform_device *pdev;
+ unsigned int cur_frequency;
+ struct regmap *nb_pm_base;
+ struct device *cpu_dev;
+ int load_lvl, ret;
+ struct clk *clk;
+
+ nb_pm_base =
+ syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm");
+
+ if (IS_ERR(nb_pm_base))
+ return -ENODEV;
+
+ /* Before doing any configuration on the DVFS first, disable it */
+ armada37xx_cpufreq_disable_dvfs(nb_pm_base);
+
+ /*
+ * On CPU 0 register the operating points supported (which are
+ * the nominal CPU frequency and full integer divisions of
+ * it).
+ */
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ dev_err(cpu_dev, "Cannot get CPU\n");
+ return -ENODEV;
+ }
+
+ clk = clk_get(cpu_dev, 0);
+ if (IS_ERR(clk)) {
+ dev_err(cpu_dev, "Cannot get clock for CPU0\n");
+ return PTR_ERR(clk);
+ }
+
+ /* Get nominal (current) CPU frequency */
+ cur_frequency = clk_get_rate(clk);
+ if (!cur_frequency) {
+ dev_err(cpu_dev, "Failed to get clock rate for CPU\n");
+ return -EINVAL;
+ }
+
+ dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
+ if (!dvfs)
+ return -EINVAL;
+
+ armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
+
+ for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
+ load_lvl++) {
+ unsigned long freq = cur_frequency / dvfs->divider[load_lvl];
+
+ ret = dev_pm_opp_add(cpu_dev, freq, 0);
+ if (ret) {
+ /* clean-up the already added opp before leaving */
+ while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
+ freq = cur_frequency / dvfs->divider[load_lvl];
+ dev_pm_opp_remove(cpu_dev, freq);
+ }
+ return ret;
+ }
+ }
+
+ /* Now that everything is setup, enable the DVFS at hardware level */
+ armada37xx_cpufreq_enable_dvfs(nb_pm_base);
+
+ pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
+late_initcall(armada37xx_cpufreq_driver_init);
+
+MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
+MODULE_DESCRIPTION("Armada 37xx cpufreq driver");
+MODULE_LICENSE("GPL");
--
2.15.0
^ permalink raw reply related
* [PATCH v2 7/7] arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq support
From: Gregory CLEMENT @ 2017-12-07 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207135616.23670-1-gregory.clement@free-electrons.com>
In order to be able to use cpu freq, we need to associate a clock to each
CPU and to expose the power management registers.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm64/boot/dts/marvell/armada-372x.dtsi | 1 +
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
index 59d7557d3b1b..2554e0baea6b 100644
--- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi
@@ -56,6 +56,7 @@
device_type = "cpu";
compatible = "arm,cortex-a53","arm,armv8";
reg = <0x1>;
+ clocks = <&nb_periph_clk 16>;
enable-method = "psci";
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 90c26d616a54..3056d7168e0b 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -65,6 +65,7 @@
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0>;
+ clocks = <&nb_periph_clk 16>;
enable-method = "psci";
};
};
@@ -234,6 +235,12 @@
};
};
+ nb_pm: syscon at 14000 {
+ compatible = "marvell,armada-3700-nb-pm",
+ "syscon";
+ reg = <0x14000 0x60>;
+ };
+
pinctrl_sb: pinctrl at 18800 {
compatible = "marvell,armada3710-sb-pinctrl",
"syscon", "simple-mfd";
--
2.15.0
^ permalink raw reply related
* [PATCH] spi: sun6i: disable/unprepare clocks on remove
From: Tobias Jordan @ 2017-12-07 14:04 UTC (permalink / raw)
To: linux-arm-kernel
sun6i_spi_probe() uses sun6i_spi_runtime_resume() to prepare/enable
clocks, so sun6i_spi_remove() should use sun6i_spi_runtime_suspend() to
disable/unprepare them if we're not suspended.
Replacing pm_runtime_disable() by pm_runtime_force_suspend() will ensure
that sun6i_spi_runtime_suspend() is called if needed.
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: 3558fe900e8af spi: sunxi: Add Allwinner A31 SPI controller driver
Signed-off-by: Tobias Jordan <Tobias.Jordan@elektrobit.com>
---
Found by LDV and discussed as RFC before; compile-tested.
drivers/spi/spi-sun6i.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index fb38234249a8..8533f4edd00a 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -541,7 +541,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
static int sun6i_spi_remove(struct platform_device *pdev)
{
- pm_runtime_disable(&pdev->dev);
+ pm_runtime_force_suspend(&pdev->dev);
return 0;
}
--
2.11.0
^ permalink raw reply related
* [PATCH v3 10/20] arm64: assembler: add utility macros to push/pop stack frames
From: Dave Martin @ 2017-12-07 14:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171206194346.24393-11-ard.biesheuvel@linaro.org>
On Wed, Dec 06, 2017 at 07:43:36PM +0000, Ard Biesheuvel wrote:
> We are going to add code to all the NEON crypto routines that will
> turn them into non-leaf functions, so we need to manage the stack
> frames. To make this less tedious and error prone, add some macros
> that take the number of callee saved registers to preserve and the
> extra size to allocate in the stack frame (for locals) and emit
> the ldp/stp sequences.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/include/asm/assembler.h | 60 ++++++++++++++++++++
> 1 file changed, 60 insertions(+)
>
> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
> index aef72d886677..5f61487e9f93 100644
> --- a/arch/arm64/include/asm/assembler.h
> +++ b/arch/arm64/include/asm/assembler.h
> @@ -499,6 +499,66 @@ alternative_else_nop_endif
> #endif
> .endm
>
> + /*
> + * frame_push - Push @regcount callee saved registers to the stack,
> + * starting at x19, as well as x29/x30, and set x29 to
> + * the new value of sp. Add @extra bytes of stack space
> + * for locals.
> + */
> + .macro frame_push, regcount:req, extra
> + __frame st, \regcount, \extra
> + .endm
> +
> + /*
> + * frame_pop - Pop @regcount callee saved registers from the stack,
> + * starting at x19, as well as x29/x30. Also pop @extra
> + * bytes of stack space for locals.
> + */
> + .macro frame_pop, regcount:req, extra
> + __frame ld, \regcount, \extra
> + .endm
> +
> + .macro __frame, op, regcount:req, extra=0
> + .ifc \op, st
> + stp x29, x30, [sp, #-((\regcount + 3) / 2) * 16 - \extra]!
> + mov x29, sp
> + .endif
> + .if \regcount < 0 || \regcount > 10
> + .error "regcount should be in the range [0 ... 10]"
> + .endif
> + .if (\extra % 16) != 0
> + .error "extra should be a multiple of 16 bytes"
> + .endif
> + .if \regcount > 1
> + \op\()p x19, x20, [sp, #16]
> + .if \regcount > 3
> + \op\()p x21, x22, [sp, #32]
> + .if \regcount > 5
> + \op\()p x23, x24, [sp, #48]
> + .if \regcount > 7
> + \op\()p x25, x26, [sp, #64]
> + .if \regcount > 9
> + \op\()p x27, x28, [sp, #80]
Can the _for thing I introduced in fpsimdmacros.h be any use here?
Alternatively, the following could replace that .if-slide,
providing the calling macro does .altmacro .. .noaltmacro somewhere.
.macro _pushpop2 op, n1, n2, offset
\op x\n1, x\n2, [sp, #\offset]
.endm
.macro _pushpop op, first, last, offset
.if \first < \last
_pushpop2 \op\()p, \first, %\first + 1, \offset
_pushpop \op, %\first + 2, \last, %\offset + 16
.elseif \first == \last
\op\()r x\first, [sp, #\offset]
.endif
.endm
Also, I wonder whether it would be more readable@the call site
to specify the first and last reg numbers instead of the reg count,
e.g.:
frame_push first_reg=19, last_reg=23
(or whatever). Just syntactic sugar though.
[...]
Cheers
---Dave
^ permalink raw reply
* [PATCH v3 10/20] arm64: assembler: add utility macros to push/pop stack frames
From: Ard Biesheuvel @ 2017-12-07 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207141104.GE22781@e103592.cambridge.arm.com>
On 7 December 2017 at 14:11, Dave Martin <Dave.Martin@arm.com> wrote:
> On Wed, Dec 06, 2017 at 07:43:36PM +0000, Ard Biesheuvel wrote:
>> We are going to add code to all the NEON crypto routines that will
>> turn them into non-leaf functions, so we need to manage the stack
>> frames. To make this less tedious and error prone, add some macros
>> that take the number of callee saved registers to preserve and the
>> extra size to allocate in the stack frame (for locals) and emit
>> the ldp/stp sequences.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> arch/arm64/include/asm/assembler.h | 60 ++++++++++++++++++++
>> 1 file changed, 60 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
>> index aef72d886677..5f61487e9f93 100644
>> --- a/arch/arm64/include/asm/assembler.h
>> +++ b/arch/arm64/include/asm/assembler.h
>> @@ -499,6 +499,66 @@ alternative_else_nop_endif
>> #endif
>> .endm
>>
>> + /*
>> + * frame_push - Push @regcount callee saved registers to the stack,
>> + * starting at x19, as well as x29/x30, and set x29 to
>> + * the new value of sp. Add @extra bytes of stack space
>> + * for locals.
>> + */
>> + .macro frame_push, regcount:req, extra
>> + __frame st, \regcount, \extra
>> + .endm
>> +
>> + /*
>> + * frame_pop - Pop @regcount callee saved registers from the stack,
>> + * starting at x19, as well as x29/x30. Also pop @extra
>> + * bytes of stack space for locals.
>> + */
>> + .macro frame_pop, regcount:req, extra
>> + __frame ld, \regcount, \extra
>> + .endm
>> +
>> + .macro __frame, op, regcount:req, extra=0
>> + .ifc \op, st
>> + stp x29, x30, [sp, #-((\regcount + 3) / 2) * 16 - \extra]!
>> + mov x29, sp
>> + .endif
>> + .if \regcount < 0 || \regcount > 10
>> + .error "regcount should be in the range [0 ... 10]"
>> + .endif
>> + .if (\extra % 16) != 0
>> + .error "extra should be a multiple of 16 bytes"
>> + .endif
>> + .if \regcount > 1
>> + \op\()p x19, x20, [sp, #16]
>> + .if \regcount > 3
>> + \op\()p x21, x22, [sp, #32]
>> + .if \regcount > 5
>> + \op\()p x23, x24, [sp, #48]
>> + .if \regcount > 7
>> + \op\()p x25, x26, [sp, #64]
>> + .if \regcount > 9
>> + \op\()p x27, x28, [sp, #80]
>
> Can the _for thing I introduced in fpsimdmacros.h be any use here?
> Alternatively, the following could replace that .if-slide,
> providing the calling macro does .altmacro .. .noaltmacro somewhere.
>
> .macro _pushpop2 op, n1, n2, offset
> \op x\n1, x\n2, [sp, #\offset]
> .endm
>
> .macro _pushpop op, first, last, offset
> .if \first < \last
> _pushpop2 \op\()p, \first, %\first + 1, \offset
> _pushpop \op, %\first + 2, \last, %\offset + 16
> .elseif \first == \last
> \op\()r x\first, [sp, #\offset]
> .endif
> .endm
>
I'd prefer not to rely on altmacro, for reasons you pointed out
yourself a while ago IIRC.
I agree your version is more compact, but for a write once thing, I'm
not sure if it matters.
> Also, I wonder whether it would be more readable at the call site
> to specify the first and last reg numbers instead of the reg count,
> e.g.:
>
> frame_push first_reg=19, last_reg=23
>
> (or whatever). Just syntactic sugar though.
>
Again, this will involve arithmetic on macro arguments, which implies
altmacro. Relying on altmacro being set is dodgy, and unfortunately,
we can't enable it in the macro without keeping it enabled (or we may
disable it on behalf of the caller. I guess we could try to come up
with a smart way to infer whether altmacro was enabled, and only
disable it afterwards if it wasn't, using some directives that get
interpreted differently, but to be honest, I factored out this
sequence so I could think about more important things :-)
^ permalink raw reply
* [RFC v3 PATCH 0/2] Introduce Security Version to EFI Stub
From: Alan Cox @ 2017-12-07 14:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171205100148.5757-1-glin@suse.com>
On Tue, 5 Dec 2017 18:01:46 +0800
Gary Lin <glin@suse.com> wrote:
> The series of patches introduce Security Version to EFI stub.
>
> Security Version is a monotonically increasing number and designed to
> prevent the user from loading an insecure kernel accidentally. The
> bootloader maintains a list of security versions corresponding to
> different distributions. After fixing a critical vulnerability, the
> distribution kernel maintainer bumps the "version", and the bootloader
> updates the list automatically.
This seems a mindbogglingly complicated way to implement something you
could do with a trivial script in the package that updates the list of
iffy kernels and when generating the new grub.conf puts them in a menu
of 'old insecure' kernels.
Why do you even need this in the EFI stub ?
What happens if you want to invalidate an old kernel but not push a new
one ? Today if you've got a package that maintains the list of 'iffy'
kernels you can push a tiny package, under your scheme you've got to push
new kernels which is an un-necessary and high risk OS change.
It just feels like an attempt to solve the problem in completely the
wrong place.
Alan
^ permalink raw reply
* [PATCH net-next v2 0/8] phy: net: meson-gxl: clean-up and improvements
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
The patchset is a v2 of the previous single clean-up patch [0] which was
part of larger series. I initially to send these patches separately but
adding helper function without using them did not make much sense after
all. So, here is the complete patchset.
This patchset add defines for the control registers and helpers to access
the banked registers. The goal being to make it easier to understand what
the driver actually does.
Then there is fix for the incorrect sampling of the MII LPA register which
is often breaking the auto-negotiation with this PHY. More details on this
in the related patch
CONFIG_A6 settings is removed since this statement was without effect
Finally interrupt support is added, speeding things up a little
This series has been tested on the libretech-cc and khadas VIM
Jerome Brunet (8):
net: phy: meson-gxl: check phy_write return value
net: phy: meson-gxl: define control registers
net: phy: meson-gxl: add read and write helpers for bank registers
net: phy: meson-gxl: use genphy_config_init
net: phy: meson-gxl: detect LPA corruption
net: phy: meson-gxl: leave CONFIG_A6 untouched
net: phy: meson-gxl: add interrupt support
net: phy: meson-gxl: join the authors
drivers/net/phy/meson-gxl.c | 215 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 197 insertions(+), 18 deletions(-)
--
2.14.3
^ permalink raw reply
* [PATCH net-next v2 1/8] net: phy: meson-gxl: check phy_write return value
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Always check phy_write return values. Better to be safe than sorry
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 50 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 1ea69b7585d9..7ddb709f69fc 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -25,27 +25,53 @@
static int meson_gxl_config_init(struct phy_device *phydev)
{
+ int ret;
+
/* Enable Analog and DSP register Bank access by */
- phy_write(phydev, 0x14, 0x0000);
- phy_write(phydev, 0x14, 0x0400);
- phy_write(phydev, 0x14, 0x0000);
- phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, 0x14, 0x0000);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0400);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0000);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0400);
+ if (ret)
+ return ret;
/* Write Analog register 23 */
- phy_write(phydev, 0x17, 0x8E0D);
- phy_write(phydev, 0x14, 0x4417);
+ ret = phy_write(phydev, 0x17, 0x8E0D);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x4417);
+ if (ret)
+ return ret;
/* Enable fractional PLL */
- phy_write(phydev, 0x17, 0x0005);
- phy_write(phydev, 0x14, 0x5C1B);
+ ret = phy_write(phydev, 0x17, 0x0005);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1B);
+ if (ret)
+ return ret;
/* Program fraction FR_PLL_DIV1 */
- phy_write(phydev, 0x17, 0x029A);
- phy_write(phydev, 0x14, 0x5C1D);
+ ret = phy_write(phydev, 0x17, 0x029A);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1D);
+ if (ret)
+ return ret;
/* Program fraction FR_PLL_DIV1 */
- phy_write(phydev, 0x17, 0xAAAA);
- phy_write(phydev, 0x14, 0x5C1C);
+ ret = phy_write(phydev, 0x17, 0xAAAA);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1C);
+ if (ret)
+ return ret;
return 0;
}
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 2/8] net: phy: meson-gxl: define control registers
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Define registers and bits in meson-gxl PHY driver to make a bit
more human friendly. No functional change.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 64 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 7ddb709f69fc..d82aa8cea401 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -22,54 +22,92 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
+#include <linux/bitfield.h>
+
+#define TSTCNTL 20
+#define TSTCNTL_READ BIT(15)
+#define TSTCNTL_WRITE BIT(14)
+#define TSTCNTL_REG_BANK_SEL GENMASK(12, 11)
+#define TSTCNTL_TEST_MODE BIT(10)
+#define TSTCNTL_READ_ADDRESS GENMASK(9, 5)
+#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
+#define TSTREAD1 21
+#define TSTWRITE 23
+
+#define BANK_ANALOG_DSP 0
+#define BANK_BIST 3
+
+/* Analog/DSP Registers */
+#define A6_CONFIG_REG 0x17
+
+/* BIST Registers */
+#define FR_PLL_CONTROL 0x1b
+#define FR_PLL_DIV0 0x1c
+#define FR_PLL_DIV1 0x1d
static int meson_gxl_config_init(struct phy_device *phydev)
{
int ret;
/* Enable Analog and DSP register Bank access by */
- ret = phy_write(phydev, 0x14, 0x0000);
+ ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0000);
+ ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
if (ret)
return ret;
- /* Write Analog register 23 */
- ret = phy_write(phydev, 0x17, 0x8E0D);
+ /* Write CONFIG_A6*/
+ ret = phy_write(phydev, TSTWRITE, 0x8e0d)
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x4417);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_ANALOG_DSP)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, A6_CONFIG_REG));
if (ret)
return ret;
/* Enable fractional PLL */
- ret = phy_write(phydev, 0x17, 0x0005);
+ ret = phy_write(phydev, TSTWRITE, 0x0005);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1B);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_CONTROL));
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, 0x17, 0x029A);
+ ret = phy_write(phydev, TSTWRITE, 0x029a);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1D);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV1));
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, 0x17, 0xAAAA);
+ ret = phy_write(phydev, TSTWRITE, 0xaaaa);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1C);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV0));
if (ret)
return ret;
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 3/8] net: phy: meson-gxl: add read and write helpers for bank registers
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Add read and write helpers to manipulate banked registers on this PHY
This helps clarify the settings applied to these registers in the init
function and upcoming changes.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 103 ++++++++++++++++++++++++++++----------------
1 file changed, 67 insertions(+), 36 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index d82aa8cea401..05054770aefb 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -45,11 +45,13 @@
#define FR_PLL_DIV0 0x1c
#define FR_PLL_DIV1 0x1d
-static int meson_gxl_config_init(struct phy_device *phydev)
+static int meson_gxl_open_banks(struct phy_device *phydev)
{
int ret;
- /* Enable Analog and DSP register Bank access by */
+ /* Enable Analog and DSP register Bank access by
+ * toggling TSTCNTL_TEST_MODE bit in the TSTCNTL register
+ */
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
@@ -59,55 +61,84 @@ static int meson_gxl_config_init(struct phy_device *phydev)
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
- if (ret)
- return ret;
+ return phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
+}
- /* Write CONFIG_A6*/
- ret = phy_write(phydev, TSTWRITE, 0x8e0d)
+static void meson_gxl_close_banks(struct phy_device *phydev)
+{
+ phy_write(phydev, TSTCNTL, 0);
+}
+
+static int meson_gxl_read_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_ANALOG_DSP)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, A6_CONFIG_REG));
+ goto out;
+
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_READ |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_READ_ADDRESS, reg));
if (ret)
- return ret;
+ goto out;
- /* Enable fractional PLL */
- ret = phy_write(phydev, TSTWRITE, 0x0005);
+ ret = phy_read(phydev, TSTREAD1);
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_write_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg,
+ uint16_t value)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_CONTROL));
+ goto out;
+
+ ret = phy_write(phydev, TSTWRITE, value);
if (ret)
- return ret;
+ goto out;
- /* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0x029a);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_WRITE |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_WRITE_ADDRESS, reg));
+
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Write CONFIG_A6*/
+ ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
+ 0x8e0d);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV1));
+
+ /* Enable fractional PLL */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0xaaaa);
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV1, 0x029a);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV0));
+
+ /* Program fraction FR_PLL_DIV1 */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV0, 0xaaaa);
if (ret)
return ret;
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 4/8] net: phy: meson-gxl: use genphy_config_init
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Use the generic init function to populate some of the phydev
structure fields
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 05054770aefb..2e8c40df33c2 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -142,7 +142,7 @@ static int meson_gxl_config_init(struct phy_device *phydev)
if (ret)
return ret;
- return 0;
+ return genphy_config_init(phydev);
}
static struct phy_driver meson_gxl_phy[] = {
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 5/8] net: phy: meson-gxl: detect LPA corruption
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
The purpose of this change is to fix the incorrect detection of the link
partner (LP) advertised capabilities which sometimes happens with this PHY
(roughly 1 time in a dozen)
This issue may cause the link to be negotiated at 10Mbps/Full or
10Mbps/Half when 100MBps/Full is actually possible. In some case, the link
is even completely broken and no communication is possible.
To detect the corruption, we must look for a magic undocumented bit in the
WOL bank (hint given by the SoC vendor kernel) but this is not enough to
cover all cases. We also have to look at the LPA ack. If the LP supports
Aneg but did not ack our base code when aneg is completed, we assume
something went wrong.
The detection of a corrupted LPA triggers a restart of the aneg process.
This solves the problem but may take up to 6 retries to complete.
Fixes: 7334b3e47aee ("net: phy: Add Meson GXL Internal PHY driver")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
I suppose this patch probably seems a bit hacky, especially the part
about the link partner acknowledge. I'm trying to figure out if the
value in MII_LPA makes sense but I don't have such a deep knowledge
of the ethernet spec.
To me, it does not makes sense for the LP to support ANEG (Bit 1 in
MII_EXPENSION), the aneg to have successfully complete and, at the
same time, LP does not ACK our base code word, which we should have
sent during this aneg.
If you think this may have unintended consequences or if you have
an idea to this differently, feel free to let me know.
drivers/net/phy/meson-gxl.c | 59 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 2e8c40df33c2..726e0eeed475 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -35,11 +35,16 @@
#define TSTWRITE 23
#define BANK_ANALOG_DSP 0
+#define BANK_WOL 1
#define BANK_BIST 3
/* Analog/DSP Registers */
#define A6_CONFIG_REG 0x17
+/* WOL Registers */
+#define LPI_STATUS 0xc
+#define LPI_STATUS_RSV12 BIT(12)
+
/* BIST Registers */
#define FR_PLL_CONTROL 0x1b
#define FR_PLL_DIV0 0x1c
@@ -145,6 +150,58 @@ static int meson_gxl_config_init(struct phy_device *phydev)
return genphy_config_init(phydev);
}
+/* This specific function is provided to cope with the possible failures of
+ * this phy during aneg process. When aneg fails, the PHY reports that aneg
+ * is done but the value found in MII_LPA is wrong:
+ * - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that
+ * the link partner (LP) supports aneg but the LP never acked our base
+ * code word, it is likely that we never sent it to begin with.
+ * - Late failures: MII_LPA is filled with a value which seems to make sense
+ * but it actually is not what the LP is advertising. It seems that we
+ * can detect this using a magic bit in the WOL bank (reg 12 - bit 12).
+ * If this particular bit is not set when aneg is reported being done,
+ * it means MII_LPA is likely to be wrong.
+ *
+ * In both case, forcing a restart of the aneg process solve the problem.
+ * When this failure happens, the first retry is usually successful but,
+ * in some cases, it may take up to 6 retries to get a decent result
+ */
+int meson_gxl_read_status(struct phy_device *phydev)
+{
+ int ret, wol, lpa, exp;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ ret = genphy_aneg_done(phydev);
+ if (ret < 0)
+ return ret;
+ else if (!ret)
+ goto read_status_continue;
+
+ /* Aneg is done, let's check everything is fine */
+ wol = meson_gxl_read_reg(phydev, BANK_WOL, LPI_STATUS);
+ if (wol < 0)
+ return wol;
+
+ lpa = phy_read(phydev, MII_LPA);
+ if (lpa < 0)
+ return lpa;
+
+ exp = phy_read(phydev, MII_EXPANSION);
+ if (exp < 0)
+ return exp;
+
+ if (!(wol & LPI_STATUS_RSV12) ||
+ ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) {
+ /* Looks like aneg failed after all */
+ phydev_dbg(phydev, "LPA corruption - aneg restart\n");
+ return genphy_restart_aneg(phydev);
+ }
+ }
+
+read_status_continue:
+ return genphy_read_status(phydev);
+}
+
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
@@ -155,7 +212,7 @@ static struct phy_driver meson_gxl_phy[] = {
.config_init = meson_gxl_config_init,
.config_aneg = genphy_config_aneg,
.aneg_done = genphy_aneg_done,
- .read_status = genphy_read_status,
+ .read_status = meson_gxl_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 6/8] net: phy: meson-gxl: leave CONFIG_A6 untouched
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
The PHY performs just as well when left in its default configuration and
it makes senses because this poke gets reset just after init.
According to the documentation, all registers in the Analog/DSP bank are
reset when there is a mode switch from 10BT to 100BT.
In the end, we have used the default configuration so far and there is no
reason to change now. Remove CONFIG_A6 poke to make this clear.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Out of curiosity, I tried to re-apply the ANALOG/DSP settings on speed
changes (patch available here [0] if someone wants to try) but I did
not notice any change as a result. In the end, I thought it was safer
to keep on using the ANALOG settings we have been actually using so far,
everybody seems to be happy with them
[0]: https://github.com/jeromebrunet/linux/commit/b594288e629a61574e76112497474fd3cf46c781
drivers/net/phy/meson-gxl.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 726e0eeed475..5325940fe899 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -38,9 +38,6 @@
#define BANK_WOL 1
#define BANK_BIST 3
-/* Analog/DSP Registers */
-#define A6_CONFIG_REG 0x17
-
/* WOL Registers */
#define LPI_STATUS 0xc
#define LPI_STATUS_RSV12 BIT(12)
@@ -126,12 +123,6 @@ static int meson_gxl_config_init(struct phy_device *phydev)
{
int ret;
- /* Write CONFIG_A6*/
- ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
- 0x8e0d);
- if (ret)
- return ret;
-
/* Enable fractional PLL */
ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 7/8] net: phy: meson-gxl: add interrupt support
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Enable interrupt support in meson-gxl PHY driver
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 5325940fe899..861b021b9758 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -33,6 +33,14 @@
#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
#define TSTREAD1 21
#define TSTWRITE 23
+#define INTSRC_FLAG 29
+#define INTSRC_ANEG_PR BIT(1)
+#define INTSRC_PARALLEL_FAULT BIT(2)
+#define INTSRC_ANEG_LP_ACK BIT(3)
+#define INTSRC_LINK_DOWN BIT(4)
+#define INTSRC_REMOTE_FAULT BIT(5)
+#define INTSRC_ANEG_COMPLETE BIT(6)
+#define INTSRC_MASK 30
#define BANK_ANALOG_DSP 0
#define BANK_WOL 1
@@ -193,17 +201,44 @@ int meson_gxl_read_status(struct phy_device *phydev)
return genphy_read_status(phydev);
}
+static int meson_gxl_ack_interrupt(struct phy_device *phydev)
+{
+ int ret = phy_read(phydev, INTSRC_FLAG);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int meson_gxl_config_intr(struct phy_device *phydev)
+{
+ u16 val;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ val = INTSRC_ANEG_PR
+ | INTSRC_PARALLEL_FAULT
+ | INTSRC_ANEG_LP_ACK
+ | INTSRC_LINK_DOWN
+ | INTSRC_REMOTE_FAULT
+ | INTSRC_ANEG_COMPLETE;
+ } else {
+ val = 0;
+ }
+
+ return phy_write(phydev, INTSRC_MASK, val);
+}
+
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
.phy_id_mask = 0xfffffff0,
.name = "Meson GXL Internal PHY",
.features = PHY_BASIC_FEATURES,
- .flags = PHY_IS_INTERNAL,
+ .flags = PHY_IS_INTERNAL | PHY_HAS_INTERRUPT,
.config_init = meson_gxl_config_init,
.config_aneg = genphy_config_aneg,
.aneg_done = genphy_aneg_done,
.read_status = meson_gxl_read_status,
+ .ack_interrupt = meson_gxl_ack_interrupt,
+ .config_intr = meson_gxl_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 8/8] net: phy: meson-gxl: join the authors
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Following previous changes, join the other authors of this driver and
take the blame with them
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 861b021b9758..4cd5b2622ae1 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -256,4 +256,5 @@ MODULE_DEVICE_TABLE(mdio, meson_gxl_tbl);
MODULE_DESCRIPTION("Amlogic Meson GXL Internal PHY driver");
MODULE_AUTHOR("Baoqi wang");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL");
--
2.14.3
^ permalink raw reply related
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