Re: [PATCH 5/8] add Texas Instruments AR7 support

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

 



Hi 

Le Wednesday 24 June 2009 13:28:56 Alexander Clouter, vous avez écrit :
> Hi,
>
> Florian Fainelli <florian@xxxxxxxxxxx> wrote:
> > Le Tuesday 23 June 2009 20:15:09 Ralf Baechle, vous avez écrit :
> >> On Tue, Jun 23, 2009 at 11:28:27AM +0200, Florian Fainelli wrote:
> >>
> >> AR7 time again - the platform pending longest ...  Let's see:
> >
> > Thank you very much for your comments Ralf, please find below an updated
> > version which addresses all of your comments. I hope this time we are
> > going to make it ;)
>
> I am hoping someone can have a tackle of the lzma/bzip2 kernel/initramfs
> generic compression code myself, but I guess one thing at a time. :)  If
> you have a simple way for me to produce a LZMA'd image, I'll test it
> this on my WAG54Gv2 (I need the image to be less than 700kB).
>
> My comments, for what they are worth, below:
> > From: Florian Fainelli <florian@xxxxxxxxxxx>
> > Subject: Add support for Texas Instruments AR7 System-on-a-Chip
> >
> > This patch adds support for the Texas Instruments AR7 System-on-a-Chip.
> > It supports the TNETD7100, 7200 and 7300 versions of the SoC.
> >
> > Changes from v4:
> > [snipped]
> >
> > Signed-off-by: Matteo Croce <matteo@xxxxxxxxxxx>
> > Signed-off-by: Felix Fietkau <nbd@xxxxxxxxxxx>
> > Signed-off-by: Eugene Konev <ejka@xxxxxxxxxxx>
> > Signed-off-by: Nicolas Thill <nico@xxxxxxxxxxx>
> > Signed-off-by: Florian Fainelli <florian@xxxxxxxxxxx>
> > --
> > [snipped]
> >
> > diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c
> > new file mode 100644
> > index 0000000..7ce5f07
> > --- /dev/null
> > +++ b/arch/mips/ar7/clock.c
> > @@ -0,0 +1,450 @@
> > [snipped]
> > +static void __init tnetd7300_init_clocks(void)
> > +{
> > +       u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
> > +       struct tnetd7300_clocks *clocks =
> > +                                       (struct tnetd7300_clocks *)
> > +                                       ioremap_nocache(AR7_REGS_POWER +
> > 0x20, +                                       sizeof(struct
> > tnetd7300_clocks)); +
>
> Needless cast'ing and also should you not check that NULL is not
> returned for both of these ioremap's?

As Ralf explained, ioremap will not fail here.

>
> > +       ar7_bus_clock = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
> > +               &clocks->bus, bootcr, AR7_AFE_CLOCK);
> > +
> > +       if (*bootcr & BOOT_PLL_ASYNC_MODE)
> > +               ar7_cpu_clock = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
> > +                       &clocks->cpu, bootcr, AR7_AFE_CLOCK);
> > +       else
> > +               ar7_cpu_clock = ar7_bus_clock;
> > +/*
> > +       tnetd7300_set_clock(USB_PLL_SOURCE_SHIFT, &clocks->usb,
> > +               bootcr, 48000000);
> > +*/
>
> Dead code?  Feels that way with what then follows.

Not really, but not used yet since we have not ported the USB HCI driver yet.

>
> > +       if (ar7_dsp_clock == 250000000)
> > +               tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp,
> > +                       bootcr, ar7_dsp_clock);
> > +
> > +       iounmap(clocks);
> > +       iounmap(bootcr);
> > +}
> >
> > [snipped]
> >
> > +static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock,
> > +       int prediv, int postdiv, int postdiv2, int mul, u32 frequency)
> > +{
> > +       printk(KERN_INFO
> > +               "Clocks: base = %d, frequency = %u, prediv = %d, "
> > +               "postdiv = %d, postdiv2 = %d, mul = %d\n",
> > +               base, frequency, prediv, postdiv, postdiv2, mul);
> > +
> > +       writel(0, &clock->ctrl);
> > +       writel(DIVISOR_ENABLE_MASK | ((prediv - 1) & 0x1F),
> > &clock->prediv); +       writel((mul - 1) & 0xF, &clock->mul);
> > +
> > +       for (mul = 0; mul < 2000; mul++)
> > +               ; /* nop */
> > +
>
> Only for furthering my know how, this because the timing is changing so
> you cannot msleep() or whatever?  Can we not jump straight into the
> while() instead and wait it out?  Alternatively start with a:
> ----
> while (!readl(&clock->status) & 0x1)
> 	;
> ----
>
> and then lead into the following?

Yes, we can keep busy waiting on the status register, this works too.

>
> > +       while (readl(&clock->status) & 0x1)
> > +               ; /* nop */
> > +
> > +       writel(DIVISOR_ENABLE_MASK | ((postdiv - 1) & 0x1F),
> > &clock->postdiv); +
> > +       writel(readl(&clock->cmden) | 1, &clock->cmden);
> > +       writel(readl(&clock->cmd) | 1, &clock->cmd);
> > +
> > +       while (readl(&clock->status) & 0x1)
> > +               ; /* nop */
> > +
> > +       writel(DIVISOR_ENABLE_MASK | ((postdiv2 - 1) & 0x1F),
> > &clock->postdiv2); +
> > +       writel(readl(&clock->cmden) | 1, &clock->cmden);
> > +       writel(readl(&clock->cmd) | 1, &clock->cmd);
> > +
> > +       while (readl(&clock->status) & 0x1)
> > +               ; /* nop */
> > +
> > +       writel(readl(&clock->ctrl) | 1, &clock->ctrl);
> > +}
> >
> > [snipped]
> >
> > +static void __init tnetd7200_init_clocks(void)
> > +{
> > +       u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
> > +       struct tnetd7200_clocks *clocks =
> > +                                       (struct tnetd7200_clocks *)
> > +                                       ioremap_nocache(AR7_REGS_POWER +
> > 0x80, +                                       sizeof(struct
> > tnetd7200_clocks));
>
> casting and NULL checks?
>
> > +int __init ar7_init_clocks(void)
> > +{
> > +       switch (ar7_chip_id()) {
> > +       case AR7_CHIP_7100:
> > +               tnetd7200_init_clocks();
> > +               break;
> > +       case AR7_CHIP_7200:
> > +               tnetd7200_init_clocks();
> > +               break;
>
> Change this to the following maybe?
> ----
> switch (ar7_chip_id()) {
> case AR7_CHIP_7100:
> case AR7_CHIP_7200:
> 	tnetd7200_init_clocks();
> 	break;
> ----
>
> > +       case AR7_CHIP_7300:
> > +               ar7_dsp_clock = tnetd7300_dsp_clock();
> > +               tnetd7300_init_clocks();
> > +               break;
> > +       default:
> > +               break;
> > +       }
> > +
> > +       return 0;
> > +}
> > +arch_initcall(ar7_init_clocks);
> >
> > diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c
>
> Too late now but gpiolib is rather nice to look into at some stage.

Yes, I will submit that later when AR7 is already included.

>
> > diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c
> > [snipped]
> > +#include <linux/version.h>
> > +#include <linux/init.h>
> > +#include <linux/ioport.h>
> > +#include <linux/pm.h>
> > +#include <linux/time.h>
> > +
> > +#include <asm/reboot.h>
> > +#include <asm/mach-ar7/ar7.h>
> > +#include <asm/mach-ar7/prom.h>
> > +
> > +static void ar7_machine_restart(char *command);
> > +static void ar7_machine_halt(void);
> > +static void ar7_machine_power_off(void);
> > +
>
> I don't think these are needed as you have the following in the
> 'correct' order.

Indeed.

>
> > +static void ar7_machine_restart(char *command)
> > +{
> > +       u32 *softres_reg = ioremap(AR7_REGS_RESET +
> > +                                         AR7_RESET_SOFTWARE, 1);
> > +       writel(1, softres_reg);
> > +}
> > +
> > +static void ar7_machine_halt(void)
> > +{
> > +       while (1)
> > +               ;
> > +}
> > +
> > +static void ar7_machine_power_off(void)
> > +{
> > +       u32 *power_reg = (u32 *)ioremap(AR7_REGS_POWER, 1);
> > +       u32 power_state = readl(power_reg) | (3 << 30);
> > +       writel(power_state, power_reg);
> > +       ar7_machine_halt();
> > +}
> >
> > +const char *get_system_type(void)
> > +{
> > +       u16 chip_id = ar7_chip_id();
> > +       switch (chip_id) {
> > +       case AR7_CHIP_7300:
> > +               return "TI AR7 (TNETD7300)";
> > +       case AR7_CHIP_7100:
> > +               return "TI AR7 (TNETD7100)";
> > +       case AR7_CHIP_7200:
> > +               return "TI AR7 (TNETD7200)";
> > +       default:
> > +               return "TI AR7 (Unknown)";
> > +       }
> > +}
> > +
> > +static int __init ar7_init_console(void)
> > +{
> > +       return 0;
> > +}
> > +console_initcall(ar7_init_console);
> > +
>
> Does this need to be called?
>
> > +/*
> > + * Initializes basic routines and structures pointers, memory size (as
> > + * given by the bios and saves the command line.
> > + */
> > +
> > +void __init plat_mem_setup(void)
> > +{
> > +       unsigned long io_base;
> > +
> > +       _machine_restart = ar7_machine_restart;
> > +       _machine_halt = ar7_machine_halt;
> > +       pm_power_off = ar7_machine_power_off;
> > +       panic_timeout = 3;
> > +
> > +       io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000);
> > +       if (!io_base)
> > +               panic("Can't remap IO base!\n");
> > +       set_io_port_base(io_base);
> > +
>
> Casting a pointer to a unsigned long...hmmmm.
>
> > +       prom_meminit();
> > +
> > +       printk(KERN_INFO "%s, ID: 0x%04x, Revision: 0x%02x\n",
> > +                                       get_system_type(),
> > +               ar7_chip_id(), ar7_chip_rev());
> > +}
> > diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c
> > new file mode 100644
> > index 0000000..a1fba89
> > --- /dev/null
> > +++ b/arch/mips/ar7/time.c
> > @@ -0,0 +1,30 @@
> > +/*
> > + * Carsten Langgaard, carstenl@xxxxxxxx
> > + * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
> > + *
> > + *  This program is free software; you can distribute it and/or modify
> > it + *  under the terms of the GNU General Public License (Version 2) as
> > + *  published by the Free Software Foundation.
> > + *
> > + *  This program is distributed in the hope it will be useful, but
> > WITHOUT + *  ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY or + *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > General Public License + *  for more details.
> > + *
> > + *  You should have received a copy of the GNU General Public License
> > along + *  with this program; if not, write to the Free Software
> > Foundation, Inc., + *  59 Temple Place - Suite 330, Boston MA 02111-1307,
> > USA.
> > + *
> > + * Setting up the clock on the MIPS boards.
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/time.h>
> > +
> > +#include <asm/time.h>
> > +#include <asm/mach-ar7/ar7.h>
> > +
> > +void __init plat_time_init(void)
> > +{
> > +       mips_hpt_frequency = ar7_cpu_freq() / 2;
> > +}
> >
> > diff --git a/arch/mips/include/asm/mach-ar7/ar7.h
> > b/arch/mips/include/asm/mach-ar7/ar7.h [snipped]
> > +#ifndef __AR7_H__
> > +#define __AR7_H__
> > +
> > +#include <linux/delay.h>
> > +#include <asm/addrspace.h>
> > +#include <linux/io.h>
> > +
> > +#define AR7_SDRAM_BASE 0x14000000
> > +
> > +#define AR7_REGS_BASE  0x08610000
> > +
> > +#define AR7_REGS_MAC0  (AR7_REGS_BASE + 0x0000)
> > +#define AR7_REGS_GPIO  (AR7_REGS_BASE + 0x0900)
> > +/* 0x08610A00 - 0x08610BFF (512 bytes, 128 bytes / clock) */
> > +#define AR7_REGS_POWER (AR7_REGS_BASE + 0x0a00)
> > +#define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00)
> > +#define AR7_REGS_USB   (AR7_REGS_BASE + 0x1200)
> > +#define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600)
> > +#define AR7_REGS_VLYNQ0        (AR7_REGS_BASE + 0x1800)
> > +#define AR7_REGS_DCL   (AR7_REGS_BASE + 0x1a00)
> > +#define AR7_REGS_VLYNQ1        (AR7_REGS_BASE + 0x1c00)
> > +#define AR7_REGS_MDIO  (AR7_REGS_BASE + 0x1e00)
> > +#define AR7_REGS_IRQ   (AR7_REGS_BASE + 0x2400)
> > +#define AR7_REGS_MAC1  (AR7_REGS_BASE + 0x2800)
> > +
> > +#define AR7_REGS_WDT   (AR7_REGS_BASE + 0x1f00)
> > +#define UR8_REGS_WDT   (AR7_REGS_BASE + 0x0b00)
> > +#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
> > +
>
> I guess it's style, but I have preferred '(<blah> | <offset>)'.  You
> might want to add a few more for unlabelled offsets such as
> "AR7_REGS_POWER + 0x80" to make things more self documenting?

Right, added too.

>
> > [snipped]
> > +extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
> > +
> > +static inline u16 ar7_chip_id(void)
> > +{
> > +       return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
> > +}
> > +
> > +static inline u8 ar7_chip_rev(void)
> > +{
> > +       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) &
> > 0xff; +}
>
> unneeded casting?
>
> > [snipped]
> > +
> > +static inline int ar7_has_high_cpmac(void)
> > +{
> > +       u16 chip_id = ar7_chip_id();
> > +       switch (chip_id) {
> > +       case AR7_CHIP_7100:
> > +       case AR7_CHIP_7200:
> > +               return 0;
> > +       default:
> > +               return 1;
> > +       }
> > +}
>
> I would probably recommend as a default to return ENXIO or EINVAL maybe?
> Then for AR7_CHIP_7300 you return 1, I'm guessing?

Yes, thanks.

>
> I have been slightly tracking the ar7 code for a while and I have to say
> it is really looking much nicer now-a-days.  Well done!  If you ever are
> in London, I'll buy you a beer.

I am in Paris at the moment, but you can also come here ;)
-- 
Best regards, Florian Fainelli
Email : florian@xxxxxxxxxxx
http://openwrt.org
-------------------------------


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux