Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH, RFC] default machine descriptor for multiplatform
From: Arnd Bergmann @ 2013-01-31 20:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510ABD70.1020408@wwwdotorg.org>

On Thursday 31 January 2013, Stephen Warren wrote:

> With that change, we can remove the custom .init_machine() functions for
> all of Tegra, since they just do that:-)

Yes, actually quite a lot of them have the same code, and we also have
an increasing number of users of the irqchip_init and clocksource_of_init,
so those can also be cleaned up as a follow-on to this patch.

The main thing that has to remain for a lot of the platforms is SMP
support, and I don't see a good way around that yet.
 
> > diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
> 
> > +#ifdef CONFIG_IRQCHIP
> >  void __init irqchip_init(void)
> >  {
> >  	of_irq_init(__irqchip_begin);
> >  }
> > +#else
> > +static inline void irqchip_init(void)
> > +{
> > +}
> > +#endif
> 
> That'd need to go in a header file.

Yep, you're right, my mistake.

	Arnd

^ permalink raw reply

* BogoMIPS change in 3.6+
From: Rob Herring @ 2013-01-31 20:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130131162322.GD835@mudshark.cambridge.arm.com>

On 01/31/2013 10:23 AM, Will Deacon wrote:
> Hi Rob,
> 
> On Thu, Jan 31, 2013 at 04:15:11PM +0000, Rob Herring wrote:
>> The BogoMIPS value has changed on highbank since the commit below in
>> 3.6. It is now half the value it used to be. Does that matter other than
>> perception (I've checked that I'm not running at half the freq)?
> 
> Are you registering a delay timer? If not, then the delay loop should be
> identical to what it was before, so that's certainly a surprise...
> 
> Are your delays ballpark correct (try 2ms)?
> 

Yes, the delays are correct and this is an A9. So I guess this may be a
surprise, but seems it is a non-issue. I'm sure I'll be getting asked
about this...

Rob

^ permalink raw reply

* [PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
From: Arnd Bergmann @ 2013-01-31 20:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130131183255.GI2244@beef>

On Thursday 31 January 2013, Matt Porter wrote:
> On Wed, Jan 30, 2013 at 09:32:58AM +0000, Arnd Bergmann wrote:
> > On Wednesday 30 January 2013, Matt Porter wrote:
> > > +               dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
> > > +               of_dma_controller_register(dev->of_node,
> > > +                                          of_dma_simple_xlate,
> > > +                                          &edma_filter_info);
> > > +       }
> > 
> > How do you actually deal with the problem mentioned by Padma, that
> > the filter function does not know which edma instance it is looking
> > at? If you assume that there can only be a single edma instance in
> > the system, that is probably a limitation that should be documented
> > somewhere, and ideally the probe() function should check for that.
> 
> I make an assumption of one edma instance in the system in the case of
> DT being populated. This is always true right now as the only SoC with
> two EDMA controllers in existence is Davinci DA850. Until recently,
> Davinci had no DT support. Given the steady work being done today on DT
> support for DA850, it'll probably be something needed in 3.10.
> 
> I will add a comment and check in probe() to capture this assumption
> and then plan to update separately to support DA850 booting from DT.

Ok, sounds good. Hopefully by then we will already have a nicer
way to write an xlate function that does not rely on a filter
function.

	Arnd

^ permalink raw reply

* [RFC] arm: use built-in byte swap function
From: Kim Phillips @ 2013-01-31 20:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130131092801.GV23505@n2100.arm.linux.org.uk>

On Thu, 31 Jan 2013 09:28:01 +0000
Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

> On Wed, Jan 30, 2013 at 08:09:00PM -0600, Kim Phillips wrote:
> > The savings come mostly from device-tree related code, and some
> > from drivers.
> 
> You forget that IP networking is all big endian, so these will be using
> the byte swapping too (search it for htons/ntohs/htonl/ntohl).

As David mentioned, there isn't much gain from net/ code.

> > v2:
> > - at91 and lpd270 builds fixed by limiting to ARMv6 and above
> >   (i.e., ARM cores that have support for the 'rev' instruction).
> >   Otherwise, the compiler emits calls to libgcc's __bswapsi2 on
> >   these ARMv4/v5 builds (and arch ARM doesn't link with libgcc).
> 
> Which compiler version?  gcc 4.5.4 doesn't do this, except for the 16-bit
> swap, so I doubt that any later compiler does.

I've tried both gcc 4.6.3 [1] and 4.6.4 [2].  If you can point me to
a 4.5.x, I'll try that, too, but as it stands now, if one moves the
code added to swab.h below outside of its armv6 protection,
gcc adds calls to __bswapsi2.

> > --- a/arch/arm/include/uapi/asm/swab.h
> > +++ b/arch/arm/include/uapi/asm/swab.h
> > @@ -50,4 +50,14 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
> >  
> >  #endif
> >  
> > +#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6
> > +#if GCC_VERSION >= 40600
> > +#define __HAVE_BUILTIN_BSWAP32__
> > +#define __HAVE_BUILTIN_BSWAP64__
> > +#endif
> > +#if GCC_VERSION >= 40800
> > +#define __HAVE_BUILTIN_BSWAP16__
> > +#endif
> > +#endif
> 
> If this is __KERNEL__ only, it should not be in a uapi header.  UAPI
> headers get exported to userland, this is not userland interface code.
> IT should be in arch/arm/include/asm/swab.h

right, I've fixed this and Boris' remove the help text comment, and
made a v3:

>From 18c86580efba42d2680f2947867722705292f80a Mon Sep 17 00:00:00 2001
From: Kim Phillips <kim.phillips@freescale.com>
Date: Mon, 28 Jan 2013 19:30:33 -0600
Subject: [PATCH] arm: use built-in byte swap function

Enable the compiler intrinsic for byte swapping on arch ARM.  This
allows the compiler to detect and be able to optimize out byte
swappings, e.g. in big endian to big endian moves.

A ARCH_DEFINES_BUILTIN_BSWAP is added to allow an ARCH to select
it when it wants to control HAVE_BUILTIN_BSWAPxx definitions over
those in the generic compiler headers.  It can be dependent on a
combination of byte swapping instruction availability, the
instruction set version, and the state of support in different
compiler versions.

AFAICT, arm gcc got __builtin_bswap{32,64} support in 4.6,
and for the 16-bit version in 4.8.

This has a tiny benefit on vmlinux text size (gcc 4.6.4):

multi_v7_defconfig:
   text    data     bss     dec     hex filename
3135208  188396  203344 3526948  35d124 vmlinux
multi_v7_defconfig with builtin_bswap:
   text    data     bss     dec     hex filename
3135112  188396  203344 3526852  35d0c4 vmlinux

exynos_defconfig:
   text    data     bss     dec     hex filename
4286605  360564  223172 4870341  4a50c5 vmlinux
exynos_defconfig with builtin_bswap:
   text    data     bss     dec     hex filename
4286405  360564  223172 4870141  4a4ffd vmlinux

The savings come mostly from device-tree related code, and some
from drivers.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
akin to: http://comments.gmane.org/gmane.linux.kernel.cross-arch/16016

based on linux-next-20130128.  Depends on commit "compiler-gcc{3,4}.h:
Use GCC_VERSION macro" by Daniel Santos <daniel.santos@pobox.com>,
currently in the akpm branch.

v3:
- moved out of uapi swab.h into arch/arm/include/asm/swab.h
- moved ARCH_DEFINES_BUILTIN_BSWAP help text into commit message
- moved GCC_VERSION >= 40800 ifdef into GCC_VERSION >= 40600 block

v2:
- at91 and lpd270 builds fixed by limiting to ARMv6 and above
  (i.e., ARM cores that have support for the 'rev' instruction).
  Otherwise, the compiler emits calls to libgcc's __bswapsi2 on
  these ARMv4/v5 builds (and arch ARM doesn't link with libgcc).
  All ARM defconfigs now have the same build status as they did
  without this patch (some are broken on linux-next).

- move ARM check from generic compiler.h to arch ARM's swab.h.
  - pretty sure it should be limited to __KERNEL__ builds

- add new ARCH_DEFINES_BUILTIN_BSWAP (see Kconfig help).
  - if set, generic compiler header does not set HAVE_BUILTIN_BSWAPxx
  - not too sure about this having to be a new CONFIG_, but it's hard
    to find a place for it given linux/compiler.h doesn't include any
    arch-specific files.

- move new selects to end of CONFIG_ARM's Kconfig select list,
  as is done in David Woodhouse's original patchseries for ppc/x86.

 arch/Kconfig                  |    4 ++++
 arch/arm/Kconfig              |    2 ++
 arch/arm/include/asm/swab.h   |    8 ++++++++
 include/linux/compiler-gcc4.h |    3 ++-
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 40e2b12..bc5ed77 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -141,6 +141,10 @@ config ARCH_USE_BUILTIN_BSWAP
 	 instructions should set this. And it shouldn't hurt to set it
 	 on architectures that don't have such instructions.
 
+config ARCH_DEFINES_BUILTIN_BSWAP
+       depends on ARCH_USE_BUILTIN_BSWAP
+       bool
+
 config HAVE_SYSCALL_WRAPPERS
 	bool
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 73027aa..b5868c2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -57,6 +57,8 @@ config ARM
 	select CLONE_BACKWARDS
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select ARCH_USE_BUILTIN_BSWAP
+	select ARCH_DEFINES_BUILTIN_BSWAP
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
index 537fc9b..e56acff 100644
--- a/arch/arm/include/asm/swab.h
+++ b/arch/arm/include/asm/swab.h
@@ -34,5 +34,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 }
 #define __arch_swab32 __arch_swab32
 
+#if GCC_VERSION >= 40600
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#if GCC_VERSION >= 40800
+#define __HAVE_BUILTIN_BSWAP16__
+#endif
+#endif
+
 #endif
 #endif
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 68b162d..fce39cb 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -66,7 +66,8 @@
 #endif
 
 
-#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) && \
+    !defined(CONFIG_ARCH_DEFINES_BUILTIN_BSWAP)
 #if GCC_VERSION >= 40400
 #define __HAVE_BUILTIN_BSWAP32__
 #define __HAVE_BUILTIN_BSWAP64__
-- 
1.7.9.7

Thanks,

Kim

[1] http://kernel.org/pub/tools/crosstool/files/bin/x86_64/

[2] http://ftp.denx.de/pub/eldk/5.2.1/targets/armv7a/

^ permalink raw reply related

* [PATCH] arm: mvebu: support for the new Armada XP evaluation board(DB-MV784MP-GP)
From: Arnd Bergmann @ 2013-01-31 21:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130131163814.GE20242@lunn.ch>

On Thursday 31 January 2013, Andrew Lunn wrote:
> I did a bit of googling:
> 
> http://www.linleygroup.com/newsletters/newsletter_detail.php?num=3982
> 
>         To address the cloud-computing market, the company added
>         40-bit physical addressing to Armada XP, using a method
>         similar to what ARM implemented in Cortex-A15. This feature
>         allows the memory controller to support up to one terabyte
>         (1TB) of DRAM.
> 
> Also:
> 
> http://www.theregister.co.uk/2012/10/24/dell_zinc_arm_server_apache_software/
> 
> talks about 40-bit.
> 
> So it should be possible to use the full 4GBytes of RAM, in theory.

But is it actually using the same page table layout as LPAE or just
something "similar"?

Note that there is also 36-bit addressing in certain CPUs, which is
far less useful in general, but which could actually help here if you
can remap the MMIO registers above 4GB to free up the 32-bit space
for RAM.

	Arnd

^ permalink raw reply

* One of these things (CONFIG_HZ) is not like the others..
From: Thomas Gleixner @ 2013-01-31 21:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKGA1bmpL-PyyMENmwgH9WNmdQ=+1oXrtDo+0OLffdvTChpLFQ@mail.gmail.com>

On Mon, 21 Jan 2013, Matt Sealey wrote:
> And if I wanted to I could register 8 more timers. That seems rather
> excessive, but the ability to use those extra 8 as clock outputs from
> the SoC or otherwise directly use comparators is useful to some
> people, does Linux in general really give a damn about having 8 timers
> of the same quality being available when most systems barely have two
> clocksources anyway (on x86, tsc and hpet - on ARM I guess twd and
> some SoC-specific timer). I dunno how many people might actually want

If you want to use that timers just for delivering arbitrary timer
events, then no. There is no point to have a gazillion of timer
interrupts happening w/o being coordinated. We have a pretty well
structured timer event infrastructure for precise and more timeout
oriented events, which are pretty happy to be served by a single per
cpu event device.

If you want to use the extra timers for other purposes (PWM, timer
triggered DMA transfers, etc...) then they are not in any way related
to the timers/timekeeping core.

Thanks,

	tglx

^ permalink raw reply

* [RFC] arm: use built-in byte swap function
From: Borislav Petkov @ 2013-01-31 21:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130131145947.f62474a0600848df86548b96@freescale.com>

On Thu, Jan 31, 2013 at 02:59:47PM -0600, Kim Phillips wrote:
> - add new ARCH_DEFINES_BUILTIN_BSWAP (see Kconfig help).
>   - if set, generic compiler header does not set HAVE_BUILTIN_BSWAPxx
>   - not too sure about this having to be a new CONFIG_, but it's hard
>     to find a place for it given linux/compiler.h doesn't include any
>     arch-specific files.

Yeah, me neither. It seems to me the whole deal can be simplified even
further without introducing CONFIG_ARCH_DEFINES_BUILTIN_BSWAP.

And, we don't even want to use CONFIG_ARCH_USE_BUILTIN_BSWAP on arm due
to different compiler versions supporting it (correct me if I'm wrong
here) vs the generic thing in include/linux/compiler-gcc4.h which we
want off.

If so, you'd need to simply put the following from below in
arch/arm/include/asm/swab.h

#if GCC_VERSION >= 40600
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#if GCC_VERSION >= 40800
#define __HAVE_BUILTIN_BSWAP16__
#endif /* GCC_VERSION >= 40800 */
#endif /* GCC_VERSION >= 40600 */

and that's it.

Makes sense or am I over-simplifying this?

Thanks.

-- 
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--

^ permalink raw reply

* [PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
From: Matt Porter @ 2013-01-31 21:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <6932828d68394f71ba6df8e6bf608635@DFLE72.ent.ti.com>

On Thu, Jan 31, 2013 at 08:58:39PM +0000, Arnd Bergmann wrote:
> On Thursday 31 January 2013, Matt Porter wrote:
> > On Wed, Jan 30, 2013 at 09:32:58AM +0000, Arnd Bergmann wrote:
> > > On Wednesday 30 January 2013, Matt Porter wrote:
> > > > +               dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
> > > > +               of_dma_controller_register(dev->of_node,
> > > > +                                          of_dma_simple_xlate,
> > > > +                                          &edma_filter_info);
> > > > +       }
> > > 
> > > How do you actually deal with the problem mentioned by Padma, that
> > > the filter function does not know which edma instance it is looking
> > > at? If you assume that there can only be a single edma instance in
> > > the system, that is probably a limitation that should be documented
> > > somewhere, and ideally the probe() function should check for that.
> > 
> > I make an assumption of one edma instance in the system in the case of
> > DT being populated. This is always true right now as the only SoC with
> > two EDMA controllers in existence is Davinci DA850. Until recently,
> > Davinci had no DT support. Given the steady work being done today on DT
> > support for DA850, it'll probably be something needed in 3.10.
> > 
> > I will add a comment and check in probe() to capture this assumption
> > and then plan to update separately to support DA850 booting from DT.
> 
> Ok, sounds good. Hopefully by then we will already have a nicer
> way to write an xlate function that does not rely on a filter
> function.

Yes, it would be nice to avoid what Padma had to do. I should have
mentioned also that the second EDMA on DA850 has no DMA events of
immediate use on it anyway. All the in-kernel users use events on the
first controller, except for the second MMC instance. That's only used
for a wl12xx module on the EVM and that driver has no DT support so it
doesn't matter yet in the DT case. Because of this, DA850 can actually
add EDMA DT support immediately (on top of this series) and add DMA
support to the DT support already posted for the Davinci SPI and MMC
client drivers.

-Matt

^ permalink raw reply

* [PATCH v2 1/2] drivers: net: cpsw: Add helper functions for VLAN ALE implementation
From: Francois Romieu @ 2013-01-31 21:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510A50DE.1010308@ti.com>

Mugunthan V N <mugunthanvnm@ti.com> :
> On 1/31/2013 3:32 AM, Francois Romieu wrote:
[...]
> > It could be factored out.
> Are you mentioning to have static inline function for the above two
> statements above?

Yes. The helper function does not need to be inlined if it does not
save space: this path is not performance critical.

[...]
> >Patch #2 doesn't use the returned status code.
> Will modify the prototype to return void

:o(

The driver should notify the upper layers that the request failed instead
of hiding the stuff under the carpet.

-- 
Ueimor

^ permalink raw reply

* [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
From: Rob Clark @ 2013-01-31 21:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510AD0B8.8020401@gmail.com>

On Thu, Jan 31, 2013 at 2:14 PM, Sebastian Hesselbarth
<sebastian.hesselbarth@gmail.com> wrote:
> On 01/31/2013 03:23 PM, Rob Clark wrote:
>>
>> On Wed, Jan 30, 2013 at 8:23 PM, Sebastian Hesselbarth
>> <sebastian.hesselbarth@gmail.com>  wrote:
>>>
>>> On 01/29/2013 06:23 PM, Rob Clark wrote:
>
> [...]
>>>>
>>>> +
>>>> +/* The TDA9988 series of devices use a paged register scheme.. to
>>>> simplify
>>>> + * things we encode the page # in upper bits of the register #.  To
>>>> read/
>>>> + * write a given register, we need to make sure CURPAGE register is set
>>>> + * appropriately.  Which implies reads/writes are not atomic.  Fun!
>>>> + */
>>>
>>>
>>> Please have a look at regmap-i2c, it also supports paged i2c registers
>>> and will save you _a lot_ of the i2c handling.
>>
>>
>> Yeah, I have looked at it, and will eventually convert over to using
>> it.  The problems at the moment are that I don't really have enough
>> documentation about the chip at the register level to properly use the
>> caching modes, and from my digging through the regmap code it looked
>> like paged regmap + non-caching will result in writes to the page
>> register for every transaction.  That, and a bit of docs or few more
>> examples of using the paging support in regmap would be nice.  For
>> now, I am punting on regmap conversion.
>
>
> Hmm, flipping through the public tda998x sources *sigh* I found a
> quite complete register list that also states if registers are RO or RW.
> Even if you are not using all registers you can still prevent regmap from
> reading/writing to them. But yes, documentation lacks some examples ;)
>
>
>>>> [...]
>>>> +
>>>> +/* Device versions: */
>>>> +#define TDA9989N2                 0x0101
>>>> +#define TDA19989                  0x0201
>>>> +#define TDA19989N2                0x0202
>>>> +#define TDA19988                  0x0301
>>>
>>>
>>>
>>> Maybe split this into device_version/revision? What does N2 stand for
>>> or is this the name NXP uses for that device?
>>
>>
>> The register names are based on the names used in the NXP out-of-tree
>> driver (the 50kloc monstrosity, if you've seen it).. that was pretty
>> much all the register level documentation I had.
>
>
> Yeah, but there is a comment about N2, that says the last bit is "not a
> register bit, but is derived by the driver from the new N5 registers..".
> I guess you will not see that many i2c devices returning you "N2" version
> registers..
>

hmm, maybe you are looking at a different (newer?) version of the nxp
code?  I did not see this.  Perhaps the "n2" stuff isn't too critical,
but I figured it would be nice to see if someone is trying to bring up
a device with one of these parts and I ask them to send me a boot log
with drm traces enabled

>
>>>> [...]
>>>
>>>
>>>> +static void
>>>> +cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val)
>>>> +{
>>>> +       struct i2c_client *client = to_tda998x_priv(encoder)->cec;
>>>> +       uint8_t buf[] = {addr, val};
>>>> +       int ret;
>>>> +
>>>> +       ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
>>>> +       if (ret<   0)
>>>> +               dev_err(&client->dev, "Error %d writing to cec:0x%x\n",
>>>> ret, addr);
>>>> +}
>>>
>>>
>>>
>>> Has there been any decision on how to split/integrate cec from drm?
>>> Or is there display stuff located in cec i2c slave (I see HPD in
>>> ..._detect below)?
>>
>>
>> not sure, but at least in this case it can't really be decoupled.  I
>> need to use the CEC interface for HPD (as you noticed) and also to
>> power up the HDMI bits..
>
>
> Just to make things clearer here, TDA998x ususally has two i2c slaves
> at power-up, 0x70 (hdmi slave) and 0x34 (cec slave). Are you actually
> accessing the cec slave?

yes, as I mentioned, it is not possible to access the hdmi slave
without first accessing the cec slave to enable the hdmi slave

> [...]
>
>>>> +static bool
>>>> +tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
>>>> +                         const struct drm_display_mode *mode,
>>>> +                         struct drm_display_mode *adjusted_mode)
>>>> +{
>>>> +       return true;
>>>> +}
>>>> +
>>>> +static int
>>>> +tda998x_encoder_mode_valid(struct drm_encoder *encoder,
>>>> +                         struct drm_display_mode *mode)
>>>> +{
>>>> +       return MODE_OK;
>>>> +}
>>>
>>>
>>>
>>> At least a note would be helpful to see what callbacks are
>>> not yet done. I guess there will be some kind of mode check
>>> someday?
>>
>>
>> Well, some of these drm will assume the fxn ptrs are not null, so we
>> need something even if it is empty.
>>
>> I suppose there are must be some upper bounds on pixel clock
>> supported, which could perhaps be added some day in _mode_valid().  On
>
>
> Depends what drm expects on mode_valid or mode_fixup, I haven't dug into
> drm encoders, yet. But usually for HDMI/DVI you will only choose between
> modes supplied by monitor EDID and not choose something "close". Anyway,
> I just think a note about stuff that is not yet working is helpful.
>

I would put a note if there was something that was not working about it ;-)

Currently there is no need to validate or fixup the mode, which is why
these functions are empty.  DRM has hooks for the drivers at many
point.  Not always are all of them needed, in this case they are not
needed.

>
>> the device I am working on, the limiting factor is the crtc (upstream
>> of the encoder), so I haven't really needed this yet.  I expect that
>> as people start using this on some other devices, we'll come across
>> some enhancements needed, some places where we need to add some
>> configuration, etc.  I cannot really predict exactly what is needed,
>> so I prefer just to put the driver out there in some form, and then
>> add it it as needed.  So, I wouldn't really say that these functions
>> are "TODO", but I also wouldn't say that we won't find some reason to
>> add some code there at some point.
>
>
> Or put it in staging?
>

that won't work too well if we end up having to add a header and
config info struct to be passed in from the driver using the encoder
slave

>
>>>> [...]
>>>>
>>>> +static enum drm_connector_status
>>>> +tda998x_encoder_detect(struct drm_encoder *encoder,
>>>> +                     struct drm_connector *connector)
>>>> +{
>>>> +       uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV);
>>>> +       return (val&   CEC_RXSHPDLEV_HPD) ? connector_status_connected :
>>>> +                       connector_status_disconnected;
>>>> +}
>>>
>>>
>>>
>>> This is where cec slave gets called from hdmi i2c driver. Any chance
>>> there is HPD status in hdmi registers, too?
>>
>>
>> Not that I know of.  But like I mentioned, we also need to use the CEC
>> interface just to talk to the HDMI interface.  Before setting ENAMODS
>> reg via cec address, the hdmi address won't even show up (for ex, on
>> i2cdetect).
>
>
> Again, I quickly checked the public sources. The cec slave looks like is
> only for cec communication, i.e. actually sending/receiving messages.
> But from your patch it isn't even clear to me, when you access hdmi or
> cec slave as you are bypassing i2c client subsystem somehow.
>

The cec_read()/cec_write() fxns use the cec i2c_client ptr.  They are
accessing the cec slave.  I'm not really sure how that is unclear.
There is not really anything being bypassed here.

Anyways, like I mentioned, the cec slave needs to be accessed before
the hdmi slave can be accessed at all.

>
>> Maybe there is some way that this code should register some interface
>> with CEC driver/subsystem?  (Is there such a thing?  I am not really
>> CEC expert.)  But I don't think there is any way to completely split
>> it out.
>
>
> When speaking about CEC subsystem you mean sending/receiving cec messages
> and the corresponding kernel API? That can come later, for now everything
> this driver needs can IMHO depend on EDID, i.e. DVI-style, only.
> CEC communication can come later.
>

Yes, presumably other than internal use (enabling hdmi subsystem, hpd,
etc), the other interesting use for CEC would be to enable
sending/receiving CEC messages.  If there is some kernel subsystem for
this, presumably the i2c encoder slave would need to register some
sort of cec_adapter with this subsystem.  I haven't really concerned
myself with this too much.  I expect enabling hdmi audio is probably
the more interesting next-feature.

>
>>>> +/* I2C driver functions */
>>>> +
>>>> +static int
>>>> +tda998x_probe(struct i2c_client *client, const struct i2c_device_id
>>>> *id)
>>>> +{
>>>> +       return 0;
>>>> +}
>>>> +
>>>> +static int
>>>> +tda998x_remove(struct i2c_client *client)
>>>> +{
>>>> +       return 0;
>>>> +}
>>>
>>>
>>>
>>> Hmm, empty _probe and _remove? Maybe these should get some code
>>> from _init below?
>>
>>
>> naw, they aren't really used for drm i2c encoder slaves.
>
>
> Well, if you use a i2c_client_addr != 0 below, the i2c subsystem will only
> bother you if it finds e.g. device 0x70 on an i2c bus. So they should be
> used. The drm API must be clear about what should happen in encoder_init
> and encoder_probe.

btw, if you haven't already, please look at drm_i2c_encoder_init() to
see how the i2c encoder slave is loaded and connected to it's master
driver.

I suppose, in theory I could read the device version information in
the _probe().  But this can't even be read until accessing the CEC
interface to enable hdmi.  So I end up reading the revision and
potentially failing later.  But for this hw, there isn't really a
better way because of the goofy way that the hdmi interface cannot be
accessed until after it is switched on via cec interface.

>
>>>> +static int
>>>> +tda998x_encoder_init(struct i2c_client *client,
>>>> +                   struct drm_device *dev,
>>>> +                   struct drm_encoder_slave *encoder_slave)
>>>> +{
>>>> +       struct drm_encoder *encoder =&encoder_slave->base;
>>>>
>>>> +       struct tda998x_priv *priv;
>>>> +
>>>> +       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>>>> +       if (!priv)
>>>> +               return -ENOMEM;
>>>> +
>>>> +       priv->current_page = 0;
>>>> +       priv->cec = i2c_new_dummy(client->adapter, 0x34);
>>>> +       priv->dpms = DRM_MODE_DPMS_OFF;
>>>> +
>>>> +       encoder_slave->slave_priv = priv;
>>>> +       encoder_slave->slave_funcs =&tda998x_encoder_funcs;
>>>> +
>>>> +       /* wake up the device: */
>>>> +       cec_write(encoder, REG_CEC_ENAMODS,
>>>> +                       CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI);
>>>> +
>>>> +       tda998x_reset(encoder);
>>>> +
>>>> +       /* read version: */
>>>> +       priv->rev = reg_read(encoder, REG_VERSION_LSB) |
>>>> +                       reg_read(encoder, REG_VERSION_MSB)<<   8;
>>>> +
>>>> +       /* mask off feature bits: */
>>>> +       priv->rev&= ~0x30; /* not-hdcp and not-scalar bit */
>>>
>>>
>>>
>>> If revision register contains features, why not save them for later
>>> driver improvements?
>>>
>>
>> can be added later if the need arises.  I prefer to leave out code
>> that only might be used later.. otherwise it is a good way to
>> accumulate cruft.
>
>
> True, but magic masking (~0x30) and some comments don't help either.
>
>
>>>
>>>> +       switch (priv->rev) {
>>>> +       case TDA9989N2:  dev_info(dev->dev, "found TDA9989 n2");  break;
>>>> +       case TDA19989:   dev_info(dev->dev, "found TDA19989");    break;
>>>> +       case TDA19989N2: dev_info(dev->dev, "found TDA19989 n2"); break;
>>>> +       case TDA19988:   dev_info(dev->dev, "found TDA19988");    break;
>>>> +       default:
>>>> +               DBG("found unsupported device: %04x", priv->rev);
>>>> +               goto fail;
>>>> +       }
>>>
>>>
>>>
>>> I think printing revision is sufficient, no user will care about the
>>> actual device or revision.
>>>
>>>
>>>> +       /* after reset, enable DDC: */
>>>> +       reg_write(encoder, REG_DDC_DISABLE, 0x00);
>>>> +
>>>> +       /* set clock on DDC channel: */
>>>> +       reg_write(encoder, REG_TX3, 39);
>>>
>>>
>>>
>>> This should be kept disabled as long as there is no monitor attached
>>> (HPD!)
>>>
>>
>> The sequence is based on NXP's driver.. I'll have to go back and
>> check, but IIRC there were a few things I had to turn on just to make
>> HPD work in the first place.
>
>
> Hmm, I have seen a note about issues with some monitors that expect
> ddc clock to be stable very early. And this looks like the NXP proposed
> workaround to always clock ddc - but it tells nothing about the reason
> and more important the note from NXP clearly puts some restrictions on
> how hdmi tx needs to be clocked by pixclk. Can you ensure a stable pixclk
> at this point at all?
>

In my experience it is not depending on pixel clock from crtc.  Or at
least it isn't turned on at this point and doesn't seem to cause
issues.  The drm core will not enable the crtc until long after the
edid is read.

>
>> Ofc, if there were actually some decent docs about the part, it would
>> be a bit easier to know what is actually required and what is not.  So
>> I don't claim everything in it's current form is optimal.
>
>
> I know, everybody knows I guess. But that is what this list is for,
> discussing when a driver is ready to be mainlined. And without regmap
> and proper i2c client handling, I have a feeling that it is not close.
>

There is not really anything wrong with the i2c client handling, or
rather it works the way that drm i2c encoder slave infrastructure
expects.

regmap, I'd partially agree..  I'd prefer to use it.  But it doesn't
really bring that much benefit and the requirements are a bit steep
considering what is known / not-known about this hw.

>
>>>> +       /* if necessary, disable multi-master: */
>>>> +       if (priv->rev == TDA19989)
>>>> +               reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM);
>>>> +
>>>> +       cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL,
>>>> +                       CEC_FRO_IM_CLK_CTRL_GHOST_DIS |
>>>> CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
>>>> +
>>>> +       return 0;
>>>> +
>>>> +fail:
>>>> +       /* if encoder_init fails, the encoder slave is never registered,
>>>> +        * so cleanup here:
>>>> +        */
>>>> +       if (priv->cec)
>>>> +               i2c_unregister_device(priv->cec);
>>>> +       kfree(priv);
>>>> +       encoder_slave->slave_priv = NULL;
>>>> +       encoder_slave->slave_funcs = NULL;
>>>> +       return -ENXIO;
>>>> +}
>>>> +
>>>> +static struct i2c_device_id tda998x_ids[] = {
>>>> +       { "tda998x", 0 },
>>>> +       { }
>>>> +};
>>>> +MODULE_DEVICE_TABLE(i2c, tda998x_ids);
>>>
>>>
>>>
>>> Shouldn't the above carry the hdmi core i2c address at least?
>>>
>>
>> no, it should come from the user of the encoder slave.  Actually the
>> CEC address should too, but current drm i2c encoder slave code sort of
>> assumes the device just has a single address
>
>
> Hmm, that is a limitation for sure. Well I checked drm_encoder_slave and
> it is calling i2c_register_driver directly. Passing a valid i2c slave
> address
> will work here.

note that the hdmi interface cannot be probed until after enabling it
via cec interface

BR,
-R

> For the cec i2c slave, we at least know that it is on the same i2c bus
> and can probe it during _init or _probe ourselves.
>
> Sebastian

^ permalink raw reply

* [RFC PATCH 0/4] Add support for LZ4-compressed kernels
From: H. Peter Anvin @ 2013-01-31 21:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301301326530.6300@xanadu.home>

On 01/30/2013 10:33 AM, Nicolas Pitre wrote:
>>
>> The only concern I have with that is if someone paints themselves into a
>> corner and absolutely wants, say, LZO.
> 
> That would be hard to justify given that the kernel provides its own 
> decompressor code, making the compression format transparent to 
> bootloaders, etc.  And no one should be poking into the compressed 
> zImage.
> 

Some utterly weird things like the Xen domain builder do that, because
they have to.  That is why we explicitly document that the payload is
ELF and how to access it in the bzImage spec.

	-hpa

^ permalink raw reply

* ixp4xx eth broken in 3.7.0/3.8-rc5?
From: Krzysztof Halasa @ 2013-01-31 21:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20744.25884.660535.514911@pilspetsen.it.uu.se>

Mikael Pettersson <mikpe@it.uu.se> writes:

>  > When I try to update my ixp4xx machine to a 3.8-rc5 kernel it boots
>  > Ok but the network (CONFIG_IXP4XX_ETH=y) fails to come up, with the
>  > following in the kernel log:
>  >
>  > net eth0: coherent DMA mask is unset
>
> A git bisect identified the following as the culprit:
>
>  > From 1a4901177574083c35fafc24c4d151c2a7c7647c Mon Sep 17 00:00:00 2001
>  > From: Xi Wang <xi.wang@gmail.com>
>  > Date: Sat, 17 Nov 2012 20:25:09 +0000
>  > Subject: [PATCH] ixp4xx_eth: avoid calling dma_pool_create() with NULL dev
>  >
>  > Use &port->netdev->dev instead of NULL since dma_pool_create() doesn't
>  > allow NULL dev.

IIRC NULL dev in dma_pool_create() meant the usual IXP4xx mask (64MB)
was used. Perhaps devices don't get a mask by default anymore. I will
look at this in few days.
-- 
Krzysztof Halasa

^ permalink raw reply

* [PATCH v4 00/13] ARM LPAE Fixes - Part 1
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

This series is a repost of the LPAE related changes in preparation for the
introduction of the Keystone sub-architecture.  The original series has now
been split, and this particular series excludes the earlier changes to the
runtime code patching implementation.  Earlier versions of this series can be
found at [1], [2], [3] and [4].

These patches are also available in git:
git://git.kernel.org/pub/scm/linux/kernel/git/cchemparathy/linux-keystone.git upstream/keystone-lpae-v4

[1] http://comments.gmane.org/gmane.linux.kernel/1341497
[2] http://comments.gmane.org/gmane.linux.kernel/1332069
[3] http://comments.gmane.org/gmane.linux.kernel/1356716
[4] http://comments.gmane.org/gmane.linux.kernel/1362529

Series changelog:

[01/13] ARM: LPAE: use signed arithmetic for mask
[02/13] ARM: LPAE: use phys_addr_t in alloc_init_pud()
[03/13] ARM: LPAE: use phys_addr_t in free_memmap()
  (v4)	unchanged from v3
  (v3)	unchanged from v2
  (v2)	unchanged from v1

[04/13] ARM: LPAE: use phys_addr_t for initrd location
  (v4)	unchanged from v3
  (v3)	unchanged from v2
  (v2)	revert to unsigned long for initrd size

[05/13] ARM: LPAE: use phys_addr_t in switch_mm()
  (v4)  collapse shift and or into a single instruction
  (v3)	remove unnecessary handling for !LPAE in proc-v7-3level
  (v2)	use phys_addr_t instead of u64 in switch_mm()
  (v2)	revert on changes to v6 and v7-2level
  (v2)	fix register mapping for big-endian in v7-3level

[06/13] ARM: LPAE: use 64-bit accessors for TTBR registers
  (v4)  remove unnecessary condition code clobber
  (v3)	remove unnecessary condition code clobber
  (v2)	restore comment in cpu_set_reserved_ttbr0()

[07/13] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for
  (v4)	unchanged from v3
  (v3)	unchanged from v2
  (v2)	unchanged from v1

[08/13] ARM: LPAE: factor out T1SZ and TTBR1 computations
  (v4)  cleanup and move code comments
  (v3)	unchanged from v2
  (v2)	unchanged from v1

[09/13] ARM: LPAE: accomodate >32-bit addresses for page
  (v4)	unchanged from v3
  (v3)	unchanged from v2
  (v2)	apply arch_pgd_shift only on lpae
  (v2)	move arch_pgd_shift definition to asm/memory.h
  (v2)	revert on changes to non-lpae procs
  (v2)	add check to ensure that the pgd physical address is aligned at an
	ARCH_PGD_SHIFT boundary

[10/13] ARM: mm: use physical addresses in highmem sanity
[11/13] ARM: mm: cleanup checks for membank overlap with
[12/13] ARM: mm: clean up membank size limit checks
  (v4)	unchanged from v3
  (v3)	unchanged from v2
  (v2)	unchanged from v1

[13/13] ARM: fix type of PHYS_PFN_OFFSET to unsigned long
  (v4)	introduced here


Cyril Chemparathy (10):
  ARM: LPAE: use signed arithmetic for mask definitions
  ARM: LPAE: use phys_addr_t in switch_mm()
  ARM: LPAE: use 64-bit accessors for TTBR registers
  ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
  ARM: LPAE: factor out T1SZ and TTBR1 computations
  ARM: LPAE: accomodate >32-bit addresses for page table base
  ARM: mm: use physical addresses in highmem sanity checks
  ARM: mm: cleanup checks for membank overlap with vmalloc area
  ARM: mm: clean up membank size limit checks
  ARM: fix type of PHYS_PFN_OFFSET to unsigned long

Vitaly Andrianov (3):
  ARM: LPAE: use phys_addr_t in alloc_init_pud()
  ARM: LPAE: use phys_addr_t in free_memmap()
  ARM: LPAE: use phys_addr_t for initrd location

 arch/arm/include/asm/memory.h               |   20 +++++++++-
 arch/arm/include/asm/page.h                 |    2 +-
 arch/arm/include/asm/pgtable-3level-hwdef.h |   20 ++++++++++
 arch/arm/include/asm/pgtable-3level.h       |    6 +--
 arch/arm/include/asm/proc-fns.h             |   26 +++++++++----
 arch/arm/kernel/head.S                      |   10 ++---
 arch/arm/kernel/smp.c                       |   11 +++++-
 arch/arm/mm/context.c                       |    9 +----
 arch/arm/mm/init.c                          |   19 +++++-----
 arch/arm/mm/mmu.c                           |   49 +++++++++----------------
 arch/arm/mm/proc-v7-3level.S                |   53 ++++++++++++++-------------
 11 files changed, 132 insertions(+), 93 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v4 01/13] ARM: LPAE: use signed arithmetic for mask definitions
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch applies to PAGE_MASK, PMD_MASK, and PGDIR_MASK, where forcing
unsigned long math truncates the mask at the 32-bits.  This clearly does bad
things on PAE systems.

This patch fixes this problem by defining these masks as signed quantities.
We then rely on sign extension to do the right thing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/include/asm/page.h           |    2 +-
 arch/arm/include/asm/pgtable-3level.h |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 812a494..6363f3d 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -13,7 +13,7 @@
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT		12
 #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
+#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index a3f3792..554f6d3 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -48,16 +48,16 @@
 #define PMD_SHIFT		21
 
 #define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE-1))
+#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
 #define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))
 
 /*
  * section address mask and size definitions.
  */
 #define SECTION_SHIFT		21
 #define SECTION_SIZE		(1UL << SECTION_SHIFT)
-#define SECTION_MASK		(~(SECTION_SIZE-1))
+#define SECTION_MASK		(~((1 << SECTION_SHIFT) - 1))
 
 #define USER_PTRS_PER_PGD	(PAGE_OFFSET / PGDIR_SIZE)
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 02/13] ARM: LPAE: use phys_addr_t in alloc_init_pud()
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the alloc_init_pud() function to use phys_addr_t instead of
unsigned long when passing in the phys argument.

This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a (ARM:
pgtable: use phys_addr_t for physical addresses), which applied similar changes
elsewhere in the ARM memory management code.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/mm/mmu.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9f06102..ef43689 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -612,7 +612,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-	unsigned long end, unsigned long phys, const struct mem_type *type)
+				  unsigned long end, phys_addr_t phys,
+				  const struct mem_type *type)
 {
 	pud_t *pud = pud_offset(pgd, addr);
 	unsigned long next;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 03/13] ARM: LPAE: use phys_addr_t in free_memmap()
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

From: Vitaly Andrianov <vitalya@ti.com>

The free_memmap() was mistakenly using unsigned long type to represent
physical addresses.  This breaks on PAE systems where memory could be placed
above the 32-bit addressible limit.

This patch fixes this function to properly use phys_addr_t instead.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/mm/init.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index ad722f1..1c5151a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -457,7 +457,7 @@ static inline void
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct page *start_pg, *end_pg;
-	unsigned long pg, pgend;
+	phys_addr_t pg, pgend;
 
 	/*
 	 * Convert start_pfn/end_pfn to a struct page pointer.
@@ -469,8 +469,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 	 * Convert to physical addresses, and
 	 * round start upwards and end downwards.
 	 */
-	pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
-	pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
+	pg = PAGE_ALIGN(__pa(start_pg));
+	pgend = __pa(end_pg) & PAGE_MASK;
 
 	/*
 	 * If there are free pages between these,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 04/13] ARM: LPAE: use phys_addr_t for initrd location
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

From: Vitaly Andrianov <vitalya@ti.com>

This patch fixes the initrd setup code to use phys_addr_t instead of assuming
32-bit addressing.  Without this we cannot boot on systems where initrd is
located above the 4G physical address limit.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/mm/init.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 1c5151a..87ee0ec 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -36,12 +36,13 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
+static phys_addr_t phys_initrd_start __initdata = 0;
 static unsigned long phys_initrd_size __initdata = 0;
 
 static int __init early_initrd(char *p)
 {
-	unsigned long start, size;
+	phys_addr_t start;
+	unsigned long size;
 	char *endp;
 
 	start = memparse(p, &endp);
@@ -347,14 +348,14 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (phys_initrd_size &&
 	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size &&
 	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size) {
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 05/13] ARM: LPAE: use phys_addr_t in switch_mm()
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch modifies the switch_mm() processor functions to use phys_addr_t.
On LPAE systems, we now honor the upper 32-bits of the physical address that
is being passed in, and program these into TTBR as expected.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/include/asm/proc-fns.h |    4 ++--
 arch/arm/mm/proc-v7-3level.S    |   16 ++++++++++++----
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index f3628fb..75b5f14 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -60,7 +60,7 @@ extern struct processor {
 	/*
 	 * Set the page table
 	 */
-	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+	void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm);
 	/*
 	 * Set a possibly extended PTE.  Non-extended PTEs should
 	 * ignore 'ext'.
@@ -82,7 +82,7 @@ extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
 #ifdef CONFIG_ARM_LPAE
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 7b56386..e64be21 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -39,6 +39,14 @@
 #define TTB_FLAGS_SMP	(TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA)
 #define PMD_FLAGS_SMP	(PMD_SECT_WBWA|PMD_SECT_S)
 
+#ifndef __ARMEB__
+#  define rpgdl	r0
+#  define rpgdh	r1
+#else
+#  define rpgdl	r1
+#  define rpgdh	r0
+#endif
+
 /*
  * cpu_v7_switch_mm(pgd_phys, tsk)
  *
@@ -47,10 +55,10 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
-	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	and	r3, r1, #0xff
-	mov	r3, r3, lsl #(48 - 32)		@ ASID
-	mcrr	p15, 0, r0, r3, c2		@ set TTB 0
+	ldr	r2, [r2, #MM_CONTEXT_ID]		@ get mm->context.id
+	and	r2, r2, #0xff				@ ASID
+	orr	rpgdh, rpgdh, r2, lsl #(48 - 32)	@ upper 32-bits of pgd
+	mcrr	p15, 0, rpgdl, rpgdh, c2		@ set TTB 0
 	isb
 #endif
 	mov	pc, lr
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 06/13] ARM: LPAE: use 64-bit accessors for TTBR registers
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch adds TTBR accessor macros, and modifies cpu_get_pgd() and
the LPAE version of cpu_set_reserved_ttbr0() to use these instead.

In the process, we also fix these functions to correctly handle cases
where the physical address lies beyond the 4G limit of 32-bit addressing.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/include/asm/proc-fns.h |   22 +++++++++++++++++-----
 arch/arm/mm/context.c           |    9 ++-------
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 75b5f14..1c3cf94 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -116,13 +116,25 @@ extern void cpu_resume(void);
 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
 
 #ifdef CONFIG_ARM_LPAE
+
+#define cpu_get_ttbr(nr)					\
+	({							\
+		u64 ttbr;					\
+		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
+			: "=r" (ttbr));				\
+		ttbr;						\
+	})
+
+#define cpu_set_ttbr(nr, val)					\
+	do {							\
+		u64 ttbr = val;					\
+		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
+			: : "r" (ttbr));			\
+	} while (0)
+
 #define cpu_get_pgd()	\
 	({						\
-		unsigned long pg, pg2;			\
-		__asm__("mrrc	p15, 0, %0, %1, c2"	\
-			: "=r" (pg), "=r" (pg2)		\
-			:				\
-			: "cc");			\
+		u64 pg = cpu_get_ttbr(0);		\
 		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
 		(pgd_t *)phys_to_virt(pg);		\
 	})
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index bc4a5e9..7c17ff8 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -20,6 +20,7 @@
 #include <asm/smp_plat.h>
 #include <asm/thread_notify.h>
 #include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
 
 /*
  * On ARMv6, we have the following structure in the Context ID:
@@ -52,17 +53,11 @@ static cpumask_t tlb_flush_pending;
 #ifdef CONFIG_ARM_LPAE
 static void cpu_set_reserved_ttbr0(void)
 {
-	unsigned long ttbl = __pa(swapper_pg_dir);
-	unsigned long ttbh = 0;
-
 	/*
 	 * Set TTBR0 to swapper_pg_dir which contains only global entries. The
 	 * ASID is set to 0.
 	 */
-	asm volatile(
-	"	mcrr	p15, 0, %0, %1, c2		@ set TTBR0\n"
-	:
-	: "r" (ttbl), "r" (ttbh));
+	cpu_set_ttbr(0, __pa(swapper_pg_dir));
 	isb();
 }
 #else
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 07/13] ARM: LPAE: define ARCH_LOW_ADDRESS_LIMIT for bootmem
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch adds an architecture defined override for ARCH_LOW_ADDRESS_LIMIT.
On PAE systems, the absence of this override causes bootmem to incorrectly
limit itself to 32-bit addressable physical memory.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/memory.h |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 73cf03a..8825abb 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -275,6 +275,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
 
+#define ARCH_LOW_ADDRESS_LIMIT		PHYS_MASK
+
 #endif
 
 #include <asm-generic/memory_model.h>
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 08/13] ARM: LPAE: factor out T1SZ and TTBR1 computations
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch moves the TTBR1 offset calculation and the T1SZ calculation out
of the TTB setup assembly code.  This should not affect functionality in
any way, but improves code readability as well as readability of subsequent
patches in this series.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/include/asm/pgtable-3level-hwdef.h |   20 ++++++++++++++++++
 arch/arm/mm/proc-v7-3level.S                |   29 ++++++++-------------------
 2 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index d795282..e9d70a3 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -74,4 +74,24 @@
 #define PHYS_MASK_SHIFT		(40)
 #define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)
 
+/*
+ * TTBR0/TTBR1 split (PAGE_OFFSET):
+ *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
+ *   0x80000000: T0SZ = 0, T1SZ = 1
+ *   0xc0000000: T0SZ = 0, T1SZ = 2
+ *
+ * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
+ * booting secondary CPUs would end up using TTBR1 for the identity
+ * mapping set up in TTBR0.
+ */
+#if defined CONFIG_VMSPLIT_2G
+#define TTBR1_OFFSET	16			/* skip two L1 entries */
+#elif defined CONFIG_VMSPLIT_3G
+#define TTBR1_OFFSET	(4096 * (1 + 3))	/* only L2, skip pgd + 3*pmd */
+#else
+#define TTBR1_OFFSET	0
+#endif
+
+#define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
+
 #endif
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index e64be21..e6576f5 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -113,7 +113,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
-	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET? (branch below)
+	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET?
 	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
 	orr	\tmp, \tmp, #TTB_EAE
 	ALT_SMP(orr	\tmp, \tmp, #TTB_FLAGS_SMP)
@@ -121,27 +121,14 @@ ENDPROC(cpu_v7_set_pte_ext)
 	ALT_SMP(orr	\tmp, \tmp, #TTB_FLAGS_SMP << 16)
 	ALT_UP(orr	\tmp, \tmp, #TTB_FLAGS_UP << 16)
 	/*
-	 * TTBR0/TTBR1 split (PAGE_OFFSET):
-	 *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
-	 *   0x80000000: T0SZ = 0, T1SZ = 1
-	 *   0xc0000000: T0SZ = 0, T1SZ = 2
-	 *
-	 * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
-	 * booting secondary CPUs would end up using TTBR1 for the identity
-	 * mapping set up in TTBR0.
+	 * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above),
+	 * otherwise booting secondary CPUs would end up using TTBR1 for the
+	 * identity mapping set up in TTBR0.
 	 */
-	bhi	9001f				@ PHYS_OFFSET > PAGE_OFFSET?
-	orr	\tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ
-#if defined CONFIG_VMSPLIT_2G
-	/* PAGE_OFFSET == 0x80000000, T1SZ == 1 */
-	add	\ttbr1, \ttbr1, #1 << 4		@ skip two L1 entries
-#elif defined CONFIG_VMSPLIT_3G
-	/* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */
-	add	\ttbr1, \ttbr1, #4096 * (1 + 3)	@ only L2 used, skip pgd+3*pmd
-#endif
-	/* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */
-9001:	mcr	p15, 0, \tmp, c2, c0, 2		@ TTB control register
-	mcrr	p15, 1, \ttbr1, \zero, c2	@ load TTBR1
+	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
+	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
 	.endm
 
 	__CPUINIT
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 09/13] ARM: LPAE: accomodate >32-bit addresses for page table base
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch redefines the early boot time use of the R4 register to steal a few
low order bits (ARCH_PGD_SHIFT bits) on LPAE systems.  This allows for up to
38-bit physical addresses.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 arch/arm/include/asm/memory.h |   16 ++++++++++++++++
 arch/arm/kernel/head.S        |   10 ++++------
 arch/arm/kernel/smp.c         |   11 +++++++++--
 arch/arm/mm/proc-v7-3level.S  |    8 ++++++++
 4 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 8825abb..f3a7f76 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -18,6 +18,8 @@
 #include <linux/types.h>
 #include <linux/sizes.h>
 
+#include <asm/cache.h>
+
 #ifdef CONFIG_NEED_MACH_MEMORY_H
 #include <mach/memory.h>
 #endif
@@ -141,6 +143,20 @@
 #define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
 #define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))
 
+/*
+ * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
+ * around in head.S and proc-*.S are shifted by this amount, in order to
+ * leave spare high bits for systems with physical address extension.  This
+ * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
+ * gives us about 38-bits or so.
+ */
+#ifdef CONFIG_ARM_LPAE
+#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
+#else
+#define ARCH_PGD_SHIFT		0
+#endif
+#define ARCH_PGD_MASK		((1 << ARCH_PGD_SHIFT) - 1)
+
 #ifndef __ASSEMBLY__
 
 /*
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 4eee351..916af3e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -156,7 +156,7 @@ ENDPROC(stext)
  *
  * Returns:
  *  r0, r3, r5-r7 corrupted
- *  r4 = physical page table address
+ *  r4 = page table (see ARCH_PGD_SHIFT in asm/memory.h)
  */
 __create_page_tables:
 	pgtbl	r4, r8				@ page table address
@@ -310,6 +310,7 @@ __create_page_tables:
 #endif
 #ifdef CONFIG_ARM_LPAE
 	sub	r4, r4, #0x1000		@ point to the PGD table
+	mov	r4, r4, lsr #ARCH_PGD_SHIFT
 #endif
 	mov	pc, lr
 ENDPROC(__create_page_tables)
@@ -387,7 +388,7 @@ __secondary_data:
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
- *  r4  = page table pointer
+ *  r4  = page table (see ARCH_PGD_SHIFT in asm/memory.h)
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  */
@@ -406,10 +407,7 @@ __enable_mmu:
 #ifdef CONFIG_CPU_ICACHE_DISABLE
 	bic	r0, r0, #CR_I
 #endif
-#ifdef CONFIG_ARM_LPAE
-	mov	r5, #0
-	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
-#else
+#ifndef CONFIG_ARM_LPAE
 	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 84f4cbf..042e12d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -78,6 +78,13 @@ void __init smp_set_ops(struct smp_operations *ops)
 		smp_ops = *ops;
 };
 
+static unsigned long get_arch_pgd(pgd_t *pgd)
+{
+	phys_addr_t pgdir = virt_to_phys(pgd);
+	BUG_ON(pgdir & ARCH_PGD_MASK);
+	return pgdir >> ARCH_PGD_SHIFT;
+}
+
 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
@@ -87,8 +94,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * its stack and the page tables.
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
-	secondary_data.pgdir = virt_to_phys(idmap_pgd);
-	secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
+	secondary_data.pgdir = get_arch_pgd(idmap_pgd);
+	secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir);
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
 	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index e6576f5..c02c1cc 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -113,6 +113,7 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
+	mov	\tmp, \tmp, lsr #ARCH_PGD_SHIFT
 	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET?
 	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
 	orr	\tmp, \tmp, #TTB_EAE
@@ -127,8 +128,15 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
 	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	mov	\tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT		@ lower bits
 	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
 	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mov	\tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT		@ lower bits
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
 	__CPUINIT
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 10/13] ARM: mm: use physical addresses in highmem sanity checks
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch modifies the highmem sanity checking code to use physical addresses
instead.  This change eliminates the wrap-around problems associated with the
original virtual address based checks, and this simplifies the code a bit.

The one constraint imposed here is that low physical memory must be mapped in
a monotonically increasing fashion if there are multiple banks of memory,
i.e., x < y must => pa(x) < pa(y).

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/mm/mmu.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index ef43689..e8875cb 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -929,6 +929,7 @@ phys_addr_t arm_lowmem_limit __initdata = 0;
 void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
+	phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
@@ -938,8 +939,7 @@ void __init sanity_check_meminfo(void)
 			highmem = 1;
 
 #ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET)
+		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
@@ -948,8 +948,8 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && __va(bank->start) < vmalloc_min &&
-		    bank->size > vmalloc_min - __va(bank->start)) {
+		if (!highmem && bank->start < vmalloc_limit &&
+		    bank->size > vmalloc_limit - bank->start) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -958,12 +958,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_min - __va(bank->start);
-				bank[1].start = __pa(vmalloc_min - 1) + 1;
+				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_min - __va(bank->start);
+			bank->size = vmalloc_limit - bank->start;
 		}
 #else
 		bank->highmem = highmem;
@@ -983,8 +983,7 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would entirely overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET) {
+		if (bank->start >= vmalloc_limit) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
 			       "(vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
@@ -996,9 +995,8 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start + bank->size - 1) >= vmalloc_min ||
-		    __va(bank->start + bank->size - 1) <= __va(bank->start)) {
-			unsigned long newsize = vmalloc_min - __va(bank->start);
+		if (bank->start + bank->size > vmalloc_limit)
+			unsigned long newsize = vmalloc_limit - bank->start;
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 11/13] ARM: mm: cleanup checks for membank overlap with vmalloc area
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

On Keystone platforms, physical memory is entirely outside the 32-bit
addressible range.  Therefore, the (bank->start > ULONG_MAX) check below marks
the entire system memory as highmem, and this causes unpleasentness all over.

This patch eliminates the extra bank start check (against ULONG_MAX) by
checking bank->start against the physical address corresponding to vmalloc_min
instead.

In the process, this patch also cleans up parts of the highmem sanity check
code by removing what has now become a redundant check for banks that entirely
overlap with the vmalloc range.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/mm/mmu.c |   19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e8875cb..85ed732 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -935,15 +935,12 @@ void __init sanity_check_meminfo(void)
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
 
-		if (bank->start > ULONG_MAX)
-			highmem = 1;
-
-#ifdef CONFIG_HIGHMEM
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
 
 		bank->highmem = highmem;
 
+#ifdef CONFIG_HIGHMEM
 		/*
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
@@ -966,8 +963,6 @@ void __init sanity_check_meminfo(void)
 			bank->size = vmalloc_limit - bank->start;
 		}
 #else
-		bank->highmem = highmem;
-
 		/*
 		 * Highmem banks not allowed with !CONFIG_HIGHMEM.
 		 */
@@ -980,18 +975,6 @@ void __init sanity_check_meminfo(void)
 		}
 
 		/*
-		 * Check whether this memory bank would entirely overlap
-		 * the vmalloc area.
-		 */
-		if (bank->start >= vmalloc_limit) {
-			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
-			       "(vmalloc region overlap).\n",
-			       (unsigned long long)bank->start,
-			       (unsigned long long)bank->start + bank->size - 1);
-			continue;
-		}
-
-		/*
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 12/13] ARM: mm: clean up membank size limit checks
From: Cyril Chemparathy @ 2013-01-31 21:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359669512-31276-1-git-send-email-cyril@ti.com>

This patch cleans up the highmem sanity check code by simplifying the range
checks with a pre-calculated size_limit.  This patch should otherwise have no
functional impact on behavior.

This patch also removes a redundant (bank->start < vmalloc_limit) check, since
this is already covered by the !highmem condition.

Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/mm/mmu.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 85ed732..2a02ff0 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -933,10 +933,15 @@ void __init sanity_check_meminfo(void)
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
+		phys_addr_t size_limit;
+
 		*bank = meminfo.bank[i];
+		size_limit = bank->size;
 
 		if (bank->start >= vmalloc_limit)
 			highmem = 1;
+		else
+			size_limit = vmalloc_limit - bank->start;
 
 		bank->highmem = highmem;
 
@@ -945,8 +950,7 @@ void __init sanity_check_meminfo(void)
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && bank->start < vmalloc_limit &&
-		    bank->size > vmalloc_limit - bank->start) {
+		if (!highmem && bank->size > size_limit) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -955,12 +959,12 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_limit - bank->start;
+				bank[1].size -= size_limit;
 				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_limit - bank->start;
+			bank->size = size_limit;
 		}
 #else
 		/*
@@ -978,14 +982,13 @@ void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (bank->start + bank->size > vmalloc_limit)
-			unsigned long newsize = vmalloc_limit - bank->start;
+		if (bank->size > size_limit) {
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
 			       (unsigned long long)bank->start + bank->size - 1,
-			       (unsigned long long)bank->start + newsize - 1);
-			bank->size = newsize;
+			       (unsigned long long)bank->start + size_limit - 1);
+			bank->size = size_limit;
 		}
 #endif
 		if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox