octeon: add support for the octeon mips64 SoC
This is the SoC used be the ESR Lite made by ubnt.com Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 37684
This commit is contained in:
parent
8a4726bca8
commit
3a2040ffee
17 changed files with 8245 additions and 0 deletions
25
target/linux/octeon/Makefile
Normal file
25
target/linux/octeon/Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Copyright (C) 2013 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=mips
|
||||
BOARD:=octeon
|
||||
BOARDNAME:=Cavium Networks Octeon
|
||||
FEATURES:=squashfs jffs2 pci usb
|
||||
CFLAGS:=-Os -pipe -march=octeon -fno-caller-saves
|
||||
MAINTAINER:=John Crispin <blogic@openwrt.org>
|
||||
|
||||
LINUX_VERSION:=3.10
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Cavium Networks Octeon-based boards.
|
||||
endef
|
||||
|
||||
$(eval $(call BuildTarget))
|
18
target/linux/octeon/base-files/etc/config/network
Normal file
18
target/linux/octeon/base-files/etc/config/network
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (C) 2009 OpenWrt.org
|
||||
|
||||
config interface loopback
|
||||
option ifname lo
|
||||
option proto static
|
||||
option ipaddr 127.0.0.1
|
||||
option netmask 255.0.0.0
|
||||
|
||||
config interface lan
|
||||
option ifname eth1
|
||||
option type bridge
|
||||
option proto static
|
||||
option ipaddr 192.168.1.1
|
||||
option netmask 255.255.255.0
|
||||
|
||||
config interface wan
|
||||
option ifname eth0
|
||||
option proto dhcp
|
228
target/linux/octeon/config-default
Normal file
228
target/linux/octeon/config-default
Normal file
|
@ -0,0 +1,228 @@
|
|||
CONFIG_64BIT=y
|
||||
CONFIG_64BIT_PHYS_ADDR=y
|
||||
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_SUPPORTS_MSI=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
|
||||
# CONFIG_ARPD is not set
|
||||
CONFIG_BINFMT_ELF32=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLOCK_COMPAT=y
|
||||
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
|
||||
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
|
||||
# CONFIG_CAVIUM_CN63XXP1 is not set
|
||||
# CONFIG_CAVIUM_OCTEON_2ND_KERNEL is not set
|
||||
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
|
||||
CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
|
||||
CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
|
||||
CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_COMPAT_BRK=y
|
||||
CONFIG_COMPAT_NETLINK_MESSAGES=y
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
CONFIG_CPU_CAVIUM_OCTEON=y
|
||||
CONFIG_CPU_GENERIC_DUMP_TLB=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CPU_SUPPORTS_HUGEPAGES=y
|
||||
CONFIG_CRAMFS=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_DEVKMEM=y
|
||||
CONFIG_DMA_COHERENT=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_FAT_FS=y
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GPIO_DEVRES=y
|
||||
# CONFIG_HAMRADIO is not set
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAVE_64BIT_ALIGNED_ACCESS=y
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||
CONFIG_HAVE_DMA_ATTRS=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_HAVE_GENERIC_HARDIRQS=y
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_MEMORY_PRESENT=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
# CONFIG_HIGH_RES_TIMERS is not set
|
||||
CONFIG_HOLES_IN_ZONE=y
|
||||
# CONFIG_HUGETLBFS is not set
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_OCTEON=y
|
||||
CONFIG_HZ=250
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_HZ_PERIODIC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MDIO_OCTEON=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS32_COMPAT=y
|
||||
CONFIG_MIPS32_N32=y
|
||||
CONFIG_MIPS32_O32=y
|
||||
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=7
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
CONFIG_MIPS_MT_DISABLED=y
|
||||
CONFIG_MIPS_PGD_C0_CONTEXT=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_OF_PARTS=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_PHYSMAP_OF=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
CONFIG_NR_CPUS=16
|
||||
CONFIG_NR_CPUS_DEFAULT_16=y
|
||||
CONFIG_OCTEON_ETHERNET=y
|
||||
# CONFIG_OCTEON_ILM is not set
|
||||
CONFIG_OCTEON_MGMT_ETHERNET=y
|
||||
CONFIG_OCTEON_USB=y
|
||||
CONFIG_OCTEON_WDT=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_DEVICE=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_MTD=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
# CONFIG_PREEMPT_RCU is not set
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_SCHED_DEBUG=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_STATIC=y
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=999999
|
||||
CONFIG_STOP_MACHINE=y
|
||||
CONFIG_SWAP_IO_SPACE=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_SYSVIPC_COMPAT=y
|
||||
CONFIG_SYS_HAS_CPU_CAVIUM_OCTEON=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
|
||||
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
|
||||
CONFIG_SYS_SUPPORTS_SMP=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_UIDGID_CONVERTED=y
|
||||
CONFIG_UNINLINE_SPIN_UNLOCK=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ARCH_HAS_XHCI=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
|
||||
# CONFIG_USB_EHCI_HCD is not set
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_VFAT_FS=y
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_WEAK_ORDERING=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZONE_DMA32=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
10
target/linux/octeon/files/drivers/staging/octeon-usb/Kconfig
Normal file
10
target/linux/octeon/files/drivers/staging/octeon-usb/Kconfig
Normal file
|
@ -0,0 +1,10 @@
|
|||
config OCTEON_USB
|
||||
tristate "Cavium Networks Octeon USB support"
|
||||
depends on CPU_CAVIUM_OCTEON && USB
|
||||
help
|
||||
This driver supports USB host controller on some Cavium
|
||||
Networks' products in the Octeon family.
|
||||
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called octeon-usb.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
obj-${CONFIG_OCTEON_USB} := octeon-usb.o
|
||||
octeon-usb-y := octeon-hcd.o
|
||||
octeon-usb-y += cvmx-usb.o
|
11
target/linux/octeon/files/drivers/staging/octeon-usb/TODO
Normal file
11
target/linux/octeon/files/drivers/staging/octeon-usb/TODO
Normal file
|
@ -0,0 +1,11 @@
|
|||
This driver is functional and has been tested on EdgeRouter Lite with
|
||||
USB mass storage.
|
||||
|
||||
TODO:
|
||||
- kernel coding style
|
||||
- checkpatch warnings
|
||||
- dead code elimination
|
||||
- device tree bindings
|
||||
- possibly eliminate the extra "hardware abstraction layer"
|
||||
|
||||
Contact: Aaro Koskinen <aaro.koskinen@iki.fi>
|
3229
target/linux/octeon/files/drivers/staging/octeon-usb/cvmx-usb.c
Normal file
3229
target/linux/octeon/files/drivers/staging/octeon-usb/cvmx-usb.c
Normal file
File diff suppressed because it is too large
Load diff
1085
target/linux/octeon/files/drivers/staging/octeon-usb/cvmx-usb.h
Normal file
1085
target/linux/octeon/files/drivers/staging/octeon-usb/cvmx-usb.h
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,887 @@
|
|||
/***********************license start***************
|
||||
* Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights
|
||||
* reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
|
||||
* * Neither the name of Cavium Networks nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
|
||||
* This Software, including technical data, may be subject to U.S. export
|
||||
* control laws, including the U.S. Export Administration Act and its associated
|
||||
* regulations, and may be subject to export or import regulations in other
|
||||
* countries.
|
||||
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
|
||||
* AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
|
||||
* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
|
||||
* THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION
|
||||
* OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
|
||||
* SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
|
||||
* VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
|
||||
* CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
|
||||
* PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
|
||||
***********************license end**************************************/
|
||||
|
||||
|
||||
/**
|
||||
* cvmx-usbnx-defs.h
|
||||
*
|
||||
* Configuration and status register (CSR) type definitions for
|
||||
* Octeon usbnx.
|
||||
*
|
||||
*/
|
||||
#ifndef __CVMX_USBNX_TYPEDEFS_H__
|
||||
#define __CVMX_USBNX_TYPEDEFS_H__
|
||||
|
||||
#define CVMX_USBNXBID1(bid) (((bid) & 1) * 0x10000000ull)
|
||||
#define CVMX_USBNXBID2(bid) (((bid) & 1) * 0x100000000000ull)
|
||||
|
||||
#define CVMX_USBNXREG1(reg, bid) \
|
||||
(CVMX_ADD_IO_SEG(0x0001180068000000ull | reg) + CVMX_USBNXBID1(bid))
|
||||
#define CVMX_USBNXREG2(reg, bid) \
|
||||
(CVMX_ADD_IO_SEG(0x00016F0000000000ull | reg) + CVMX_USBNXBID2(bid))
|
||||
|
||||
#define CVMX_USBNX_CLK_CTL(bid) CVMX_USBNXREG1(0x10, bid)
|
||||
#define CVMX_USBNX_DMA0_INB_CHN0(bid) CVMX_USBNXREG2(0x818, bid)
|
||||
#define CVMX_USBNX_DMA0_OUTB_CHN0(bid) CVMX_USBNXREG2(0x858, bid)
|
||||
#define CVMX_USBNX_USBP_CTL_STATUS(bid) CVMX_USBNXREG1(0x18, bid)
|
||||
|
||||
/**
|
||||
* cvmx_usbn#_clk_ctl
|
||||
*
|
||||
* USBN_CLK_CTL = USBN's Clock Control
|
||||
*
|
||||
* This register is used to control the frequency of the hclk and the
|
||||
* hreset and phy_rst signals.
|
||||
*/
|
||||
union cvmx_usbnx_clk_ctl {
|
||||
uint64_t u64;
|
||||
/**
|
||||
* struct cvmx_usbnx_clk_ctl_s
|
||||
* @divide2: The 'hclk' used by the USB subsystem is derived
|
||||
* from the eclk.
|
||||
* Also see the field DIVIDE. DIVIDE2<1> must currently
|
||||
* be zero because it is not implemented, so the maximum
|
||||
* ratio of eclk/hclk is currently 16.
|
||||
* The actual divide number for hclk is:
|
||||
* (DIVIDE2 + 1) * (DIVIDE + 1)
|
||||
* @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
|
||||
* generate the hclk in the USB Subsystem is held
|
||||
* in reset. This bit must be set to '0' before
|
||||
* changing the value os DIVIDE in this register.
|
||||
* The reset to the HCLK_DIVIDERis also asserted
|
||||
* when core reset is asserted.
|
||||
* @p_x_on: Force USB-PHY on during suspend.
|
||||
* '1' USB-PHY XO block is powered-down during
|
||||
* suspend.
|
||||
* '0' USB-PHY XO block is powered-up during
|
||||
* suspend.
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
|
||||
* remain powered in Suspend Mode.
|
||||
* '1' The USB-PHY XO Bias, Bandgap and PLL are
|
||||
* powered down in suspend mode.
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @p_c_sel: Phy clock speed select.
|
||||
* Selects the reference clock / crystal frequency.
|
||||
* '11': Reserved
|
||||
* '10': 48 MHz (reserved when a crystal is used)
|
||||
* '01': 24 MHz (reserved when a crystal is used)
|
||||
* '00': 12 MHz
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* NOTE: if a crystal is used as a reference clock,
|
||||
* this field must be set to 12 MHz.
|
||||
* @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
|
||||
* @sd_mode: Scaledown mode for the USBC. Control timing events
|
||||
* in the USBC, for normal operation this must be '0'.
|
||||
* @s_bist: Starts bist on the hclk memories, during the '0'
|
||||
* to '1' transition.
|
||||
* @por: Power On Reset for the PHY.
|
||||
* Resets all the PHYS registers and state machines.
|
||||
* @enable: When '1' allows the generation of the hclk. When
|
||||
* '0' the hclk will not be generated. SEE DIVIDE
|
||||
* field of this register.
|
||||
* @prst: When this field is '0' the reset associated with
|
||||
* the phy_clk functionality in the USB Subsystem is
|
||||
* help in reset. This bit should not be set to '1'
|
||||
* until the time it takes 6 clocks (hclk or phy_clk,
|
||||
* whichever is slower) has passed. Under normal
|
||||
* operation once this bit is set to '1' it should not
|
||||
* be set to '0'.
|
||||
* @hrst: When this field is '0' the reset associated with
|
||||
* the hclk functioanlity in the USB Subsystem is
|
||||
* held in reset.This bit should not be set to '1'
|
||||
* until 12ms after phy_clk is stable. Under normal
|
||||
* operation, once this bit is set to '1' it should
|
||||
* not be set to '0'.
|
||||
* @divide: The frequency of 'hclk' used by the USB subsystem
|
||||
* is the eclk frequency divided by the value of
|
||||
* (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
|
||||
* DIVIDE2 of this register.
|
||||
* The hclk frequency should be less than 125Mhz.
|
||||
* After writing a value to this field the SW should
|
||||
* read the field for the value written.
|
||||
* The ENABLE field of this register should not be set
|
||||
* until AFTER this field is set and then read.
|
||||
*/
|
||||
struct cvmx_usbnx_clk_ctl_s {
|
||||
uint64_t reserved_20_63 : 44;
|
||||
uint64_t divide2 : 2;
|
||||
uint64_t hclk_rst : 1;
|
||||
uint64_t p_x_on : 1;
|
||||
uint64_t reserved_14_15 : 2;
|
||||
uint64_t p_com_on : 1;
|
||||
uint64_t p_c_sel : 2;
|
||||
uint64_t cdiv_byp : 1;
|
||||
uint64_t sd_mode : 2;
|
||||
uint64_t s_bist : 1;
|
||||
uint64_t por : 1;
|
||||
uint64_t enable : 1;
|
||||
uint64_t prst : 1;
|
||||
uint64_t hrst : 1;
|
||||
uint64_t divide : 3;
|
||||
} s;
|
||||
/**
|
||||
* struct cvmx_usbnx_clk_ctl_cn30xx
|
||||
* @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
|
||||
* generate the hclk in the USB Subsystem is held
|
||||
* in reset. This bit must be set to '0' before
|
||||
* changing the value os DIVIDE in this register.
|
||||
* The reset to the HCLK_DIVIDERis also asserted
|
||||
* when core reset is asserted.
|
||||
* @p_x_on: Force USB-PHY on during suspend.
|
||||
* '1' USB-PHY XO block is powered-down during
|
||||
* suspend.
|
||||
* '0' USB-PHY XO block is powered-up during
|
||||
* suspend.
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @p_rclk: Phy refrence clock enable.
|
||||
* '1' The PHY PLL uses the XO block output as a
|
||||
* reference.
|
||||
* '0' Reserved.
|
||||
* @p_xenbn: Phy external clock enable.
|
||||
* '1' The XO block uses the clock from a crystal.
|
||||
* '0' The XO block uses an external clock supplied
|
||||
* on the XO pin. USB_XI should be tied to
|
||||
* ground for this usage.
|
||||
* @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
|
||||
* remain powered in Suspend Mode.
|
||||
* '1' The USB-PHY XO Bias, Bandgap and PLL are
|
||||
* powered down in suspend mode.
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @p_c_sel: Phy clock speed select.
|
||||
* Selects the reference clock / crystal frequency.
|
||||
* '11': Reserved
|
||||
* '10': 48 MHz
|
||||
* '01': 24 MHz
|
||||
* '00': 12 MHz
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
|
||||
* @sd_mode: Scaledown mode for the USBC. Control timing events
|
||||
* in the USBC, for normal operation this must be '0'.
|
||||
* @s_bist: Starts bist on the hclk memories, during the '0'
|
||||
* to '1' transition.
|
||||
* @por: Power On Reset for the PHY.
|
||||
* Resets all the PHYS registers and state machines.
|
||||
* @enable: When '1' allows the generation of the hclk. When
|
||||
* '0' the hclk will not be generated.
|
||||
* @prst: When this field is '0' the reset associated with
|
||||
* the phy_clk functionality in the USB Subsystem is
|
||||
* help in reset. This bit should not be set to '1'
|
||||
* until the time it takes 6 clocks (hclk or phy_clk,
|
||||
* whichever is slower) has passed. Under normal
|
||||
* operation once this bit is set to '1' it should not
|
||||
* be set to '0'.
|
||||
* @hrst: When this field is '0' the reset associated with
|
||||
* the hclk functioanlity in the USB Subsystem is
|
||||
* held in reset.This bit should not be set to '1'
|
||||
* until 12ms after phy_clk is stable. Under normal
|
||||
* operation, once this bit is set to '1' it should
|
||||
* not be set to '0'.
|
||||
* @divide: The 'hclk' used by the USB subsystem is derived
|
||||
* from the eclk. The eclk will be divided by the
|
||||
* value of this field +1 to determine the hclk
|
||||
* frequency. (Also see HRST of this register).
|
||||
* The hclk frequency must be less than 125 MHz.
|
||||
*/
|
||||
struct cvmx_usbnx_clk_ctl_cn30xx {
|
||||
uint64_t reserved_18_63 : 46;
|
||||
uint64_t hclk_rst : 1;
|
||||
uint64_t p_x_on : 1;
|
||||
uint64_t p_rclk : 1;
|
||||
uint64_t p_xenbn : 1;
|
||||
uint64_t p_com_on : 1;
|
||||
uint64_t p_c_sel : 2;
|
||||
uint64_t cdiv_byp : 1;
|
||||
uint64_t sd_mode : 2;
|
||||
uint64_t s_bist : 1;
|
||||
uint64_t por : 1;
|
||||
uint64_t enable : 1;
|
||||
uint64_t prst : 1;
|
||||
uint64_t hrst : 1;
|
||||
uint64_t divide : 3;
|
||||
} cn30xx;
|
||||
struct cvmx_usbnx_clk_ctl_cn30xx cn31xx;
|
||||
/**
|
||||
* struct cvmx_usbnx_clk_ctl_cn50xx
|
||||
* @divide2: The 'hclk' used by the USB subsystem is derived
|
||||
* from the eclk.
|
||||
* Also see the field DIVIDE. DIVIDE2<1> must currently
|
||||
* be zero because it is not implemented, so the maximum
|
||||
* ratio of eclk/hclk is currently 16.
|
||||
* The actual divide number for hclk is:
|
||||
* (DIVIDE2 + 1) * (DIVIDE + 1)
|
||||
* @hclk_rst: When this field is '0' the HCLK-DIVIDER used to
|
||||
* generate the hclk in the USB Subsystem is held
|
||||
* in reset. This bit must be set to '0' before
|
||||
* changing the value os DIVIDE in this register.
|
||||
* The reset to the HCLK_DIVIDERis also asserted
|
||||
* when core reset is asserted.
|
||||
* @p_rtype: PHY reference clock type
|
||||
* '0' The USB-PHY uses a 12MHz crystal as a clock
|
||||
* source at the USB_XO and USB_XI pins
|
||||
* '1' Reserved
|
||||
* '2' The USB_PHY uses 12/24/48MHz 2.5V board clock
|
||||
* at the USB_XO pin. USB_XI should be tied to
|
||||
* ground in this case.
|
||||
* '3' Reserved
|
||||
* (bit 14 was P_XENBN on 3xxx)
|
||||
* (bit 15 was P_RCLK on 3xxx)
|
||||
* @p_com_on: '0' Force USB-PHY XO Bias, Bandgap and PLL to
|
||||
* remain powered in Suspend Mode.
|
||||
* '1' The USB-PHY XO Bias, Bandgap and PLL are
|
||||
* powered down in suspend mode.
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* @p_c_sel: Phy clock speed select.
|
||||
* Selects the reference clock / crystal frequency.
|
||||
* '11': Reserved
|
||||
* '10': 48 MHz (reserved when a crystal is used)
|
||||
* '01': 24 MHz (reserved when a crystal is used)
|
||||
* '00': 12 MHz
|
||||
* The value of this field must be set while POR is
|
||||
* active.
|
||||
* NOTE: if a crystal is used as a reference clock,
|
||||
* this field must be set to 12 MHz.
|
||||
* @cdiv_byp: Used to enable the bypass input to the USB_CLK_DIV.
|
||||
* @sd_mode: Scaledown mode for the USBC. Control timing events
|
||||
* in the USBC, for normal operation this must be '0'.
|
||||
* @s_bist: Starts bist on the hclk memories, during the '0'
|
||||
* to '1' transition.
|
||||
* @por: Power On Reset for the PHY.
|
||||
* Resets all the PHYS registers and state machines.
|
||||
* @enable: When '1' allows the generation of the hclk. When
|
||||
* '0' the hclk will not be generated. SEE DIVIDE
|
||||
* field of this register.
|
||||
* @prst: When this field is '0' the reset associated with
|
||||
* the phy_clk functionality in the USB Subsystem is
|
||||
* help in reset. This bit should not be set to '1'
|
||||
* until the time it takes 6 clocks (hclk or phy_clk,
|
||||
* whichever is slower) has passed. Under normal
|
||||
* operation once this bit is set to '1' it should not
|
||||
* be set to '0'.
|
||||
* @hrst: When this field is '0' the reset associated with
|
||||
* the hclk functioanlity in the USB Subsystem is
|
||||
* held in reset.This bit should not be set to '1'
|
||||
* until 12ms after phy_clk is stable. Under normal
|
||||
* operation, once this bit is set to '1' it should
|
||||
* not be set to '0'.
|
||||
* @divide: The frequency of 'hclk' used by the USB subsystem
|
||||
* is the eclk frequency divided by the value of
|
||||
* (DIVIDE2 + 1) * (DIVIDE + 1), also see the field
|
||||
* DIVIDE2 of this register.
|
||||
* The hclk frequency should be less than 125Mhz.
|
||||
* After writing a value to this field the SW should
|
||||
* read the field for the value written.
|
||||
* The ENABLE field of this register should not be set
|
||||
* until AFTER this field is set and then read.
|
||||
*/
|
||||
struct cvmx_usbnx_clk_ctl_cn50xx {
|
||||
uint64_t reserved_20_63 : 44;
|
||||
uint64_t divide2 : 2;
|
||||
uint64_t hclk_rst : 1;
|
||||
uint64_t reserved_16_16 : 1;
|
||||
uint64_t p_rtype : 2;
|
||||
uint64_t p_com_on : 1;
|
||||
uint64_t p_c_sel : 2;
|
||||
uint64_t cdiv_byp : 1;
|
||||
uint64_t sd_mode : 2;
|
||||
uint64_t s_bist : 1;
|
||||
uint64_t por : 1;
|
||||
uint64_t enable : 1;
|
||||
uint64_t prst : 1;
|
||||
uint64_t hrst : 1;
|
||||
uint64_t divide : 3;
|
||||
} cn50xx;
|
||||
struct cvmx_usbnx_clk_ctl_cn50xx cn52xx;
|
||||
struct cvmx_usbnx_clk_ctl_cn50xx cn56xx;
|
||||
};
|
||||
typedef union cvmx_usbnx_clk_ctl cvmx_usbnx_clk_ctl_t;
|
||||
|
||||
/**
|
||||
* cvmx_usbn#_usbp_ctl_status
|
||||
*
|
||||
* USBN_USBP_CTL_STATUS = USBP Control And Status Register
|
||||
*
|
||||
* Contains general control and status information for the USBN block.
|
||||
*/
|
||||
union cvmx_usbnx_usbp_ctl_status {
|
||||
uint64_t u64;
|
||||
/**
|
||||
* struct cvmx_usbnx_usbp_ctl_status_s
|
||||
* @txrisetune: HS Transmitter Rise/Fall Time Adjustment
|
||||
* @txvreftune: HS DC Voltage Level Adjustment
|
||||
* @txfslstune: FS/LS Source Impedence Adjustment
|
||||
* @txhsxvtune: Transmitter High-Speed Crossover Adjustment
|
||||
* @sqrxtune: Squelch Threshold Adjustment
|
||||
* @compdistune: Disconnect Threshold Adjustment
|
||||
* @otgtune: VBUS Valid Threshold Adjustment
|
||||
* @otgdisable: OTG Block Disable
|
||||
* @portreset: Per_Port Reset
|
||||
* @drvvbus: Drive VBUS
|
||||
* @lsbist: Low-Speed BIST Enable.
|
||||
* @fsbist: Full-Speed BIST Enable.
|
||||
* @hsbist: High-Speed BIST Enable.
|
||||
* @bist_done: PHY Bist Done.
|
||||
* Asserted at the end of the PHY BIST sequence.
|
||||
* @bist_err: PHY Bist Error.
|
||||
* Indicates an internal error was detected during
|
||||
* the BIST sequence.
|
||||
* @tdata_out: PHY Test Data Out.
|
||||
* Presents either internaly generated signals or
|
||||
* test register contents, based upon the value of
|
||||
* test_data_out_sel.
|
||||
* @siddq: Drives the USBP (USB-PHY) SIDDQ input.
|
||||
* Normally should be set to zero.
|
||||
* When customers have no intent to use USB PHY
|
||||
* interface, they should:
|
||||
* - still provide 3.3V to USB_VDD33, and
|
||||
* - tie USB_REXT to 3.3V supply, and
|
||||
* - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
|
||||
* @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
|
||||
* @dma_bmode: When set to 1 the L2C DMA address will be updated
|
||||
* with byte-counts between packets. When set to 0
|
||||
* the L2C DMA address is incremented to the next
|
||||
* 4-byte aligned address after adding byte-count.
|
||||
* @usbc_end: Bigendian input to the USB Core. This should be
|
||||
* set to '0' for operation.
|
||||
* @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
|
||||
* @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
|
||||
* @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D+ line. '1' pull down-resistance is connected
|
||||
* to D+/ '0' pull down resistance is not connected
|
||||
* to D+. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D- line. '1' pull down-resistance is connected
|
||||
* to D-. '0' pull down resistance is not connected
|
||||
* to D-. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @hst_mode: When '0' the USB is acting as HOST, when '1'
|
||||
* USB is acting as device. This field needs to be
|
||||
* set while the USB is in reset.
|
||||
* @tuning: Transmitter Tuning for High-Speed Operation.
|
||||
* Tunes the current supply and rise/fall output
|
||||
* times for high-speed operation.
|
||||
* [20:19] == 11: Current supply increased
|
||||
* approximately 9%
|
||||
* [20:19] == 10: Current supply increased
|
||||
* approximately 4.5%
|
||||
* [20:19] == 01: Design default.
|
||||
* [20:19] == 00: Current supply decreased
|
||||
* approximately 4.5%
|
||||
* [22:21] == 11: Rise and fall times are increased.
|
||||
* [22:21] == 10: Design default.
|
||||
* [22:21] == 01: Rise and fall times are decreased.
|
||||
* [22:21] == 00: Rise and fall times are decreased
|
||||
* further as compared to the 01 setting.
|
||||
* @tx_bs_enh: Transmit Bit Stuffing on [15:8].
|
||||
* Enables or disables bit stuffing on data[15:8]
|
||||
* when bit-stuffing is enabled.
|
||||
* @tx_bs_en: Transmit Bit Stuffing on [7:0].
|
||||
* Enables or disables bit stuffing on data[7:0]
|
||||
* when bit-stuffing is enabled.
|
||||
* @loop_enb: PHY Loopback Test Enable.
|
||||
* '1': During data transmission the receive is
|
||||
* enabled.
|
||||
* '0': During data transmission the receive is
|
||||
* disabled.
|
||||
* Must be '0' for normal operation.
|
||||
* @vtest_enb: Analog Test Pin Enable.
|
||||
* '1' The PHY's analog_test pin is enabled for the
|
||||
* input and output of applicable analog test signals.
|
||||
* '0' THe analog_test pin is disabled.
|
||||
* @bist_enb: Built-In Self Test Enable.
|
||||
* Used to activate BIST in the PHY.
|
||||
* @tdata_sel: Test Data Out Select.
|
||||
* '1' test_data_out[3:0] (PHY) register contents
|
||||
* are output. '0' internaly generated signals are
|
||||
* output.
|
||||
* @taddr_in: Mode Address for Test Interface.
|
||||
* Specifies the register address for writing to or
|
||||
* reading from the PHY test interface register.
|
||||
* @tdata_in: Internal Testing Register Input Data and Select
|
||||
* This is a test bus. Data is present on [3:0],
|
||||
* and its corresponding select (enable) is present
|
||||
* on bits [7:4].
|
||||
* @ate_reset: Reset input from automatic test equipment.
|
||||
* This is a test signal. When the USB Core is
|
||||
* powered up (not in Susned Mode), an automatic
|
||||
* tester can use this to disable phy_clock and
|
||||
* free_clk, then re-eanable them with an aligned
|
||||
* phase.
|
||||
* '1': The phy_clk and free_clk outputs are
|
||||
* disabled. "0": The phy_clock and free_clk outputs
|
||||
* are available within a specific period after the
|
||||
* de-assertion.
|
||||
*/
|
||||
struct cvmx_usbnx_usbp_ctl_status_s {
|
||||
uint64_t txrisetune : 1;
|
||||
uint64_t txvreftune : 4;
|
||||
uint64_t txfslstune : 4;
|
||||
uint64_t txhsxvtune : 2;
|
||||
uint64_t sqrxtune : 3;
|
||||
uint64_t compdistune : 3;
|
||||
uint64_t otgtune : 3;
|
||||
uint64_t otgdisable : 1;
|
||||
uint64_t portreset : 1;
|
||||
uint64_t drvvbus : 1;
|
||||
uint64_t lsbist : 1;
|
||||
uint64_t fsbist : 1;
|
||||
uint64_t hsbist : 1;
|
||||
uint64_t bist_done : 1;
|
||||
uint64_t bist_err : 1;
|
||||
uint64_t tdata_out : 4;
|
||||
uint64_t siddq : 1;
|
||||
uint64_t txpreemphasistune : 1;
|
||||
uint64_t dma_bmode : 1;
|
||||
uint64_t usbc_end : 1;
|
||||
uint64_t usbp_bist : 1;
|
||||
uint64_t tclk : 1;
|
||||
uint64_t dp_pulld : 1;
|
||||
uint64_t dm_pulld : 1;
|
||||
uint64_t hst_mode : 1;
|
||||
uint64_t tuning : 4;
|
||||
uint64_t tx_bs_enh : 1;
|
||||
uint64_t tx_bs_en : 1;
|
||||
uint64_t loop_enb : 1;
|
||||
uint64_t vtest_enb : 1;
|
||||
uint64_t bist_enb : 1;
|
||||
uint64_t tdata_sel : 1;
|
||||
uint64_t taddr_in : 4;
|
||||
uint64_t tdata_in : 8;
|
||||
uint64_t ate_reset : 1;
|
||||
} s;
|
||||
/**
|
||||
* struct cvmx_usbnx_usbp_ctl_status_cn30xx
|
||||
* @bist_done: PHY Bist Done.
|
||||
* Asserted at the end of the PHY BIST sequence.
|
||||
* @bist_err: PHY Bist Error.
|
||||
* Indicates an internal error was detected during
|
||||
* the BIST sequence.
|
||||
* @tdata_out: PHY Test Data Out.
|
||||
* Presents either internaly generated signals or
|
||||
* test register contents, based upon the value of
|
||||
* test_data_out_sel.
|
||||
* @dma_bmode: When set to 1 the L2C DMA address will be updated
|
||||
* with byte-counts between packets. When set to 0
|
||||
* the L2C DMA address is incremented to the next
|
||||
* 4-byte aligned address after adding byte-count.
|
||||
* @usbc_end: Bigendian input to the USB Core. This should be
|
||||
* set to '0' for operation.
|
||||
* @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
|
||||
* @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
|
||||
* @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D+ line. '1' pull down-resistance is connected
|
||||
* to D+/ '0' pull down resistance is not connected
|
||||
* to D+. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D- line. '1' pull down-resistance is connected
|
||||
* to D-. '0' pull down resistance is not connected
|
||||
* to D-. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @hst_mode: When '0' the USB is acting as HOST, when '1'
|
||||
* USB is acting as device. This field needs to be
|
||||
* set while the USB is in reset.
|
||||
* @tuning: Transmitter Tuning for High-Speed Operation.
|
||||
* Tunes the current supply and rise/fall output
|
||||
* times for high-speed operation.
|
||||
* [20:19] == 11: Current supply increased
|
||||
* approximately 9%
|
||||
* [20:19] == 10: Current supply increased
|
||||
* approximately 4.5%
|
||||
* [20:19] == 01: Design default.
|
||||
* [20:19] == 00: Current supply decreased
|
||||
* approximately 4.5%
|
||||
* [22:21] == 11: Rise and fall times are increased.
|
||||
* [22:21] == 10: Design default.
|
||||
* [22:21] == 01: Rise and fall times are decreased.
|
||||
* [22:21] == 00: Rise and fall times are decreased
|
||||
* further as compared to the 01 setting.
|
||||
* @tx_bs_enh: Transmit Bit Stuffing on [15:8].
|
||||
* Enables or disables bit stuffing on data[15:8]
|
||||
* when bit-stuffing is enabled.
|
||||
* @tx_bs_en: Transmit Bit Stuffing on [7:0].
|
||||
* Enables or disables bit stuffing on data[7:0]
|
||||
* when bit-stuffing is enabled.
|
||||
* @loop_enb: PHY Loopback Test Enable.
|
||||
* '1': During data transmission the receive is
|
||||
* enabled.
|
||||
* '0': During data transmission the receive is
|
||||
* disabled.
|
||||
* Must be '0' for normal operation.
|
||||
* @vtest_enb: Analog Test Pin Enable.
|
||||
* '1' The PHY's analog_test pin is enabled for the
|
||||
* input and output of applicable analog test signals.
|
||||
* '0' THe analog_test pin is disabled.
|
||||
* @bist_enb: Built-In Self Test Enable.
|
||||
* Used to activate BIST in the PHY.
|
||||
* @tdata_sel: Test Data Out Select.
|
||||
* '1' test_data_out[3:0] (PHY) register contents
|
||||
* are output. '0' internaly generated signals are
|
||||
* output.
|
||||
* @taddr_in: Mode Address for Test Interface.
|
||||
* Specifies the register address for writing to or
|
||||
* reading from the PHY test interface register.
|
||||
* @tdata_in: Internal Testing Register Input Data and Select
|
||||
* This is a test bus. Data is present on [3:0],
|
||||
* and its corresponding select (enable) is present
|
||||
* on bits [7:4].
|
||||
* @ate_reset: Reset input from automatic test equipment.
|
||||
* This is a test signal. When the USB Core is
|
||||
* powered up (not in Susned Mode), an automatic
|
||||
* tester can use this to disable phy_clock and
|
||||
* free_clk, then re-eanable them with an aligned
|
||||
* phase.
|
||||
* '1': The phy_clk and free_clk outputs are
|
||||
* disabled. "0": The phy_clock and free_clk outputs
|
||||
* are available within a specific period after the
|
||||
* de-assertion.
|
||||
*/
|
||||
struct cvmx_usbnx_usbp_ctl_status_cn30xx {
|
||||
uint64_t reserved_38_63 : 26;
|
||||
uint64_t bist_done : 1;
|
||||
uint64_t bist_err : 1;
|
||||
uint64_t tdata_out : 4;
|
||||
uint64_t reserved_30_31 : 2;
|
||||
uint64_t dma_bmode : 1;
|
||||
uint64_t usbc_end : 1;
|
||||
uint64_t usbp_bist : 1;
|
||||
uint64_t tclk : 1;
|
||||
uint64_t dp_pulld : 1;
|
||||
uint64_t dm_pulld : 1;
|
||||
uint64_t hst_mode : 1;
|
||||
uint64_t tuning : 4;
|
||||
uint64_t tx_bs_enh : 1;
|
||||
uint64_t tx_bs_en : 1;
|
||||
uint64_t loop_enb : 1;
|
||||
uint64_t vtest_enb : 1;
|
||||
uint64_t bist_enb : 1;
|
||||
uint64_t tdata_sel : 1;
|
||||
uint64_t taddr_in : 4;
|
||||
uint64_t tdata_in : 8;
|
||||
uint64_t ate_reset : 1;
|
||||
} cn30xx;
|
||||
/**
|
||||
* struct cvmx_usbnx_usbp_ctl_status_cn50xx
|
||||
* @txrisetune: HS Transmitter Rise/Fall Time Adjustment
|
||||
* @txvreftune: HS DC Voltage Level Adjustment
|
||||
* @txfslstune: FS/LS Source Impedence Adjustment
|
||||
* @txhsxvtune: Transmitter High-Speed Crossover Adjustment
|
||||
* @sqrxtune: Squelch Threshold Adjustment
|
||||
* @compdistune: Disconnect Threshold Adjustment
|
||||
* @otgtune: VBUS Valid Threshold Adjustment
|
||||
* @otgdisable: OTG Block Disable
|
||||
* @portreset: Per_Port Reset
|
||||
* @drvvbus: Drive VBUS
|
||||
* @lsbist: Low-Speed BIST Enable.
|
||||
* @fsbist: Full-Speed BIST Enable.
|
||||
* @hsbist: High-Speed BIST Enable.
|
||||
* @bist_done: PHY Bist Done.
|
||||
* Asserted at the end of the PHY BIST sequence.
|
||||
* @bist_err: PHY Bist Error.
|
||||
* Indicates an internal error was detected during
|
||||
* the BIST sequence.
|
||||
* @tdata_out: PHY Test Data Out.
|
||||
* Presents either internaly generated signals or
|
||||
* test register contents, based upon the value of
|
||||
* test_data_out_sel.
|
||||
* @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
|
||||
* @dma_bmode: When set to 1 the L2C DMA address will be updated
|
||||
* with byte-counts between packets. When set to 0
|
||||
* the L2C DMA address is incremented to the next
|
||||
* 4-byte aligned address after adding byte-count.
|
||||
* @usbc_end: Bigendian input to the USB Core. This should be
|
||||
* set to '0' for operation.
|
||||
* @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
|
||||
* @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
|
||||
* @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D+ line. '1' pull down-resistance is connected
|
||||
* to D+/ '0' pull down resistance is not connected
|
||||
* to D+. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D- line. '1' pull down-resistance is connected
|
||||
* to D-. '0' pull down resistance is not connected
|
||||
* to D-. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @hst_mode: When '0' the USB is acting as HOST, when '1'
|
||||
* USB is acting as device. This field needs to be
|
||||
* set while the USB is in reset.
|
||||
* @tx_bs_enh: Transmit Bit Stuffing on [15:8].
|
||||
* Enables or disables bit stuffing on data[15:8]
|
||||
* when bit-stuffing is enabled.
|
||||
* @tx_bs_en: Transmit Bit Stuffing on [7:0].
|
||||
* Enables or disables bit stuffing on data[7:0]
|
||||
* when bit-stuffing is enabled.
|
||||
* @loop_enb: PHY Loopback Test Enable.
|
||||
* '1': During data transmission the receive is
|
||||
* enabled.
|
||||
* '0': During data transmission the receive is
|
||||
* disabled.
|
||||
* Must be '0' for normal operation.
|
||||
* @vtest_enb: Analog Test Pin Enable.
|
||||
* '1' The PHY's analog_test pin is enabled for the
|
||||
* input and output of applicable analog test signals.
|
||||
* '0' THe analog_test pin is disabled.
|
||||
* @bist_enb: Built-In Self Test Enable.
|
||||
* Used to activate BIST in the PHY.
|
||||
* @tdata_sel: Test Data Out Select.
|
||||
* '1' test_data_out[3:0] (PHY) register contents
|
||||
* are output. '0' internaly generated signals are
|
||||
* output.
|
||||
* @taddr_in: Mode Address for Test Interface.
|
||||
* Specifies the register address for writing to or
|
||||
* reading from the PHY test interface register.
|
||||
* @tdata_in: Internal Testing Register Input Data and Select
|
||||
* This is a test bus. Data is present on [3:0],
|
||||
* and its corresponding select (enable) is present
|
||||
* on bits [7:4].
|
||||
* @ate_reset: Reset input from automatic test equipment.
|
||||
* This is a test signal. When the USB Core is
|
||||
* powered up (not in Susned Mode), an automatic
|
||||
* tester can use this to disable phy_clock and
|
||||
* free_clk, then re-eanable them with an aligned
|
||||
* phase.
|
||||
* '1': The phy_clk and free_clk outputs are
|
||||
* disabled. "0": The phy_clock and free_clk outputs
|
||||
* are available within a specific period after the
|
||||
* de-assertion.
|
||||
*/
|
||||
struct cvmx_usbnx_usbp_ctl_status_cn50xx {
|
||||
uint64_t txrisetune : 1;
|
||||
uint64_t txvreftune : 4;
|
||||
uint64_t txfslstune : 4;
|
||||
uint64_t txhsxvtune : 2;
|
||||
uint64_t sqrxtune : 3;
|
||||
uint64_t compdistune : 3;
|
||||
uint64_t otgtune : 3;
|
||||
uint64_t otgdisable : 1;
|
||||
uint64_t portreset : 1;
|
||||
uint64_t drvvbus : 1;
|
||||
uint64_t lsbist : 1;
|
||||
uint64_t fsbist : 1;
|
||||
uint64_t hsbist : 1;
|
||||
uint64_t bist_done : 1;
|
||||
uint64_t bist_err : 1;
|
||||
uint64_t tdata_out : 4;
|
||||
uint64_t reserved_31_31 : 1;
|
||||
uint64_t txpreemphasistune : 1;
|
||||
uint64_t dma_bmode : 1;
|
||||
uint64_t usbc_end : 1;
|
||||
uint64_t usbp_bist : 1;
|
||||
uint64_t tclk : 1;
|
||||
uint64_t dp_pulld : 1;
|
||||
uint64_t dm_pulld : 1;
|
||||
uint64_t hst_mode : 1;
|
||||
uint64_t reserved_19_22 : 4;
|
||||
uint64_t tx_bs_enh : 1;
|
||||
uint64_t tx_bs_en : 1;
|
||||
uint64_t loop_enb : 1;
|
||||
uint64_t vtest_enb : 1;
|
||||
uint64_t bist_enb : 1;
|
||||
uint64_t tdata_sel : 1;
|
||||
uint64_t taddr_in : 4;
|
||||
uint64_t tdata_in : 8;
|
||||
uint64_t ate_reset : 1;
|
||||
} cn50xx;
|
||||
/**
|
||||
* struct cvmx_usbnx_usbp_ctl_status_cn52xx
|
||||
* @txrisetune: HS Transmitter Rise/Fall Time Adjustment
|
||||
* @txvreftune: HS DC Voltage Level Adjustment
|
||||
* @txfslstune: FS/LS Source Impedence Adjustment
|
||||
* @txhsxvtune: Transmitter High-Speed Crossover Adjustment
|
||||
* @sqrxtune: Squelch Threshold Adjustment
|
||||
* @compdistune: Disconnect Threshold Adjustment
|
||||
* @otgtune: VBUS Valid Threshold Adjustment
|
||||
* @otgdisable: OTG Block Disable
|
||||
* @portreset: Per_Port Reset
|
||||
* @drvvbus: Drive VBUS
|
||||
* @lsbist: Low-Speed BIST Enable.
|
||||
* @fsbist: Full-Speed BIST Enable.
|
||||
* @hsbist: High-Speed BIST Enable.
|
||||
* @bist_done: PHY Bist Done.
|
||||
* Asserted at the end of the PHY BIST sequence.
|
||||
* @bist_err: PHY Bist Error.
|
||||
* Indicates an internal error was detected during
|
||||
* the BIST sequence.
|
||||
* @tdata_out: PHY Test Data Out.
|
||||
* Presents either internaly generated signals or
|
||||
* test register contents, based upon the value of
|
||||
* test_data_out_sel.
|
||||
* @siddq: Drives the USBP (USB-PHY) SIDDQ input.
|
||||
* Normally should be set to zero.
|
||||
* When customers have no intent to use USB PHY
|
||||
* interface, they should:
|
||||
* - still provide 3.3V to USB_VDD33, and
|
||||
* - tie USB_REXT to 3.3V supply, and
|
||||
* - set USBN*_USBP_CTL_STATUS[SIDDQ]=1
|
||||
* @txpreemphasistune: HS Transmitter Pre-Emphasis Enable
|
||||
* @dma_bmode: When set to 1 the L2C DMA address will be updated
|
||||
* with byte-counts between packets. When set to 0
|
||||
* the L2C DMA address is incremented to the next
|
||||
* 4-byte aligned address after adding byte-count.
|
||||
* @usbc_end: Bigendian input to the USB Core. This should be
|
||||
* set to '0' for operation.
|
||||
* @usbp_bist: PHY, This is cleared '0' to run BIST on the USBP.
|
||||
* @tclk: PHY Test Clock, used to load TDATA_IN to the USBP.
|
||||
* @dp_pulld: PHY DP_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D+ line. '1' pull down-resistance is connected
|
||||
* to D+/ '0' pull down resistance is not connected
|
||||
* to D+. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @dm_pulld: PHY DM_PULLDOWN input to the USB-PHY.
|
||||
* This signal enables the pull-down resistance on
|
||||
* the D- line. '1' pull down-resistance is connected
|
||||
* to D-. '0' pull down resistance is not connected
|
||||
* to D-. When an A/B device is acting as a host
|
||||
* (downstream-facing port), dp_pulldown and
|
||||
* dm_pulldown are enabled. This must not toggle
|
||||
* during normal opeartion.
|
||||
* @hst_mode: When '0' the USB is acting as HOST, when '1'
|
||||
* USB is acting as device. This field needs to be
|
||||
* set while the USB is in reset.
|
||||
* @tx_bs_enh: Transmit Bit Stuffing on [15:8].
|
||||
* Enables or disables bit stuffing on data[15:8]
|
||||
* when bit-stuffing is enabled.
|
||||
* @tx_bs_en: Transmit Bit Stuffing on [7:0].
|
||||
* Enables or disables bit stuffing on data[7:0]
|
||||
* when bit-stuffing is enabled.
|
||||
* @loop_enb: PHY Loopback Test Enable.
|
||||
* '1': During data transmission the receive is
|
||||
* enabled.
|
||||
* '0': During data transmission the receive is
|
||||
* disabled.
|
||||
* Must be '0' for normal operation.
|
||||
* @vtest_enb: Analog Test Pin Enable.
|
||||
* '1' The PHY's analog_test pin is enabled for the
|
||||
* input and output of applicable analog test signals.
|
||||
* '0' THe analog_test pin is disabled.
|
||||
* @bist_enb: Built-In Self Test Enable.
|
||||
* Used to activate BIST in the PHY.
|
||||
* @tdata_sel: Test Data Out Select.
|
||||
* '1' test_data_out[3:0] (PHY) register contents
|
||||
* are output. '0' internaly generated signals are
|
||||
* output.
|
||||
* @taddr_in: Mode Address for Test Interface.
|
||||
* Specifies the register address for writing to or
|
||||
* reading from the PHY test interface register.
|
||||
* @tdata_in: Internal Testing Register Input Data and Select
|
||||
* This is a test bus. Data is present on [3:0],
|
||||
* and its corresponding select (enable) is present
|
||||
* on bits [7:4].
|
||||
* @ate_reset: Reset input from automatic test equipment.
|
||||
* This is a test signal. When the USB Core is
|
||||
* powered up (not in Susned Mode), an automatic
|
||||
* tester can use this to disable phy_clock and
|
||||
* free_clk, then re-eanable them with an aligned
|
||||
* phase.
|
||||
* '1': The phy_clk and free_clk outputs are
|
||||
* disabled. "0": The phy_clock and free_clk outputs
|
||||
* are available within a specific period after the
|
||||
* de-assertion.
|
||||
*/
|
||||
struct cvmx_usbnx_usbp_ctl_status_cn52xx {
|
||||
uint64_t txrisetune : 1;
|
||||
uint64_t txvreftune : 4;
|
||||
uint64_t txfslstune : 4;
|
||||
uint64_t txhsxvtune : 2;
|
||||
uint64_t sqrxtune : 3;
|
||||
uint64_t compdistune : 3;
|
||||
uint64_t otgtune : 3;
|
||||
uint64_t otgdisable : 1;
|
||||
uint64_t portreset : 1;
|
||||
uint64_t drvvbus : 1;
|
||||
uint64_t lsbist : 1;
|
||||
uint64_t fsbist : 1;
|
||||
uint64_t hsbist : 1;
|
||||
uint64_t bist_done : 1;
|
||||
uint64_t bist_err : 1;
|
||||
uint64_t tdata_out : 4;
|
||||
uint64_t siddq : 1;
|
||||
uint64_t txpreemphasistune : 1;
|
||||
uint64_t dma_bmode : 1;
|
||||
uint64_t usbc_end : 1;
|
||||
uint64_t usbp_bist : 1;
|
||||
uint64_t tclk : 1;
|
||||
uint64_t dp_pulld : 1;
|
||||
uint64_t dm_pulld : 1;
|
||||
uint64_t hst_mode : 1;
|
||||
uint64_t reserved_19_22 : 4;
|
||||
uint64_t tx_bs_enh : 1;
|
||||
uint64_t tx_bs_en : 1;
|
||||
uint64_t loop_enb : 1;
|
||||
uint64_t vtest_enb : 1;
|
||||
uint64_t bist_enb : 1;
|
||||
uint64_t tdata_sel : 1;
|
||||
uint64_t taddr_in : 4;
|
||||
uint64_t tdata_in : 8;
|
||||
uint64_t ate_reset : 1;
|
||||
} cn52xx;
|
||||
};
|
||||
typedef union cvmx_usbnx_usbp_ctl_status cvmx_usbnx_usbp_ctl_status_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,832 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2008 Cavium Networks
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/octeon/cvmx.h>
|
||||
#include "cvmx-usb.h"
|
||||
#include <asm/octeon/cvmx-iob-defs.h>
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
#include <linux/err.h>
|
||||
|
||||
struct octeon_hcd {
|
||||
spinlock_t lock;
|
||||
cvmx_usb_state_t usb;
|
||||
struct tasklet_struct dequeue_tasklet;
|
||||
struct list_head dequeue_list;
|
||||
};
|
||||
|
||||
/* convert between an HCD pointer and the corresponding struct octeon_hcd */
|
||||
static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
|
||||
{
|
||||
return (struct octeon_hcd *)(hcd->hcd_priv);
|
||||
}
|
||||
|
||||
static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
|
||||
{
|
||||
return container_of((void *)p, struct usb_hcd, hcd_priv);
|
||||
}
|
||||
|
||||
static inline struct octeon_hcd *cvmx_usb_to_octeon(cvmx_usb_state_t *p)
|
||||
{
|
||||
return container_of(p, struct octeon_hcd, usb);
|
||||
}
|
||||
|
||||
static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_poll(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void octeon_usb_port_callback(cvmx_usb_state_t *usb,
|
||||
cvmx_usb_callback_t reason,
|
||||
cvmx_usb_complete_t status,
|
||||
int pipe_handle,
|
||||
int submit_handle,
|
||||
int bytes_transferred,
|
||||
void *user_data)
|
||||
{
|
||||
struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
usb_hcd_poll_rh_status(octeon_to_hcd(priv));
|
||||
spin_lock(&priv->lock);
|
||||
}
|
||||
|
||||
static int octeon_usb_start(struct usb_hcd *hcd)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
unsigned long flags;
|
||||
|
||||
hcd->state = HC_STATE_RUNNING;
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
|
||||
octeon_usb_port_callback, NULL);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void octeon_usb_stop(struct usb_hcd *hcd)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
|
||||
NULL, NULL);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
hcd->state = HC_STATE_HALT;
|
||||
}
|
||||
|
||||
static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
|
||||
return cvmx_usb_get_frame_number(&priv->usb);
|
||||
}
|
||||
|
||||
static void octeon_usb_urb_complete_callback(cvmx_usb_state_t *usb,
|
||||
cvmx_usb_callback_t reason,
|
||||
cvmx_usb_complete_t status,
|
||||
int pipe_handle,
|
||||
int submit_handle,
|
||||
int bytes_transferred,
|
||||
void *user_data)
|
||||
{
|
||||
struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
|
||||
struct usb_hcd *hcd = octeon_to_hcd(priv);
|
||||
struct device *dev = hcd->self.controller;
|
||||
struct urb *urb = user_data;
|
||||
|
||||
urb->actual_length = bytes_transferred;
|
||||
urb->hcpriv = NULL;
|
||||
|
||||
if (!list_empty(&urb->urb_list)) {
|
||||
/*
|
||||
* It is on the dequeue_list, but we are going to call
|
||||
* usb_hcd_giveback_urb(), so we must clear it from
|
||||
* the list. We got to it before the
|
||||
* octeon_usb_urb_dequeue_work() tasklet did.
|
||||
*/
|
||||
list_del(&urb->urb_list);
|
||||
/* No longer on the dequeue_list. */
|
||||
INIT_LIST_HEAD(&urb->urb_list);
|
||||
}
|
||||
|
||||
/* For Isochronous transactions we need to update the URB packet status
|
||||
list from data in our private copy */
|
||||
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
|
||||
int i;
|
||||
/*
|
||||
* The pointer to the private list is stored in the setup_packet
|
||||
* field.
|
||||
*/
|
||||
cvmx_usb_iso_packet_t *iso_packet = (cvmx_usb_iso_packet_t *) urb->setup_packet;
|
||||
/* Recalculate the transfer size by adding up each packet */
|
||||
urb->actual_length = 0;
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
|
||||
urb->iso_frame_desc[i].status = 0;
|
||||
urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
|
||||
urb->actual_length += urb->iso_frame_desc[i].actual_length;
|
||||
} else {
|
||||
dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%d submit=%d size=%d\n",
|
||||
i, urb->number_of_packets,
|
||||
iso_packet[i].status, pipe_handle,
|
||||
submit_handle, iso_packet[i].length);
|
||||
urb->iso_frame_desc[i].status = -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
/* Free the private list now that we don't need it anymore */
|
||||
kfree(iso_packet);
|
||||
urb->setup_packet = NULL;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case CVMX_USB_COMPLETE_SUCCESS:
|
||||
urb->status = 0;
|
||||
break;
|
||||
case CVMX_USB_COMPLETE_CANCEL:
|
||||
if (urb->status == 0)
|
||||
urb->status = -ENOENT;
|
||||
break;
|
||||
case CVMX_USB_COMPLETE_STALL:
|
||||
dev_dbg(dev, "status=stall pipe=%d submit=%d size=%d\n",
|
||||
pipe_handle, submit_handle, bytes_transferred);
|
||||
urb->status = -EPIPE;
|
||||
break;
|
||||
case CVMX_USB_COMPLETE_BABBLEERR:
|
||||
dev_dbg(dev, "status=babble pipe=%d submit=%d size=%d\n",
|
||||
pipe_handle, submit_handle, bytes_transferred);
|
||||
urb->status = -EPIPE;
|
||||
break;
|
||||
case CVMX_USB_COMPLETE_SHORT:
|
||||
dev_dbg(dev, "status=short pipe=%d submit=%d size=%d\n",
|
||||
pipe_handle, submit_handle, bytes_transferred);
|
||||
urb->status = -EREMOTEIO;
|
||||
break;
|
||||
case CVMX_USB_COMPLETE_ERROR:
|
||||
case CVMX_USB_COMPLETE_XACTERR:
|
||||
case CVMX_USB_COMPLETE_DATATGLERR:
|
||||
case CVMX_USB_COMPLETE_FRAMEERR:
|
||||
dev_dbg(dev, "status=%d pipe=%d submit=%d size=%d\n",
|
||||
status, pipe_handle, submit_handle, bytes_transferred);
|
||||
urb->status = -EPROTO;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&priv->lock);
|
||||
usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
|
||||
spin_lock(&priv->lock);
|
||||
}
|
||||
|
||||
static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
|
||||
struct urb *urb,
|
||||
gfp_t mem_flags)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
struct device *dev = hcd->self.controller;
|
||||
int submit_handle = -1;
|
||||
int pipe_handle;
|
||||
unsigned long flags;
|
||||
cvmx_usb_iso_packet_t *iso_packet;
|
||||
struct usb_host_endpoint *ep = urb->ep;
|
||||
|
||||
urb->status = 0;
|
||||
INIT_LIST_HEAD(&urb->urb_list); /* not enqueued on dequeue_list */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
if (!ep->hcpriv) {
|
||||
cvmx_usb_transfer_t transfer_type;
|
||||
cvmx_usb_speed_t speed;
|
||||
int split_device = 0;
|
||||
int split_port = 0;
|
||||
switch (usb_pipetype(urb->pipe)) {
|
||||
case PIPE_ISOCHRONOUS:
|
||||
transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
|
||||
break;
|
||||
case PIPE_INTERRUPT:
|
||||
transfer_type = CVMX_USB_TRANSFER_INTERRUPT;
|
||||
break;
|
||||
case PIPE_CONTROL:
|
||||
transfer_type = CVMX_USB_TRANSFER_CONTROL;
|
||||
break;
|
||||
default:
|
||||
transfer_type = CVMX_USB_TRANSFER_BULK;
|
||||
break;
|
||||
}
|
||||
switch (urb->dev->speed) {
|
||||
case USB_SPEED_LOW:
|
||||
speed = CVMX_USB_SPEED_LOW;
|
||||
break;
|
||||
case USB_SPEED_FULL:
|
||||
speed = CVMX_USB_SPEED_FULL;
|
||||
break;
|
||||
default:
|
||||
speed = CVMX_USB_SPEED_HIGH;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* For slow devices on high speed ports we need to find the hub
|
||||
* that does the speed translation so we know where to send the
|
||||
* split transactions.
|
||||
*/
|
||||
if (speed != CVMX_USB_SPEED_HIGH) {
|
||||
/*
|
||||
* Start at this device and work our way up the usb
|
||||
* tree.
|
||||
*/
|
||||
struct usb_device *dev = urb->dev;
|
||||
while (dev->parent) {
|
||||
/*
|
||||
* If our parent is high speed then he'll
|
||||
* receive the splits.
|
||||
*/
|
||||
if (dev->parent->speed == USB_SPEED_HIGH) {
|
||||
split_device = dev->parent->devnum;
|
||||
split_port = dev->portnum;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Move up the tree one level. If we make it all
|
||||
* the way up the tree, then the port must not
|
||||
* be in high speed mode and we don't need a
|
||||
* split.
|
||||
*/
|
||||
dev = dev->parent;
|
||||
}
|
||||
}
|
||||
pipe_handle = cvmx_usb_open_pipe(&priv->usb,
|
||||
0,
|
||||
usb_pipedevice(urb->pipe),
|
||||
usb_pipeendpoint(urb->pipe),
|
||||
speed,
|
||||
le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
|
||||
transfer_type,
|
||||
usb_pipein(urb->pipe) ? CVMX_USB_DIRECTION_IN : CVMX_USB_DIRECTION_OUT,
|
||||
urb->interval,
|
||||
(le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
|
||||
split_device,
|
||||
split_port);
|
||||
if (pipe_handle < 0) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
dev_dbg(dev, "Failed to create pipe\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ep->hcpriv = (void *)(0x10000L + pipe_handle);
|
||||
} else {
|
||||
pipe_handle = 0xffff & (long)ep->hcpriv;
|
||||
}
|
||||
|
||||
switch (usb_pipetype(urb->pipe)) {
|
||||
case PIPE_ISOCHRONOUS:
|
||||
dev_dbg(dev, "Submit isochronous to %d.%d\n",
|
||||
usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
|
||||
/*
|
||||
* Allocate a structure to use for our private list of
|
||||
* isochronous packets.
|
||||
*/
|
||||
iso_packet = kmalloc(urb->number_of_packets * sizeof(cvmx_usb_iso_packet_t), GFP_ATOMIC);
|
||||
if (iso_packet) {
|
||||
int i;
|
||||
/* Fill the list with the data from the URB */
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
iso_packet[i].offset = urb->iso_frame_desc[i].offset;
|
||||
iso_packet[i].length = urb->iso_frame_desc[i].length;
|
||||
iso_packet[i].status = CVMX_USB_COMPLETE_ERROR;
|
||||
}
|
||||
/*
|
||||
* Store a pointer to the list in the URB setup_packet
|
||||
* field. We know this currently isn't being used and
|
||||
* this saves us a bunch of logic.
|
||||
*/
|
||||
urb->setup_packet = (char *)iso_packet;
|
||||
submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
|
||||
urb->start_frame,
|
||||
0 /* flags */ ,
|
||||
urb->number_of_packets,
|
||||
iso_packet,
|
||||
urb->transfer_dma,
|
||||
urb->transfer_buffer_length,
|
||||
octeon_usb_urb_complete_callback,
|
||||
urb);
|
||||
/*
|
||||
* If submit failed we need to free our private packet
|
||||
* list.
|
||||
*/
|
||||
if (submit_handle < 0) {
|
||||
urb->setup_packet = NULL;
|
||||
kfree(iso_packet);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_INTERRUPT:
|
||||
dev_dbg(dev, "Submit interrupt to %d.%d\n",
|
||||
usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
|
||||
submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle,
|
||||
urb->transfer_dma,
|
||||
urb->transfer_buffer_length,
|
||||
octeon_usb_urb_complete_callback,
|
||||
urb);
|
||||
break;
|
||||
case PIPE_CONTROL:
|
||||
dev_dbg(dev, "Submit control to %d.%d\n",
|
||||
usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
|
||||
submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle,
|
||||
urb->setup_dma,
|
||||
urb->transfer_dma,
|
||||
urb->transfer_buffer_length,
|
||||
octeon_usb_urb_complete_callback,
|
||||
urb);
|
||||
break;
|
||||
case PIPE_BULK:
|
||||
dev_dbg(dev, "Submit bulk to %d.%d\n",
|
||||
usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
|
||||
submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle,
|
||||
urb->transfer_dma,
|
||||
urb->transfer_buffer_length,
|
||||
octeon_usb_urb_complete_callback,
|
||||
urb);
|
||||
break;
|
||||
}
|
||||
if (submit_handle < 0) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
dev_dbg(dev, "Failed to submit\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
urb->hcpriv = (void *)(long)(((submit_handle & 0xffff) << 16) | pipe_handle);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void octeon_usb_urb_dequeue_work(unsigned long arg)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct octeon_hcd *priv = (struct octeon_hcd *)arg;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
while (!list_empty(&priv->dequeue_list)) {
|
||||
int pipe_handle;
|
||||
int submit_handle;
|
||||
struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
|
||||
list_del(&urb->urb_list);
|
||||
/* not enqueued on dequeue_list */
|
||||
INIT_LIST_HEAD(&urb->urb_list);
|
||||
pipe_handle = 0xffff & (long)urb->hcpriv;
|
||||
submit_handle = ((long)urb->hcpriv) >> 16;
|
||||
cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
unsigned long flags;
|
||||
|
||||
if (!urb->dev)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
urb->status = status;
|
||||
list_add_tail(&urb->urb_list, &priv->dequeue_list);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
tasklet_schedule(&priv->dequeue_tasklet);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct device *dev = hcd->self.controller;
|
||||
|
||||
if (ep->hcpriv) {
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
int pipe_handle = 0xffff & (long)ep->hcpriv;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_cancel_all(&priv->usb, pipe_handle);
|
||||
if (cvmx_usb_close_pipe(&priv->usb, pipe_handle))
|
||||
dev_dbg(dev, "Closing pipe %d failed\n", pipe_handle);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
ep->hcpriv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
cvmx_usb_port_status_t port_status;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
port_status = cvmx_usb_get_status(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
buf[0] = 0;
|
||||
buf[0] = port_status.connect_change << 1;
|
||||
|
||||
return (buf[0] != 0);
|
||||
}
|
||||
|
||||
static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
|
||||
{
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
struct device *dev = hcd->self.controller;
|
||||
cvmx_usb_port_status_t usb_port_status;
|
||||
int port_status;
|
||||
struct usb_hub_descriptor *desc;
|
||||
unsigned long flags;
|
||||
|
||||
switch (typeReq) {
|
||||
case ClearHubFeature:
|
||||
dev_dbg(dev, "ClearHubFeature\n");
|
||||
switch (wValue) {
|
||||
case C_HUB_LOCAL_POWER:
|
||||
case C_HUB_OVER_CURRENT:
|
||||
/* Nothing required here */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case ClearPortFeature:
|
||||
dev_dbg(dev, "ClearPortFeature\n");
|
||||
if (wIndex != 1) {
|
||||
dev_dbg(dev, " INVALID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (wValue) {
|
||||
case USB_PORT_FEAT_ENABLE:
|
||||
dev_dbg(dev, " ENABLE\n");
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_disable(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(dev, " SUSPEND\n");
|
||||
/* Not supported on Octeon */
|
||||
break;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
dev_dbg(dev, " POWER\n");
|
||||
/* Not supported on Octeon */
|
||||
break;
|
||||
case USB_PORT_FEAT_INDICATOR:
|
||||
dev_dbg(dev, " INDICATOR\n");
|
||||
/* Port inidicator not supported */
|
||||
break;
|
||||
case USB_PORT_FEAT_C_CONNECTION:
|
||||
dev_dbg(dev, " C_CONNECTION\n");
|
||||
/* Clears drivers internal connect status change flag */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case USB_PORT_FEAT_C_RESET:
|
||||
dev_dbg(dev, " C_RESET\n");
|
||||
/*
|
||||
* Clears the driver's internal Port Reset Change flag.
|
||||
*/
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case USB_PORT_FEAT_C_ENABLE:
|
||||
dev_dbg(dev, " C_ENABLE\n");
|
||||
/*
|
||||
* Clears the driver's internal Port Enable/Disable
|
||||
* Change flag.
|
||||
*/
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
dev_dbg(dev, " C_SUSPEND\n");
|
||||
/*
|
||||
* Clears the driver's internal Port Suspend Change
|
||||
* flag, which is set when resume signaling on the host
|
||||
* port is complete.
|
||||
*/
|
||||
break;
|
||||
case USB_PORT_FEAT_C_OVER_CURRENT:
|
||||
dev_dbg(dev, " C_OVER_CURRENT\n");
|
||||
/* Clears the driver's overcurrent Change flag */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev, " UNKNOWN\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case GetHubDescriptor:
|
||||
dev_dbg(dev, "GetHubDescriptor\n");
|
||||
desc = (struct usb_hub_descriptor *)buf;
|
||||
desc->bDescLength = 9;
|
||||
desc->bDescriptorType = 0x29;
|
||||
desc->bNbrPorts = 1;
|
||||
desc->wHubCharacteristics = 0x08;
|
||||
desc->bPwrOn2PwrGood = 1;
|
||||
desc->bHubContrCurrent = 0;
|
||||
desc->u.hs.DeviceRemovable[0] = 0;
|
||||
desc->u.hs.DeviceRemovable[1] = 0xff;
|
||||
break;
|
||||
case GetHubStatus:
|
||||
dev_dbg(dev, "GetHubStatus\n");
|
||||
*(__le32 *) buf = 0;
|
||||
break;
|
||||
case GetPortStatus:
|
||||
dev_dbg(dev, "GetPortStatus\n");
|
||||
if (wIndex != 1) {
|
||||
dev_dbg(dev, " INVALID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
usb_port_status = cvmx_usb_get_status(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
port_status = 0;
|
||||
|
||||
if (usb_port_status.connect_change) {
|
||||
port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
|
||||
dev_dbg(dev, " C_CONNECTION\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.port_enabled) {
|
||||
port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
|
||||
dev_dbg(dev, " C_ENABLE\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.connected) {
|
||||
port_status |= (1 << USB_PORT_FEAT_CONNECTION);
|
||||
dev_dbg(dev, " CONNECTION\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.port_enabled) {
|
||||
port_status |= (1 << USB_PORT_FEAT_ENABLE);
|
||||
dev_dbg(dev, " ENABLE\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.port_over_current) {
|
||||
port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
|
||||
dev_dbg(dev, " OVER_CURRENT\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.port_powered) {
|
||||
port_status |= (1 << USB_PORT_FEAT_POWER);
|
||||
dev_dbg(dev, " POWER\n");
|
||||
}
|
||||
|
||||
if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
|
||||
port_status |= USB_PORT_STAT_HIGH_SPEED;
|
||||
dev_dbg(dev, " HIGHSPEED\n");
|
||||
} else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
|
||||
port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
|
||||
dev_dbg(dev, " LOWSPEED\n");
|
||||
}
|
||||
|
||||
*((__le32 *) buf) = cpu_to_le32(port_status);
|
||||
break;
|
||||
case SetHubFeature:
|
||||
dev_dbg(dev, "SetHubFeature\n");
|
||||
/* No HUB features supported */
|
||||
break;
|
||||
case SetPortFeature:
|
||||
dev_dbg(dev, "SetPortFeature\n");
|
||||
if (wIndex != 1) {
|
||||
dev_dbg(dev, " INVALID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (wValue) {
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(dev, " SUSPEND\n");
|
||||
return -EINVAL;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
dev_dbg(dev, " POWER\n");
|
||||
return -EINVAL;
|
||||
case USB_PORT_FEAT_RESET:
|
||||
dev_dbg(dev, " RESET\n");
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_disable(&priv->usb);
|
||||
if (cvmx_usb_enable(&priv->usb))
|
||||
dev_dbg(dev, "Failed to enable the port\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return 0;
|
||||
case USB_PORT_FEAT_INDICATOR:
|
||||
dev_dbg(dev, " INDICATOR\n");
|
||||
/* Not supported */
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev, " UNKNOWN\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev, "Unknown root hub request\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct hc_driver octeon_hc_driver = {
|
||||
.description = "Octeon USB",
|
||||
.product_desc = "Octeon Host Controller",
|
||||
.hcd_priv_size = sizeof(struct octeon_hcd),
|
||||
.irq = octeon_usb_irq,
|
||||
.flags = HCD_MEMORY | HCD_USB2,
|
||||
.start = octeon_usb_start,
|
||||
.stop = octeon_usb_stop,
|
||||
.urb_enqueue = octeon_usb_urb_enqueue,
|
||||
.urb_dequeue = octeon_usb_urb_dequeue,
|
||||
.endpoint_disable = octeon_usb_endpoint_disable,
|
||||
.get_frame_number = octeon_usb_get_frame_number,
|
||||
.hub_status_data = octeon_usb_hub_status_data,
|
||||
.hub_control = octeon_usb_hub_control,
|
||||
};
|
||||
|
||||
|
||||
static int octeon_usb_driver_probe(struct device *dev)
|
||||
{
|
||||
int status;
|
||||
int usb_num = to_platform_device(dev)->id;
|
||||
int irq = platform_get_irq(to_platform_device(dev), 0);
|
||||
struct octeon_hcd *priv;
|
||||
struct usb_hcd *hcd;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Set the DMA mask to 64bits so we get buffers already translated for
|
||||
* DMA.
|
||||
*/
|
||||
dev->coherent_dma_mask = ~0;
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
|
||||
hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
|
||||
if (!hcd) {
|
||||
dev_dbg(dev, "Failed to allocate memory for HCD\n");
|
||||
return -1;
|
||||
}
|
||||
hcd->uses_new_polling = 1;
|
||||
priv = (struct octeon_hcd *)hcd->hcd_priv;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
|
||||
INIT_LIST_HEAD(&priv->dequeue_list);
|
||||
|
||||
status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
|
||||
if (status) {
|
||||
dev_dbg(dev, "USB initialization failed with %d\n", status);
|
||||
kfree(hcd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This delay is needed for CN3010, but I don't know why... */
|
||||
mdelay(10);
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cvmx_usb_poll(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
status = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
if (status) {
|
||||
dev_dbg(dev, "USB add HCD failed with %d\n", status);
|
||||
kfree(hcd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int octeon_usb_driver_remove(struct device *dev)
|
||||
{
|
||||
int status;
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
unsigned long flags;
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
tasklet_kill(&priv->dequeue_tasklet);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = cvmx_usb_shutdown(&priv->usb);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
if (status)
|
||||
dev_dbg(dev, "USB shutdown failed with %d\n", status);
|
||||
|
||||
kfree(hcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver octeon_usb_driver = {
|
||||
.name = "OcteonUSB",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = octeon_usb_driver_probe,
|
||||
.remove = octeon_usb_driver_remove,
|
||||
};
|
||||
|
||||
|
||||
#define MAX_USB_PORTS 10
|
||||
static struct platform_device *pdev_glob[MAX_USB_PORTS];
|
||||
static int octeon_usb_registered;
|
||||
static int __init octeon_usb_module_init(void)
|
||||
{
|
||||
int num_devices = cvmx_usb_get_num_ports();
|
||||
int device;
|
||||
|
||||
if (usb_disabled() || num_devices == 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (driver_register(&octeon_usb_driver))
|
||||
return -ENOMEM;
|
||||
|
||||
octeon_usb_registered = 1;
|
||||
|
||||
/*
|
||||
* Only cn52XX and cn56XX have DWC_OTG USB hardware and the
|
||||
* IOB priority registers. Under heavy network load USB
|
||||
* hardware can be starved by the IOB causing a crash. Give
|
||||
* it a priority boost if it has been waiting more than 400
|
||||
* cycles to avoid this situation.
|
||||
*
|
||||
* Testing indicates that a cnt_val of 8192 is not sufficient,
|
||||
* but no failures are seen with 4096. We choose a value of
|
||||
* 400 to give a safety factor of 10.
|
||||
*/
|
||||
if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
|
||||
union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
|
||||
|
||||
pri_cnt.u64 = 0;
|
||||
pri_cnt.s.cnt_enb = 1;
|
||||
pri_cnt.s.cnt_val = 400;
|
||||
cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
|
||||
}
|
||||
|
||||
for (device = 0; device < num_devices; device++) {
|
||||
struct resource irq_resource;
|
||||
struct platform_device *pdev;
|
||||
memset(&irq_resource, 0, sizeof(irq_resource));
|
||||
irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
|
||||
irq_resource.end = irq_resource.start;
|
||||
irq_resource.flags = IORESOURCE_IRQ;
|
||||
pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1);
|
||||
if (IS_ERR(pdev)) {
|
||||
driver_unregister(&octeon_usb_driver);
|
||||
octeon_usb_registered = 0;
|
||||
return PTR_ERR(pdev);
|
||||
}
|
||||
if (device < MAX_USB_PORTS)
|
||||
pdev_glob[device] = pdev;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit octeon_usb_module_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_USB_PORTS; i++)
|
||||
if (pdev_glob[i]) {
|
||||
platform_device_unregister(pdev_glob[i]);
|
||||
pdev_glob[i] = NULL;
|
||||
}
|
||||
if (octeon_usb_registered)
|
||||
driver_unregister(&octeon_usb_driver);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
|
||||
MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
|
||||
module_init(octeon_usb_module_init);
|
||||
module_exit(octeon_usb_module_cleanup);
|
26
target/linux/octeon/image/Makefile
Normal file
26
target/linux/octeon/image/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# Copyright (C) 2009-2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
define Image/BuildKernel
|
||||
# Workaround pre-SDK-1.9.0 u-boot versions not handling the .notes section
|
||||
$(TARGET_CROSS)strip -R .notes $(KDIR)/vmlinux.elf -o $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.elf
|
||||
$(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.bin.l7
|
||||
dd if=$(KDIR)/vmlinux.bin.l7 of=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux.lzma bs=65536 conv=sync
|
||||
endef
|
||||
|
||||
define Image/Build/squashfs
|
||||
$(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1))
|
||||
dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
|
||||
endef
|
||||
|
||||
$(eval $(call BuildImage))
|
|
@ -0,0 +1,46 @@
|
|||
From ab2bb148c5932712d2717a7f3a452846f07a660a Mon Sep 17 00:00:00 2001
|
||||
From: Faidon Liambotis <paravoid@debian.org>
|
||||
Date: Thu, 11 Jul 2013 21:08:09 +0000
|
||||
Subject: [PATCH] MIPS: Octeon: Fix DT pruning bug with pip ports
|
||||
|
||||
During the pruning of the device tree octeon_fdt_pip_iface() is called
|
||||
for each PIP interface and every port up to the port count is removed
|
||||
from the device tree. However, the count was set to the return value of
|
||||
cvmx_helper_interface_enumerate() which doesn't actually return the
|
||||
count but just returns zero on success. This effectively removed *all*
|
||||
ports from the tree.
|
||||
|
||||
Use cvmx_helper_ports_on_interface() instead to fix this. This
|
||||
successfully restores the 3 ports of my ERLite-3 and fixes the "kernel
|
||||
assigns random MAC addresses" issue.
|
||||
|
||||
Signed-off-by: Faidon Liambotis <paravoid@debian.org>
|
||||
Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Acked-by: David Daney <david.daney@cavium.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/5587/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/cavium-octeon/octeon-platform.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
|
||||
index 7b746e7..1830874 100644
|
||||
--- a/arch/mips/cavium-octeon/octeon-platform.c
|
||||
+++ b/arch/mips/cavium-octeon/octeon-platform.c
|
||||
@@ -334,9 +334,10 @@ static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
|
||||
char name_buffer[20];
|
||||
int iface;
|
||||
int p;
|
||||
- int count;
|
||||
+ int count = 0;
|
||||
|
||||
- count = cvmx_helper_interface_enumerate(idx);
|
||||
+ if (cvmx_helper_interface_enumerate(idx) == 0)
|
||||
+ count = cvmx_helper_ports_on_interface(idx);
|
||||
|
||||
snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
|
||||
iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
|
||||
--
|
||||
1.7.10.4
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
From a135a9b5d9683ace787c7d86f1e642d9acfacdde Mon Sep 17 00:00:00 2001
|
||||
From: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Date: Sun, 23 Jun 2013 20:38:44 +0000
|
||||
Subject: [PATCH] MIPS: Octeon: Enable interfaces on EdgeRouter Lite
|
||||
|
||||
Enable interfaces on EdgeRouter Lite. Tested with cavium_octeon_defconfig
|
||||
and busybox shell. DHCP & ping works with eth0, eth1 and eth2.
|
||||
|
||||
The board type "UBNT_E100" is taken from the sources of the vendor kernel
|
||||
shipped with the product.
|
||||
|
||||
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Acked-by: David Daney <david.daney@cavium.com>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Patchwork: https://patchwork.linux-mips.org/patch/5546/
|
||||
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||||
---
|
||||
arch/mips/cavium-octeon/executive/cvmx-helper-board.c | 13 +++++++++++++
|
||||
arch/mips/include/asm/octeon/cvmx-bootinfo.h | 2 ++
|
||||
2 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
|
||||
index 7c64977..0a1283c 100644
|
||||
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
|
||||
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
|
||||
@@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
|
||||
return ipd_port - 16 + 4;
|
||||
else
|
||||
return -1;
|
||||
+ case CVMX_BOARD_TYPE_UBNT_E100:
|
||||
+ if (ipd_port >= 0 && ipd_port <= 2)
|
||||
+ return 7 - ipd_port;
|
||||
+ else
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/* Some unknown board. Somebody forgot to update this function... */
|
||||
@@ -706,6 +711,14 @@ int __cvmx_helper_board_hardware_enable(int interface)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ } else if (cvmx_sysinfo_get()->board_type ==
|
||||
+ CVMX_BOARD_TYPE_UBNT_E100) {
|
||||
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
|
||||
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
|
||||
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
|
||||
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
|
||||
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
|
||||
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
|
||||
index 284fa8d..7b7818d 100644
|
||||
--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
|
||||
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
|
||||
@@ -227,6 +227,7 @@ enum cvmx_board_types_enum {
|
||||
* use any numbers in this range.
|
||||
*/
|
||||
CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
|
||||
+ CVMX_BOARD_TYPE_UBNT_E100 = 20002,
|
||||
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
|
||||
|
||||
/* The remaining range is reserved for future use. */
|
||||
@@ -325,6 +326,7 @@ static inline const char *cvmx_board_type_to_string(enum
|
||||
|
||||
/* Customer private range */
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
|
||||
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
|
||||
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
|
||||
}
|
||||
return "Unsupported Board";
|
||||
--
|
||||
1.7.10.4
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
From b164935b38d64557a32892e7aa45e213e9d11ea8 Mon Sep 17 00:00:00 2001
|
||||
From: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Date: Sat, 1 Jun 2013 21:42:58 +0300
|
||||
Subject: [PATCH] staging: MIPS: add Octeon USB HCD support
|
||||
|
||||
Add support for Octeon USB HCD. Tested on EdgeRouter Lite with USB
|
||||
mass storage.
|
||||
|
||||
The driver has been extracted from GPL sources of EdgeRouter Lite firmware
|
||||
(based on Linux 2.6.32.13). Some minor fixes and cleanups have been done
|
||||
to make it work with 3.10-rc3.
|
||||
|
||||
$ uname -a
|
||||
Linux (none) 3.10.0-rc3-edge-00005-g86cb5bc #41 SMP PREEMPT Sat Jun 1 20:41:46 EEST 2013 mips64 GNU/Linux
|
||||
$ modprobe octeon-usb
|
||||
[ 37.971683] octeon_usb: module is from the staging directory, the quality is unknown, you have been warned.
|
||||
[ 37.983649] OcteonUSB: Detected 1 ports
|
||||
[ 37.999360] OcteonUSB OcteonUSB.0: Octeon Host Controller
|
||||
[ 38.004847] OcteonUSB OcteonUSB.0: new USB bus registered, assigned bus number 1
|
||||
[ 38.012332] OcteonUSB OcteonUSB.0: irq 122, io mem 0x00000000
|
||||
[ 38.019970] hub 1-0:1.0: USB hub found
|
||||
[ 38.023851] hub 1-0:1.0: 1 port detected
|
||||
[ 38.028101] OcteonUSB: Registered HCD for port 0 on irq 122
|
||||
[ 38.391443] usb 1-1: new high-speed USB device number 2 using OcteonUSB
|
||||
[ 38.586922] usb-storage 1-1:1.0: USB Mass Storage device detected
|
||||
[ 38.597375] scsi0 : usb-storage 1-1:1.0
|
||||
[ 39.604111] scsi 0:0:0:0: Direct-Access USB DISK 2.0 PMAP PQ: 0 ANSI: 4
|
||||
[ 39.619113] sd 0:0:0:0: [sda] 7579008 512-byte logical blocks: (3.88 GB/3.61 GiB)
|
||||
[ 39.630696] sd 0:0:0:0: [sda] Write Protect is off
|
||||
[ 39.635945] sd 0:0:0:0: [sda] No Caching mode page present
|
||||
[ 39.641464] sd 0:0:0:0: [sda] Assuming drive cache: write through
|
||||
[ 39.651341] sd 0:0:0:0: [sda] No Caching mode page present
|
||||
[ 39.656917] sd 0:0:0:0: [sda] Assuming drive cache: write through
|
||||
[ 39.664296] sda: sda1 sda2
|
||||
[ 39.675574] sd 0:0:0:0: [sda] No Caching mode page present
|
||||
[ 39.681093] sd 0:0:0:0: [sda] Assuming drive cache: write through
|
||||
[ 39.687223] sd 0:0:0:0: [sda] Attached SCSI removable disk
|
||||
|
||||
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Cc: David Daney <ddaney.cavm@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/staging/Kconfig | 2 +
|
||||
drivers/staging/Makefile | 1 +
|
||||
drivers/staging/octeon-usb/Kconfig | 10 +
|
||||
drivers/staging/octeon-usb/Makefile | 3 +
|
||||
drivers/staging/octeon-usb/TODO | 11 +
|
||||
drivers/staging/octeon-usb/cvmx-usb.c | 3344 ++++++++++++++++++++++++++
|
||||
drivers/staging/octeon-usb/cvmx-usb.h | 1085 +++++++++
|
||||
drivers/staging/octeon-usb/cvmx-usbcx-defs.h | 3086 ++++++++++++++++++++++++
|
||||
drivers/staging/octeon-usb/cvmx-usbnx-defs.h | 1596 ++++++++++++
|
||||
drivers/staging/octeon-usb/octeon-hcd.c | 854 +++++++
|
||||
10 files changed, 9992 insertions(+)
|
||||
create mode 100644 drivers/staging/octeon-usb/Kconfig
|
||||
create mode 100644 drivers/staging/octeon-usb/Makefile
|
||||
create mode 100644 drivers/staging/octeon-usb/TODO
|
||||
create mode 100644 drivers/staging/octeon-usb/cvmx-usb.c
|
||||
create mode 100644 drivers/staging/octeon-usb/cvmx-usb.h
|
||||
create mode 100644 drivers/staging/octeon-usb/cvmx-usbcx-defs.h
|
||||
create mode 100644 drivers/staging/octeon-usb/cvmx-usbnx-defs.h
|
||||
create mode 100644 drivers/staging/octeon-usb/octeon-hcd.c
|
||||
|
||||
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
|
||||
index 4464f26..f64b662 100644
|
||||
--- a/drivers/staging/Kconfig
|
||||
+++ b/drivers/staging/Kconfig
|
||||
@@ -62,6 +62,8 @@ source "drivers/staging/line6/Kconfig"
|
||||
|
||||
source "drivers/staging/octeon/Kconfig"
|
||||
|
||||
+source "drivers/staging/octeon-usb/Kconfig"
|
||||
+
|
||||
source "drivers/staging/serqt_usb2/Kconfig"
|
||||
|
||||
source "drivers/staging/vt6655/Kconfig"
|
||||
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
|
||||
index f689b9d..1fb58a1 100644
|
||||
--- a/drivers/staging/Makefile
|
||||
+++ b/drivers/staging/Makefile
|
||||
@@ -25,6 +25,7 @@ obj-$(CONFIG_LINE6_USB) += line6/
|
||||
obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
|
||||
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
|
||||
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
|
||||
+obj-$(CONFIG_OCTEON_USB) += octeon-usb/
|
||||
obj-$(CONFIG_VT6655) += vt6655/
|
||||
obj-$(CONFIG_VT6656) += vt6656/
|
||||
obj-$(CONFIG_VME_BUS) += vme/
|
115
target/linux/octeon/patches-3.10/0004-fix_hcd.patch
Normal file
115
target/linux/octeon/patches-3.10/0004-fix_hcd.patch
Normal file
|
@ -0,0 +1,115 @@
|
|||
Index: linux-3.10/drivers/staging/octeon-usb/octeon-hcd.c
|
||||
===================================================================
|
||||
--- linux-3.10.orig/drivers/staging/octeon-usb/octeon-hcd.c 2013-08-03 16:11:44.269610286 +0200
|
||||
+++ linux-3.10/drivers/staging/octeon-usb/octeon-hcd.c 2013-08-04 13:18:54.011421971 +0200
|
||||
@@ -673,8 +673,9 @@
|
||||
};
|
||||
|
||||
|
||||
-static int octeon_usb_driver_probe(struct device *dev)
|
||||
+static int octeon_usb_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
int status;
|
||||
int usb_num = to_platform_device(dev)->id;
|
||||
int irq = platform_get_irq(to_platform_device(dev), 0);
|
||||
@@ -728,8 +729,9 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int octeon_usb_driver_remove(struct device *dev)
|
||||
+static int octeon_usb_driver_remove(struct platform_device *pdev)
|
||||
{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
int status;
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct octeon_hcd *priv = hcd_to_octeon(hcd);
|
||||
@@ -748,30 +750,35 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct device_driver octeon_usb_driver = {
|
||||
- .name = "OcteonUSB",
|
||||
- .bus = &platform_bus_type,
|
||||
+static struct platform_driver octeon_usb_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "OcteonUSB",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
.probe = octeon_usb_driver_probe,
|
||||
.remove = octeon_usb_driver_remove,
|
||||
};
|
||||
|
||||
+static struct resource octeon_usb_resources = {
|
||||
+ .start = OCTEON_IRQ_USB0,
|
||||
+ .end = OCTEON_IRQ_USB0,
|
||||
+ .flags = IORESOURCE_IRQ,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device octeon_usb_device = {
|
||||
+ .name = "OcteonUSB",
|
||||
+ .id = 0,
|
||||
+ .resource = &octeon_usb_resources,
|
||||
+ .num_resources = 1,
|
||||
+};
|
||||
|
||||
-#define MAX_USB_PORTS 10
|
||||
-static struct platform_device *pdev_glob[MAX_USB_PORTS];
|
||||
-static int octeon_usb_registered;
|
||||
static int __init octeon_usb_module_init(void)
|
||||
{
|
||||
int num_devices = cvmx_usb_get_num_ports();
|
||||
- int device;
|
||||
|
||||
if (usb_disabled() || num_devices == 0)
|
||||
return -ENODEV;
|
||||
|
||||
- if (driver_register(&octeon_usb_driver))
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- octeon_usb_registered = 1;
|
||||
-
|
||||
/*
|
||||
* Only cn52XX and cn56XX have DWC_OTG USB hardware and the
|
||||
* IOB priority registers. Under heavy network load USB
|
||||
@@ -792,37 +799,14 @@
|
||||
cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
|
||||
}
|
||||
|
||||
- for (device = 0; device < num_devices; device++) {
|
||||
- struct resource irq_resource;
|
||||
- struct platform_device *pdev;
|
||||
- memset(&irq_resource, 0, sizeof(irq_resource));
|
||||
- irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
|
||||
- irq_resource.end = irq_resource.start;
|
||||
- irq_resource.flags = IORESOURCE_IRQ;
|
||||
- pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1);
|
||||
- if (IS_ERR(pdev)) {
|
||||
- driver_unregister(&octeon_usb_driver);
|
||||
- octeon_usb_registered = 0;
|
||||
- return PTR_ERR(pdev);
|
||||
- }
|
||||
- if (device < MAX_USB_PORTS)
|
||||
- pdev_glob[device] = pdev;
|
||||
+ platform_device_register(&octeon_usb_device);
|
||||
|
||||
- }
|
||||
- return 0;
|
||||
+ return platform_driver_register(&octeon_usb_driver);
|
||||
}
|
||||
|
||||
static void __exit octeon_usb_module_cleanup(void)
|
||||
{
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < MAX_USB_PORTS; i++)
|
||||
- if (pdev_glob[i]) {
|
||||
- platform_device_unregister(pdev_glob[i]);
|
||||
- pdev_glob[i] = NULL;
|
||||
- }
|
||||
- if (octeon_usb_registered)
|
||||
- driver_unregister(&octeon_usb_driver);
|
||||
+ platform_driver_unregister(&octeon_usb_driver);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
17
target/linux/octeon/profiles/000-Generic.mk
Normal file
17
target/linux/octeon/profiles/000-Generic.mk
Normal file
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Copyright (C) 2013 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/generic
|
||||
NAME:=Generic Octeon board
|
||||
PACKAGES:=kmod-ath9k
|
||||
endef
|
||||
|
||||
define Profile/generic/Description
|
||||
Base packages for Octeon boards.
|
||||
endef
|
||||
$(eval $(call Profile,generic))
|
||||
|
Loading…
Reference in a new issue