[PATCH 2/2] 83xx USB platform code rework
Kumar Gala
galak at kernel.crashing.org
Fri May 11 00:58:50 EST 2007
On May 9, 2007, at 10:15 PM, Li Yang wrote:
> Add 831x USB platform setup code and rework 834x USB
> platform setup code. Move USB platform code to usb.c
> for different boards with CPU of the same series to share
> the USB initialization code.
Can you give a better explanation as to why the 834x and 831x usb
code isn't the same. (I'm guessing some of this has to do with the
built in PHY on 831x).
>
> Signed-off-by: Li Yang <leoli at freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips at freescale.com>
> ---
> arch/powerpc/platforms/83xx/Kconfig | 2 +
> arch/powerpc/platforms/83xx/Makefile | 2 +-
> arch/powerpc/platforms/83xx/mpc8313_rdb.c | 1 +
> arch/powerpc/platforms/83xx/mpc834x_mds.c | 47 +-------
> arch/powerpc/platforms/83xx/mpc83xx.h | 28 ++++-
> arch/powerpc/platforms/83xx/usb.c | 174 +++++++++++++++++++
> ++++++++++
> 6 files changed, 207 insertions(+), 47 deletions(-)
> create mode 100644 arch/powerpc/platforms/83xx/usb.c
>
> diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/
> platforms/83xx/Kconfig
> index 713b31a..9cb4d88 100644
> --- a/arch/powerpc/platforms/83xx/Kconfig
> +++ b/arch/powerpc/platforms/83xx/Kconfig
> @@ -51,6 +51,7 @@ config PPC_MPC831x
> bool
> select PPC_UDBG_16550
> select PPC_INDIRECT_PCI
> + select USB_EHCI_FSL
Did I miss where this is actually used (or defined)
> default y if MPC8313_RDB
> config PPC_MPC832x
> @@ -63,6 +64,7 @@ config MPC834x
> bool
> select PPC_UDBG_16550
> select PPC_INDIRECT_PCI
> + select USB_EHCI_FSL
> default y if MPC834x_MDS || MPC834x_ITX
> config PPC_MPC836x
> diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/
> platforms/83xx/Makefile
> index dfc970d..77712cb 100644
> --- a/arch/powerpc/platforms/83xx/Makefile
> +++ b/arch/powerpc/platforms/83xx/Makefile
> @@ -1,7 +1,7 @@
> #
> # Makefile for the PowerPC 83xx linux kernel.
> #
> -obj-y := misc.o
> +obj-y := misc.o usb.o
> obj-$(CONFIG_PCI) += pci.o
> obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o
> obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
> diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/
> powerpc/platforms/83xx/mpc8313_rdb.c
> index 96970ac..a404910 100644
> --- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
> +++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
> @@ -53,6 +53,7 @@ static void __init mpc8313_rdb_setup_arch(void)
> ppc_md.pci_exclude_device = mpc83xx_exclude_device;
> #endif
> + mpc831x_usb_cfg();
> }
> void __init mpc8313_rdb_init_IRQ(void)
> diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/
> powerpc/platforms/83xx/mpc834x_mds.c
> index 10394b2..d6bee69 100644
> --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
> +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
> @@ -44,55 +44,15 @@ unsigned long isa_mem_base = 0;
> #endif
> #define BCSR5_INT_USB 0x02
> -/* Note: This is only for PB, not for PB+PIB
> - * On PB only port0 is connected using ULPI */
> -static int mpc834x_usb_cfg(void)
> +static int mpc834xemds_usb_cfg(void)
> {
> - unsigned long sccr, sicrl;
> - void __iomem *immap;
> + struct device_node *np;
> void __iomem *bcsr_regs = NULL;
> u8 bcsr5;
> - struct device_node *np = NULL;
> - int port0_is_dr = 0;
> -
> - if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) !=
> NULL)
> - port0_is_dr = 1;
> - if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) !
> = NULL){
> - if (port0_is_dr) {
> - printk(KERN_WARNING
> - "There is only one USB port on PB board! \n");
> - return -1;
> - } else if (!port0_is_dr)
> - /* No usb port enabled */
> - return -1;
> - }
> -
> - immap = ioremap(get_immrbase(), 0x1000);
> - if (!immap)
> - return -1;
> -
> - /* Configure clock */
> - sccr = in_be32(immap + MPC83XX_SCCR_OFFS);
> - if (port0_is_dr)
> - sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
> - else
> - sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
> - out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
> -
> - /* Configure Pin */
> - sicrl = in_be32(immap + MPC83XX_SICRL_OFFS);
> - /* set port0 only */
> - if (port0_is_dr)
> - sicrl |= MPC83XX_SICRL_USB0;
> - else
> - sicrl &= ~(MPC83XX_SICRL_USB0);
> - out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
> -
> - iounmap(immap);
> /* Map BCSR area */
> np = of_find_node_by_name(NULL, "bcsr");
> - if (np != 0) {
> + if (np) {
> struct resource res;
> of_address_to_resource(np, 0, &res);
> @@ -135,6 +95,7 @@ static void __init mpc834x_mds_setup_arch(void)
> #endif
> mpc834x_usb_cfg();
> + mpc834xemds_usb_cfg();
seems like we should just call mpc834x_usb_cfg() from inside of
mpc834x_mds_usb_cfg()
> }
> static void __init mpc834x_mds_init_IRQ(void)
> diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/
> platforms/83xx/mpc83xx.h
> index 9cd03b5..a44e5b1 100644
> --- a/arch/powerpc/platforms/83xx/mpc83xx.h
> +++ b/arch/powerpc/platforms/83xx/mpc83xx.h
> @@ -6,6 +6,7 @@
> /* System Clock Control Register */
> #define MPC83XX_SCCR_OFFS 0xA08
> +#define MPC83XX_SCCR_USB_MASK 0x00f00000
> #define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000
> #define MPC83XX_SCCR_USB_MPHCM_01 0x00400000
> #define MPC83XX_SCCR_USB_MPHCM_10 0x00800000
> @@ -15,12 +16,31 @@
> /* system i/o configuration register low */
> #define MPC83XX_SICRL_OFFS 0x114
> -#define MPC83XX_SICRL_USB0 0x40000000
> -#define MPC83XX_SICRL_USB1 0x20000000
> +#define MPC834X_SICRL_USB_MASK 0x60000000
> +#define MPC834X_SICRL_USB0 0x40000000
> +#define MPC834X_SICRL_USB1 0x20000000
> +#define MPC831X_SICRL_USB_MASK 0x00000c00
> +#define MPC831X_SICRL_USB_ULPI 0x00000800
> /* system i/o configuration register high */
> #define MPC83XX_SICRH_OFFS 0x118
> -#define MPC83XX_SICRH_USB_UTMI 0x00020000
> +#define MPC834X_SICRH_USB_UTMI 0x00020000
> +#define MPC831X_SICRH_USB_MASK 0x000000e0
> +#define MPC831X_SICRH_USB_ULPI 0x000000a0
> +
> +/* USB Control Register */
> +#define FSL_USB2_CONTROL_OFFS 0x500
> +#define CONTROL_UTMI_PHY_EN 0x00000200
> +#define CONTROL_REFSEL_48MHZ 0x00000080
> +#define CONTROL_PHY_CLK_SEL_ULPI 0x00000400
> +#define CONTROL_OTG_PORT 0x00000020
> +
> +/* USB PORTSC Registers */
> +#define FSL_USB2_PORTSC1_OFFS 0x184
> +#define FSL_USB2_PORTSC2_OFFS 0x188
> +#define PORTSCX_PTW_16BIT 0x10000000
> +#define PORTSCX_PTS_UTMI 0x00000000
> +#define PORTSCX_PTS_ULPI 0x80000000
> /*
> * Declaration for the various functions exported by the
> @@ -31,5 +51,7 @@ extern int add_bridge(struct device_node *dev);
> extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
> extern void mpc83xx_restart(char *cmd);
> extern long mpc83xx_time_init(void);
> +extern int mpc834x_usb_cfg(void);
> +extern int mpc831x_usb_cfg(void);
> #endif /* __MPC83XX_H__ */
> diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/
> platforms/83xx/usb.c
> new file mode 100644
> index 0000000..4c2511c
> --- /dev/null
> +++ b/arch/powerpc/platforms/83xx/usb.c
> @@ -0,0 +1,174 @@
> +/*
> + * Freescale 83xx USB SOC setup code
> + *
> + * Copyright (C) 2007 Freescale Semiconductor, Inc.
> + * Author: Li Yang
> + *
> + * This program is free software; you can redistribute it and/or
> modify it
> + * under the terms of the GNU General Public License as
> published by the
> + * Free Software Foundation; either version 2 of the License, or
> (at your
> + * option) any later version.
> + */
> +
> +
> +#include <linux/stddef.h>
> +#include <linux/kernel.h>
> +#include <linux/errno.h>
> +
> +#include <asm/io.h>
> +#include <asm/prom.h>
> +#include <sysdev/fsl_soc.h>
> +
> +#include "mpc83xx.h"
> +
> +
> +#ifdef CONFIG_MPC834x
> +int mpc834x_usb_cfg(void)
> +{
> + unsigned long sccr, sicrl, sicrh;
> + void __iomem *immap;
> + struct device_node *np = NULL;
> + int port0_is_dr = 0, port1_is_dr = 0;
> + const void *prop;
> +
> + immap = ioremap(get_immrbase(), 0x1000);
> + if (!immap)
> + return -ENOMEM;
> +
> + /* Read registers */
> + /* Note: DR and MPH must use the same clock setting in SCCR */
> + sccr = in_be32(immap + MPC83XX_SCCR_OFFS) & ~MPC83XX_SCCR_USB_MASK;
> + sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) &
> ~MPC834X_SICRL_USB_MASK;
> + sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) &
> ~MPC834X_SICRH_USB_UTMI;
> +
> + if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr"))
> + != NULL) {
> + sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
> +
> + prop = get_property(np, "phy_type", NULL);
> + if (prop && (!strcmp(prop, "utmi") ||
> + !strcmp(prop, "utmi_wide"))) {
> + sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
> + sicrh |= MPC834X_SICRH_USB_UTMI;
> + port1_is_dr = 1;
> + } else if (prop && !strcmp(prop, "serial")) {
> + if (!strcmp(get_property(np, "dr_mode", NULL), "otg")) {
> + sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
> + port1_is_dr = 1;
> + } else {
> + sicrl |= MPC834X_SICRL_USB0;
> + }
> + } else if (prop && !strcmp(prop, "ulpi")) {
> + sicrl |= MPC834X_SICRL_USB0;
> + } else {
> + printk(KERN_WARNING "834x USB PHY type not supported\n");
> + }
> + port0_is_dr = 1;
> + of_node_put(np);
> + }
> + if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph"))
> + != NULL) {
> + sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
> +
> + prop = get_property(np, "port0", NULL);
> + if (prop) {
> + if (port0_is_dr)
> + printk(KERN_WARNING
> + "834x USB port0 can't be used by both DR and MPH!\n");
> + sicrl |= MPC834X_SICRL_USB0;
> + }
> + prop = get_property(np, "port1", NULL);
> + if (prop) {
> + if (port1_is_dr)
> + printk(KERN_WARNING
> + "834x USB port1 can't be used by both DR and MPH!\n");
> + sicrl |= MPC834X_SICRL_USB1;
> + }
> + of_node_put(np);
> + }
> +
> + /* Write back */
> + out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
> + out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
> + out_be32(immap + MPC83XX_SICRH_OFFS, sicrh);
> +
> + iounmap(immap);
> + return 0;
> +}
> +#endif /* CONFIG_MPC834x */
> +
> +#ifdef CONFIG_PPC_MPC831x
> +int mpc831x_usb_cfg(void)
> +{
> + u32 temp;
> + void __iomem *immap, *usb_regs;
> + struct device_node *np = NULL;
> + const void *prop;
> + struct resource res;
> + int ret = 0;
> +
> + if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) ==
> NULL)
> + return -ENODEV;
> + prop = get_property(np, "phy_type", NULL);
> +
> + /* Map IMMR space for pin and clock settings */
> + immap = ioremap(get_immrbase(), 0x1000);
> + if (!immap) {
> + of_node_put(np);
> + return -ENOMEM;
> + }
> +
> + /* Configure clock */
> + temp = in_be32(immap + MPC83XX_SCCR_OFFS);
> + temp &= ~MPC83XX_SCCR_USB_MASK;
> + temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
> + out_be32(immap + MPC83XX_SCCR_OFFS, temp);
> +
> + /* Configure pin mux for ULPI. There is no pin mux for UTMI */
> + if (!strcmp(prop, "ulpi")) {
> + temp = in_be32(immap + MPC83XX_SICRL_OFFS);
> + temp &= ~MPC831X_SICRL_USB_MASK;
> + temp |= MPC831X_SICRL_USB_ULPI;
> + out_be32(immap + MPC83XX_SICRL_OFFS, temp);
> +
> + temp = in_be32(immap + MPC83XX_SICRH_OFFS);
> + temp &= ~MPC831X_SICRH_USB_MASK;
> + temp |= MPC831X_SICRH_USB_ULPI;
> + out_be32(immap + MPC83XX_SICRH_OFFS, temp);
> + }
> +
> + iounmap(immap);
> +
> + /* Map USB SOC space */
> + ret = of_address_to_resource(np, 0, &res);
> + if (ret) {
> + of_node_put(np);
> + return ret;
> + }
> + usb_regs = ioremap(res.start, res.end - res.start + 1);
> +
> + /* Using on-chip PHY */
> + if (!strcmp(prop, "utmi_wide") ||
> + !strcmp(prop, "utmi")) {
> + /* Set UTMI_PHY_EN, REFSEL to 48MHZ */
> + out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
> + CONTROL_UTMI_PHY_EN | CONTROL_REFSEL_48MHZ);
> + /* Using external UPLI PHY */
> + } else if (!strcmp(prop, "ulpi")) {
> + /* Set PHY_CLK_SEL to ULPI */
> + temp = CONTROL_PHY_CLK_SEL_ULPI;
> +#ifdef CONFIG_USB_OTG
> + /* Set OTG_PORT */
> + temp |= CONTROL_OTG_PORT;
Shouldn't the 'otg' prop also be looked at?
> +#endif /* CONFIG_USB_OTG */
> + out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
> + } else {
> + printk(KERN_WARNING "831x USB PHY type not supported\n");
> + ret = -EINVAL;
> + }
> +
> + iounmap(usb_regs);
> + of_node_put(np);
> + return ret;
> +}
> +#endif /* CONFIG_PPC_MPC831x */
More information about the Linuxppc-dev
mailing list