Port from Gus' wm8505-2.6.29 to android-2.6.35

78 views
Skip to first unread message

ginge

unread,
Aug 18, 2010, 3:26:38 PM8/18/10
to VT8500/WM8505 Linux Kernel
First of all, hello!

As per subject, I have done some kernel porting...

Seems I can't post files yet, so for now here is a link to the diff:

http://headfuzz.co.uk/files/eken/2.6.35-eken-m001.diff

I can't guarantee it will work, it might eat your dog etc.
Also this port took me approx 1 day, so it is more than rough. The new
ABI port to MTD is terrible, and I am ashamed of myself ;)


-------------------------
WonderMedia wm8505-2.6.29 -gus to android-2.6.35 kernel port & general
notes
Readme

Barry Carter (ginge) barry....@gmail.com Aug 2010

Porting notes:
Port from

* I2C: I have converted i2c_wmt core driver to the new kernel ABI in
kernel
version > 2.6.32
* MTD: I have ported this away from the insanely bad mtd_table
referencing
code to the new(er) mtd interface style. ** NOTE THIS IS NOW FLAKY!
* time.c: I failed here. I patched up some semantics from the WMT
driver,
but left the WMT hack in place of the arm time.c file. The files are
not too
dissimilar, so recommend a separation of these files.
* ASM (.S) files: Some of the files had some shoddy asm

General Notes:
* Time interface is horrible. For now this is replacing the current
arm clock
interface code time.c -- this is really bad.
* The video driver code is very odd. I am not sure why, but most
video
parameters seem to be set from userspace in some sort of weird and
wonderful
dev/sys interface to change the params. I noted Gus was working on
decoding this.
I suspect it will require a special amount of loving to make the
code work
in something that approximates a normal driver.
* MTD interface driver is a bad patch with my terrible hacky port over
the top
of it. This seriously needs a rewrite.
* time.c As noted above, this code for this is overwriting the current
kernel
code. factor out!
This file also handles RTC stuff, making it quite massive. Suggest
new rtc.c
* GPIO control is in need of tidying up.
* AC97. Oh Dear. This needs a complete rewrite to move away from the
odd custom
driver that WMT used
* Power management. Looking at some of the periphery modules, say I2C,
the
power management code is non existant stubs.
* SD: No source driver!

Generally there is a lot of room for improvement with these drivers.
Looking at
some of the more "normal" interfaces, I believe it possible to get
some
performance gains on this one.
I think there is also a lot of room for improvement of the power
management
scheme in place. Some of the PM code is non-existant.

The SD driver is the show stopper now. I can't think of an easy way to
reverse
this object file into something useful... at least without mental
pain!
I have started to pick this file apart, but suspect it may be a long
process.

The only other option I can think of is to install CE on the device,
and use
a modified HaRET bootstrapper to log and see what the CE SD card is
doing.
Using this, write a new driver.
I have been there before and don't fancy going through that one again!

Staging area:
There are more than a few devices with this chipset. Mine isn't even
an eken!
I think it might be a good idea to have a staging area for each
device's
specific GPIO/MMAP/PCOM /other hardware settings. This is some work!

ginge

ginge

unread,
Aug 18, 2010, 3:30:48 PM8/18/10
to VT8500/WM8505 Linux Kernel
My eyes!

Horrible formatting there. not a good start!

-------------------------
WonderMedia wm8505-2.6.29 -gus to android-2.6.35 kernel port & general
notes
Readme

Barry Carter (ginge) barry.car...@gmail.com Aug 2010
On Aug 18, 8:26 pm, ginge <barry.car...@gmail.com> wrote:
> First of all, hello!
>
> As per subject, I have done some kernel porting...
>
> Seems I can't post files yet, so for now here is a link to the diff:
>
> http://headfuzz.co.uk/files/eken/2.6.35-eken-m001.diff
>
> I can't guarantee it will work, it might eat your dog etc.
> Also this port took me approx 1 day, so it is more than rough. The new
> ABI port to MTD is terrible, and I am ashamed of myself ;)
>
> -------------------------
> WonderMedia wm8505-2.6.29 -gus to android-2.6.35 kernel port & general
> notes
> Readme
>
> Barry Carter (ginge) barry.car...@gmail.com Aug 2010

Angus Gratton

unread,
Aug 18, 2010, 7:50:02 PM8/18/10
to vt8500-wm8505...@googlegroups.com
Hi Barry,

Thanks heaps for posting your notes and your patch.

I think, as you've noticed as well, there's a lot of horrible code in
the WMT source release. I now agree with Alexey Charkov on this - I
think we should work on his kernel as a clean implementation, rather
than try to tidy up the giant mess in the WMT codebase. There's just too
much to clean!


On Wed, 2010-08-18 at 12:26 -0700, ginge wrote:
> * The video driver code is very odd. I am not sure why, but most
> video
> parameters seem to be set from userspace in some sort of weird and
> wonderful
> dev/sys interface to change the params. I noted Gus was working on
> decoding this.
> I suspect it will require a special amount of loving to make the
> code work
> in something that approximates a normal driver.

Could not agree more. I'll post my complete notes on what I think it's
doing shortly, but there's no clean abstraction here - there's multiple
memory-mapped device interfaces, and multiple different sets of custom
ioctls, and even they don't seem to be organised in an easy to
understand way.

Again, this is one case where if we start from Alexey's clean kernel
then we can add (or not add) small pieces of video functionality as we
understand it. Because I think a lot of what is in the WMT video driver
codebase is either redundant or unused.


> Generally there is a lot of room for improvement with these drivers.
> Looking at
> some of the more "normal" interfaces, I believe it possible to get
> some
> performance gains on this one.
> I think there is also a lot of room for improvement of the power
> management
> scheme in place. Some of the PM code is non-existant.

I agree completely, particularly about power management.


>
> The SD driver is the show stopper now. I can't think of an easy way to
> reverse
> this object file into something useful... at least without mental
> pain!
> I have started to pick this file apart, but suspect it may be a long
> process.
>

Well, I know about one thing that might help. I don't know if I'd call
it "mental pain free", but it's a few step better than objdump.
http://pastebin.com/LrV7xAAU

I'm not the person who decompiled it, but I'm hoping that person will
join the list as well.

Obviously, I wouldn't use that as a basis for writing a driver (for both
practical & legal reasons), but it is useful for reading & reverse
engineering. The strategy I used for understanding the 'libui' Android
decompiled output was to work through renaming variables and functions
as I worked out what they did, and commenting, until the code made more
sense. After a while chipping away at tiny details, a bigger picture
started to emerge.

There are some pretty epic functions in that dump, though. :|.


> The only other option I can think of is to install CE on the device,
> and use
> a modified HaRET bootstrapper to log and see what the CE SD card is
> doing.
> Using this, write a new driver.
> I have been there before and don't fancy going through that one again!
>

The other good place to look is the u-boot source code released by WMT.
U-boot can at least read the SD card. I haven't looked there at all,
myself. It's possible the SD support there is binary-only, too.


> Staging area:
> There are more than a few devices with this chipset. Mine isn't even
> an eken!
> I think it might be a good idea to have a staging area for each
> device's
> specific GPIO/MMAP/PCOM /other hardware settings. This is some work!

I agree. The good news is that I think the variations between devices is
fairly low. I think everything out there so far is based on a tiny
handful of reference designs, all done by VIA or Wondermedia.

I certainly dislike Wondermedia's method of boot-argument configuration
though. Although it makes sense if they were not expecting manufacturers
to compile their own kernels.

But things like the amp_powerup/wifi_powerup env values, which are just
raw addresses/bitmasks of GPIO registers (3 addresses,
enable/direction/value) for powering up/down each peripheral.
Ewwwwwwwwwwww!


- Angus

edo1

unread,
Aug 19, 2010, 12:29:39 PM8/19/10
to VT8500/WM8505 Linux Kernel
On Aug 18, 11:26 pm, ginge <barry.car...@gmail.com> wrote:
> First of all, hello!
>
> As per subject, I have done some kernel porting...
>
> Seems I can't post files yet, so for now here is a link to the diff:
>
> http://headfuzz.co.uk/files/eken/2.6.35-eken-m001.diff

I see in this patch:
diff --git a/include/linux/android_pmem.h b/include/linux/
android_pmem.h

I don't see android_pmem.h in vanila kernel ;)
With which branch of the kernel should this patch be used?

Arnd Bergmann

unread,
Aug 20, 2010, 10:00:34 AM8/20/10
to vt8500-wm8505...@googlegroups.com, Angus Gratton
On Thursday 19 August 2010, Angus Gratton wrote:
> I think, as you've noticed as well, there's a lot of horrible code in
> the WMT source release. I now agree with Alexey Charkov on this - I
> think we should work on his kernel as a clean implementation, rather
> than try to tidy up the giant mess in the WMT codebase. There's just too
> much to clean!

Yes, at least the platform code needs to get rewritten before we
can get this in the upstream direction. For most of the device drivers,
we can probably get them into drivers/staging and start using them
while either cleaning them up or working on a replacement.

> > The SD driver is the show stopper now. I can't think of an easy way to
> > reverse
> > this object file into something useful... at least without mental
> > pain!
> > I have started to pick this file apart, but suspect it may be a long
> > process.
> >
>
> Well, I know about one thing that might help. I don't know if I'd call
> it "mental pain free", but it's a few step better than objdump.
> http://pastebin.com/LrV7xAAU
>
> I'm not the person who decompiled it, but I'm hoping that person will
> join the list as well.
>
> Obviously, I wouldn't use that as a basis for writing a driver (for both
> practical & legal reasons), but it is useful for reading & reverse
> engineering. The strategy I used for understanding the 'libui' Android
> decompiled output was to work through renaming variables and functions
> as I worked out what they did, and commenting, until the code made more
> sense. After a while chipping away at tiny details, a bigger picture
> started to emerge.
>
> There are some pretty epic functions in that dump, though. :|.

It seems to be mostly concerned with programming the DMA unit, judging
from the register addresses.
Also from all I can tell, the legal problem is on the side of the people
shipping the driver as part of a binary kernel, not on our side ;-)

I've taken a brief look at the patch (minus the video code), here are
some things that stuck out.

Arnd

> --- a/Makefile
> +++ b/Makefile
> @@ -188,9 +188,8 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
> # Default value for CROSS_COMPILE is not to prefix executables
> # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
> export KBUILD_BUILDHOST := $(SUBARCH)
> -ARCH ?= $(SUBARCH)
> -CROSS_COMPILE ?=
> -CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
> +ARCH ?= arm
> +CROSS_COMPILE ?= arm-none-linux-gnueabi-
>
> # Architecture as present in compile.h
> UTS_MACHINE := $(ARCH)

I wouldn't change this in the repository, even if it seems useful.
The CROSS_COMPILE-option is host specific and the ARCH has to be set anyway.
You can keep a local patch to this effect, but any change like this obviously
cannot get merged anywhere.

> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 98922f7..fdeb273 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -43,7 +43,7 @@ config GENERIC_GPIO
>
> config GENERIC_TIME
> bool
> - default y
> + default n
>
> config ARCH_USES_GETTIMEOFFSET
> bool

As you mentioned, this needs to get changed back and the original
code put in place again.

> @@ -208,7 +208,7 @@ config MMU
> #
> choice
> prompt "ARM system type"
> - default ARCH_VERSATILE
> + default ARCH_WMT
>
> config ARCH_AAEC2000
> bool "Agilent AAEC-2000 based"

Also no need for this, your .config can hold this.

> @@ -794,6 +794,14 @@ config PLAT_SPEAR
> help
> Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
>
> +
> +config ARCH_WMT
> + bool "WonderMedia Technology"
> + select ARCH_REQUIRE_GPIOLIB
> + select ARCH_USES_GETTIMEOFFSET
> + help
> + This enables support for systems based on a WonderMedia Technology system.
> +
> endchoice

Maybe be more specific here and mention the specific SoCs WM8505 and
VT8500?

>
> config LEDS
> bool "Timer and CPU usage LEDs"
> - depends on ARCH_CDB89712 || ARCH_EBSA110 || \
> + depends on ARCH_WMT || ARCH_CDB89712 || ARCH_EBSA110 || \
> ARCH_EBSA285 || ARCH_INTEGRATOR || \
> ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
> ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \

The others seem to be sorted alphabetically, so better put this at the
end.

> @@ -1319,6 +1329,7 @@ config LEDS_TIMER
> depends on LEDS
> depends on !GENERIC_CLOCKEVENTS
> default y if ARCH_EBSA110
> + default y if ARCH_WMT
> help
> If you say Y here, one of the system LEDs (the green one on the
> NetWinder, the amber one on the EBSA285, or the red one on the LART)

Not needed, just use .config.

> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 95327b4..17e9679 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -71,6 +71,11 @@ wait: mrc p14, 0, pc, c0, c1, 0
> mov \rb, #0x50000000
> add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
> .endm
> +#elif defined(CONFIG_ARCH_WMT)
> + .macro loadsp, rb
> + mov \rb, #0xd8000000 @ wmt register base address
> + add \rb, \rb, #0x00200000 @ uart0 base address offset
> + .endm
> #else
> .macro loadsp, rb, tmp
> addruart \rb, \tmp

I guess we should get away with just defining the addruart macro and
using the default loadsp version.

> index 0000000..6dc0648
> --- /dev/null
> +++ b/arch/arm/boot/compressed/lib1funcs.S

This seems rather wrong. What do we need lib1funcs.S for in the boot
code?

> diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
> index 242da13..b157133 100644
> --- a/arch/arm/boot/compressed/misc.c
> +++ b/arch/arm/boot/compressed/misc.c
> @@ -103,6 +103,7 @@ static void icedcc_putc(int ch)
> #define putc(ch) icedcc_putc(ch)
> #endif
>
> +#if !defined (CONFIG_ARCH_WMT)
> static void putstr(const char *ptr)
> {
> char c;
> @@ -115,6 +116,7 @@ static void putstr(const char *ptr)
>
> flush();
> }
> +#endif
>
> #endif

Why?

> diff --git a/arch/arm/boot/compressed/piggy.gzip b/arch/arm/boot/compressed/piggy.gzip
> new file mode 100644
> index 0000000..3072a1c
> Binary files /dev/null and b/arch/arm/boot/compressed/piggy.gzip differ
> diff --git a/arch/arm/boot/compressed/vmlinux b/arch/arm/boot/compressed/vmlinux
> new file mode 100755
> index 0000000..1af6c16
> Binary files /dev/null and b/arch/arm/boot/compressed/vmlinux differ

These files should probably get removed and listed in the local
.gitignore file.

> diff --git a/arch/arm/configs/android_wm8505_config b/arch/arm/configs/android_wm8505_config
> new file mode 100644
> index 0000000..c07550e
> --- /dev/null
> +++ b/arch/arm/configs/android_wm8505_config
> @@ -0,0 +1,2053 @@
> +#
> +# Automatically generated make config: don't edit
> +# Linux kernel version: 2.6.29
> +# Wed Jan 13 09:17:03 2010
> +#
> +CONFIG_ARM=y
> +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
> +# CONFIG_GENERIC_GPIO is not set
> +# CONFIG_GENERIC_TIME is not set
> +# CONFIG_GENERIC_CLOCKEVENTS is not set
> +CONFIG_MMU=y
> ...

The 2.6.36-rc1 kernel now has a 'make savedefconfig' target, please use
that to generate a minimal defconfig file instead of one that contains
all config options.

> diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
> index 52f0da1..fb78a5f 100644
> --- a/arch/arm/include/asm/mach/pci.h
> +++ b/arch/arm/include/asm/mach/pci.h
> @@ -80,4 +80,7 @@ extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
> extern void pci_v3_preinit(void);
> extern void pci_v3_postinit(void);
>
> +extern int wmt_pci_setup(int nr, struct pci_sys_data *);
> +extern struct pci_bus *wmt_pci_scan_bus(int nr, struct pci_sys_data *);
> +
> #endif /* __ASM_MACH_PCI_H */

Nothing seems to use these right now...

> diff --git a/arch/arm/mach-msm/dma.h b/arch/arm/mach-msm/dma.h
> new file mode 100644
> index 0000000..a811ac2
> --- /dev/null
> +++ b/arch/arm/mach-msm/dma.h
> @@ -0,0 +1,468 @@
> +/*++
> + linux/include/asm-arm/arch-wmt/dma.h

What happened here? I don't think it should be in mach-msm.

> +choice
> + prompt "Select WonderMedia Technology evaluation board type"
> + depends on WMT_EVB
> + default VT9043A1
> + ---help---
> + Choose the type of WonderMedia Technology evaluation board type.
> + There are four types of WonderMedia Technology EVB, depend on the mounted components.
> +
> +config VT9043A1
> + bool "VT9043A1"
> + ---help---
> + Say Y here if you intend to build kernel on VT9043A1.
> +
> +endchoice

So is VT9043A1 the CPU daughtercard in all those devices?

> +
> + /*FIXME, Harry, remove following while ATAG passing from bootloader is ok.*/
> + t->hdr.tag = ATAG_CORE;
> + t->hdr.size = tag_size(tag_core);
> + t->u.core.flags = 0;
> + t->u.core.pagesize = PAGE_SIZE;
> + t->u.core.rootdev = (RAMDISK_MAJOR << 8) | 0;
> + t = tag_next(t);
> +
> + t->hdr.tag = ATAG_MEM;
> + t->hdr.size = tag_size(tag_mem32);
> + t->u.mem.start = 0x00000000;
> + t->u.mem.size = 64 * 1024 * 1024;
> + t = tag_next(t);
> + /**/
> + /* ramdisk.size = decompressed ramdisk size in _kilo_ bytes.*/
> + /**/
> + t->hdr.tag = ATAG_RAMDISK;
> + t->hdr.size = tag_size(tag_ramdisk);
> + t->u.ramdisk.flags = 1;
> + t->u.ramdisk.size = 8 * 1024;
> + t->u.ramdisk.start = 0;
> + t = tag_next(t);
> + /**/
> + /* initrd.size = size of compressed ramdisk image in bytes.*/
> + /**/
> + t->hdr.tag = ATAG_INITRD2;
> + t->hdr.size = tag_size(tag_initrd);
> + t->u.initrd.start = 0x01000000; /* physical*/
> + /*t->u.initrd.size = 3 * 1024 * 1024;*/
> + t->u.initrd.size = 8 * 1024 * 1024; /* depend on the size of ramdisk.gz*/
> + t = tag_next(t);

I assume the ATAG from the boot loader are not ok then, right?

> +/*------------------------------------------------------------------------------
> + Macros below are used for driver in IOCTL
> +------------------------------------------------------------------------------*/
> +#define MB_IOC_MAGIC 'M'
> +
> +#define MBIO_MALLOC _IOWR(MB_IOC_MAGIC, 0, unsigned long) // I: size O: physical address
> +#define MBIO_FREE _IOWR(MB_IOC_MAGIC, 1, unsigned long) // I: user address O: ummap size
> +#define MBIO_UNMAP _IOWR(MB_IOC_MAGIC, 2, unsigned long) // I: user address O: ummap size
> +#define MBIO_MBSIZE _IOWR(MB_IOC_MAGIC, 3, unsigned long) // I: phys address O: mb size
> +#define MBIO_MAX_AVAILABLE_SIZE _IOR (MB_IOC_MAGIC, 4, unsigned long) // O: max free mba size
> +/* advance use only */
> +#define MBIO_GET _IOW (MB_IOC_MAGIC, 5, unsigned long) // I: user address
> +#define MBIO_PUT _IOW (MB_IOC_MAGIC, 6, unsigned long) // I: user address
> +#define MBIO_USER_TO_VIRT _IOWR(MB_IOC_MAGIC, 7, unsigned long) // I: user address O: virt address
> +#define MBIO_USER_TO_PHYS _IOWR(MB_IOC_MAGIC, 8, unsigned long) // I: user address O: phys address
> +#define MBIO_PREFETCH _IOW (MB_IOC_MAGIC, 9, unsigned long) // I: size
> +#define MBIO_STATIC_SIZE _IOR (MB_IOC_MAGIC,10, unsigned long) // O: static mba size
> +#define MBIO_MB_USER_COUNT _IOWR(MB_IOC_MAGIC,11, unsigned long) // I: phys address O: use counter
> +#define MBIO_FORCE_RESET _IO (MB_IOC_MAGIC,12)
> +
> +#define MBIO_MAXiMUM 11
> +#endif /* ifndef COM_MB_H */

Do we know if anything uses the memblock device driver? This interface
is certainly not acceptable to kernel integration.

> diff --git a/arch/arm/mach-wmt/cpu-freq.c b/arch/arm/mach-wmt/cpu-freq.c
> new file mode 100644
> index 0000000..b8e28cc
> --- /dev/null
> +++ b/arch/arm/mach-wmt/cpu-freq.c
> @@ -0,0 +1,308 @@
> +/*
> + linux/arch/arm/mach-wmt/cpu-freq.c
> +
> + CPU frequency scaling

This driver looks like it can be fixed.

> +/*
> + * Generic macro : restart CPU for reload PLL.
> + * PLL-A ,ZAC Clock Divisor,AHB Clock Divisor,PLL-B ,PLL-C
> + * need waitting about 5ms for PLL to stable
> + */
> +static void wmt_restart_cpu(void)
> +{
> + unsigned int reg_11c, reg_120;
> + const int zero = 0;
> + unsigned int reg_time;
> +
> + REG8_VAL(0xd8140000 + 0x65) = 0x8; /* route irq to irq*/
> + REG32_VAL(0xd8130000 + 0x120) = 0x03;
> + while (REG32_VAL(0xd8130000 + 0x124) != 0)

The main problem here is the direct access of the MMIO areas, which
needs to be replaced with proper ioremap/readl/writel calls.

> diff --git a/arch/arm/mach-wmt/dma.c b/arch/arm/mach-wmt/dma.c
> new file mode 100644
> index 0000000..6538b0a
> --- /dev/null
> +++ b/arch/arm/mach-wmt/dma.c
> @@ -0,0 +1,1313 @@
> +/*
> + arch/arm/mach-wmt/dma.c - DMA 4 driver
> +

This driver has a less bright future IMHO. Not sure what to do with it.
The only driver using this interface in the kernel patch is the SPI
one, so if that's indeed the only one that needs it, the necessary code
may get integrated in there.

> +/*
> + * Common Constant define
> + */
> +/*
> +#define TRUE 1
> +#define FALSE !TRUE
> +
> +#define SUCCESS 1
> +#define FAIL !SUCCESS
> +
> +#ifndef NULL
> +#define NULL 0
> +#endif
> +*/

Lovely.

> diff --git a/arch/arm/mach-wmt/include/mach/hardware.h b/arch/arm/mach-wmt/include/mach/hardware.h
> new file mode 100644
> index 0000000..139ade5
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/hardware.h
> @@ -0,0 +1,170 @@
> +#ifndef __ASM_ARCH_HARDWARE_H
> +#define __ASM_ARCH_HARDWARE_H
> +
> +/*
> + * Those are statically mapped PCMCIA IO space for designs using it as a
> + * generic IO bus, typically with ISA parts, hardwired IDE interfaces, etc.
> + * The actual PCMCIA code is mapping required IO region at run time.
> + */
> +
> +/*#define PCMCIA_IO_0_BASE 0xf6000000 */
> +/*#define PCMCIA_IO_1_BASE 0xf7000000 */

Is there actually PCMCIA present anywhere?

> +
> +/*
> + * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for
> + * in*()/out*() macros to be usable for all cases.
> + */
> +#define PCIO_BASE 0

This is almost certainly wrong, I would expect the PCI IO base to be
somewhere in the MMIO range, but certainly not at physical address 0.

> +#define IO_SPACE_LIMIT 0xffffffff

And a size of 4GB would mean that the I/O space takes up all the
physical addressing. Most likely the PCI implementation does not
support I/O port mapping at all, so it doesn't matter in practice.

> diff --git a/arch/arm/mach-wmt/include/mach/memblock.h b/arch/arm/mach-wmt/include/mach/memblock.h
> new file mode 100644
> index 0000000..1f08595
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/memblock.h
> @@ -0,0 +1,49 @@
> +// 1 presents the task init that would never be released
> +#define MB_DEF_TGID 1
> +
> +/* this function must be immediately called when kernel driver
> + get user address in direct ioctrl*/
> +#define mb_user_to_virt(u) mb_do_user_to_virt(u,MB_DEF_TGID)
> +#define mb_user_to_phys(u) mb_do_user_to_phys(u,MB_DEF_TGID)
> +/* All following 0 means type 0 (kernel space user) */
> +#define mb_allocate(s) mb_do_allocate(s,0,THE_MB_USER,MB_DEF_TGID)
> +#define mb_free(v) mb_do_free(v,0,THE_MB_USER,MB_DEF_TGID)
> +#define mb_get(v) mb_do_get(v,0,THE_MB_USER,MB_DEF_TGID)
> +#define mb_put(v) mb_do_put(v,0,THE_MB_USER,MB_DEF_TGID)
> +#define mb_counter(p) mb_do_counter(p,0,THE_MB_USER)

This interface will probably cause us problems when we get to the device
drivers using it.

> diff --git a/arch/arm/mach-wmt/include/mach/rtc.h b/arch/arm/mach-wmt/include/mach/rtc.h
> new file mode 100644
> index 0000000..1a5c923
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/rtc.h

completely unused, AFAICT

> diff --git a/arch/arm/mach-wmt/include/mach/vt1613.h b/arch/arm/mach-wmt/include/mach/vt1613.h
> new file mode 100644
> index 0000000..f944fdb
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/vt1613.h
> @@ -0,0 +1,352 @@
> +/*++
> + linux/include/asm-arm/arch-wmt/vt1613.h

Hmm, the defconfig files contain CONFIG_VT1613=y, but nothing includes
this header and no driver seems to be there. Is there more stuff missing
than just the SD driver in the end?

> diff --git a/arch/arm/mach-wmt/include/mach/wmt_ac97.h b/arch/arm/mach-wmt/include/mach/wmt_ac97.h
> new file mode 100644
> index 0000000..cbf41b3
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/wmt_ac97.h

Files like this one can probably get moved into the directory that
contains the driver including it. That would make it much easier to
separate the platform code from the drivers.

> diff --git a/arch/arm/mach-wmt/include/mach/wmt_i8042.h b/arch/arm/mach-wmt/include/mach/wmt_i8042.h
> new file mode 100644
> index 0000000..77a9d81
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/wmt_i8042.h

Wow, a PC-style keyboard controller! I wonder if VIA ended up resusing
parts from their PC chipsets. Maybe more of these things are actually
standard components that we already have drivers for if we just look
in the proper places.

> diff --git a/arch/arm/mach-wmt/include/mach/wmt_sdmmc.h b/arch/arm/mach-wmt/include/mach/wmt_sdmmc.h
> new file mode 100644
> index 0000000..7aca58a
> --- /dev/null
> +++ b/arch/arm/mach-wmt/include/mach/wmt_sdmmc.h
> @@ -0,0 +1,638 @@
> +
> +/*
> + * SD/SDIO/MMC Host Control Register Offset
> + */
> +#define _CTLR 0x00
> +#define _CMDI 0X01
> +#define _REST 0X02
> +#define _CMDA3 0X03
> +#define _CMDA2 0X04
> +#define _CMDA1 0X05
> +#define _CMDA0 0X06
> +#define _BUSM 0X07
> +#define _BLKL1 0X08
> +#define _BLKL0 0X09
> +#define _BLKC1 0X0A
> +#define _BLKC0 0X0B
> +#define _RESR 0X0C
> +#define _DATR 0X0D
> +#define _IMR0 0X0E
> +#define _IMR1 0X0F
> +#define _STR0 0X10
> +#define _STR1 0X11
> +#define _STR2 0X12
> +#define _STR3 0X13
> +#define _RTOR 0X14
> +#define _DTOR2 0X15
> +#define _DTOR1 0X16
> +#define _DTOR0 0X17
> +#define _CKDR 0X18
> +#define _DMAC 0X19

This is not related to drivers/mmc/host/via/sdmmc.c or any other one in
there, AFAICT.

> diff --git a/arch/arm/mach-wmt/pci_wmt.c b/arch/arm/mach-wmt/pci_wmt.c
> new file mode 100644
> index 0000000..67f8d66
> --- /dev/null
> +++ b/arch/arm/mach-wmt/pci_wmt.c
> +
> +#include <asm/io.h>
> +#include <asm/system.h>
> +
> +#include <asm/mach/pci.h>
> +#include <asm/mach/time.h>
> +
> +/*#define PATA*/
> +/*#define SATA*/
> +#define USB_HOST
> +#define MAC
> +/*#define EXT_PCI*/

Which ones have this? I suppose the WM8505 has USB and ethernet, but
none of the others, right?

> +#define CONFIG_CMD(bus, devfn, where) (0x80000000 | ((devfn) << 8) | ((where) & ~3))
> +
> +static u32 pci_config_ba;
> +static u32 pci_config_addr;
> +static u32 pci_config_data;
> +
> +#define MAX_PCI_DEV 0xC
> +#define INT_SATA 0
> +#define INT_PATA 1
> +#define INT_MAC0 2
> +#define INT_MAC1 3
> +#define INT_USB_EHCI 4
> +#define INT_USB_UHCI 5
> +#define EXT_PCI7 7
> +#define EXT_PCI8 8
> +#define EXT_PCI9 9
> +#define EXT_PCIA 0xA
> +#define EXT_PCIB 0xB
> +
> +u32 pci_config_mask[MAX_PCI_DEV][8][0x10];
> +u32 pci_config_shadow[MAX_PCI_DEV][8][0x10];
> +u32 pci_config_ro[MAX_PCI_DEV][8][0x10];
> +
> +#ifdef SATA
> +#define SATA_PCI_CONFIG 0xd800d100
> +#endif
> +
> +static int
> +wmt_read_config(
> + struct pci_bus *bus,
> + unsigned int devfn,
> + int where,
> + int size,
> + u32 *value
> + )
> +{
> + u32 bar, mask, devno, func;
> +
> + devno = devfn >> 3;
> + func = devfn & 7;
> + *value = 0xFFFFFFFF;
> +
> +#ifndef EXT_PCI
> + if (devno > 6)
> + return 0;
> +#endif
> +
> + switch (devno) { /* Check the dev number */
> + /* external PCI devices */
> + case EXT_PCI7:
> + case EXT_PCI8:
> + case EXT_PCI9:
> + case EXT_PCIA:
> + case EXT_PCIB:
> + {
> + if ((where >= 0x10) && (where < 0x28)) {

So if it's an external device, treat the base address registers in a
special way -- the driver never looks at the real BAR but only at the
shadow.

> + switch (size) {
> + case 1:
> + bar = (where & ~3)/4;
> + mask = 0xFF << 8*(where & 3);
> + *value = pci_config_shadow[devno][func][bar] & mask;
> + *value = (*value) >> 8*(where & 3);
> + break;
> +
> + case 2:
> + bar = (where & ~3)/4;
> + mask = 0xFFFF << 8*(where & 2);
> + *value = pci_config_shadow[devno][func][bar] & mask;
> + *value = (*value) >> 8*(where & 2);
> + break;
> +
> + case 4:
> + bar = (where & ~3)/4;
> + mask = 0xFFFFFFFF;
> + *value = pci_config_shadow[devno][func][bar] & mask;
> + }

My guess is that they never really got the BARs working because of the
broken I/O space setup mentioned above.

> + } else {
> + writel(CONFIG_CMD(bus, devfn, where), pci_config_addr);
> + switch (size) {
> + case 1:
> + *value = readb(pci_config_data + (where&3));
> + break;
> +
> + case 2:
> + *value = readw(pci_config_data + (where&2));
> + break;
> +
> + case 4:
> + *value = readl(pci_config_data);
> + break;
> + }
> + }

All other config space accesses for external devices are accessed in a
regular way.

> + break;
> +
> + /* internal PCI devices */
> +#ifdef SATA
> + case INT_SATA:
> + if ((where >= 0xA0) && (where <= 0xAF)) {
> + switch (size) {
> + case 1:
> + *value = inb((SATA_PCI_CONFIG + where));
> + break;
> + case 2:
> + *value = inw((SATA_PCI_CONFIG + (where & ~1)));
> + break;
> + case 4:
> + *value = inl((SATA_PCI_CONFIG + (where & ~3)));
> + break;
> + }
> + break;
> + }
> +#endif

For SATA, part of the config space is mapped separately, probably a flaw
in the PCI config space implementation.

> + case INT_PATA:
> + case INT_MAC0:
> + case INT_MAC1:
> + case INT_USB_UHCI:
> + case INT_USB_EHCI:

It seems that these devices are not actually PCI, but instead the code
tries to make them look as if they were in order to use the regular
device drivers!

This is of course not the right way to do it, we should simply create
platform devices. For USB and ATA, that is already supported, and the
via-velocity network driver code could simply gain the same capability.

> + case 2:
> + if (where < 0x40) {
> + bar = (where & ~3)/4;
> + mask = 0xFFFF << 8*(where & 2);
> + *value = pci_config_shadow[devno][0][bar] & mask;
> + *value = (*value) >> 8*(where & 2);
> + } else if (where == 0x84) {
> + if (devno == INT_USB_UHCI) {
> + bar = pci_config_shadow[devno][0][8];
> + bar &= ~0x1;
> + } else
> + bar = pci_config_shadow[devno][0][4];
> +
> + bar = bar - 0x100;
> + *value = * (volatile unsigned short *)(bar + where);
> +
> + }else
> + *value = 0;
> + break;

Lots of ugly hacks can then just go away...

> +static int
> +wmt_write_config(struct pci_bus *bus, unsigned int devfn, int where,
> + int size, u32 value)
> +{
> + u32 bar, mask, devno, func;
> +
> + devno = devfn >> 3;
> + func = devfn & 7;
> + switch (devno) { /* Check the dev number */
> + /* external PCI devices */
> + case EXT_PCI7:
> + case EXT_PCI8:
> + case EXT_PCI9:
> + case EXT_PCIA:
> + case EXT_PCIB:

same as for read

> +#ifdef EXT_PCI
> +void init_ext_pci(void)
> +{
> + int i, func, bar, size;
> + u32 val, ori_val, new_val;
> + /* windows size is 64KB */
> + u32 io_base = 0x10000;
> + /* windows size is 16MB, but according to the architecture spec,
> + the windows is 64MB. */
> + u32 mem_base = 0xC2000000;
> +
> + /* assign resource for I/O, Memory and IRQ */
> + for (i = EXT_PCI7; i <= EXT_PCIB; i++) {


We have generic code to do this.

> + /*
> + * PCI Bridge Memory Map is between 0xC0000:0000 - 0xC3FF:FFFF(64MB)
> + * The first 64KB is allocated for the PCI I/O Space, except for the
> + * 0xCF8 - 0xCFF(8Bytes) for the PCI Configuration
> + * Others are reserved for the MemorySpace.
> + */
> + if (!request_region(0xC0000CF8, 8, "pci config")) {
> + printk("WonderMidia Technology PCI: Unable to request region 0xCF8\n");
> + return;
> + }

I love it when people can't spell the name of their employer correctly!

> +}
> +#endif
> +
> +/* void __init wmt_pci_preinit(void *sysdata) */
> +void __init wmt_pci_preinit(void)
> +{
> + int i, j, bar;
> +
> + printk("PCI: WonderMidia Technology PCI Bridge\n");
> +
> + if (!pci_config_ba) {
> + pci_config_ba = (ulong)ioremap_nocache(0xC0000CF8, 8);

Ok, so that's where the I/O space really is: 0xC0000000.
0xcf8 is the I/O port used for PCI config space access on
PC-Like systems.

> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 101105e..219149a 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -163,7 +163,8 @@ config CPU_ARM925T
>
> # ARM926T
> config CPU_ARM926T
> - bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
> + bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_WMT
> + default y if ARCH_WMT
> select CPU_32v5
> select CPU_ABRT_EV5TJ
> select CPU_PABRT_LEGACY

No, just select CPU_ARM926T from CONFIG_WMT!

> diff --git a/configaa b/configaa
> new file mode 100644
> index 0000000..41b140d
> --- /dev/null
> +++ b/configaa

This doesn't belong here, I guess

> +config WMT_VIBRATOR
> + tristate "WMT vibrator support"
> + depends on ARCH_WMT
> + default y
> + ---help---
> + Say Y here if you want to enable vibrator driver.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called wmt_vibrate
> +
> config DTLK
> tristate "Double Talk PC internal speech card support"
> depends on ISA

Yay!

> diff --git a/drivers/mtd/wmt_env.c b/drivers/mtd/wmt_env.c
> new file mode 100644
> index 0000000..da94786
> --- /dev/null
> +++ b/drivers/mtd/wmt_env.c
> @@ -0,0 +1,681 @@
> +/*
> + * wmt_env.c
> + *
> + * Maintained by: Jeff Garzik <jga...@pobox.com>

Unlikely.

> diff --git a/drivers/video/wmt/...

skipping these for now...

> diff --git a/include/linux/android_pmem.h b/include/linux/android_pmem.h
> index f633621..837b150 100644
> --- a/include/linux/android_pmem.h
> +++ b/include/linux/android_pmem.h
> @@ -57,7 +57,7 @@ struct pmem_region {
> unsigned long len;
> };
>
> -#ifdef CONFIG_ANDROID_PMEM
> +#if defined (CONFIG_ANDROID_PMEM) || defined (CONFIG_ARCH_WMT)
> int is_pmem_file(struct file *file);
> int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
> unsigned long *end, struct file **filp);

Make ARCH_WMT select CONFIG_ANDROID_PMEM if this is needed.

ginge

unread,
Aug 20, 2010, 1:20:39 PM8/20/10
to VT8500/WM8505 Linux Kernel
The patch will apply against android-2.6.35 which is the latest branch
in this repo:

http://android.git.kernel.org/?p=kernel/common.git;a=shortlog;h=refs/heads/android-2.6.35

edo1

unread,
Aug 27, 2010, 10:42:39 AM8/27/10
to VT8500/WM8505 Linux Kernel
On Aug 18, 11:26 pm, ginge <barry.car...@gmail.com> wrote:
> First of all, hello!
>
> As per subject, I have done some kernel porting...
>
> Seems I can't post files yet, so for now here is a link to the diff:
>
> http://headfuzz.co.uk/files/eken/2.6.35-eken-m001.diff
>
> I can't guarantee it will work, it might eat your dog etc.


Why you drop wmt_serial? It is very usefull for debugging.

Reply all
Reply to author
Forward
0 new messages