diff options
Diffstat (limited to 'configs/platform-rpi/patches')
15 files changed, 1557 insertions, 0 deletions
diff --git a/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch b/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch new file mode 100644 index 0000000..ac782ab --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch @@ -0,0 +1,66 @@ +From: Eric Anholt <eric@anholt.net> +Date: Wed, 16 Dec 2015 12:25:00 -0800 +Subject: [PATCH] irq: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ + timers + +The irqchip's register area includes the the setup for the timer's +scaling factors, and for the platform we want a fixed configuration of +these registers. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + drivers/irqchip/irq-bcm2836.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c +index f68708281fcf..6ec125ef3607 100644 +--- a/drivers/irqchip/irq-bcm2836.c ++++ b/drivers/irqchip/irq-bcm2836.c +@@ -21,6 +21,9 @@ + #include <linux/irqdomain.h> + #include <asm/exception.h> + ++#define LOCAL_CONTROL 0x000 ++#define LOCAL_PRESCALER 0x008 ++ + /* + * The low 2 bits identify the CPU that the GPU IRQ goes to, and the + * next 2 bits identify the CPU that the GPU FIQ goes to. +@@ -237,6 +240,27 @@ bcm2836_arm_irqchip_smp_init(void) + #endif + } + ++/* ++ * The LOCAL_IRQ_CNT* timer firings are based off of the external ++ * oscillator with some scaling. The firmware sets up CNTFRQ to ++ * report 19.2Mhz, but doesn't set up the scaling registers. ++ */ ++static void bcm2835_init_local_timer_frequency(void) ++{ ++ /* ++ * Set the timer to source from the 19.2Mhz crystal clock (bit ++ * 8 unset), and only increment by 1 instead of 2 (bit 9 ++ * unset). ++ */ ++ writel(0, intc.base + LOCAL_CONTROL); ++ ++ /* ++ * Set the timer prescaler to 1:1 (timer freq = input freq * ++ * 2**31 / prescaler) ++ */ ++ writel(0x80000000, intc.base + LOCAL_PRESCALER); ++} ++ + static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, + struct device_node *parent) + { +@@ -246,6 +270,8 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, + node->full_name); + } + ++ bcm2835_init_local_timer_frequency(); ++ + intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, + &bcm2836_arm_irqchip_intc_ops, + NULL); diff --git a/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch b/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch new file mode 100644 index 0000000..2e25c68 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch @@ -0,0 +1,75 @@ +From: Andrea Merello <andrea.merello@gmail.com> +Date: Sun, 3 May 2015 01:03:11 +0200 +Subject: [PATCH] irq: bcm2836: Add SMP support for the 2836 + +The firmware sets the secondaries spinning waiting for a non-NULL +value to show up in the last IPI mailbox. + +The original SMP port from the downstream tree was done by Andrea, and +Eric cleaned it up/rewrote it a few times from there. + +Signed-off-by: Andrea Merello <andrea.merello@gmail.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + drivers/irqchip/irq-bcm2836.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c +index 6ec125ef3607..c5ef4dfb5bb0 100644 +--- a/drivers/irqchip/irq-bcm2836.c ++++ b/drivers/irqchip/irq-bcm2836.c +@@ -53,14 +53,16 @@ + /* Same status bits as above, but for FIQ. */ + #define LOCAL_FIQ_PENDING0 0x070 + /* +- * Mailbox0 write-to-set bits. There are 16 mailboxes, 4 per CPU, and ++ * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and + * these bits are organized by mailbox number and then CPU number. We + * use mailbox 0 for IPIs. The mailbox's interrupt is raised while + * any bit is set. + */ + #define LOCAL_MAILBOX0_SET0 0x080 +-/* Mailbox0 write-to-clear bits. */ ++#define LOCAL_MAILBOX3_SET0 0x08c ++/* Mailbox write-to-clear bits. */ + #define LOCAL_MAILBOX0_CLR0 0x0c0 ++#define LOCAL_MAILBOX3_CLR0 0x0cc + + #define LOCAL_IRQ_CNTPSIRQ 0 + #define LOCAL_IRQ_CNTPNSIRQ 1 +@@ -226,6 +228,26 @@ static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { + .xlate = irq_domain_xlate_onecell + }; + ++#ifdef CONFIG_SMP ++int __init bcm2836_smp_boot_secondary(unsigned int cpu, ++ struct task_struct *idle) ++{ ++ unsigned long secondary_startup_phys = ++ (unsigned long)virt_to_phys((void *)secondary_startup); ++ ++ dsb(); ++ writel(secondary_startup_phys, ++ intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); ++ ++ return 0; ++} ++ ++static const struct smp_operations bcm2836_smp_ops __initconst = { ++ .smp_boot_secondary = bcm2836_smp_boot_secondary, ++}; ++ ++#endif ++ + static void + bcm2836_arm_irqchip_smp_init(void) + { +@@ -237,6 +259,7 @@ bcm2836_arm_irqchip_smp_init(void) + register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier); + + set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); ++ smp_set_ops(&bcm2836_smp_ops); + #endif + } + diff --git a/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch b/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch new file mode 100644 index 0000000..062781e --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch @@ -0,0 +1,25 @@ +From: Eric Anholt <eric@anholt.net> +Date: Tue, 21 Apr 2015 09:42:21 -0700 +Subject: [PATCH] dt-bindings: Add root properties for Raspberry Pi 2 + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +index c78576bb7729..11d3056dc2bd 100644 +--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt ++++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +@@ -26,6 +26,10 @@ Raspberry Pi Model B+ + Required root node properties: + compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; + ++Raspberry Pi 2 Model B ++Required root node properties: ++compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; ++ + Raspberry Pi Compute Module + Required root node properties: + compatible = "raspberrypi,compute-module", "brcm,bcm2835"; diff --git a/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch b/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch new file mode 100644 index 0000000..1d01eb3 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch @@ -0,0 +1,444 @@ +From: Eric Anholt <eric@anholt.net> +Date: Wed, 16 Dec 2015 13:24:40 -0800 +Subject: [PATCH] ARM: bcm2835: Split the DT for peripherals from the DT for + the CPU + +The set of peripherals remained constant across bcm2835 (Raspberry Pi +1) and bcm2836 (Raspberry Pi 2), but the CPU was swapped out. Split +the files so that we can include just peripheral setup in 2836. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/boot/dts/bcm2835.dtsi | 194 +------------------------------------- + arch/arm/boot/dts/bcm283x.dtsi | 209 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 210 insertions(+), 193 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm283x.dtsi + +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index aef64de77495..b83b32639358 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -1,206 +1,14 @@ +-#include <dt-bindings/pinctrl/bcm2835.h> +-#include <dt-bindings/clock/bcm2835.h> +-#include "skeleton.dtsi" ++#include "bcm283x.dtsi" + + / { + compatible = "brcm,bcm2835"; +- model = "BCM2835"; +- interrupt-parent = <&intc>; +- +- chosen { +- bootargs = "earlyprintk console=ttyAMA0"; +- }; + + soc { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <1>; + ranges = <0x7e000000 0x20000000 0x02000000>; + dma-ranges = <0x40000000 0x00000000 0x20000000>; + +- timer@7e003000 { +- compatible = "brcm,bcm2835-system-timer"; +- reg = <0x7e003000 0x1000>; +- interrupts = <1 0>, <1 1>, <1 2>, <1 3>; +- /* This could be a reference to BCM2835_CLOCK_TIMER, +- * but we don't have the driver using the common clock +- * support yet. +- */ +- clock-frequency = <1000000>; +- }; +- +- dma: dma@7e007000 { +- compatible = "brcm,bcm2835-dma"; +- reg = <0x7e007000 0xf00>; +- interrupts = <1 16>, +- <1 17>, +- <1 18>, +- <1 19>, +- <1 20>, +- <1 21>, +- <1 22>, +- <1 23>, +- <1 24>, +- <1 25>, +- <1 26>, +- <1 27>, +- <1 28>; +- +- #dma-cells = <1>; +- brcm,dma-channel-mask = <0x7f35>; +- }; +- +- intc: interrupt-controller@7e00b200 { +- compatible = "brcm,bcm2835-armctrl-ic"; +- reg = <0x7e00b200 0x200>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- watchdog@7e100000 { +- compatible = "brcm,bcm2835-pm-wdt"; +- reg = <0x7e100000 0x28>; +- }; +- +- clocks: cprman@7e101000 { +- compatible = "brcm,bcm2835-cprman"; +- #clock-cells = <1>; +- reg = <0x7e101000 0x2000>; +- +- /* CPRMAN derives everything from the platform's +- * oscillator. +- */ +- clocks = <&clk_osc>; +- }; +- +- rng@7e104000 { +- compatible = "brcm,bcm2835-rng"; +- reg = <0x7e104000 0x10>; +- }; +- +- mailbox: mailbox@7e00b800 { +- compatible = "brcm,bcm2835-mbox"; +- reg = <0x7e00b880 0x40>; +- interrupts = <0 1>; +- #mbox-cells = <0>; +- }; +- +- gpio: gpio@7e200000 { +- compatible = "brcm,bcm2835-gpio"; +- reg = <0x7e200000 0xb4>; +- /* +- * The GPIO IP block is designed for 3 banks of GPIOs. +- * Each bank has a GPIO interrupt for itself. +- * There is an overall "any bank" interrupt. +- * In order, these are GIC interrupts 17, 18, 19, 20. +- * Since the BCM2835 only has 2 banks, the 2nd bank +- * interrupt output appears to be mirrored onto the +- * 3rd bank's interrupt signal. +- * So, a bank0 interrupt shows up on 17, 20, and +- * a bank1 interrupt shows up on 18, 19, 20! +- */ +- interrupts = <2 17>, <2 18>, <2 19>, <2 20>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- +- uart0: uart@7e201000 { +- compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; +- reg = <0x7e201000 0x1000>; +- interrupts = <2 25>; +- clocks = <&clocks BCM2835_CLOCK_UART>, +- <&clocks BCM2835_CLOCK_VPU>; +- clock-names = "uartclk", "apb_pclk"; +- arm,primecell-periphid = <0x00241011>; +- }; +- +- i2s: i2s@7e203000 { +- compatible = "brcm,bcm2835-i2s"; +- reg = <0x7e203000 0x20>, +- <0x7e101098 0x02>; +- +- dmas = <&dma 2>, +- <&dma 3>; +- dma-names = "tx", "rx"; +- status = "disabled"; +- }; +- +- spi: spi@7e204000 { +- compatible = "brcm,bcm2835-spi"; +- reg = <0x7e204000 0x1000>; +- interrupts = <2 22>; +- clocks = <&clocks BCM2835_CLOCK_VPU>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c0: i2c@7e205000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e205000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clocks BCM2835_CLOCK_VPU>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- sdhci: sdhci@7e300000 { +- compatible = "brcm,bcm2835-sdhci"; +- reg = <0x7e300000 0x100>; +- interrupts = <2 30>; +- clocks = <&clocks BCM2835_CLOCK_EMMC>; +- status = "disabled"; +- }; +- +- i2c1: i2c@7e804000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e804000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clocks BCM2835_CLOCK_VPU>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c2: i2c@7e805000 { +- compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e805000 0x1000>; +- interrupts = <2 21>; +- clocks = <&clocks BCM2835_CLOCK_VPU>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- usb@7e980000 { +- compatible = "brcm,bcm2835-usb"; +- reg = <0x7e980000 0x10000>; +- interrupts = <1 9>; +- }; +- + arm-pmu { + compatible = "arm,arm1176-pmu"; + }; + }; +- +- clocks { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- /* The oscillator is the root of the clock tree. */ +- clk_osc: clock@3 { +- compatible = "fixed-clock"; +- reg = <3>; +- #clock-cells = <0>; +- clock-output-names = "osc"; +- clock-frequency = <19200000>; +- }; +- +- }; + }; +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +new file mode 100644 +index 000000000000..bf74e8afbe88 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -0,0 +1,209 @@ ++#include <dt-bindings/pinctrl/bcm2835.h> ++#include <dt-bindings/clock/bcm2835.h> ++#include "skeleton.dtsi" ++ ++/* This include file covers the common peripherals and configuration between ++ * bcm2835 and bcm2836 implementations, leaving the CPU configuration to ++ * bcm2835.dtsi and bcm2836.dtsi. ++ */ ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ model = "BCM2835"; ++ interrupt-parent = <&intc>; ++ ++ chosen { ++ bootargs = "earlyprintk console=ttyAMA0"; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ timer@7e003000 { ++ compatible = "brcm,bcm2835-system-timer"; ++ reg = <0x7e003000 0x1000>; ++ interrupts = <1 0>, <1 1>, <1 2>, <1 3>; ++ /* This could be a reference to BCM2835_CLOCK_TIMER, ++ * but we don't have the driver using the common clock ++ * support yet. ++ */ ++ clock-frequency = <1000000>; ++ }; ++ ++ dma: dma@7e007000 { ++ compatible = "brcm,bcm2835-dma"; ++ reg = <0x7e007000 0xf00>; ++ interrupts = <1 16>, ++ <1 17>, ++ <1 18>, ++ <1 19>, ++ <1 20>, ++ <1 21>, ++ <1 22>, ++ <1 23>, ++ <1 24>, ++ <1 25>, ++ <1 26>, ++ <1 27>, ++ <1 28>; ++ ++ #dma-cells = <1>; ++ brcm,dma-channel-mask = <0x7f35>; ++ }; ++ ++ intc: interrupt-controller@7e00b200 { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++ reg = <0x7e00b200 0x200>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ watchdog@7e100000 { ++ compatible = "brcm,bcm2835-pm-wdt"; ++ reg = <0x7e100000 0x28>; ++ }; ++ ++ clocks: cprman@7e101000 { ++ compatible = "brcm,bcm2835-cprman"; ++ #clock-cells = <1>; ++ reg = <0x7e101000 0x2000>; ++ ++ /* CPRMAN derives everything from the platform's ++ * oscillator. ++ */ ++ clocks = <&clk_osc>; ++ }; ++ ++ rng@7e104000 { ++ compatible = "brcm,bcm2835-rng"; ++ reg = <0x7e104000 0x10>; ++ }; ++ ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2835-mbox"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ #mbox-cells = <0>; ++ }; ++ ++ gpio: gpio@7e200000 { ++ compatible = "brcm,bcm2835-gpio"; ++ reg = <0x7e200000 0xb4>; ++ /* ++ * The GPIO IP block is designed for 3 banks of GPIOs. ++ * Each bank has a GPIO interrupt for itself. ++ * There is an overall "any bank" interrupt. ++ * In order, these are GIC interrupts 17, 18, 19, 20. ++ * Since the BCM2835 only has 2 banks, the 2nd bank ++ * interrupt output appears to be mirrored onto the ++ * 3rd bank's interrupt signal. ++ * So, a bank0 interrupt shows up on 17, 20, and ++ * a bank1 interrupt shows up on 18, 19, 20! ++ */ ++ interrupts = <2 17>, <2 18>, <2 19>, <2 20>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ uart0: uart@7e201000 { ++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; ++ reg = <0x7e201000 0x1000>; ++ interrupts = <2 25>; ++ clocks = <&clocks BCM2835_CLOCK_UART>, ++ <&clocks BCM2835_CLOCK_VPU>; ++ clock-names = "uartclk", "apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; ++ }; ++ ++ i2s: i2s@7e203000 { ++ compatible = "brcm,bcm2835-i2s"; ++ reg = <0x7e203000 0x20>, ++ <0x7e101098 0x02>; ++ ++ dmas = <&dma 2>, ++ <&dma 3>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ spi: spi@7e204000 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204000 0x1000>; ++ interrupts = <2 22>; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@7e205000 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e205000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ sdhci: sdhci@7e300000 { ++ compatible = "brcm,bcm2835-sdhci"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clocks BCM2835_CLOCK_EMMC>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@7e804000 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e804000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@7e805000 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e805000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usb@7e980000 { ++ compatible = "brcm,bcm2835-usb"; ++ reg = <0x7e980000 0x10000>; ++ interrupts = <1 9>; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,arm1176-pmu"; ++ }; ++ }; ++ ++ clocks { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* The oscillator is the root of the clock tree. */ ++ clk_osc: clock@3 { ++ compatible = "fixed-clock"; ++ reg = <3>; ++ #clock-cells = <0>; ++ clock-output-names = "osc"; ++ clock-frequency = <19200000>; ++ }; ++ ++ }; ++}; diff --git a/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch b/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch new file mode 100644 index 0000000..1a71a3f --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch @@ -0,0 +1,68 @@ +From: Eric Anholt <eric@anholt.net> +Date: Wed, 16 Dec 2015 14:43:52 -0800 +Subject: [PATCH] ARM: bcm2835: Move the CPU/peripheral include out of common + RPi DT. + +For Raspberry Pi 2, we want to use the same general pin assignment +bits, but need to use bcm2836.dtsi for the CPU instead. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 1 + + arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 1 + + arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 1 + + arch/arm/boot/dts/bcm2835-rpi-b.dts | 1 + + arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 -- + 5 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts +index b2bff43b135c..228614ffff44 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts +@@ -1,4 +1,5 @@ + /dts-v1/; ++#include "bcm2835.dtsi" + #include "bcm2835-rpi.dtsi" + + / { +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +index 668442b1bda5..ef5405025223 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +@@ -1,4 +1,5 @@ + /dts-v1/; ++#include "bcm2835.dtsi" + #include "bcm2835-rpi.dtsi" + + / { +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +index eab8b5916e8a..86f1f2f598a7 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +@@ -1,4 +1,5 @@ + /dts-v1/; ++#include "bcm2835.dtsi" + #include "bcm2835-rpi.dtsi" + + / { +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts +index ff6b2d1c6c90..4859e9d81b23 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts +@@ -1,4 +1,5 @@ + /dts-v1/; ++#include "bcm2835.dtsi" + #include "bcm2835-rpi.dtsi" + + / { +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 3572f0367baf..3afb9fefe2d1 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -1,5 +1,3 @@ +-#include "bcm2835.dtsi" +- + / { + memory { + reg = <0 0x10000000>; diff --git a/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch b/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch new file mode 100644 index 0000000..9adf7a3 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch @@ -0,0 +1,141 @@ +From: Eric Anholt <eric@anholt.net> +Date: Thu, 16 Apr 2015 15:26:45 -0700 +Subject: [PATCH] ARM: bcm2835: Add devicetree for bcm2836 and Raspberry Pi 2 B + +The Pi 2 B ends up like a Pi 1 B+, with the same peripherals and +pinout, but the CPU and memory layout changed to use the 2836. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 35 ++++++++++++++++ + arch/arm/boot/dts/bcm2836.dtsi | 78 +++++++++++++++++++++++++++++++++++ + 2 files changed, 113 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2836-rpi-2-b.dts + create mode 100644 arch/arm/boot/dts/bcm2836.dtsi + +diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +new file mode 100644 +index 000000000000..ff946661bd13 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +@@ -0,0 +1,35 @@ ++/dts-v1/; ++#include "bcm2836.dtsi" ++#include "bcm2835-rpi.dtsi" ++ ++/ { ++ compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; ++ model = "Raspberry Pi 2 Model B"; ++ ++ memory { ++ reg = <0 0x40000000>; ++ }; ++ ++ leds { ++ act { ++ gpios = <&gpio 47 0>; ++ }; ++ ++ pwr { ++ label = "PWR"; ++ gpios = <&gpio 35 0>; ++ default-state = "keep"; ++ linux,default-trigger = "default-on"; ++ }; ++ }; ++}; ++ ++&gpio { ++ pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; ++ ++ /* I2S interface */ ++ i2s_alt0: i2s_alt0 { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi +new file mode 100644 +index 000000000000..9d0651d8f373 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2836.dtsi +@@ -0,0 +1,78 @@ ++#include "bcm283x.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2836"; ++ ++ soc { ++ ranges = <0x7e000000 0x3f000000 0x1000000>, ++ <0x40000000 0x40000000 0x00001000>; ++ dma-ranges = <0xc0000000 0x00000000 0x3f000000>; ++ ++ local_intc: local_intc { ++ compatible = "brcm,bcm2836-l1-intc"; ++ reg = <0x40000000 0x100>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ interrupt-parent = <&local_intc>; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupt-parent = <&local_intc>; ++ interrupts = <9>; ++ }; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&local_intc>; ++ interrupts = <0>, // PHYS_SECURE_PPI ++ <1>, // PHYS_NONSECURE_PPI ++ <3>, // VIRT_PPI ++ <2>; // HYP_PPI ++ always-on; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ v7_cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf00>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf01>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf02>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf03>; ++ clock-frequency = <800000000>; ++ }; ++ }; ++}; ++ ++/* Make the BCM2835-style global interrupt controller be a child of the ++ * CPU-local interrupt controller. ++ */ ++&intc { ++ compatible = "brcm,bcm2836-armctrl-ic"; ++ reg = <0x7e00b200 0x200>; ++ interrupt-parent = <&local_intc>; ++ interrupts = <8>; ++}; diff --git a/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch b/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch new file mode 100644 index 0000000..794ac9d --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch @@ -0,0 +1,30 @@ +From: Eric Anholt <eric@anholt.net> +Date: Fri, 13 Mar 2015 10:18:06 -0700 +Subject: [PATCH] ARM: bcm2835: Add a compat string for bcm2836 machine probe + +Supporting the 2836 requires using the new interrupt controller, which +we have support for. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/mach-bcm/board_bcm2835.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c +index 0f7b9eac3d15..834d67684e20 100644 +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -36,7 +36,12 @@ static void __init bcm2835_init(void) + } + + static const char * const bcm2835_compat[] = { ++#ifdef CONFIG_ARCH_MULTI_V6 + "brcm,bcm2835", ++#endif ++#ifdef CONFIG_ARCH_MULTI_V7 ++ "brcm,bcm2836", ++#endif + NULL + }; + diff --git a/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch b/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch new file mode 100644 index 0000000..18d0f16 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch @@ -0,0 +1,94 @@ +From: Eric Anholt <eric@anholt.net> +Date: Tue, 24 Feb 2015 15:07:55 +0000 +Subject: [PATCH] ARM: bcm2835: Add Kconfig support for bcm2836 + +This should be a complete port of bcm2835 functionality to bcm2836 +(Raspberry Pi 2). + +v2: Implement Arnd's feedback to not split to ARCH_BCM2836, and + instead use more conditionals in ARCH_BCM2835. Also reduce diff + between 2835 and 2836. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/Kconfig.debug | 10 ++++++++-- + arch/arm/boot/dts/Makefile | 3 ++- + arch/arm/mach-bcm/Kconfig | 8 ++++---- + 3 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug +index 259c0ca9c99a..957b876fda92 100644 +--- a/arch/arm/Kconfig.debug ++++ b/arch/arm/Kconfig.debug +@@ -143,7 +143,12 @@ choice + + config DEBUG_BCM2835 + bool "Kernel low-level debugging on BCM2835 PL011 UART" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 && ARCH_MULTI_V6 ++ select DEBUG_UART_PL01X ++ ++ config DEBUG_BCM2836 ++ bool "Kernel low-level debugging on BCM2836 PL011 UART" ++ depends on ARCH_BCM2835 && ARCH_MULTI_V7 + select DEBUG_UART_PL01X + + config DEBUG_BCM_5301X +@@ -1402,6 +1407,7 @@ config DEBUG_UART_PHYS + default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 + default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 + default 0x20201000 if DEBUG_BCM2835 ++ default 0x3f201000 if DEBUG_BCM2836 + default 0x3e000000 if DEBUG_BCM_KONA_UART + default 0x4000e400 if DEBUG_LL_UART_EFM32 + default 0x40081000 if DEBUG_LPC18XX_UART0 +@@ -1485,7 +1491,7 @@ config DEBUG_UART_VIRT + default 0xf0000be0 if ARCH_EBSA110 + default 0xf0010000 if DEBUG_ASM9260_UART + default 0xf01fb000 if DEBUG_NOMADIK_UART +- default 0xf0201000 if DEBUG_BCM2835 ++ default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836 + default 0xf1000300 if DEBUG_BCM_5301X + default 0xf1002000 if DEBUG_MT8127_UART0 + default 0xf1006000 if DEBUG_MT6589_UART0 +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 30bbc3746130..54e8f6bc038f 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -60,7 +60,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2835-rpi-b.dtb \ + bcm2835-rpi-b-rev2.dtb \ + bcm2835-rpi-b-plus.dtb \ +- bcm2835-rpi-a-plus.dtb ++ bcm2835-rpi-a-plus.dtb \ ++ bcm2836-rpi-2-b.dtb + dtb-$(CONFIG_ARCH_BCM_5301X) += \ + bcm4708-asus-rt-ac56u.dtb \ + bcm4708-asus-rt-ac68u.dtb \ +diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig +index 8c53c55be1fe..d7cada994295 100644 +--- a/arch/arm/mach-bcm/Kconfig ++++ b/arch/arm/mach-bcm/Kconfig +@@ -122,17 +122,17 @@ config ARCH_BCM_MOBILE_SMP + comment "Other Architectures" + + config ARCH_BCM2835 +- bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 ++ bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 || ARCH_MULTI_V7 + select ARCH_REQUIRE_GPIOLIB + select ARM_AMBA +- select ARM_ERRATA_411920 ++ select ARM_ERRATA_411920 if ARCH_MULTI_V6 + select ARM_TIMER_SP804 + select CLKSRC_OF + select PINCTRL + select PINCTRL_BCM2835 + help +- This enables support for the Broadcom BCM2835 SoC. This SoC is +- used in the Raspberry Pi and Roku 2 devices. ++ This enables support for the Broadcom BCM2835 and BCM2836 SoCs. ++ This SoC is used in the Raspberry Pi and Roku 2 devices. + + config ARCH_BCM_63XX + bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 diff --git a/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch b/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch new file mode 100644 index 0000000..49f4df9 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch @@ -0,0 +1,34 @@ +From: Andrea Merello <andrea.merello@gmail.com> +Date: Sat, 26 Dec 2015 13:47:23 -0800 +Subject: [PATCH] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR + +On my RPi2 I got a lot of: +unexpected IRQ trap at vector 00 + +This happens because bcm2836_arm_irqchip_handle_irq() is sometimes +invoked even if the ISR is clear, and this case is not handled. + +This patch explicitly handle this case, fixing the kernel complaints +about the bad IRQ lookup. + +Signed-off-by: Andrea Merello <andrea.merello@gmail.com> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + drivers/irqchip/irq-bcm2836.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c +index c5ef4dfb5bb0..e314cce70201 100644 +--- a/drivers/irqchip/irq-bcm2836.c ++++ b/drivers/irqchip/irq-bcm2836.c +@@ -177,7 +177,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) + writel(1 << ipi, mailbox0); + handle_IPI(ipi, regs); + #endif +- } else { ++ } else if (stat) { + u32 hwirq = ffs(stat) - 1; + + handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); diff --git a/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch b/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch new file mode 100644 index 0000000..7a4315d --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch @@ -0,0 +1,28 @@ +From: Andrea Merello <andrea.merello@gmail.com> +Date: Sat, 26 Dec 2015 13:47:24 -0800 +Subject: [PATCH] irqchip: bcm2836: make code more readable + +Avoid using hardcoded magics. We have a #define for this number. +No functional changes. + +Signed-off-by: Andrea Merello <andrea.merello@gmail.com> +Reviewed-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + drivers/irqchip/irq-bcm2836.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c +index e314cce70201..6c9aaad0e4f1 100644 +--- a/drivers/irqchip/irq-bcm2836.c ++++ b/drivers/irqchip/irq-bcm2836.c +@@ -167,7 +167,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) + u32 stat; + + stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); +- if (stat & 0x10) { ++ if (stat & BIT(LOCAL_IRQ_MAILBOX0)) { + #ifdef CONFIG_SMP + void __iomem *mailbox0 = (intc.base + + LOCAL_MAILBOX0_CLR0 + 16 * cpu); diff --git a/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch b/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch new file mode 100644 index 0000000..807084e --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch @@ -0,0 +1,32 @@ +From: Eric Anholt <eric@anholt.net> +Date: Wed, 16 Dec 2015 16:26:46 -0800 +Subject: [PATCH] ARM: bcm2835: Define two new packets from the latest + firmware. + +These packets give us direct access to the firmware's power management +code, as opposed to GET/SET_POWER_STATE packets that only had a couple +of domains implemented. + +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + include/soc/bcm2835/raspberrypi-firmware.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index c07d74aa39bf..3fb357193f09 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -72,10 +72,12 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, + RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, ++ RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, + RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, + RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, + RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, + RPI_FIRMWARE_SET_TURBO = 0x00038009, ++ RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, diff --git a/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch b/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch new file mode 100644 index 0000000..e4aad60 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch @@ -0,0 +1,374 @@ +From: Alexander Aring <alex.aring@gmail.com> +Date: Wed, 16 Dec 2015 16:26:47 -0800 +Subject: [PATCH] ARM: bcm2835: add rpi power domain driver + +This patch adds support for several power domains on Raspberry Pi, +including USB (so it can be enabled even if the bootloader didn't do +it), and graphics. + +This patch is the combined work of Eric Anholt (who wrote USB support +inside of the Raspberry Pi firmware driver, and wrote the non-USB +domain support) and Alexander Aring (who separated the original USB +work out from the firmware driver). + +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + drivers/soc/Kconfig | 1 + + drivers/soc/Makefile | 1 + + drivers/soc/bcm/Kconfig | 9 + + drivers/soc/bcm/Makefile | 1 + + drivers/soc/bcm/raspberrypi-power.c | 247 ++++++++++++++++++++++++++++ + include/dt-bindings/soc/raspberrypi-power.h | 41 +++++ + 6 files changed, 300 insertions(+) + create mode 100644 drivers/soc/bcm/Kconfig + create mode 100644 drivers/soc/bcm/Makefile + create mode 100644 drivers/soc/bcm/raspberrypi-power.c + create mode 100644 include/dt-bindings/soc/raspberrypi-power.h + +diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig +index 4e853ed2c82b..844142620031 100644 +--- a/drivers/soc/Kconfig ++++ b/drivers/soc/Kconfig +@@ -1,5 +1,6 @@ + menu "SOC (System On Chip) specific Drivers" + ++source "drivers/soc/bcm/Kconfig" + source "drivers/soc/brcmstb/Kconfig" + source "drivers/soc/mediatek/Kconfig" + source "drivers/soc/qcom/Kconfig" +diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile +index f2ba2e932ae1..f3f955cdb04b 100644 +--- a/drivers/soc/Makefile ++++ b/drivers/soc/Makefile +@@ -2,6 +2,7 @@ + # Makefile for the Linux Kernel SOC specific device drivers. + # + ++obj-y += bcm/ + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ + obj-$(CONFIG_MACH_DOVE) += dove/ + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig +new file mode 100644 +index 000000000000..5ba1827fe36f +--- /dev/null ++++ b/drivers/soc/bcm/Kconfig +@@ -0,0 +1,9 @@ ++config RASPBERRYPI_POWER ++ bool "Raspberry Pi power domain driver" ++ depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on RASPBERRYPI_FIRMWARE ++ select PM_GENERIC_DOMAINS if PM ++ select PM_GENERIC_DOMAINS_OF if PM ++ help ++ This enables support for the RPi power domains which can be enabled ++ or disabled via the RPi firmware. +diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile +new file mode 100644 +index 000000000000..63aa3eb23087 +--- /dev/null ++++ b/drivers/soc/bcm/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o +diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c +new file mode 100644 +index 000000000000..d5bab0696580 +--- /dev/null ++++ b/drivers/soc/bcm/raspberrypi-power.c +@@ -0,0 +1,247 @@ ++/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de> ++ * ++ * 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. ++ * ++ * Authors: ++ * Alexander Aring <aar@pengutronix.de> ++ * Eric Anholt <eric@anholt.net> ++ */ ++ ++#include <linux/module.h> ++#include <linux/of_platform.h> ++#include <linux/platform_device.h> ++#include <linux/pm_domain.h> ++#include <dt-bindings/soc/raspberrypi-power.h> ++#include <soc/bcm2835/raspberrypi-firmware.h> ++ ++/* ++ * Firmware indices for the old power domains interface. Only a few ++ * of them were actually implemented. ++ */ ++#define RPI_OLD_POWER_DOMAIN_USB 3 ++#define RPI_OLD_POWER_DOMAIN_V3D 10 ++ ++struct rpi_power_domain { ++ u32 domain; ++ bool enabled; ++ bool old_interface; ++ struct generic_pm_domain base; ++ struct rpi_firmware *fw; ++}; ++ ++struct rpi_power_domains { ++ bool has_new_interface; ++ struct genpd_onecell_data xlate; ++ struct rpi_firmware *fw; ++ struct rpi_power_domain domains[RPI_POWER_DOMAIN_COUNT]; ++}; ++ ++/* ++ * Packet definition used by RPI_FIRMWARE_SET_POWER_STATE and ++ * RPI_FIRMWARE_SET_DOMAIN_STATE ++ */ ++struct rpi_power_domain_packet { ++ u32 domain; ++ u32 on; ++} __packet; ++ ++/* ++ * Asks the firmware to enable or disable power on a specific power ++ * domain. ++ */ ++static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on) ++{ ++ struct rpi_power_domain_packet packet; ++ ++ packet.domain = rpi_domain->domain; ++ packet.on = on; ++ return rpi_firmware_property(rpi_domain->fw, ++ rpi_domain->old_interface ? ++ RPI_FIRMWARE_SET_POWER_STATE : ++ RPI_FIRMWARE_SET_DOMAIN_STATE, ++ &packet, sizeof(packet)); ++} ++ ++static int rpi_domain_off(struct generic_pm_domain *domain) ++{ ++ struct rpi_power_domain *rpi_domain = ++ container_of(domain, struct rpi_power_domain, base); ++ ++ return rpi_firmware_set_power(rpi_domain, false); ++} ++ ++static int rpi_domain_on(struct generic_pm_domain *domain) ++{ ++ struct rpi_power_domain *rpi_domain = ++ container_of(domain, struct rpi_power_domain, base); ++ ++ return rpi_firmware_set_power(rpi_domain, true); ++} ++ ++static void rpi_common_init_power_domain(struct rpi_power_domains *rpi_domains, ++ int xlate_index, const char *name) ++{ ++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index]; ++ ++ dom->fw = rpi_domains->fw; ++ ++ dom->base.name = name; ++ dom->base.power_on = rpi_domain_on; ++ dom->base.power_off = rpi_domain_off; ++ ++ /* ++ * Treat all power domains as off at boot. ++ * ++ * The firmware itself may be keeping some domains on, but ++ * from Linux's perspective all we control is the refcounts ++ * that we give to the firmware, and we can't ask the firmware ++ * to turn off something that we haven't ourselves turned on. ++ */ ++ pm_genpd_init(&dom->base, NULL, true); ++ ++ rpi_domains->xlate.domains[xlate_index] = &dom->base; ++} ++ ++static void rpi_init_power_domain(struct rpi_power_domains *rpi_domains, ++ int xlate_index, const char *name) ++{ ++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index]; ++ ++ if (!rpi_domains->has_new_interface) ++ return; ++ ++ /* The DT binding index is the firmware's domain index minus one. */ ++ dom->domain = xlate_index + 1; ++ ++ rpi_common_init_power_domain(rpi_domains, xlate_index, name); ++} ++ ++static void rpi_init_old_power_domain(struct rpi_power_domains *rpi_domains, ++ int xlate_index, int domain, ++ const char *name) ++{ ++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index]; ++ ++ dom->old_interface = true; ++ dom->domain = domain; ++ ++ rpi_common_init_power_domain(rpi_domains, xlate_index, name); ++} ++ ++/* ++ * Detects whether the firmware supports the new power domains interface. ++ * ++ * The firmware doesn't actually return an error on an unknown tag, ++ * and just skips over it, so we do the detection by putting an ++ * unexpected value in the return field and checking if it was ++ * unchanged. ++ */ ++static bool ++rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains) ++{ ++ struct rpi_power_domain_packet packet; ++ int ret; ++ ++ packet.domain = RPI_POWER_DOMAIN_ARM; ++ packet.on = ~0; ++ ++ ret = rpi_firmware_property(rpi_domains->fw, ++ RPI_FIRMWARE_GET_DOMAIN_STATE, ++ &packet, sizeof(packet)); ++ ++ return ret == 0 && packet.on != ~0; ++} ++ ++static int rpi_power_probe(struct platform_device *pdev) ++{ ++ struct device_node *fw_np; ++ struct device *dev = &pdev->dev; ++ struct rpi_power_domains *rpi_domains; ++ ++ rpi_domains = devm_kzalloc(dev, sizeof(*rpi_domains), GFP_KERNEL); ++ if (!rpi_domains) ++ return -ENOMEM; ++ ++ rpi_domains->xlate.domains = ++ devm_kzalloc(dev, sizeof(*rpi_domains->xlate.domains) * ++ RPI_POWER_DOMAIN_COUNT, GFP_KERNEL); ++ if (!rpi_domains->xlate.domains) ++ return -ENOMEM; ++ ++ rpi_domains->xlate.num_domains = RPI_POWER_DOMAIN_COUNT; ++ ++ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0); ++ if (!fw_np) { ++ dev_err(&pdev->dev, "no firmware node\n"); ++ return -ENODEV; ++ } ++ ++ rpi_domains->fw = rpi_firmware_get(fw_np); ++ of_node_put(fw_np); ++ if (!rpi_domains->fw) ++ return -EPROBE_DEFER; ++ ++ rpi_domains->has_new_interface = ++ rpi_has_new_domain_support(rpi_domains); ++ ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C0, "I2C0"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C1, "I2C1"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C2, "I2C2"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VIDEO_SCALER, ++ "VIDEO_SCALER"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VPU1, "VPU1"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_HDMI, "HDMI"); ++ ++ /* ++ * Use the old firmware interface for USB power, so that we ++ * can turn it on even if the firmware hasn't been updated. ++ */ ++ rpi_init_old_power_domain(rpi_domains, RPI_POWER_DOMAIN_USB, ++ RPI_OLD_POWER_DOMAIN_USB, "USB"); ++ ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VEC, "VEC"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_JPEG, "JPEG"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_H264, "H264"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_V3D, "V3D"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ISP, "ISP"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM0, "UNICAM0"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM1, "UNICAM1"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2RX, "CCP2RX"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CSI2, "CSI2"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CPI, "CPI"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI0, "DSI0"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI1, "DSI1"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_TRANSPOSER, ++ "TRANSPOSER"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2TX, "CCP2TX"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CDP, "CDP"); ++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ARM, "ARM"); ++ ++ of_genpd_add_provider_onecell(dev->of_node, &rpi_domains->xlate); ++ ++ platform_set_drvdata(pdev, rpi_domains); ++ ++ return 0; ++} ++ ++static const struct of_device_id rpi_power_of_match[] = { ++ { .compatible = "raspberrypi,bcm2835-power", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rpi_power_of_match); ++ ++static struct platform_driver rpi_power_driver = { ++ .driver = { ++ .name = "raspberrypi-power", ++ .of_match_table = rpi_power_of_match, ++ }, ++ .probe = rpi_power_probe, ++}; ++builtin_platform_driver(rpi_power_driver); ++ ++MODULE_AUTHOR("Alexander Aring <aar@pengutronix.de>"); ++MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); ++MODULE_DESCRIPTION("Raspberry Pi power domain driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/dt-bindings/soc/raspberrypi-power.h b/include/dt-bindings/soc/raspberrypi-power.h +new file mode 100644 +index 000000000000..b3ff8e09a78f +--- /dev/null ++++ b/include/dt-bindings/soc/raspberrypi-power.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright © 2015 Broadcom ++ * ++ * 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. ++ */ ++ ++#ifndef _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H ++#define _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H ++ ++/* These power domain indices are the firmware interface's indices ++ * minus one. ++ */ ++#define RPI_POWER_DOMAIN_I2C0 0 ++#define RPI_POWER_DOMAIN_I2C1 1 ++#define RPI_POWER_DOMAIN_I2C2 2 ++#define RPI_POWER_DOMAIN_VIDEO_SCALER 3 ++#define RPI_POWER_DOMAIN_VPU1 4 ++#define RPI_POWER_DOMAIN_HDMI 5 ++#define RPI_POWER_DOMAIN_USB 6 ++#define RPI_POWER_DOMAIN_VEC 7 ++#define RPI_POWER_DOMAIN_JPEG 8 ++#define RPI_POWER_DOMAIN_H264 9 ++#define RPI_POWER_DOMAIN_V3D 10 ++#define RPI_POWER_DOMAIN_ISP 11 ++#define RPI_POWER_DOMAIN_UNICAM0 12 ++#define RPI_POWER_DOMAIN_UNICAM1 13 ++#define RPI_POWER_DOMAIN_CCP2RX 14 ++#define RPI_POWER_DOMAIN_CSI2 15 ++#define RPI_POWER_DOMAIN_CPI 16 ++#define RPI_POWER_DOMAIN_DSI0 17 ++#define RPI_POWER_DOMAIN_DSI1 18 ++#define RPI_POWER_DOMAIN_TRANSPOSER 19 ++#define RPI_POWER_DOMAIN_CCP2TX 20 ++#define RPI_POWER_DOMAIN_CDP 21 ++#define RPI_POWER_DOMAIN_ARM 22 ++ ++#define RPI_POWER_DOMAIN_COUNT 23 ++ ++#endif /* _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H */ diff --git a/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch b/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch new file mode 100644 index 0000000..e8cab3a --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch @@ -0,0 +1,69 @@ +From: Alexander Aring <alex.aring@gmail.com> +Date: Wed, 16 Dec 2015 16:26:48 -0800 +Subject: [PATCH] dt-bindings: add rpi power domain driver bindings + +This patch adds devicetree tree bindings for the Raspberry Pi power +domain driver. + +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + .../bindings/soc/bcm/raspberrypi,bcm2835-power.txt | 47 ++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + create mode 100644 Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt + +diff --git a/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt +new file mode 100644 +index 000000000000..30942cf7992b +--- /dev/null ++++ b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt +@@ -0,0 +1,47 @@ ++Raspberry Pi power domain driver ++ ++Required properties: ++ ++- compatible: Should be "raspberrypi,bcm2835-power". ++- firmware: Reference to the RPi firmware device node. ++- #power-domain-cells: Should be <1>, we providing multiple power domains. ++ ++The valid defines for power domain are: ++ ++ RPI_POWER_DOMAIN_I2C0 ++ RPI_POWER_DOMAIN_I2C1 ++ RPI_POWER_DOMAIN_I2C2 ++ RPI_POWER_DOMAIN_VIDEO_SCALER ++ RPI_POWER_DOMAIN_VPU1 ++ RPI_POWER_DOMAIN_HDMI ++ RPI_POWER_DOMAIN_USB ++ RPI_POWER_DOMAIN_VEC ++ RPI_POWER_DOMAIN_JPEG ++ RPI_POWER_DOMAIN_H264 ++ RPI_POWER_DOMAIN_V3D ++ RPI_POWER_DOMAIN_ISP ++ RPI_POWER_DOMAIN_UNICAM0 ++ RPI_POWER_DOMAIN_UNICAM1 ++ RPI_POWER_DOMAIN_CCP2RX ++ RPI_POWER_DOMAIN_CSI2 ++ RPI_POWER_DOMAIN_CPI ++ RPI_POWER_DOMAIN_DSI0 ++ RPI_POWER_DOMAIN_DSI1 ++ RPI_POWER_DOMAIN_TRANSPOSER ++ RPI_POWER_DOMAIN_CCP2TX ++ RPI_POWER_DOMAIN_CDP ++ RPI_POWER_DOMAIN_ARM ++ ++Example: ++ ++power: power { ++ compatible = "raspberrypi,bcm2835-power"; ++ firmware = <&firmware>; ++ #power-domain-cells = <1>; ++}; ++ ++Example for using power domain: ++ ++&usb { ++ power-domains = <&power RPI_POWER_DOMAIN_USB>; ++}; diff --git a/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch b/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch new file mode 100644 index 0000000..6bbce3f --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch @@ -0,0 +1,60 @@ +From: Alexander Aring <alex.aring@gmail.com> +Date: Wed, 16 Dec 2015 16:26:49 -0800 +Subject: [PATCH] ARM: bcm2835: Add the Raspberry Pi power domain driver to the + DT. + +This connects the USB driver to the USB power domain, so that USB can +actually be turned on at boot if the bootloader didn't do it for us. + +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Signed-off-by: Alexander Aring <alex.aring@gmail.com> +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 12 ++++++++++++ + arch/arm/boot/dts/bcm283x.dtsi | 2 +- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 3afb9fefe2d1..aad668c81d8c 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -1,3 +1,5 @@ ++#include <dt-bindings/soc/raspberrypi-power.h> ++ + / { + memory { + reg = <0 0x10000000>; +@@ -18,6 +20,12 @@ + compatible = "raspberrypi,bcm2835-firmware"; + mboxes = <&mailbox>; + }; ++ ++ power: power { ++ compatible = "raspberrypi,bcm2835-power"; ++ firmware = <&firmware>; ++ #power-domain-cells = <1>; ++ }; + }; + }; + +@@ -58,3 +66,7 @@ + status = "okay"; + bus-width = <4>; + }; ++ ++&usb { ++ power-domains = <&power RPI_POWER_DOMAIN_USB>; ++}; +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +index bf74e8afbe88..c8e8e4b98097 100644 +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -180,7 +180,7 @@ + status = "disabled"; + }; + +- usb@7e980000 { ++ usb: usb@7e980000 { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; diff --git a/configs/platform-rpi/patches/linux-4.4/series b/configs/platform-rpi/patches/linux-4.4/series new file mode 100644 index 0000000..6ab99e2 --- /dev/null +++ b/configs/platform-rpi/patches/linux-4.4/series @@ -0,0 +1,17 @@ +# generated by git-ptx-patches +#tag:base --start-number 1 +0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch +0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch +0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch +0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch +0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch +0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch +0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch +0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch +0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch +0010-irqchip-bcm2836-make-code-more-readable.patch +0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch +0012-ARM-bcm2835-add-rpi-power-domain-driver.patch +0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch +0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch +# bb2d21d7e88e49e7345c57522cc98977 - git-ptx-patches magic |