Support for Fujitsu MB86S7X SoCs
Subsystems (9)
cover Support for Fujitsu MB86S7X SoCs
Hello,
Fujitsu have a series of SoC already shipping based around
variations of 2xCA7+2xCA15 big.LITTLE architecture, and we would like to upstream the basic support in this series.
MB86S70 is a big.LITTLE platform with 2xCA7+2xCA15 and an additional
CM3 as the master. MB86S73 is a simple 2xCA7 and an additional CM3 master.
The DT includes references to sdhci patches which are being sent to the mmc list at the same time.
We welcome any comments or questions.
Thanks.
Vincent Yang (9):
ARM: Add platform support for Fujitsu MB86S7X SoCs
mailbox: arm_mhu: add driver for ARM MHU controller
ARM: MB86S7X: Add MCPM support
clk: Add clock driver for mb86s7x
gpio: Add Fujitsu MB86S7x GPIO driver
mmc: sdhci: host: add new f_sdh30
dt: mb86s7x: add dt files for MB86S7x evbs
of: add Fujitsu vendor prefix
ARM: MB86S7x: Add configs
Documentation/devicetree/bindings/arm/mb86s7x.txt | 8 + .../bindings/clock/fujitsu,mb86s70-clk.txt | 34 ++ .../bindings/gpio/fujitsu,mb86s70-gpio.txt | 18 + .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++ .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 ++ .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt | 35 ++ .../devicetree/bindings/vendor-prefixes.txt | 1 + MAINTAINERS | 7 + arch/arm/Kconfig | 2 + arch/arm/Makefile | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/mb86s70.dtsi | 91 ++++ arch/arm/boot/dts/mb86s70eb.dts | 52 ++ arch/arm/boot/dts/mb86s73.dtsi | 49 ++ arch/arm/boot/dts/mb86s73eb.dts | 39 ++ arch/arm/boot/dts/mb86s7x.dtsi | 595 +++++++++++++++++++++ arch/arm/configs/fujitsu_defconfig | 232 ++++++++ arch/arm/configs/multi_v7_defconfig | 5 + arch/arm/mach-mb86s7x/Kconfig | 19 + arch/arm/mach-mb86s7x/Makefile | 1 + arch/arm/mach-mb86s7x/board.c | 23 + arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 + drivers/clk/Makefile | 1 + drivers/clk/clk-mb86s7x.c | 359 +++++++++++++ drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mb86s7x.c | 211 ++++++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++ drivers/soc/Makefile | 1 + drivers/soc/mb86s7x/Makefile | 4 + drivers/soc/mb86s7x/scb_mhu.c | 516 ++++++++++++++++++ include/dt-bindings/clock/mb86s70-clk.h | 22 + include/soc/mb86s7x/scb_mhu.h | 97 ++++ 39 files changed, 3420 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt create mode 100644 arch/arm/boot/dts/mb86s70.dtsi create mode 100644 arch/arm/boot/dts/mb86s70eb.dts create mode 100644 arch/arm/boot/dts/mb86s73.dtsi create mode 100644 arch/arm/boot/dts/mb86s73eb.dts create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi create mode 100644 arch/arm/configs/fujitsu_defconfig create mode 100644 arch/arm/mach-mb86s7x/Kconfig create mode 100644 arch/arm/mach-mb86s7x/Makefile create mode 100644 arch/arm/mach-mb86s7x/board.c create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.S create mode 100644 drivers/clk/clk-mb86s7x.c create mode 100644 drivers/gpio/gpio-mb86s7x.c create mode 100644 drivers/mailbox/arm_mhu.c create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c create mode 100644 drivers/soc/mb86s7x/Makefile create mode 100644 drivers/soc/mb86s7x/scb_mhu.c create mode 100644 include/dt-bindings/clock/mb86s70-clk.h create mode 100644 include/soc/mb86s7x/scb_mhu.h
Signature · 1 line
1.9.0
PATCH 1/9 ARM: Add platform support for Fujitsu MB86S7X SoCs
The MB86S7X is a bigLITTLE configuration of 2xCA7 & 2xCA15 under Linux. And the remote master firmware (called SCB) running on CM3. Linux asks for things to be done over Mailbox API, to SCB which controls most of the important things. variations S70 & S73 are supported.
--- Documentation/devicetree/bindings/arm/mb86s7x.txt | 8 + .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt | 35 ++ MAINTAINERS | 7 + arch/arm/Kconfig | 2 + arch/arm/Makefile | 1 + arch/arm/mach-mb86s7x/Kconfig | 19 + arch/arm/mach-mb86s7x/Makefile | 1 + arch/arm/mach-mb86s7x/board.c | 23 + drivers/soc/Makefile | 1 + drivers/soc/mb86s7x/Makefile | 4 + drivers/soc/mb86s7x/scb_mhu.c | 516 +++++++++++++++++++++ include/soc/mb86s7x/scb_mhu.h | 97 ++++ 12 files changed, 714 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt create mode 100644 arch/arm/mach-mb86s7x/Kconfig create mode 100644 arch/arm/mach-mb86s7x/Makefile create mode 100644 arch/arm/mach-mb86s7x/board.c create mode 100644 drivers/soc/mb86s7x/Makefile create mode 100644 drivers/soc/mb86s7x/scb_mhu.c create mode 100644 include/soc/mb86s7x/scb_mhu.h
Documentation/devicetree/bindings/arm/mb86s7x.txt new file +8 -0
@@ -0,0 +1,8 @@ +Fujitsu MB86S7X Device Tree Bindings + +Fujitsu has a few closely related platforms that are basically different +configurations of each others. Like MB86S7{0,1,2,3}. + +The EVB boards with S70/S73 have the following property: +Required root node property: + compatible: must contain "fujitsu,mb86s70-evb" or "fujitsu,mb86s73-evb"
Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt new file +35 -0
@@ -0,0 +1,35 @@ +Fujitsu SCB (Mailbox's Remote Firmware) bindings +------------------------------------------------ + +The firmware (running of a remote Cortex-M3 master) on Fujitsu's MB86S7X +platforms is named SCB. The SCB owns most of core h/w IPs like Clock, +CPUFreq/DVFS, CPUIdle/SMP, Thermal, a recovery block device and even an +I2C controller. Linux has to map all of these functionalities on to +the Mailbox API and get things done by the remote master. + Let the current state of SCB firmware be versioned 1.0. + +Required properties : +- compatible : Shall contain "fujitsu,mb86s70-scb-1.0" +- reg : Point to SharedMemory used for Mailbox protocol. +- mboxes : phandle to the mailbox controller:channel node. + +The consumer specifies the desired clock pointing to its phandle. + +Example: + + mhu: mhu0 at 2b1f0000 { + #mbox-cells = <1>; + compatible = "arm,mbox-mhu"; + reg = <0 0x2b1f0000 0x1000>; + interrupts = <0 36 4>, /* LP Non-Sec */ + <0 35 4>, /* HP Non-Sec */ + <0 37 4>; /* Secure */ + clocks = <&clk_alw_2_1>; + clock-names = "clk"; + }; + + mhu_client: scb at 2e000000 { + compatible = "fujitsu,mb86s70-scb-1.0"; + reg = <0 0x2e000000 0x4000>; /* SHM for IPC */ + mboxes = <&mhu 1>; + };
MAINTAINERS +7 -0
@@ -1087,6 +1087,13 @@ M: Lennert Buytenhek <[email protected]> L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/MB86S7X SOC SUPPORT +M: Vincent Yang <[email protected]> +M: Tetsuya Nuriya <[email protected]> +L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers) +S: Supported +F: arch/arm/mach-mb86s7x/ + ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE M: Santosh Shilimkar <[email protected]> L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
arch/arm/Kconfig +2 -0
@@ -894,6 +894,8 @@ source "arch/arm/mach-keystone/Kconfig" source "arch/arm/mach-ks8695/Kconfig" +source "arch/arm/mach-mb86s7x/Kconfig" + source "arch/arm/mach-meson/Kconfig" source "arch/arm/mach-msm/Kconfig"
arch/arm/Makefile +1 -0
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx machine-$(CONFIG_ARCH_KEYSTONE) += keystone machine-$(CONFIG_ARCH_KS8695) += ks8695 machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx +machine-$(CONFIG_ARCH_MB86S7X) += mb86s7x machine-$(CONFIG_ARCH_MESON) += meson machine-$(CONFIG_ARCH_MMP) += mmp machine-$(CONFIG_ARCH_MOXART) += moxart
arch/arm/mach-mb86s7x/Kconfig new file +19 -0
@@ -0,0 +1,19 @@ +config ARCH_MB86S7X + bool "Fujitsu MB86S7x platforms" if ARCH_MULTI_V7 + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP + select ARCH_REQUIRE_GPIOLIB + select ARM_AMBA + select ARM_CCI + select ARM_GIC + select ARM_TIMER_SP804 + select BIG_LITTLE + select HAVE_ARM_ARCH_TIMER + select MAILBOX + select PINCTRL + select PINCTRL_MB86S7X + select PM_OPP + select ZONE_DMA if ARM_LPAE + help + Support for Fujitsu MB86S7x based platforms
arch/arm/mach-mb86s7x/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_MB86S7X) += board.o
arch/arm/mach-mb86s7x/board.c new file +23 -0
@@ -0,0 +1,23 @@ +/* +* Support for the Fujitsu's MB86S7x based devices. +* +* Copyright (C) 2014 Linaro, LTD +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +* +*/ + +#include <linux/of.h> +#include <asm/mach/arch.h> + +static const char *mb86s7x_dt_match[]__initconst = { +"fujitsu,mb86s70-evb" , +"fujitsu,mb86s73-evb" , +NULL , +}; + +DT_MACHINE_START (MB86S7X_DT ,"Fujitsu MB86S7X-based board" ) + .dt_compat = mb86s7x_dt_match, +MACHINE_END
drivers/soc/Makefile +1 -0
@@ -2,6 +2,7 @@ # Makefile for the Linux Kernel SOC specific device drivers. # +obj-$(CONFIG_ARCH_MB86S7X) += mb86s7x/ obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_SOC_TI) += ti/
drivers/soc/mb86s7x/Makefile new file +4 -0
@@ -0,0 +1,4 @@ +# +# Fujitsu's MB86S7X drivers +# +obj-$(CONFIG_ARCH_MB86S7X) += scb_mhu.o
drivers/soc/mb86s7x/scb_mhu.c new file +516 -0
516 lines not on this page · raw message
include/soc/mb86s7x/scb_mhu.h new file +97 -0
97 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
In reply to Vincent YangAdd driver for the ARM Message-Handling-Unit (MHU).
--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt create mode 100644 drivers/mailbox/arm_mhu.c
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +33 -0
@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== + +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has +3 independent channels/links to communicate with remote processor(s). + MHU links are hardwired on a platform. A link raises interrupt for any +received data. However, there is no specified way of knowing if the sent +data has been read by the remote. This driver assumes the sender polls +STAT register and the remote clears it after having read the data. + +Mailbox Device Node: +==================== + +Required properties: +-------------------- +- compatible: Shall be "arm,mbox-mhu" +- reg: Contains the mailbox register address range (base + address and length) +- #mbox-cells Shall be 1 +- interrupts: Contains the interrupt information corresponding to + each of the 3 links of MHU. + +Example: +-------- + + mhu: mailbox at 2b1f0000 { + #mbox-cells = <1>; + compatible = "arm,mbox-mhu"; + reg = <0 0x2b1f0000 0x1000>; + interrupts = <0 36 4>, + <0 35 4>, + <0 37 4>; + };
drivers/mailbox/Kconfig +7 -0
@@ -6,6 +6,13 @@ menuconfig MAILBOX signals. Say Y if your platform supports hardware mailboxes. if MAILBOX + +config ARM_MHU + tristate "ARM MHU Mailbox" + depends on ARM + help + Say Y here if you want to build the ARM MHU controller driver + config PL320_MBOX bool "ARM PL320 Mailbox" depends on ARM_AMBA
drivers/mailbox/Makefile +2 -0
@@ -2,6 +2,8 @@ obj-$(CONFIG_MAILBOX) += mailbox.o +obj-$(CONFIG_ARM_MHU) += arm_mhu.o + obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o
drivers/mailbox/arm_mhu.c new file +196 -0
196 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 21 lines · Vincent Yang
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+)create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txtcreate mode 100644drivers/mailbox/arm_mhu.cDocumentation/devicetree/bindings/mailbox/arm-mhu.txt new file +0
-0
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 5 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +5
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== + +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has +3 independent channels/links to communicate with remote processor(s).
I had reviewed this before and I see not all the comments are addressed. I had mentioned that you can't add support to _SECURE_ channel in Linux as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 9
Quoted 4 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +4
-0+ MHU links are hardwired on a platform. A link raises interrupt for any +received data. However, there is no specified way of knowing if the sent +data has been read by the remote. This driver assumes the sender polls +STAT register and the remote clears it after having read the data.
That could be design, interrupt support could be present on some systems. The bindings should be flexible to add that support in future if needed along with necessary code.
Regards,
Sudeep
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 30 lines · Sudeep Holla
Quoted 27 lines · Vincent Yang
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+)create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txtcreate mode 100644drivers/mailbox/arm_mhu.cDocumentation/devicetree/bindings/mailbox/arm-mhu.txt new file +3
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== +
Quoted 9 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 2 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +2
-0+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has +3 independent channels/links to communicate with remote processor(s).I had reviewed this before and I see not all the comments are addressed. I had mentioned that you can't add support to _SECURE_ channel in Linux as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Please revisit the old thread. After some discussion you had graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you have valid reasons. In case you decide to support it ....
]
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.
Though I did forget to add .remove() function in case the driver is used as a module. Will add that.
Quoted 10 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 9
Quoted 4 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +4
-0+ MHU links are hardwired on a platform. A link raises interrupt for any +received data. However, there is no specified way of knowing if the sent +data has been read by the remote. This driver assumes the sender polls +STAT register and the remote clears it after having read the data.That could be design, interrupt support could be present on some systems. The bindings should be flexible to add that support in future if needed along with necessary code.
We are the only 2 users of MHU atm and neither have that feature. I even doubt if that is a configurable option. I stand corrected if you share some spec telling otherwise because all I have is a few snapshot'ed pages of MHU spec in a Japanese manual. So please lets keep things simple until we see real need for it.
Thanks
Jassi
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 40 lines · Jassi Brar
Quoted 30 lines · Sudeep Holla
Quoted 27 lines · Vincent Yang
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+)create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txtcreate mode 100644drivers/mailbox/arm_mhu.cDocumentation/devicetree/bindings/mailbox/arm-mhu.txt new file +3
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== +Quoted 9 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 2 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +2
-0+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has +3 independent channels/links to communicate with remote processor(s).I had reviewed this before and I see not all the comments are addressed. I had mentioned that you can't add support to _SECURE_ channel in Linux as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Quoted 6 lines
Please revisit the old thread. After some discussion you had graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you have valid reasons. In case you decide to support it ....
]
Agreed but based on the other email in the same thread it looks like you want to run the same kernel both in secure and no-secure mode on this platform, in which case you _have_to_assume_ it's *non-secure only* always unless you come up with some DT magic.
Quoted 6 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.
Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
Regards,
Sudeep
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 56 lines · Sudeep Holla
Quoted 45 lines · Jassi Brar
Quoted 34 lines · Sudeep Holla
Quoted 30 lines · Vincent Yang
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+)create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txt
create mode 100644drivers/mailbox/arm_mhu.cDocumentation/devicetree/bindings/mailbox/arm-mhu.txt new file +4
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== + +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that hasQuoted 9 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 1 line
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +1
-0+3 independent channels/links to communicate with remote processor(s).I had reviewed this before and I see not all the comments are addressed. I had mentioned that you can't add support to _SECURE_ channel in Linux as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Quoted 6 lines
Please revisit the old thread. After some discussion you had graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you have valid reasons. In case you decide to support it ....
]
Quoted 5 lines
Agreed but based on the other email in the same thread it looks like you want to run the same kernel both in secure and no-secure mode on this platform, in which case you _have_to_assume_ it's *non-secure only* always unless you come up with some DT magic.
Yes, the S vs NS mode should ideally be defined in DT. The kernel image should remain the same.
Quoted 11 lines
Quoted 6 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
mhu: mailbox at 2b1f0000 {
#mbox-cells = <1>;
compatible = "arm,mbox-mhu";
reg = <0 0x2b1f0000 0x1000>;
interrupts = <0 36 4>, /* LP Non-Sec */
<0 35 4>, /* HP Non-Sec */
<0 37 4>; /* Secure */
};
mhu_client: scb at 2e000000 {
compatible = "fujitsu,mb86s70-scb-1.0";
reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
mboxes = <&mhu 1>;
};See the DT for mbox client specifies that it uses channel-1 which is High-Priority_Non-Secure channel.
-jassi
Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 7 lines · Jassi Brar
Quoted 5 lines · Sudeep Holla
Quoted 2 lines · Jassi Brar
On 25 November 2014 at 20:07, Sudeep Holla <[email protected]>
Quoted 23 lines · wrote:
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines · Vincent Yang
Quoted 19 lines
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+)create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txt
create mode 100644drivers/mailbox/arm_mhu.c
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 4
Quoted 11 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +4
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== + +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that
has
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 1 line
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +1
-0+3 independent channels/links to communicate with remote
processor(s).
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
I had reviewed this before and I see not all the comments are
addressed.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
I had mentioned that you can't add support to _SECURE_ channel in
Linux
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 3 lines
as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Please revisit the old thread. After some discussion you had graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux,
you
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines
have valid reasons. In case you decide to support it .... ]
Agreed but based on the other email in the same thread it looks like you want to run the same kernel both in secure and no-secure mode on this platform, in which case you _have_to_assume_ it's *non-secure only*
always
Quoted 4 lines
Quoted 2 lines
unless you come up with some DT magic.
Yes, the S vs NS mode should ideally be defined in DT. The kernel image should remain the same.
If this is desirable, we can edit the related dtb path in memory accordingly at the bootloader, since that knows at runtime if he's secure or nonsecure.
-Andy
Quoted 32 lines
Quoted 11 lines
Quoted 6 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
mhu: mailbox@2b1f0000 { #mbox-cells = <1>; compatible = "arm,mbox-mhu"; reg = <0 0x2b1f0000 0x1000>; interrupts = <0 36 4>, /* LP Non-Sec */ <0 35 4>, /* HP Non-Sec */ <0 37 4>; /* Secure */ }; mhu_client: scb@2e000000 { compatible = "fujitsu,mb86s70-scb-1.0"; reg = <0 0x2e000000 0x4000>; /* SHM for IPC */ mboxes = <&mhu 1>; };See the DT for mbox client specifies that it uses channel-1 which is High-Priority_Non-Secure channel.
-jassi
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
In reply to Jassi BrarQuoted 57 lines · Jassi Brar
Quoted 56 lines · Sudeep Holla
Quoted 51 lines · Jassi Brar
Quoted 34 lines · Sudeep Holla
Quoted 30 lines · Vincent Yang
Add driver for the ARM Message-Handling-Unit (MHU).
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../devicetree/bindings/mailbox/arm-mhu.txt | 33 ++++ drivers/mailbox/Kconfig | 7 + drivers/mailbox/Makefile | 2 + drivers/mailbox/arm_mhu.c | 196 +++++++++++++++++++++ 4 files changed, 238 insertions(+) create mode 100644
Documentation/devicetree/bindings/mailbox/arm-mhu.txt
create mode 100644drivers/mailbox/arm_mhu.cDocumentation/devicetree/bindings/mailbox/arm-mhu.txt new file +4
-0@@ -0,0 +1,33 @@ +ARM MHU Mailbox Driver +====================== + +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that hasQuoted 9 lines
Documentation/devicetree/bindings/mailbox/arm-mhu.txt line 5
Quoted 1 line
Documentation/devicetree/bindings/mailbox/arm-mhu.txt new file +1
-0+3 independent channels/links to communicate with remote processor(s).I had reviewed this before and I see not all the comments are addressed. I had mentioned that you can't add support to _SECURE_ channel in Linux as you need to assume Linux runs in non-secure privilege(and I gather that's the case even on this platform from other email in the thread)
Please revisit the old thread. After some discussion you had graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you have valid reasons. In case you decide to support it ....
]
Quoted 8 lines
Quoted 5 lines
Agreed but based on the other email in the same thread it looks like you want to run the same kernel both in secure and no-secure mode on this platform, in which case you _have_to_assume_ it's *non-secure only* always unless you come up with some DT magic.
Yes, the S vs NS mode should ideally be defined in DT. The kernel image should remain the same.
That's good :)
Quoted 13 lines
Quoted 11 lines
Quoted 6 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
Quoted 7 lines
mhu: mailbox at 2b1f0000 {
#mbox-cells = <1>;
compatible = "arm,mbox-mhu";
reg = <0 0x2b1f0000 0x1000>;
interrupts = <0 36 4>, /* LP Non-Sec */
<0 35 4>, /* HP Non-Sec */
<0 37 4>; /* Secure */One possible issue I can think of(though current driver design requests irq only on channel startup, it could be moved to probe for optimization in which case you need a way to make sure secure channel or irq is not accessed)
Quoted 11 lines
}; mhu_client: scb at 2e000000 { compatible = "fujitsu,mb86s70-scb-1.0"; reg = <0 0x2e000000 0x4000>; /* SHM for IPC */ mboxes = <&mhu 1>; };See the DT for mbox client specifies that it uses channel-1 which is High-Priority_Non-Secure channel.
Yes I noticed that, but still a wrong entry of another mhu_client with secure channel might end up crashing MHU driver or even whole system. Not sure but still probably one could try to play around with DT overlays in future, just a thought. So you need to ensure that's handled properly in the MHU driver.
Regards,
Sudeep
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 25 lines · Sudeep Holla
Quoted 15 lines · Jassi Brar
Quoted 9 lines
Quoted 8 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Quoted 4 lines
Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
Quoted 7 lines
mhu: mailbox at 2b1f0000 { #mbox-cells = <1>; compatible = "arm,mbox-mhu"; reg = <0 0x2b1f0000 0x1000>; interrupts = <0 36 4>, /* LP Non-Sec */ <0 35 4>, /* HP Non-Sec */ <0 37 4>; /* Secure */
Quoted 5 lines
One possible issue I can think of(though current driver design requests irq only on channel startup, it could be moved to probe for optimization in which case you need a way to make sure secure channel or irq is not accessed)
As you see it is fine as such.
I don't think acquiring all irqs during probe is a good idea. mbox_request_channel() is when we should actually be reserving resources.
Quoted 12 lines
Quoted 11 lines
}; mhu_client: scb at 2e000000 { compatible = "fujitsu,mb86s70-scb-1.0"; reg = <0 0x2e000000 0x4000>; /* SHM for IPC */ mboxes = <&mhu 1>; };See the DT for mbox client specifies that it uses channel-1 which is High-Priority_Non-Secure channel.
Quoted 6 lines
Yes I noticed that, but still a wrong entry of another
mhu_clientwith secure channel might end up crashing MHU driver or even whole system. Not sure but still probably one could try to play around with DT overlays in future, just a thought. So you need to ensure that's handled properly in the MHU driver.
You worry too much ;) what if some 'wrong entry' in DT specifies memory where there is none or some voltage that could toast the board?
-Jassi
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 26 lines · Jassi Brar
Quoted 25 lines · Sudeep Holla
Quoted 22 lines · Jassi Brar
Quoted 9 lines
Quoted 8 lines
It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Quoted 4 lines
Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
mhu: mailbox at 2b1f0000 { #mbox-cells = <1>; compatible = "arm,mbox-mhu"; reg = <0 0x2b1f0000 0x1000>; interrupts = <0 36 4>, /* LP Non-Sec */ <0 35 4>, /* HP Non-Sec */ <0 37 4>; /* Secure */
Quoted 6 lines
Quoted 5 lines
One possible issue I can think of(though current driver design requests irq only on channel startup, it could be moved to probe for optimization in which case you need a way to make sure secure channel or irq is not accessed)
As you see it is fine as such.
Agreed, but assuming some driver logic. I would like to see some way of identifying that from DT if we adding the support for secure channel in the driver else I prefer not to add it unless there is a real user of it(which is not the case with your current patch set). That will be handy if there's any issue in future due to some firmware that can't be changed or upgraded.
Regards,
Sudeep
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 42 lines · Sudeep Holla
Quoted 31 lines · Jassi Brar
Quoted 29 lines · Sudeep Holla
Quoted 24 lines · Jassi Brar
Quoted 11 lines
Quoted 10 lines
It seems you still don't get my point that the driver should
manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Quoted 4 lines
Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
mhu: mailbox at 2b1f0000 { #mbox-cells = <1>; compatible = "arm,mbox-mhu"; reg = <0 0x2b1f0000 0x1000>; interrupts = <0 36 4>, /* LP Non-Sec */ <0 35 4>, /* HP Non-Sec */ <0 37 4>; /* Secure */Quoted 6 lines
Quoted 5 lines
One possible issue I can think of(though current driver design requests irq only on channel startup, it could be moved to probe for optimization in which case you need a way to make sure secure channel or irq is not accessed)
As you see it is fine as such.
Quoted 7 lines
Agreed, but assuming some driver logic. I would like to see some way of identifying that from DT if we adding the support for secure channel in the driver else I prefer not to add it unless there is a real user of it(which is not the case with your current patch set). That will be handy if there's any issue in future due to some firmware that can't be changed or upgraded.
Could you please suggest some way of identifying that from DT if we adding the support for secure channel in the driver?
-jassi
PATCH 2/9 mailbox: arm_mhu: add driver for ARM MHU controller
Quoted 50 lines · Jassi Brar
Quoted 42 lines · Sudeep Holla
Quoted 31 lines · Jassi Brar
Quoted 29 lines · Sudeep Holla
Quoted 24 lines · Jassi Brar
Quoted 11 lines
Quoted 10 lines
It seems you still don't get my point that the driver should
manage
all channels - S & NS. If Linux is running in NS mode on a platform, the DT will specify only some NS channel to be used. The controller driver shouldn't be crippled just because you think Linux will never be run in Secure mode.Quoted 4 lines
Ok how do you handle that, I don't see that in the DT binding. As it stands, you can unconditionally try to access the secure channel and cause aborts if the platform is running in non-secure mode.
No. Please look at the dtsi again ....
mhu: mailbox at 2b1f0000 { #mbox-cells = <1>; compatible = "arm,mbox-mhu"; reg = <0 0x2b1f0000 0x1000>; interrupts = <0 36 4>, /* LP Non-Sec */ <0 35 4>, /* HP Non-Sec */ <0 37 4>; /* Secure */Quoted 6 lines
Quoted 5 lines
One possible issue I can think of(though current driver design requests irq only on channel startup, it could be moved to probe for optimization in which case you need a way to make sure secure channel or irq is not accessed)
As you see it is fine as such.
Quoted 7 lines
Agreed, but assuming some driver logic. I would like to see some way of identifying that from DT if we adding the support for secure channel in the driver else I prefer not to add it unless there is a real user of it(which is not the case with your current patch set). That will be handy if there's any issue in future due to some firmware that can't be changed or upgraded.
Quoted 3 lines
Could you please suggest some way of identifying that from DT if we adding the support for secure channel in the driver?
Sorry, I don't have any idea yet on that as the general rule is not to touch anything secure in kernel assuming Linux always runs in non-secure mode.
Now if you need an exception, you need to propose the binding and take up the discussion on the devicetree list.
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Vincent YangThe remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.S
arch/arm/mach-mb86s7x/Makefile +1 -1
@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.o
arch/arm/mach-mb86s7x/mcpm.c new file +360 -0
360 lines not on this page · raw message
arch/arm/mach-mb86s7x/smc.S new file +27 -0
@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0 + mcr p15, 0, r4, c1, c0, 0 + ldmfd sp!, {r1-r11, pc} +ENDPROC(mb86s7x_cpu_entry)
Signature · 1 line
1.9.0
Arnd Bergmann
maintainerPATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 20 lines · On Thursday 20 November 2014 20:35:20 Vincent Yang wrote:
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +0
-0
arch/arm/mach-mb86s7x/Makefile line 1
Quoted 2 lines
arch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.o
The two files are using ARMv7-only instructions in inline assembly, which means that you will get a compile error for a combined arvm6+armv7 kernel. Please add the appropriate 'CFLAGS_mcpm.o += -march=armv7-a' statements in the Makefile for each file with this problem.
arch/arm/mach-mb86s7x/Makefile
Quoted 4 lines
arch/arm/mach-mb86s7x/Makefile +4
-0+ +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU]; +extern void __iomem *mb86s7x_shm_base;
Out of principle, you should never put an 'extern' declaration into .c file. Better put this into a header file that is shared between all files accessing the variable. In this particular case, I think it would be better to just move the mb86s7x_set_wficolor() implementation into drivers/soc/mb86s7x/scb_mhu.c and add an exported symbol for that, so you can keep the variable local to the mhu implementation.
Quoted 8 lines
arch/arm/mach-mb86s7x/Makefile +8
-0+#define mb86s70evb_exit_coherency_flush(level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \ + "bic r0, r0, #"__stringify(CR_C)"\n\t" \ + "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ + "isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \
arch/arm/mach-mb86s7x/Makefile
Quoted 10 lines
arch/arm/mach-mb86s7x/Makefile +10
-0+ "bl mb86s70evb_outer_flush_all\n\t" \ + "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \ + "bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \ + "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \ + "isb\n\t" \ + "dsb\n\t" \ + "ldmfd sp!, {fp, ip}" \ + : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ + "r9", "r10", "lr", "memory"); \ + }
Please make this an inline function instead of a macro.
arch/arm/mach-mb86s7x/Makefile
Quoted 2 lines
arch/arm/mach-mb86s7x/Makefile +2
-0+ +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);
Same comment about the extern declaration here. The header won't be used by the implementation file as that is written in assembly, but it's better to be consistent.
Arnd
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 60 lines · Arnd Bergmann
Quoted 20 lines · On Thursday 20 November 2014 20:35:20 Vincent Yang wrote:
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +0
-0arch/arm/mach-mb86s7x/Makefile line 1
Quoted 2 lines
arch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oThe two files are using ARMv7-only instructions in inline assembly, which means that you will get a compile error for a combined arvm6+armv7 kernel. Please add the appropriate 'CFLAGS_mcpm.o += -march=armv7-a' statements in the
Makefilefor each file with this problem.arch/arm/mach-mb86s7x/Makefile
Quoted 4 lines
arch/arm/mach-mb86s7x/Makefile +4
-0+ +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU]; +extern void __iomem *mb86s7x_shm_base;Out of principle, you should never put an 'extern' declaration into .c file. Better put this into a header file that is shared between all files accessing the variable. In this particular case, I think it would be better to just move the
mb86s7x_set_wficolor()implementation intodrivers/soc/mb86s7x/scb_mhu.cand add an exported symbol for that, so you can keep the variable local to the mhu implementation.Quoted 8 lines
arch/arm/mach-mb86s7x/Makefile +8
-0+#define mb86s70evb_exit_coherency_flush(level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \ + "bic r0, r0, #"__stringify(CR_C)"\n\t" \ + "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ + "isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \arch/arm/mach-mb86s7x/Makefile
Quoted 10 lines
arch/arm/mach-mb86s7x/Makefile +10
-0+ "bl mb86s70evb_outer_flush_all\n\t" \ + "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \ + "bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \ + "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \ + "isb\n\t" \ + "dsb\n\t" \ + "ldmfd sp!, {fp, ip}" \ + : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ + "r9", "r10", "lr", "memory"); \ + }
Quoted 9 lines
Please make this an inline function instead of a macro.
arch/arm/mach-mb86s7x/Makefile
Quoted 2 lines
arch/arm/mach-mb86s7x/Makefile +2
-0+ +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);Same comment about the extern declaration here. The header won't be used by the implementation file as that is written in assembly, but it's better to be consistent.
Will do all.
Thanks,
Jassi
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Vincent YangQuoted 15 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-)create mode 100644
arch/arm/mach-mb86s7x/mcpm.c
create mode 100644arch/arm/mach-mb86s7x/smc.S
[...]
arch/arm/mach-mb86s7x/mcpm.c line 65
Quoted 6 lines
arch/arm/mach-mb86s7x/mcpm.c new file +6
-0+asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \
You are duplicating the generic macro just to add outer cache, I was thinking of extending the generic macro to add outer cache support, but IMO it might be bit tricky for below mentioned reasons.
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c new file +8
-0+ asmvolatile ( \ +"stmfd sp!, {fp, ip}\n\t" \ +"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \ + "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \
IIUC, this seem to be broken IMO, you are doing the outer cache flush unconditionally which means:
1. You do this for every CPU power down(i.e. when level = louis) which is incorrect.
2. You do this for every cluster powerdown, again is that required if the other cluster is active. You may have to trace last cluster in the system.
Quoted 20 lines
arch/arm/mach-mb86s7x/smc.S new file +14
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec +
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 10 lines
arch/arm/mach-mb86s7x/smc.S new file +10
-0+/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0
Interesting, it looks like you have some secure entity running on your platform.
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
2. Is Linux running in Secure or Non-secure mode ?
3. Why do you need this smc call for secondary boot only ?
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 32 lines · Sudeep Holla
Quoted 31 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
arch/arm/mach-mb86s7x/smc.S new file +20
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0
Quoted 8 lines
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 4 lines
arch/arm/mach-mb86s7x/smc.S new file +4
-0+ mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0Interesting, it looks like you have some secure entity running on your platform.
Yes, we have a stub "secure firmware" that implements a few critical functions to allow us to operate the kernel as nonsecure. It's part of the bootloader for this platform which is also GPL'd.
Quoted 2 lines
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
Nothing. The secure firmware is in a bootloader that is copied to and runs from secure sram. When the cpu is reset, he comes back up in secure mode and gets initialized in the secure firmware, before entering Non-secure mode and the kernel's secondary entry point.
Quoted 1 line
2. Is Linux running in Secure or Non-secure mode ?
Another firmware (unfortunately not GPL) running on an on-die M3 informs the secure firmware on the AP whether he should set the AP cpu to nonsecure or not before jumping to the kernel... basically it's decided at runtime and the same kernel binary serves in both modes.
Quoted 1 line
3. Why do you need this smc call for secondary boot only ?
The call sets the secondary entry point stored in the secure sram.
The bootloader heuristic is if that's unset (0), and it's what the bootloader decided should be regarded as the primary cpu, then we do the real onetime cold boot flow, load the kernel etc. Non-primary cpus wait at WFI in the bootloader. When the primary cpu runs the code above, he sets the secondary entry point, and later starts to bring up the other cores who jump to the secondary entry that was set.
-Andy
Quoted 3 lines
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 43 lines · Andy Green
Quoted 32 lines · Sudeep Holla
Quoted 31 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
arch/arm/mach-mb86s7x/smc.S new file +20
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0Quoted 8 lines
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 4 lines
arch/arm/mach-mb86s7x/smc.S new file +4
-0+ mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0Interesting, it looks like you have some secure entity running on your platform.
Quoted 4 lines
Yes, we have a stub "secure firmware" that implements a few critical functions to allow us to operate the kernel as nonsecure. It's part of the bootloader for this platform which is also GPL'd.
OK, thanks for clarifying.
Quoted 8 lines
Quoted 2 lines
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
Nothing. The secure firmware is in a bootloader that is copied to and runs from secure sram. When the cpu is reset, he comes back up in secure mode and gets initialized in the secure firmware, before entering Non-secure mode and the kernel's secondary entry point.
So you do have live secure firmware stub on secure sram at any time, right ? When the CPUs are powered down especially for low power states, how is the secure state of the CPUs preserved ?
Quoted 7 lines
Quoted 1 line
2. Is Linux running in Secure or Non-secure mode ?
Another firmware (unfortunately not GPL) running on an on-die M3 informs the secure firmware on the AP whether he should set the AP cpu to nonsecure or not before jumping to the kernel... basically it's decided at runtime and the same kernel binary serves in both modes.
OK that's fine as along as you assume that kernel *always* runs in *non-secure* mode and never attempts any *secure access*.
Quoted 4 lines
Quoted 1 line
3. Why do you need this smc call for secondary boot only ?
The call sets the secondary entry point stored in the secure sram.
So IIUC, you run Linux in non-secure mode, PSCI would be more suitable than MCPM when you start thinking/implementing CPUIdle otherwise I think you will end up duplicating some logic(last man and race management) both in Linux as well as your secure firmware.
Quoted 1 line
The bootloader heuristic is if that's unset (0), and it's what the
This could be problem as when the CPU is hotplugged out, ideally it should be set to 0 to avoid spurious wakeup and entry into Linux. Yes MCPM does manage it, but IMO you are mixing up secure and non-secure methods which might become issue later when implementing low power CPU states.
Quoted 4 lines
bootloader decided should be regarded as the primary cpu, then we do the real onetime cold boot flow, load the kernel etc. Non-primary cpus wait at WFI in the bootloader. When the primary cpu runs the code above, he sets the secondary entry point, and later starts to
I assume it's not done when primary boots, but by primary cpu when bringing up the secondaries.
Quoted 2 lines
bring up the other cores who jump to the secondary entry that was set.
I assume primary sends IPI to wake up secondaries, but if the SGIs are configured as secure, then it will _not_ be delivered. If not it *might* work but I can't understand the need of running Linux non-secure with all secure access given to it.
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 67 lines · Sudeep Holla
Quoted 47 lines · Andy Green
Quoted 34 lines · Sudeep Holla
Quoted 33 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
arch/arm/mach-mb86s7x/smc.S new file +21
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3Quoted 8 lines
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 3 lines
arch/arm/mach-mb86s7x/smc.S new file +3
-0+ and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0Interesting, it looks like you have some secure entity running on your platform.
Quoted 4 lines
Yes, we have a stub "secure firmware" that implements a few critical functions to allow us to operate the kernel as nonsecure. It's part of the bootloader for this platform which is also GPL'd.
OK, thanks for clarifying.
Quoted 9 lines
Quoted 2 lines
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
Nothing. The secure firmware is in a bootloader that is copied to and runs from secure sram. When the cpu is reset, he comes back up in secure mode and gets initialized in the secure firmware, before entering Non-secure mode and the kernel's secondary entry point.
Quoted 3 lines
So you do have live secure firmware stub on secure sram at any time, right ? When the CPUs are powered down especially for low power states, how is the secure state of the CPUs preserved ?
There isn't any 'secure state' like you are thinking.
Our secure firmware is a rudimentary stub that provides a handful of stateless secure services to the kernel.
There's nothing to save or restore.
Quoted 11 lines
Quoted 8 lines
Quoted 1 line
2. Is Linux running in Secure or Non-secure mode ?
Another firmware (unfortunately not GPL) running on an on-die M3 informs the secure firmware on the AP whether he should set the AP cpu to nonsecure or not before jumping to the kernel... basically it's decided at runtime and the same kernel binary serves in both modes.
OK that's fine as along as you assume that kernel *always* runs in *non-secure* mode and never attempts any *secure access*.
Yes that's how it's set up.
When this M3 tells the bootloader to make us nonsecure before going to the kernel, he marks up all the IPs that have dynamic access control to allow access in nonsecure. That's because we have complete BSP support out of tree and we want to prove that it can all work from nonsecure directly.
When Fujitsu want to restrict an IP from nonsecure access for a particular customer they will add support to manage the IP either on the M3 or the AP secure firmware and disable the IP support in DT. But that does not exist yet.
Quoted 10 lines
Quoted 5 lines
Quoted 1 line
3. Why do you need this smc call for secondary boot only ?
The call sets the secondary entry point stored in the secure sram.
So IIUC, you run Linux in non-secure mode, PSCI would be more suitable than MCPM when you start thinking/implementing CPUIdle otherwise I think you will end up duplicating some logic(last man and race management) both in Linux as well as your secure firmware.
As I mentioned our secure firmware is not what you're imagining.
MCPM works very well for us. Are you saying we can't use MCPM and must reimplement with PSCI on both sides?
Quoted 5 lines
Quoted 1 line
The bootloader heuristic is if that's unset (0), and it's what the
This could be problem as when the CPU is hotplugged out, ideally it should be set to 0 to avoid spurious wakeup and entry into Linux.
... I think you are talking about something else.
This is a PA stored in secure SRAM that holds the kernel's secondary entry point. It's 0 when the bootloader is copied to the secure SRAM by the M3 at cold reset. If anybody set it, it means Linux booted.
The M3 manages AP core state and either depowers the cluster or holds them in reset. So there can be no 'spurious wakeup and entry into Linux'.
Quoted 3 lines
Yes MCPM does manage it, but IMO you are mixing up secure and non-secure methods which might become issue later when implementing low power CPU states.
Can you explain where you see the problem? All we are doing is storing the kernel secondary entry point. The bootloader / secure firmware always receives any started core first and decides when and how to jump to it.
Quoted 8 lines
Quoted 4 lines
bootloader decided should be regarded as the primary cpu, then we do the real onetime cold boot flow, load the kernel etc. Non-primary cpus wait at WFI in the bootloader. When the primary cpu runs the code above, he sets the secondary entry point, and later starts to
I assume it's not done when primary boots, but by primary cpu when bringing up the secondaries.
Yes the point is the primary sets the secondary entry at the secure firmware using the SMC and then the IPIs can start flying.
Quoted 5 lines
Quoted 2 lines
bring up the other cores who jump to the secondary entry that was set.
I assume primary sends IPI to wake up secondaries, but if the SGIs are configured as secure, then it will _not_ be delivered. If not it *might*
Well, it is coordinated between M3 and AP bootloader / secure firmware if we should run nonsecure or not, and it configures a bunch of stuff like GIC accordingly so it works. And it does work.
Quoted 2 lines
work but I can't understand the need of running Linux non-secure with all secure access given to it.
Fujitsu's goal with this was confirm the SoC + kernel can work in nonsecure for the whole BSP stack. Then as customers want particular IPs secure-only, implement the behaviour they need in the AP secure firmware or M3. But as yet, no support for that is implemented.
-Andy
Quoted 3 lines
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 11 lines · Andy Green
Quoted 4 lines · Sudeep Holla
So IIUC, you run Linux in non-secure mode, PSCI would be more suitable than MCPM when you start thinking/implementing CPUIdle otherwise I think you will end up duplicating some logic(last man and race management) both in Linux as well as your secure firmware.
As I mentioned our secure firmware is not what you're imagining.
MCPM works very well for us. Are you saying we can't use MCPM and must reimplement with PSCI on both sides?
I said it many times before: not everyone is willing to invest in the complexity trap implied by the firmware model as proposed by ARM. This is a concrete example of that. MCPM-like functionality is an order of magnitude simpler to debug and maintain when implemented on the easily-replaceable kernel side.
Nicolas
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Andy GreenQuoted 72 lines · Andy Green
Quoted 67 lines · Sudeep Holla
Quoted 47 lines · Andy Green
Quoted 34 lines · Sudeep Holla
Quoted 33 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
arch/arm/mach-mb86s7x/smc.S new file +21
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3Quoted 8 lines
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 3 lines
arch/arm/mach-mb86s7x/smc.S new file +3
-0+ and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0Interesting, it looks like you have some secure entity running on your platform.
Quoted 4 lines
Yes, we have a stub "secure firmware" that implements a few critical functions to allow us to operate the kernel as nonsecure. It's part of the bootloader for this platform which is also GPL'd.
OK, thanks for clarifying.
Quoted 9 lines
Quoted 2 lines
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
Nothing. The secure firmware is in a bootloader that is copied to and runs from secure sram. When the cpu is reset, he comes back up in secure mode and gets initialized in the secure firmware, before entering Non-secure mode and the kernel's secondary entry point.
Quoted 3 lines
So you do have live secure firmware stub on secure sram at any time, right ? When the CPUs are powered down especially for low power states, how is the secure state of the CPUs preserved ?
Quoted 7 lines
There isn't any 'secure state' like you are thinking.
Our secure firmware is a rudimentary stub that provides a handful of stateless secure services to the kernel.
There's nothing to save or restore.
Ok that clarifies, but I assume some customers would like to extend that beyond the stub.
Quoted 20 lines
Quoted 11 lines
Quoted 8 lines
Quoted 1 line
2. Is Linux running in Secure or Non-secure mode ?
Another firmware (unfortunately not GPL) running on an on-die M3 informs the secure firmware on the AP whether he should set the AP cpu to nonsecure or not before jumping to the kernel... basically it's decided at runtime and the same kernel binary serves in both modes.
OK that's fine as along as you assume that kernel *always* runs in *non-secure* mode and never attempts any *secure access*.
Yes that's how it's set up.
When this M3 tells the bootloader to make us nonsecure before going to the kernel, he marks up all the IPs that have dynamic access control to allow access in nonsecure. That's because we have complete BSP support out of tree and we want to prove that it can all work from nonsecure directly.
Quoted 5 lines
When Fujitsu want to restrict an IP from nonsecure access for a particular customer they will add support to manage the IP either on the M3 or the AP secure firmware and disable the IP support in DT. But that does not exist yet.
Yes this was what I was trying to tell. From what I understand now, if the customer implements secure firmware which might need to save and restore the state, then he needs to manage.(He might end up with duplication of this last man algorithm in the secure firmware too, I was just trying to mention this)
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 1 line
3. Why do you need this smc call for secondary boot only ?
The call sets the secondary entry point stored in the secure sram.
Quoted 7 lines
Quoted 4 lines
So IIUC, you run Linux in non-secure mode, PSCI would be more suitable than MCPM when you start thinking/implementing CPUIdle otherwise I think you will end up duplicating some logic(last man and race management) both in Linux as well as your secure firmware.
As I mentioned our secure firmware is not what you're imagining.
Understood, that?s about the current stub secure firmware and I was talking about non-existent full blown secure firmware. If that's not the case, then it's fine.
Quoted 3 lines
MCPM works very well for us. Are you saying we can't use MCPM and must reimplement with PSCI on both sides?
No I never said that, I wanted to understand what's the scope of your or any secure firmware of your customer.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
The bootloader heuristic is if that's unset (0), and it's what the
This could be problem as when the CPU is hotplugged out, ideally it should be set to 0 to avoid spurious wakeup and entry into Linux.
... I think you are talking about something else.
Quoted 8 lines
This is a PA stored in secure SRAM that holds the kernel's secondary entry point. It's 0 when the bootloader is copied to the secure SRAM by the M3 at cold reset. If anybody set it, it means Linux booted.
The M3 manages AP core state and either depowers the cluster or holds them in reset. So there can be no 'spurious wakeup and entry into Linux'.
Ok, good that you can guarantee that.
Quoted 15 lines
Quoted 3 lines
Yes MCPM does manage it, but IMO you are mixing up secure and non-secure methods which might become issue later when implementing low power CPU states.
Can you explain where you see the problem? All we are doing is storing the kernel secondary entry point. The bootloader / secure firmware always receives any started core first and decides when and how to jump to it.
Quoted 6 lines
Quoted 4 lines
bootloader decided should be regarded as the primary cpu, then we do the real onetime cold boot flow, load the kernel etc. Non-primary cpus wait at WFI in the bootloader. When the primary cpu runs the code above, he sets the secondary entry point, and later starts to
Quoted 6 lines
Quoted 2 lines
I assume it's not done when primary boots, but by primary cpu when bringing up the secondaries.
Yes the point is the primary sets the secondary entry at the secure firmware using the SMC and then the IPIs can start flying.
Only if GIC is properly configured for that though I don't see the point in giving non-secure entity secure access. If any secure firmware wants to change that in future that could be issue.
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
bring up the other cores who jump to the secondary entry that was set.
I assume primary sends IPI to wake up secondaries, but if the SGIs are configured as secure, then it will _not_ be delivered. If not it *might*
Well, it is coordinated between M3 and AP bootloader / secure firmware if we should run nonsecure or not, and it configures a bunch of stuff like GIC accordingly so it works. And it does work.
Quoted 8 lines
Quoted 2 lines
work but I can't understand the need of running Linux non-secure with all secure access given to it.
Fujitsu's goal with this was confirm the SoC + kernel can work in nonsecure for the whole BSP stack. Then as customers want particular IPs secure-only, implement the behaviour they need in the AP secure firmware or M3. But as yet, no support for that is implemented.
I never said you *must implement* PSCI and *not use* MCPM. Since you mentioned that you will be providing option to run Linux in non-secure mode, which means there can be _secure_entity_ which does more than your current stub, I just wanted to mention the possible issues you may need to resolve then.
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 86 lines · Sudeep Holla
Quoted 83 lines · Andy Green
Quoted 74 lines · Sudeep Holla
Quoted 52 lines · Andy Green
Quoted 37 lines · Sudeep Holla
Quoted 36 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
arch/arm/mach-mb86s7x/smc.S new file +6
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/ormodify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */arch/arm/mach-mb86s7x/smc.S new file +13
-0+ +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3 + and r3, #0xbfffffffQuoted 8 lines
arch/arm/mach-mb86s7x/smc.S line 24
Quoted 2 lines
arch/arm/mach-mb86s7x/smc.S new file +2
-0+ mcr p15, 0, r3, c1, c0, 0 + smc #0Interesting, it looks like you have some secure entity running on your platform.
Quoted 4 lines
Yes, we have a stub "secure firmware" that implements a few critical functions to allow us to operate the kernel as nonsecure. It's part of the bootloader for this platform which is also GPL'd.
OK, thanks for clarifying.
Quoted 10 lines
Quoted 2 lines
1. While the CPU is powered down who is taking care of saving it's state as you are doing it in the Linux itself ?
Nothing. The secure firmware is in a bootloader that is copied to and runs from secure sram. When the cpu is reset, he comes back up in secure mode and gets initialized in the secure firmware, before entering Non-secure mode and the kernel's secondary entry point.
Quoted 3 lines
So you do have live secure firmware stub on secure sram at any time, right ? When the CPUs are powered down especially for low power states, how is the secure state of the CPUs preserved ?
There isn't any 'secure state' like you are thinking.
Quoted 8 lines
Quoted 5 lines
Our secure firmware is a rudimentary stub that provides a handful of stateless secure services to the kernel.
There's nothing to save or restore.
Ok that clarifies, but I assume some customers would like to extend that beyond the stub.
Yes. But currently the only implementation is the stub one.
Quoted 28 lines
Quoted 22 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
2. Is Linux running in Secure or Non-secure mode ?
Quoted 8 lines
Quoted 5 lines
Another firmware (unfortunately not GPL) running on an on-die M3 informs the secure firmware on the AP whether he should set the AP cpu to nonsecure or not before jumping to the kernel... basically it's decided at runtime and the same kernel binary serves in both modes.
OK that's fine as along as you assume that kernel *always* runs in *non-secure* mode and never attempts any *secure access*.
Yes that's how it's set up.
When this M3 tells the bootloader to make us nonsecure before going to the kernel, he marks up all the IPs that have dynamic access control to allow access in nonsecure. That's because we have complete BSP support out of tree and we want to prove that it can all work from nonsecure directly.
Quoted 5 lines
When Fujitsu want to restrict an IP from nonsecure access for a particular customer they will add support to manage the IP either on the M3 or the AP secure firmware and disable the IP support in DT. But that does not exist yet.
Quoted 3 lines
Yes this was what I was trying to tell. From what I understand now, if the customer implements secure firmware which might need to save and restore the state, then he needs to manage.(He might end up with
Yes. But I think we'll have to implement and test management for that when it exists.
Quoted 2 lines
duplication of this last man algorithm in the secure firmware too, I was just trying to mention this)
Maybe... other patterns are also possible like whole core reservation at the bootloader / secure firmware to run a different secure OS and leave smp like it is.
Fujitsu's market is ASIC so they will implement whatever customization their customer likes in hardware, firmware and software.
Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
Quoted 6 lines
Quoted 1 line
3. Why do you need this smc call for secondary boot only ?
The call sets the secondary entry point stored in the secure sram.
So IIUC, you run Linux in non-secure mode, PSCI would be more suitable than MCPM when you start thinking/implementing CPUIdle otherwise I think you will end up duplicating some logic(last man and race management) both in Linux as well as your secure firmware.
Quoted 6 lines
Quoted 2 lines
As I mentioned our secure firmware is not what you're imagining.
Understood, that?s about the current stub secure firmware and I was talking about non-existent full blown secure firmware. If that's not the case, then it's fine.
OK
Quoted 6 lines
Quoted 3 lines
MCPM works very well for us. Are you saying we can't use MCPM and must reimplement with PSCI on both sides?
No I never said that, I wanted to understand what's the scope of your or any secure firmware of your customer.
Good thanks.
Quoted 42 lines
Quoted 10 lines
Quoted 6 lines
Quoted 1 line
The bootloader heuristic is if that's unset (0), and it's what the
This could be problem as when the CPU is hotplugged out, ideally it should be set to 0 to avoid spurious wakeup and entry into Linux.
... I think you are talking about something else.
Quoted 8 lines
This is a PA stored in secure SRAM that holds the kernel's secondary entry point. It's 0 when the bootloader is copied to the secure SRAM by the M3 at cold reset. If anybody set it, it means Linux booted.
The M3 manages AP core state and either depowers the cluster or holds them in reset. So there can be no 'spurious wakeup and entry into Linux'.
Ok, good that you can guarantee that.
Quoted 21 lines
Quoted 3 lines
Yes MCPM does manage it, but IMO you are mixing up secure and non-secure methods which might become issue later when implementing low power CPU states.
Can you explain where you see the problem? All we are doing is storing the kernel secondary entry point. The bootloader / secure firmware always receives any started core first and decides when and how to jump to it.
Quoted 9 lines
Quoted 4 lines
bootloader decided should be regarded as the primary cpu, then we do the real onetime cold boot flow, load the kernel etc. Non-primary cpus wait at WFI in the bootloader. When the primary cpu runs the code above, he sets the secondary entry point, and later starts to
I assume it's not done when primary boots, but by primary cpu when bringing up the secondaries.
Quoted 7 lines
Quoted 3 lines
Yes the point is the primary sets the secondary entry at the secure firmware using the SMC and then the IPIs can start flying.
Only if GIC is properly configured for that though I don't see the point in giving non-secure entity secure access. If any secure firmware wants to change that in future that could be issue.
Well the point is there is no irq handling or smp management in the secure firmware stub.
If it grows traditional secure world features like dealing with irqs in secure world we'll have to cross / test that bridge when and if we come to it.
Quoted 15 lines
Quoted 15 lines
Quoted 5 lines
Quoted 2 lines
bring up the other cores who jump to the secondary entry that was set.
I assume primary sends IPI to wake up secondaries, but if the SGIs are configured as secure, then it will _not_ be delivered. If not it *might*
Well, it is coordinated between M3 and AP bootloader / secure firmware if we should run nonsecure or not, and it configures a bunch of stuff like GIC accordingly so it works. And it does work.
Quoted 2 lines
work but I can't understand the need of running Linux non-secure with all secure access given to it.
Quoted 7 lines
Quoted 5 lines
Fujitsu's goal with this was confirm the SoC + kernel can work in nonsecure for the whole BSP stack. Then as customers want particular IPs secure-only, implement the behaviour they need in the AP secure firmware or M3. But as yet, no support for that is implemented.
I never said you *must implement* PSCI and *not use* MCPM. Since you
OK, good.
Quoted 4 lines
mentioned that you will be providing option to run Linux in non-secure mode, which means there can be _secure_entity_ which does more than your current stub, I just wanted to mention the possible issues you may need to resolve then.
OK, thanks for your feedback.
-Andy
Quoted 3 lines
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Vincent YangQuoted 91 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +63
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +}
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+ +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \ + "bic r0, r0, #"__stringify(CR_C)"\n\t" \ + "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ + "isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ + "bl mb86s70evb_outer_flush_all\n\t" \
This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Furthermore, the safety of this macro is ensured by not having any memory writes in the middle of the whole sequence. By calling mb86s70evb_outer_flush_all() there could be the return address pushed onto the stack before calling outer_flush_all() if some tail call optimization is not applied. And this is without saying what outer_flush_all() actually does.
Why can't you simply do this instead:
v7_exit_coherency_flush(all); outer_flush_all();
Of course you'll have to audit everything in the outer_flush_all() path to make sure no atomic instructions such as LDREX/STREX are invoked. Those have undefined behavior after CR_C is cleared.
Quoted 7 lines
arch/arm/mach-mb86s7x/mcpm.c new file +7
-0+"mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \ +"bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \ +"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \ +"isb\n\t" \ +"dsb\n\t" \ +"ldmfd sp!, {fp, ip}" \ + : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
arch/arm/mach-mb86s7x/mcpm.c line 90
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+ "r9", "r10", "lr", "memory"); \ + } + +static void +mb86s7x_set_wficolor (unsigned clstr,unsigned cpu,unsigned clr) +{ +u8 val; + +if (clr & ~AT_WFI_COLOR_MASK ) +return ;
Shouldn't this be a BUG() rather than a return?
Quoted 29 lines
arch/arm/mach-mb86s7x/mcpm.c new file +28
-0+ + val =readb_relaxed (mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); + val &= ~AT_WFI_COLOR_MASK ; + val |= clr; +writeb_relaxed (val, mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); +} + +static int mb86s7x_pm_power_up (unsigned int cpu,unsigned int cluster) +{ +int ret =0 ; + +if (cluster >=S7X_MAX_CLUSTER || cpu >=S7X_MAX_CPU ) +return -EINVAL ; + +pr_debug ("%s: cpu %u cluster %u\n" , __func__, cpu, cluster); + +local_irq_disable (); +arch_spin_lock (&mb86s7x_pm_lock); + + mb86s7x_pm_use_count[cluster][cpu]++; + +if (mb86s7x_pm_use_count[cluster][cpu] ==1 ) { +struct mb86s7x_cpu_gate cmd; + +arch_spin_unlock (&mb86s7x_pm_lock); +local_irq_enable ();
Quoted 1 line
From that point onward, nothing prevents concurrent execution in
mb86s7x_pm_suspend() racing to call mb86s7x_set_wficolor() resulting in an incoherent state depending on who wins the race.
Quoted 104 lines
arch/arm/mach-mb86s7x/mcpm.c new file +104
-0+ cmd.payload_size =sizeof (cmd); + cmd.cluster_class =0 ; + cmd.cluster_id = cluster; + cmd.cpu_id = cpu; + cmd.cpu_state =SCB_CPU_STATE_ON ; + +pr_debug ("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n" , + __func__, __LINE__, cmd.cluster_class, + cmd.cluster_id, cmd.cpu_id, cmd.cpu_state); + +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_NOTHING ); + ret =mb86s7x_send_packet (CMD_CPU_CLOCK_GATE_SET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) { +pr_err ("%s:%d failed!\n" , __func__, __LINE__); +return ret; + } + +pr_debug ("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n" , + __func__, __LINE__, cmd.cluster_class, + cmd.cluster_id, cmd.cpu_id, cmd.cpu_state); + +if (cmd.cpu_state !=SCB_CPU_STATE_ON ) +return -ENODEV ; + }else if (mb86s7x_pm_use_count[cluster][cpu] !=2 ) { +/* +* The only possible values are: +* 0 = CPU down +* 1 = CPU (still) up +* 2 = CPU requested to be up before it had a chance +* to actually make itself down. +* Any other value is a bug. +*/ +BUG (); + } + +return 0 ; +} + +static void mb86s7x_pm_suspend (u64 ignored) +{ +unsigned int mpidr, cpu, cluster; +bool last_man = false, skip_wfi = false; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +pr_debug ("%s: cpu %u cluster %u\n" , __func__, cpu, cluster); +__mcpm_cpu_going_down (cpu, cluster); + +arch_spin_lock (&mb86s7x_pm_lock); +BUG_ON (__mcpm_cluster_state (cluster) !=CLUSTER_UP ); + + mb86s7x_pm_use_count[cluster][cpu]--; + +if (mb86s7x_pm_use_count[cluster][cpu] ==0 ) { +if (!mb86s7x_pm_use_count[cluster][0 ] && + !mb86s7x_pm_use_count[cluster][1 ]) + last_man = true; +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_POWEROFF ); + }else if (mb86s7x_pm_use_count[cluster][cpu] ==1 ) { + skip_wfi = true;/* Overtaken by a power up */ + }else { +BUG (); + } + +if (!skip_wfi) +gic_cpu_if_down (); + +if (last_man &&__mcpm_outbound_enter_critical (cpu, cluster)) { +arch_spin_unlock (&mb86s7x_pm_lock); + +if (read_cpuid_part () ==ARM_CPU_PART_CORTEX_A15 ) { +/* +* On the Cortex-A15 we need to disable +* L2 prefetching before flushing the cache. +*/ + asmvolatile ( +"mcr p15, 1, %0, c15, c0, 3\n\t" +"isb\n\t" +"dsb" + : :"r" (0x400 )); + } + +mb86s70evb_exit_coherency_flush (all); + +cci_disable_port_by_cpu (mpidr); + +__mcpm_outbound_leave_critical (cluster,CLUSTER_DOWN ); + }else { +arch_spin_unlock (&mb86s7x_pm_lock); +mb86s70evb_exit_coherency_flush (louis); + } + +__mcpm_cpu_down (cpu, cluster); + +/* Now we are prepared for power-down, do it: */ +if (!skip_wfi) +wfi (); +} + +static void mb86s7x_pm_power_down (void ) +{
arch/arm/mach-mb86s7x/mcpm.c line 232
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+mb86s7x_pm_suspend (0 ); +} + +static int mb86s7x_wait_for_powerdown (unsigned int cpu,unsigned int cluster) +{ +struct mb86s7x_cpu_gate cmd; +int i, ret; + +if (cluster >=S7X_MAX_CLUSTER || cpu >=S7X_MAX_CPU ) +return 0 ;
This should return an error or BUG().
Quoted 164 lines
arch/arm/mach-mb86s7x/mcpm.c new file +127
-0+ cmd.payload_size =sizeof (cmd); + cmd.cluster_class =0 ; + cmd.cluster_id = cluster; + cmd.cpu_id = cpu; + cmd.cpu_state =SCB_CPU_STATE_ON ; + +for (i =0 ; i <50 ; i++) { + ret =mb86s7x_send_packet (CMD_CPU_CLOCK_GATE_GET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) { +pr_err ("%s:%d failed to get CPU status\n" , + __func__, __LINE__); +return ret; + } + +pr_debug ("%s:%d Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u\n" , + __func__, __LINE__, + cmd.cluster_class, cmd.cluster_id, + cmd.cpu_id, cmd.cpu_state); + +if (cmd.cpu_state ==SCB_CPU_STATE_OFF ) +return 0 ; + +msleep (20 ); + } + +return -ETIMEDOUT ; +} + +static void mb86s7x_pm_powered_up (void ) +{ +unsigned int mpidr, cpu, cluster; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +arch_spin_lock (&mb86s7x_pm_lock); +if (!mb86s7x_pm_use_count[cluster][cpu]) + mb86s7x_pm_use_count[cluster][cpu] =1 ; +arch_spin_unlock (&mb86s7x_pm_lock); +} + +static const struct mcpm_platform_ops mb86s7x_pm_power_ops = { + .power_up = mb86s7x_pm_power_up, + .power_down = mb86s7x_pm_power_down, + .wait_for_powerdown = mb86s7x_wait_for_powerdown, + .suspend = mb86s7x_pm_suspend, + .powered_up = mb86s7x_pm_powered_up, +}; + +/* +* Enable cluster-level coherency, in preparation for turning on the MMU. +*/ +static void __naked mb86s7x_pm_power_up_setup (unsigned int affinity_level) +{ + asmvolatile ("\n" +" cmp r0, #1\n" +" bxne lr\n" +" b cci_enable_port_for_self" ); +} + +static void __init mb86s7x_cache_off (void ) +{ +if (read_cpuid_part () ==ARM_CPU_PART_CORTEX_A15 ) { +/* disable L2 prefetching on the Cortex-A15 */ + asmvolatile ( +"mcr p15, 1, %0, c15, c0, 3\n\t" +"isb\n\t" +"dsb" + : :"r" (0x400 )); + } +mb86s70evb_exit_coherency_flush (all); +} + +struct mb86s7x_scb_version { +u32 payload_size; +u32 version; +u32 config_version; +}; + +extern void mb86s7x_cpu_entry (unsigned long secondary_entry); + +static int __init mb86s7x_mcpm_init (void ) +{ +unsigned int mpidr, cpu, cluster; +struct mb86s7x_scb_version cmd; +int ret; + +if (!cci_probed ()) +return -ENODEV ; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +pr_info ("Booting on cpu_%u cluster_%u\n" , cpu, cluster); + mb86s7x_pm_use_count[cluster][cpu] =1 ; + +/* reset the wfi 'color' for primary cpu */ +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_NOTHING ); + +/* Do SMC to set entry address for CPUs coming online */ +mb86s7x_cpu_entry (virt_to_phys (mcpm_entry_point)); + + cmd.payload_size =sizeof (cmd); + cmd.version =0 ; + cmd.config_version =0 ; + ret =mb86s7x_send_packet (CMD_SCB_CAPABILITY_GET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) +pr_err ("%s:%d failed to get SCB version\n" , + __func__, __LINE__); + +pr_info ("MB86S7x MCPM initialized: SCB version 0x%x:0x%x\n" , + cmd.version, cmd.config_version); + + ret =mcpm_platform_register (&mb86s7x_pm_power_ops); +if (!ret) + ret =mcpm_sync_init (mb86s7x_pm_power_up_setup); +if (!ret) + ret =mcpm_loopback (mb86s7x_cache_off);/* turn on the CCI */ +mcpm_smp_set_ops (); + +return ret; +} +early_initcall (mb86s7x_mcpm_init);arch/arm/mach-mb86s7x/smc.S new file +27
-0@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0 + mcr p15, 0, r4, c1, c0, 0 + ldmfd sp!, {r1-r11, pc} +ENDPROC(mb86s7x_cpu_entry)Signature · 1 line
1.9.0
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 98 lines · Nicolas Pitre
Quoted 96 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-)create mode 100644
arch/arm/mach-mb86s7x/mcpm.c
create mode 100644arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \
Quoted 9 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
IIUC the external/outer cache needs to be flushed only if it's last cluster going down. It would be suboptimal to flush it when one cluster is going down while other is still active. So it's not always correct for even "all" case too.
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 113 lines · Sudeep Holla
Quoted 100 lines · Nicolas Pitre
Quoted 98 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-)create mode 100644
arch/arm/mach-mb86s7x/mcpm.c
create mode 100644arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \Quoted 9 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Quoted 4 lines
IIUC the external/outer cache needs to be flushed only if it's last cluster going down. It would be suboptimal to flush it when one cluster is going down while other is still active. So it's not always correct for even "all" case too.
Indeed.
It is trivial to look at the cluster usage count and flush L2 whenever the other cluster's count is also 0. This would happen when the count lock is released which opens the possibility for races with the other cluster coming up or in the process of going down at the same time, causing spurious flushes... which we certainly can live with.
Nicolas
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Nicolas PitreQuoted 98 lines · Nicolas Pitre
Quoted 96 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \
Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Is this a bL system with unified and architected L2s ? I think so, so what's the outercache for ?
Quoted 7 lines
Furthermore, the safety of this macro is ensured by not having any memory writes in the middle of the whole sequence. By calling
mb86s70evb_outer_flush_all()there could be the return address pushed onto the stack before callingouter_flush_all()if some tail call optimization is not applied. And this is without saying whatouter_flush_all()actually does.
Quoted 8 lines
Why can't you simply do this instead:
v7_exit_coherency_flush(all); outer_flush_all();Of course you'll have to audit everything in the
outer_flush_all()path to make sure no atomic instructions such as LDREX/STREX are invoked. Those have undefined behavior afterCR_Cis cleared.
What you are saying is correct but first of all I would like to understand what outercache we are talking about here.
Code snippet above is fragile, as you said, and I'd rather disable the outercache before executing the power down sequence (which implies cache is cleaned/invalidated and quiescent before we clear the C bit) if there is an outercache to be managed.
Waiting in trepidation :)
Lorenzo
Quoted 341 lines
Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c new file +7
-0+"mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \ +"bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \ +"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \ +"isb\n\t" \ +"dsb\n\t" \ +"ldmfd sp!, {fp, ip}" \ + : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \arch/arm/mach-mb86s7x/mcpm.c line 90
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+ "r9", "r10", "lr", "memory"); \ + } + +static void +mb86s7x_set_wficolor (unsigned clstr,unsigned cpu,unsigned clr) +{ +u8 val; + +if (clr & ~AT_WFI_COLOR_MASK ) +return ;Shouldn't this be a
BUG()rather than a return?Quoted 18 lines
arch/arm/mach-mb86s7x/mcpm.c new file +18
-0+ + val =readb_relaxed (mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); + val &= ~AT_WFI_COLOR_MASK ; + val |= clr; +writeb_relaxed (val, mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); +} + +static int mb86s7x_pm_power_up (unsigned int cpu,unsigned int cluster) +{ +int ret =0 ; + +if (cluster >=S7X_MAX_CLUSTER || cpu >=S7X_MAX_CPU ) +return -EINVAL ; + +pr_debug ("%s: cpu %u cluster %u\n" , __func__, cpu, cluster); +arch/arm/mach-mb86s7x/mcpm.c line 118
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+local_irq_disable (); +arch_spin_lock (&mb86s7x_pm_lock); + + mb86s7x_pm_use_count[cluster][cpu]++; + +if (mb86s7x_pm_use_count[cluster][cpu] ==1 ) { +struct mb86s7x_cpu_gate cmd; + +arch_spin_unlock (&mb86s7x_pm_lock); +local_irq_enable ();From that point onward, nothing prevents concurrent execution in
mb86s7x_pm_suspend()racing to callmb86s7x_set_wficolor()resulting in an incoherent state depending on who wins the race.Quoted 104 lines
arch/arm/mach-mb86s7x/mcpm.c new file +104
-0+ cmd.payload_size =sizeof (cmd); + cmd.cluster_class =0 ; + cmd.cluster_id = cluster; + cmd.cpu_id = cpu; + cmd.cpu_state =SCB_CPU_STATE_ON ; + +pr_debug ("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n" , + __func__, __LINE__, cmd.cluster_class, + cmd.cluster_id, cmd.cpu_id, cmd.cpu_state); + +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_NOTHING ); + ret =mb86s7x_send_packet (CMD_CPU_CLOCK_GATE_SET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) { +pr_err ("%s:%d failed!\n" , __func__, __LINE__); +return ret; + } + +pr_debug ("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n" , + __func__, __LINE__, cmd.cluster_class, + cmd.cluster_id, cmd.cpu_id, cmd.cpu_state); + +if (cmd.cpu_state !=SCB_CPU_STATE_ON ) +return -ENODEV ; + }else if (mb86s7x_pm_use_count[cluster][cpu] !=2 ) { +/* +* The only possible values are: +* 0 = CPU down +* 1 = CPU (still) up +* 2 = CPU requested to be up before it had a chance +* to actually make itself down. +* Any other value is a bug. +*/ +BUG (); + } + +return 0 ; +} + +static void mb86s7x_pm_suspend (u64 ignored) +{ +unsigned int mpidr, cpu, cluster; +bool last_man = false, skip_wfi = false; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +pr_debug ("%s: cpu %u cluster %u\n" , __func__, cpu, cluster); +__mcpm_cpu_going_down (cpu, cluster); + +arch_spin_lock (&mb86s7x_pm_lock); +BUG_ON (__mcpm_cluster_state (cluster) !=CLUSTER_UP ); + + mb86s7x_pm_use_count[cluster][cpu]--; + +if (mb86s7x_pm_use_count[cluster][cpu] ==0 ) { +if (!mb86s7x_pm_use_count[cluster][0 ] && + !mb86s7x_pm_use_count[cluster][1 ]) + last_man = true; +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_POWEROFF ); + }else if (mb86s7x_pm_use_count[cluster][cpu] ==1 ) { + skip_wfi = true;/* Overtaken by a power up */ + }else { +BUG (); + } + +if (!skip_wfi) +gic_cpu_if_down (); + +if (last_man &&__mcpm_outbound_enter_critical (cpu, cluster)) { +arch_spin_unlock (&mb86s7x_pm_lock); + +if (read_cpuid_part () ==ARM_CPU_PART_CORTEX_A15 ) { +/* +* On the Cortex-A15 we need to disable +* L2 prefetching before flushing the cache. +*/ + asmvolatile ( +"mcr p15, 1, %0, c15, c0, 3\n\t" +"isb\n\t" +"dsb" + : :"r" (0x400 )); + } + +mb86s70evb_exit_coherency_flush (all); + +cci_disable_port_by_cpu (mpidr); + +__mcpm_outbound_leave_critical (cluster,CLUSTER_DOWN ); + }else { +arch_spin_unlock (&mb86s7x_pm_lock); +mb86s70evb_exit_coherency_flush (louis); + } + +__mcpm_cpu_down (cpu, cluster); + +/* Now we are prepared for power-down, do it: */ +if (!skip_wfi) +wfi (); +} + +static void mb86s7x_pm_power_down (void ) +{arch/arm/mach-mb86s7x/mcpm.c line 232
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+mb86s7x_pm_suspend (0 ); +} + +static int mb86s7x_wait_for_powerdown (unsigned int cpu,unsigned int cluster) +{ +struct mb86s7x_cpu_gate cmd; +int i, ret; + +if (cluster >=S7X_MAX_CLUSTER || cpu >=S7X_MAX_CPU ) +return 0 ;This should return an error or
BUG().Quoted 161 lines
arch/arm/mach-mb86s7x/mcpm.c new file +127
-0+ cmd.payload_size =sizeof (cmd); + cmd.cluster_class =0 ; + cmd.cluster_id = cluster; + cmd.cpu_id = cpu; + cmd.cpu_state =SCB_CPU_STATE_ON ; + +for (i =0 ; i <50 ; i++) { + ret =mb86s7x_send_packet (CMD_CPU_CLOCK_GATE_GET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) { +pr_err ("%s:%d failed to get CPU status\n" , + __func__, __LINE__); +return ret; + } + +pr_debug ("%s:%d Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u\n" , + __func__, __LINE__, + cmd.cluster_class, cmd.cluster_id, + cmd.cpu_id, cmd.cpu_state); + +if (cmd.cpu_state ==SCB_CPU_STATE_OFF ) +return 0 ; + +msleep (20 ); + } + +return -ETIMEDOUT ; +} + +static void mb86s7x_pm_powered_up (void ) +{ +unsigned int mpidr, cpu, cluster; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +arch_spin_lock (&mb86s7x_pm_lock); +if (!mb86s7x_pm_use_count[cluster][cpu]) + mb86s7x_pm_use_count[cluster][cpu] =1 ; +arch_spin_unlock (&mb86s7x_pm_lock); +} + +static const struct mcpm_platform_ops mb86s7x_pm_power_ops = { + .power_up = mb86s7x_pm_power_up, + .power_down = mb86s7x_pm_power_down, + .wait_for_powerdown = mb86s7x_wait_for_powerdown, + .suspend = mb86s7x_pm_suspend, + .powered_up = mb86s7x_pm_powered_up, +}; + +/* +* Enable cluster-level coherency, in preparation for turning on the MMU. +*/ +static void __naked mb86s7x_pm_power_up_setup (unsigned int affinity_level) +{ + asmvolatile ("\n" +" cmp r0, #1\n" +" bxne lr\n" +" b cci_enable_port_for_self" ); +} + +static void __init mb86s7x_cache_off (void ) +{ +if (read_cpuid_part () ==ARM_CPU_PART_CORTEX_A15 ) { +/* disable L2 prefetching on the Cortex-A15 */ + asmvolatile ( +"mcr p15, 1, %0, c15, c0, 3\n\t" +"isb\n\t" +"dsb" + : :"r" (0x400 )); + } +mb86s70evb_exit_coherency_flush (all); +} + +struct mb86s7x_scb_version { +u32 payload_size; +u32 version; +u32 config_version; +}; + +extern void mb86s7x_cpu_entry (unsigned long secondary_entry); + +static int __init mb86s7x_mcpm_init (void ) +{ +unsigned int mpidr, cpu, cluster; +struct mb86s7x_scb_version cmd; +int ret; + +if (!cci_probed ()) +return -ENODEV ; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +pr_info ("Booting on cpu_%u cluster_%u\n" , cpu, cluster); + mb86s7x_pm_use_count[cluster][cpu] =1 ; + +/* reset the wfi 'color' for primary cpu */ +mb86s7x_set_wficolor (cluster, cpu,AT_WFI_DO_NOTHING ); + +/* Do SMC to set entry address for CPUs coming online */ +mb86s7x_cpu_entry (virt_to_phys (mcpm_entry_point)); + + cmd.payload_size =sizeof (cmd); + cmd.version =0 ; + cmd.config_version =0 ; + ret =mb86s7x_send_packet (CMD_SCB_CAPABILITY_GET_REQ , + &cmd,sizeof (cmd)); +if (ret <0 ) +pr_err ("%s:%d failed to get SCB version\n" , + __func__, __LINE__); + +pr_info ("MB86S7x MCPM initialized: SCB version 0x%x:0x%x\n" , + cmd.version, cmd.config_version); + + ret =mcpm_platform_register (&mb86s7x_pm_power_ops); +if (!ret) + ret =mcpm_sync_init (mb86s7x_pm_power_up_setup); +if (!ret) + ret =mcpm_loopback (mb86s7x_cache_off);/* turn on the CCI */ +mcpm_smp_set_ops (); + +return ret; +} +early_initcall (mb86s7x_mcpm_init);arch/arm/mach-mb86s7x/smc.S new file +27
-1@@ -0,0 +1,27 @@ +/* + * SMC command interface to set secondary entry point + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited + * Copyright: (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +.arch_extension sec + +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */ +ENTRY(mb86s7x_cpu_entry) + stmfd sp!, {r1-r11, lr} + mov r1, r0 + ldr r0, =1 + mrc p15, 0, r3, c1, c0, 0 + mov r4, r3 + and r3, #0xbfffffff + mcr p15, 0, r3, c1, c0, 0 + smc #0 + mcr p15, 0, r4, c1, c0, 0 + ldmfd sp!, {r1-r11, pc} +ENDPROC(mb86s7x_cpu_entry) --Quoted 3 lines
1.9.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 127 lines · Lorenzo Pieralisi
Quoted 98 lines · Nicolas Pitre
Quoted 96 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Is this a bL system with unified and architected L2s ? I think so, so what's the outercache for ?
Quoted 7 lines
Furthermore, the safety of this macro is ensured by not having any memory writes in the middle of the whole sequence. By calling
mb86s70evb_outer_flush_all()there could be the return address pushed onto the stack before callingouter_flush_all()if some tail call optimization is not applied. And this is without saying whatouter_flush_all()actually does.Quoted 8 lines
Why can't you simply do this instead:
v7_exit_coherency_flush(all); outer_flush_all();Of course you'll have to audit everything in the
outer_flush_all()path to make sure no atomic instructions such as LDREX/STREX are invoked. Those have undefined behavior afterCR_Cis cleared.
Quoted 7 lines
What you are saying is correct but first of all I would like to understand what outercache we are talking about here.
Code snippet above is fragile, as you said, and I'd rather disable the outercache before executing the power down sequence (which implies cache is cleaned/invalidated and quiescent before we clear the C bit) if there is an outercache to be managed.
Good question. That opens the potential for an even simpler fix! ;-)
Nicolas
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 132 lines · Nicolas Pitre
Quoted 130 lines · Lorenzo Pieralisi
Quoted 98 lines · Nicolas Pitre
Quoted 96 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-)create mode 100644
arch/arm/mach-mb86s7x/mcpm.c
create mode 100644arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Is this a bL system with unified and architected L2s ? I think so, so what's the outercache for ?
Quoted 7 lines
Furthermore, the safety of this macro is ensured by not having any memory writes in the middle of the whole sequence. By calling
mb86s70evb_outer_flush_all()there could be the return address pushed onto the stack before callingouter_flush_all()if some tail call optimization is not applied. And this is without saying whatouter_flush_all()actually does.Quoted 8 lines
Why can't you simply do this instead:
v7_exit_coherency_flush(all); outer_flush_all();Of course you'll have to audit everything in the
outer_flush_all()path to make sure no atomic instructions such as LDREX/STREX are invoked. Those have undefined behavior afterCR_Cis cleared.What you are saying is correct but first of all I would like to understand what outercache we are talking about here.
Quoted 7 lines
Quoted 4 lines
Code snippet above is fragile, as you said, and I'd rather disable the outercache before executing the power down sequence (which implies cache is cleaned/invalidated and quiescent before we clear the C bit) if there is an outercache to be managed.
Good question. That opens the potential for an even simpler fix! ;-)
Ah right, sorry my bad somehow I assumed this is system cache at higher level apart from the intra-cluster unified and architected L2 cache. Now checking the DT again I don't see any outer cache controller, so it's better to get that info.
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Lorenzo PieralisiQuoted 108 lines · Lorenzo Pieralisi
Quoted 98 lines · Nicolas Pitre
Quoted 96 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- arch/arm/mach-mb86s7x/Makefile | 2 +- arch/arm/mach-mb86s7x/mcpm.c | 360 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-mb86s7x/smc.S | 27 ++++ 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mb86s7x/mcpm.c create mode 100644 arch/arm/mach-mb86s7x/smc.Sarch/arm/mach-mb86s7x/Makefile +1
-1@@ -1 +1 @@ -obj-$(CONFIG_ARCH_MB86S7X) += board.o +obj-$(CONFIG_ARCH_MB86S7X) += board.o mcpm.o smc.oarch/arm/mach-mb86s7x/mcpm.c new file +68
-0@@ -0,0 +1,360 @@ +/* +* arch/arm/mach-mb86s7x/mcpm.c +* Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited +* Copyright: (C) 2014 Linaro Ltd. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/cpu_pm.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/arm-cci.h> +#include <linux/spinlock.h> +#include <linux/suspend.h> +#include <linux/of_device.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/platform_device.h> + +#include <soc/mb86s7x/scb_mhu.h> + +#include <asm/mcpm.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/suspend.h> +#include <asm/idmap.h> + +#define S7X_MAX_CLUSTER 2 +#define S7X_MAX_CPU 2 + +#define MHU_SHM_OFFSET 0x3800 +#define WFI_COLOR_OFFSET 0x3f00 +#define TRAMPOLINE_OFFSET 0x3c00 +#define RESET_OFFSET (TRAMPOLINE_OFFSET + 0x3fc) + +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER ][S7X_MAX_CPU ]; +extern void __iomem *mb86s7x_shm_base; + +#define AT_WFI_DO_NOTHING 0x0 +#define AT_WFI_DO_SUSPEND 0x1 +#define AT_WFI_DO_POWEROFF 0x2 +#define AT_WFI_COLOR_MASK 0x3 + +struct mb86s7x_cpu_gate { +u32 payload_size; +u32 cluster_class; +u32 cluster_id; +u32 cpu_id; +#define SCB_CPU_STATE_OFF 0x0 +#define SCB_CPU_STATE_ON 0x1 +#define SCB_CPU_STATE_SUSP 0x2 +u32 cpu_state; +}; + +asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +} + +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \Quoted 8 lines
arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 5 lines
arch/arm/mach-mb86s7x/mcpm.c new file +5
-0+ "bic r0, r0, #"__stringify(CR_C)"\n\t" \ +"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ +"isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ +"bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Quoted 3 lines
Is this a bL system with unified and architected L2s ? I think so, so what's the outercache for ?
Yes, the CA15 has 1MB and CA7 256KB L2 cache, that's it. This thing sneaked in via a patch from someone desperate to make Suspend-To-Ram (not yet submitted) work and I failed to spot it. We should remove the mb86s70evb_outer_flush_all()
Thanks,
Jassi
PATCH 3/9 ARM: MB86S7X: Add MCPM support
Quoted 13 lines · Jassi Brar
Quoted 11 lines · Lorenzo Pieralisi
Quoted 10 lines · Nicolas Pitre
Quoted 8 lines · Vincent Yang
The remote firmware(SCB) owns the SMP control. This MCPM driver gets CPU/CLUSTER power up/down done by SCB over mailbox.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>---
[...]
Quoted 18 lines
Quoted 18 lines
Quoted 17 lines
Quoted 4 lines
arch/arm/mach-mb86s7x/mcpm.c new file +4
-0+asmlinkage void mb86s70evb_outer_flush_all(void) +{ +outer_flush_all (); +}arch/arm/mach-mb86s7x/mcpm.c line 73
Quoted 10 lines
arch/arm/mach-mb86s7x/mcpm.c new file +10
-0+ +#define mb86s70evb_exit_coherency_flush (level) { \ + asm volatile( \ + "stmfd sp!, {fp, ip}\n\t" \ + "mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \ + "bic r0, r0, #"__stringify(CR_C)"\n\t" \ + "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ + "isb\n\t" \ + "bl v7_flush_dcache_"__stringify(level)"\n\t" \ + "bl mb86s70evb_outer_flush_all\n\t" \This is wrong. As mentioned already, this unconditionally flushes L2 in all cases which shouldn't be necessary in the "louis" case.
Quoted 7 lines
Quoted 3 lines
Is this a bL system with unified and architected L2s ? I think so, so what's the outercache for ?
Yes, the CA15 has 1MB and CA7 256KB L2 cache, that's it. This thing sneaked in via a patch from someone desperate to make Suspend-To-Ram (not yet submitted) work and I failed to spot it. We should remove the
mb86s70evb_outer_flush_all()
Good, so this platform doesn't have any outer cache at all ? And that shouldn't sneak-in back again for suspend2ram case also. So you can use the generic v7_exit_coherency_flush as is ?
Regards,
Sudeep
PATCH 3/9 ARM: MB86S7X: Add MCPM support
In reply to Nicolas PitreQuoted 12 lines · Nicolas Pitre
arch/arm/mach-mb86s7x/mcpm.c line 90
Quoted 9 lines
arch/arm/mach-mb86s7x/mcpm.c new file +8
-0+ +static void +mb86s7x_set_wficolor (unsigned clstr,unsigned cpu,unsigned clr) +{ +u8 val; + +if (clr & ~AT_WFI_COLOR_MASK ) +return ;Shouldn't this be a
BUG()rather than a return?
There are only 2 callers of this and they use explicit defines AT_WFI_DO_xxx, so the check is actually lame and could be removed.
Quoted 24 lines
Quoted 24 lines
arch/arm/mach-mb86s7x/mcpm.c new file +24
-0+ + val =readb_relaxed (mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); + val &= ~AT_WFI_COLOR_MASK ; + val |= clr; +writeb_relaxed (val, mb86s7x_shm_base + +WFI_COLOR_OFFSET + clstr *2 + cpu); +} + +static int mb86s7x_pm_power_up (unsigned int cpu,unsigned int cluster) +{ +int ret =0 ; + +if (cluster >=S7X_MAX_CLUSTER || cpu >=S7X_MAX_CPU ) +return -EINVAL ; + +pr_debug ("%s: cpu %u cluster %u\n" , __func__, cpu, cluster); + +local_irq_disable (); +arch_spin_lock (&mb86s7x_pm_lock); + + mb86s7x_pm_use_count[cluster][cpu]++; + +if (mb86s7x_pm_use_count[cluster][cpu] ==1 ) {
Quoted 9 lines
arch/arm/mach-mb86s7x/mcpm.c line 118
Quoted 4 lines
arch/arm/mach-mb86s7x/mcpm.c new file +4
-0+struct mb86s7x_cpu_gate cmd; + +arch_spin_unlock (&mb86s7x_pm_lock); +local_irq_enable ();From that point onward, nothing prevents concurrent execution in
mb86s7x_pm_suspend()racing to callmb86s7x_set_wficolor()resulting in an incoherent state depending on who wins the race.
yeah, the set_wficolor() better be before we release the arch_spin_unlock.
Thanks,
Jassi
PATCH 4/9 clk: Add clock driver for mb86s7x
In reply to Vincent Yang The CRG11 clock controller is managed by remote f/w.
This driver simply maps Linux CLK ops onto mailbox api.
--- .../bindings/clock/fujitsu,mb86s70-clk.txt | 34 ++ drivers/clk/Makefile | 1 + drivers/clk/clk-mb86s7x.c | 359 +++++++++++++++++++++ include/dt-bindings/clock/mb86s70-clk.h | 22 ++ 4 files changed, 416 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt create mode 100644 drivers/clk/clk-mb86s7x.c create mode 100644 include/dt-bindings/clock/mb86s70-clk.h
Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt new file +34 -0
@@ -0,0 +1,34 @@ +Fujitsu CRG11 clock driver bindings +----------------------------------- + +Required properties : +- compatible : Shall contain "fujitsu,mb86s70-clk" +- #clock-cells : Shall be 0 +- cntrlr : 0->ALW, 1->DDR3, 2->MAIN, 3->CA15, 4->HDMI, 5->DPHY +- domain : [0, 15] +- port : [0,7] -> Gateable Clock Ports. [8]->UngatedCLK + The UngatedCLK is the source of 8 maskable clock ports + as well as having its own output port which can't be masked. + +The consumer specifies the desired clock pointing to its phandle. + +Example: + + clk_alw_2_1: clk_alw_2_1 { + compatible = "fujitsu,mb86s70-clk"; + #clock-cells = <0>; + cntrlr = <0>; + domain = <2>; + port = <1>; + }; + + mhu: mhu0 at 2b1f0000 { + #mbox-cells = <1>; + compatible = "arm,mbox-mhu"; + reg = <0 0x2B1F0000 0x1000>; + interrupts = <0 36 4>, /* LP Non-Sec */ + <0 35 4>, /* HP Non-Sec */ + <0 37 4>; /* Secure */ + clocks = <&clk_alw_2_1>; + clock-names = "clk"; + };
drivers/clk/Makefile +1 -0
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o +obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
drivers/clk/clk-mb86s7x.c new file +359 -0
359 lines not on this page · raw message
include/dt-bindings/clock/mb86s70-clk.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +* Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED +* Copyright (C) 2014 Linaro Ltd. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +*/ + +#ifndef __DTS_MB86S70_CLK_H +#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8 + +#endif
Signature · 1 line
1.9.0
Arnd Bergmann
maintainerPATCH 4/9 clk: Add clock driver for mb86s7x
include/dt-bindings/clock/mb86s70-clk.h line 20
Quoted 11 lines · On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
include/dt-bindings/clock/mb86s70-clk.h new file +10
-0+#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8
The clock driver doesn't seem to use those macros at all, how does the driver know which clock you are referring to?
Arnd
PATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 16 lines · Arnd Bergmann
include/dt-bindings/clock/mb86s70-clk.h line 20
Quoted 11 lines · On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
include/dt-bindings/clock/mb86s70-clk.h new file +10
-0+#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8The clock driver doesn't seem to use those macros at all, how does the driver know which clock you are referring to?
That was just an attempt to make a bit verbose the controller instance. Instead of specifying controller:=4, it reads better controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver simply fills in controller+domain+port of the given clock into mailbox payload.
Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.
Thanks
Jassi
Arnd Bergmann
maintainerPATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 17 lines · On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
Quoted 16 lines · Arnd Bergmann
include/dt-bindings/clock/mb86s70-clk.h line 20
Quoted 11 lines · On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
include/dt-bindings/clock/mb86s70-clk.h new file +10
-0+#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8The clock driver doesn't seem to use those macros at all, how does the driver know which clock you are referring to?
Quoted 5 lines
That was just an attempt to make a bit verbose the controller instance. Instead of specifying controller:=4, it reads better controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver simply fills in controller+domain+port of the given clock into mailbox payload.
See my other comments on the clock nodes. If these are hardware properties, just leave them as numbers in the DT, the header files are only used to establish an interface between the binding and the driver in case there is no sensible way to express which one you have.
Quoted 2 lines
Only
MB86S70_CRG11_UNGPRTis marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.
Is this the actual port number that is known to be non-maskable? How about adding a property to the clock node to mark the logical controller nonmaskable (in case you go for #clock-cells=2)?
For the #clock-cells=3 case, you should probably just hardcode this in the driver based on the compatible string.
Arnd
PATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 24 lines · Arnd Bergmann
Quoted 17 lines · On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
Quoted 16 lines · Arnd Bergmann
include/dt-bindings/clock/mb86s70-clk.h line 20
Quoted 11 lines · On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
include/dt-bindings/clock/mb86s70-clk.h new file +10
-0+#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8The clock driver doesn't seem to use those macros at all, how does the driver know which clock you are referring to?
Quoted 5 lines
That was just an attempt to make a bit verbose the controller instance. Instead of specifying controller:=4, it reads better controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver simply fills in controller+domain+port of the given clock into mailbox payload.
Quoted 5 lines
See my other comments on the clock nodes. If these are hardware properties, just leave them as numbers in the DT, the header files are only used to establish an interface between the binding and the driver in case there is no sensible way to express which one you have.
OK, I'll hardcode numbers there.
Quoted 5 lines
Quoted 2 lines
Only
MB86S70_CRG11_UNGPRTis marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.Is this the actual port number that is known to be non-maskable?
Yes the clock comes out of the controller and is also the parent of other 8 independently maskable clock ports of the domain.
The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request only appropriate rates at appropriate times so that other devices are not messed up.
Quoted 6 lines
How about adding a property to the clock node to mark the logical controller nonmaskable (in case you go for #clock-cells=2)?
For the #clock-cells=3 case, you should probably just hardcode this in the driver based on the compatible string.
The SoC has 6 controllers, each controller has 16domains and each domain has 8+1 ports. Instead of 864 clocks, we wanted to populate only clocks that some device actually use (some clocks seem unused in this patchset but we have users that will be upstreamed later). The remote f/w can't manage inter-dependencies and expect Linux to send only appropriate requests on port basis, so we populate ports as tiny independent clock controllers with single clock output.
Thanks
Jassi
Arnd Bergmann
maintainerPATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 32 lines · On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
Quoted 24 lines · Arnd Bergmann
Quoted 17 lines · On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
Quoted 16 lines · Arnd Bergmann
include/dt-bindings/clock/mb86s70-clk.h line 20
Quoted 11 lines · On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
include/dt-bindings/clock/mb86s70-clk.h new file +10
-0+#define __DTS_MB86S70_CLK_H + +#define MB86S70_CRG11_ALW 0 +#define MB86S70_CRG11_DDR3 1 +#define MB86S70_CRG11_MAIN 2 +#define MB86S70_CRG11_CA15 3 +#define MB86S70_CRG11_HDMI 4 +#define MB86S70_CRG11_DPHY 5 + +#define MB86S70_CRG11_UNGPRT 8The clock driver doesn't seem to use those macros at all, how does the driver know which clock you are referring to?
Quoted 5 lines
That was just an attempt to make a bit verbose the controller instance. Instead of specifying controller:=4, it reads better controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver simply fills in controller+domain+port of the given clock into mailbox payload.
Quoted 5 lines
See my other comments on the clock nodes. If these are hardware properties, just leave them as numbers in the DT, the header files are only used to establish an interface between the binding and the driver in case there is no sensible way to express which one you have.
OK, I'll hardcode numbers there.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Only
MB86S70_CRG11_UNGPRTis marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.Is this the actual port number that is known to be non-maskable?
Yes the clock comes out of the controller and is also the parent of other 8 independently maskable clock ports of the domain.
I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW a port or a controller?
Quoted 4 lines
The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request only appropriate rates at appropriate times so that other devices are not messed up.
Is there any code to validate that, or does Linux just treat all clocks transparently?
Quoted 6 lines
Quoted 6 lines
How about adding a property to the clock node to mark the logical controller nonmaskable (in case you go for #clock-cells=2)?
For the #clock-cells=3 case, you should probably just hardcode this in the driver based on the compatible string.
Quoted 7 lines
The SoC has 6 controllers, each controller has 16domains and each domain has 8+1 ports. Instead of 864 clocks, we wanted to populate only clocks that some device actually use (some clocks seem unused in this patchset but we have users that will be upstreamed later). The remote f/w can't manage inter-dependencies and expect Linux to send only appropriate requests on port basis, so we populate ports as tiny independent clock controllers with single clock output.
My impression is that it would be best to model each controller of the SoC as a clock controller device node with #clock-cells=<2>, and hardcode the behavior of the special port in the driver.
Arnd
PATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 5 lines · Arnd Bergmann
Quoted 3 lines · On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
Quoted 3 lines
Quoted 2 lines
Only
MB86S70_CRG11_UNGPRTis marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Is this the actual port number that is known to be non-maskable?
Yes the clock comes out of the controller and is also the parent of other 8 independently maskable clock ports of the domain.
I'm getting confused by the terminology here. Is
MB86S70_CRG11_ALWa port or a controller?
Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth parent clock (port) of a domain that can't be masked.
FYKI, there are 6 instances, of some CRG11 clock controller, under control of the remote f/w. The Mailbox protocol between remote f/w and Linux assigned indices [0-5] to these controllers.
Quoted 8 lines
Quoted 4 lines
The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request only appropriate rates at appropriate times so that other devices are not messed up.Is there any code to validate that, or does Linux just treat all clocks transparently?
The remote does not expose the clock topology and only accepts requests on port-basis. The remote f/w is supposed to keep track of which ports are used by Linux and then work out inter-dependencies upon receiving a request from Linux. So for Linux there are N independent 'root' clocks, ops on which may or may not succeed at any given time.
thanks
jassi
Arnd Bergmann
maintainerPATCH 4/9 clk: Add clock driver for mb86s7x
Quoted 11 lines · On Friday 21 November 2014 23:28:38 Jassi Brar wrote:
Quoted 10 lines · Arnd Bergmann
Quoted 7 lines · On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
Quoted 5 lines
Quoted 2 lines
Only
MB86S70_CRG11_UNGPRTis marked to mean one special (non-maskable) port on the controller, which the clock driver does make use of.Is this the actual port number that is known to be non-maskable?
Yes the clock comes out of the controller and is also the parent of other 8 independently maskable clock ports of the domain.
Quoted 8 lines
Quoted 3 lines
I'm getting confused by the terminology here. Is
MB86S70_CRG11_ALWa port or a controller?Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth parent clock (port) of a domain that can't be masked.
FYKI, there are 6 instances, of some CRG11 clock controller, under control of the remote f/w. The Mailbox protocol between remote f/w and Linux assigned indices [0-5] to these controllers.
Ok, not it makes sense, thanks for clearing that up!
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request only appropriate rates at appropriate times so that other devices are not messed up.Is there any code to validate that, or does Linux just treat all clocks transparently?
Quoted 6 lines
The remote does not expose the clock topology and only accepts requests on port-basis. The remote f/w is supposed to keep track of which ports are used by Linux and then work out inter-dependencies upon receiving a request from Linux. So for Linux there are N independent 'root' clocks, ops on which may or may not succeed at any given time.
Ok.
Arnd
PATCH 5/9 gpio: Add Fujitsu MB86S7x GPIO driver
In reply to Vincent YangDriver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
--- .../bindings/gpio/fujitsu,mb86s70-gpio.txt | 18 ++ drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mb86s7x.c | 211 +++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt create mode 100644 drivers/gpio/gpio-mb86s7x.c
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +18 -0
@@ -0,0 +1,18 @@ +Fujitsu MB86S7x GPIO Controller +------------------------------- + +Required properties: +- compatible: Should be "fujitsu,mb86s70-gpio" +- gpio-controller: Marks the device node as a gpio controller. +- #gpio-cells: Should be <2>. The first cell is the pin number and the + second cell is used to specify optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted). + +Examples: + gpio0: gpio at 31000000 { + compatible = "fujitsu,mb86s70-gpio"; + reg = <0 0x31000000 0x10000>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&clk_alw_2_1>; + };
drivers/gpio/Kconfig +6 -0
@@ -181,6 +181,12 @@ config GPIO_F7188X To compile this driver as a module, choose M here: the module will be called f7188x-gpio. +config GPIO_MB86S7X + bool "GPIO support for Fujitsu MB86S7x Platforms" + depends on ARCH_MB86S7X + help + Say yes here to support the GPIO controller in LSI ZEVIO SoCs. + config GPIO_MOXART bool "MOXART GPIO support" depends on ARCH_MOXART
drivers/gpio/Makefile +1 -0
@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o +obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
drivers/gpio/gpio-mb86s7x.c new file +211 -0
211 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH 5/9 gpio: Add Fujitsu MB86S7x GPIO driver
Quoted 21 lines · Vincent Yang
Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../bindings/gpio/fujitsu,mb86s70-gpio.txt | 18 ++ drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mb86s7x.c | 211 +++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt create mode 100644 drivers/gpio/gpio-mb86s7x.cDocumentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +0
-0
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt line 9
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +9
-0@@ -0,0 +1,18 @@ +Fujitsu MB86S7x GPIO Controller +------------------------------- + +Required properties: +- compatible: Should be "fujitsu,mb86s70-gpio" +- gpio-controller: Marks the device node as a gpio controller. +- #gpio-cells: Should be <2>. The first cell is the pin number and the + second cell is used to specify optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted).
According to the example below and the code, "reg" and "clocks" are also required properties.
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt line 17
Quoted 8 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +8
-0+ +Examples: + gpio0: gpio at 31000000 { + compatible = "fujitsu,mb86s70-gpio"; + reg = <0 0x31000000 0x10000>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&clk_alw_2_1>;
Maybe add a "clocks-names" property so the clock can be given a meaningful name?
Quoted 58 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +1
-0+ };drivers/gpio/Kconfig +6
-0@@ -181,6 +181,12 @@ config GPIO_F7188X To compile this driver as a module, choose M here: the module will be called f7188x-gpio. +config GPIO_MB86S7X + bool "GPIO support for Fujitsu MB86S7x Platforms" + depends on ARCH_MB86S7X + help + Say yes here to support the GPIO controller in LSI ZEVIO SoCs. + config GPIO_MOXART bool "MOXART GPIO support" depends on ARCH_MOXARTdrivers/gpio/Makefile +1
-0@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o +obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.odrivers/gpio/gpio-mb86s7x.c new file +22
-0@@ -0,0 +1,211 @@ +/* +* linux/drivers/gpio/gpio-mb86s7x.c +* +* Copyright (C) 2014 Fujitsu Semiconductor Limited +* Copyright (C) 2014 Linaro Ltd. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/io.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/module.h> +#include <linux/err.h>
drivers/gpio/gpio-mb86s7x.c line 32
Quoted 10 lines
drivers/gpio/gpio-mb86s7x.c new file +10
-0+#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/slab.h> + +#define PDR (x) (0x0 + x) +#define DDR (x) (0x10 + x) +#define PFR (x) (0x20 + x)
Everytime these macros are used in the code, they are called in the form PFR(offset / 8 * 4). How about doing this operation in the macros instead of repeating it at every call?
drivers/gpio/gpio-mb86s7x.c line 44
Quoted 12 lines
drivers/gpio/gpio-mb86s7x.c new file +12
-0+ +struct mb86s70_gpio_chip { +spinlock_t lock; +struct clk *clk; +void __iomem *base; +struct gpio_chip gc; +}; + +static int mb86s70_gpio_request (struct gpio_chip *gc,unsigned offset) +{ +struct mb86s70_gpio_chip *gchip =container_of (gc, + struct mb86s70_gpio_chip, gc);
Please have a chip_to_mb86s70() macro to avoid that cumbersome call to container_of in every function. Also I suggest you move the gpio_chip to the top of your mb86s70_gpio_chip structure so the container_of translates to a simple recast without any arithmetic.
drivers/gpio/gpio-mb86s7x.c line 49
Quoted 5 lines
drivers/gpio/gpio-mb86s7x.c new file +5
-0+unsigned long flags; +u32 val; + +spin_lock_irqsave (&gchip->lock, flags); + val =readl (gchip->base +PFR (offset /8 *4 ));
Same, having mb86s70_readl()/mb86s70_writel() functions would prevent you from explicitly doing pointer arithmetic every time you write a register.
drivers/gpio/gpio-mb86s7x.c line 50
Quoted 1 line
drivers/gpio/gpio-mb86s7x.c new file +1
-0+ val &= ~(1 << (offset %8 ));/* as gpio-port */
val &= ~BIT(offset % 8); ? Same everywhere it applies.
Quoted 61 lines
drivers/gpio/gpio-mb86s7x.c new file +61
-0+writel (val, gchip->base +PFR (offset /8 *4 )); +spin_unlock_irqrestore (&gchip->lock, flags); + +return 0 ; +} + +static void mb86s70_gpio_free (struct gpio_chip *gc,unsigned offset) +{ +struct mb86s70_gpio_chip *gchip =container_of (gc, + struct mb86s70_gpio_chip, gc); +unsigned long flags; +u32 val; + +spin_lock_irqsave (&gchip->lock, flags); + val =readl (gchip->base +PFR (offset /8 *4 )); + val |= (1 << (offset %8 ));/* as peri-port */ +writel (val, gchip->base +PFR (offset /8 *4 )); +spin_unlock_irqrestore (&gchip->lock, flags); +} + +static int mb86s70_gpio_direction_input (struct gpio_chip *gc,unsigned offset) +{ +struct mb86s70_gpio_chip *gchip = + container_of(gc, struct mb86s70_gpio_chip, gc); +unsigned long flags; +unsigned char val; + +spin_lock_irqsave (&gchip->lock, flags); + val =readl (gchip->base +DDR (offset /8 *4 )); + val &= ~(1 << (offset %8 )); +writel (val, gchip->base +DDR (offset /8 *4 )); +spin_unlock_irqrestore (&gchip->lock, flags); + +return 0 ; +} + +static int mb86s70_gpio_direction_output (struct gpio_chip *gc, +unsigned offset,int value) +{ +struct mb86s70_gpio_chip *gchip = + container_of(gc, struct mb86s70_gpio_chip, gc); +unsigned long flags; +unsigned char val; + +spin_lock_irqsave (&gchip->lock, flags); + + val =readl (gchip->base +PDR (offset /8 *4 )); +if (value) + val |= (1 << (offset %8 )); +else + val &= ~(1 << (offset %8 )); +writel (val, gchip->base +PDR (offset /8 *4 )); + + val =readl (gchip->base +DDR (offset /8 *4 )); + val |= (1 << (offset %8 )); +writel (val, gchip->base +DDR (offset /8 *4 )); + +spin_unlock_irqrestore (&gchip->lock, flags); + +return 0 ; +}
drivers/gpio/gpio-mb86s7x.c line 121
Quoted 10 lines
drivers/gpio/gpio-mb86s7x.c new file +10
-0+ +static int mb86s70_gpio_get (struct gpio_chip *gc,unsigned offset) +{ +struct mb86s70_gpio_chip *gchip = + container_of(gc, struct mb86s70_gpio_chip, gc); +unsigned char val; + + val =readl (gchip->base +PDR (offset /8 *4 )); + val &= (1 << (offset %8 )); +return val ?1 :0 ;
Shouldn't this function be protected by the spin lock as well?
These minor comments aside, the driver looks nice and simple.
PATCH 5/9 gpio: Add Fujitsu MB86S7x GPIO driver
Quoted 27 lines · Alexandre Courbot
Quoted 25 lines · Vincent Yang
Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>--- .../bindings/gpio/fujitsu,mb86s70-gpio.txt | 18 ++ drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mb86s7x.c | 211 +++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt create mode 100644 drivers/gpio/gpio-mb86s7x.cDocumentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +4
-0@@ -0,0 +1,18 @@ +Fujitsu MB86S7x GPIO Controller +------------------------------- + +Required properties:
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt line 9
Quoted 5 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +5
-0+- compatible: Should be "fujitsu,mb86s70-gpio" +- gpio-controller: Marks the device node as a gpio controller. +- #gpio-cells: Should be <2>. The first cell is the pin number and the + second cell is used to specify optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted).According to the example below and the code, "reg" and "clocks" are also required properties.
OK, will add them as well.
Quoted 11 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt line 17
Quoted 8 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +8
-0+ +Examples: + gpio0: gpio at 31000000 { + compatible = "fujitsu,mb86s70-gpio"; + reg = <0 0x31000000 0x10000>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&clk_alw_2_1>;Maybe add a "clocks-names" property so the clock can be given a meaningful name?
Other mb86s7x drivers don't use that either and we do just fine :)
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
Quoted 4 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +4
-0+ +#define PDR(x) (0x0 + x) +#define DDR(x) (0x10 + x) +#define PFR(x) (0x20 + x)Everytime these macros are used in the code, they are called in the form
PFR(offset / 8 * 4). How about doing this operation in the macros instead of repeating it at every call?
OK
Quoted 9 lines
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +9
-0+ +struct mb86s70_gpio_chip { + spinlock_t lock; + struct clk *clk; + void __iomem *base; + struct gpio_chip gc; +}; + +static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
Quoted 3 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +3
-0+{ + struct mb86s70_gpio_chip *gchip = container_of(gc, + struct mb86s70_gpio_chip, gc);Please have a
chip_to_mb86s70()macro to avoid that cumbersome call tocontainer_ofin every function. Also I suggest you move thegpio_chipto the top of yourmb86s70_gpio_chipstructure so thecontainer_oftranslates to a simple recast without any arithmetic.
OK
Quoted 10 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
Quoted 5 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +5
-0+ unsigned long flags; + u32 val; + + spin_lock_irqsave(&gchip->lock, flags); + val = readl(gchip->base + PFR(offset / 8 * 4));Same, having mb86s70_readl()/mb86s70_writel() functions would prevent you from explicitly doing pointer arithmetic every time you write a register.
This becomes trivial after updating macros.
Quoted 4 lines
Quoted 1 line
+ val &= ~(1 << (offset % 8)); /* as gpio-port */
val &= ~BIT(offset % 8); ? Same everywhere it applies.
OK
Quoted 4 lines
Quoted 4 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +4
-0+ +static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct mb86s70_gpio_chip *gchip =
Quoted 9 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
Quoted 6 lines
Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt new file +6
-0+ container_of(gc, struct mb86s70_gpio_chip, gc); + unsigned char val; + + val = readl(gchip->base + PDR(offset / 8 * 4)); + val &= (1 << (offset % 8)); + return val ? 1 : 0;Shouldn't this function be protected by the spin lock as well?
hmm... then we need to fix most other drivers as well :)
Quoted 1 line
These minor comments aside, the driver looks nice and simple.
Thanks for the review.
-Jassi
PATCH 5/9 gpio: Add Fujitsu MB86S7x GPIO driver
In reply to Vincent YangQuoted 6 lines · Vincent Yang
Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>
This is a very simple MMIO GPIO controller.
Why can this *not* just select GPIO_GENERIC and
use drivers/gpio/gpio-generic.c?
You need a smallish driver making use of the generic MMIO library, see for example drivers/gpio/gpio-74xx-mmio.c
or any other driver selecting GPIO_GENERIC.
Yours,
Linus Walleij
PATCH 5/9 gpio: Add Fujitsu MB86S7x GPIO driver
Quoted 10 lines · Linus Walleij
Quoted 6 lines · Vincent Yang
Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>
Quoted 5 lines
This is a very simple MMIO GPIO controller.
Why can this *not* just select
GPIO_GENERICand
usedrivers/gpio/gpio-generic.c?
The math isn't the simple shift operation that the gpio-generic.c assumes.
-jassi
PATCH 6/9 mmc: sdhci: host: add new f_sdh30
In reply to Vincent YangThis patch adds new host controller driver for
Fujitsu SDHCI controller f_sdh30.
--- .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 +++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +35 -0
@@ -0,0 +1,35 @@ +* Fujitsu SDHCI controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci_f_sdh30 driver. + +Required properties: +- compatible: "fujitsu,mb86s70-sdh30" +- voltage-ranges : This is a list of pairs. In each pair, two cells + are required. First cell specifies minimum slot voltage (mV), second + cell specifies maximum slot voltage (mV). In case of supported voltage + range is discontinuous, several ranges could be specified as a list. + +Optional properties: +- vqmmc-supply: phandle to the regulator device tree node, mentioned + as the VCCQ/VDD_IO supply in the eMMC/SD specs. +- clocks: Must contain an entry for each entry in clock-names. It is a + list of phandles and clock-specifier pairs. + See ../clocks/clock-bindings.txt for details. +- clock-names: Should contain the following two entries: + "iface" - clock used for sdhci interface + "core" - core clock for sdhci controller + +Example: + + sdhci1: sdio at 36600000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + vqmmc-supply = <&vccq_sdhci1>; + clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>; + clock-names = "iface", "core"; + };
drivers/mmc/host/Kconfig +9 -0
@@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835 This selects the BCM2835 SD/MMC controller. If you have a BCM2835 platform with SD or MMC devices, say Y or M here. +config MMC_SDHCI_F_SDH30 + tristate "SDHCI support for Fujitsu Semiconductor F_SDH30" + depends on ARCH_MB86S7X + depends on MMC_SDHCI_PLTFM + depends on OF + help + This selects the Secure Digital Host Controller Interface (SDHCI) + Needed by some Fujitsu SoC for MMC / SD / SDIO support. + If you have a controller with this interface, say Y or M here. If unsure, say N. config MMC_MOXART
drivers/mmc/host/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o +obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
drivers/mmc/host/sdhci_f_sdh30.c new file +319 -0
319 lines not on this page · raw message
Signature · 1 line
1.9.0
PATCH 6/9 mmc: sdhci: host: add new f_sdh30
Quoted 21 lines · Vincent Yang
This patch adds new host controller driver for
Fujitsu SDHCI controllerf_sdh30.Signed-off-by Andy Green <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Takinishi <[email protected]>--- .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 +++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 drivers/mmc/host/sdhci_f_sdh30.cDocumentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +0
-0
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt line 7
Quoted 7 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +7
-0@@ -0,0 +1,35 @@ +* Fujitsu SDHCI controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci_f_sdh30 driver. + +Required properties: +- compatible: "fujitsu,mb86s70-sdh30"
It would be nice to have sdhci in the name to indicate it is an SDHCI controller.
Quoted 388 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +28
-0+- voltage-ranges : This is a list of pairs. In each pair, two cells + are required. First cell specifies minimum slot voltage (mV), second + cell specifies maximum slot voltage (mV). In case of supported voltage + range is discontinuous, several ranges could be specified as a list. + +Optional properties: +- vqmmc-supply: phandle to the regulator device tree node, mentioned + as the VCCQ/VDD_IO supply in the eMMC/SD specs. +- clocks: Must contain an entry for each entry in clock-names. It is a + list of phandles and clock-specifier pairs. + See ../clocks/clock-bindings.txt for details. +- clock-names: Should contain the following two entries: + "iface" - clock used for sdhci interface + "core" - core clock for sdhci controller + +Example: + + sdhci1: sdio at 36600000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + vqmmc-supply = <&vccq_sdhci1>; + clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>; + clock-names = "iface", "core"; + };drivers/mmc/host/Kconfig +9
-0@@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835 This selects the BCM2835 SD/MMC controller. If you have a BCM2835 platform with SD or MMC devices, say Y or M here. +config MMC_SDHCI_F_SDH30 + tristate "SDHCI support for Fujitsu Semiconductor F_SDH30" + depends on ARCH_MB86S7X + depends on MMC_SDHCI_PLTFM + depends on OF + help + This selects the Secure Digital Host Controller Interface (SDHCI) + Needed by some Fujitsu SoC for MMC / SD / SDIO support. + If you have a controller with this interface, say Y or M here. If unsure, say N. config MMC_MOXARTdrivers/mmc/host/Makefile +1
-0@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o +obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.odrivers/mmc/host/sdhci_f_sdh30.c new file +319
-1@@ -0,0 +1,319 @@ +/* +* linux/drivers/mmc/host/sdhci_f_sdh30.c +* +* Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd +* Vincent Yang <[email protected]> +* Copyright (C) 2014 Linaro Ltd Andy Green <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +*/ + +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/mmc/sd.h> +#include <linux/mmc/host.h> +#include <linux/mmc/card.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/suspend.h> + +#include "sdhci.h" +#include "sdhci-pltfm.h" + +/* F_SDH30 extended Controller registers */ +#define F_SDH30_AHB_CONFIG 0x100 +#define F_SDH30_AHB_BIGED 0x00000040 +#define F_SDH30_BUSLOCK_DMA 0x00000020 +#define F_SDH30_BUSLOCK_EN 0x00000010 +#define F_SDH30_SIN 0x00000008 +#define F_SDH30_AHB_INCR_16 0x00000004 +#define F_SDH30_AHB_INCR_8 0x00000002 +#define F_SDH30_AHB_INCR_4 0x00000001 + +#define F_SDH30_TUNING_SETTING 0x108 +#define F_SDH30_CMD_CHK_DIS 0x00010000 + +#define F_SDH30_IO_CONTROL2 0x114 +#define F_SDH30_CRES_O_DN 0x00080000 +#define F_SDH30_MSEL_O_1_8 0x00040000 + +#define F_SDH30_ESD_CONTROL 0x124 +#define F_SDH30_EMMC_RST 0x00000002 +#define F_SDH30_EMMC_HS200 0x01000000 + +#define F_SDH30_CMD_DAT_DELAY 0x200 + +#define F_SDH30_MIN_CLOCK 400000 + +struct f_sdhost_priv { +struct clk *clk_iface; +struct clk *clk; +u32 vendor_hs200; +struct device *dev; +}; + +void sdhci_f_sdh30_soft_voltage_switch (struct sdhci_host *host) +{ +struct f_sdhost_priv *priv =sdhci_priv (host); +u32 ctrl =0 ; + +usleep_range (2500 ,3000 ); + ctrl =sdhci_readl (host,F_SDH30_IO_CONTROL2 ); + ctrl |=F_SDH30_CRES_O_DN ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); + ctrl |=F_SDH30_MSEL_O_1_8 ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); + + ctrl &= ~F_SDH30_CRES_O_DN ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); +usleep_range (2500 ,3000 ); + +if (priv->vendor_hs200) { +dev_info (priv->dev,"%s: setting hs200\n" , __func__); + ctrl =sdhci_readl (host,F_SDH30_ESD_CONTROL ); + ctrl |= priv->vendor_hs200; +sdhci_writel (host, ctrl,F_SDH30_ESD_CONTROL ); + } + + ctrl =sdhci_readl (host,F_SDH30_TUNING_SETTING ); + ctrl |=F_SDH30_CMD_CHK_DIS ; +sdhci_writel (host, ctrl,F_SDH30_TUNING_SETTING ); +} + +unsigned int sdhci_f_sdh30_get_min_clock (struct sdhci_host *host) +{ +return F_SDH30_MIN_CLOCK ; +} + +void sdhci_f_sdh30_reset (struct sdhci_host *host,u8 mask) +{ +if (sdhci_readw (host,SDHCI_CLOCK_CONTROL ) ==0 ) +sdhci_writew (host,0xBC01 ,SDHCI_CLOCK_CONTROL ); + +sdhci_reset (host, mask); +} + +static const struct sdhci_ops sdhci_f_sdh30_ops = { + .voltage_switch = sdhci_f_sdh30_soft_voltage_switch, + .get_min_clock = sdhci_f_sdh30_get_min_clock, + .reset = sdhci_f_sdh30_reset, + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .set_uhs_signaling = sdhci_set_uhs_signaling, +}; + +static int sdhci_f_sdh30_probe (struct platform_device *pdev) +{ +struct sdhci_host *host; +struct device *dev = &pdev->dev; +int irq, ctrl =0 , ret =0 ; +struct f_sdhost_priv *priv; +u32 reg =0 ; + + irq =platform_get_irq (pdev,0 ); +if (irq <0 ) { +dev_err (dev,"%s: no irq specified\n" , __func__); + ret = irq; + goto err; + } + + host =sdhci_alloc_host (dev,sizeof (struct sdhci_host ) + +sizeof (struct f_sdhost_priv )); +if (IS_ERR (host)) { +dev_err (dev,"%s: host allocate error\n" , __func__); + ret = -ENOMEM ; + goto err; + } + priv =sdhci_priv (host); + priv->dev = dev; + + host->quirks =SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | +SDHCI_QUIRK_INVERTED_WRITE_PROTECT ; + host->quirks2 =SDHCI_QUIRK2_SUPPORT_SINGLE | +SDHCI_QUIRK2_TUNING_WORK_AROUND ; + + ret =mmc_of_parse (host->mmc); +if (ret) + goto err_of_parse; + + ret =mmc_of_parse_voltage (pdev->dev.of_node, &host->ocr_mask); +if (ret) + goto err_of_parse; + +platform_set_drvdata (pdev, host); + +sdhci_get_of_property (pdev); + host->hw_name ="f_sdh30" ; + host->ops = &sdhci_f_sdh30_ops; + host->irq = irq; + + host->ioaddr =of_iomap (pdev->dev.of_node,0 ); +if (!host->ioaddr) { +dev_err (dev,"%s: failed to remap registers\n" , __func__); + ret = -ENXIO ; + goto err_remap; + } + + priv->clk_iface =clk_get (&pdev->dev,"iface" ); +if (!IS_ERR (priv->clk_iface)) { + ret =clk_prepare_enable (priv->clk_iface); +if (ret <0 ) { +dev_err (dev,"Failed to enable iface clock: %d\n" , ret); + goto err_clk1; + } + } + priv->clk =clk_get (&pdev->dev,"core" ); +if (!IS_ERR (priv->clk)) { + ret =clk_prepare_enable (priv->clk); +if (ret <0 ) { +dev_err (dev,"Failed to enable core clock: %d\n" , ret); + goto err_clk2; + } + } + +#ifdef CONFIG_PM_RUNTIME +pm_runtime_set_active (&pdev->dev); +pm_runtime_enable (&pdev->dev); + ret =pm_runtime_get_sync (&pdev->dev); +if (ret <0 ) +dev_err (dev,"Failed to pm_runtime_get_sync: %d\n" , ret); +#endif + + ret =sdhci_add_host (host); +if (ret) { +dev_err (dev,"%s: host add error\n" , __func__); + goto err_add_host; + } + +/* init vendor specific regs */ + ctrl =sdhci_readw (host,F_SDH30_AHB_CONFIG ); + ctrl |=F_SDH30_SIN |F_SDH30_AHB_INCR_16 |F_SDH30_AHB_INCR_8 | +F_SDH30_AHB_INCR_4 ; + ctrl &= ~(F_SDH30_AHB_BIGED |F_SDH30_BUSLOCK_EN ); +sdhci_writew (host, ctrl,F_SDH30_AHB_CONFIG ); + + reg =sdhci_readl (host,F_SDH30_ESD_CONTROL ); +sdhci_writel (host, reg & ~F_SDH30_EMMC_RST ,F_SDH30_ESD_CONTROL ); +msleep (20 ); +sdhci_writel (host, reg |F_SDH30_EMMC_RST ,F_SDH30_ESD_CONTROL ); + + reg =sdhci_readl (host,SDHCI_CAPABILITIES ); +if (reg &SDHCI_CAN_DO_8BIT ) + priv->vendor_hs200 =F_SDH30_EMMC_HS200 ; +else + priv->vendor_hs200 =0 ; + +return 0 ; + +err_add_host: +clk_put (priv->clk); +err_clk2: +clk_put (priv->clk_iface); +err_clk1: +iounmap (host->ioaddr); +err_remap: +err_of_parse: +sdhci_free_host (host); +err: +return ret; +} + +static int sdhci_f_sdh30_remove (struct platform_device *pdev) +{ +struct sdhci_host *host =platform_get_drvdata (pdev); +struct f_sdhost_priv *priv =sdhci_priv (host); +struct resource *iomem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + +sdhci_remove_host (host,readl (host->ioaddr +SDHCI_INT_STATUS ) == +0xffffffff ); +iounmap (host->ioaddr); +release_mem_region (iomem->start,resource_size (iomem)); + +clk_disable_unprepare (priv->clk_iface); +clk_disable_unprepare (priv->clk); + +clk_put (priv->clk); +clk_put (priv->clk_iface); + +sdhci_free_host (host); +platform_set_drvdata (pdev,NULL ); + +return 0 ; +} + +#ifdef CONFIG_PM_SLEEP +static int sdhci_f_sdh30_suspend (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_suspend_host (host); +} + +static int sdhci_f_sdh30_resume (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_resume_host (host); +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int sdhci_f_sdh30_runtime_suspend (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_runtime_suspend_host (host); +} + +static int sdhci_f_sdh30_runtime_resume (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_runtime_resume_host (host); +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops sdhci_f_sdh30_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume) +SET_RUNTIME_PM_OPS (sdhci_f_sdh30_runtime_suspend, + sdhci_f_sdh30_runtime_resume,NULL ) +}; + +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops) + +#else +#define SDHCI_F_SDH30_PMOPS NULL +#endif + +static const struct of_device_id f_sdh30_dt_ids[] = { + { .compatible ="fujitsu,mb86s70-sdh30" }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (of, f_sdh30_dt_ids); + +static struct platform_driver sdhci_f_sdh30_driver = { + .driver = { + .name ="f_sdh30" , + .of_match_table = f_sdh30_dt_ids, +#ifdef CONFIG_PM_SLEEP + .pm =SDHCI_F_SDH30_PMOPS , +#endif + }, + .probe = sdhci_f_sdh30_probe, + .remove = sdhci_f_sdh30_remove, +}; + +module_platform_driver (sdhci_f_sdh30_driver); + +MODULE_DESCRIPTION ("F_SDH30 SD Card Controller driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_AUTHOR ("FUJITSU SEMICONDUCTOR LTD." ); +MODULE_ALIAS ("platform:f_sdh30" ); --1.9.0
PATCH 6/9 mmc: sdhci: host: add new f_sdh30
2014-11-20 23:22 GMT+08:00 Rob Herring <[email protected]>:
Quoted 17 lines
Quoted 15 lines · Vincent Yang
This patch adds new host controller driver for
Fujitsu SDHCI controllerf_sdh30.Signed-off-by Andy Green <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Takinishi <[email protected]>--- .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 +++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
Quoted 16 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt line 7
Quoted 13 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +7
-0@@ -0,0 +1,35 @@ +* Fujitsu SDHCI controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci_f_sdh30 driver. + +Required properties: +- compatible: "fujitsu,mb86s70-sdh30"It would be nice to have sdhci in the name to indicate it is an SDHCI controller.
Yes, we will update it to "fujitsu,sdhci-f-sdh30"
Thanks for your review!
- Vincent Yang
Quoted 389 lines
Quoted 389 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +28
-0+- voltage-ranges : This is a list of pairs. In each pair, two cells + are required. First cell specifies minimum slot voltage (mV), second + cell specifies maximum slot voltage (mV). In case of supported voltage + range is discontinuous, several ranges could be specified as a list. + +Optional properties: +- vqmmc-supply: phandle to the regulator device tree node, mentioned + as the VCCQ/VDD_IO supply in the eMMC/SD specs. +- clocks: Must contain an entry for each entry in clock-names. It is a + list of phandles and clock-specifier pairs. + See ../clocks/clock-bindings.txt for details. +- clock-names: Should contain the following two entries: + "iface" - clock used for sdhci interface + "core" - core clock for sdhci controller + +Example: + + sdhci1: sdio at 36600000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + vqmmc-supply = <&vccq_sdhci1>; + clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>; + clock-names = "iface", "core"; + };drivers/mmc/host/Kconfig +9
-0@@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835 This selects the BCM2835 SD/MMC controller. If you have a BCM2835 platform with SD or MMC devices, say Y or M here. +config MMC_SDHCI_F_SDH30 + tristate "SDHCI support for Fujitsu Semiconductor F_SDH30" + depends on ARCH_MB86S7X + depends on MMC_SDHCI_PLTFM + depends on OF + help + This selects the Secure Digital Host Controller Interface (SDHCI) + Needed by some Fujitsu SoC for MMC / SD / SDIO support. + If you have a controller with this interface, say Y or M here. If unsure, say N. config MMC_MOXARTdrivers/mmc/host/Makefile +1
-0@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o +obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.odrivers/mmc/host/sdhci_f_sdh30.c new file +319
-1@@ -0,0 +1,319 @@ +/* +* linux/drivers/mmc/host/sdhci_f_sdh30.c +* +* Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd +* Vincent Yang <[email protected]> +* Copyright (C) 2014 Linaro Ltd Andy Green <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +*/ + +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/mmc/sd.h> +#include <linux/mmc/host.h> +#include <linux/mmc/card.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/suspend.h> + +#include "sdhci.h" +#include "sdhci-pltfm.h" + +/* F_SDH30 extended Controller registers */ +#define F_SDH30_AHB_CONFIG 0x100 +#define F_SDH30_AHB_BIGED 0x00000040 +#define F_SDH30_BUSLOCK_DMA 0x00000020 +#define F_SDH30_BUSLOCK_EN 0x00000010 +#define F_SDH30_SIN 0x00000008 +#define F_SDH30_AHB_INCR_16 0x00000004 +#define F_SDH30_AHB_INCR_8 0x00000002 +#define F_SDH30_AHB_INCR_4 0x00000001 + +#define F_SDH30_TUNING_SETTING 0x108 +#define F_SDH30_CMD_CHK_DIS 0x00010000 + +#define F_SDH30_IO_CONTROL2 0x114 +#define F_SDH30_CRES_O_DN 0x00080000 +#define F_SDH30_MSEL_O_1_8 0x00040000 + +#define F_SDH30_ESD_CONTROL 0x124 +#define F_SDH30_EMMC_RST 0x00000002 +#define F_SDH30_EMMC_HS200 0x01000000 + +#define F_SDH30_CMD_DAT_DELAY 0x200 + +#define F_SDH30_MIN_CLOCK 400000 + +struct f_sdhost_priv { +struct clk *clk_iface; +struct clk *clk; +u32 vendor_hs200; +struct device *dev; +}; + +void sdhci_f_sdh30_soft_voltage_switch (struct sdhci_host *host) +{ +struct f_sdhost_priv *priv =sdhci_priv (host); +u32 ctrl =0 ; + +usleep_range (2500 ,3000 ); + ctrl =sdhci_readl (host,F_SDH30_IO_CONTROL2 ); + ctrl |=F_SDH30_CRES_O_DN ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); + ctrl |=F_SDH30_MSEL_O_1_8 ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); + + ctrl &= ~F_SDH30_CRES_O_DN ; +sdhci_writel (host, ctrl,F_SDH30_IO_CONTROL2 ); +usleep_range (2500 ,3000 ); + +if (priv->vendor_hs200) { +dev_info (priv->dev,"%s: setting hs200\n" , __func__); + ctrl =sdhci_readl (host,F_SDH30_ESD_CONTROL ); + ctrl |= priv->vendor_hs200; +sdhci_writel (host, ctrl,F_SDH30_ESD_CONTROL ); + } + + ctrl =sdhci_readl (host,F_SDH30_TUNING_SETTING ); + ctrl |=F_SDH30_CMD_CHK_DIS ; +sdhci_writel (host, ctrl,F_SDH30_TUNING_SETTING ); +} + +unsigned int sdhci_f_sdh30_get_min_clock (struct sdhci_host *host) +{ +return F_SDH30_MIN_CLOCK ; +} + +void sdhci_f_sdh30_reset (struct sdhci_host *host,u8 mask) +{ +if (sdhci_readw (host,SDHCI_CLOCK_CONTROL ) ==0 ) +sdhci_writew (host,0xBC01 ,SDHCI_CLOCK_CONTROL ); + +sdhci_reset (host, mask); +} + +static const struct sdhci_ops sdhci_f_sdh30_ops = { + .voltage_switch = sdhci_f_sdh30_soft_voltage_switch, + .get_min_clock = sdhci_f_sdh30_get_min_clock, + .reset = sdhci_f_sdh30_reset, + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .set_uhs_signaling = sdhci_set_uhs_signaling, +}; + +static int sdhci_f_sdh30_probe (struct platform_device *pdev) +{ +struct sdhci_host *host; +struct device *dev = &pdev->dev; +int irq, ctrl =0 , ret =0 ; +struct f_sdhost_priv *priv; +u32 reg =0 ; + + irq =platform_get_irq (pdev,0 ); +if (irq <0 ) { +dev_err (dev,"%s: no irq specified\n" , __func__); + ret = irq; + goto err; + } + + host =sdhci_alloc_host (dev,sizeof (struct sdhci_host ) + +sizeof (struct f_sdhost_priv )); +if (IS_ERR (host)) { +dev_err (dev,"%s: host allocate error\n" , __func__); + ret = -ENOMEM ; + goto err; + } + priv =sdhci_priv (host); + priv->dev = dev; + + host->quirks =SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | +SDHCI_QUIRK_INVERTED_WRITE_PROTECT ; + host->quirks2 =SDHCI_QUIRK2_SUPPORT_SINGLE | +SDHCI_QUIRK2_TUNING_WORK_AROUND ; + + ret =mmc_of_parse (host->mmc); +if (ret) + goto err_of_parse; + + ret =mmc_of_parse_voltage (pdev->dev.of_node, &host->ocr_mask); +if (ret) + goto err_of_parse; + +platform_set_drvdata (pdev, host); + +sdhci_get_of_property (pdev); + host->hw_name ="f_sdh30" ; + host->ops = &sdhci_f_sdh30_ops; + host->irq = irq; + + host->ioaddr =of_iomap (pdev->dev.of_node,0 ); +if (!host->ioaddr) { +dev_err (dev,"%s: failed to remap registers\n" , __func__); + ret = -ENXIO ; + goto err_remap; + } + + priv->clk_iface =clk_get (&pdev->dev,"iface" ); +if (!IS_ERR (priv->clk_iface)) { + ret =clk_prepare_enable (priv->clk_iface); +if (ret <0 ) { +dev_err (dev,"Failed to enable iface clock: %d\n" , ret); + goto err_clk1; + } + } + priv->clk =clk_get (&pdev->dev,"core" ); +if (!IS_ERR (priv->clk)) { + ret =clk_prepare_enable (priv->clk); +if (ret <0 ) { +dev_err (dev,"Failed to enable core clock: %d\n" , ret); + goto err_clk2; + } + } + +#ifdef CONFIG_PM_RUNTIME +pm_runtime_set_active (&pdev->dev); +pm_runtime_enable (&pdev->dev); + ret =pm_runtime_get_sync (&pdev->dev); +if (ret <0 ) +dev_err (dev,"Failed to pm_runtime_get_sync: %d\n" , ret); +#endif + + ret =sdhci_add_host (host); +if (ret) { +dev_err (dev,"%s: host add error\n" , __func__); + goto err_add_host; + } + +/* init vendor specific regs */ + ctrl =sdhci_readw (host,F_SDH30_AHB_CONFIG ); + ctrl |=F_SDH30_SIN |F_SDH30_AHB_INCR_16 |F_SDH30_AHB_INCR_8 | +F_SDH30_AHB_INCR_4 ; + ctrl &= ~(F_SDH30_AHB_BIGED |F_SDH30_BUSLOCK_EN ); +sdhci_writew (host, ctrl,F_SDH30_AHB_CONFIG ); + + reg =sdhci_readl (host,F_SDH30_ESD_CONTROL ); +sdhci_writel (host, reg & ~F_SDH30_EMMC_RST ,F_SDH30_ESD_CONTROL ); +msleep (20 ); +sdhci_writel (host, reg |F_SDH30_EMMC_RST ,F_SDH30_ESD_CONTROL ); + + reg =sdhci_readl (host,SDHCI_CAPABILITIES ); +if (reg &SDHCI_CAN_DO_8BIT ) + priv->vendor_hs200 =F_SDH30_EMMC_HS200 ; +else + priv->vendor_hs200 =0 ; + +return 0 ; + +err_add_host: +clk_put (priv->clk); +err_clk2: +clk_put (priv->clk_iface); +err_clk1: +iounmap (host->ioaddr); +err_remap: +err_of_parse: +sdhci_free_host (host); +err: +return ret; +} + +static int sdhci_f_sdh30_remove (struct platform_device *pdev) +{ +struct sdhci_host *host =platform_get_drvdata (pdev); +struct f_sdhost_priv *priv =sdhci_priv (host); +struct resource *iomem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + +sdhci_remove_host (host,readl (host->ioaddr +SDHCI_INT_STATUS ) == +0xffffffff ); +iounmap (host->ioaddr); +release_mem_region (iomem->start,resource_size (iomem)); + +clk_disable_unprepare (priv->clk_iface); +clk_disable_unprepare (priv->clk); + +clk_put (priv->clk); +clk_put (priv->clk_iface); + +sdhci_free_host (host); +platform_set_drvdata (pdev,NULL ); + +return 0 ; +} + +#ifdef CONFIG_PM_SLEEP +static int sdhci_f_sdh30_suspend (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_suspend_host (host); +} + +static int sdhci_f_sdh30_resume (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_resume_host (host); +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int sdhci_f_sdh30_runtime_suspend (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_runtime_suspend_host (host); +} + +static int sdhci_f_sdh30_runtime_resume (struct device *dev) +{ +struct sdhci_host *host =dev_get_drvdata (dev); + +return sdhci_runtime_resume_host (host); +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops sdhci_f_sdh30_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume) +SET_RUNTIME_PM_OPS (sdhci_f_sdh30_runtime_suspend, + sdhci_f_sdh30_runtime_resume,NULL ) +}; + +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops) + +#else +#define SDHCI_F_SDH30_PMOPS NULL +#endif + +static const struct of_device_id f_sdh30_dt_ids[] = { + { .compatible ="fujitsu,mb86s70-sdh30" }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (of, f_sdh30_dt_ids); + +static struct platform_driver sdhci_f_sdh30_driver = { + .driver = { + .name ="f_sdh30" , + .of_match_table = f_sdh30_dt_ids, +#ifdef CONFIG_PM_SLEEP + .pm =SDHCI_F_SDH30_PMOPS , +#endif + }, + .probe = sdhci_f_sdh30_probe, + .remove = sdhci_f_sdh30_remove, +}; + +module_platform_driver (sdhci_f_sdh30_driver); + +MODULE_DESCRIPTION ("F_SDH30 SD Card Controller driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_AUTHOR ("FUJITSU SEMICONDUCTOR LTD." ); +MODULE_ALIAS ("platform:f_sdh30" ); --1.9.0
PATCH 6/9 mmc: sdhci: host: add new f_sdh30
Quoted 35 lines · Vincent Yang
2014-11-20 23:22 GMT+08:00 Rob Herring <[email protected]>:
Quoted 17 lines
Quoted 15 lines · Vincent Yang
This patch adds new host controller driver for
Fujitsu SDHCI controllerf_sdh30.Signed-off-by Andy Green <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Takinishi <[email protected]>--- .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 +++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 drivers/mmc/host/sdhci_f_sdh30.cQuoted 16 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt line 7
Quoted 13 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +7
-0@@ -0,0 +1,35 @@ +* Fujitsu SDHCI controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci_f_sdh30 driver. + +Required properties: +- compatible: "fujitsu,mb86s70-sdh30"It would be nice to have sdhci in the name to indicate it is an SDHCI controller.
Quoted 2 lines
Yes, we will update it to "fujitsu,sdhci-f-sdh30"
Thanks for your review!
Not really what I had in mind as you are then dropping the chip name. Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP version? If the former, I think I'd drop it as IIRC that is available in a register.
Rob
PATCH 6/9 mmc: sdhci: host: add new f_sdh30
2014-11-21 2:18 GMT+08:00 Rob Herring <[email protected]>:
Quoted 37 lines
Quoted 35 lines · Vincent Yang
2014-11-20 23:22 GMT+08:00 Rob Herring <[email protected]>:
Quoted 33 lines
Quoted 21 lines · Vincent Yang
This patch adds new host controller driver for
Fujitsu SDHCI controllerf_sdh30.Signed-off-by Andy Green <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Takinishi <[email protected]>--- .../devicetree/bindings/mmc/sdhci-fujitsu.txt | 35 +++ drivers/mmc/host/Kconfig | 9 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci_f_sdh30.c | 319 +++++++++++++++++++++ 4 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt create mode 100644 drivers/mmc/host/sdhci_f_sdh30.cDocumentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +0
-0Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt line 7
Quoted 7 lines
Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file +7
-0@@ -0,0 +1,35 @@ +* Fujitsu SDHCI controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci_f_sdh30 driver. + +Required properties: +- compatible: "fujitsu,mb86s70-sdh30"It would be nice to have sdhci in the name to indicate it is an SDHCI controller.
Quoted 7 lines
Quoted 2 lines
Yes, we will update it to "fujitsu,sdhci-f-sdh30"
Thanks for your review!Not really what I had in mind as you are then dropping the chip name. Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP version? If the former, I think I'd drop it as IIRC that is available in a register.
We will update it to "fujitsu,mb86s70-sdhci-3.0" as you suggest because 3.0 is IP version
Thanks for your review!
Vincent
Quoted 2 lines
Rob
PATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
In reply to Vincent YangAdd dt files for MB86S7x evb.
--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/mb86s70.dtsi | 91 ++++++ arch/arm/boot/dts/mb86s70eb.dts | 52 ++++ arch/arm/boot/dts/mb86s73.dtsi | 49 ++++ arch/arm/boot/dts/mb86s73eb.dts | 39 +++ arch/arm/boot/dts/mb86s7x.dtsi | 595 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 827 insertions(+) create mode 100644 arch/arm/boot/dts/mb86s70.dtsi create mode 100644 arch/arm/boot/dts/mb86s70eb.dts create mode 100644 arch/arm/boot/dts/mb86s73.dtsi create mode 100644 arch/arm/boot/dts/mb86s73eb.dts create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi
arch/arm/boot/dts/Makefile +1 -0
@@ -163,6 +163,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \ kirkwood-ts419-6282.dtb dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb +dtb-$(CONFIG_ARCH_MB86S7X) += mb86s70eb.dtb mb86s73eb.dtb dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb dtb-$(CONFIG_ARCH_MXC) += \
arch/arm/boot/dts/mb86s70.dtsi new file +91 -0
91 lines not on this page · raw message
arch/arm/boot/dts/mb86s70eb.dts new file +52 -0
52 lines not on this page · raw message
arch/arm/boot/dts/mb86s73.dtsi new file +49 -0
49 lines not on this page · raw message
arch/arm/boot/dts/mb86s73eb.dts new file +39 -0
@@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + */ + +/dts-v1/; + +#include "mb86s73.dtsi" + +/ { + model = "Fujitsu MB86S73 EVB"; + compatible = "fujitsu,mb86s73-evb"; + + memory { + device_type = "memory"; + reg = <0 0x80000000 0x80000000>; + }; + + chosen { + bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw"; + linux,initrd-start = <0xc0000000>; + linux,initrd-end = <0xc0800000>; + }; + + sdhci1: sdio at 36600000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + clocks = <&clk_main_c_0>, <&clk_main_d_0>; + clock-names = "iface", "core"; + }; +};
arch/arm/boot/dts/mb86s7x.dtsi new file +595 -0
595 lines not on this page · raw message
Signature · 1 line
1.9.0
Arnd Bergmann
maintainerPATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
Quoted 24 lines · On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
arch/arm/boot/dts/mb86s70eb.dts new file +18
-0@@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + */ + +/dts-v1/; + +#include "mb86s70.dtsi" + +/ { + model = "Fujitsu MB86S70 EVB"; + compatible = "fujitsu,mb86s70-evb"; + + memory {
arch/arm/boot/dts/mb86s70eb.dts line 28
Quoted 10 lines
arch/arm/boot/dts/mb86s70eb.dts new file +10
-0+ device_type = "memory"; + reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>; + + }; + + chosen { + bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw"; + linux,initrd-start = <0xc0000000>; + linux,initrd-end = <0xc0800000>; + };
The initrd parameters seem misplaced here, they should be set by the boot loader. The loglevel=8 seems to be for debugging only, better remove that.
arch/arm/boot/dts/mb86s70eb.dts line 39
Quoted 10 lines
arch/arm/boot/dts/mb86s70eb.dts new file +10
-0+ vccq_sdhci1: regulator at 0 { + compatible = "regulator-gpio"; + regulator-name = "SDHCI1 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio0 7 0>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + };
This looks whitespace damaged, have you used checkpatch.pl to check your patch before submitting?
arch/arm/boot/dts/mb86s70eb.dts line 39
Quoted 1 line
arch/arm/boot/dts/mb86s70eb.dts new file +1
-0+ sdhci1: sdio at 36600000 {
I think the node name should be 'mmc'
arch/arm/boot/dts/mb86s70eb.dts line 52
Quoted 11 lines
arch/arm/boot/dts/mb86s70eb.dts new file +11
-0+ compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + clocks = <&clk_main_c_0>, <&clk_main_d_0>; + clock-names = "iface", "core"; + vqmmc-supply = <&vccq_sdhci1>; + }; +};
Better move the actual node into the main dtsi file for the chip that contains it, and add a 'status="disabled" property, then just do this here:
&sdhci1 {
status = "ok";
};It probably makes sense to also leave the bus-width and voltage-ranges properties in the per-board file if they are specific to the attached device rather than the controller.
arch/arm/boot/dts/mb86s73eb.dts
Quoted 5 lines
arch/arm/boot/dts/mb86s73eb.dts new file +0
-0
Some comments for this file.
Quoted 18 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +12
-0@@ -0,0 +1,595 @@ +/* + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + */ + +#include "skeleton.dtsi" +#include <dt-bindings/clock/mb86s70-clk.h> +
arch/arm/boot/dts/mb86s7x.dtsi line 22
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <1>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + };
Please move the aliases into the per-board file as well, some other boards might not support all the uarts and should only list the ones that have a connector.
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ /** + * The UngatedCLK is the source of 8 maskable clock ports + * as well as having its own output port which can't be masked. + */ + clocks { + clk_alw_0_0: clk_alw_0_0 { + compatible = "fujitsu,mb86s70-clk"; + #clock-cells = <0>; + cntrlr = <MB86S70_CRG11_ALW>; + domain = <0>;
arch/arm/boot/dts/mb86s7x.dtsi line 49
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ port = <0>; + }; + + clk_alw_0_1: clk_alw_0_1 { + compatible = "fujitsu,mb86s70-clk"; + #clock-cells = <0>; + cntrlr = <MB86S70_CRG11_ALW>; + domain = <0>; + port = <1>; + };
This seems weird: rather than have one clock controller node per clock source, why not just have one node with #clock-cells = <3>?
Your controller seems perfectly capable of this, and you even put the numbers in the label. It would be much more straightforward to do
clocks = <&clk_alw 0 1>;
than
clocks = <&clk_alw_0_1>;
here. Possibly even
clocks = <&clk MB86S70_CRG11_ALW 0 1>;
with #clock-cells = <3>
Quoted 8 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +8
-0+ + timer0: timer at 31080000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0 0x31080000 0x1000>; + interrupts = <0 324 4>, + <0 325 4>; + clocks = <&clk_alw_6_8>; + clock-names = "apb_pclk";
arch/arm/boot/dts/mb86s7x.dtsi line 508
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ }; + + timer1: archtimer { + compatible = "arm,armv7-timer"; + clock-frequency = <125000000>; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + };
Inconsistent node names: please call the archtimer node 'timer' as well, like the other one.
The label is free-form though, so you can just use 'archtimer:' ther if you need to reference it.
arch/arm/boot/dts/mb86s7x.dtsi line 595
Quoted 11 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +11
-0+ sdhci0: emmc at 300c0000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x300c0000 0x1000>; + interrupts = <0 164 0x4>, + <0 165 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <8>; + clocks = <&clk_alw_c_0>, <&clk_alw_b_0>; + clock-names = "iface", "core"; + }; +};
Maybe also leave this as disabled in the base dtsi file and move the status="ok" property and the bus width into the per-board file.
Also change the node name to mmc.
Arnd
PATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
Quoted 31 lines · Arnd Bergmann
Quoted 30 lines · On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
arch/arm/boot/dts/mb86s70eb.dts new file +24
-0@@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + */ + +/dts-v1/; + +#include "mb86s70.dtsi" + +/ { + model = "Fujitsu MB86S70 EVB"; + compatible = "fujitsu,mb86s70-evb"; + + memory { + device_type = "memory"; + reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>; + + }; + + chosen {
Quoted 9 lines
arch/arm/boot/dts/mb86s70eb.dts line 28
Quoted 4 lines
arch/arm/boot/dts/mb86s70eb.dts new file +4
-0+ bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw"; + linux,initrd-start = <0xc0000000>; + linux,initrd-end = <0xc0800000>; + };The initrd parameters seem misplaced here, they should be set by the boot loader. The loglevel=8 seems to be for debugging only, better remove that.
IIRC our custom made bootloader had some issues so we needed the initrd params here. I'll check internally. And will fix the loglevel.
Quoted 11 lines
arch/arm/boot/dts/mb86s70eb.dts line 39
Quoted 10 lines
arch/arm/boot/dts/mb86s70eb.dts new file +10
-0+ vccq_sdhci1: regulator at 0 { + compatible = "regulator-gpio"; + regulator-name = "SDHCI1 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio0 7 0>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + };
Quoted 3 lines
This looks whitespace damaged, have you used checkpatch.pl to check your patch before submitting?
Sorry the sdhci and its supply node were added just before the patchset was sent out. We did run checkpatch on patches though.
Quoted 20 lines
arch/arm/boot/dts/mb86s70eb.dts line 39
Quoted 1 line
arch/arm/boot/dts/mb86s70eb.dts new file +1
-0+ sdhci1: sdio at 36600000 {I think the node name should be 'mmc'
arch/arm/boot/dts/mb86s70eb.dts line 52
Quoted 11 lines
arch/arm/boot/dts/mb86s70eb.dts new file +11
-0+ compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x36600000 0x1000>; + interrupts = <0 172 0x4>, + <0 173 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <4>; + clocks = <&clk_main_c_0>, <&clk_main_d_0>; + clock-names = "iface", "core"; + vqmmc-supply = <&vccq_sdhci1>; + }; +};Better move the actual node into the main dtsi file for the chip that contains it, and add a 'status="disabled" property, then just do this here:
Quoted 8 lines
&sdhci1 { status = "ok"; };It probably makes sense to also leave the bus-width and voltage-ranges properties in the per-board file if they are specific to the attached device rather than the controller.
Yes, I think the vqmmc-supply also needs to be moved in the dts.
Quoted 72 lines
arch/arm/boot/dts/mb86s73eb.dts
Quoted 5 lines
arch/arm/boot/dts/mb86s73eb.dts new file +0
-0Some comments for this file.
Quoted 18 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +12
-0@@ -0,0 +1,595 @@ +/* + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + */ + +#include "skeleton.dtsi" +#include <dt-bindings/clock/mb86s70-clk.h> +arch/arm/boot/dts/mb86s7x.dtsi line 22
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <1>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + };Please move the aliases into the per-board file as well, some other boards might not support all the uarts and should only list the ones that have a connector.
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ /** + * The UngatedCLK is the source of 8 maskable clock ports + * as well as having its own output port which can't be masked. + */ + clocks { + clk_alw_0_0: clk_alw_0_0 { + compatible = "fujitsu,mb86s70-clk"; + #clock-cells = <0>; + cntrlr = <MB86S70_CRG11_ALW>; + domain = <0>;arch/arm/boot/dts/mb86s7x.dtsi line 49
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ port = <0>; + }; + + clk_alw_0_1: clk_alw_0_1 { + compatible = "fujitsu,mb86s70-clk"; + #clock-cells = <0>; + cntrlr = <MB86S70_CRG11_ALW>; + domain = <0>; + port = <1>; + };This seems weird: rather than have one clock controller node per clock source, why not just have one node with #clock-cells = <3>?
Your controller seems perfectly capable of this, and you even put the numbers in the label. It would be much more straightforward to do
clocks = <&clk_alw 0 1>;than
Quoted 8 lines
clocks = <&clk_alw_0_1>;here. Possibly even
clocks = <&clk MB86S70_CRG11_ALW 0 1>;with #clock-cells = <3>
Is there a way to compact the dtsi and yet populate only clocks that are actually ever used (instead of 6x16x9)?
Quoted 37 lines
Quoted 8 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +8
-0+ + timer0: timer at 31080000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0 0x31080000 0x1000>; + interrupts = <0 324 4>, + <0 325 4>; + clocks = <&clk_alw_6_8>; + clock-names = "apb_pclk";arch/arm/boot/dts/mb86s7x.dtsi line 508
Quoted 10 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +10
-0+ }; + + timer1: archtimer { + compatible = "arm,armv7-timer"; + clock-frequency = <125000000>; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + };Inconsistent node names: please call the archtimer node 'timer' as well, like the other one.
The label is free-form though, so you can just use 'archtimer:' ther if you need to reference it.
arch/arm/boot/dts/mb86s7x.dtsi line 595
Quoted 11 lines
arch/arm/boot/dts/mb86s7x.dtsi new file +11
-0+ sdhci0: emmc at 300c0000 { + compatible = "fujitsu,mb86s70-sdh30"; + reg = <0 0x300c0000 0x1000>; + interrupts = <0 164 0x4>, + <0 165 0x4>; + voltage-ranges = <1800 1800>, <3300 3300>; + bus-width = <8>; + clocks = <&clk_alw_c_0>, <&clk_alw_b_0>; + clock-names = "iface", "core"; + }; +};
Quoted 5 lines
Maybe also leave this as disabled in the base dtsi file and move the status="ok" property and the bus width into the per-board file.
Also change the node name to mmc.
Will address all comments.
Thanks.
Jassi
Arnd Bergmann
maintainerPATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
Quoted 14 lines · On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
Quoted 14 lines
This seems weird: rather than have one clock controller node per clock source, why not just have one node with #clock-cells = >?
Your controller seems perfectly capable of this, and you even put the numbers in the label. It would be much more straightforward to do
clocks = <&clk_alw 0 1>;than
clocks = <&clk_alw_0_1>;
Quoted 8 lines
Quoted 6 lines
here. Possibly even
clocks = <&clk MB86S70_CRG11_ALW 0 1>;with #clock-cells = >
Is there a way to compact the dtsi and yet populate only clocks that are actually ever used (instead of 6x16x9)?
I believe the clock driver just wouldn't create the clocks until a device driver requests them.
Arnd
PATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
Quoted 19 lines · Arnd Bergmann
Quoted 18 lines · On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
Quoted 18 lines
This seems weird: rather than have one clock controller node per clock source, why not just have one node with #clock-cells = >?
Your controller seems perfectly capable of this, and you even put the numbers in the label. It would be much more straightforward to do
clocks = <&clk_alw 0 1>;than
clocks = <&clk_alw_0_1>;here. Possibly even
clocks = <&clk MB86S70_CRG11_ALW 0 1>;
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
with #clock-cells = >
Is there a way to compact the dtsi and yet populate only clocks that are actually ever used (instead of 6x16x9)?
I believe the clock driver just wouldn't create the clocks until a device driver requests them.
Seems like the chicken-egg problem. Let me check.
Thanks
Jassi
Arnd Bergmann
maintainerPATCH 7/9 dt: mb86s7x: add dt files for MB86S7x evbs
Quoted 22 lines · On Friday 21 November 2014 23:05:28 Jassi Brar wrote:
Quoted 21 lines · Arnd Bergmann
Quoted 20 lines · On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
Quoted 20 lines
This seems weird: rather than have one clock controller node per clock source, why not just have one node with #clock-cells = >?
Your controller seems perfectly capable of this, and you even put the numbers in the label. It would be much more straightforward to do
clocks = <&clk_alw 0 1>;than
clocks = <&clk_alw_0_1>;here. Possibly even
clocks = <&clk MB86S70_CRG11_ALW 0 1>;with #clock-cells = >
Quoted 7 lines
Quoted 6 lines
Quoted 2 lines
Is there a way to compact the dtsi and yet populate only clocks that are actually ever used (instead of 6x16x9)?
I believe the clock driver just wouldn't create the clocks until a device driver requests them.
Seems like the chicken-egg problem. Let me check.
What I mean is that you should call of_clk_add_provider once for each of the six clock controllers, but not call clk_register_gate or clk_register for each possible output until it gets requested.
Arnd
PATCH 8/9 of: add Fujitsu vendor prefix
In reply to Vincent YangAdd 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
--- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
@@ -56,6 +56,7 @@ everest Everest Semiconductor Co. Ltd. excito Excito fcs Fairchild Semiconductor fsl Freescale Semiconductor +fujitsu Fujitsu Semiconductor Ltd. GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc.
Signature · 1 line
1.9.0
PATCH 8/9 of: add Fujitsu vendor prefix
Quoted 6 lines · Vincent Yang
Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
Signed-off-by Andy Green <[email protected]>Signed-off-by Jassi Brar <[email protected]>Signed-off-by Vincent Yang <[email protected]>Signed-off-by Tetsuya Nuriya <[email protected]>
Quoted 19 lines
--- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+)Documentation/devicetree/bindings/vendor-prefixes.txt +1
-1@@ -56,6 +56,7 @@ everest Everest Semiconductor Co. Ltd. excito Excito fcs Fairchild Semiconductor fsl Freescale Semiconductor +fujitsu Fujitsu Semiconductor Ltd. GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. --1.9.0
PATCH 9/9 ARM: MB86S7x: Add configs
In reply to Vincent YangFujitsu's ARCH_MB86S7X is multi_v7 compatible, so add options to multi_v7_defconfig. Also add a new defconfig for MB86S7X for those who want the kernel built specifically for ARCH_MB86S7X.
--- arch/arm/configs/fujitsu_defconfig | 232 ++++++++++++++++++++++++++++++++++++ arch/arm/configs/multi_v7_defconfig | 5 + 2 files changed, 237 insertions(+) create mode 100644 arch/arm/configs/fujitsu_defconfig
arch/arm/configs/fujitsu_defconfig new file +232 -0
@@ -0,0 +1,232 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="MB86S7x" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NAMESPACES=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +CONFIG_PROFILING=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_ARCH_MB86S7X=y +CONFIG_ARM_LPAE=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_754327=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_ARM_ERRATA_798181=y +CONFIG_PCI=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT=y +CONFIG_THUMB2_KERNEL=y +CONFIG_HIGHMEM=y +CONFIG_CMA=y +CONFIG_CMA_AREAS=8 +# CONFIG_ATAGS is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=2048M console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw" +CONFIG_KEXEC=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPUFREQ_DT=m +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_RUNTIME=y +CONFIG_PM_DEBUG=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=192 +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_ROM=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_PLATRAM=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=1024 +CONFIG_BLK_DEV_SD=m +CONFIG_ATA=m +# CONFIG_ATA_VERBOSE_ERROR is not set +# CONFIG_SATA_PMP is not set +CONFIG_SATA_AHCI_PLATFORM=m +# CONFIG_ATA_SFF is not set +CONFIG_NETDEVICES=y +CONFIG_TUN=m +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=800 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +CONFIG_INPUT_EVDEV=m +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_MOUSE_GPIO=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_EGALAX=m +CONFIG_TOUCHSCREEN_ILI210X=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_SPI=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_MB86S7X=y +CONFIG_GPIO_MCP23S08=m +# CONFIG_HWMON is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_GPIO=y +# CONFIG_VGA_ARB is not set +CONFIG_DRM=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_SOC=m +CONFIG_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=m +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=m +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_HCD_PLATFORM=m +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_PCI is not set +CONFIG_USB_OHCI_HCD_PLATFORM=m +CONFIG_USB_ACM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_DWC3=m +CONFIG_USB_DWC3_HOST=y +CONFIG_USB_DWC3_DEBUG=y +CONFIG_USB_GADGET=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_MULTI=m +CONFIG_MMC=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_F_SDH30=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_DMADEVICES=y +CONFIG_STAGING=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_LOGGER=m +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ION=y +CONFIG_ARM_MHU=y +CONFIG_ARM_SMMU=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_VFAT_FS=m +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=m +CONFIG_CRAMFS=y +CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BOTH=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_ISO8859_1=m +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_RCU_CPU_STALL_VERBOSE is not set +# CONFIG_FTRACE is not set +CONFIG_DEBUG_USER=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +CONFIG_FONTS=y +CONFIG_FONT_SUN8x16=y
arch/arm/configs/multi_v7_defconfig +5 -0
@@ -45,6 +45,7 @@ CONFIG_SOC_AM43XX=y CONFIG_SOC_DRA7XX=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MB86S7X=y CONFIG_ARCH_MSM8X60=y CONFIG_ARCH_MSM8960=y CONFIG_ARCH_MSM8974=y
@@ -247,6 +248,7 @@ CONFIG_GPIO_TWL4030=y CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y +CONFIG_GPIO_MB86S7X=y CONFIG_BATTERY_SBS=y CONFIG_CHARGER_TPS65090=y CONFIG_POWER_RESET_AS3722=y
@@ -348,6 +350,7 @@ CONFIG_MMC_SDHCI_SPEAR=y CONFIG_MMC_SDHCI_S3C=y CONFIG_MMC_SDHCI_S3C_DMA=y CONFIG_MMC_SDHCI_BCM_KONA=y +CONFIG_MMC_SDHCI_F_SDH30=y CONFIG_MMC_SDHCI_ST=y CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y
@@ -429,6 +432,8 @@ CONFIG_OMAP_USB2=y CONFIG_TI_PIPE3=y CONFIG_PHY_MIPHY365X=y CONFIG_PHY_SUN4I_USB=y +CONFIG_MAILBOX=y +CONFIG_ARM_MHU=y CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y
Signature · 1 line
1.9.0