1/* 2 * linux/drivers/ide/ide-m8xx.c 3 * 4 * Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de 5 * Modified for direct IDE interface 6 * by Thomas Lange, thomas@corelatus.com 7 * Modified for direct IDE interface on 8xx without using the PCMCIA 8 * controller 9 * by Steven.Scholz@imc-berlin.de 10 * Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups 11 * by Mathew Locke <mattl@mvista.com> 12 */ 13 14#include <linux/config.h> 15#include <linux/errno.h> 16#include <linux/sched.h> 17#include <linux/kernel.h> 18#include <linux/mm.h> 19#include <linux/stddef.h> 20#include <linux/unistd.h> 21#include <linux/ptrace.h> 22#include <linux/slab.h> 23#include <linux/user.h> 24#include <linux/a.out.h> 25#include <linux/tty.h> 26#include <linux/major.h> 27#include <linux/interrupt.h> 28#include <linux/reboot.h> 29#include <linux/init.h> 30#include <linux/blk.h> 31#include <linux/ioport.h> 32#include <linux/ide.h> 33#include <linux/bootmem.h> 34 35#include <asm/mpc8xx.h> 36#include <asm/mmu.h> 37#include <asm/processor.h> 38#include <asm/residual.h> 39#include <asm/io.h> 40#include <asm/pgtable.h> 41#include <asm/ide.h> 42#include <asm/8xx_immap.h> 43#include <asm/machdep.h> 44#include <asm/irq.h> 45 46#include "ide_modes.h" 47static int identify (volatile unsigned char *p); 48static void print_fixed (volatile unsigned char *p); 49static void print_funcid (int func); 50static int check_ide_device (unsigned long base); 51 52static void ide_interrupt_ack (void *dev); 53static void m8xx_ide_tuneproc(ide_drive_t *drive, byte pio); 54 55typedef struct ide_ioport_desc { 56 unsigned long base_off; /* Offset to PCMCIA memory */ 57 ide_ioreg_t reg_off[IDE_NR_PORTS]; /* controller register offsets */ 58 int irq; /* IRQ */ 59} ide_ioport_desc_t; 60 61ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = { 62#ifdef IDE0_BASE_OFFSET 63 { IDE0_BASE_OFFSET, 64 { 65 IDE0_DATA_REG_OFFSET, 66 IDE0_ERROR_REG_OFFSET, 67 IDE0_NSECTOR_REG_OFFSET, 68 IDE0_SECTOR_REG_OFFSET, 69 IDE0_LCYL_REG_OFFSET, 70 IDE0_HCYL_REG_OFFSET, 71 IDE0_SELECT_REG_OFFSET, 72 IDE0_STATUS_REG_OFFSET, 73 IDE0_CONTROL_REG_OFFSET, 74 IDE0_IRQ_REG_OFFSET, 75 }, 76 IDE0_INTERRUPT, 77 }, 78#ifdef IDE1_BASE_OFFSET 79 { IDE1_BASE_OFFSET, 80 { 81 IDE1_DATA_REG_OFFSET, 82 IDE1_ERROR_REG_OFFSET, 83 IDE1_NSECTOR_REG_OFFSET, 84 IDE1_SECTOR_REG_OFFSET, 85 IDE1_LCYL_REG_OFFSET, 86 IDE1_HCYL_REG_OFFSET, 87 IDE1_SELECT_REG_OFFSET, 88 IDE1_STATUS_REG_OFFSET, 89 IDE1_CONTROL_REG_OFFSET, 90 IDE1_IRQ_REG_OFFSET, 91 }, 92 IDE1_INTERRUPT, 93 }, 94#endif /* IDE1_BASE_OFFSET */ 95#endif /* IDE0_BASE_OFFSET */ 96}; 97 98ide_pio_timings_t ide_pio_clocks[6]; 99int hold_time[6] = {30, 20, 15, 10, 10, 10 }; /* PIO Mode 5 with IORDY (nonstandard) */ 100 101/* 102 * Warning: only 1 (ONE) PCMCIA slot supported here, 103 * which must be correctly initialized by the firmware (PPCBoot). 104 */ 105static int _slot_ = -1; /* will be read from PCMCIA registers */ 106 107/* Make clock cycles and always round up */ 108#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U ) 109 110 111 112/* 113 * IDE stuff. 114 */ 115static int 116m8xx_ide_default_irq(ide_ioreg_t base) 117{ 118#ifdef CONFIG_BLK_DEV_MPC8xx_IDE 119 if (base >= MAX_HWIFS) 120 return 0; 121 122 printk("[%d] m8xx_ide_default_irq %d\n",__LINE__,ioport_dsc[base].irq); 123 124 return (ioport_dsc[base].irq); 125#else 126 return 9; 127#endif 128} 129 130static ide_ioreg_t 131m8xx_ide_default_io_base(int index) 132{ 133 return index; 134} 135 136#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4)) 137#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4)) 138 139/* 140 * The TQM850L hardware has two pins swapped! Grrrrgh! 141 */ 142#ifdef CONFIG_TQM850L 143#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE 144#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET 145#else 146#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET 147#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE 148#endif 149 150#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD) 151#define PCMCIA_SCHLVL IDE0_INTERRUPT /* Status Change Interrupt Level */ 152static int pcmcia_schlvl = PCMCIA_SCHLVL; 153#endif 154 155/* 156 * See include/linux/ide.h for definition of hw_regs_t (p, base) 157 */ 158 159/* 160 * m8xx_ide_init_hwif_ports for a direct IDE interface _using_ 161 */ 162#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) 163static void 164m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 165 ide_ioreg_t ctrl_port, int *irq) 166{ 167 ide_ioreg_t *p = hw->io_ports; 168 int i; 169 170 typedef struct { 171 ulong br; 172 ulong or; 173 } pcmcia_win_t; 174 volatile pcmcia_win_t *win; 175 volatile pcmconf8xx_t *pcmp; 176 177 uint *pgcrx; 178 u32 pcmcia_phy_base; 179 u32 pcmcia_phy_end; 180 static unsigned long pcmcia_base = 0; 181 unsigned long base; 182 183 *p = 0; 184 if (irq) 185 *irq = 0; 186 187 pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); 188 189 if (!pcmcia_base) { 190 /* 191 * Read out PCMCIA registers. Since the reset values 192 * are undefined, we sure hope that they have been 193 * set up by firmware 194 */ 195 196 /* Scan all registers for valid settings */ 197 pcmcia_phy_base = 0xFFFFFFFF; 198 pcmcia_phy_end = 0; 199 /* br0 is start of brX and orX regs */ 200 win = (pcmcia_win_t *) \ 201 (&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0)); 202 for (i = 0; i < 8; i++) { 203 if (win->or & 1) { /* This bank is marked as valid */ 204 if (win->br < pcmcia_phy_base) { 205 pcmcia_phy_base = win->br; 206 } 207 if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) { 208 pcmcia_phy_end = win->br + PCMCIA_MEM_SIZE; 209 } 210 /* Check which slot that has been defined */ 211 _slot_ = (win->or >> 2) & 1; 212 213 } /* Valid bank */ 214 win++; 215 } /* for */ 216 217 printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n", 218 'A' + _slot_, 219 pcmcia_phy_base, pcmcia_phy_end, 220 pcmcia_phy_end - pcmcia_phy_base); 221 222 pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base, 223 pcmcia_phy_end-pcmcia_phy_base); 224 225#ifdef DEBUG 226 printk ("PCMCIA virt base: %08lx\n", pcmcia_base); 227#endif 228 /* Compute clock cycles for PIO timings */ 229 for (i=0; i<6; ++i) { 230 bd_t *binfo = (bd_t *)__res; 231 232 hold_time[i] = 233 PCMCIA_MK_CLKS (hold_time[i], 234 binfo->bi_busfreq); 235 ide_pio_clocks[i].setup_time = 236 PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time, 237 binfo->bi_busfreq); 238 ide_pio_clocks[i].active_time = 239 PCMCIA_MK_CLKS (ide_pio_timings[i].active_time, 240 binfo->bi_busfreq); 241 ide_pio_clocks[i].cycle_time = 242 PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time, 243 binfo->bi_busfreq); 244 } 245 } 246 247 if (data_port >= MAX_HWIFS) 248 return; 249 250 if (_slot_ == -1) { 251 printk ("PCMCIA slot has not been defined! Using A as default\n"); 252 _slot_ = 0; 253 } 254 255#ifdef CONFIG_IDE_8xx_PCCARD 256 257#ifdef DEBUG 258 printk ("PIPR = 0x%08X slot %c ==> mask = 0x%X\n", 259 pcmp->pcmc_pipr, 260 'A' + _slot_, 261 M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) ); 262#endif /* DEBUG */ 263 264 if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) { 265 printk ("No card in slot %c: PIPR=%08x\n", 266 'A' + _slot_, (u32) pcmp->pcmc_pipr); 267 return; /* No card in slot */ 268 } 269 270 check_ide_device (pcmcia_base); 271 272#endif /* CONFIG_IDE_8xx_PCCARD */ 273 274 base = pcmcia_base + ioport_dsc[data_port].base_off; 275#ifdef DEBUG 276 printk ("base: %08x + %08x = %08x\n", 277 pcmcia_base, ioport_dsc[data_port].base_off, base); 278#endif 279 280 for (i = 0; i < IDE_NR_PORTS; ++i) { 281#ifdef DEBUG 282 printk ("port[%d]: %08x + %08x = %08x\n", 283 i, 284 base, 285 ioport_dsc[data_port].reg_off[i], 286 i, base + ioport_dsc[data_port].reg_off[i]); 287#endif 288 *p++ = base + ioport_dsc[data_port].reg_off[i]; 289 } 290 291 if (irq) { 292#ifdef CONFIG_IDE_8xx_PCCARD 293 unsigned int reg; 294 295 *irq = ioport_dsc[data_port].irq; 296 if (_slot_) 297 pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb; 298 else 299 pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra; 300 301 reg = *pgcrx; 302 reg |= mk_int_int_mask (pcmcia_schlvl) << 24; 303 reg |= mk_int_int_mask (pcmcia_schlvl) << 16; 304 *pgcrx = reg; 305#else /* direct connected IDE drive, i.e. external IRQ, not the PCMCIA irq */ 306 *irq = ioport_dsc[data_port].irq; 307#endif /* CONFIG_IDE_8xx_PCCARD */ 308 } 309 310 /* register routine to tune PIO mode */ 311 ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc; 312 313 hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack; 314 /* Enable Harddisk Interrupt, 315 * and make it edge sensitive 316 */ 317 /* (11-18) Set edge detect for irq, no wakeup from low power mode */ 318 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= 319 (0x80000000 >> ioport_dsc[data_port].irq); 320 321#ifdef CONFIG_IDE_8xx_PCCARD 322 /* Make sure we dont get garbage irq */ 323 ((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF; 324 325 /* Enable falling edge irq */ 326 pcmp->pcmc_per = 0x100000 >> (16 * _slot_); 327#endif /* CONFIG_IDE_8xx_PCCARD */ 328} /* m8xx_ide_init_hwif_ports() using 8xx internal PCMCIA interface */ 329#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ 330 331/* 332 * m8xx_ide_init_hwif_ports for a direct IDE interface _not_ using 333 * MPC8xx's internal PCMCIA interface 334 */ 335#if defined(CONFIG_IDE_EXT_DIRECT) 336void m8xx_ide_init_hwif_ports (hw_regs_t *hw, 337 ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) 338{ 339 ide_ioreg_t *p = hw->io_ports; 340 int i; 341 342 u32 ide_phy_base; 343 u32 ide_phy_end; 344 static unsigned long ide_base = 0; 345 unsigned long base; 346 347 *p = 0; 348 if (irq) 349 *irq = 0; 350 351 if (!ide_base) { 352 353 /* TODO: 354 * - add code to read ORx, BRx 355 */ 356 ide_phy_base = CFG_ATA_BASE_ADDR; 357 ide_phy_end = CFG_ATA_BASE_ADDR + 0x200; 358 359 printk ("IDE phys mem : %08x...%08x (size %08x)\n", 360 ide_phy_base, ide_phy_end, 361 ide_phy_end - ide_phy_base); 362 363 ide_base=(unsigned long)ioremap(ide_phy_base, 364 ide_phy_end-ide_phy_base); 365 366#ifdef DEBUG 367 printk ("IDE virt base: %08lx\n", ide_base); 368#endif 369 } 370 371 if (data_port >= MAX_HWIFS) 372 return; 373 374 base = ide_base + ioport_dsc[data_port].base_off; 375#ifdef DEBUG 376 printk ("base: %08x + %08x = %08x\n", 377 ide_base, ioport_dsc[data_port].base_off, base); 378#endif 379 380 for (i = 0; i < IDE_NR_PORTS; ++i) { 381#ifdef DEBUG 382 printk ("port[%d]: %08x + %08x = %08x\n", 383 i, 384 base, 385 ioport_dsc[data_port].reg_off[i], 386 i, base + ioport_dsc[data_port].reg_off[i]); 387#endif 388 *p++ = base + ioport_dsc[data_port].reg_off[i]; 389 } 390 391 if (irq) { 392 /* direct connected IDE drive, i.e. external IRQ */ 393 *irq = ioport_dsc[data_port].irq; 394 } 395 396 /* register routine to tune PIO mode */ 397 ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc; 398 399 hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack; 400 /* Enable Harddisk Interrupt, 401 * and make it edge sensitive 402 */ 403 /* (11-18) Set edge detect for irq, no wakeup from low power mode */ 404 ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= 405 (0x80000000 >> ioport_dsc[data_port].irq); 406} /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */ 407 408#endif /* CONFIG_IDE_8xx_DIRECT */ 409 410 411/* -------------------------------------------------------------------- */ 412 413 414/* PCMCIA Timing */ 415#ifndef PCMCIA_SHT 416#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */ 417#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */ 418#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */ 419#endif 420 421 422/* Calculate PIO timings */ 423static void 424m8xx_ide_tuneproc(ide_drive_t *drive, byte pio) 425{ 426 ide_pio_data_t d; 427#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) 428 volatile pcmconf8xx_t *pcmp; 429 ulong timing, mask, reg; 430#endif 431 432 pio = ide_get_best_pio_mode(drive, pio, 4, &d); 433 434 printk("%s[%d] %s: best PIO mode: %d\n", 435 __FILE__,__LINE__,__FUNCTION__, pio); 436 437#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) 438 pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); 439 440 mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF)); 441 442 timing = PCMCIA_SHT(hold_time[pio] ) 443 | PCMCIA_SST(ide_pio_clocks[pio].setup_time ) 444 | PCMCIA_SL (ide_pio_clocks[pio].active_time) 445 ; 446 447 printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing); 448 if ((reg = pcmp->pcmc_por0 & mask) != 0) 449 pcmp->pcmc_por0 = reg | timing; 450 451 if ((reg = pcmp->pcmc_por1 & mask) != 0) 452 pcmp->pcmc_por1 = reg | timing; 453 454 if ((reg = pcmp->pcmc_por2 & mask) != 0) 455 pcmp->pcmc_por2 = reg | timing; 456 457 if ((reg = pcmp->pcmc_por3 & mask) != 0) 458 pcmp->pcmc_por3 = reg | timing; 459 460 if ((reg = pcmp->pcmc_por4 & mask) != 0) 461 pcmp->pcmc_por4 = reg | timing; 462 463 if ((reg = pcmp->pcmc_por5 & mask) != 0) 464 pcmp->pcmc_por5 = reg | timing; 465 466 if ((reg = pcmp->pcmc_por6 & mask) != 0) 467 pcmp->pcmc_por6 = reg | timing; 468 469 if ((reg = pcmp->pcmc_por7 & mask) != 0) 470 pcmp->pcmc_por7 = reg | timing; 471 472#elif defined(CONFIG_IDE_EXT_DIRECT) 473 474 printk("%s[%d] %s: not implemented yet!\n", 475 __FILE__,__LINE__,__FUNCTION__); 476#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */ 477} 478 479static void 480ide_interrupt_ack (void *dev) 481{ 482#ifdef CONFIG_IDE_8xx_PCCARD 483 u_int pscr, pipr; 484 485#if PCMCIA_SOCKETS_NO == 2 486 u_int _slot_; 487#endif 488 489 /* get interrupt sources */ 490 491 pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr; 492 pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr; 493 494 /* 495 * report only if both card detect signals are the same 496 * not too nice done, 497 * we depend on that CD2 is the bit to the left of CD1... 498 */ 499 500 if(_slot_==-1){ 501 printk("PCMCIA slot has not been defined! Using A as default\n"); 502 _slot_=0; 503 } 504 505 if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^ 506 (pipr & M8XX_PCMCIA_CD1(_slot_)) ) { 507 printk ("card detect interrupt\n"); 508 } 509 /* clear the interrupt sources */ 510 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr; 511 512#else /* ! CONFIG_IDE_8xx_PCCARD */ 513 /* 514 * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the 515 * MPC8xx's PCMCIA controller, so there is nothing to be done here 516 * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT. 517 * The interrupt is handled somewhere else. -- Steven 518 */ 519#endif /* CONFIG_IDE_8xx_PCCARD */ 520} 521 522 523 524/* 525 * CIS Tupel codes 526 */ 527#define CISTPL_NULL 0x00 528#define CISTPL_DEVICE 0x01 529#define CISTPL_LONGLINK_CB 0x02 530#define CISTPL_INDIRECT 0x03 531#define CISTPL_CONFIG_CB 0x04 532#define CISTPL_CFTABLE_ENTRY_CB 0x05 533#define CISTPL_LONGLINK_MFC 0x06 534#define CISTPL_BAR 0x07 535#define CISTPL_PWR_MGMNT 0x08 536#define CISTPL_EXTDEVICE 0x09 537#define CISTPL_CHECKSUM 0x10 538#define CISTPL_LONGLINK_A 0x11 539#define CISTPL_LONGLINK_C 0x12 540#define CISTPL_LINKTARGET 0x13 541#define CISTPL_NO_LINK 0x14 542#define CISTPL_VERS_1 0x15 543#define CISTPL_ALTSTR 0x16 544#define CISTPL_DEVICE_A 0x17 545#define CISTPL_JEDEC_C 0x18 546#define CISTPL_JEDEC_A 0x19 547#define CISTPL_CONFIG 0x1a 548#define CISTPL_CFTABLE_ENTRY 0x1b 549#define CISTPL_DEVICE_OC 0x1c 550#define CISTPL_DEVICE_OA 0x1d 551#define CISTPL_DEVICE_GEO 0x1e 552#define CISTPL_DEVICE_GEO_A 0x1f 553#define CISTPL_MANFID 0x20 554#define CISTPL_FUNCID 0x21 555#define CISTPL_FUNCE 0x22 556#define CISTPL_SWIL 0x23 557#define CISTPL_END 0xff 558 559/* 560 * CIS Function ID codes 561 */ 562#define CISTPL_FUNCID_MULTI 0x00 563#define CISTPL_FUNCID_MEMORY 0x01 564#define CISTPL_FUNCID_SERIAL 0x02 565#define CISTPL_FUNCID_PARALLEL 0x03 566#define CISTPL_FUNCID_FIXED 0x04 567#define CISTPL_FUNCID_VIDEO 0x05 568#define CISTPL_FUNCID_NETWORK 0x06 569#define CISTPL_FUNCID_AIMS 0x07 570#define CISTPL_FUNCID_SCSI 0x08 571 572/* 573 * Fixed Disk FUNCE codes 574 */ 575#define CISTPL_IDE_INTERFACE 0x01 576 577#define CISTPL_FUNCE_IDE_IFACE 0x01 578#define CISTPL_FUNCE_IDE_MASTER 0x02 579#define CISTPL_FUNCE_IDE_SLAVE 0x03 580 581/* First feature byte */ 582#define CISTPL_IDE_SILICON 0x04 583#define CISTPL_IDE_UNIQUE 0x08 584#define CISTPL_IDE_DUAL 0x10 585 586/* Second feature byte */ 587#define CISTPL_IDE_HAS_SLEEP 0x01 588#define CISTPL_IDE_HAS_STANDBY 0x02 589#define CISTPL_IDE_HAS_IDLE 0x04 590#define CISTPL_IDE_LOW_POWER 0x08 591#define CISTPL_IDE_REG_INHIBIT 0x10 592#define CISTPL_IDE_HAS_INDEX 0x20 593#define CISTPL_IDE_IOIS16 0x40 594 595 596/* -------------------------------------------------------------------- */ 597 598 599#define MAX_TUPEL_SZ 512 600#define MAX_FEATURES 4 601 602static int check_ide_device (unsigned long base) 603{ 604 volatile unsigned char *ident = NULL; 605 volatile unsigned char *feature_p[MAX_FEATURES]; 606 volatile unsigned char *p, *start; 607 int n_features = 0; 608 unsigned char func_id = ~0; 609 unsigned char code, len; 610 unsigned short config_base = 0; 611 int found = 0; 612 int i; 613 614#ifdef DEBUG 615 printk ("PCMCIA MEM: %08lX\n", base); 616#endif 617 start = p = (volatile unsigned char *) base; 618 619 while ((p - start) < MAX_TUPEL_SZ) { 620 621 code = *p; p += 2; 622 623 if (code == 0xFF) { /* End of chain */ 624 break; 625 } 626 627 len = *p; p += 2; 628#ifdef DEBUG_PCMCIA 629 { volatile unsigned char *q = p; 630 printk ("\nTuple code %02x length %d\n\tData:", 631 code, len); 632 633 for (i = 0; i < len; ++i) { 634 printk (" %02x", *q); 635 q+= 2; 636 } 637 } 638#endif /* DEBUG_PCMCIA */ 639 switch (code) { 640 case CISTPL_VERS_1: 641 ident = p + 4; 642 break; 643 case CISTPL_FUNCID: 644 func_id = *p; 645 break; 646 case CISTPL_FUNCE: 647 if (n_features < MAX_FEATURES) 648 feature_p[n_features++] = p; 649 break; 650 case CISTPL_CONFIG: 651 config_base = (*(p+6) << 8) + (*(p+4)); 652 default: 653 break; 654 } 655 p += 2 * len; 656 } 657 658 found = identify (ident); 659 660 if (func_id != ((unsigned char)~0)) { 661 print_funcid (func_id); 662 663 if (func_id == CISTPL_FUNCID_FIXED) 664 found = 1; 665 else 666 return (1); /* no disk drive */ 667 } 668 669 for (i=0; i<n_features; ++i) { 670 print_fixed (feature_p[i]); 671 } 672 673 if (!found) { 674 printk ("unknown card type\n"); 675 return (1); 676 } 677 678 /* set level mode irq and I/O mapped device in config reg*/ 679 *((unsigned char *)(base + config_base)) = 0x41; 680 681 return (0); 682} 683 684/* ------------------------------------------------------------------------- */ 685 686static void print_funcid (int func) 687{ 688 switch (func) { 689 case CISTPL_FUNCID_MULTI: 690 printk (" Multi-Function"); 691 break; 692 case CISTPL_FUNCID_MEMORY: 693 printk (" Memory"); 694 break; 695 case CISTPL_FUNCID_SERIAL: 696 printk (" Serial Port"); 697 break; 698 case CISTPL_FUNCID_PARALLEL: 699 printk (" Parallel Port"); 700 break; 701 case CISTPL_FUNCID_FIXED: 702 printk (" Fixed Disk"); 703 break; 704 case CISTPL_FUNCID_VIDEO: 705 printk (" Video Adapter"); 706 break; 707 case CISTPL_FUNCID_NETWORK: 708 printk (" Network Adapter"); 709 break; 710 case CISTPL_FUNCID_AIMS: 711 printk (" AIMS Card"); 712 break; 713 case CISTPL_FUNCID_SCSI: 714 printk (" SCSI Adapter"); 715 break; 716 default: 717 printk (" Unknown"); 718 break; 719 } 720 printk (" Card\n"); 721} 722 723/* ------------------------------------------------------------------------- */ 724 725static void print_fixed (volatile unsigned char *p) 726{ 727 if (p == NULL) 728 return; 729 730 switch (*p) { 731 case CISTPL_FUNCE_IDE_IFACE: 732 { unsigned char iface = *(p+2); 733 734 printk ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown"); 735 printk (" interface "); 736 break; 737 } 738 case CISTPL_FUNCE_IDE_MASTER: 739 case CISTPL_FUNCE_IDE_SLAVE: 740 { unsigned char f1 = *(p+2); 741 unsigned char f2 = *(p+4); 742 743 printk ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]"); 744 745 if (f1 & CISTPL_IDE_UNIQUE) 746 printk (" [unique]"); 747 748 printk ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]"); 749 750 if (f2 & CISTPL_IDE_HAS_SLEEP) 751 printk (" [sleep]"); 752 753 if (f2 & CISTPL_IDE_HAS_STANDBY) 754 printk (" [standby]"); 755 756 if (f2 & CISTPL_IDE_HAS_IDLE) 757 printk (" [idle]"); 758 759 if (f2 & CISTPL_IDE_LOW_POWER) 760 printk (" [low power]"); 761 762 if (f2 & CISTPL_IDE_REG_INHIBIT) 763 printk (" [reg inhibit]"); 764 765 if (f2 & CISTPL_IDE_HAS_INDEX) 766 printk (" [index]"); 767 768 if (f2 & CISTPL_IDE_IOIS16) 769 printk (" [IOis16]"); 770 771 break; 772 } 773 } 774 printk ("\n"); 775} 776 777/* ------------------------------------------------------------------------- */ 778 779 780#define MAX_IDENT_CHARS 64 781#define MAX_IDENT_FIELDS 4 782 783static unsigned char *known_cards[] = { 784 "ARGOSY PnPIDE D5", 785 NULL 786}; 787 788static int identify (volatile unsigned char *p) 789{ 790 unsigned char id_str[MAX_IDENT_CHARS]; 791 unsigned char data; 792 unsigned char *t; 793 unsigned char **card; 794 int i, done; 795 796 if (p == NULL) 797 return (0); /* Don't know */ 798 799 t = id_str; 800 done =0; 801 802 for (i=0; i<=4 && !done; ++i, p+=2) { 803 while ((data = *p) != '\0') { 804 if (data == 0xFF) { 805 done = 1; 806 break; 807 } 808 *t++ = data; 809 if (t == &id_str[MAX_IDENT_CHARS-1]) { 810 done = 1; 811 break; 812 } 813 p += 2; 814 } 815 if (!done) 816 *t++ = ' '; 817 } 818 *t = '\0'; 819 while (--t > id_str) { 820 if (*t == ' ') 821 *t = '\0'; 822 else 823 break; 824 } 825 printk ("Card ID: %s\n", id_str); 826 827 for (card=known_cards; *card; ++card) { 828 if (strcmp(*card, id_str) == 0) { /* found! */ 829 return (1); 830 } 831 } 832 833 return (0); /* don't know */ 834} 835 836void m8xx_ide_init(void) 837{ 838 ppc_ide_md.default_irq = m8xx_ide_default_irq; 839 ppc_ide_md.default_io_base = m8xx_ide_default_io_base; 840 ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; 841} 842