Path: blob/master/drivers/firewire/init_ohci1394_dma.c
15109 views
/*1* init_ohci1394_dma.c - Initializes physical DMA on all OHCI 1394 controllers2*3* Copyright (C) 2006-2007 Bernhard Kaindl <[email protected]>4*5* Derived from drivers/ieee1394/ohci1394.c and arch/x86/kernel/early-quirks.c6* this file has functions to:7* - scan the PCI very early on boot for all OHCI 1394-compliant controllers8* - reset and initialize them and make them join the IEEE1394 bus and9* - enable physical DMA on them to allow remote debugging10*11* All code and data is marked as __init and __initdata, respective as12* during boot, all OHCI1394 controllers may be claimed by the firewire13* stack and at this point, this code should not touch them anymore.14*15* To use physical DMA after the initialization of the firewire stack,16* be sure that the stack enables it and (re-)attach after the bus reset17* which may be caused by the firewire stack initialization.18*19* This program is free software; you can redistribute it and/or modify20* it under the terms of the GNU General Public License as published by21* the Free Software Foundation; either version 2 of the License, or22* (at your option) any later version.23*24* This program is distributed in the hope that it will be useful,25* but WITHOUT ANY WARRANTY; without even the implied warranty of26* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the27* GNU General Public License for more details.28*29* You should have received a copy of the GNU General Public License30* along with this program; if not, write to the Free Software Foundation,31* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.32*/3334#include <linux/delay.h>35#include <linux/io.h>36#include <linux/kernel.h>37#include <linux/pci.h> /* for PCI defines */38#include <linux/string.h>3940#include <asm/pci-direct.h> /* for direct PCI config space access */41#include <asm/fixmap.h>4243#include <linux/init_ohci1394_dma.h>44#include "ohci.h"4546int __initdata init_ohci1394_dma_early;4748struct ohci {49void __iomem *registers;50};5152static inline void reg_write(const struct ohci *ohci, int offset, u32 data)53{54writel(data, ohci->registers + offset);55}5657static inline u32 reg_read(const struct ohci *ohci, int offset)58{59return readl(ohci->registers + offset);60}6162#define OHCI_LOOP_COUNT 100 /* Number of loops for reg read waits */6364/* Reads a PHY register of an OHCI-1394 controller */65static inline u8 __init get_phy_reg(struct ohci *ohci, u8 addr)66{67int i;68u32 r;6970reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);7172for (i = 0; i < OHCI_LOOP_COUNT; i++) {73if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)74break;75mdelay(1);76}77r = reg_read(ohci, OHCI1394_PhyControl);7879return (r & 0x00ff0000) >> 16;80}8182/* Writes to a PHY register of an OHCI-1394 controller */83static inline void __init set_phy_reg(struct ohci *ohci, u8 addr, u8 data)84{85int i;8687reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);8889for (i = 0; i < OHCI_LOOP_COUNT; i++) {90if (!(reg_read(ohci, OHCI1394_PhyControl) & 0x00004000))91break;92mdelay(1);93}94}9596/* Resets an OHCI-1394 controller (for sane state before initialization) */97static inline void __init init_ohci1394_soft_reset(struct ohci *ohci)98{99int i;100101reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);102103for (i = 0; i < OHCI_LOOP_COUNT; i++) {104if (!(reg_read(ohci, OHCI1394_HCControlSet)105& OHCI1394_HCControl_softReset))106break;107mdelay(1);108}109}110111#define OHCI1394_MAX_AT_REQ_RETRIES 0xf112#define OHCI1394_MAX_AT_RESP_RETRIES 0x2113#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8114115/* Basic OHCI-1394 register and port inititalization */116static inline void __init init_ohci1394_initialize(struct ohci *ohci)117{118u32 bus_options;119int num_ports, i;120121/* Put some defaults to these undefined bus options */122bus_options = reg_read(ohci, OHCI1394_BusOptions);123bus_options |= 0x60000000; /* Enable CMC and ISC */124bus_options &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */125bus_options &= ~0x18000000; /* Disable PMC and BMC */126reg_write(ohci, OHCI1394_BusOptions, bus_options);127128/* Set the bus number */129reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);130131/* Enable posted writes */132reg_write(ohci, OHCI1394_HCControlSet,133OHCI1394_HCControl_postedWriteEnable);134135/* Clear link control register */136reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);137138/* enable phys */139reg_write(ohci, OHCI1394_LinkControlSet,140OHCI1394_LinkControl_rcvPhyPkt);141142/* Don't accept phy packets into AR request context */143reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);144145/* Clear the Isochonouys interrupt masks */146reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);147reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);148reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);149reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);150151/* Accept asyncronous transfer requests from all nodes for now */152reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);153154/* Specify asyncronous transfer retries */155reg_write(ohci, OHCI1394_ATRetries,156OHCI1394_MAX_AT_REQ_RETRIES |157(OHCI1394_MAX_AT_RESP_RETRIES<<4) |158(OHCI1394_MAX_PHYS_RESP_RETRIES<<8));159160/* We don't want hardware swapping */161reg_write(ohci, OHCI1394_HCControlClear,162OHCI1394_HCControl_noByteSwapData);163164/* Enable link */165reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);166167/* If anything is connected to a port, make sure it is enabled */168num_ports = get_phy_reg(ohci, 2) & 0xf;169for (i = 0; i < num_ports; i++) {170unsigned int status;171172set_phy_reg(ohci, 7, i);173status = get_phy_reg(ohci, 8);174175if (status & 0x20)176set_phy_reg(ohci, 8, status & ~1);177}178}179180/**181* init_ohci1394_wait_for_busresets - wait until bus resets are completed182*183* OHCI1394 initialization itself and any device going on- or offline184* and any cable issue cause a IEEE1394 bus reset. The OHCI1394 spec185* specifies that physical DMA is disabled on each bus reset and it186* has to be enabled after each bus reset when needed. We resort187* to polling here because on early boot, we have no interrupts.188*/189static inline void __init init_ohci1394_wait_for_busresets(struct ohci *ohci)190{191int i, events;192193for (i = 0; i < 9; i++) {194mdelay(200);195events = reg_read(ohci, OHCI1394_IntEventSet);196if (events & OHCI1394_busReset)197reg_write(ohci, OHCI1394_IntEventClear,198OHCI1394_busReset);199}200}201202/**203* init_ohci1394_enable_physical_dma - Enable physical DMA for remote debugging204* This enables remote DMA access over IEEE1394 from every host for the low205* 4GB of address space. DMA accesses above 4GB are not available currently.206*/207static inline void __init init_ohci1394_enable_physical_dma(struct ohci *ohci)208{209reg_write(ohci, OHCI1394_PhyReqFilterHiSet, 0xffffffff);210reg_write(ohci, OHCI1394_PhyReqFilterLoSet, 0xffffffff);211reg_write(ohci, OHCI1394_PhyUpperBound, 0xffff0000);212}213214/**215* init_ohci1394_reset_and_init_dma - init controller and enable DMA216* This initializes the given controller and enables physical DMA engine in it.217*/218static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci)219{220/* Start off with a soft reset, clears everything to a sane state. */221init_ohci1394_soft_reset(ohci);222223/* Accessing some registers without LPS enabled may cause lock up */224reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS);225226/* Disable and clear interrupts */227reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);228reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);229230mdelay(50); /* Wait 50msec to make sure we have full link enabled */231232init_ohci1394_initialize(ohci);233/*234* The initialization causes at least one IEEE1394 bus reset. Enabling235* physical DMA only works *after* *all* bus resets have calmed down:236*/237init_ohci1394_wait_for_busresets(ohci);238239/* We had to wait and do this now if we want to debug early problems */240init_ohci1394_enable_physical_dma(ohci);241}242243/**244* init_ohci1394_controller - Map the registers of the controller and init DMA245* This maps the registers of the specified controller and initializes it246*/247static inline void __init init_ohci1394_controller(int num, int slot, int func)248{249unsigned long ohci_base;250struct ohci ohci;251252printk(KERN_INFO "init_ohci1394_dma: initializing OHCI-1394"253" at %02x:%02x.%x\n", num, slot, func);254255ohci_base = read_pci_config(num, slot, func, PCI_BASE_ADDRESS_0+(0<<2))256& PCI_BASE_ADDRESS_MEM_MASK;257258set_fixmap_nocache(FIX_OHCI1394_BASE, ohci_base);259260ohci.registers = (void __iomem *)fix_to_virt(FIX_OHCI1394_BASE);261262init_ohci1394_reset_and_init_dma(&ohci);263}264265/**266* debug_init_ohci1394_dma - scan for OHCI1394 controllers and init DMA on them267* Scans the whole PCI space for OHCI1394 controllers and inits DMA on them268*/269void __init init_ohci1394_dma_on_all_controllers(void)270{271int num, slot, func;272u32 class;273274if (!early_pci_allowed())275return;276277/* Poor man's PCI discovery, the only thing we can do at early boot */278for (num = 0; num < 32; num++) {279for (slot = 0; slot < 32; slot++) {280for (func = 0; func < 8; func++) {281class = read_pci_config(num, slot, func,282PCI_CLASS_REVISION);283if (class == 0xffffffff)284continue; /* No device at this func */285286if (class>>8 != PCI_CLASS_SERIAL_FIREWIRE_OHCI)287continue; /* Not an OHCI-1394 device */288289init_ohci1394_controller(num, slot, func);290break; /* Assume one controller per device */291}292}293}294printk(KERN_INFO "init_ohci1394_dma: finished initializing OHCI DMA\n");295}296297/**298* setup_init_ohci1394_early - enables early OHCI1394 DMA initialization299*/300static int __init setup_ohci1394_dma(char *opt)301{302if (!strcmp(opt, "early"))303init_ohci1394_dma_early = 1;304return 0;305}306307/* passing ohci1394_dma=early on boot causes early OHCI1394 DMA initialization */308early_param("ohci1394_dma", setup_ohci1394_dma);309310311