Beispiel #1
0
static void hisnfc100_select_chip(struct mtd_info *mtd, int chipselect)
{
	struct nand_chip *chip = mtd->priv;
	struct hisnfc_host *host = chip->priv;

	if (chipselect < 0)
		return;

	if (chipselect > CONFIG_HISNFC100_MAX_CHIP)
		DBG_BUG("invalid chipselect: %d\n", chipselect);

	host->cmd_option.chipselect = chipselect + 1;

	switch (chip->state) {
	case FL_ERASING:
		host->cmd_option.last_cmd = NAND_CMD_ERASE1;
		break;

	case FL_WRITING:
		host->cmd_option.last_cmd = NAND_CMD_PAGEPROG;
		break;

	default:
		break;
	}
}
Beispiel #2
0
/*
 * the parameter 'ddrsize' don't care, it is only used for compatibility the
 * old source.
 */
void dcache_enable(uint32_t unused)
{
	if (transform_table_base == 1) {
		DBG_BUG(("mmu has not be initialized.\n"));
		return;
	}
	/* enable mmu */
	mmu_startup(transform_table_base);
	dcache_start();
}
Beispiel #3
0
/* used the best correct arithmetic. */
struct nand_config_info *hisnfc100_get_best_ecc(struct mtd_info *mtd)
{
	struct nand_config_info *best = NULL;
	struct nand_config_info *info = hisnfc_spi_nand_config_table;

	for (; info->layout; info++) {
		if (nandpage_type2size(info->pagetype) != mtd->writesize)
			continue;

		if (mtd->oobsize < info->oobsize)
			continue;

		if (!best || (best->ecctype < info->ecctype))
			best = info;
	}

	if (!best)
		DBG_BUG(ERSTR_DRIVER "Driver does not support the pagesize");
		DBG_BUG("(%d) and oobsize(%d).\n",
				mtd->writesize, mtd->oobsize);

	return best;
}
Beispiel #4
0
/* force the pagesize and ecctype */
struct nand_config_info *hisnfc100_force_ecc(struct mtd_info *mtd, int pagetype,
		int ecctype, char *cfgmsg, int allow_pagediv)
{
	int pagesize;
	struct nand_config_info *fit = NULL;
	struct nand_config_info *info = hisnfc_spi_nand_config_table;

	for (; info->layout; info++) {
		if (info->pagetype == pagetype && info->ecctype == ecctype) {
			fit = info;
			break;
		}
	}

	if (!fit) {
		DBG_BUG(ERSTR_DRIVER "Driver(%s mode) does not support this",
				cfgmsg);
		DBG_BUG(" Nand Flash pagesize:%s, ecctype:%s\n",
				nand_page_name(pagetype),
				nand_ecc_name(ecctype));
		return NULL;
	}

	pagesize = nandpage_type2size(pagetype);
	if ((pagesize != mtd->writesize)
		&& (pagesize > mtd->writesize || !allow_pagediv)) {
		DBG_BUG(ERSTR_HARDWARE "Hardware (%s mode) configure pagesize",
				cfgmsg);
		DBG_BUG(" %d, but the Nand Flash pageszie is %d\n",
				pagesize, mtd->writesize);
		return NULL;
	}

	if (fit->oobsize > mtd->oobsize) {
		DBG_BUG(ERSTR_HARDWARE "(%s mode) The Nand Flash offer space",
				cfgmsg);
		DBG_BUG(" area is %d bytes, but the controller request %d",
				mtd->oobsize, fit->oobsize);
		DBG_BUG("bytes in ecc %s. Please make sure the hardware ECC ",
				nand_ecc_name(ecctype));
		DBG_BUG("configuration is correct.");
		return NULL;
	}

	return fit;
}
Beispiel #5
0
void spi_get_erase(struct spi_info *spiinfo, struct spi_operation *spiop_erase)
{
	int ix;

	spiop_erase->size = 0;
	for (ix = 0; ix < MAX_SPI_OP; ix++) {
		if (spiinfo->erase[ix] == NULL)
			break;
		if (spiinfo->erasesize == spiinfo->erase[ix]->size) {
			memcpy(spiop_erase, spiinfo->erase[ix],
				sizeof(struct spi_operation));
			break;
		}
	}
	if (!spiop_erase->size)
		DBG_BUG(("Spi erasesize error!"));
}
Beispiel #6
0
int mmu_init(unsigned int ttb, unsigned int ddr_start, unsigned int ddr_size)
{
	if (ttb < ddr_start || ttb > (ddr_start + ddr_size)) {
		DBG_BUG(("transform table base address(0x%08X)"
		         " out of ddr range[0x%08X, 0x%08X].\n",
		         ttb, ddr_start, (ddr_start + ddr_size)));
		return 0;
	}
	transform_table_base = ttb;

	/* init page dir table in main mem 0- 16k */
	mmu_pagedir_init(transform_table_base);

	/* init cache page flag */
	mmu_pagedir_cached_range(transform_table_base, ddr_start, ddr_size);

	/* page table is 16K */
	return (0x4000);
}
Beispiel #7
0
void spi_get_erase_sfcv300(struct spi_info *spiinfo,
			   struct spi_operation *spiop_erase,
			   unsigned int *erasesize)
{
	int ix;

	(*erasesize) = spiinfo->erasesize;
	for (ix = 0; ix < MAX_SPI_OP; ix++) {
		if (spiinfo->erase[ix] == NULL)
			break;

		memcpy(&spiop_erase[ix], spiinfo->erase[ix],
			sizeof(struct spi_operation));

		switch (spiop_erase[ix].size) {
		case SPI_IF_ERASE_SECTOR:
			spiop_erase[ix].size = spiinfo->erasesize;
			break;
		case SPI_IF_ERASE_CHIP:
			spiop_erase[ix].size = spiinfo->chipsize;
			break;
		}


		if ((int)(spiop_erase[ix].size) < _2K) {
			char buf[20];
			DBG_BUG("erase block size mistaken: "
				"spi->erase[%d].size:%s\n",
				ix, ultohstr(spiop_erase[ix].size,
				buf, sizeof(buf)));
		}

		if (spiop_erase[ix].size < (*erasesize)) {
			(*erasesize) = spiop_erase[ix].size;
		}
	}
}
Beispiel #8
0
int hisnfc100_ecc_probe(struct mtd_info *mtd, struct nand_chip *chip,
	struct nand_dev_t *flash_dev_ex)
{
	char *start_type = "unknown";
	struct nand_config_info *best = NULL;
	struct hisnfc_host *host = chip->priv;
	unsigned reg_pagetype, reg_ecctype, pagetype, ecctype;

#ifdef CONFIG_HISNFC100_AUTO_PAGESIZE_ECC
	best = hisnfc100_get_best_ecc(mtd);
	start_type = "Auto";
#endif /* CONFIG_HISNFC100_AUTO_PAGESIZE_ECC */

#ifdef CONFIG_HISNFC100_HARDWARE_PAGESIZE_ECC
#  ifdef CONFIG_HISNFC100_AUTO_PAGESIZE_ECC
#  error you SHOULD NOT define CONFIG_HISNFC100_AUTO_PAGESIZE_ECC \
	and CONFIG_HISNFC100_HARDWARE_PAGESIZE_ECC at the same time
#  endif

	reg_pagetype = (host->NFC_CFG & PAGE_SIZE_MASK) >> PAGE_SIZE_SHIFT;
	switch (reg_pagetype) {
	case 0:
		pagetype = NAND_PAGE_2K;
		break;
	case 1:
		pagetype = NAND_PAGE_4K;
		break;
	default:
		pagetype = NAND_PAGE_2K;
	}

	reg_ecctype = (host->NFC_CFG & ECC_TYPE_MASK) >> ECC_TYPE_SHIFT;
	switch (reg_ecctype) {
	case 0x01:
		ecctype = NAND_ECC_8BIT;
		break;
	case 0x02:
		ecctype = NAND_ECC_16BIT;
		break;
	case 0x03:
		ecctype = NAND_ECC_24BIT;
		break;
	case 0:
	default:
		ecctype = NAND_ECC_8BIT;
	}
	best = hisnfc100_force_ecc(mtd, pagetype, ecctype,
			"hardware config", 0);
	start_type = "Hardware";

#endif /* CONFIG_HISNFC100_HARDWARE_PAGESIZE_ECC */

#ifdef CONFIG_HISNFC100_PAGESIZE_AUTO_ECC_NONE
#  ifdef CONFIG_HISNFC100_AUTO_PAGESIZE_ECC
#  error you SHOULD NOT define CONFIG_HISNFC100_PAGESIZE_AUTO_ECC_NONE \
	and CONFIG_HISNFC100_AUTO_PAGESIZE_ECC at the same time
#  endif
#  ifdef CONFIG_HISNFC100_HARDWARE_PAGESIZE_ECC
#  error you SHOULD NOT define CONFIG_HISNFC100_PAGESIZE_AUTO_ECC_NONE \
	and CONFIG_HISNFC100_HARDWARE_PAGESIZE_ECC at the same time
#  endif

	{
		int pagetype;

		switch (mtd->writesize) {
		case _2K:
			pagetype = NAND_PAGE_2K;
			break;
		case _4K:
			pagetype = NAND_PAGE_4K;
			break;
		default:
			pagetype = NAND_PAGE_2K;
			break;
		}
		best = hisnfc100_force_ecc(mtd, pagetype, NAND_ECC_0BIT,
					  "force config", 0);
		start_type = "AutoForce";
	}
#endif /* CONFIG_HISNFC100_PAGESIZE_AUTO_ECC_NONE */

	if (!best)
		DBG_BUG(ERSTR_HARDWARE
			"Please configure SPI Nand Flash pagesize and ecctype!\n");

	if (best->ecctype != NAND_ECC_0BIT)
		mtd->oobsize = best->oobsize;

	chip->ecc.layout = best->layout;

	host->ecctype  = best->ecctype;
	host->pagesize = nandpage_type2size(best->pagetype);
	host->oobsize  = mtd->oobsize;
	host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1);

	host->dma_oob = host->dma_buffer + host->pagesize;

	host->bbm = (unsigned char *)(host->buffer + host->pagesize
			+ HINFC_BAD_BLOCK_POS);

	host->epm = (unsigned short *)(host->buffer + host->pagesize
			+ chip->ecc.layout->oobfree[0].offset + 28);

	host->NFC_CFG |= (HISNFC100_CFG_ECC_TYPE(best->ecctype)
		| HISNFC100_CFG_PAGE_SIZE(best->pagetype)
		| HISNFC100_CFG_OP_MODE(OP_MODE_NORMAL));

	if (mtd->writesize > SPI_NAND_MAX_PAGESIZE
		|| mtd->oobsize > SPI_NAND_MAX_OOBSIZE) {
		DBG_BUG(ERSTR_DRIVER "Driver does not support this Nand ");
		DBG_BUG("Flash. Please increase SPI_NAND_MAX_PAGESIZE and ");
		DBG_BUG("SPI_NAND_MAX_OOBSIZE.\n");
	}

	if (mtd->writesize != host->pagesize) {
		unsigned int shift = 0;
		unsigned int writesize = mtd->writesize;
		while (writesize > host->pagesize) {
			writesize >>= 1;
			shift++;
		}
		chip->chipsize = chip->chipsize >> shift;
		mtd->erasesize = mtd->erasesize >> shift;
		mtd->writesize = host->pagesize;
		pr_info("Nand divide into 1/%u\n", (1 << shift));
	}
Beispiel #9
0
int arch_usb_init(void)
{
	unsigned int reg;

	if (_HI3712_V100 == get_chipid()) {
		int timeout;

		reg = readl(HI3712_USB_PERI_USB0);
		reg |= HI3712_USB_ULPI_BYPASS_EN;

		reg |= HI3712_USB_WORDINTERFACE;
		reg &= ~(HI3712_USB_SS_BURST16_EN);
		reg &= ~(HI3712_USB_ATERESET1);
		reg &= ~(HI3712_USB_ATERESETX);
		writel(reg, HI3712_USB_PERI_USB0);
		udelay(100);

		reg = readl(HI3712_USB_PREI_USB1);
		reg |= HI3712_USB_FREECLK0_INV_EN;
		writel(reg, HI3712_USB_PREI_USB1);
		udelay(100);

		reg = readl(HI3712_PERI_CRG36);
		reg |= HI3712_USB_BRG_CKEN;
		reg |= HI3712_USB_OTG_CKEN;
		reg |= HI3712_USB_HOST_CKEN;
		reg |= HI3712_USB1_CKEN;
		reg |= HI3712_USB0_CKEN;
		writel(reg, HI3712_PERI_CRG36);
		udelay(100);

		timeout = 0x10;
		do {
			reg = readl(HI3712_PERI_CRG36);
			reg |= HI3712_USBPHY0_REQ;
			reg |= HI3712_USBPHY1_REQ;
			writel(reg, HI3712_PERI_CRG36);
			udelay(100);
			reg &= ~(HI3712_USBPHY0_REQ);
			reg &= ~(HI3712_USBPHY1_REQ);
			writel(reg, HI3712_PERI_CRG36);
			udelay(100);

			reg = readl(HI3712_PERI_USB3);

			switch (get_cpu_version(NULL)) {
			case _HI3712_V100A:
				if (reg & HI3712_USBPHY0_CLK_TEST)
					timeout = -1;
				break;
			default:
			case _HI3712_V100I:
				if ((reg & HI3712_USBPHY0_CLK_TEST)
				    && (reg & HI3712_USBPHY1_CLK_TEST))
					timeout = -1;
				break;
			}

		} while (timeout-- > 0);

		if (!timeout) {
			DBG_BUG(("Usb phy initialize timeout.\n"));
		}

		udelay(100);
		reg = readl(HI3712_USB_PERI_USB0);
		reg |= HI3712_USB_ATERESETX;
		udelay(100);
		reg &= ~(HI3712_USB_ATERESETX);
		writel(reg, HI3712_USB_PERI_USB0);
		udelay(100);

		reg = readl(HI3712_PERI_CRG36);
		reg &= ~(HI3712_USB_BRG_SRST_REQ);
		reg &= ~(HI3712_UTMI1_HOST_REQ);
		reg &= ~(HI3712_UTMI0_HOST_REQ);
		reg &= ~(HI3712_USBPHY1_TREQ);
		reg &= ~(HI3712_USBPHY0_TREQ);
		reg &= ~(HI3712_USB_OTG_REQ);
		reg &= ~(HI3712_USB_HOST_REQ);
		reg &= ~(HI3712_USB_OTG_SRST_REQ);
		reg &= ~(HI3712_USB_HOST_SRST_REQ);
		writel(reg, HI3712_PERI_CRG36);
		udelay(100);

	} else {

		reg = readl(HI3716X_PERI_CRG36);
		reg |= HI3716X_USB_CKEN;
		reg |= HI3716X_USBPHY_REQ;
		reg &= ~(HI3716X_USBPHY_PORT1_TREQ);
		reg &= ~(HI3716X_USBPHY_PORT0_TREQ);
		reg |= HI3716X_USB_CTRL_UTMI1_REG;
		reg |= HI3716X_USB_CTRL_UTMI0_REG;
		reg |= HI3716X_USB_AHB_SRST_REQ;
		writel(reg, HI3716X_PERI_CRG36);
		udelay(20);

		reg = readl(HI3716X_USB_PERI_USB0);
		reg |= HI3716X_USB_ULPI_BYPASS_EN;
		reg &= ~(HI3716X_USB_WORDINTERFACE);
		reg &= ~(HI3716X_USB_SS_BURST16_EN);
		writel(reg, HI3716X_USB_PERI_USB0);
		udelay(100);

		reg = readl(HI3716X_PERI_CRG36);
		reg &= ~(HI3716X_USBPHY_REQ);
		writel(reg, HI3716X_PERI_CRG36);
		udelay(100);

		reg = readl(HI3716X_PERI_CRG36);
		reg &= ~(HI3716X_USB_CTRL_UTMI1_REG);
		reg &= ~(HI3716X_USB_CTRL_UTMI0_REG);
		reg &= ~(HI3716X_USB_CTRL_HUB_REG);
		reg &= ~(HI3716X_USB_AHB_SRST_REQ);
		writel(reg, HI3716X_PERI_CRG36);
		udelay(10);
		WDG_ENABLE(0x5DC0);
		readl(0x60070000);
		WDG_DISABLE();
	}

	return 0;
}
Beispiel #10
0
static void cfg_chk_area(struct config* cfg, signed char a)
{
	struct config_area* ar = &cfg->area[a];
	char const *ptr, *ptr_, *end;
	ar->crc = CRC16_INIT;
	ar->status = area_empty;
	for (ptr = ar->storage, end = ptr + CFG_BUFF_SIZE; ptr < end; ptr = ptr_)
	{
		unsigned sz;
		struct cfg_obj_footer const* f;
		struct cfg_obj_header const* h = (struct cfg_obj_header const*)ptr;
		struct cfg_type const* t = cfg_get_obj_type(h);
		if (!t) {
			if ((unsigned char)~h->type_tag)
				goto invalid;
			if (!(unsigned char)~h->ij) // header is all ones
				break;
		}
		sz = cfg_obj_size_(t, h);
		ptr_ = ptr + sz;
		if (ptr_ > end)
			goto invalid;
		f = (struct cfg_obj_footer const*)ptr_ - 1;
		ar->crc = crc16_up_buff(ar->crc, ptr, sz - sizeof(*f));
		if (f->crc != ar->crc)
			goto invalid;
		if (!t) {
			switch (h->ij) {
			case area_open:
				if (ar->status != area_empty && ar->status != area_dirty)
					goto invalid_status;
				ar->status = area_open;
				break;
			case area_closed:
				if (ar->status != area_open && ar->status != area_modified)
					goto invalid_status;
				ar->status = area_closed;
				break;
			case area_completed:
				if (ar->status != area_closed && ar->status != area_empty)
					goto invalid_status;
				ar->status = area_completed;
				break;
			default:
				goto invalid_status;
			}
		} else {
			if (ar->status > area_modified)
				goto invalid_status;
			switch (ar->status) {
			case area_empty:
				ar->status = area_dirty;
				break;
			case area_open:
				ar->status = area_modified;
				break;
			}
		}
		continue;
invalid_status:
		DBG_BUG();
invalid:
		ar->invalid = 1;
		break;
	}
	ar->used_bytes = ptr - ar->storage;
	BUG_ON(ar->used_bytes > CFG_BUFF_SIZE);
	if (!ar->invalid && !cfg_is_area_clean(cfg, a))
		ar->invalid = 1;
}