Re: [RESEND PATCH 4/4] ARM: msm: Add support for 8974 SMP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 14, 2013 at 11:38:44PM +0100, Rohit Vaswani wrote:
> On 8/12/2013 9:39 AM, Mark Rutland wrote:
> > On Fri, Aug 02, 2013 at 03:15:25AM +0100, Rohit Vaswani wrote:
> >> Add the cpus bindings and the Kraitv2 release sequence
> >> to make SMP work for 2 cores on MSM8974.
> >>
> >> Signed-off-by: Rohit Vaswani <rvaswani@xxxxxxxxxxxxxx>
> >> ---
> >>   Documentation/devicetree/bindings/arm/cpus.txt |  1 +
> >>   arch/arm/boot/dts/msm8974.dts                  | 23 ++++++++
> >>   arch/arm/mach-msm/board-dt-8974.c              |  3 +
> >>   arch/arm/mach-msm/platsmp.c                    | 79 ++++++++++++++++++++++++++
> >>   4 files changed, 106 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
> >> index 1132eac..7c3c677 100644
> >> --- a/Documentation/devicetree/bindings/arm/cpus.txt
> >> +++ b/Documentation/devicetree/bindings/arm/cpus.txt
> >> @@ -52,6 +52,7 @@ For the ARM architecture every CPU node must contain the following properties:
> >>   		 This should be one of:
> >>   		 "qcom,scss"
> >>   		 "qcom,kpssv1"
> >> +		 "qcom,kpssv2"
> > I guess I should've looked at the whole series before responding, that
> > answers my prior question about what variation we expect.
> >
> >>   
> >>   Example:
> >>   
> >> diff --git a/arch/arm/boot/dts/msm8974.dts b/arch/arm/boot/dts/msm8974.dts
> >> index c31c097..ef35a9b 100644
> >> --- a/arch/arm/boot/dts/msm8974.dts
> >> +++ b/arch/arm/boot/dts/msm8974.dts
> >> @@ -7,6 +7,22 @@
> >>   	compatible = "qcom,msm8974";
> >>   	interrupt-parent = <&intc>;
> >>   
> >> +	cpus {
> >> +		#address-cells = <1>;
> >> +		#size-cells = <0>;
> >> +		compatible = "qcom,krait";
> >> +		device_type = "cpu";
> >> +		enable-method = "qcom,kpssv2";
> >> +
> >> +		cpu@0 {
> >> +			reg = <0>;
> >> +		};
> >> +
> >> +		cpu@1 {
> >> +			reg = <1>;
> >> +		};
> >> +	};
> >> +
> >>   	intc: interrupt-controller@f9000000 {
> >>   		compatible = "qcom,msm-qgic2";
> >>   		interrupt-controller;
> >> @@ -23,4 +39,11 @@
> >>   			     <1 1 0xf08>;
> >>   		clock-frequency = <19200000>;
> >>   	};
> >> +
> >> +	kpss@f9012000 {
> >> +		compatible = "qcom,kpss";
> >> +		reg = <0xf9012000 0x1000>,
> >> +		      <0xf9088000 0x1000>,
> >> +		      <0xf9098000 0x1000>;
> >> +	};
> > In the previous examples, the number of CPUs was equal to the number of
> > kpss reg values. Why does it differ here. Either:
> >
> > * We always have the extra regsiter here, and it should be described
> >    even if we don't use it.
> >
> > * It's a different hardware block, and needs a more specific
> >    compatible string.
> >
> > Eitehr way this strengthens my feeling that we need to define the linkage
> > from a CPU to the portion of the kpss which affects it.
> Will add documentation for each of the registers. We have one for each 
> CPU and one within the KPSS (Krait Processor Sub-System) e.g the L2 saw 
> base in this case.

Ok.

So the previous example had no L2 saw base?

> >
> >>   };
> >> diff --git a/arch/arm/mach-msm/board-dt-8974.c b/arch/arm/mach-msm/board-dt-8974.c
> >> index d7f84f2..06119f9 100644
> >> --- a/arch/arm/mach-msm/board-dt-8974.c
> >> +++ b/arch/arm/mach-msm/board-dt-8974.c
> >> @@ -13,11 +13,14 @@
> >>   #include <linux/of_platform.h>
> >>   #include <asm/mach/arch.h>
> >>   
> >> +#include "common.h"
> >> +
> >>   static const char * const msm8974_dt_match[] __initconst = {
> >>   	"qcom,msm8974",
> >>   	NULL
> >>   };
> >>   
> >>   DT_MACHINE_START(MSM8974_DT, "Qualcomm MSM (Flattened Device Tree)")
> >> +	.smp = smp_ops(msm_smp_ops),
> >>   	.dt_compat = msm8974_dt_match,
> >>   MACHINE_END
> >> diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
> >> index 82eb079..0fdae69 100644
> >> --- a/arch/arm/mach-msm/platsmp.c
> >> +++ b/arch/arm/mach-msm/platsmp.c
> >> @@ -124,6 +124,80 @@ static int msm8960_release_secondary(unsigned int cpu)
> >>   	return 0;
> >>   }
> >>   
> >> +static int msm8974_release_secondary(unsigned int cpu)
> >> +{
> >> +	void __iomem *reg;
> >> +	void __iomem *l2_saw_base;
> >> +	struct device_node *dn = NULL;
> >> +	unsigned apc_pwr_gate_ctl = 0x14;
> >> +	unsigned reg_val;
> >> +
> >> +	if (cpu == 0 || cpu >= num_possible_cpus())
> >> +		return -EINVAL;
> >> +
> >> +	dn = of_find_compatible_node(dn, NULL, "qcom,kpss");
> >> +	if (!dn) {
> >> +		pr_err("%s : Missing kpss node from device tree\n", __func__);
> >> +		return -ENXIO;
> >> +	}
> >> +
> >> +	reg = of_iomap(dn, cpu+1);
> > This looks very fishy given the prior patch being one off from this.
> > why is reg[0] now different?
> >
> >> +	if (!reg)
> >> +		return -ENOMEM;
> >> +
> >> +	pr_debug("Starting secondary CPU %d\n", cpu);
> >> +
> >> +	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
> >> +	reg_val =  0x403f0001;
> > Magic number?
> It represents the comment above it. It didnt seem clean to define 4 
> different offsets with #defines within a single register for the purpose 
> of 1 write.

In general I'd prefer having symbolic names, but I'm not going to argue
here.

> >
> >> +	writel_relaxed(reg_val, reg + apc_pwr_gate_ctl);
> >> +
> >> +	/* complete the above write before the delay */
> >> +	mb();
> > Use writel?
> >
> >> +	/* wait for the bhs to settle */
> >> +	udelay(1);
> >> +
> >> +	/* Turn on BHS segments */
> >> +	reg_val |= 0x3f << 1;
> >> +	writel_relaxed(reg_val, reg + apc_pwr_gate_ctl);
> >> +
> >> +	/* complete the above write before the delay */
> >> +	mb();
> > Use writel again?
> >
> >> +	 /* wait for the bhs to settle */
> >> +	udelay(1);
> >> +
> >> +	/* Finally turn on the bypass so that BHS supplies power */
> >> +	reg_val |= 0x3f << 8;
> >> +	writel_relaxed(reg_val, reg + apc_pwr_gate_ctl);
> >> +
> >> +	/* enable max phases */
> >> +	l2_saw_base = of_iomap(dn, 0);
> >> +	if (!l2_saw_base) {
> >> +		return -ENOMEM;
> >> +	}
> > What?
> >
> > You've just lost your only reference to the mapping in reg.
> >
> > Why do you not do this at the start, before poking everything else? Even
> > better, do it at probe time and fail once rather than for each CPU you
> > have no chance of bringing up.
> Will do.
> 
> >
> > [...]
> >>   static void boot_cold_cpu(unsigned int cpu)
> >> @@ -151,6 +225,11 @@ static void boot_cold_cpu(unsigned int cpu)
> >>   			msm8960_release_secondary(cpu);
> >>   			per_cpu(cold_boot_done, cpu) = true;
> >>   		}
> >> +	} else if (!strcmp(enable_method, "qcom,kpssv2")) {
> >> +		if (per_cpu(cold_boot_done, cpu) == false) {
> >> +			msm8974_release_secondary(cpu);
> >> +			per_cpu(cold_boot_done, cpu) = true;
> >> +		}
> >>   	} else {
> >>   		pr_err("%s: Invalid enable-method property: %s\n",
> >>   				__func__, enable_method);
> > The enable-method parsing really should be moved out to common code. We
> > could make it scan the enable-method if a machine has no smp ops (which
> > is more general than the PSCI fallback that's been suggested before).
> But we have smp ops like every other SoC. I might need to go back to the 
> drawing board for incorporating enable-method into generic code.
> Any suggestions are appreciated.

I think we need generic infrastructure that checks if we have a NULL
smp_ops and tries to find one based on any enable-method properties in
the dt.

> If enable-method seems cumbersome to be enforced for every SoC, I would 
> be comfortable using the cpu compatible string as you suggested in the 
> previous patch.

I'm not sure cpu compatible string alone gives us enough, the
integration of the SoC and particular board will affect how we bring up
secondaries.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux