uboot/drivers/pcmcia/i82365.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003-2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 ********************************************************************
  24 *
  25 * Lots of code copied from:
  26 *
  27 * i82365.c 1.352 - Linux driver for Intel 82365 and compatible
  28 * PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers.
  29 * (C) 1999 David A. Hinds <dahinds@users.sourceforge.net>
  30 */
  31
  32#include <common.h>
  33
  34#include <command.h>
  35#include <pci.h>
  36#include <pcmcia.h>
  37#include <asm/io.h>
  38
  39#include <pcmcia/ss.h>
  40#include <pcmcia/i82365.h>
  41#include <pcmcia/yenta.h>
  42#ifdef CONFIG_CPC45
  43#include <pcmcia/cirrus.h>
  44#else
  45#include <pcmcia/ti113x.h>
  46#endif
  47
  48static struct pci_device_id supported[] = {
  49#ifdef CONFIG_CPC45
  50        {PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729},
  51#else
  52        {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510},
  53#endif
  54        {0, 0}
  55};
  56
  57#define CYCLE_TIME      120
  58
  59#ifdef CONFIG_CPC45
  60extern int SPD67290Init (void);
  61#endif
  62
  63#ifdef DEBUG
  64static void i82365_dump_regions (pci_dev_t dev);
  65#endif
  66
  67typedef struct socket_info_t {
  68        pci_dev_t       dev;
  69        u_short         bcr;
  70        u_char          pci_lat, cb_lat, sub_bus, cache;
  71        u_int           cb_phys;
  72
  73        socket_cap_t    cap;
  74        u_short         type;
  75        u_int           flags;
  76#ifdef CONFIG_CPC45
  77        cirrus_state_t  c_state;
  78#else
  79        ti113x_state_t  state;
  80#endif
  81} socket_info_t;
  82
  83#ifdef CONFIG_CPC45
  84/* These definitions must match the pcic table! */
  85typedef enum pcic_id {
  86        IS_PD6710, IS_PD672X, IS_VT83C469
  87} pcic_id;
  88
  89typedef struct pcic_t {
  90        char *name;
  91} pcic_t;
  92
  93static pcic_t pcic[] = {
  94        {" Cirrus PD6710: "},
  95        {" Cirrus PD672x: "},
  96        {" VIA VT83C469: "},
  97};
  98#endif
  99
 100static socket_info_t socket;
 101static socket_state_t state;
 102static struct pccard_mem_map mem;
 103static struct pccard_io_map io;
 104
 105/*====================================================================*/
 106
 107/* Some PCI shortcuts */
 108
 109static int pci_readb (socket_info_t * s, int r, u_char * v)
 110{
 111        return pci_read_config_byte (s->dev, r, v);
 112}
 113static int pci_writeb (socket_info_t * s, int r, u_char v)
 114{
 115        return pci_write_config_byte (s->dev, r, v);
 116}
 117static int pci_readw (socket_info_t * s, int r, u_short * v)
 118{
 119        return pci_read_config_word (s->dev, r, v);
 120}
 121static int pci_writew (socket_info_t * s, int r, u_short v)
 122{
 123        return pci_write_config_word (s->dev, r, v);
 124}
 125#ifndef CONFIG_CPC45
 126static int pci_readl (socket_info_t * s, int r, u_int * v)
 127{
 128        return pci_read_config_dword (s->dev, r, v);
 129}
 130static int pci_writel (socket_info_t * s, int r, u_int v)
 131{
 132        return pci_write_config_dword (s->dev, r, v);
 133}
 134#endif  /* !CONFIG_CPC45 */
 135
 136/*====================================================================*/
 137
 138#ifdef CONFIG_CPC45
 139
 140#define cb_readb(s)             readb((s)->cb_phys + 1)
 141#define cb_writeb(s, v)         writeb(v, (s)->cb_phys)
 142#define cb_writeb2(s, v)        writeb(v, (s)->cb_phys + 1)
 143#define cb_readl(s, r)          readl((s)->cb_phys + (r))
 144#define cb_writel(s, r, v)      writel(v, (s)->cb_phys + (r))
 145
 146
 147static u_char i365_get (socket_info_t * s, u_short reg)
 148{
 149        u_char val;
 150#ifdef CONFIG_PCMCIA_SLOT_A
 151        int slot = 0;
 152#else
 153        int slot = 1;
 154#endif
 155
 156        val = I365_REG (slot, reg);
 157
 158        cb_writeb (s, val);
 159        val = cb_readb (s);
 160
 161        debug ("i365_get slot:%x reg: %x val: %x\n", slot, reg, val);
 162        return val;
 163}
 164
 165static void i365_set (socket_info_t * s, u_short reg, u_char data)
 166{
 167#ifdef CONFIG_PCMCIA_SLOT_A
 168        int slot = 0;
 169#else
 170        int slot = 1;
 171#endif
 172        u_char val;
 173
 174        val = I365_REG (slot, reg);
 175
 176        cb_writeb (s, val);
 177        cb_writeb2 (s, data);
 178
 179        debug ("i365_set slot:%x reg: %x data:%x\n", slot, reg, data);
 180}
 181
 182#else   /* ! CONFIG_CPC45 */
 183
 184#define cb_readb(s, r)          readb((s)->cb_phys + (r))
 185#define cb_readl(s, r)          readl((s)->cb_phys + (r))
 186#define cb_writeb(s, r, v)      writeb(v, (s)->cb_phys + (r))
 187#define cb_writel(s, r, v)      writel(v, (s)->cb_phys + (r))
 188
 189static u_char i365_get (socket_info_t * s, u_short reg)
 190{
 191        return cb_readb (s, 0x0800 + reg);
 192}
 193
 194static void i365_set (socket_info_t * s, u_short reg, u_char data)
 195{
 196        cb_writeb (s, 0x0800 + reg, data);
 197}
 198#endif  /* CONFIG_CPC45 */
 199
 200static void i365_bset (socket_info_t * s, u_short reg, u_char mask)
 201{
 202        i365_set (s, reg, i365_get (s, reg) | mask);
 203}
 204
 205static void i365_bclr (socket_info_t * s, u_short reg, u_char mask)
 206{
 207        i365_set (s, reg, i365_get (s, reg) & ~mask);
 208}
 209
 210#if 0   /* not used */
 211static void i365_bflip (socket_info_t * s, u_short reg, u_char mask, int b)
 212{
 213        u_char d = i365_get (s, reg);
 214
 215        i365_set (s, reg, (b) ? (d | mask) : (d & ~mask));
 216}
 217
 218static u_short i365_get_pair (socket_info_t * s, u_short reg)
 219{
 220        return (i365_get (s, reg) + (i365_get (s, reg + 1) << 8));
 221}
 222#endif  /* not used */
 223
 224static void i365_set_pair (socket_info_t * s, u_short reg, u_short data)
 225{
 226        i365_set (s, reg, data & 0xff);
 227        i365_set (s, reg + 1, data >> 8);
 228}
 229
 230#ifdef CONFIG_CPC45
 231/*======================================================================
 232
 233    Code to save and restore global state information for Cirrus
 234    PD67xx controllers, and to set and report global configuration
 235    options.
 236
 237======================================================================*/
 238
 239#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
 240
 241static void cirrus_get_state (socket_info_t * s)
 242{
 243        int i;
 244        cirrus_state_t *p = &s->c_state;
 245
 246        p->misc1 = i365_get (s, PD67_MISC_CTL_1);
 247        p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 248        p->misc2 = i365_get (s, PD67_MISC_CTL_2);
 249        for (i = 0; i < 6; i++)
 250                p->timer[i] = i365_get (s, PD67_TIME_SETUP (0) + i);
 251
 252}
 253
 254static void cirrus_set_state (socket_info_t * s)
 255{
 256        int i;
 257        u_char misc;
 258        cirrus_state_t *p = &s->c_state;
 259
 260        misc = i365_get (s, PD67_MISC_CTL_2);
 261        i365_set (s, PD67_MISC_CTL_2, p->misc2);
 262        if (misc & PD67_MC2_SUSPEND)
 263                udelay (50000);
 264        misc = i365_get (s, PD67_MISC_CTL_1);
 265        misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 266        i365_set (s, PD67_MISC_CTL_1, misc | p->misc1);
 267        for (i = 0; i < 6; i++)
 268                i365_set (s, PD67_TIME_SETUP (0) + i, p->timer[i]);
 269}
 270
 271static u_int cirrus_set_opts (socket_info_t * s)
 272{
 273        cirrus_state_t *p = &s->c_state;
 274        u_int mask = 0xffff;
 275#if DEBUG
 276        char buf[200];
 277
 278        memset (buf, 0, 200);
 279#endif
 280
 281        if (has_ring == -1)
 282                has_ring = 1;
 283        flip (p->misc2, PD67_MC2_IRQ15_RI, has_ring);
 284        flip (p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
 285#if DEBUG
 286        if (p->misc2 & PD67_MC2_IRQ15_RI)
 287                strcat (buf, " [ring]");
 288        if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
 289                strcat (buf, " [dyn mode]");
 290        if (p->misc1 & PD67_MC1_INPACK_ENA)
 291                strcat (buf, " [inpack]");
 292#endif
 293
 294        if (p->misc2 & PD67_MC2_IRQ15_RI)
 295                mask &= ~0x8000;
 296        if (has_led > 0) {
 297#if DEBUG
 298                strcat (buf, " [led]");
 299#endif
 300                mask &= ~0x1000;
 301        }
 302        if (has_dma > 0) {
 303#if DEBUG
 304                strcat (buf, " [dma]");
 305#endif
 306                mask &= ~0x0600;
 307                flip (p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
 308#if DEBUG
 309                if (p->misc2 & PD67_MC2_FREQ_BYPASS)
 310                        strcat (buf, " [freq bypass]");
 311#endif
 312        }
 313
 314        if (setup_time >= 0)
 315                p->timer[0] = p->timer[3] = setup_time;
 316        if (cmd_time > 0) {
 317                p->timer[1] = cmd_time;
 318                p->timer[4] = cmd_time * 2 + 4;
 319        }
 320        if (p->timer[1] == 0) {
 321                p->timer[1] = 6;
 322                p->timer[4] = 16;
 323                if (p->timer[0] == 0)
 324                        p->timer[0] = p->timer[3] = 1;
 325        }
 326        if (recov_time >= 0)
 327                p->timer[2] = p->timer[5] = recov_time;
 328
 329        debug ("i82365 Opt: %s [%d/%d/%d] [%d/%d/%d]\n",
 330                buf,
 331                p->timer[0], p->timer[1], p->timer[2],
 332                p->timer[3], p->timer[4], p->timer[5]);
 333
 334        return mask;
 335}
 336
 337#else   /* !CONFIG_CPC45 */
 338
 339/*======================================================================
 340
 341    Code to save and restore global state information for TI 1130 and
 342    TI 1131 controllers, and to set and report global configuration
 343    options.
 344
 345======================================================================*/
 346
 347static void ti113x_get_state (socket_info_t * s)
 348{
 349        ti113x_state_t *p = &s->state;
 350
 351        pci_readl (s, TI113X_SYSTEM_CONTROL, &p->sysctl);
 352        pci_readb (s, TI113X_CARD_CONTROL, &p->cardctl);
 353        pci_readb (s, TI113X_DEVICE_CONTROL, &p->devctl);
 354        pci_readb (s, TI1250_DIAGNOSTIC, &p->diag);
 355        pci_readl (s, TI12XX_IRQMUX, &p->irqmux);
 356}
 357
 358static void ti113x_set_state (socket_info_t * s)
 359{
 360        ti113x_state_t *p = &s->state;
 361
 362        pci_writel (s, TI113X_SYSTEM_CONTROL, p->sysctl);
 363        pci_writeb (s, TI113X_CARD_CONTROL, p->cardctl);
 364        pci_writeb (s, TI113X_DEVICE_CONTROL, p->devctl);
 365        pci_writeb (s, TI1250_MULTIMEDIA_CTL, 0);
 366        pci_writeb (s, TI1250_DIAGNOSTIC, p->diag);
 367        pci_writel (s, TI12XX_IRQMUX, p->irqmux);
 368        i365_set_pair (s, TI113X_IO_OFFSET (0), 0);
 369        i365_set_pair (s, TI113X_IO_OFFSET (1), 0);
 370}
 371
 372static u_int ti113x_set_opts (socket_info_t * s)
 373{
 374        ti113x_state_t *p = &s->state;
 375        u_int mask = 0xffff;
 376
 377        p->cardctl &= ~TI113X_CCR_ZVENABLE;
 378        p->cardctl |= TI113X_CCR_SPKROUTEN;
 379
 380        return mask;
 381}
 382#endif  /* CONFIG_CPC45 */
 383
 384/*======================================================================
 385
 386    Routines to handle common CardBus options
 387
 388======================================================================*/
 389
 390/* Default settings for PCI command configuration register */
 391#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
 392                  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
 393
 394static void cb_get_state (socket_info_t * s)
 395{
 396        pci_readb (s, PCI_CACHE_LINE_SIZE, &s->cache);
 397        pci_readb (s, PCI_LATENCY_TIMER, &s->pci_lat);
 398        pci_readb (s, CB_LATENCY_TIMER, &s->cb_lat);
 399        pci_readb (s, CB_CARDBUS_BUS, &s->cap.cardbus);
 400        pci_readb (s, CB_SUBORD_BUS, &s->sub_bus);
 401        pci_readw (s, CB_BRIDGE_CONTROL, &s->bcr);
 402}
 403
 404static void cb_set_state (socket_info_t * s)
 405{
 406#ifndef CONFIG_CPC45
 407        pci_writel (s, CB_LEGACY_MODE_BASE, 0);
 408        pci_writel (s, PCI_BASE_ADDRESS_0, s->cb_phys);
 409#endif
 410        pci_writew (s, PCI_COMMAND, CMD_DFLT);
 411        pci_writeb (s, PCI_CACHE_LINE_SIZE, s->cache);
 412        pci_writeb (s, PCI_LATENCY_TIMER, s->pci_lat);
 413        pci_writeb (s, CB_LATENCY_TIMER, s->cb_lat);
 414        pci_writeb (s, CB_CARDBUS_BUS, s->cap.cardbus);
 415        pci_writeb (s, CB_SUBORD_BUS, s->sub_bus);
 416        pci_writew (s, CB_BRIDGE_CONTROL, s->bcr);
 417}
 418
 419static void cb_set_opts (socket_info_t * s)
 420{
 421#ifndef CONFIG_CPC45
 422        if (s->cache == 0)
 423                s->cache = 8;
 424        if (s->pci_lat == 0)
 425                s->pci_lat = 0xa8;
 426        if (s->cb_lat == 0)
 427                s->cb_lat = 0xb0;
 428#endif
 429}
 430
 431/*======================================================================
 432
 433    Power control for Cardbus controllers: used both for 16-bit and
 434    Cardbus cards.
 435
 436======================================================================*/
 437
 438static int cb_set_power (socket_info_t * s, socket_state_t * state)
 439{
 440        u_int reg = 0;
 441
 442#ifdef CONFIG_CPC45
 443
 444        reg = I365_PWR_NORESET;
 445        if (state->flags & SS_PWR_AUTO)
 446                reg |= I365_PWR_AUTO;
 447        if (state->flags & SS_OUTPUT_ENA)
 448                reg |= I365_PWR_OUT;
 449        if (state->Vpp != 0) {
 450                if (state->Vpp == 120) {
 451                        reg |= I365_VPP1_12V;
 452                        puts (" 12V card found: ");
 453                } else if (state->Vpp == state->Vcc) {
 454                        reg |= I365_VPP1_5V;
 455                } else {
 456                        puts (" power not found: ");
 457                        return -1;
 458                }
 459        }
 460        if (state->Vcc != 0) {
 461                reg |= I365_VCC_5V;
 462                if (state->Vcc == 33) {
 463                        puts (" 3.3V card found: ");
 464                        i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 465                } else if (state->Vcc == 50) {
 466                        puts (" 5V card found: ");
 467                        i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 468                } else {
 469                        puts (" power not found: ");
 470                        return -1;
 471                }
 472        }
 473
 474        if (reg != i365_get (s, I365_POWER)) {
 475                reg = (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V);
 476                i365_set (s, I365_POWER, reg);
 477        }
 478
 479#else   /* ! CONFIG_CPC45 */
 480
 481        /* restart card voltage detection if it seems appropriate */
 482        if ((state->Vcc == 0) && (state->Vpp == 0) &&
 483           !(cb_readl (s, CB_SOCKET_STATE) & CB_SS_VSENSE))
 484                cb_writel (s, CB_SOCKET_FORCE, CB_SF_CVSTEST);
 485        switch (state->Vcc) {
 486        case 0:
 487                reg = 0;
 488                break;
 489        case 33:
 490                reg = CB_SC_VCC_3V;
 491                break;
 492        case 50:
 493                reg = CB_SC_VCC_5V;
 494                break;
 495        default:
 496                return -1;
 497        }
 498        switch (state->Vpp) {
 499        case 0:
 500                break;
 501        case 33:
 502                reg |= CB_SC_VPP_3V;
 503                break;
 504        case 50:
 505                reg |= CB_SC_VPP_5V;
 506                break;
 507        case 120:
 508                reg |= CB_SC_VPP_12V;
 509                break;
 510        default:
 511                return -1;
 512        }
 513        if (reg != cb_readl (s, CB_SOCKET_CONTROL))
 514                cb_writel (s, CB_SOCKET_CONTROL, reg);
 515#endif  /* CONFIG_CPC45 */
 516        return 0;
 517}
 518
 519/*======================================================================
 520
 521    Generic routines to get and set controller options
 522
 523======================================================================*/
 524
 525static void get_bridge_state (socket_info_t * s)
 526{
 527#ifdef CONFIG_CPC45
 528        cirrus_get_state (s);
 529#else
 530        ti113x_get_state (s);
 531#endif
 532        cb_get_state (s);
 533}
 534
 535static void set_bridge_state (socket_info_t * s)
 536{
 537        cb_set_state (s);
 538        i365_set (s, I365_GBLCTL, 0x00);
 539        i365_set (s, I365_GENCTL, 0x00);
 540#ifdef CONFIG_CPC45
 541        cirrus_set_state (s);
 542#else
 543        ti113x_set_state (s);
 544#endif
 545}
 546
 547static void set_bridge_opts (socket_info_t * s)
 548{
 549#ifdef CONFIG_CPC45
 550        cirrus_set_opts (s);
 551#else
 552        ti113x_set_opts (s);
 553#endif
 554        cb_set_opts (s);
 555}
 556
 557/*====================================================================*/
 558#define PD67_EXT_INDEX          0x2e    /* Extension index */
 559#define PD67_EXT_DATA           0x2f    /* Extension data */
 560#define PD67_EXD_VS1(s)         (0x01 << ((s)<<1))
 561
 562#define pd67_ext_get(s, r) \
 563    (i365_set(s, PD67_EXT_INDEX, r), i365_get(s, PD67_EXT_DATA))
 564
 565static int i365_get_status (socket_info_t * s, u_int * value)
 566{
 567        u_int status;
 568#ifdef CONFIG_CPC45
 569        u_char val;
 570        u_char power, vcc, vpp;
 571        u_int powerstate;
 572#endif
 573
 574        status = i365_get (s, I365_IDENT);
 575        status = i365_get (s, I365_STATUS);
 576        *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
 577        if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {
 578                *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
 579        } else {
 580                *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
 581                *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
 582        }
 583        *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
 584        *value |= (status & I365_CS_READY) ? SS_READY : 0;
 585        *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
 586
 587#ifdef CONFIG_CPC45
 588        /* Check for Cirrus CL-PD67xx chips */
 589        i365_set (s, PD67_CHIP_INFO, 0);
 590        val = i365_get (s, PD67_CHIP_INFO);
 591        s->type = -1;
 592        if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
 593                val = i365_get (s, PD67_CHIP_INFO);
 594                if ((val & PD67_INFO_CHIP_ID) == 0) {
 595                        s->type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
 596                        i365_set (s, PD67_EXT_INDEX, 0xe5);
 597                        if (i365_get (s, PD67_EXT_INDEX) != 0xe5)
 598                                s->type = IS_VT83C469;
 599                }
 600        } else {
 601                printf ("no Cirrus Chip found\n");
 602                *value = 0;
 603                return -1;
 604        }
 605
 606        power = i365_get (s, I365_POWER);
 607        state.flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
 608        state.flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
 609        vcc = power & I365_VCC_MASK;
 610        vpp = power & I365_VPP1_MASK;
 611        state.Vcc = state.Vpp = 0;
 612        if((vcc== 0) || (vpp == 0)) {
 613                /*
 614                 * On the Cirrus we get the info which card voltage
 615                 * we have in EXTERN DATA and write it to MISC_CTL1
 616                 */
 617                powerstate = pd67_ext_get(s, PD67_EXTERN_DATA);
 618                if (powerstate & PD67_EXD_VS1(0)) {
 619                        /* 5V Card */
 620                        i365_bclr (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 621                } else {
 622                        /* 3.3V Card */
 623                        i365_bset (s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 624                }
 625                i365_set (s, I365_POWER, (I365_PWR_OUT | I365_PWR_NORESET | I365_VCC_5V | I365_VPP1_5V));
 626                power = i365_get (s, I365_POWER);
 627        }
 628        if (power & I365_VCC_5V) {
 629                state.Vcc = (i365_get(s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) ? 33 : 50;
 630        }
 631
 632        if (power == I365_VPP1_12V)
 633                state.Vpp = 120;
 634
 635        /* IO card, RESET flags, IO interrupt */
 636        power = i365_get (s, I365_INTCTL);
 637        state.flags |= (power & I365_PC_RESET) ? 0 : SS_RESET;
 638        if (power & I365_PC_IOCARD)
 639                state.flags |= SS_IOCARD;
 640        state.io_irq = power & I365_IRQ_MASK;
 641
 642        /* Card status change mask */
 643        power = i365_get (s, I365_CSCINT);
 644        state.csc_mask = (power & I365_CSC_DETECT) ? SS_DETECT : 0;
 645        if (state.flags & SS_IOCARD)
 646                state.csc_mask |= (power & I365_CSC_STSCHG) ? SS_STSCHG : 0;
 647        else {
 648                state.csc_mask |= (power & I365_CSC_BVD1) ? SS_BATDEAD : 0;
 649                state.csc_mask |= (power & I365_CSC_BVD2) ? SS_BATWARN : 0;
 650                state.csc_mask |= (power & I365_CSC_READY) ? SS_READY : 0;
 651        }
 652        debug ("i82365: GetStatus(0) = flags %#3.3x, Vcc %d, Vpp %d, "
 653                "io_irq %d, csc_mask %#2.2x\n", state.flags,
 654                state.Vcc, state.Vpp, state.io_irq, state.csc_mask);
 655
 656#else   /* !CONFIG_CPC45 */
 657
 658        status = cb_readl (s, CB_SOCKET_STATE);
 659        *value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;
 660        *value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;
 661        *value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;
 662        *value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;
 663        /* For now, ignore cards with unsupported voltage keys */
 664        if (*value & SS_XVCARD)
 665                *value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);
 666#endif  /* CONFIG_CPC45 */
 667        return 0;
 668}       /* i365_get_status */
 669
 670static int i365_set_socket (socket_info_t * s, socket_state_t * state)
 671{
 672        u_char reg;
 673
 674        set_bridge_state (s);
 675
 676        /* IO card, RESET flag */
 677        reg = 0;
 678        reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
 679        reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
 680        i365_set (s, I365_INTCTL, reg);
 681
 682#ifdef CONFIG_CPC45
 683        cb_set_power (s, state);
 684
 685#if 0
 686        /* Card status change interrupt mask */
 687        reg = s->cs_irq << 4;
 688        if (state->csc_mask & SS_DETECT)
 689                reg |= I365_CSC_DETECT;
 690        if (state->flags & SS_IOCARD) {
 691                if (state->csc_mask & SS_STSCHG)
 692                        reg |= I365_CSC_STSCHG;
 693        } else {
 694                if (state->csc_mask & SS_BATDEAD)
 695                        reg |= I365_CSC_BVD1;
 696                if (state->csc_mask & SS_BATWARN)
 697                        reg |= I365_CSC_BVD2;
 698                if (state->csc_mask & SS_READY)
 699                        reg |= I365_CSC_READY;
 700        }
 701        i365_set (s, I365_CSCINT, reg);
 702        i365_get (s, I365_CSC);
 703#endif  /* 0 */
 704
 705#else   /* !CONFIG_CPC45 */
 706
 707        reg = I365_PWR_NORESET;
 708        if (state->flags & SS_PWR_AUTO)
 709                reg |= I365_PWR_AUTO;
 710        if (state->flags & SS_OUTPUT_ENA)
 711                reg |= I365_PWR_OUT;
 712
 713        cb_set_power (s, state);
 714        reg |= i365_get (s, I365_POWER) & (I365_VCC_MASK | I365_VPP1_MASK);
 715
 716        if (reg != i365_get (s, I365_POWER))
 717                i365_set (s, I365_POWER, reg);
 718#endif  /* CONFIG_CPC45 */
 719
 720        return 0;
 721}       /* i365_set_socket */
 722
 723/*====================================================================*/
 724
 725static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem)
 726{
 727        u_short base, i;
 728        u_char map;
 729
 730        debug ("i82365: SetMemMap(%d, %#2.2x, %d ns, %#5.5lx-%#5.5lx, %#5.5x)\n",
 731                mem->map, mem->flags, mem->speed,
 732                mem->sys_start, mem->sys_stop, mem->card_start);
 733
 734        map = mem->map;
 735        if ((map > 4) ||
 736            (mem->card_start > 0x3ffffff) ||
 737            (mem->sys_start > mem->sys_stop) ||
 738            (mem->speed > 1000)) {
 739                return -1;
 740        }
 741
 742        /* Turn off the window before changing anything */
 743        if (i365_get (s, I365_ADDRWIN) & I365_ENA_MEM (map))
 744                i365_bclr (s, I365_ADDRWIN, I365_ENA_MEM (map));
 745
 746        /* Take care of high byte, for PCI controllers */
 747        i365_set (s, CB_MEM_PAGE (map), mem->sys_start >> 24);
 748
 749        base = I365_MEM (map);
 750        i = (mem->sys_start >> 12) & 0x0fff;
 751        if (mem->flags & MAP_16BIT)
 752                i |= I365_MEM_16BIT;
 753        if (mem->flags & MAP_0WS)
 754                i |= I365_MEM_0WS;
 755        i365_set_pair (s, base + I365_W_START, i);
 756
 757        i = (mem->sys_stop >> 12) & 0x0fff;
 758        switch (mem->speed / CYCLE_TIME) {
 759        case 0:
 760                break;
 761        case 1:
 762                i |= I365_MEM_WS0;
 763                break;
 764        case 2:
 765                i |= I365_MEM_WS1;
 766                break;
 767        default:
 768                i |= I365_MEM_WS1 | I365_MEM_WS0;
 769                break;
 770        }
 771        i365_set_pair (s, base + I365_W_STOP, i);
 772
 773#ifdef CONFIG_CPC45
 774        i = 0;
 775#else
 776        i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
 777#endif
 778        if (mem->flags & MAP_WRPROT)
 779                i |= I365_MEM_WRPROT;
 780        if (mem->flags & MAP_ATTRIB)
 781                i |= I365_MEM_REG;
 782        i365_set_pair (s, base + I365_W_OFF, i);
 783
 784#ifdef CONFIG_CPC45
 785        /* set System Memory map Upper Adress */
 786        i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
 787        i365_set(s, PD67_EXT_DATA, ((mem->sys_start >> 24) & 0xff));
 788#endif
 789
 790        /* Turn on the window if necessary */
 791        if (mem->flags & MAP_ACTIVE)
 792                i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));
 793        return 0;
 794}       /* i365_set_mem_map */
 795
 796static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io)
 797{
 798        u_char map, ioctl;
 799
 800        map = io->map;
 801        /* comment out: comparison is always false due to limited range of data type */
 802        if ((map > 1) || /* (io->start > 0xffff) || (io->stop > 0xffff) || */
 803            (io->stop < io->start))
 804                return -1;
 805        /* Turn off the window before changing anything */
 806        if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))
 807                i365_bclr (s, I365_ADDRWIN, I365_ENA_IO (map));
 808        i365_set_pair (s, I365_IO (map) + I365_W_START, io->start);
 809        i365_set_pair (s, I365_IO (map) + I365_W_STOP, io->stop);
 810        ioctl = i365_get (s, I365_IOCTL) & ~I365_IOCTL_MASK (map);
 811        if (io->speed)
 812                ioctl |= I365_IOCTL_WAIT (map);
 813        if (io->flags & MAP_0WS)
 814                ioctl |= I365_IOCTL_0WS (map);
 815        if (io->flags & MAP_16BIT)
 816                ioctl |= I365_IOCTL_16BIT (map);
 817        if (io->flags & MAP_AUTOSZ)
 818                ioctl |= I365_IOCTL_IOCS16 (map);
 819        i365_set (s, I365_IOCTL, ioctl);
 820        /* Turn on the window if necessary */
 821        if (io->flags & MAP_ACTIVE)
 822                i365_bset (s, I365_ADDRWIN, I365_ENA_IO (map));
 823        return 0;
 824}       /* i365_set_io_map */
 825
 826/*====================================================================*/
 827
 828int i82365_init (void)
 829{
 830        u_int val;
 831        int i;
 832
 833#ifdef CONFIG_CPC45
 834        if (SPD67290Init () != 0)
 835                return 1;
 836#endif
 837        if ((socket.dev = pci_find_devices (supported, 0)) < 0) {
 838                /* Controller not found */
 839                return 1;
 840        }
 841        debug ("i82365 Device Found!\n");
 842
 843        pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);
 844        socket.cb_phys &= ~0xf;
 845
 846#ifdef CONFIG_CPC45
 847        /* + 0xfe000000 see MPC 8245 Users Manual Adress Map B */
 848        socket.cb_phys += 0xfe000000;
 849#endif
 850
 851        get_bridge_state (&socket);
 852        set_bridge_opts (&socket);
 853
 854        i = i365_get_status (&socket, &val);
 855
 856#ifdef CONFIG_CPC45
 857        if (i > -1) {
 858                puts (pcic[socket.type].name);
 859        } else {
 860                printf ("i82365: Controller not found.\n");
 861                return 1;
 862        }
 863        if((val & SS_DETECT) != SS_DETECT){
 864                puts ("No card\n");
 865                return 1;
 866        }
 867#else   /* !CONFIG_CPC45 */
 868        if (val & SS_DETECT) {
 869                if (val & SS_3VCARD) {
 870                        state.Vcc = state.Vpp = 33;
 871                        puts (" 3.3V card found: ");
 872                } else if (!(val & SS_XVCARD)) {
 873                        state.Vcc = state.Vpp = 50;
 874                        puts (" 5.0V card found: ");
 875                } else {
 876                        puts ("i82365: unsupported voltage key\n");
 877                        state.Vcc = state.Vpp = 0;
 878                }
 879        } else {
 880                /* No card inserted */
 881                puts ("No card\n");
 882                return 1;
 883        }
 884#endif  /* CONFIG_CPC45 */
 885
 886#ifdef CONFIG_CPC45
 887        state.flags |= SS_OUTPUT_ENA;
 888#else
 889        state.flags = SS_IOCARD | SS_OUTPUT_ENA;
 890        state.csc_mask = 0;
 891        state.io_irq = 0;
 892#endif
 893
 894        i365_set_socket (&socket, &state);
 895
 896        for (i = 500; i; i--) {
 897                if ((i365_get (&socket, I365_STATUS) & I365_CS_READY))
 898                        break;
 899                udelay (1000);
 900        }
 901
 902        if (i == 0) {
 903                /* PC Card not ready for data transfer */
 904                puts ("i82365 PC Card not ready for data transfer\n");
 905                return 1;
 906        }
 907        debug (" PC Card ready for data transfer: ");
 908
 909        mem.map = 0;
 910        mem.flags = MAP_ATTRIB | MAP_ACTIVE;
 911        mem.speed = 300;
 912        mem.sys_start = CONFIG_SYS_PCMCIA_MEM_ADDR;
 913        mem.sys_stop = CONFIG_SYS_PCMCIA_MEM_ADDR + CONFIG_SYS_PCMCIA_MEM_SIZE - 1;
 914        mem.card_start = 0;
 915        i365_set_mem_map (&socket, &mem);
 916
 917#ifdef CONFIG_CPC45
 918        mem.map = 1;
 919        mem.flags = MAP_ACTIVE;
 920        mem.speed = 300;
 921        mem.sys_start = CONFIG_SYS_PCMCIA_MEM_ADDR + CONFIG_SYS_PCMCIA_MEM_SIZE;
 922        mem.sys_stop = CONFIG_SYS_PCMCIA_MEM_ADDR + (2 * CONFIG_SYS_PCMCIA_MEM_SIZE) - 1;
 923        mem.card_start = 0;
 924        i365_set_mem_map (&socket, &mem);
 925
 926#else   /* !CONFIG_CPC45 */
 927
 928        io.map = 0;
 929        io.flags = MAP_AUTOSZ | MAP_ACTIVE;
 930        io.speed = 0;
 931        io.start = 0x0100;
 932        io.stop = 0x010F;
 933        i365_set_io_map (&socket, &io);
 934
 935#endif  /* CONFIG_CPC45 */
 936
 937#ifdef DEBUG
 938        i82365_dump_regions (socket.dev);
 939#endif
 940
 941        return 0;
 942}
 943
 944void i82365_exit (void)
 945{
 946        io.map = 0;
 947        io.flags = 0;
 948        io.speed = 0;
 949        io.start = 0;
 950        io.stop = 0x1;
 951
 952        i365_set_io_map (&socket, &io);
 953
 954        mem.map = 0;
 955        mem.flags = 0;
 956        mem.speed = 0;
 957        mem.sys_start = 0;
 958        mem.sys_stop = 0x1000;
 959        mem.card_start = 0;
 960
 961        i365_set_mem_map (&socket, &mem);
 962
 963#ifdef CONFIG_CPC45
 964        mem.map = 1;
 965        mem.flags = 0;
 966        mem.speed = 0;
 967        mem.sys_start = 0;
 968        mem.sys_stop = 0x1000;
 969        mem.card_start = 0;
 970
 971        i365_set_mem_map (&socket, &mem);
 972#else   /* !CONFIG_CPC45 */
 973        socket.state.sysctl &= 0xFFFF00FF;
 974#endif
 975        state.Vcc = state.Vpp = 0;
 976
 977        i365_set_socket (&socket, &state);
 978}
 979
 980/*======================================================================
 981
 982    Debug stuff
 983
 984======================================================================*/
 985
 986#ifdef DEBUG
 987static void i82365_dump_regions (pci_dev_t dev)
 988{
 989        u_int tmp[2];
 990        u_int *mem = (void *) socket.cb_phys;
 991        u_char *cis = (void *) CONFIG_SYS_PCMCIA_MEM_ADDR;
 992        u_char *ide = (void *) (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_REG_OFFSET);
 993
 994        pci_read_config_dword (dev, 0x00, tmp + 0);
 995        pci_read_config_dword (dev, 0x80, tmp + 1);
 996
 997        printf ("PCI CONF: %08X ... %08X\n",
 998                tmp[0], tmp[1]);
 999        printf ("PCI MEM:  ... %08X ... %08X\n",
1000                mem[0x8 / 4], mem[0x800 / 4]);
1001        printf ("CIS:      ...%c%c%c%c%c%c%c%c...\n",
1002                cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],
1003                cis[0x40], cis[0x42], cis[0x44], cis[0x48]);
1004        printf ("CIS CONF: %02X %02X %02X ...\n",
1005                cis[0x200], cis[0x202], cis[0x204]);
1006        printf ("IDE:      %02X %02X %02X %02X %02X %02X %02X %02X\n",
1007                ide[0], ide[1], ide[2], ide[3],
1008                ide[4], ide[5], ide[6], ide[7]);
1009}
1010#endif  /* DEBUG */
1011