1e8b12f0fSMahesh Rajashekhara /* 2e8b12f0fSMahesh Rajashekhara * Adaptec AAC series RAID controller driver 3e8b12f0fSMahesh Rajashekhara * (c) Copyright 2001 Red Hat Inc. 4e8b12f0fSMahesh Rajashekhara * 5e8b12f0fSMahesh Rajashekhara * based on the old aacraid driver that is.. 6e8b12f0fSMahesh Rajashekhara * Adaptec aacraid device driver for Linux. 7e8b12f0fSMahesh Rajashekhara * 8e8b12f0fSMahesh Rajashekhara * Copyright (c) 2000-2010 Adaptec, Inc. 9e8b12f0fSMahesh Rajashekhara * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) 10e8b12f0fSMahesh Rajashekhara * 11e8b12f0fSMahesh Rajashekhara * This program is free software; you can redistribute it and/or modify 12e8b12f0fSMahesh Rajashekhara * it under the terms of the GNU General Public License as published by 13e8b12f0fSMahesh Rajashekhara * the Free Software Foundation; either version 2, or (at your option) 14e8b12f0fSMahesh Rajashekhara * any later version. 15e8b12f0fSMahesh Rajashekhara * 16e8b12f0fSMahesh Rajashekhara * This program is distributed in the hope that it will be useful, 17e8b12f0fSMahesh Rajashekhara * but WITHOUT ANY WARRANTY; without even the implied warranty of 18e8b12f0fSMahesh Rajashekhara * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19e8b12f0fSMahesh Rajashekhara * GNU General Public License for more details. 20e8b12f0fSMahesh Rajashekhara * 21e8b12f0fSMahesh Rajashekhara * You should have received a copy of the GNU General Public License 22e8b12f0fSMahesh Rajashekhara * along with this program; see the file COPYING. If not, write to 23e8b12f0fSMahesh Rajashekhara * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24e8b12f0fSMahesh Rajashekhara * 25e8b12f0fSMahesh Rajashekhara * Module Name: 26e8b12f0fSMahesh Rajashekhara * src.c 27e8b12f0fSMahesh Rajashekhara * 28e8b12f0fSMahesh Rajashekhara * Abstract: Hardware Device Interface for PMC SRC based controllers 29e8b12f0fSMahesh Rajashekhara * 30e8b12f0fSMahesh Rajashekhara */ 31e8b12f0fSMahesh Rajashekhara 32e8b12f0fSMahesh Rajashekhara #include <linux/kernel.h> 33e8b12f0fSMahesh Rajashekhara #include <linux/init.h> 34e8b12f0fSMahesh Rajashekhara #include <linux/types.h> 35e8b12f0fSMahesh Rajashekhara #include <linux/pci.h> 36e8b12f0fSMahesh Rajashekhara #include <linux/spinlock.h> 37e8b12f0fSMahesh Rajashekhara #include <linux/slab.h> 38e8b12f0fSMahesh Rajashekhara #include <linux/blkdev.h> 39e8b12f0fSMahesh Rajashekhara #include <linux/delay.h> 40e8b12f0fSMahesh Rajashekhara #include <linux/completion.h> 41e8b12f0fSMahesh Rajashekhara #include <linux/time.h> 42e8b12f0fSMahesh Rajashekhara #include <linux/interrupt.h> 43e8b12f0fSMahesh Rajashekhara #include <scsi/scsi_host.h> 44e8b12f0fSMahesh Rajashekhara 45e8b12f0fSMahesh Rajashekhara #include "aacraid.h" 46e8b12f0fSMahesh Rajashekhara 47495c0217SMahesh Rajashekhara static int aac_src_get_sync_status(struct aac_dev *dev); 48495c0217SMahesh Rajashekhara 49305974feSkbuild test robot static irqreturn_t aac_src_intr_message(int irq, void *dev_id) 50e8b12f0fSMahesh Rajashekhara { 51495c0217SMahesh Rajashekhara struct aac_msix_ctx *ctx; 52495c0217SMahesh Rajashekhara struct aac_dev *dev; 53e8b12f0fSMahesh Rajashekhara unsigned long bellbits, bellbits_shifted; 54495c0217SMahesh Rajashekhara int vector_no; 55495c0217SMahesh Rajashekhara int isFastResponse, mode; 56e8b12f0fSMahesh Rajashekhara u32 index, handle; 57e8b12f0fSMahesh Rajashekhara 58495c0217SMahesh Rajashekhara ctx = (struct aac_msix_ctx *)dev_id; 59495c0217SMahesh Rajashekhara dev = ctx->dev; 60495c0217SMahesh Rajashekhara vector_no = ctx->vector_no; 61495c0217SMahesh Rajashekhara 62495c0217SMahesh Rajashekhara if (dev->msi_enabled) { 63495c0217SMahesh Rajashekhara mode = AAC_INT_MODE_MSI; 64495c0217SMahesh Rajashekhara if (vector_no == 0) { 65495c0217SMahesh Rajashekhara bellbits = src_readl(dev, MUnit.ODR_MSI); 66495c0217SMahesh Rajashekhara if (bellbits & 0x40000) 67495c0217SMahesh Rajashekhara mode |= AAC_INT_MODE_AIF; 68495c0217SMahesh Rajashekhara if (bellbits & 0x1000) 69495c0217SMahesh Rajashekhara mode |= AAC_INT_MODE_SYNC; 70495c0217SMahesh Rajashekhara } 71495c0217SMahesh Rajashekhara } else { 72495c0217SMahesh Rajashekhara mode = AAC_INT_MODE_INTX; 73e8b12f0fSMahesh Rajashekhara bellbits = src_readl(dev, MUnit.ODR_R); 74e8b12f0fSMahesh Rajashekhara if (bellbits & PmDoorBellResponseSent) { 75e8b12f0fSMahesh Rajashekhara bellbits = PmDoorBellResponseSent; 7685d22bbfSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, bellbits); 7785d22bbfSMahesh Rajashekhara src_readl(dev, MUnit.ODR_C); 78e8b12f0fSMahesh Rajashekhara } else { 79e8b12f0fSMahesh Rajashekhara bellbits_shifted = (bellbits >> SRC_ODR_SHIFT); 8085d22bbfSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, bellbits); 8185d22bbfSMahesh Rajashekhara src_readl(dev, MUnit.ODR_C); 82495c0217SMahesh Rajashekhara 83495c0217SMahesh Rajashekhara if (bellbits_shifted & DoorBellAifPending) 84495c0217SMahesh Rajashekhara mode |= AAC_INT_MODE_AIF; 85495c0217SMahesh Rajashekhara else if (bellbits_shifted & OUTBOUNDDOORBELL_0) 86495c0217SMahesh Rajashekhara mode |= AAC_INT_MODE_SYNC; 87495c0217SMahesh Rajashekhara } 88495c0217SMahesh Rajashekhara } 89495c0217SMahesh Rajashekhara 90495c0217SMahesh Rajashekhara if (mode & AAC_INT_MODE_SYNC) { 9111604612SMahesh Rajashekhara unsigned long sflags; 9211604612SMahesh Rajashekhara struct list_head *entry; 9311604612SMahesh Rajashekhara int send_it = 0; 9485d22bbfSMahesh Rajashekhara extern int aac_sync_mode; 9585d22bbfSMahesh Rajashekhara 96495c0217SMahesh Rajashekhara if (!aac_sync_mode && !dev->msi_enabled) { 97c5bebd82SMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, bellbits); 98c5bebd82SMahesh Rajashekhara src_readl(dev, MUnit.ODR_C); 9985d22bbfSMahesh Rajashekhara } 10011604612SMahesh Rajashekhara 10111604612SMahesh Rajashekhara if (dev->sync_fib) { 10211604612SMahesh Rajashekhara if (dev->sync_fib->callback) 10311604612SMahesh Rajashekhara dev->sync_fib->callback(dev->sync_fib->callback_data, 10411604612SMahesh Rajashekhara dev->sync_fib); 10511604612SMahesh Rajashekhara spin_lock_irqsave(&dev->sync_fib->event_lock, sflags); 10611604612SMahesh Rajashekhara if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) { 10711604612SMahesh Rajashekhara dev->management_fib_count--; 10811604612SMahesh Rajashekhara up(&dev->sync_fib->event_wait); 10911604612SMahesh Rajashekhara } 110495c0217SMahesh Rajashekhara spin_unlock_irqrestore(&dev->sync_fib->event_lock, 111495c0217SMahesh Rajashekhara sflags); 11211604612SMahesh Rajashekhara spin_lock_irqsave(&dev->sync_lock, sflags); 11311604612SMahesh Rajashekhara if (!list_empty(&dev->sync_fib_list)) { 11411604612SMahesh Rajashekhara entry = dev->sync_fib_list.next; 115495c0217SMahesh Rajashekhara dev->sync_fib = list_entry(entry, 116495c0217SMahesh Rajashekhara struct fib, 117495c0217SMahesh Rajashekhara fiblink); 11811604612SMahesh Rajashekhara list_del(entry); 11911604612SMahesh Rajashekhara send_it = 1; 12011604612SMahesh Rajashekhara } else { 12111604612SMahesh Rajashekhara dev->sync_fib = NULL; 12211604612SMahesh Rajashekhara } 12311604612SMahesh Rajashekhara spin_unlock_irqrestore(&dev->sync_lock, sflags); 12411604612SMahesh Rajashekhara if (send_it) { 12511604612SMahesh Rajashekhara aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB, 126495c0217SMahesh Rajashekhara (u32)dev->sync_fib->hw_fib_pa, 127495c0217SMahesh Rajashekhara 0, 0, 0, 0, 0, 12811604612SMahesh Rajashekhara NULL, NULL, NULL, NULL, NULL); 12911604612SMahesh Rajashekhara } 13011604612SMahesh Rajashekhara } 131495c0217SMahesh Rajashekhara if (!dev->msi_enabled) 132495c0217SMahesh Rajashekhara mode = 0; 133495c0217SMahesh Rajashekhara 134e8b12f0fSMahesh Rajashekhara } 135e8b12f0fSMahesh Rajashekhara 136495c0217SMahesh Rajashekhara if (mode & AAC_INT_MODE_AIF) { 137495c0217SMahesh Rajashekhara /* handle AIF */ 1389cb62fa2SRaghava Aditya Renukunta if (dev->aif_thread && dev->fsa_dev) 139495c0217SMahesh Rajashekhara aac_intr_normal(dev, 0, 2, 0, NULL); 140495c0217SMahesh Rajashekhara if (dev->msi_enabled) 141495c0217SMahesh Rajashekhara aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT); 142495c0217SMahesh Rajashekhara mode = 0; 143e8b12f0fSMahesh Rajashekhara } 144495c0217SMahesh Rajashekhara 145495c0217SMahesh Rajashekhara if (mode) { 146495c0217SMahesh Rajashekhara index = dev->host_rrq_idx[vector_no]; 147495c0217SMahesh Rajashekhara 148495c0217SMahesh Rajashekhara for (;;) { 149495c0217SMahesh Rajashekhara isFastResponse = 0; 150495c0217SMahesh Rajashekhara /* remove toggle bit (31) */ 151495c0217SMahesh Rajashekhara handle = (dev->host_rrq[index] & 0x7fffffff); 152495c0217SMahesh Rajashekhara /* check fast response bit (30) */ 153495c0217SMahesh Rajashekhara if (handle & 0x40000000) 154495c0217SMahesh Rajashekhara isFastResponse = 1; 155495c0217SMahesh Rajashekhara handle &= 0x0000ffff; 156495c0217SMahesh Rajashekhara if (handle == 0) 157495c0217SMahesh Rajashekhara break; 158495c0217SMahesh Rajashekhara if (dev->msi_enabled && dev->max_msix > 1) 159495c0217SMahesh Rajashekhara atomic_dec(&dev->rrq_outstanding[vector_no]); 160495c0217SMahesh Rajashekhara dev->host_rrq[index++] = 0; 1613f4ce057SRaghava Aditya Renukunta aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL); 162495c0217SMahesh Rajashekhara if (index == (vector_no + 1) * dev->vector_cap) 163495c0217SMahesh Rajashekhara index = vector_no * dev->vector_cap; 164495c0217SMahesh Rajashekhara dev->host_rrq_idx[vector_no] = index; 165495c0217SMahesh Rajashekhara } 166495c0217SMahesh Rajashekhara mode = 0; 167495c0217SMahesh Rajashekhara } 168495c0217SMahesh Rajashekhara 169495c0217SMahesh Rajashekhara return IRQ_HANDLED; 170e8b12f0fSMahesh Rajashekhara } 171e8b12f0fSMahesh Rajashekhara 172e8b12f0fSMahesh Rajashekhara /** 173e8b12f0fSMahesh Rajashekhara * aac_src_disable_interrupt - Disable interrupts 174e8b12f0fSMahesh Rajashekhara * @dev: Adapter 175e8b12f0fSMahesh Rajashekhara */ 176e8b12f0fSMahesh Rajashekhara 177e8b12f0fSMahesh Rajashekhara static void aac_src_disable_interrupt(struct aac_dev *dev) 178e8b12f0fSMahesh Rajashekhara { 179e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff); 180e8b12f0fSMahesh Rajashekhara } 181e8b12f0fSMahesh Rajashekhara 182e8b12f0fSMahesh Rajashekhara /** 183e8b12f0fSMahesh Rajashekhara * aac_src_enable_interrupt_message - Enable interrupts 184e8b12f0fSMahesh Rajashekhara * @dev: Adapter 185e8b12f0fSMahesh Rajashekhara */ 186e8b12f0fSMahesh Rajashekhara 187e8b12f0fSMahesh Rajashekhara static void aac_src_enable_interrupt_message(struct aac_dev *dev) 188e8b12f0fSMahesh Rajashekhara { 189495c0217SMahesh Rajashekhara aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT); 190e8b12f0fSMahesh Rajashekhara } 191e8b12f0fSMahesh Rajashekhara 192e8b12f0fSMahesh Rajashekhara /** 193e8b12f0fSMahesh Rajashekhara * src_sync_cmd - send a command and wait 194e8b12f0fSMahesh Rajashekhara * @dev: Adapter 195e8b12f0fSMahesh Rajashekhara * @command: Command to execute 196e8b12f0fSMahesh Rajashekhara * @p1: first parameter 197e8b12f0fSMahesh Rajashekhara * @ret: adapter status 198e8b12f0fSMahesh Rajashekhara * 199e8b12f0fSMahesh Rajashekhara * This routine will send a synchronous command to the adapter and wait 200e8b12f0fSMahesh Rajashekhara * for its completion. 201e8b12f0fSMahesh Rajashekhara */ 202e8b12f0fSMahesh Rajashekhara 203e8b12f0fSMahesh Rajashekhara static int src_sync_cmd(struct aac_dev *dev, u32 command, 204e8b12f0fSMahesh Rajashekhara u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, 205e8b12f0fSMahesh Rajashekhara u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) 206e8b12f0fSMahesh Rajashekhara { 207e8b12f0fSMahesh Rajashekhara unsigned long start; 208dafde947SMahesh Rajashekhara unsigned long delay; 209e8b12f0fSMahesh Rajashekhara int ok; 210e8b12f0fSMahesh Rajashekhara 211e8b12f0fSMahesh Rajashekhara /* 212e8b12f0fSMahesh Rajashekhara * Write the command into Mailbox 0 213e8b12f0fSMahesh Rajashekhara */ 214e8b12f0fSMahesh Rajashekhara writel(command, &dev->IndexRegs->Mailbox[0]); 215e8b12f0fSMahesh Rajashekhara /* 216e8b12f0fSMahesh Rajashekhara * Write the parameters into Mailboxes 1 - 6 217e8b12f0fSMahesh Rajashekhara */ 218e8b12f0fSMahesh Rajashekhara writel(p1, &dev->IndexRegs->Mailbox[1]); 219e8b12f0fSMahesh Rajashekhara writel(p2, &dev->IndexRegs->Mailbox[2]); 220e8b12f0fSMahesh Rajashekhara writel(p3, &dev->IndexRegs->Mailbox[3]); 221e8b12f0fSMahesh Rajashekhara writel(p4, &dev->IndexRegs->Mailbox[4]); 222e8b12f0fSMahesh Rajashekhara 223e8b12f0fSMahesh Rajashekhara /* 224e8b12f0fSMahesh Rajashekhara * Clear the synch command doorbell to start on a clean slate. 225e8b12f0fSMahesh Rajashekhara */ 226495c0217SMahesh Rajashekhara if (!dev->msi_enabled) 227495c0217SMahesh Rajashekhara src_writel(dev, 228495c0217SMahesh Rajashekhara MUnit.ODR_C, 229495c0217SMahesh Rajashekhara OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); 230e8b12f0fSMahesh Rajashekhara 231e8b12f0fSMahesh Rajashekhara /* 232e8b12f0fSMahesh Rajashekhara * Disable doorbell interrupts 233e8b12f0fSMahesh Rajashekhara */ 234e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff); 235e8b12f0fSMahesh Rajashekhara 236e8b12f0fSMahesh Rajashekhara /* 237e8b12f0fSMahesh Rajashekhara * Force the completion of the mask register write before issuing 238e8b12f0fSMahesh Rajashekhara * the interrupt. 239e8b12f0fSMahesh Rajashekhara */ 240e8b12f0fSMahesh Rajashekhara src_readl(dev, MUnit.OIMR); 241e8b12f0fSMahesh Rajashekhara 242e8b12f0fSMahesh Rajashekhara /* 243e8b12f0fSMahesh Rajashekhara * Signal that there is a new synch command 244e8b12f0fSMahesh Rajashekhara */ 245e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT); 246e8b12f0fSMahesh Rajashekhara 24711604612SMahesh Rajashekhara if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) { 248e8b12f0fSMahesh Rajashekhara ok = 0; 249e8b12f0fSMahesh Rajashekhara start = jiffies; 250e8b12f0fSMahesh Rajashekhara 251dafde947SMahesh Rajashekhara if (command == IOP_RESET_ALWAYS) { 252dafde947SMahesh Rajashekhara /* Wait up to 10 sec */ 253dafde947SMahesh Rajashekhara delay = 10*HZ; 254dafde947SMahesh Rajashekhara } else { 255dafde947SMahesh Rajashekhara /* Wait up to 5 minutes */ 256dafde947SMahesh Rajashekhara delay = 300*HZ; 257dafde947SMahesh Rajashekhara } 258dafde947SMahesh Rajashekhara while (time_before(jiffies, start+delay)) { 25911604612SMahesh Rajashekhara udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ 26011604612SMahesh Rajashekhara /* 26111604612SMahesh Rajashekhara * Mon960 will set doorbell0 bit when it has completed the command. 262e8b12f0fSMahesh Rajashekhara */ 263495c0217SMahesh Rajashekhara if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) { 26411604612SMahesh Rajashekhara /* 26511604612SMahesh Rajashekhara * Clear the doorbell. 26611604612SMahesh Rajashekhara */ 267495c0217SMahesh Rajashekhara if (dev->msi_enabled) 268495c0217SMahesh Rajashekhara aac_src_access_devreg(dev, 269495c0217SMahesh Rajashekhara AAC_CLEAR_SYNC_BIT); 270495c0217SMahesh Rajashekhara else 271495c0217SMahesh Rajashekhara src_writel(dev, 272495c0217SMahesh Rajashekhara MUnit.ODR_C, 273495c0217SMahesh Rajashekhara OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); 274e8b12f0fSMahesh Rajashekhara ok = 1; 275e8b12f0fSMahesh Rajashekhara break; 276e8b12f0fSMahesh Rajashekhara } 27711604612SMahesh Rajashekhara /* 27811604612SMahesh Rajashekhara * Yield the processor in case we are slow 27911604612SMahesh Rajashekhara */ 280e8b12f0fSMahesh Rajashekhara msleep(1); 281e8b12f0fSMahesh Rajashekhara } 282e8b12f0fSMahesh Rajashekhara if (unlikely(ok != 1)) { 28311604612SMahesh Rajashekhara /* 28411604612SMahesh Rajashekhara * Restore interrupt mask even though we timed out 28511604612SMahesh Rajashekhara */ 286e8b12f0fSMahesh Rajashekhara aac_adapter_enable_int(dev); 287e8b12f0fSMahesh Rajashekhara return -ETIMEDOUT; 288e8b12f0fSMahesh Rajashekhara } 28911604612SMahesh Rajashekhara /* 29011604612SMahesh Rajashekhara * Pull the synch status from Mailbox 0. 29111604612SMahesh Rajashekhara */ 292e8b12f0fSMahesh Rajashekhara if (status) 293e8b12f0fSMahesh Rajashekhara *status = readl(&dev->IndexRegs->Mailbox[0]); 294e8b12f0fSMahesh Rajashekhara if (r1) 295e8b12f0fSMahesh Rajashekhara *r1 = readl(&dev->IndexRegs->Mailbox[1]); 296e8b12f0fSMahesh Rajashekhara if (r2) 297e8b12f0fSMahesh Rajashekhara *r2 = readl(&dev->IndexRegs->Mailbox[2]); 298e8b12f0fSMahesh Rajashekhara if (r3) 299e8b12f0fSMahesh Rajashekhara *r3 = readl(&dev->IndexRegs->Mailbox[3]); 300e8b12f0fSMahesh Rajashekhara if (r4) 301e8b12f0fSMahesh Rajashekhara *r4 = readl(&dev->IndexRegs->Mailbox[4]); 302495c0217SMahesh Rajashekhara if (command == GET_COMM_PREFERRED_SETTINGS) 303495c0217SMahesh Rajashekhara dev->max_msix = 304495c0217SMahesh Rajashekhara readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF; 30511604612SMahesh Rajashekhara /* 30611604612SMahesh Rajashekhara * Clear the synch command doorbell. 30711604612SMahesh Rajashekhara */ 308495c0217SMahesh Rajashekhara if (!dev->msi_enabled) 309495c0217SMahesh Rajashekhara src_writel(dev, 310495c0217SMahesh Rajashekhara MUnit.ODR_C, 311495c0217SMahesh Rajashekhara OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); 31211604612SMahesh Rajashekhara } 313e8b12f0fSMahesh Rajashekhara 31411604612SMahesh Rajashekhara /* 31511604612SMahesh Rajashekhara * Restore interrupt mask 31611604612SMahesh Rajashekhara */ 317e8b12f0fSMahesh Rajashekhara aac_adapter_enable_int(dev); 318e8b12f0fSMahesh Rajashekhara return 0; 319e8b12f0fSMahesh Rajashekhara } 320e8b12f0fSMahesh Rajashekhara 321e8b12f0fSMahesh Rajashekhara /** 322e8b12f0fSMahesh Rajashekhara * aac_src_interrupt_adapter - interrupt adapter 323e8b12f0fSMahesh Rajashekhara * @dev: Adapter 324e8b12f0fSMahesh Rajashekhara * 325e8b12f0fSMahesh Rajashekhara * Send an interrupt to the i960 and breakpoint it. 326e8b12f0fSMahesh Rajashekhara */ 327e8b12f0fSMahesh Rajashekhara 328e8b12f0fSMahesh Rajashekhara static void aac_src_interrupt_adapter(struct aac_dev *dev) 329e8b12f0fSMahesh Rajashekhara { 330e8b12f0fSMahesh Rajashekhara src_sync_cmd(dev, BREAKPOINT_REQUEST, 331e8b12f0fSMahesh Rajashekhara 0, 0, 0, 0, 0, 0, 332e8b12f0fSMahesh Rajashekhara NULL, NULL, NULL, NULL, NULL); 333e8b12f0fSMahesh Rajashekhara } 334e8b12f0fSMahesh Rajashekhara 335e8b12f0fSMahesh Rajashekhara /** 336e8b12f0fSMahesh Rajashekhara * aac_src_notify_adapter - send an event to the adapter 337e8b12f0fSMahesh Rajashekhara * @dev: Adapter 338e8b12f0fSMahesh Rajashekhara * @event: Event to send 339e8b12f0fSMahesh Rajashekhara * 340e8b12f0fSMahesh Rajashekhara * Notify the i960 that something it probably cares about has 341e8b12f0fSMahesh Rajashekhara * happened. 342e8b12f0fSMahesh Rajashekhara */ 343e8b12f0fSMahesh Rajashekhara 344e8b12f0fSMahesh Rajashekhara static void aac_src_notify_adapter(struct aac_dev *dev, u32 event) 345e8b12f0fSMahesh Rajashekhara { 346e8b12f0fSMahesh Rajashekhara switch (event) { 347e8b12f0fSMahesh Rajashekhara 348e8b12f0fSMahesh Rajashekhara case AdapNormCmdQue: 349e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 350e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_1 << SRC_ODR_SHIFT); 351e8b12f0fSMahesh Rajashekhara break; 352e8b12f0fSMahesh Rajashekhara case HostNormRespNotFull: 353e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 354e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_4 << SRC_ODR_SHIFT); 355e8b12f0fSMahesh Rajashekhara break; 356e8b12f0fSMahesh Rajashekhara case AdapNormRespQue: 357e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 358e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_2 << SRC_ODR_SHIFT); 359e8b12f0fSMahesh Rajashekhara break; 360e8b12f0fSMahesh Rajashekhara case HostNormCmdNotFull: 361e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 362e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_3 << SRC_ODR_SHIFT); 363e8b12f0fSMahesh Rajashekhara break; 364e8b12f0fSMahesh Rajashekhara case FastIo: 365e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 366e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_6 << SRC_ODR_SHIFT); 367e8b12f0fSMahesh Rajashekhara break; 368e8b12f0fSMahesh Rajashekhara case AdapPrintfDone: 369e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 370e8b12f0fSMahesh Rajashekhara INBOUNDDOORBELL_5 << SRC_ODR_SHIFT); 371e8b12f0fSMahesh Rajashekhara break; 372e8b12f0fSMahesh Rajashekhara default: 373e8b12f0fSMahesh Rajashekhara BUG(); 374e8b12f0fSMahesh Rajashekhara break; 375e8b12f0fSMahesh Rajashekhara } 376e8b12f0fSMahesh Rajashekhara } 377e8b12f0fSMahesh Rajashekhara 378e8b12f0fSMahesh Rajashekhara /** 379e8b12f0fSMahesh Rajashekhara * aac_src_start_adapter - activate adapter 380e8b12f0fSMahesh Rajashekhara * @dev: Adapter 381e8b12f0fSMahesh Rajashekhara * 382e8b12f0fSMahesh Rajashekhara * Start up processing on an i960 based AAC adapter 383e8b12f0fSMahesh Rajashekhara */ 384e8b12f0fSMahesh Rajashekhara 385e8b12f0fSMahesh Rajashekhara static void aac_src_start_adapter(struct aac_dev *dev) 386e8b12f0fSMahesh Rajashekhara { 387e8b12f0fSMahesh Rajashekhara struct aac_init *init; 388495c0217SMahesh Rajashekhara int i; 389e8b12f0fSMahesh Rajashekhara 39085d22bbfSMahesh Rajashekhara /* reset host_rrq_idx first */ 391495c0217SMahesh Rajashekhara for (i = 0; i < dev->max_msix; i++) { 392495c0217SMahesh Rajashekhara dev->host_rrq_idx[i] = i * dev->vector_cap; 393495c0217SMahesh Rajashekhara atomic_set(&dev->rrq_outstanding[i], 0); 394495c0217SMahesh Rajashekhara } 395495c0217SMahesh Rajashekhara dev->fibs_pushed_no = 0; 39685d22bbfSMahesh Rajashekhara 397e8b12f0fSMahesh Rajashekhara init = dev->init; 398e8b12f0fSMahesh Rajashekhara init->HostElapsedSeconds = cpu_to_le32(get_seconds()); 399e8b12f0fSMahesh Rajashekhara 400e8b12f0fSMahesh Rajashekhara /* We can only use a 32 bit address here */ 401e8b12f0fSMahesh Rajashekhara src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 402e8b12f0fSMahesh Rajashekhara 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 403e8b12f0fSMahesh Rajashekhara } 404e8b12f0fSMahesh Rajashekhara 405e8b12f0fSMahesh Rajashekhara /** 406e8b12f0fSMahesh Rajashekhara * aac_src_check_health 407e8b12f0fSMahesh Rajashekhara * @dev: device to check if healthy 408e8b12f0fSMahesh Rajashekhara * 409e8b12f0fSMahesh Rajashekhara * Will attempt to determine if the specified adapter is alive and 410e8b12f0fSMahesh Rajashekhara * capable of handling requests, returning 0 if alive. 411e8b12f0fSMahesh Rajashekhara */ 412e8b12f0fSMahesh Rajashekhara static int aac_src_check_health(struct aac_dev *dev) 413e8b12f0fSMahesh Rajashekhara { 414e8b12f0fSMahesh Rajashekhara u32 status = src_readl(dev, MUnit.OMR); 415e8b12f0fSMahesh Rajashekhara 416e8b12f0fSMahesh Rajashekhara /* 417e8b12f0fSMahesh Rajashekhara * Check to see if the board failed any self tests. 418e8b12f0fSMahesh Rajashekhara */ 419e8b12f0fSMahesh Rajashekhara if (unlikely(status & SELF_TEST_FAILED)) 420e8b12f0fSMahesh Rajashekhara return -1; 421e8b12f0fSMahesh Rajashekhara 422e8b12f0fSMahesh Rajashekhara /* 423e8b12f0fSMahesh Rajashekhara * Check to see if the board panic'd. 424e8b12f0fSMahesh Rajashekhara */ 425e8b12f0fSMahesh Rajashekhara if (unlikely(status & KERNEL_PANIC)) 426e8b12f0fSMahesh Rajashekhara return (status >> 16) & 0xFF; 427e8b12f0fSMahesh Rajashekhara /* 428e8b12f0fSMahesh Rajashekhara * Wait for the adapter to be up and running. 429e8b12f0fSMahesh Rajashekhara */ 430e8b12f0fSMahesh Rajashekhara if (unlikely(!(status & KERNEL_UP_AND_RUNNING))) 431e8b12f0fSMahesh Rajashekhara return -3; 432e8b12f0fSMahesh Rajashekhara /* 433e8b12f0fSMahesh Rajashekhara * Everything is OK 434e8b12f0fSMahesh Rajashekhara */ 435e8b12f0fSMahesh Rajashekhara return 0; 436e8b12f0fSMahesh Rajashekhara } 437e8b12f0fSMahesh Rajashekhara 438e8b12f0fSMahesh Rajashekhara /** 439e8b12f0fSMahesh Rajashekhara * aac_src_deliver_message 440e8b12f0fSMahesh Rajashekhara * @fib: fib to issue 441e8b12f0fSMahesh Rajashekhara * 442e8b12f0fSMahesh Rajashekhara * Will send a fib, returning 0 if successful. 443e8b12f0fSMahesh Rajashekhara */ 444e8b12f0fSMahesh Rajashekhara static int aac_src_deliver_message(struct fib *fib) 445e8b12f0fSMahesh Rajashekhara { 446e8b12f0fSMahesh Rajashekhara struct aac_dev *dev = fib->dev; 447e8b12f0fSMahesh Rajashekhara struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; 448e8b12f0fSMahesh Rajashekhara u32 fibsize; 449b5f1758fSBen Collins dma_addr_t address; 450e8b12f0fSMahesh Rajashekhara struct aac_fib_xporthdr *pFibX; 451c6992781SMahesh Rajashekhara #if !defined(writeq) 452c6992781SMahesh Rajashekhara unsigned long flags; 453c6992781SMahesh Rajashekhara #endif 454c6992781SMahesh Rajashekhara 455b5f1758fSBen Collins u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size); 4563f4ce057SRaghava Aditya Renukunta u16 vector_no; 457e8b12f0fSMahesh Rajashekhara 458ef616233SMahesh Rajashekhara atomic_inc(&q->numpending); 459e8b12f0fSMahesh Rajashekhara 460495c0217SMahesh Rajashekhara if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest && 461495c0217SMahesh Rajashekhara dev->max_msix > 1) { 4623f4ce057SRaghava Aditya Renukunta vector_no = fib->vector_no; 463495c0217SMahesh Rajashekhara fib->hw_fib_va->header.Handle += (vector_no << 16); 4643f4ce057SRaghava Aditya Renukunta } else { 4653f4ce057SRaghava Aditya Renukunta vector_no = 0; 466495c0217SMahesh Rajashekhara } 467495c0217SMahesh Rajashekhara 4683f4ce057SRaghava Aditya Renukunta atomic_inc(&dev->rrq_outstanding[vector_no]); 4693f4ce057SRaghava Aditya Renukunta 47085d22bbfSMahesh Rajashekhara if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { 47185d22bbfSMahesh Rajashekhara /* Calculate the amount to the fibsize bits */ 47285d22bbfSMahesh Rajashekhara fibsize = (hdr_size + 127) / 128 - 1; 47385d22bbfSMahesh Rajashekhara if (fibsize > (ALIGN32 - 1)) 47485d22bbfSMahesh Rajashekhara return -EMSGSIZE; 47585d22bbfSMahesh Rajashekhara /* New FIB header, 32-bit */ 47685d22bbfSMahesh Rajashekhara address = fib->hw_fib_pa; 47785d22bbfSMahesh Rajashekhara fib->hw_fib_va->header.StructType = FIB_MAGIC2; 47885d22bbfSMahesh Rajashekhara fib->hw_fib_va->header.SenderFibAddress = (u32)address; 47985d22bbfSMahesh Rajashekhara fib->hw_fib_va->header.u.TimeStamp = 0; 48098f99a8aSPaul Bolle BUG_ON(upper_32_bits(address) != 0L); 48185d22bbfSMahesh Rajashekhara address |= fibsize; 48285d22bbfSMahesh Rajashekhara } else { 483e8b12f0fSMahesh Rajashekhara /* Calculate the amount to the fibsize bits */ 484b5f1758fSBen Collins fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; 485e8b12f0fSMahesh Rajashekhara if (fibsize > (ALIGN32 - 1)) 486b5f1758fSBen Collins return -EMSGSIZE; 487e8b12f0fSMahesh Rajashekhara 488e8b12f0fSMahesh Rajashekhara /* Fill XPORT header */ 489b5f1758fSBen Collins pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr); 49085d22bbfSMahesh Rajashekhara pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.Handle); 491b5f1758fSBen Collins pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa); 492b5f1758fSBen Collins pFibX->Size = cpu_to_le32(hdr_size); 493e8b12f0fSMahesh Rajashekhara 494b5f1758fSBen Collins /* 495b5f1758fSBen Collins * The xport header has been 32-byte aligned for us so that fibsize 496b5f1758fSBen Collins * can be masked out of this address by hardware. -- BenC 497b5f1758fSBen Collins */ 498b5f1758fSBen Collins address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr); 499b5f1758fSBen Collins if (address & (ALIGN32 - 1)) 500b5f1758fSBen Collins return -EINVAL; 501b5f1758fSBen Collins address |= fibsize; 50285d22bbfSMahesh Rajashekhara } 503c6992781SMahesh Rajashekhara #if defined(writeq) 504c6992781SMahesh Rajashekhara src_writeq(dev, MUnit.IQ_L, (u64)address); 505c6992781SMahesh Rajashekhara #else 506c6992781SMahesh Rajashekhara spin_lock_irqsave(&fib->dev->iq_lock, flags); 50798f99a8aSPaul Bolle src_writel(dev, MUnit.IQ_H, upper_32_bits(address) & 0xffffffff); 508b5f1758fSBen Collins src_writel(dev, MUnit.IQ_L, address & 0xffffffff); 509c6992781SMahesh Rajashekhara spin_unlock_irqrestore(&fib->dev->iq_lock, flags); 510c6992781SMahesh Rajashekhara #endif 511e8b12f0fSMahesh Rajashekhara return 0; 512e8b12f0fSMahesh Rajashekhara } 513e8b12f0fSMahesh Rajashekhara 514e8b12f0fSMahesh Rajashekhara /** 515e8b12f0fSMahesh Rajashekhara * aac_src_ioremap 516e8b12f0fSMahesh Rajashekhara * @size: mapping resize request 517e8b12f0fSMahesh Rajashekhara * 518e8b12f0fSMahesh Rajashekhara */ 519e8b12f0fSMahesh Rajashekhara static int aac_src_ioremap(struct aac_dev *dev, u32 size) 520e8b12f0fSMahesh Rajashekhara { 521e8b12f0fSMahesh Rajashekhara if (!size) { 52271552505STomas Henzl iounmap(dev->regs.src.bar1); 52371552505STomas Henzl dev->regs.src.bar1 = NULL; 524e8b12f0fSMahesh Rajashekhara iounmap(dev->regs.src.bar0); 52511604612SMahesh Rajashekhara dev->base = dev->regs.src.bar0 = NULL; 526e8b12f0fSMahesh Rajashekhara return 0; 527e8b12f0fSMahesh Rajashekhara } 528e8b12f0fSMahesh Rajashekhara dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2), 529e8b12f0fSMahesh Rajashekhara AAC_MIN_SRC_BAR1_SIZE); 530e8b12f0fSMahesh Rajashekhara dev->base = NULL; 531e8b12f0fSMahesh Rajashekhara if (dev->regs.src.bar1 == NULL) 532e8b12f0fSMahesh Rajashekhara return -1; 533ff08784bSBen Collins dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size); 534e8b12f0fSMahesh Rajashekhara if (dev->base == NULL) { 535e8b12f0fSMahesh Rajashekhara iounmap(dev->regs.src.bar1); 536e8b12f0fSMahesh Rajashekhara dev->regs.src.bar1 = NULL; 537e8b12f0fSMahesh Rajashekhara return -1; 538e8b12f0fSMahesh Rajashekhara } 539e8b12f0fSMahesh Rajashekhara dev->IndexRegs = &((struct src_registers __iomem *) 54011604612SMahesh Rajashekhara dev->base)->u.tupelo.IndexRegs; 54111604612SMahesh Rajashekhara return 0; 54211604612SMahesh Rajashekhara } 54311604612SMahesh Rajashekhara 54411604612SMahesh Rajashekhara /** 54511604612SMahesh Rajashekhara * aac_srcv_ioremap 54611604612SMahesh Rajashekhara * @size: mapping resize request 54711604612SMahesh Rajashekhara * 54811604612SMahesh Rajashekhara */ 54911604612SMahesh Rajashekhara static int aac_srcv_ioremap(struct aac_dev *dev, u32 size) 55011604612SMahesh Rajashekhara { 55111604612SMahesh Rajashekhara if (!size) { 55211604612SMahesh Rajashekhara iounmap(dev->regs.src.bar0); 55311604612SMahesh Rajashekhara dev->base = dev->regs.src.bar0 = NULL; 55411604612SMahesh Rajashekhara return 0; 55511604612SMahesh Rajashekhara } 556ff08784bSBen Collins dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size); 55711604612SMahesh Rajashekhara if (dev->base == NULL) 55811604612SMahesh Rajashekhara return -1; 55911604612SMahesh Rajashekhara dev->IndexRegs = &((struct src_registers __iomem *) 56011604612SMahesh Rajashekhara dev->base)->u.denali.IndexRegs; 561e8b12f0fSMahesh Rajashekhara return 0; 562e8b12f0fSMahesh Rajashekhara } 563e8b12f0fSMahesh Rajashekhara 564e8b12f0fSMahesh Rajashekhara static int aac_src_restart_adapter(struct aac_dev *dev, int bled) 565e8b12f0fSMahesh Rajashekhara { 566e8b12f0fSMahesh Rajashekhara u32 var, reset_mask; 567e8b12f0fSMahesh Rajashekhara 568e8b12f0fSMahesh Rajashekhara if (bled >= 0) { 569e8b12f0fSMahesh Rajashekhara if (bled) 570e8b12f0fSMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", 571e8b12f0fSMahesh Rajashekhara dev->name, dev->id, bled); 572dafde947SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 573e8b12f0fSMahesh Rajashekhara bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 574e8b12f0fSMahesh Rajashekhara 0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL); 575dafde947SMahesh Rajashekhara if ((bled || (var != 0x00000001)) && 576dafde947SMahesh Rajashekhara !dev->doorbell_mask) 57711604612SMahesh Rajashekhara return -EINVAL; 578dafde947SMahesh Rajashekhara else if (dev->doorbell_mask) { 579dafde947SMahesh Rajashekhara reset_mask = dev->doorbell_mask; 580dafde947SMahesh Rajashekhara bled = 0; 581dafde947SMahesh Rajashekhara var = 0x00000001; 582dafde947SMahesh Rajashekhara } 583495c0217SMahesh Rajashekhara 584495c0217SMahesh Rajashekhara if ((dev->pdev->device == PMC_DEVICE_S7 || 585495c0217SMahesh Rajashekhara dev->pdev->device == PMC_DEVICE_S8 || 586495c0217SMahesh Rajashekhara dev->pdev->device == PMC_DEVICE_S9) && dev->msi_enabled) { 587495c0217SMahesh Rajashekhara aac_src_access_devreg(dev, AAC_ENABLE_INTX); 588495c0217SMahesh Rajashekhara dev->msi_enabled = 0; 589495c0217SMahesh Rajashekhara msleep(5000); /* Delay 5 seconds */ 590495c0217SMahesh Rajashekhara } 591495c0217SMahesh Rajashekhara 592dafde947SMahesh Rajashekhara if (!bled && (dev->supplement_adapter_info.SupportedOptions2 & 593dafde947SMahesh Rajashekhara AAC_OPTION_DOORBELL_RESET)) { 594e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.IDR, reset_mask); 595495c0217SMahesh Rajashekhara ssleep(45); 596dafde947SMahesh Rajashekhara } else { 597dafde947SMahesh Rajashekhara src_writel(dev, MUnit.IDR, 0x100); 598dafde947SMahesh Rajashekhara ssleep(45); 599e8b12f0fSMahesh Rajashekhara } 600e8b12f0fSMahesh Rajashekhara } 601e8b12f0fSMahesh Rajashekhara 602e8b12f0fSMahesh Rajashekhara if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC) 603e8b12f0fSMahesh Rajashekhara return -ENODEV; 604e8b12f0fSMahesh Rajashekhara 605e8b12f0fSMahesh Rajashekhara if (startup_timeout < 300) 606e8b12f0fSMahesh Rajashekhara startup_timeout = 300; 607e8b12f0fSMahesh Rajashekhara 608e8b12f0fSMahesh Rajashekhara return 0; 609e8b12f0fSMahesh Rajashekhara } 610e8b12f0fSMahesh Rajashekhara 611e8b12f0fSMahesh Rajashekhara /** 612e8b12f0fSMahesh Rajashekhara * aac_src_select_comm - Select communications method 613e8b12f0fSMahesh Rajashekhara * @dev: Adapter 614e8b12f0fSMahesh Rajashekhara * @comm: communications method 615e8b12f0fSMahesh Rajashekhara */ 616a44199eeSBaoyou Xie static int aac_src_select_comm(struct aac_dev *dev, int comm) 617e8b12f0fSMahesh Rajashekhara { 618e8b12f0fSMahesh Rajashekhara switch (comm) { 619e8b12f0fSMahesh Rajashekhara case AAC_COMM_MESSAGE: 620e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_intr = aac_src_intr_message; 621e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_deliver = aac_src_deliver_message; 622e8b12f0fSMahesh Rajashekhara break; 623e8b12f0fSMahesh Rajashekhara default: 624e8b12f0fSMahesh Rajashekhara return 1; 625e8b12f0fSMahesh Rajashekhara } 626e8b12f0fSMahesh Rajashekhara return 0; 627e8b12f0fSMahesh Rajashekhara } 628e8b12f0fSMahesh Rajashekhara 629e8b12f0fSMahesh Rajashekhara /** 630e8b12f0fSMahesh Rajashekhara * aac_src_init - initialize an Cardinal Frey Bar card 631e8b12f0fSMahesh Rajashekhara * @dev: device to configure 632e8b12f0fSMahesh Rajashekhara * 633e8b12f0fSMahesh Rajashekhara */ 634e8b12f0fSMahesh Rajashekhara 635e8b12f0fSMahesh Rajashekhara int aac_src_init(struct aac_dev *dev) 636e8b12f0fSMahesh Rajashekhara { 637e8b12f0fSMahesh Rajashekhara unsigned long start; 638e8b12f0fSMahesh Rajashekhara unsigned long status; 639e8b12f0fSMahesh Rajashekhara int restart = 0; 640e8b12f0fSMahesh Rajashekhara int instance = dev->id; 641e8b12f0fSMahesh Rajashekhara const char *name = dev->name; 642e8b12f0fSMahesh Rajashekhara 643e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_ioremap = aac_src_ioremap; 644e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_comm = aac_src_select_comm; 645e8b12f0fSMahesh Rajashekhara 646e8b12f0fSMahesh Rajashekhara dev->base_size = AAC_MIN_SRC_BAR0_SIZE; 647e8b12f0fSMahesh Rajashekhara if (aac_adapter_ioremap(dev, dev->base_size)) { 648e8b12f0fSMahesh Rajashekhara printk(KERN_WARNING "%s: unable to map adapter.\n", name); 649e8b12f0fSMahesh Rajashekhara goto error_iounmap; 650e8b12f0fSMahesh Rajashekhara } 651e8b12f0fSMahesh Rajashekhara 652e8b12f0fSMahesh Rajashekhara /* Failure to reset here is an option ... */ 653e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_sync_cmd = src_sync_cmd; 654e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 655e8b12f0fSMahesh Rajashekhara if ((aac_reset_devices || reset_devices) && 656e8b12f0fSMahesh Rajashekhara !aac_src_restart_adapter(dev, 0)) 657e8b12f0fSMahesh Rajashekhara ++restart; 658e8b12f0fSMahesh Rajashekhara /* 659e8b12f0fSMahesh Rajashekhara * Check to see if the board panic'd while booting. 660e8b12f0fSMahesh Rajashekhara */ 661e8b12f0fSMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 662e8b12f0fSMahesh Rajashekhara if (status & KERNEL_PANIC) { 663e8b12f0fSMahesh Rajashekhara if (aac_src_restart_adapter(dev, aac_src_check_health(dev))) 664e8b12f0fSMahesh Rajashekhara goto error_iounmap; 665e8b12f0fSMahesh Rajashekhara ++restart; 666e8b12f0fSMahesh Rajashekhara } 667e8b12f0fSMahesh Rajashekhara /* 668e8b12f0fSMahesh Rajashekhara * Check to see if the board failed any self tests. 669e8b12f0fSMahesh Rajashekhara */ 670e8b12f0fSMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 671e8b12f0fSMahesh Rajashekhara if (status & SELF_TEST_FAILED) { 672e8b12f0fSMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter self-test failed.\n", 673e8b12f0fSMahesh Rajashekhara dev->name, instance); 674e8b12f0fSMahesh Rajashekhara goto error_iounmap; 675e8b12f0fSMahesh Rajashekhara } 676e8b12f0fSMahesh Rajashekhara /* 677e8b12f0fSMahesh Rajashekhara * Check to see if the monitor panic'd while booting. 678e8b12f0fSMahesh Rajashekhara */ 679e8b12f0fSMahesh Rajashekhara if (status & MONITOR_PANIC) { 680e8b12f0fSMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter monitor panic.\n", 681e8b12f0fSMahesh Rajashekhara dev->name, instance); 682e8b12f0fSMahesh Rajashekhara goto error_iounmap; 683e8b12f0fSMahesh Rajashekhara } 684e8b12f0fSMahesh Rajashekhara start = jiffies; 685e8b12f0fSMahesh Rajashekhara /* 686e8b12f0fSMahesh Rajashekhara * Wait for the adapter to be up and running. Wait up to 3 minutes 687e8b12f0fSMahesh Rajashekhara */ 688e8b12f0fSMahesh Rajashekhara while (!((status = src_readl(dev, MUnit.OMR)) & 689e8b12f0fSMahesh Rajashekhara KERNEL_UP_AND_RUNNING)) { 690e8b12f0fSMahesh Rajashekhara if ((restart && 691e8b12f0fSMahesh Rajashekhara (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || 692e8b12f0fSMahesh Rajashekhara time_after(jiffies, start+HZ*startup_timeout)) { 693e8b12f0fSMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 694e8b12f0fSMahesh Rajashekhara dev->name, instance, status); 695e8b12f0fSMahesh Rajashekhara goto error_iounmap; 696e8b12f0fSMahesh Rajashekhara } 697e8b12f0fSMahesh Rajashekhara if (!restart && 698e8b12f0fSMahesh Rajashekhara ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || 699e8b12f0fSMahesh Rajashekhara time_after(jiffies, start + HZ * 700e8b12f0fSMahesh Rajashekhara ((startup_timeout > 60) 701e8b12f0fSMahesh Rajashekhara ? (startup_timeout - 60) 702e8b12f0fSMahesh Rajashekhara : (startup_timeout / 2))))) { 703e8b12f0fSMahesh Rajashekhara if (likely(!aac_src_restart_adapter(dev, 704e8b12f0fSMahesh Rajashekhara aac_src_check_health(dev)))) 705e8b12f0fSMahesh Rajashekhara start = jiffies; 706e8b12f0fSMahesh Rajashekhara ++restart; 707e8b12f0fSMahesh Rajashekhara } 708e8b12f0fSMahesh Rajashekhara msleep(1); 709e8b12f0fSMahesh Rajashekhara } 710e8b12f0fSMahesh Rajashekhara if (restart && aac_commit) 711e8b12f0fSMahesh Rajashekhara aac_commit = 1; 712e8b12f0fSMahesh Rajashekhara /* 713e8b12f0fSMahesh Rajashekhara * Fill in the common function dispatch table. 714e8b12f0fSMahesh Rajashekhara */ 715e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; 716e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; 717dafde947SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 718e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_notify = aac_src_notify_adapter; 719e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_sync_cmd = src_sync_cmd; 720e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_check_health = aac_src_check_health; 721e8b12f0fSMahesh Rajashekhara dev->a_ops.adapter_restart = aac_src_restart_adapter; 722de665f28SMahesh Rajashekhara dev->a_ops.adapter_start = aac_src_start_adapter; 723e8b12f0fSMahesh Rajashekhara 724e8b12f0fSMahesh Rajashekhara /* 725e8b12f0fSMahesh Rajashekhara * First clear out all interrupts. Then enable the one's that we 726e8b12f0fSMahesh Rajashekhara * can handle. 727e8b12f0fSMahesh Rajashekhara */ 728e8b12f0fSMahesh Rajashekhara aac_adapter_comm(dev, AAC_COMM_MESSAGE); 729e8b12f0fSMahesh Rajashekhara aac_adapter_disable_int(dev); 730e8b12f0fSMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 0xffffffff); 731e8b12f0fSMahesh Rajashekhara aac_adapter_enable_int(dev); 732e8b12f0fSMahesh Rajashekhara 733e8b12f0fSMahesh Rajashekhara if (aac_init_adapter(dev) == NULL) 734e8b12f0fSMahesh Rajashekhara goto error_iounmap; 735e8b12f0fSMahesh Rajashekhara if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1) 736e8b12f0fSMahesh Rajashekhara goto error_iounmap; 737e8b12f0fSMahesh Rajashekhara 7389022d375SMahesh Rajashekhara dev->msi = !pci_enable_msi(dev->pdev); 739e8b12f0fSMahesh Rajashekhara 740495c0217SMahesh Rajashekhara dev->aac_msix[0].vector_no = 0; 741495c0217SMahesh Rajashekhara dev->aac_msix[0].dev = dev; 742495c0217SMahesh Rajashekhara 743e8b12f0fSMahesh Rajashekhara if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, 744495c0217SMahesh Rajashekhara IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) { 745e8b12f0fSMahesh Rajashekhara 746e8b12f0fSMahesh Rajashekhara if (dev->msi) 747e8b12f0fSMahesh Rajashekhara pci_disable_msi(dev->pdev); 748e8b12f0fSMahesh Rajashekhara 749e8b12f0fSMahesh Rajashekhara printk(KERN_ERR "%s%d: Interrupt unavailable.\n", 750e8b12f0fSMahesh Rajashekhara name, instance); 751e8b12f0fSMahesh Rajashekhara goto error_iounmap; 752e8b12f0fSMahesh Rajashekhara } 753e8b12f0fSMahesh Rajashekhara dev->dbg_base = pci_resource_start(dev->pdev, 2); 754e8b12f0fSMahesh Rajashekhara dev->dbg_base_mapped = dev->regs.src.bar1; 755e8b12f0fSMahesh Rajashekhara dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE; 756dafde947SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message; 757e8b12f0fSMahesh Rajashekhara 758e8b12f0fSMahesh Rajashekhara aac_adapter_enable_int(dev); 75911604612SMahesh Rajashekhara 76011604612SMahesh Rajashekhara if (!dev->sync_mode) { 761e8b12f0fSMahesh Rajashekhara /* 762e8b12f0fSMahesh Rajashekhara * Tell the adapter that all is configured, and it can 763e8b12f0fSMahesh Rajashekhara * start accepting requests 764e8b12f0fSMahesh Rajashekhara */ 765e8b12f0fSMahesh Rajashekhara aac_src_start_adapter(dev); 76611604612SMahesh Rajashekhara } 767e8b12f0fSMahesh Rajashekhara return 0; 768e8b12f0fSMahesh Rajashekhara 769e8b12f0fSMahesh Rajashekhara error_iounmap: 770e8b12f0fSMahesh Rajashekhara 771e8b12f0fSMahesh Rajashekhara return -1; 772e8b12f0fSMahesh Rajashekhara } 77311604612SMahesh Rajashekhara 77411604612SMahesh Rajashekhara /** 77511604612SMahesh Rajashekhara * aac_srcv_init - initialize an SRCv card 77611604612SMahesh Rajashekhara * @dev: device to configure 77711604612SMahesh Rajashekhara * 77811604612SMahesh Rajashekhara */ 77911604612SMahesh Rajashekhara 78011604612SMahesh Rajashekhara int aac_srcv_init(struct aac_dev *dev) 78111604612SMahesh Rajashekhara { 78211604612SMahesh Rajashekhara unsigned long start; 78311604612SMahesh Rajashekhara unsigned long status; 78411604612SMahesh Rajashekhara int restart = 0; 78511604612SMahesh Rajashekhara int instance = dev->id; 78611604612SMahesh Rajashekhara const char *name = dev->name; 78711604612SMahesh Rajashekhara 78811604612SMahesh Rajashekhara dev->a_ops.adapter_ioremap = aac_srcv_ioremap; 78911604612SMahesh Rajashekhara dev->a_ops.adapter_comm = aac_src_select_comm; 79011604612SMahesh Rajashekhara 79111604612SMahesh Rajashekhara dev->base_size = AAC_MIN_SRCV_BAR0_SIZE; 79211604612SMahesh Rajashekhara if (aac_adapter_ioremap(dev, dev->base_size)) { 79311604612SMahesh Rajashekhara printk(KERN_WARNING "%s: unable to map adapter.\n", name); 79411604612SMahesh Rajashekhara goto error_iounmap; 79511604612SMahesh Rajashekhara } 79611604612SMahesh Rajashekhara 79711604612SMahesh Rajashekhara /* Failure to reset here is an option ... */ 79811604612SMahesh Rajashekhara dev->a_ops.adapter_sync_cmd = src_sync_cmd; 79911604612SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 80011604612SMahesh Rajashekhara if ((aac_reset_devices || reset_devices) && 80111604612SMahesh Rajashekhara !aac_src_restart_adapter(dev, 0)) 80211604612SMahesh Rajashekhara ++restart; 80311604612SMahesh Rajashekhara /* 8042c10cd43SMahesh Rajashekhara * Check to see if flash update is running. 8052c10cd43SMahesh Rajashekhara * Wait for the adapter to be up and running. Wait up to 5 minutes 8062c10cd43SMahesh Rajashekhara */ 8072c10cd43SMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 8082c10cd43SMahesh Rajashekhara if (status & FLASH_UPD_PENDING) { 8092c10cd43SMahesh Rajashekhara start = jiffies; 8102c10cd43SMahesh Rajashekhara do { 8112c10cd43SMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 8122c10cd43SMahesh Rajashekhara if (time_after(jiffies, start+HZ*FWUPD_TIMEOUT)) { 8132c10cd43SMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter flash update failed.\n", 8142c10cd43SMahesh Rajashekhara dev->name, instance); 8152c10cd43SMahesh Rajashekhara goto error_iounmap; 8162c10cd43SMahesh Rajashekhara } 8172c10cd43SMahesh Rajashekhara } while (!(status & FLASH_UPD_SUCCESS) && 8182c10cd43SMahesh Rajashekhara !(status & FLASH_UPD_FAILED)); 8192c10cd43SMahesh Rajashekhara /* Delay 10 seconds. 8202c10cd43SMahesh Rajashekhara * Because right now FW is doing a soft reset, 8212c10cd43SMahesh Rajashekhara * do not read scratch pad register at this time 8222c10cd43SMahesh Rajashekhara */ 8232c10cd43SMahesh Rajashekhara ssleep(10); 8242c10cd43SMahesh Rajashekhara } 8252c10cd43SMahesh Rajashekhara /* 82611604612SMahesh Rajashekhara * Check to see if the board panic'd while booting. 82711604612SMahesh Rajashekhara */ 82811604612SMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 82911604612SMahesh Rajashekhara if (status & KERNEL_PANIC) { 83011604612SMahesh Rajashekhara if (aac_src_restart_adapter(dev, aac_src_check_health(dev))) 83111604612SMahesh Rajashekhara goto error_iounmap; 83211604612SMahesh Rajashekhara ++restart; 83311604612SMahesh Rajashekhara } 83411604612SMahesh Rajashekhara /* 83511604612SMahesh Rajashekhara * Check to see if the board failed any self tests. 83611604612SMahesh Rajashekhara */ 83711604612SMahesh Rajashekhara status = src_readl(dev, MUnit.OMR); 83811604612SMahesh Rajashekhara if (status & SELF_TEST_FAILED) { 83911604612SMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); 84011604612SMahesh Rajashekhara goto error_iounmap; 84111604612SMahesh Rajashekhara } 84211604612SMahesh Rajashekhara /* 84311604612SMahesh Rajashekhara * Check to see if the monitor panic'd while booting. 84411604612SMahesh Rajashekhara */ 84511604612SMahesh Rajashekhara if (status & MONITOR_PANIC) { 84611604612SMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); 84711604612SMahesh Rajashekhara goto error_iounmap; 84811604612SMahesh Rajashekhara } 84911604612SMahesh Rajashekhara start = jiffies; 85011604612SMahesh Rajashekhara /* 85111604612SMahesh Rajashekhara * Wait for the adapter to be up and running. Wait up to 3 minutes 85211604612SMahesh Rajashekhara */ 8532c10cd43SMahesh Rajashekhara while (!((status = src_readl(dev, MUnit.OMR)) & 8542c10cd43SMahesh Rajashekhara KERNEL_UP_AND_RUNNING) || 8552c10cd43SMahesh Rajashekhara status == 0xffffffff) { 85611604612SMahesh Rajashekhara if ((restart && 85711604612SMahesh Rajashekhara (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || 85811604612SMahesh Rajashekhara time_after(jiffies, start+HZ*startup_timeout)) { 85911604612SMahesh Rajashekhara printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 86011604612SMahesh Rajashekhara dev->name, instance, status); 86111604612SMahesh Rajashekhara goto error_iounmap; 86211604612SMahesh Rajashekhara } 86311604612SMahesh Rajashekhara if (!restart && 86411604612SMahesh Rajashekhara ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || 86511604612SMahesh Rajashekhara time_after(jiffies, start + HZ * 86611604612SMahesh Rajashekhara ((startup_timeout > 60) 86711604612SMahesh Rajashekhara ? (startup_timeout - 60) 86811604612SMahesh Rajashekhara : (startup_timeout / 2))))) { 86911604612SMahesh Rajashekhara if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev)))) 87011604612SMahesh Rajashekhara start = jiffies; 87111604612SMahesh Rajashekhara ++restart; 87211604612SMahesh Rajashekhara } 87311604612SMahesh Rajashekhara msleep(1); 87411604612SMahesh Rajashekhara } 87511604612SMahesh Rajashekhara if (restart && aac_commit) 87611604612SMahesh Rajashekhara aac_commit = 1; 87711604612SMahesh Rajashekhara /* 87811604612SMahesh Rajashekhara * Fill in the common function dispatch table. 87911604612SMahesh Rajashekhara */ 88011604612SMahesh Rajashekhara dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; 88111604612SMahesh Rajashekhara dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; 882dafde947SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 88311604612SMahesh Rajashekhara dev->a_ops.adapter_notify = aac_src_notify_adapter; 88411604612SMahesh Rajashekhara dev->a_ops.adapter_sync_cmd = src_sync_cmd; 88511604612SMahesh Rajashekhara dev->a_ops.adapter_check_health = aac_src_check_health; 88611604612SMahesh Rajashekhara dev->a_ops.adapter_restart = aac_src_restart_adapter; 887de665f28SMahesh Rajashekhara dev->a_ops.adapter_start = aac_src_start_adapter; 88811604612SMahesh Rajashekhara 88911604612SMahesh Rajashekhara /* 89011604612SMahesh Rajashekhara * First clear out all interrupts. Then enable the one's that we 89111604612SMahesh Rajashekhara * can handle. 89211604612SMahesh Rajashekhara */ 89311604612SMahesh Rajashekhara aac_adapter_comm(dev, AAC_COMM_MESSAGE); 89411604612SMahesh Rajashekhara aac_adapter_disable_int(dev); 89511604612SMahesh Rajashekhara src_writel(dev, MUnit.ODR_C, 0xffffffff); 89611604612SMahesh Rajashekhara aac_adapter_enable_int(dev); 89711604612SMahesh Rajashekhara 89811604612SMahesh Rajashekhara if (aac_init_adapter(dev) == NULL) 89911604612SMahesh Rajashekhara goto error_iounmap; 90085d22bbfSMahesh Rajashekhara if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) 90111604612SMahesh Rajashekhara goto error_iounmap; 902495c0217SMahesh Rajashekhara if (dev->msi_enabled) 903495c0217SMahesh Rajashekhara aac_src_access_devreg(dev, AAC_ENABLE_MSIX); 904495c0217SMahesh Rajashekhara 9058b1462e0SMahesh Rajashekhara if (aac_acquire_irq(dev)) 906495c0217SMahesh Rajashekhara goto error_iounmap; 907495c0217SMahesh Rajashekhara 908ff08784bSBen Collins dev->dbg_base = dev->base_start; 90911604612SMahesh Rajashekhara dev->dbg_base_mapped = dev->base; 91011604612SMahesh Rajashekhara dev->dbg_size = dev->base_size; 911dafde947SMahesh Rajashekhara dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message; 91211604612SMahesh Rajashekhara 91311604612SMahesh Rajashekhara aac_adapter_enable_int(dev); 91411604612SMahesh Rajashekhara 91511604612SMahesh Rajashekhara if (!dev->sync_mode) { 91611604612SMahesh Rajashekhara /* 91711604612SMahesh Rajashekhara * Tell the adapter that all is configured, and it can 91811604612SMahesh Rajashekhara * start accepting requests 91911604612SMahesh Rajashekhara */ 92011604612SMahesh Rajashekhara aac_src_start_adapter(dev); 92111604612SMahesh Rajashekhara } 92211604612SMahesh Rajashekhara return 0; 92311604612SMahesh Rajashekhara 92411604612SMahesh Rajashekhara error_iounmap: 92511604612SMahesh Rajashekhara 92611604612SMahesh Rajashekhara return -1; 92711604612SMahesh Rajashekhara } 92811604612SMahesh Rajashekhara 929495c0217SMahesh Rajashekhara void aac_src_access_devreg(struct aac_dev *dev, int mode) 930495c0217SMahesh Rajashekhara { 931495c0217SMahesh Rajashekhara u_int32_t val; 932495c0217SMahesh Rajashekhara 933495c0217SMahesh Rajashekhara switch (mode) { 934495c0217SMahesh Rajashekhara case AAC_ENABLE_INTERRUPT: 935495c0217SMahesh Rajashekhara src_writel(dev, 936495c0217SMahesh Rajashekhara MUnit.OIMR, 937495c0217SMahesh Rajashekhara dev->OIMR = (dev->msi_enabled ? 938495c0217SMahesh Rajashekhara AAC_INT_ENABLE_TYPE1_MSIX : 939495c0217SMahesh Rajashekhara AAC_INT_ENABLE_TYPE1_INTX)); 940495c0217SMahesh Rajashekhara break; 941495c0217SMahesh Rajashekhara 942495c0217SMahesh Rajashekhara case AAC_DISABLE_INTERRUPT: 943495c0217SMahesh Rajashekhara src_writel(dev, 944495c0217SMahesh Rajashekhara MUnit.OIMR, 945495c0217SMahesh Rajashekhara dev->OIMR = AAC_INT_DISABLE_ALL); 946495c0217SMahesh Rajashekhara break; 947495c0217SMahesh Rajashekhara 948495c0217SMahesh Rajashekhara case AAC_ENABLE_MSIX: 949495c0217SMahesh Rajashekhara /* set bit 6 */ 950495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.IDR); 951495c0217SMahesh Rajashekhara val |= 0x40; 952495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IDR, val); 953495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IDR); 954495c0217SMahesh Rajashekhara /* unmask int. */ 955495c0217SMahesh Rajashekhara val = PMC_ALL_INTERRUPT_BITS; 956495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IOAR, val); 957495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.OIMR); 958495c0217SMahesh Rajashekhara src_writel(dev, 959495c0217SMahesh Rajashekhara MUnit.OIMR, 960495c0217SMahesh Rajashekhara val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0))); 961495c0217SMahesh Rajashekhara break; 962495c0217SMahesh Rajashekhara 963495c0217SMahesh Rajashekhara case AAC_DISABLE_MSIX: 964495c0217SMahesh Rajashekhara /* reset bit 6 */ 965495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.IDR); 966495c0217SMahesh Rajashekhara val &= ~0x40; 967495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IDR, val); 968495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IDR); 969495c0217SMahesh Rajashekhara break; 970495c0217SMahesh Rajashekhara 971495c0217SMahesh Rajashekhara case AAC_CLEAR_AIF_BIT: 972495c0217SMahesh Rajashekhara /* set bit 5 */ 973495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.IDR); 974495c0217SMahesh Rajashekhara val |= 0x20; 975495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IDR, val); 976495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IDR); 977495c0217SMahesh Rajashekhara break; 978495c0217SMahesh Rajashekhara 979495c0217SMahesh Rajashekhara case AAC_CLEAR_SYNC_BIT: 980495c0217SMahesh Rajashekhara /* set bit 4 */ 981495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.IDR); 982495c0217SMahesh Rajashekhara val |= 0x10; 983495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IDR, val); 984495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IDR); 985495c0217SMahesh Rajashekhara break; 986495c0217SMahesh Rajashekhara 987495c0217SMahesh Rajashekhara case AAC_ENABLE_INTX: 988495c0217SMahesh Rajashekhara /* set bit 7 */ 989495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.IDR); 990495c0217SMahesh Rajashekhara val |= 0x80; 991495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IDR, val); 992495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IDR); 993495c0217SMahesh Rajashekhara /* unmask int. */ 994495c0217SMahesh Rajashekhara val = PMC_ALL_INTERRUPT_BITS; 995495c0217SMahesh Rajashekhara src_writel(dev, MUnit.IOAR, val); 996495c0217SMahesh Rajashekhara src_readl(dev, MUnit.IOAR); 997495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.OIMR); 998495c0217SMahesh Rajashekhara src_writel(dev, MUnit.OIMR, 999495c0217SMahesh Rajashekhara val & (~(PMC_GLOBAL_INT_BIT2))); 1000495c0217SMahesh Rajashekhara break; 1001495c0217SMahesh Rajashekhara 1002495c0217SMahesh Rajashekhara default: 1003495c0217SMahesh Rajashekhara break; 1004495c0217SMahesh Rajashekhara } 1005495c0217SMahesh Rajashekhara } 1006495c0217SMahesh Rajashekhara 1007495c0217SMahesh Rajashekhara static int aac_src_get_sync_status(struct aac_dev *dev) 1008495c0217SMahesh Rajashekhara { 1009495c0217SMahesh Rajashekhara 1010495c0217SMahesh Rajashekhara int val; 1011495c0217SMahesh Rajashekhara 1012495c0217SMahesh Rajashekhara if (dev->msi_enabled) 1013495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0; 1014495c0217SMahesh Rajashekhara else 1015495c0217SMahesh Rajashekhara val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; 1016495c0217SMahesh Rajashekhara 1017495c0217SMahesh Rajashekhara return val; 1018495c0217SMahesh Rajashekhara } 1019