Browse Source

Merge tag 'socfpga_fixes_for_3.18' of git://git.rocketboards.org/linux-socfpga-next into fixes

Merge "SOCFPGA fixes for 3.18" from Dinh Nguyen:

These patches fixes an SMP and SDMMC driver hang during boot up on the
SOCFPGA platform.

Patch "arm: socfpga: fix fetching cpu1start_addr for SMP" fixes the SMP
trampoline code in order for CPU1 to correctly fetch it's cpu1start_addr.

Patch "ARM: dts: socfpga: rename gpio nodes" renames that GPIO node in order
to allow a standard way of specifying status="okay" in the board DTS file.

Patch "ARM: dts: socfpga: Fix SD card detect" fixes a SDMMC driver hang
during boot. The reason for the hang was the deferred probe of the SDMMC
driver was waiting for the GPIO resource that would never come.

Patch "ARM: dts: socfpga: Add a 3.3V fixed regulator node" adds a fixed
regulator node for the SDMMC driver to use.

* tag 'socfpga_fixes_for_3.18' of git://git.rocketboards.org/linux-socfpga-next:
  ARM: dts: socfpga: Add a 3.3V fixed regulator node
  ARM: dts: socfpga: Fix SD card detect
  ARM: dts: socfpga: rename gpio nodes
  arm: socfpga: fix fetching cpu1start_addr for SMP

Signed-off-by: Olof Johansson <olof@lixom.net>
Olof Johansson 11 years ago
parent
commit
4fbc400cfc

+ 6 - 6
arch/arm/boot/dts/socfpga.dtsi

@@ -547,7 +547,7 @@
 			status = "disabled";
 		};
 
-		gpio@ff708000 {
+		gpio0: gpio@ff708000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
@@ -555,7 +555,7 @@
 			clocks = <&per_base_clk>;
 			status = "disabled";
 
-			gpio0: gpio-controller@0 {
+			porta: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
 				gpio-controller;
 				#gpio-cells = <2>;
@@ -567,7 +567,7 @@
 			};
 		};
 
-		gpio@ff709000 {
+		gpio1: gpio@ff709000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
@@ -575,7 +575,7 @@
 			clocks = <&per_base_clk>;
 			status = "disabled";
 
-			gpio1: gpio-controller@0 {
+			portb: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
 				gpio-controller;
 				#gpio-cells = <2>;
@@ -587,7 +587,7 @@
 			};
 		};
 
-		gpio@ff70a000 {
+		gpio2: gpio@ff70a000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "snps,dw-apb-gpio";
@@ -595,7 +595,7 @@
 			clocks = <&per_base_clk>;
 			status = "disabled";
 
-			gpio2: gpio-controller@0 {
+			portc: gpio-controller@0 {
 				compatible = "snps,dw-apb-gpio-port";
 				gpio-controller;
 				#gpio-cells = <2>;

+ 1 - 1
arch/arm/boot/dts/socfpga_arria5.dtsi

@@ -29,7 +29,7 @@
 			};
 		};
 
-		dwmmc0@ff704000 {
+		mmc0: dwmmc0@ff704000 {
 			num-slots = <1>;
 			broken-cd;
 			bus-width = <4>;

+ 12 - 0
arch/arm/boot/dts/socfpga_arria5_socdk.dts

@@ -37,6 +37,13 @@
 		*/
 		ethernet0 = &gmac1;
 	};
+
+	regulator_3_3v: 3-3-v-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &gmac1 {
@@ -68,6 +75,11 @@
 	};
 };
 
+&mmc0 {
+	vmmc-supply = <&regulator_3_3v>;
+	vqmmc-supply = <&regulator_3_3v>;
+};
+
 &usb1 {
 	status = "okay";
 };

+ 14 - 1
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts

@@ -37,6 +37,13 @@
 		 */
 		ethernet0 = &gmac1;
 	};
+
+	regulator_3_3v: 3-3-v-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &gmac1 {
@@ -53,6 +60,10 @@
 	rxc-skew-ps = <2000>;
 };
 
+&gpio1 {
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -69,7 +80,9 @@
 };
 
 &mmc0 {
-	cd-gpios = <&gpio1 18 0>;
+	cd-gpios = <&portb 18 0>;
+	vmmc-supply = <&regulator_3_3v>;
+	vqmmc-supply = <&regulator_3_3v>;
 };
 
 &usb1 {

+ 12 - 0
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts

@@ -37,6 +37,13 @@
 		 */
 		ethernet0 = &gmac1;
 	};
+
+	regulator_3_3v: vcc3p3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC3P3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &gmac1 {
@@ -53,6 +60,11 @@
 	rxc-skew-ps = <2000>;
 };
 
+&mmc0 {
+	vmmc-supply = <&regulator_3_3v>;
+	vqmmc-supply = <&regulator_3_3v>;
+};
+
 &usb1 {
 	status = "okay";
 };

+ 1 - 1
arch/arm/mach-socfpga/core.h

@@ -40,7 +40,7 @@ extern void __iomem *rst_manager_base_addr;
 extern struct smp_operations socfpga_smp_ops;
 extern char secondary_trampoline, secondary_trampoline_end;
 
-extern unsigned long cpu1start_addr;
+extern unsigned long socfpga_cpu1start_addr;
 
 #define SOCFPGA_SCU_VIRT_BASE   0xfffec000
 

+ 15 - 10
arch/arm/mach-socfpga/headsmp.S

@@ -9,21 +9,26 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/memory.h>
 
 	.arch	armv7-a
 
 ENTRY(secondary_trampoline)
-	movw	r2, #:lower16:cpu1start_addr
-	movt  r2, #:upper16:cpu1start_addr
-
-	/* The socfpga VT cannot handle a 0xC0000000 page offset when loading
-		the cpu1start_addr, we bit clear it. Tested on HW and VT. */
-	bic	r2, r2, #0x40000000
-
-	ldr	r0, [r2]
-	ldr	r1, [r0]
-	bx	r1
+	/* CPU1 will always fetch from 0x0 when it is brought out of reset.
+	 * Thus, we can just subtract the PAGE_OFFSET to get the physical
+	 * address of &cpu1start_addr. This would not work for platforms
+	 * where the physical memory does not start at 0x0.
+	 */
+	adr	r0, 1f
+	ldmia	r0, {r1, r2}
+	sub	r2, r2, #PAGE_OFFSET
+	ldr	r3, [r2]
+	ldr	r4, [r3]
+	bx	r4
 
+	.align
+1:	.long	.
+	.long	socfpga_cpu1start_addr
 ENTRY(secondary_trampoline_end)
 
 ENTRY(socfpga_secondary_startup)

+ 2 - 2
arch/arm/mach-socfpga/platsmp.c

@@ -33,11 +33,11 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
 
-	if (cpu1start_addr) {
+	if (socfpga_cpu1start_addr) {
 		memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
 
 		__raw_writel(virt_to_phys(socfpga_secondary_startup),
-			(sys_manager_base_addr + (cpu1start_addr & 0x000000ff)));
+			(sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff)));
 
 		flush_cache_all();
 		smp_wmb();

+ 2 - 2
arch/arm/mach-socfpga/socfpga.c

@@ -29,7 +29,7 @@
 void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
 void __iomem *sys_manager_base_addr;
 void __iomem *rst_manager_base_addr;
-unsigned long cpu1start_addr;
+unsigned long socfpga_cpu1start_addr;
 
 static struct map_desc scu_io_desc __initdata = {
 	.virtual	= SOCFPGA_SCU_VIRT_BASE,
@@ -70,7 +70,7 @@ void __init socfpga_sysmgr_init(void)
 	np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
 
 	if (of_property_read_u32(np, "cpu1-start-addr",
-			(u32 *) &cpu1start_addr))
+			(u32 *) &socfpga_cpu1start_addr))
 		pr_err("SMP: Need cpu1-start-addr in device tree.\n");
 
 	sys_manager_base_addr = of_iomap(np, 0);