External Bus example on Colibri T20

Hi!

Is there any example to show how to communicate through external bus on Linux system.
I compile bitbake -k angstrom-lxde-image (LinuxImageV2.5) with no problem.
Brandon Shibley send to my mail patch with DMA support (change board-colibri_t20.c), but what about CS, bus data width, clock settings, etc? Where they need to be adjusted? Any example?
Sources of bench (External Memory Bus (Linux) | Toradex Developer Center)?
Thanks!

I apologize for not responding right away. On T20, the driver defaults to 32-bit, non-mux’d, async mode. The bus width is set to 32-bit in board-colibri_t20.h with #define GMI_32BIT. Some configurations are simply unsupported in the driver; however the driver does have some configurability via ioctl settings which you can see by inspecting the source code. This is the relevant function:

static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{

	int ret=0;

	switch(cmd) {

		case GMI_IOCTL_READ_MODE:
			if(arg == GMI_PIO_MODE || arg == GMI_DMA_MODE)
				gmi_read_mode = arg&0xFF;
			else
				ret = -18;
			break;

		case GMI_IOCTL_WRITE_MODE:
			if(arg == GMI_PIO_MODE || arg == GMI_DMA_MODE)
				gmi_write_mode = arg&0xFF;
			else
				ret = -18;
			break;

		case GMI_IOCTL_READ_MODE_PIO:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_READ_MODE_PIO\n");
			gmi_read_mode = GMI_PIO_MODE;
			break;

		case GMI_IOCTL_READ_MODE_DMA:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_READ_MODE_DMA\n");
			gmi_read_mode = GMI_DMA_MODE;
			break;

		case GMI_IOCTL_WRITE_MODE_PIO:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_WRITE_MODE_PIO\n");
			gmi_write_mode = GMI_PIO_MODE;
			break;

		case GMI_IOCTL_WRITE_MODE_DMA:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_WRITE_MODE_DMA\n");
			gmi_write_mode = GMI_DMA_MODE;
			break;

		case GMI_IOCTL_SPEED_LO:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_SPEED_LO\n");
			inst_info->timing0_default = 0xD0A073A8;
			inst_info->timing0_read = 0xD0A073A8;
			//inst_info->timing1_default = 0x00101010;
			//inst_info->timing1_read = 0x00101010;
			inst_info->timing1_default = 0x00141010;
			inst_info->timing1_read = 0x00141010;
			//snor_tegra_writel(c, c->timing0_default, TEGRA_SNOR_TIMING0_REG);
			//snor_tegra_writel(c, c->timing1_default, TEGRA_SNOR_TIMING1_REG);
			break;

		case GMI_IOCTL_SPEED_MED:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_SPEED_MED\n");
			inst_info->timing0_default = 0xA0A05585;
			inst_info->timing0_read = 0xA0A05585;
			inst_info->timing1_default = 0x00050406;
			inst_info->timing1_read = 0x00050406;
			//snor_tegra_writel(c, c->timing0_default, TEGRA_SNOR_TIMING0_REG);
			//snor_tegra_writel(c, c->timing1_default, TEGRA_SNOR_TIMING1_REG);
			break;

		case GMI_IOCTL_SPEED_HI:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_SPEED_HI\n");
			inst_info->timing0_default = 0xA0A02020;
			inst_info->timing0_read = 0xA0A02020;
			inst_info->timing1_default = 0x00040200;
			inst_info->timing1_read = 0x00040200;
			//snor_tegra_writel(c, c->timing0_default, TEGRA_SNOR_TIMING0_REG);
			//snor_tegra_writel(c, c->timing1_default, TEGRA_SNOR_TIMING1_REG);
			break;

		case GMI_IOCTL_WIDTH_16:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_WIDTH_16\n");
			inst_info->plat->flash.width = 2;
			inst_info->init_config &= ~TEGRA_SNOR_CONFIG_WORDWIDE;	// 16 bit
			break;

		case GMI_IOCTL_WIDTH_32:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_WIDTH_32\n");
			inst_info->plat->flash.width = 4;
			inst_info->init_config |= TEGRA_SNOR_CONFIG_WORDWIDE;	// 32 bit
			break;

		case GMI_IOCTL_MODE_ASYNC:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_MODE_ASYNC\n");
			inst_info->plat->chip_parms.ReadMode = NorReadMode_Async;
			break;

		case GMI_IOCTL_MODE_BURST:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_MODE_BURST\n");
			inst_info->plat->chip_parms.ReadMode = NorReadMode_Burst;
			break;

		case GMI_IOCTL_MODE_PAGE:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_MODE_PAGE\n");
			inst_info->plat->chip_parms.ReadMode = NorReadMode_Page;
			break;

		//case GMI_IOCTL_DMA_INDIRECT:
			//pr_info("gmi-chardev: ioctl(): GMI_IOCTL_DMA_INDIRECT\n");
			//dma_direct = 0;
			//break;

		//case GMI_IOCTL_DMA_DIRECT:
			//pr_info("gmi-chardev: ioctl(): GMI_IOCTL_DMA_DIRECT\n");
			//dma_direct = 1;
			//break;

		case GMI_IOCTL_DMA_BURST_1:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_DMA_BURST_1\n");
			dma_burst_size = 1;
			break;

		case GMI_IOCTL_DMA_BURST_4:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_DMA_BURST_4\n");
			dma_burst_size = 4;
			break;

		case GMI_IOCTL_DMA_BURST_8:
			pr_info("gmi-chardev: ioctl(): GMI_IOCTL_DMA_BURST_8\n");
			dma_burst_size = 8;
			break;

		default:
			pr_info("gmi-chardev: ioctl(): INVALID\n");
			ret = -25;
			break;
	}

	if(ret==0)
		pr_info("gmi ioctl: success: cmd = %08x, arg = %08x\n", cmd, arg, ret);
	else
		pr_info("gmi ioctl: error cmd/arg not valid: cmd = %08x, arg = %08x, ret = %d\n", cmd, arg, ret);

	return ret;
}

Hi!
Thanks!
Now I work on Colibri T30 module and have some question.

  1. In tegra-gmi-bus.c
    config |= TEGRA_SNOR_CONFIG_SNOR_CS(4); // chip select = 4
    In Nvidia datasheet 6:4 bit of SNOR_CONFIG_0 is CS4.
    Where is CS4 on Colibri Evaluation Board v3.2B?
    I think that actually used CS0 because on A27(X3) where are right signal.
    I try to set CS0, recompile kernel, and after that, there are nothing on A27(X3).
  2. I try to write some data in tegra-nor device in nonmux async 16bit mode, but only GMI_AD[7:0]
    is right signal. In 15:8 there are some strange signal.
    Please help.