pcmcia.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:10k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*++
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Copyright (c) 2001. Samsung Electronics, co. ltd All rights reserved.
- --*/
- #include <windows.h>
- #include <ethdbg.h>
- #include <halether.h>
- #include "....driverspcmciasockpd.h"
- #include "....driverspcmciapd6710.h"
- #include <S2440.h>
- #define PCMCIA_ATTR_READ(x) ((*(volatile unsigned char *)(x+attr_addr)))
- #define CIS_R0 0x3F8
- #define CARD_IS_UNKNOWN 0
- #define CARD_IS_MEMORY 1
- #define CARD_IS_ENET 2
- #define PD6710_MEM_BASE_ADDRESS (0xA4000000) //(0x10000000) // nGCS2 (A24 == 0)
- #define PD6710_IO_BASE_ADDRESS (0xA5000000) //(0x11000000) // (A24 == 1)
- #define rPD6710_INDEX (*(volatile unsigned char *)(PD6710_IO_BASE_ADDRESS+0x3e0))
- #define rPD6710_DATA (*(volatile unsigned char *)(PD6710_IO_BASE_ADDRESS+0x3e1))
- void PCICDataWrite_(unsigned char index, unsigned char data)
- {
- rPD6710_INDEX=index;
- rPD6710_DATA=data;
- }
- unsigned char PCICDataRead_(unsigned char index)
- {
- rPD6710_INDEX=index;
- return rPD6710_DATA;
- }
- void PCICDataModify_(unsigned char index,unsigned char mask,unsigned char data)
- {
- rPD6710_INDEX=index;
- rPD6710_DATA=(rPD6710_DATA)&~mask|data;
- }
- static void Delay(DWORD dwMSecs)
- {
- #define MSEC_DELAY_SCALER 0x200
- volatile DWORD dwScaledSecs = (dwMSecs * MSEC_DELAY_SCALER);
- while (dwScaledSecs)
- {
- dwScaledSecs--;
- }
- }
- int PrintTuples(unsigned long attr_addr)
- {
- UCHAR data, tuple_id, *pData;
- UCHAR buf[256];
- int offset;
- int size;
- int i, numBytes;
- ULONG configBase;
- EdbgOutputDebugString("n[Tuple Listing]n");
- offset = 0;
- while (1) {
- tuple_id = PCMCIA_ATTR_READ(offset);
- if (tuple_id == 0xFF) {
- break; /* End of Chain */
- }
- EdbgOutputDebugString ("[%x] ID=0x%xn", offset, tuple_id);
- offset+=2;
- size = PCMCIA_ATTR_READ(offset);
- EdbgOutputDebugString ("[%x] SIZE=0x%x", offset, size);
- offset+=2;
- pData = buf;
- for (i=0; i<size; i++, offset+=2) {
- data = PCMCIA_ATTR_READ(offset);
- if ((i%8) == 0) {
- EdbgOutputDebugString ("n[%x] DATA=", offset);
- }
- *pData ++ = data;
- EdbgOutputDebugString ("0x%x ", data);
- }
- EdbgOutputDebugString ("nn");
- pData = buf;
- switch (tuple_id) {
- case 0x15:
- EdbgOutputDebugString ("* Major version= %sn",
- (*pData==4) ? "for 2.01/2.1" : "for PCCard 95");
- pData ++;
- EdbgOutputDebugString ("* Minor version= %sn",
- (*pData==1) ? "for 2.0/2.01/2.1" : "for PCCard 95");
- pData ++;
- EdbgOutputDebugString ("* Menufacturer= %sn", pData);
- pData += (strlen (pData) + 1);
- EdbgOutputDebugString ("* Product= %sn", pData);
- pData += (strlen (pData) + 1);
- EdbgOutputDebugString ("* Product info 1= %sn", pData);
- pData += (strlen (pData) + 1);
- EdbgOutputDebugString ("* Product info 2= %sn", pData);
- EdbgOutputDebugString ("n");
- break;
- case 0x1a:
- numBytes = ((*pData) & 0x3)+1;
- pData += 2;
- configBase = 0;
- for (i=numBytes; i>0; i--) {
- configBase <<= 8;
- configBase |= *(pData + i - 1);
- }
- EdbgOutputDebugString ("* Config Base= 0x%xn", configBase);
- EdbgOutputDebugString ("n");
- break;
- default:
- break;
- } /* switch-tuple_id */
- }
- return 0;
- } /* PrintTuples */
- PVOID PCMCIA_Init(void)
- {
- unsigned char tmp, uByte;
- int Offset;
- volatile unsigned char *pAttr;
- volatile IOPreg *v_pIOPRegs = (volatile IOPreg *)IOP_BASE;
- volatile MEMreg *v_pMEMRegs = (volatile MEMreg *)MEMCTRL_BASE;
- UINT EbootDeviceAddress = 0;
- // Initialize S3C2440 for PD6710
- // EINT3(GPF3) is enabled.
- v_pIOPRegs->rGPFCON = (v_pIOPRegs->rGPFCON & ~(0x3<<6)) | (0x2<<6);
- // EINT3 is PULLUP enabled.
- v_pIOPRegs->rGPFUP = (v_pIOPRegs->rGPFUP & ~(0x1<<3));
- // EINT8(GPG0) is enabled.
- v_pIOPRegs->rGPGCON = (v_pIOPRegs->rGPGCON & ~(0x3<<0)) | (0x2<<0);
- // EINT8 is *not* PULLUP enabled.
- v_pIOPRegs->rGPGUP = (v_pIOPRegs->rGPGUP | (0x1<<0));
- // nGCS2=nUB/nLB(nSBHE),nWAIT,16-bit
- v_pMEMRegs->rBWSCON = (v_pMEMRegs->rBWSCON & ~(0xf<<8)) | (0xd<<8);
- // BANK2 access timing
- v_pMEMRegs->rBANKCON2 = ((B6710_Tacs<<13)+(B6710_Tcos<<11)+(B6710_Tacc<<8)+(B6710_Tcoh<<6)
- +(B6710_Tah<<4)+(B6710_Tacp<<2)+(B6710_PMC));
- // EINT8=Level-high triggered, IRQ3.
- // EINT3=Falling Edge triggering -> connected INTR(controller)
- v_pIOPRegs->rEXTINT1=(v_pIOPRegs->rEXTINT1 & ~(0xf<<0)) | (0x1<<0);
- v_pIOPRegs->rEXTINT0=(v_pIOPRegs->rEXTINT0 & ~(0xf<<12)) | (0x2<<12);
- //
- // 0x3E0 is the standard Intel compatible socket controller I/O port.
- //
- tmp = PCICDataRead_(REG_CHIP_REVISION);
- if ((tmp != 0x83) && (tmp != 0x82)) {
- EdbgOutputDebugString("PDCardInitServices CHIP_REVISION = 0x%x, expected = 0x83 !!!rn", tmp);
- return(NULL);
- }
- //output2card_disable,AUTO_POWER,VCC_POWER_OFF,Vpp1=0V
- PCICDataWrite_(REG_POWER_CONTROL, (0<<7)|(1<<5)|(0<<4)|(0<<0));
- // Management int -> edge triggering(PULSE), System int -> LEVEL triggering
- PCICDataWrite_(REG_GENERAL_CONTROL, (MISC1_VCC_33|MISC1_PM_IRQ|MISC1_SPK_ENABLE));
- // 25Mhz_bypass,low_power_dynamic,IRQ12=drive_LED
- // PCICDataWrite_(REG_GLOBAL_CONTROL, (MISC2_BFS|MISC2_LOW_POWER_MODE|MISC2_LED_ENABLE));
- PCICDataWrite_(REG_GLOBAL_CONTROL, (MISC2_LOW_POWER_MODE|MISC2_LED_ENABLE));
- //status_change_int_enable, card_detect_int_enable, IRQ disabled(IRQ_3)
- PCICDataWrite_(REG_STATUS_CHANGE_INT_CONFIG, (1<<0)|(1<<3)|(3<<4));
- //IO0=16bit,timing_set_0
- PCICDataWrite_(REG_IO_WINDOW_CONTROL, 1|(1<<1)|(0<<3));
- // I/O windows must never include 3e0h and 3e1h
- // IO AREA=0x300~0x340(NE2K) -> 0x300~0x340
- PCICDataWrite_(REG_IO_MAP0_START_ADDR_LO, 0x00);
- PCICDataWrite_(REG_IO_MAP0_START_ADDR_HI, 0x3);
- PCICDataWrite_(REG_IO_MAP0_END_ADDR_LO, 0x40);
- PCICDataWrite_(REG_IO_MAP0_END_ADDR_HI, 0x3);
- PCICDataWrite_(REG_CARD_IO_MAP0_OFFSET_L, 0x0);
- PCICDataWrite_(REG_CARD_IO_MAP0_OFFSET_H, 0x0);
- //If this is memory window, the lowest 64KB should be reserved.
- //MEM AREA=0x0~0xFFFF ->0x0~0xFFFFFF
- PCICDataWrite_(REG_MEM_MAP0_START_ADDR_LO, 0x00); //MEM0=8bit data width
- PCICDataWrite_(REG_MEM_MAP0_START_ADDR_HI, 0x00);
- PCICDataWrite_(REG_MEM_MAP0_END_ADDR_LO, 0x01); //0x0 ~ 0xffff
- PCICDataWrite_(REG_MEM_MAP0_END_ADDR_HI, 0x00|(0<<6)); //timing_set_0
- PCICDataWrite_(REG_MEM_MAP0_ADDR_OFFSET_LO, 0x0);
- PCICDataWrite_(REG_MEM_MAP0_ADDR_OFFSET_HI, 0x0|(1<<6)); //nREG=active
- //memory map 0 enabled, I/O map 0 enabled
- PCICDataWrite_(REG_WINDOW_ENABLE, 1|(1<<6));
- // before configuring timing register, FIFO should be cleared.
- PCICDataWrite_(REG_FIFO_CTRL, FIFO_EMPTY_WRITE); //Flush FIFO
- //default access time is 300ns
- PCICDataWrite_(REG_SETUP_TIMING0, 2); //80ns(no spec)
- PCICDataWrite_(REG_CMD_TIMING0, 8); //320ns(by spec,25Mhz clock)
- PCICDataWrite_(REG_RECOVERY_TIMING0, 2); //80ns(no spec)
- //default access time is 300ns
- PCICDataWrite_(REG_SETUP_TIMING1, 2); //80ns(no spec)
- PCICDataWrite_(REG_CMD_TIMING1, 8); //320ns(by spec,25Mhz clock)
- PCICDataWrite_(REG_RECOVERY_TIMING1, 2); //80ns(no spec)
- PCICDataWrite_(REG_CHIP_INFO,0x0);
- if((PCICDataRead_(REG_CHIP_INFO)&0xc0) != 0xc0 || (PCICDataRead_(REG_CHIP_INFO)&0xc0) != 0x00 )
- {
- EdbgOutputDebugString("PD6710 hardware identification error!!!n");
- return(NULL);
- }
- EbootDeviceAddress = PD6710_MEM_BASE_ADDRESS;
- if((PCICDataRead_(REG_INTERFACE_STATUS)&0xc)==0xc)
- {
- EdbgOutputDebugString("Card is inserted.n");
- //For card contact stablization. This delay is needed for stable operation.
- //If this delay isn't here, CF card will not be identified.
- if(PCICDataRead_(REG_GENERAL_CONTROL)&0x1) //MISC_CTRL1[0] 0=3.3V 1=5.0V
- {
- PCICDataModify_(REG_GENERAL_CONTROL,0x2,0x0); //nVCC_5_enabled
- EdbgOutputDebugString("5.0V card is detected.n");
- }
- else
- {
- PCICDataModify_(REG_GENERAL_CONTROL,0x2,0x2); //nVCC_3_enabled
- EdbgOutputDebugString("3.3V card is detected.n");
- }
- PCICDataModify_(REG_POWER_CONTROL,(1<<4)|3,(1<<4)|1);
- //VCC_POWER_on,VPP=Vcc(3.3V or 5.0V)
- Delay(20);
- //Delay 10ms should be here for power stabilization.
- //If this time is not here, the program may halt
- // in case that the pc card has been inserted before power_on
- //But, Why?
- Delay(2); //RESET should be Hi-Z for minimum 1ms
- PCICDataModify_(REG_INTERRUPT_AND_GENERAL_CONTROL,(1<<6),0); //RESET=active(H)
- PCICDataModify_(REG_POWER_CONTROL,(1<<7),(1<<7)); //output2card_enable(RESET=Hi-Z -> output)
- PCICDataModify_(REG_INTERRUPT_AND_GENERAL_CONTROL,(1<<6),0); //RESET=active(H)
- Delay(1); //wait for minimum 10us
- PCICDataModify_(REG_INTERRUPT_AND_GENERAL_CONTROL, (1<<6),(1<<6)); //RESET=inactive(L)
- Delay(40); //wait for 20ms
- // Watch for RDY signal to be asserted by the card. The NE2000 card will initially come up in memory mode so it's
- // safe to watch for RDY. Later, we put the NE2000 in IO mode.
- //
- while(!(PCICDataRead_(REG_INTERFACE_STATUS)&0x20));
- PCICDataModify_(REG_INTERRUPT_AND_GENERAL_CONTROL,(1<<5),(1<<5)); //mem_card -> mem_io_card
- PCICDataModify_(REG_INTERRUPT_AND_GENERAL_CONTROL, 0xf, 0x3); // IREQ == IRQ3.
- Delay(200);
- //If this delay isn't here, some CF card will not be identified.
- //In oder to remove this delay, I think, we have to check READY signal.
- }
- else {
- EdbgOutputDebugString("NO card is detected.n");
- return(NULL);
- }
- // Switch the NE2000 card to 16-bit IO mode.
- //
- if(PCICDataRead_(REG_GENERAL_CONTROL)&0x1)
- {
- // 5V.
- //
- uByte = 0x21;
- Offset = CIS_R0;
- pAttr = (PUCHAR) EbootDeviceAddress;
- pAttr += Offset;
- *pAttr = uByte;
- uByte = 0x1;
- Offset = CIS_R0 + 2;
- pAttr = (PUCHAR) EbootDeviceAddress;
- pAttr += Offset;
- *pAttr = uByte;
- }
- else
- {
- // 3.3V.
- //
- uByte = 0x20;
- Offset = CIS_R0;
- pAttr = (PUCHAR) EbootDeviceAddress;
- pAttr += Offset;
- *pAttr = uByte;
- }
- Delay(200);
- #if 0
- // Print tuple information from the PCMCIA/CF card.
- //
- PrintTuples(EbootDeviceAddress);
- #endif
- return ((PVOID)(PD6710_IO_BASE_ADDRESS + 0x300));
- }