From: Florian Fainelli <florian@openwrt.org>
To: Alexander Clouter <alex@digriz.org.uk>
Cc: linux-mips@linux-mips.org
Subject: Re: [PATCH 5/8] add Texas Instruments AR7 support
Date: Wed, 24 Jun 2009 19:32:09 +0200 [thread overview]
Message-ID: <200906241932.09909.florian@openwrt.org> (raw)
In-Reply-To: <o8f9h6-v4l.ln1@woodchuck.wormnet.eu>
Hi
Le Wednesday 24 June 2009 13:28:56 Alexander Clouter, vous avez écrit :
> Hi,
>
> Florian Fainelli <florian@openwrt.org> 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@openwrt.org>
> > 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@openwrt.org>
> > Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> > Signed-off-by: Eugene Konev <ejka@openwrt.org>
> > Signed-off-by: Nicolas Thill <nico@openwrt.org>
> > Signed-off-by: Florian Fainelli <florian@openwrt.org>
> > --
> > [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@mips.com
> > + * 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@openwrt.org
http://openwrt.org
-------------------------------
next prev parent reply other threads:[~2009-06-24 20:19 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-04 14:19 [PATCH 5/8] add Texas Instruments AR7 support Florian Fainelli
[not found] ` <200906161428.33571.florian@openwrt.org>
2009-06-23 9:28 ` Florian Fainelli
2009-06-23 18:15 ` Ralf Baechle
2009-06-24 9:12 ` Florian Fainelli
2009-06-24 10:22 ` Ralf Baechle
2009-06-24 12:17 ` Florian Fainelli
2009-06-24 11:28 ` Alexander Clouter
2009-06-24 12:23 ` Ralf Baechle
2009-06-24 20:18 ` Florian Fainelli
2009-06-24 17:32 ` Florian Fainelli [this message]
2009-06-24 21:16 ` Alexander Clouter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200906241932.09909.florian@openwrt.org \
--to=florian@openwrt.org \
--cc=alex@digriz.org.uk \
--cc=linux-mips@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.