// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> * (C) Copyright 2002 Hewlett-Packard Company * * Bus Glue for pxa27x * * Written by Christopher Hoover <ch@hpl.hp.com> * Based on fragments of previous driver by Russell King et al. * * Modified for LH7A404 from ohci-sa1111.c * by Durgesh Pattamatta <pattamattad@sharpsec.com> * * Modified for pxa27x from ohci-lh7a404.c * by Nick Bane <nick@cecomputing.co.uk> 26-8-2004 * * This file is licenced under the GPL.
*/
#define UHCRHDA (0x0048) /* UHC Root Hub Descriptor A */ #define UHCRHDA_NOCP (1 << 12) /* No over current protection */ #define UHCRHDA_OCPM (1 << 11) /* Over Current Protection Mode */ #define UHCRHDA_POTPGT(x) \
(((x) & 0xff) << 24) /* Power On To Power Good Time */
#define UHCRHDB (0x004C) /* UHC Root Hub Descriptor B */ #define UHCRHS (0x0050) /* UHC Root Hub Status */ #define UHCRHPS1 (0x0054) /* UHC Root Hub Port 1 Status */ #define UHCRHPS2 (0x0058) /* UHC Root Hub Port 2 Status */ #define UHCRHPS3 (0x005C) /* UHC Root Hub Port 3 Status */
#define UHCSTAT (0x0060) /* UHC Status Register */ #define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */ #define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/ #define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/ #define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */ #define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */ #define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */ #define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */ #define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */ #define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */
#define UHCHR (0x0064) /* UHC Reset Register */ #define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */ #define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */ #define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */ #define UHCHR_PCPL (1 << 7) /* Power control polarity low */ #define UHCHR_PSPL (1 << 6) /* Power sense polarity low */ #define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */ #define UHCHR_UIT (1 << 4) /* USB Interrupt Test */ #define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */ #define UHCHR_CGR (1 << 2) /* Clock Generation Reset */ #define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */ #define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */
#define UHCHIE (0x0068) /* UHC Interrupt Enable Register*/ #define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */ #define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */ #define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */ #define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */ #define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort
Interrupt Enable*/ #define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */ #define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */
#define UHCHIT (0x006C) /* UHC Interrupt Test register */
PMM_GLOBAL_MODE -- PMM global switching mode All ports are powered at the same time.
PMM_PERPORT_MODE -- PMM per port switching mode Ports are powered individually.
*/ staticint pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)
{
uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);
switch (mode) { case PMM_NPS_MODE:
uhcrhda |= RH_A_NPS; break; case PMM_GLOBAL_MODE:
uhcrhda &= ~(RH_A_NPS | RH_A_PSM); break; case PMM_PERPORT_MODE:
uhcrhda &= ~(RH_A_NPS);
uhcrhda |= RH_A_PSM;
/* Set port power control mask bits, only 3 ports. */
uhcrhdb |= (0x7<<17); break; default:
printk( KERN_ERR "Invalid mode %d, set to non-power switch mode.\n",
mode );
staticint pxa27x_ohci_set_vbus_power(struct pxa27x_ohci *pxa_ohci, unsignedint port, bool enable)
{ struct regulator *vbus = pxa_ohci->vbus[port]; int ret = 0;
if (IS_ERR_OR_NULL(vbus)) return 0;
if (enable && !pxa_ohci->vbus_enabled[port])
ret = regulator_enable(vbus); elseif (!enable && pxa_ohci->vbus_enabled[port])
ret = regulator_disable(vbus);
/* Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away.
*/
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (ret) return ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM;
if (of_property_read_bool(np, "marvell,enable-port1"))
pdata->flags |= ENABLE_PORT1; if (of_property_read_bool(np, "marvell,enable-port2"))
pdata->flags |= ENABLE_PORT2; if (of_property_read_bool(np, "marvell,enable-port3"))
pdata->flags |= ENABLE_PORT3; if (of_property_read_bool(np, "marvell,port-sense-low"))
pdata->flags |= POWER_SENSE_LOW; if (of_property_read_bool(np, "marvell,power-control-low"))
pdata->flags |= POWER_CONTROL_LOW; if (of_property_read_bool(np, "marvell,no-oc-protection"))
pdata->flags |= NO_OC_PROTECTION; if (of_property_read_bool(np, "marvell,oc-mode-perport"))
pdata->flags |= OC_MODE_PERPORT; if (!of_property_read_u32(np, "marvell,power-on-delay", &tmp))
pdata->power_on_delay = tmp; if (!of_property_read_u32(np, "marvell,port-mode", &tmp))
pdata->port_mode = tmp; if (!of_property_read_u32(np, "marvell,power-budget", &tmp))
pdata->power_budget = tmp;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.