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; } }
/* * 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(); }
/* 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; }
/* 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; }
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!")); }
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); }
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; } } }
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)); }
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; }
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; }