[PATCH 2.6.23] 83xx USB platform code rework
Grant Likely
grant.likely at secretlab.ca
Sat Jul 7 08:27:17 EST 2007
On 7/3/07, Li Yang <leoli at freescale.com> 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.
>
> Signed-off-by: Li Yang <leoli at freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips at freescale.com>
Acked-by: Grant Likely <grant.likely at secretlab.ca>
> ---
> Respin for 2.6.22-rc7. Remove USB_EHCI_FSL selects in Kconfig, as they
> will be enabled in USB Kconfig.
>
> arch/powerpc/platforms/83xx/Makefile | 2 +-
> arch/powerpc/platforms/83xx/mpc8313_rdb.c | 1 +
> arch/powerpc/platforms/83xx/mpc834x_mds.c | 49 +-------
> arch/powerpc/platforms/83xx/mpc83xx.h | 28 ++++-
> arch/powerpc/platforms/83xx/usb.c | 181 +++++++++++++++++++++++++++++
> 5 files changed, 213 insertions(+), 48 deletions(-)
> create mode 100644 arch/powerpc/platforms/83xx/usb.c
>
> diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
> index 31a91b5..5a98f88 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_MPC832x_RDB) += mpc832x_rdb.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..28b3840 100644
> --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
> +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
> @@ -44,55 +44,16 @@ 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);
>
> + mpc834x_usb_cfg();
> /* 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);
> @@ -134,7 +95,7 @@ static void __init mpc834x_mds_setup_arch(void)
> ppc_md.pci_exclude_device = mpc83xx_exclude_device;
> #endif
>
> - mpc834x_usb_cfg();
> + mpc834xemds_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..e7fdf01
> --- /dev/null
> +++ b/arch/powerpc/platforms/83xx/usb.c
> @@ -0,0 +1,181 @@
> +/*
> + * 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, *dr_mode;
> +
> + 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;
> +
> + np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
> + if (np) {
> + sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
> +
> + prop = of_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")) {
> + dr_mode = of_get_property(np, "dr_mode", NULL);
> + if (dr_mode && !strcmp(dr_mode, "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);
> + }
> + np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph");
> + if (np) {
> + sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
> +
> + prop = of_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 = of_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;
> +#ifdef CONFIG_USB_OTG
> + const void *dr_mode;
> +#endif
> +
> + np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
> + if (!np)
> + return -ENODEV;
> + prop = of_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 */
> + dr_mode = of_get_property(np, "dr_mode", NULL);
> + if (dr_mode && !strcmp(dr_mode, "otg"))
> + temp |= CONTROL_OTG_PORT;
> +#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 */
> --
> 1.5.2.GIT
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely at secretlab.ca
(403) 399-0195
More information about the Linuxppc-dev
mailing list