コード例 #1
0
ファイル: mvDramIf.c プロジェクト: juergh/dns323-fw
/*******************************************************************************
* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
*
* DESCRIPTION: 
*       This function calculates sdram timing control low register 
*       optimized value based on the bank info parameters and the minCas.
*
* INPUT:
*	    pBankInfo - sdram bank parameters
*       busClk    - Bus clock
*
* OUTPUT:
*       None
*
* RETURN:
*       sdram timinf control low reg value.
*
*******************************************************************************/
static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, 
                                                MV_U32 minCas, MV_U32 busClk)
{
	MV_U32 tRp  = 0;
	MV_U32 tRrd = 0;
	MV_U32 tRcd = 0;
	MV_U32 tRas = 0;
	MV_U32 tWr  = 0;
	MV_U32 tWtr = 0;
	MV_U32 tRtp = 0;
	
	MV_U32 bankNum;
	
	busClk = busClk / 1000000;    /* In MHz */
	
	/* Scan all DRAM banks to find maximum timing values */
	for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
	{
		tRp  = MV_MAX(tRp,  pBankInfo[bankNum].minRowPrechargeTime);
		tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
		tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
		tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
	}
	
	/* Extract timing (in ns) from SPD value. We ignore the tenth ns part.  */
	/* by shifting the data two bits right.                                 */
	tRp  = tRp  >> 2;    /* For example 0x50 -> 20ns                        */
	tRrd = tRrd >> 2;
	tRcd = tRcd >> 2;
	
	/* Extract clock cycles from time parameter. We need to round up        */
	tRp  = ((busClk * tRp)  / 1000) + (((busClk * tRp)  % 1000) ? 1 : 0);
	DB(mvOsPrintf("Dram  Timing Low: tRp = %d ", tRp));
	tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
	DB(mvOsPrintf("tRrd = %d ", tRrd));
	tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
	DB(mvOsPrintf("tRcd = %d ", tRcd));
	tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
	DB(mvOsPrintf("tRas = %d ", tRas));
	
	/* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2   */
	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
	{
		/* Scan all DRAM banks to find maximum timing values */
		for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
		{
			tWr  = MV_MAX(tWr,  pBankInfo[bankNum].minWriteRecoveryTime);
			tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
			tRtp = MV_MAX(tWtr, pBankInfo[bankNum].minReadToPrechCmdDelay);
		}
		
		/* Extract timing (in ns) from SPD value. We ignore the tenth ns    */
		/* part by shifting the data two bits right.                        */
		tWr  = tWr  >> 2;    /* For example 0x50 -> 20ns                    */
		tWtr = tWtr >> 2;
		tRtp = tRtp >> 2;
	
		/* Extract clock cycles from time parameter. We need to round up    */
		tWr  = ((busClk * tWr)  / 1000) + (((busClk * tWr)  % 1000) ? 1 : 0);
		DB(mvOsPrintf("tWr = %d ", tWr));
		tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
		DB(mvOsPrintf("tWtr = %d ", tWtr));
		tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
		DB(mvOsPrintf("tRtp = %d ", tRtp));
	}
	else
	{    
コード例 #2
0
ファイル: mv_tsu.c プロジェクト: HuxyUK/xpenology-3.x
int mvtsu_open (struct inode *inode, struct file *filp)
{
	struct mvtsu_dev *dev;
	MV_TSU_PORT_CONFIG port_cfg;
	MV_TSU_BUFF_INFO *binfo = NULL;
	MV_STATUS status;
	int result = 0;
	int stat_size = 0;
	int data_size = 0;
	int data_buff_offs;

	TSU_ENTER(TSU_DBG_OPEN, "mvtsu_open");

	if(MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0)) {
		printk("Transport Stream interface is powered off.\n");
		return 0;
	}

	/*  Find the device structure.	*/
	dev = container_of(inode->i_cdev, struct mvtsu_dev, cdev);

    	/* Determine the port direction according to the read / write flag.*/
	if ((filp->f_mode & (FMODE_WRITE | FMODE_READ)) == FMODE_WRITE) {
		port_cfg.portDir = TSU_PORT_OUTPUT;
	} else if ((filp->f_mode & (FMODE_WRITE | FMODE_READ)) == FMODE_READ) {
		port_cfg.portDir = TSU_PORT_INPUT;
	} else {
		result = -EINVAL;
		goto fail_init;
	}

	/* Reset the port.		*/
	mvTsuPortReset(dev->port);

	/* Initialize the port.		*/
	port_cfg.pktSize = cfg_pkt_size;
       	status = mvTsuPortInit(dev->port,&port_cfg);
	if(status != MV_OK) {
		result = -EINVAL;
		goto fail_init;
	}

	TSU_DPRINT(TSU_DBG_OPEN, ("\tTSU unit initialized successfully.\n"));

	/* Initialize the port buffers.	*/
	binfo = &dev->buff_info;
	switch(binfo->aggrMode)
	{
	case (MV_TSU_AGGR_MODE_DISABLED):
		binfo->dataBlockSize = port_cfg.pktSize;
		dev->valid_data_size = port_cfg.pktSize;
		dev->rd_rw_data_size = binfo->dataBlockSize + TSU_DONE_STATUS_ENTRY_SIZE;
		binfo->aggrNumPackets = 1;
		break;
	case (MV_TSU_AGGR_MODE_1):
		binfo->dataBlockSize = port_cfg.pktSize * binfo->aggrNumPackets;
		if(port_cfg.portDir == TSU_PORT_OUTPUT) {
			binfo->dataBlockSize += MV_MAX(TSU_DMA_ALIGN,TSU_MODE1_OUT_TMS_SIZE);
			dev->rd_rw_data_size = binfo->dataBlockSize;
		}
		else {
			dev->rd_rw_data_size = binfo->dataBlockSize +
				(binfo->aggrNumPackets * TSU_DONE_STATUS_ENTRY_SIZE);
		}
		dev->valid_data_size = port_cfg.pktSize * binfo->aggrNumPackets;
		break;
	case (MV_TSU_AGGR_MODE_2):
		binfo->aggrMode2TmstmpOff = TSU_DMA_ALIGN -
			(port_cfg.pktSize & (TSU_DMA_ALIGN - 1));
		binfo->dataBlockSize =
			(binfo->aggrNumPackets *
			 (port_cfg.pktSize + binfo->aggrMode2TmstmpOff) +
			 TSU_DMA_ALIGN);
		dev->valid_data_size = (binfo->aggrNumPackets *
					(port_cfg.pktSize + binfo->aggrMode2TmstmpOff));
		dev->rd_rw_data_size = dev->valid_data_size;
	default:
		break;
	}

	dev->port_dir = port_cfg.portDir;

	/* Align the data block size to a cache line.	*/
	binfo->dataBlockSize = MV_ALIGN_UP(binfo->dataBlockSize,32);
	data_size = binfo->dataBlockSize * binfo->numTsDesc;
#ifdef TSU_UNCACHED_DATA_BUFFERS
	binfo->tsDataBuff =
		mvOsIoUncachedMalloc(NULL,data_size,(MV_ULONG*)(&binfo->tsDataBuffPhys),
				     NULL);
#else
	binfo->tsDataBuff =
		mvOsIoCachedMalloc(NULL,data_size,(MV_ULONG*)(&binfo->tsDataBuffPhys),
				   NULL);
#endif /* TSU_UNCACHED_DATA_BUFFERS */
	if(binfo->tsDataBuff == NULL) {
		result = -ENOMEM;
		goto fail_init;
	}
//	memset(binfo->tsDataBuff,0x88,data_size);
#ifndef TSU_UNCACHED_DATA_BUFFERS
	mvOsCacheClear(NULL,(MV_U32*)TSU_DATA_BUFF_HW_2_SW(binfo->tsDataBuff),
		       data_size);
#endif /* TSU_UNCACHED_DATA_BUFFERS */

	/* Align tsDataBuff according to the HW limitation.	*/
	if(binfo->aggrMode == MV_TSU_AGGR_MODE_2) {
		data_buff_offs = port_cfg.pktSize & (TSU_DMA_ALIGN - 1);
	}
	else if((binfo->aggrMode == MV_TSU_AGGR_MODE_1) &&
		(port_cfg.portDir == TSU_PORT_OUTPUT)) {
        	data_buff_offs = TSU_DMA_ALIGN - TSU_MODE1_OUT_TMS_SIZE;
	}
	else {
		data_buff_offs = 0;
	}

	binfo->tsDataBuff = (MV_U32*)((MV_U32)binfo->tsDataBuff + data_buff_offs);
	binfo->tsDataBuffPhys += data_buff_offs;

	TSU_DPRINT(TSU_DBG_OPEN, ("\tTSU Data buffer allocated successfully "
				  "(%p, %d).\n",binfo->tsDataBuff, data_size));
	/* Allocate memory for done queue.	*/
	stat_size = TSU_DONE_STATUS_ENTRY_SIZE * binfo->numDoneQEntry;
	dev->stat_buff_size = stat_size;
	binfo->tsDoneBuff =
		mvOsIoUncachedMalloc(NULL,stat_size,
				     (MV_ULONG*)(&binfo->tsDoneBuffPhys),NULL);
	if(binfo->tsDoneBuff == NULL) {
		result = -ENOMEM;
		goto fail_init;
	}

	TSU_DPRINT(TSU_DBG_OPEN, ("\tTSU Done buffer allocated successfully"
				  "(%p, %d).\n",binfo->tsDoneBuff, stat_size));

	status = mvTsuBuffersInit(dev->port,&dev->buff_info);
	if(status != MV_OK) {
		TSU_DPRINT(TSU_DBG_OPEN, ("\tmvTsuBuffersInit() Failed (%d).",
					  status));
		result = -EINVAL;
		goto fail_init;
	}
	TSU_DPRINT(TSU_DBG_OPEN, ("\tHAL Buffers initialized successfully.\n"));

	status = mvTsuPortSignalCfgSet(dev->port,&(dev->signal_cfg),dev->serial_sig_flags);
	if(status != MV_OK) {
		TSU_DPRINT(TSU_DBG_OPEN, ("\tmvTsuPortSignalCfgSet() Failed (%d).",
					status));
		result = -EINVAL;
		goto fail_init;
	}
	TSU_DPRINT(TSU_DBG_OPEN, ("\tPort signal parameters set successfully.\n"));

	status = mvTsuRxSyncDetectionSet(dev->port,dev->sync_detect,dev->sync_loss);
	if(status != MV_OK) {
		TSU_DPRINT(TSU_DBG_OPEN, ("\tmvTsuRxSyncDetectionSet() Failed (%d).",
					status));
		result = -EINVAL;
		goto fail_init;
	}
	TSU_DPRINT(TSU_DBG_OPEN, ("\tRx sync parameters set successfully.\n"));

	mvtsu_rd_wr_timeout_calc(dev);

	if(dev->port_dir == TSU_PORT_OUTPUT) {
		mvtsu_tx_timestamp_calc(dev);
	}

	/* Register IRQ.	*/
	MV_REG_WRITE(MV_TSU_INTERRUPT_MASK_REG(dev->port),TSU_DFLT_INT_MASK);
	if(request_irq(IRQ_TS_INT(dev->port),mvtsu_interrupt_handler,
		       IRQF_DISABLED | IRQF_SAMPLE_RANDOM,"tsu",dev)) {
		printk(KERN_ERR "Cannot assign irq%d to TSU port%d\n",
		       IRQ_TS_INT(dev->port), dev->port);
		goto fail_init;
	}
	TSU_DPRINT(TSU_DBG_OPEN, ("\tTSU interrupt registered at IRQ %d.\n",
				  IRQ_TS_INT(dev->port)));

	if(port_cfg.portDir == TSU_PORT_INPUT) {
		/* Enable Rx timestamp.	*/
		mvTsuRxTimestampCntEn(dev->port,MV_TRUE);
		mvTsuDmaWatermarkSet(dev->port,0x8);
	}

	/* Make the private_data hold the pointer to the device data.	*/
	filp->private_data = dev;

	TSU_LEAVE(TSU_DBG_OPEN, "mvtsu_open");
	return 0;

fail_init:
	if(binfo != NULL) {
		if(binfo->tsDataBuff != NULL)
#ifdef TSU_UNCACHED_DATA_BUFFERS
			mvOsIoUncachedFree(
				NULL,data_size,
				TSU_DATA_BUFF_HW_2_SW(binfo->tsDataBuffPhys),
				(MV_U32*)TSU_DATA_BUFF_HW_2_SW(binfo->tsDataBuff),0);
#else
		mvOsIoCachedFree(
			NULL,data_size,
			TSU_DATA_BUFF_HW_2_SW(binfo->tsDataBuffPhys),
			(MV_U32*)TSU_DATA_BUFF_HW_2_SW(binfo->tsDataBuff),0);
#endif /* TSU_UNCACHED_DATA_BUFFERS */
		if(binfo->tsDoneBuff != NULL)
			mvOsIoUncachedFree(NULL,stat_size,binfo->tsDoneBuffPhys,
					   binfo->tsDoneBuff,0);
		binfo->tsDataBuff = NULL;
		binfo->tsDoneBuff = NULL;
	}
	TSU_LEAVE(TSU_DBG_OPEN, "mvtsu_open");
	return result;
}