⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 powerpc82xx mcc driver
💻 C
📖 第 1 页 / 共 2 页
字号:
    MCCglobal->rinttmp0 = ALL_ZEROS;    /* must be cleared by user */    MCCglobal->rinttmp1 = ALL_ZEROS;    /* must be cleared by user */    MCCglobal->rinttmp2 = ALL_ZEROS;    /* must be cleared by user */    MCCglobal->rinttmp3 = ALL_ZEROS;    /* must be cleared by user */        addr = (unsigned int )rxIntCQ;         MCCglobal->rintbase0 = addr - PAGE_OFFSET;  /* base of Rx int. circular queue #0*/    MCCglobal->rintptr0 = MCCglobal->rintbase0;   /* current RxINTCQ0 ptr */    MCCglobal->rintbase1 = ALL_ZEROS;   /* base of Rx int. circular queue #1*/    MCCglobal->rintptr1 = MCCglobal->rintbase1;   /* current RxINTCQ1 ptr */    MCCglobal->rintbase2 = ALL_ZEROS;   /* base of Rx int. circular queue #2*/    MCCglobal->rintptr2 = MCCglobal->rintbase2;   /* current RxINTCQ2 ptr */    MCCglobal->rintbase3 = ALL_ZEROS;   /* base of Rx int. circular queue #3*/    MCCglobal->rintptr3 = MCCglobal->rintbase3;   /* current RxINTCQ3 ptr */        	IMM->si_regs[MCC].mccr = 0x1b; /* gruppo 1 a TDMA1,									  gruppo 2 a TDMB1									  gruppo 3 a TDMC1									  gruppo 4 a TDMD1	*/                /* Enable all interrupts     */    IMM->si_regs[MCC].mccm = 0xff0f ;        /* Clear MCCE Register by writing all 1's     */    IMM->si_regs[MCC].mcce = (unsigned short )ALL_ONES;} /* end MCCGlobalInit() *//* * Name: *	MCCChanSpecInit * Description: *	configure MCC channel specific parameter */void MCCChanSpecInit(unsigned short mcn, unsigned char   mode){	t_Mch_Pram* MCCmch;	MCCmch =  (t_Mch_Pram*) ((unsigned int )IMM + (64 * ((unsigned int )  mcn)));            /* Channel-Specific Parameter RAM Initialization     */	MCCmch->zistate = 0x10000207;	/* regular channel */	MCCmch->zidata0 = ALL_ONES;	MCCmch->zidata1 = ALL_ONES;    MCCmch->tbdflags = ALL_ZEROS;    MCCmch->tbdcnt  = ALL_ZEROS;    MCCmch->tbdptr = ALL_ZEROS;	if (mcn == CHNINT2 )		MCCmch->intmask = 0x0001;		/* enable interrupts for RXB */    else		MCCmch->intmask = 0x0000;		/* disable interrupts for RXB */        if ((mode==HDLC_SUPERCHAN) || (mode==HDLC_NOTSUPERCHAN)){  /* HDLC*/        MCCmch->chamr = 0xE480;     /* set MODE to HDLC, POL, CRC, Reversed bit ordering*/        MCCmch->maxrlen = MCC_MRBLR;	/* HDLC max frame receive length */        MCCmch->zdstate = 0x00FFFFE0;    } else { /* TRANSPARENT */            MCCmch->chamr = 0x7400;     /* set MODE to TRAN, POL */        MCCmch->maxrlen = BUFFER_SIZE;  /* in transparent, this should be                                           to exactly the amount of data                                           desired to fill the BD */        MCCmch->zdstate = 0x50ffffe0;	/* changed for ucode patch for non-sync tran. */    };    	MCCmch->tcrc = ALL_ZEROS;	MCCmch->zddata0 = ALL_ONES;	MCCmch->zddata1 = ALL_ONES;    MCCmch->rbdflags = ALL_ZEROS;    MCCmch->rbdcnt  = ALL_ZEROS;    MCCmch->rbdptr = ALL_ZEROS;    MCCmch->sync_maxcnt = ALL_ZEROS;    MCCmch->rcrc  = ALL_ZEROS;        if ((mode==HDLC_NOTSUPERCHAN) || (mode==TRAN_NOTSUPERCHAN)){        MCCmch->tstate = 0x38800000;	/* global, big endian*/        MCCmch->rstate = 0x38800000;	/* global, big endian*/        if (BD_BUS == LOCAL) {            MCCmch->tstate |= 0x01000000;	/* set BDB */            MCCmch->rstate |= 0x01000000;	/* set BDB */        }            if (BUFFER_BUS == LOCAL) {            MCCmch->tstate |= 0x02000000;	/* set DTB */            MCCmch->rstate |= 0x02000000;	/* set DTB */        }    } else {     /* initialize states for superchannelling (to be set in StartChannel) */            MCCmch->tstate = ALL_ZEROS;	        MCCmch->rstate = ALL_ZEROS;	    };    } /* end MCCChanSpecInit() *//* * Name: *	MCCExChanSpecInit * Description: *	configure MCC channel extra specific parameter */void MCCExChanSpecInit(unsigned int mcn, unsigned short mctbase, unsigned short mcrbase) {	t_MchXtra_Pram* MCCmchx;	MCCmchx=(t_MchXtra_Pram * ) ((unsigned int )IMM  + MCCXTRABASE + (8 * mcn));    /*-----------------------------------------------------------------*/    /* Let MCC1 know where base of TxBDs are for this logical channel. */    /* Note that tbase is an offset from MCCBASE in the global params. */    /*-----------------------------------------------------------------*/        MCCmchx->tbase = mctbase;	MCCmchx->tbptr = MCCmchx->tbase;		/* init "current TxBD ptr" */    /*-----------------------------------------------------------------*/    /* Let MCC1 know where base of RxBDs are for this logical channel  */    /* Note that rbase is an offset from MCCBASE in the global params. */    /*-----------------------------------------------------------------*/        MCCmchx->rbase = mcrbase;	MCCmchx->rbptr = MCCmchx->rbase;		/* init "current RxBD ptr" */	} /* MCCExChanSpecInit *//* * Name: *	InitTxRxParams * Description: *	Issues the INIT_TX_RX_PARAMS command to the CPCR for the given mcn * NOTE: *	issuing an init params command to an MCC channel   * 	actually initializes the 32 consecutive channels starting with   * 	channel number specified.*/void InitTxRxParams (unsigned short mcn) {    volatile unsigned int psbc;    if (MCC == MCC1)     	psbc = CPCR_MCC1_PSBC;    else    psbc = CPCR_MCC2_PSBC;    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);     IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS |                 psbc |                   (mcn<<6)|                 CPCR_FLG;              /* ISSUE COMMAND */    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD);    } /* InitTxRxParams *//* * Name: *	getFrame * Description: *	copy read data from RxBDs into the read buffer * Input parameter: *	chn:channel number,  *	offset:chn offset in BufferPool area,  *	index: BD identifier */void getFrame(unsigned int chn, unsigned short offset) {	unsigned int index=0;    unsigned char *rx;    FrameBuffer *read = (FrameBuffer *) ((unsigned int )ReadBuffer + (sizeof(FrameBuffer))*chn);    unsigned int i;	while(index<NUM_RXBDS){		if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */    		rx = BufferPool + BUFFER_SIZE*NUMBER_OF_CHANNELS*NUM_TXBDS + (offset+index)*BUFFER_SIZE;    	index++;    }	for(i = 0; i < BUFFER_SIZE; i++){	    read->data[i] = (unsigned char) *rx++;     }    readNow[chn] = 1;} /* getFrame *//* * Name: *	sendFrame * Description: *	copy from write buffer into the TxBDs  * Input parameter: *	chn:channel number,  *	offset:chn offset in BufferPool area,  *	index: BD identifier */void sendFrame(unsigned int chn,unsigned short offset) {	unsigned int index=0;    unsigned char *tx;    unsigned short i;    FrameBuffer *write = (FrameBuffer *) ( (unsigned int ) WriteBuffer + (sizeof(FrameBuffer))*chn);	while (index<NUM_TXBDS){		if( (RxTxBD->TxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD serviced */    		tx = BufferPool+((offset+index)*BUFFER_SIZE);    	index++;    }	if ( valid[chn] == 0){        for (i = 0; i < BUFFER_SIZE; i++) {            *tx++ = ((chn == 0) || (chn == 32) )? SYNC_PATTERN : SILENCE_PATTERN;        }	} else {	    for (i = 0; i < BUFFER_SIZE; i++) {    	    *tx++ = (unsigned char) write->data[i];    	}    	valid[chn] = 0;	}	writeNow[chn] = 1;} /* end of sendFrame *//* * Name: *	restoreBDs * Description: * 	reinitilize BDs	 */void restoreBDs(unsigned short offset){	unsigned int index=0;	while (index<NUM_RXBDS){		if( index != (NUM_RXBDS-1) ){/* If not the last RxBD for this channel */			if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */ 		   		RxTxBD->RxBD[index+offset].bd_cstatus = 0x9000; /* Empty, No Interrupt */ /* old 0x9000 */        		RxTxBD->TxBD[index+offset].bd_cstatus = 0x8000; /* Set Ready bit */		} else {/* if last RxBD for this channel */			if( (RxTxBD->RxBD[index+offset].bd_cstatus & 0x8000 )== 0) /* BD filled */	        	RxTxBD->RxBD[index+offset].bd_cstatus = 0xB000; /* Empty, Interrupt,Wrap */				RxTxBD->TxBD[index+offset].bd_cstatus = 0xA000;/* Set Ready, Wrap bits */    	}		index++;	}}/* * Name: *	mcc_ISR * Description: *	MCC Interrupt handler *	a new interrupt comes when 32癱hannel buffer has been recieved */void mcc_ISR(int irq, void *dev_id, struct pt_regs *regs) {	unsigned int mcce;	unsigned int chnOffset;	unsigned int chnNum;	/* lock intetruupt handler	*/	spin_lock_irq(&lock);   	/* Copy the MCC event register    	*/	mcce = IMM->si_regs[MCC].mcce; /* Save off scce */   	/* Clear MCC1 Event Register (by writing 1s)    	*/   	IMM->si_regs[MCC].mcce = (unsigned short )ALL_ONES;			if (mcce & RINT0){/* at last one new entry was added in the Rx interrupt table */			chnOffset = 0;			for(chnNum = 0; chnNum < (NUMBER_OF_CHANNELS); chnNum++){				getFrame(chnNum,chnOffset);				sendFrame(chnNum,chnOffset);				restoreBDs(chnOffset);				chnOffset+=NUM_RXBDS;				}    		memset((unsigned char  *)&rxIntCQ[0], 0,NUM_CHN_INT*NUM_RXBDS*4);    		*((unsigned int  *)&rxIntCQ[0] + NUM_CHN_INT*NUM_RXBDS - 1) = 0x40000000; /* set wrap bit at end of RX intcq */	} else {			/* may be underrun, fatal error			*/			printk("MCC:interrupt error:0x%x\n",mcce);			/* Restart the driver			RestartServiceRoutine();*/			/* asyncronous notification 			*/			mccFasync();	}	/* unlock intetruupt handler	*/	spin_unlock_irq(&lock);	/* Enable RINT0 interrupts 	*/	IMM->si_regs[MCC].mccm =0xff0f; /* all source interrupt abled, see page 27-19*/} /* end of mcc_ISR *//* * Name: *	BDsStatus * Description: *	read TxRxBDs satus  */void BDsStatus(unsigned char TxRx, unsigned char offset, unsigned short *bd_status, unsigned short *bd_length, unsigned int  *bd_addr){	unsigned char index;	if (TxRx == TX){		for (index=0;index<NUM_TXBDS;index++){        	bd_status[index]=RxTxBD->TxBD[index+offset].bd_cstatus;        	bd_length[index]=RxTxBD->TxBD[index+offset].bd_length;        	bd_addr[index]=RxTxBD->TxBD[index+offset].bd_addr;        }	} else {		for (index=0;index<NUM_RXBDS;index++){        	bd_status[index]=RxTxBD->RxBD[index+offset].bd_cstatus;        	bd_length[index]=RxTxBD->RxBD[index+offset].bd_length;        	bd_addr[index]=RxTxBD->RxBD[index+offset].bd_addr;        }	}}/* BDsStatus end *//* * Name: *	SiRamStatus * Description: *	read Si ram satus  */void SiRamStatus(unsigned char chn,unsigned char *sigmr,unsigned char *sicmdr,					unsigned char *sistr,unsigned short *sirsr,unsigned short *mcce,					unsigned short *mccm,unsigned char *mccr,unsigned short *sixmr,					unsigned short *tx_siram,unsigned short *rx_siram){	*sigmr=IMM->si_regs[SI].sigmr;	*sicmdr=IMM->si_regs[SI].sicmdr;	*sistr=IMM->si_regs[SI].sistr;	*sirsr=IMM->si_regs[SI].sirsr;	*mcce=IMM->si_regs[SI].mcce;	*mccm=IMM->si_regs[SI].mccm;	*mccr=IMM->si_regs[SI].mccr;	*sixmr=IMM->si_regs[SI].sixmr[(chn<32)?TDMC:TDMD];	*tx_siram=IMM->si_ram[SI].tx_siram[(chn<32)?chn:(chn+32)];	*rx_siram=IMM->si_ram[SI].rx_siram[(chn<32)?chn:(chn+32)];}/* SiRamStatus end*/   /* * Name: *	CpmReadRegisters * Description: *	read CPM register  */void CpmReadRegisters(CPM_STATUS_IOC *CpmStatusRegisterIOCTL){	CpmStatusRegisterIOCTL->cpm_cpcr=IMM->cpm_cpcr;	CpmStatusRegisterIOCTL->cpm_rccr=IMM->cpm_rccr;	CpmStatusRegisterIOCTL->cpm_rmdr=IMM->cpm_rmdr;	CpmStatusRegisterIOCTL->cpm_rctr1=IMM->cpm_rctr1;	CpmStatusRegisterIOCTL->cpm_rctr2=IMM->cpm_rctr2;	CpmStatusRegisterIOCTL->cpm_rctr3=IMM->cpm_rctr3;	CpmStatusRegisterIOCTL->cpm_rctr3=IMM->cpm_rctr3;	CpmStatusRegisterIOCTL->cpm_rter=IMM->cpm_rter;	CpmStatusRegisterIOCTL->cpm_rtmr=IMM->cpm_rtmr;	CpmStatusRegisterIOCTL->cpm_rtscr=IMM->cpm_rtscr;	CpmStatusRegisterIOCTL->cpm_rmds=IMM->cpm_rmds;	CpmStatusRegisterIOCTL->cpm_rtsr=IMM->cpm_rtsr;} /* CpmReadRegisters end  *//* * Name: *	RestartServiceRoutine * Description: *	restart of mcc after a fatal error */void RestartServiceRoutine(void){	unsigned char chnOffset,chnNum;	/* reinizilize the mcc.	*/	stopTxRx();	/*Reinitialize TxRxBDs	*/	chnOffset = 0;	for(chnNum = CHNSTART;chnNum < (CHNSTART+NUMBER_OF_CHANNELS);chnNum++){		InitBDs(chnOffset,TRAN_NOTSUPERCHAN);		chnOffset+=NUM_RXBDS;		}		startTxRx();			return;} /* end of RestartServiceRoutine */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -