BestComm Task enable

From: Pedro Luis D. L. <hidden>
Date: 2007-08-16 15:38:47

Hello,

I=B4m trying to develop an SPI audio driver for a Phytec 5200b tiny platfor=
m. For this purpose, I=B4m reusing a working I2S driver that was working in=
 a Lite5200b platform. This I2S driver was developed for 2.6.16 kernel, usi=
ng the PPC arch. The kernel used by the new platform is a 2.6.20 version, u=
sing the powerpc arch.
This kernel does not include the gen_bd files for the BestComm to set up a =
generic task for the DMA, so I had to patch this kernel with the files from=
 Sylvain 2.6.20 tree (gen_bd.h, gen_bd.c, sdma_gen_bd_rx_task.c and sdma_ge=
n_bd_tx_task.c) and compile them so now, the functions are available. As it=
 was working with the old platform, my main goal is to stablish two interru=
pt routines for the dma to read and copy data from the PSC1 configured as a=
n SPI master device..
The question is: when I enable the sdma task (with sdma_enable() function),=
 the system seems to halt for a while and then continue (so I guess it is d=
oing something...) and I have also noticed that the interrupt routines that=
 I requested for transmission and reception are not called (a simple printk=
 with a character is not printed). May be a problem of setting up the inter=
rupts? I have no clue, but the irq allocation seems to be a success
Any hint will be appreciated.

Here is the Setup function that configures the PSC and the DMA tasks:

static int SPI_setup(void) {

	int i;
	// CDM
	struct mpc52xx_cdm __iomem *cdm;
//=20
// 	/* GPIO Modification */
	struct mpc52xx_gpio __iomem *gpio;

// 	/* END GPIO Modification */
//=20
	cdm =3D ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
	gpio =3D ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
//=20
	printk("psc_num %d\n", psc_num);

	/* Phytec, PSC1*/
	switch(psc_num) {
		case 1:
			initiator_tx =3D SDMA_INITIATOR_PSC1_TX;
			initiator_rx =3D SDMA_INITIATOR_PSC1_RX;
			break;
		case 2:
			initiator_tx =3D SDMA_INITIATOR_PSC2_TX;
			initiator_rx =3D SDMA_INITIATOR_PSC2_RX;
			break;
		default:
			panic("snd-SPImgt.o: invalid value for psc_num (%i)\n",psc_num);
			break;
	};

	/* 528MHz/(0x1f+1)=3D16.5 MHz */
	cdm->mclken_div_psc1 =3D 0x8001; // Mhz MCLK ( Khz * )
	psc->command =3D (MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
	/* PSC1 CODEC with Master Clock */
	printk("GPIO->port_config 0x%08x\n", gpio->port_config);
	gpio->port_config |=3D 0x00000007;
	printk("GPIO->port_config 0x%08x\n", gpio->port_config);
	/* PSC1 clock enable */
	cdm->clk_enables |=3D 0x20;

	// PSC reset
	psc->command =3D MPC52xx_PSC_RST_RX;
	psc->command =3D MPC52xx_PSC_RST_TX;
 	psc->command =3D MPC52xx_PSC_SEL_MODE_REG_1;
 	psc->command =3D MPC52xx_PSC_RST_ERR_STAT;


	// PSC setup SPI
	psc->mode =3D 0;
	psc->rfalarm =3D RX_ALARM;
 	psc->tfalarm =3D TX_ALARM;
	psc->rfcntl =3D RX_GRAN;
 	psc->tfcntl =3D TX_GRAN;
	psc->mpc52xx_psc_imr =3D 0x0000;
=09
	psc->sicr =3D 0x0290E000;
=09

	psc->ccr =3D 0x3f00; //LRCK  KHz, BitCLK  MHz  0x3f05!

	psc->command =3D MPC52xx_PSC_RST_RX;
	psc->command =3D MPC52xx_PSC_RST_TX;
	psc->command =3D MPC52xx_PSC_SEL_MODE_REG_1;
	psc->command =3D MPC52xx_PSC_RST_ERR_STAT;
//=20
// 	// setup the sdma tasks
	tx_sdma =3D sdma_alloc(PERIODS_HW+1);
	rx_sdma =3D sdma_alloc(PERIODS_HW+1);

	if (!tx_sdma || !rx_sdma) {
		printk("sdma_alloc failed\n");
		return -ENOMEM;
	}
//=20
	sdma_gen_bd_rx_init(0, rx_sdma, (phys_addr_t)&(psc->rfdata), initiator_rx,=
 6, PERIODSIZE_HW);
	sdma_gen_bd_tx_init(1, tx_sdma, (phys_addr_t)&(psc->tfdata), initiator_tx,=
 6);

	printk("txtask is %d rxtask is %d\n", tx_sdma->tasknum, rx_sdma->tasknum);
//=20
	// prepare the ring buffers
	for(i=3D0;itasknum %d\n", sdma_irq(rx_sdma), MPC52xx_SDMA_IRQ_BASE + rx_sd=
ma->tasknum);
	if (request_irq(sdma_irq(rx_sdma), SPI_rx_irq, IRQF_DISABLED, "SPI rx dma"=
, NULL)) {
		printk(KERN_ERR "SPI: SDMA rx irq allocation failed\n");
		return -EINVAL;
	} else printk("SPI: SDA rx irq allocation was a success\n");
	if (request_irq(sdma_irq(tx_sdma), SPI_tx_irq, IRQF_DISABLED, "SPI tx dma"=
, NULL)) {
		printk(KERN_ERR "SPI: SDMA tx irq allocation failed\n");
		return -EINVAL;
	} else printk("SPI: SDA tx irq allocation was a success\n");
=09
//=20
// 	// clear any pending interrupts
	sdma_clear_irq(tx_sdma);
	sdma_clear_irq(rx_sdma);
//=20
	printk("Before activating the tasks\n");
// 	// activate the tasks
	sdma_enable(tx_sdma);  /*Halts or gets stucked here for a while */
	sdma_enable(rx_sdma);  /*Halts or gets stucked here for a while */
//=20
// 	printk("about to enable SPI psc\n");
	udelay(100);
//=20
// 	// enable transmitter and receiver
	psc->command =3D MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE;

	return 0;
};

And here the interrupt routines:

static irqreturn_t SPI_tx_irq(int irq, void *dev_id) {

	if(psc->mpc52xx_psc_status&0x1800) {
		SPI_panic(__FUNCTION__);
		return 0;
	};
	printk("I");
	for (;;) {
		if (!sdma_buffer_done(tx_sdma)) {
			break;
		}
		sdma_retrieve_buffer(tx_sdma, NULL);
		if(snd_SPImgt_running) {
			sdma_submit_buffer(tx_sdma, NULL, (void *)(((u32)SPI_tx_bufs.pa) + (SPI_=
play*SAMPLESIZE)), PERIODSIZE_HW);
// 			printk("Ti %d ",SPI_play);
			SPI_play +=3D FPP_HW;
			if(SPI_play =3D=3D FPP*PERIODS) SPI_play=3D0;
			if(snd_SPImgt_started) {
				snd_SPImgt_started--;
			}
			else {
				SPI_pos +=3D FPP_HW;
				if(SPI_pos =3D=3D FPP*PERIODS) SPI_pos=3D0;
// 				snd_pcm_period_elapsed(snd_SPImgt_substream);
			};
		}
		else {
			sdma_submit_buffer(tx_sdma, NULL, (void *)SPI_tx_silence.pa, PERIODSIZE_=
HW);
		};
	};
=09
	if(snd_SPImgt_running &&(!snd_SPImgt_started)){
		snd_pcm_period_elapsed(snd_SPImgt_substream);
	}
	return IRQ_HANDLED;
};


static irqreturn_t SPI_rx_irq(int irq, void *dev_id) {

	//SPI_print(__FUNCTION__);
	if(psc->mpc52xx_psc_status&0x1800) {
		SPI_panic(__FUNCTION__);
		return 0;
	};
 	printk("R");	=09
	for (;;) {
		if (!sdma_buffer_done(rx_sdma)) {
			break;
		}
		sdma_retrieve_buffer(rx_sdma, NULL);
		sdma_submit_buffer(rx_sdma, NULL, (void *)SPI_rx_bufs.pa, PERIODSIZE_HW);
	};
	return IRQ_HANDLED;
};

Regards,
Pedro.

_________________________________________________________________
Llama a tus amigos de PC a PC: =A1Es GRATIS!
http://get.live.com/messenger/overview=
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help