diff options
author | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
---|---|---|
committer | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
commit | 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf (patch) | |
tree | cd70a267a5ef105ba32f200aa088e281fbd85747 /bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19 | |
parent | 4204309872da5cb401cbb2729d9e2d4869a87f42 (diff) |
basesystem-jjsandbox/ToshikazuOhiwa/master-jj
recipes
Diffstat (limited to 'bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19')
5 files changed, 1473 insertions, 0 deletions
diff --git a/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0001-MLK-11719-4-mtd-gpmi-change-the-BCH-layout-setting-f.patch b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0001-MLK-11719-4-mtd-gpmi-change-the-BCH-layout-setting-f.patch new file mode 100644 index 00000000..c2b81030 --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0001-MLK-11719-4-mtd-gpmi-change-the-BCH-layout-setting-f.patch @@ -0,0 +1,552 @@ +From: Alex Gonzalez <alex.gonzalez@digi.com> +Date: Fri, 24 Aug 2018 18:53:40 +0200 +Subject: [PATCH] MLK-11719-4: mtd: gpmi: change the BCH layout setting for + large oob NAND +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The cod change updated the NAND driver BCH ECC layout algorithm to +support large oob size NAND chips(oob > 1024 bytes) and proposed a new +way to set ECC layout. + +Current implementation requires each chunk size larger than oob size so +the bad block marker (BBM) can be guaranteed located in data chunk. The +ECC layout always using the unbalanced layout(Ecc for both meta and +Data0 chunk), but for the NAND chips with oob larger than 1k, the driver +cannot support because BCH doesn’t support GF 15 for 2K chunk. + +The change keeps the data chunk no larger than 1k and adjust the ECC +strength or ECC layout to locate the BBM in data chunk. General idea for +large oob NAND chips is + +1.Try all ECC strength from the minimum value required by NAND spec to +the maximum one that works, any ECC makes the BBM locate in data chunk +can be chosen. + +2.If none of them works, using separate ECC for meta, which will add one +extra ecc with the same ECC strength as other data chunks. This extra +ECC can guarantee BBM located in data chunk, of course, we need to check +if oob can afford it. + +Previous code has two methods for ECC layout setting, the +legacy_set_geometry and set_geometry_by_ecc_info, the difference +between these two methods is, legacy_set_geometry set the chunk size +larger chan oob size and then set the maximum ECC strength that oob can +afford. While the set_geometry_by_ecc_info set chunk size and ECC +strength according to NAND spec. It has been proved that the first +method cannot provide safe ECC strength for some modern NAND chips, so +in current code, + +1. Driver read NAND parameters first and then chose the proper ECC +layout setting method. + +2. If the oob is large or NAND required data chunk larger than oob size, +chose set_geometry_for_large_oob, otherwise use set_geometry_by_ecc_info + +3. legacy_set_geometry only used for some NAND chips does not contains +necessary information. So this is only a backup plan, it is NOT +recommended to use these NAND chips. + +Signed-off-by: Han Xu <b45815@freescale.com> +(cherry picked from commit 78e8beff734adb72185405ae2cb55e0097eb96cb) +Signed-off-by: Alex Gonzalez <alex.gonzalez@digi.com> +--- + drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c | 16 +- + drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 269 ++++++++++++++++++++++++----- + drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h | 12 +- + 3 files changed, 248 insertions(+), 49 deletions(-) + +diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c +index 88ea2203e263..a4cd9523e220 100644 +--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c ++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c +@@ -212,7 +212,8 @@ void gpmi_dump_info(struct gpmi_nand_data *this) + "ECC Strength : %u\n" + "Page Size in Bytes : %u\n" + "Metadata Size in Bytes : %u\n" +- "ECC Chunk Size in Bytes: %u\n" ++ "ECC Chunk0 Size in Bytes: %u\n" ++ "ECC Chunkn Size in Bytes: %u\n" + "ECC Chunk Count : %u\n" + "Payload Size in Bytes : %u\n" + "Auxiliary Size in Bytes: %u\n" +@@ -223,7 +224,8 @@ void gpmi_dump_info(struct gpmi_nand_data *this) + geo->ecc_strength, + geo->page_size, + geo->metadata_size, +- geo->ecc_chunk_size, ++ geo->ecc_chunk0_size, ++ geo->ecc_chunkn_size, + geo->ecc_chunk_count, + geo->payload_size, + geo->auxiliary_size, +@@ -238,7 +240,8 @@ int bch_set_geometry(struct gpmi_nand_data *this) + struct resources *r = &this->resources; + struct bch_geometry *bch_geo = &this->bch_geometry; + unsigned int block_count; +- unsigned int block_size; ++ unsigned int block0_size; ++ unsigned int blockn_size; + unsigned int metadata_size; + unsigned int ecc_strength; + unsigned int page_size; +@@ -250,7 +253,8 @@ int bch_set_geometry(struct gpmi_nand_data *this) + return ret; + + block_count = bch_geo->ecc_chunk_count - 1; +- block_size = bch_geo->ecc_chunk_size; ++ block0_size = bch_geo->ecc_chunk0_size; ++ blockn_size = bch_geo->ecc_chunkn_size; + metadata_size = bch_geo->metadata_size; + ecc_strength = bch_geo->ecc_strength >> 1; + page_size = bch_geo->page_size; +@@ -277,13 +281,13 @@ int bch_set_geometry(struct gpmi_nand_data *this) + | BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size) + | BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this) + | BF_BCH_FLASH0LAYOUT0_GF(gf_len, this) +- | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this), ++ | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block0_size, this), + r->bch_regs + HW_BCH_FLASH0LAYOUT0); + + writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size) + | BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this) + | BF_BCH_FLASH0LAYOUT1_GF(gf_len, this) +- | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this), ++ | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(blockn_size, this), + r->bch_regs + HW_BCH_FLASH0LAYOUT1); + + /* Set *all* chip selects to use layout 0. */ +diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +index 1c1ebbc82824..bc4a364e5696 100644 +--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c ++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +@@ -179,6 +179,36 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) + return geo->ecc_strength <= this->devdata->bch_max_ecc_strength; + } + ++static inline bool bbm_in_data_chunk(struct gpmi_nand_data *this, ++ unsigned int *chunk_num) ++{ ++ struct bch_geometry *geo = &this->bch_geometry; ++ struct mtd_info *mtd = &this->nand.mtd; ++ unsigned int i, j; ++ ++ if (geo->ecc_chunk0_size != geo->ecc_chunkn_size) { ++ dev_err(this->dev, "The size of chunk0 must equal to chunkn\n"); ++ return false; ++ } ++ ++ i = (mtd->writesize * 8 - geo->metadata_size * 8) / ++ (geo->gf_len * geo->ecc_strength + ++ geo->ecc_chunkn_size * 8); ++ ++ j = (mtd->writesize * 8 - geo->metadata_size * 8) - ++ (geo->gf_len * geo->ecc_strength + ++ geo->ecc_chunkn_size * 8) * i; ++ ++ if (j < geo->ecc_chunkn_size * 8) { ++ *chunk_num = i+1; ++ dev_dbg(this->dev, "Set ecc to %d and bbm in chunk %d\n", ++ geo->ecc_strength, *chunk_num); ++ return true; ++ } ++ ++ return false; ++} ++ + /* + * If we can get the ECC information from the nand chip, we do not + * need to calculate them ourselves. +@@ -207,13 +237,14 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, + chip->ecc_strength_ds, chip->ecc_step_ds); + return -EINVAL; + } +- geo->ecc_chunk_size = ecc_step; +- geo->ecc_strength = round_up(ecc_strength, 2); ++ geo->ecc_chunk0_size = chip->ecc_step_ds; ++ geo->ecc_chunkn_size = chip->ecc_step_ds; ++ geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); + if (!gpmi_check_ecc(this)) + return -EINVAL; + + /* Keep the C >= O */ +- if (geo->ecc_chunk_size < mtd->oobsize) { ++ if (geo->ecc_chunkn_size < mtd->oobsize) { + dev_err(this->dev, + "unsupported nand chip. ecc size: %d, oob size : %d\n", + ecc_step, mtd->oobsize); +@@ -223,7 +254,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, + /* The default value, see comment in the legacy_set_geometry(). */ + geo->metadata_size = 10; + +- geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; ++ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; + + /* + * Now, the NAND chip with 2K page(data chunk is 512byte) shows below: +@@ -295,6 +326,129 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, + return 0; + } + ++static int set_geometry_for_large_oob(struct gpmi_nand_data *this) ++{ ++ struct bch_geometry *geo = &this->bch_geometry; ++ struct mtd_info *mtd = &this->nand.mtd; ++ struct nand_chip *chip = mtd->priv; ++ unsigned int block_mark_bit_offset; ++ unsigned int max_ecc; ++ unsigned int bbm_chunk; ++ unsigned int i; ++ ++ ++ /* sanity check for the minimum ecc nand required */ ++ if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) ++ return -EINVAL; ++ geo->ecc_strength = chip->ecc_strength_ds; ++ ++ /* check if platform can support this nand */ ++ if (!gpmi_check_ecc(this)) { ++ dev_err(this->dev, "unsupported NAND chip, minimum ecc required %d\n" ++ , geo->ecc_strength); ++ return -EINVAL; ++ } ++ ++ /* calculate the maximum ecc platform can support*/ ++ geo->metadata_size = 10; ++ geo->gf_len = 14; ++ geo->ecc_chunk0_size = 1024; ++ geo->ecc_chunkn_size = 1024; ++ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; ++ max_ecc = min(get_ecc_strength(this), ++ this->devdata->bch_max_ecc_strength); ++ ++ /* search a supported ecc strength that makes bbm */ ++ /* located in data chunk */ ++ geo->ecc_strength = chip->ecc_strength_ds; ++ while (!(geo->ecc_strength > max_ecc)) { ++ if (bbm_in_data_chunk(this, &bbm_chunk)) ++ goto geo_setting; ++ geo->ecc_strength += 2; ++ } ++ ++ /* if none of them works, keep using the minimum ecc */ ++ /* nand required but changing ecc page layout */ ++ geo->ecc_strength = chip->ecc_strength_ds; ++ /* add extra ecc for meta data */ ++ geo->ecc_chunk0_size = 0; ++ geo->ecc_chunk_count = (mtd->writesize / geo->ecc_chunkn_size) + 1; ++ geo->ecc_for_meta = 1; ++ /* check if oob can afford this extra ecc chunk */ ++ if (mtd->oobsize * 8 < geo->metadata_size * 8 + ++ geo->gf_len * geo->ecc_strength ++ * geo->ecc_chunk_count) { ++ dev_err(this->dev, "unsupported NAND chip with new layout\n"); ++ return -EINVAL; ++ } ++ ++ /* calculate in which chunk bbm located */ ++ bbm_chunk = (mtd->writesize * 8 - geo->metadata_size * 8 - ++ geo->gf_len * geo->ecc_strength) / ++ (geo->gf_len * geo->ecc_strength + ++ geo->ecc_chunkn_size * 8) + 1; ++ ++geo_setting: ++ ++ geo->page_size = mtd->writesize + mtd->oobsize; ++ geo->payload_size = mtd->writesize; ++ ++ /* ++ * The auxiliary buffer contains the metadata and the ECC status. The ++ * metadata is padded to the nearest 32-bit boundary. The ECC status ++ * contains one byte for every ECC chunk, and is also padded to the ++ * nearest 32-bit boundary. ++ */ ++ geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4); ++ geo->auxiliary_size = ALIGN(geo->metadata_size, 4) ++ + ALIGN(geo->ecc_chunk_count, 4); ++ ++ if (!this->swap_block_mark) ++ return 0; ++ ++ /* calculate the number of ecc chunk behind the bbm */ ++ i = (mtd->writesize / geo->ecc_chunkn_size) - bbm_chunk + 1; ++ ++ block_mark_bit_offset = mtd->writesize * 8 - ++ (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - i) ++ + geo->metadata_size * 8); ++ ++ geo->block_mark_byte_offset = block_mark_bit_offset / 8; ++ geo->block_mark_bit_offset = block_mark_bit_offset % 8; ++ ++ dev_dbg(this->dev, "BCH Geometry :\n" ++ "GF length : %u\n" ++ "ECC Strength : %u\n" ++ "Page Size in Bytes : %u\n" ++ "Metadata Size in Bytes : %u\n" ++ "ECC Chunk0 Size in Bytes: %u\n" ++ "ECC Chunkn Size in Bytes: %u\n" ++ "ECC Chunk Count : %u\n" ++ "Payload Size in Bytes : %u\n" ++ "Auxiliary Size in Bytes: %u\n" ++ "Auxiliary Status Offset: %u\n" ++ "Block Mark Byte Offset : %u\n" ++ "Block Mark Bit Offset : %u\n" ++ "Block Mark in chunk : %u\n" ++ "Ecc for Meta data : %u\n", ++ geo->gf_len, ++ geo->ecc_strength, ++ geo->page_size, ++ geo->metadata_size, ++ geo->ecc_chunk0_size, ++ geo->ecc_chunkn_size, ++ geo->ecc_chunk_count, ++ geo->payload_size, ++ geo->auxiliary_size, ++ geo->auxiliary_status_offset, ++ geo->block_mark_byte_offset, ++ geo->block_mark_bit_offset, ++ bbm_chunk, ++ geo->ecc_for_meta); ++ ++ return 0; ++} ++ + static int legacy_set_geometry(struct gpmi_nand_data *this) + { + struct bch_geometry *geo = &this->bch_geometry; +@@ -314,13 +468,15 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) + geo->gf_len = 13; + + /* The default for chunk size. */ +- geo->ecc_chunk_size = 512; +- while (geo->ecc_chunk_size < mtd->oobsize) { +- geo->ecc_chunk_size *= 2; /* keep C >= O */ ++ geo->ecc_chunk0_size = 512; ++ geo->ecc_chunkn_size = 512; ++ while (geo->ecc_chunkn_size < mtd->oobsize) { ++ geo->ecc_chunk0_size *= 2; /* keep C >= O */ ++ geo->ecc_chunkn_size *= 2; /* keep C >= O */ + geo->gf_len = 14; + } + +- geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; ++ geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; + + /* We use the same ECC strength for all chunks. */ + geo->ecc_strength = get_ecc_strength(this); +@@ -409,22 +565,25 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) + + int common_nfc_set_geometry(struct gpmi_nand_data *this) + { +- struct nand_chip *chip = &this->nand; ++ struct mtd_info *mtd = &this->nand.mtd; ++ struct nand_chip *chip = mtd_to_nand(mtd); + +- if (chip->ecc.strength > 0 && chip->ecc.size > 0) +- return set_geometry_by_ecc_info(this, chip->ecc.strength, +- chip->ecc.size); ++ if (chip->ecc_strength_ds > this->devdata->bch_max_ecc_strength) { ++ dev_err(this->dev, ++ "unsupported NAND chip, minimum ecc required %d\n" ++ , chip->ecc_strength_ds); ++ return -EINVAL; ++ } + +- if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) +- || legacy_set_geometry(this)) { +- if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) +- return -EINVAL; ++ if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && ++ !(mtd->oobsize > 1024)) ++ return legacy_set_geometry(this); + +- return set_geometry_by_ecc_info(this, chip->ecc_strength_ds, +- chip->ecc_step_ds); +- } ++ if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize) ++ return set_geometry_for_large_oob(this); + +- return 0; ++ return set_geometry_by_ecc_info(this, chip->ecc_strength_ds, ++ chip->ecc_step_ds); + } + + struct dma_chan *get_dma_chan(struct gpmi_nand_data *this) +@@ -997,7 +1156,8 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, + + /* Read ECC bytes into our internal raw_buffer */ + offset = nfc_geo->metadata_size * 8; +- offset += ((8 * nfc_geo->ecc_chunk_size) + eccbits) * (i + 1); ++ offset += ((8 * nfc_geo->ecc_chunkn_size) + eccbits) * ++ (i + 1); + offset -= eccbits; + bitoffset = offset % 8; + eccbytes = DIV_ROUND_UP(offset + eccbits, 8); +@@ -1034,19 +1194,19 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, + if (i == 0) { + /* The first block includes metadata */ + flips = nand_check_erased_ecc_chunk( +- buf + i * nfc_geo->ecc_chunk_size, +- nfc_geo->ecc_chunk_size, +- eccbuf, eccbytes, +- this->auxiliary_virt, +- nfc_geo->metadata_size, +- nfc_geo->ecc_strength); ++ buf + i * nfc_geo->ecc_chunkn_size, ++ nfc_geo->ecc_chunkn_size, ++ eccbuf, eccbytes, ++ this->payload_virt, ++ nfc_geo->metadata_size, ++ nfc_geo->ecc_strength); + } else { + flips = nand_check_erased_ecc_chunk( +- buf + i * nfc_geo->ecc_chunk_size, +- nfc_geo->ecc_chunk_size, +- eccbuf, eccbytes, +- NULL, 0, +- nfc_geo->ecc_strength); ++ buf + i * nfc_geo->ecc_chunkn_size, ++ nfc_geo->ecc_chunkn_size, ++ eccbuf, eccbytes, ++ NULL, 0, ++ nfc_geo->ecc_strength); + } + + if (flips > 0) { +@@ -1134,9 +1294,24 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, + } + } + ++ /* ++ * if there is an ECC dedicate for meta: ++ * - need to add an extra ECC size when calculating col and page_size, ++ * if the meta size is NOT zero. ++ * ++ * - chunk0 size need to set to the same size as other chunks, ++ * if the meta size is zero. ++ */ ++ + meta = geo->metadata_size; + if (first) { +- col = meta + (size + ecc_parity_size) * first; ++ if (geo->ecc_for_meta) ++ col = meta + ecc_parity_size ++ + (size + ecc_parity_size) * first; ++ else ++ col = meta + (size + ecc_parity_size) * first; ++ ++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1); + meta = 0; + buf = buf + first * size; + } +@@ -1149,21 +1324,37 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, + + /* change the BCH registers and bch_geometry{} */ + n = last - first + 1; +- page_size = meta + (size + ecc_parity_size) * n; ++ ++ if (geo->ecc_for_meta && meta) ++ page_size = meta + ecc_parity_size ++ + (size + ecc_parity_size) * n; ++ else ++ page_size = meta + (size + ecc_parity_size) * n; + + r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS | + BM_BCH_FLASH0LAYOUT0_META_SIZE); +- r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1) ++ r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS( ++ (geo->ecc_for_meta && meta) ? n : n - 1) + | BF_BCH_FLASH0LAYOUT0_META_SIZE(meta); ++ ++ /* set chunk0 size if meta size is 0 */ ++ if (!meta) { ++ if (GPMI_IS_MX6(this)) ++ r1_new &= ~MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE; ++ else ++ r1_new &= ~BM_BCH_FLASH0LAYOUT0_DATA0_SIZE; ++ r1_new |= BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(size, this); ++ } + writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0); + + r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE; + r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size); + writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1); + +- geo->ecc_chunk_count = n; ++ geo->ecc_chunk_count = (geo->ecc_for_meta && meta) ? n + 1 : n; + geo->payload_size = n * size; + geo->page_size = page_size; ++ geo->metadata_size = meta; + geo->auxiliary_status_offset = ALIGN(meta, 4); + + dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n", +@@ -1386,7 +1577,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, + { + struct gpmi_nand_data *this = nand_get_controller_data(chip); + struct bch_geometry *nfc_geo = &this->bch_geometry; +- int eccsize = nfc_geo->ecc_chunk_size; ++ int eccsize = nfc_geo->ecc_chunkn_size; + int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; + u8 *tmp_buf = this->raw_buffer; + size_t src_bit_off; +@@ -1471,7 +1662,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, + { + struct gpmi_nand_data *this = nand_get_controller_data(chip); + struct bch_geometry *nfc_geo = &this->bch_geometry; +- int eccsize = nfc_geo->ecc_chunk_size; ++ int eccsize = nfc_geo->ecc_chunkn_size; + int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; + u8 *tmp_buf = this->raw_buffer; + uint8_t *oob = chip->oob_poi; +@@ -1847,7 +2038,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this) + ecc->read_oob_raw = gpmi_ecc_read_oob_raw; + ecc->write_oob_raw = gpmi_ecc_write_oob_raw; + ecc->mode = NAND_ECC_HW; +- ecc->size = bch_geo->ecc_chunk_size; ++ ecc->size = bch_geo->ecc_chunkn_size; + ecc->strength = bch_geo->ecc_strength; + mtd_set_ooblayout(mtd, &gpmi_ooblayout_ops); + +diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h +index 69cd0cbde4f2..ef4e57256d30 100644 +--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h ++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h +@@ -30,9 +30,9 @@ struct resources { + * @page_size: The size, in bytes, of a physical page, including + * both data and OOB. + * @metadata_size: The size, in bytes, of the metadata. +- * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note +- * the first chunk in the page includes both data and +- * metadata, so it's a bit larger than this value. ++ * @ecc_chunk0_size: The size, in bytes, of a first ECC chunk. ++ * @ecc_chunkn_size: The size, in bytes, of a single ECC chunk after ++ * the first chunk in the page. + * @ecc_chunk_count: The number of ECC chunks in the page, + * @payload_size: The size, in bytes, of the payload buffer. + * @auxiliary_size: The size, in bytes, of the auxiliary buffer. +@@ -42,19 +42,23 @@ struct resources { + * which the underlying physical block mark appears. + * @block_mark_bit_offset: The bit offset into the ECC-based page view at + * which the underlying physical block mark appears. ++ * @ecc_for_meta: The flag to indicate if there is a dedicate ecc ++ * for meta. + */ + struct bch_geometry { + unsigned int gf_len; + unsigned int ecc_strength; + unsigned int page_size; + unsigned int metadata_size; +- unsigned int ecc_chunk_size; ++ unsigned int ecc_chunk0_size; ++ unsigned int ecc_chunkn_size; + unsigned int ecc_chunk_count; + unsigned int payload_size; + unsigned int auxiliary_size; + unsigned int auxiliary_status_offset; + unsigned int block_mark_byte_offset; + unsigned int block_mark_bit_offset; ++ unsigned int ecc_for_meta; /* ECC for meta data */ + }; + + /** diff --git a/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0002-cpufreq-imx6q-read-OCOTP-through-nvmem-for-imx6ul-im.patch b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0002-cpufreq-imx6q-read-OCOTP-through-nvmem-for-imx6ul-im.patch new file mode 100644 index 00000000..26f6ba89 --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0002-cpufreq-imx6q-read-OCOTP-through-nvmem-for-imx6ul-im.patch @@ -0,0 +1,113 @@ +From: Anson Huang <Anson.Huang@nxp.com> +Date: Mon, 8 Oct 2018 14:07:34 +0800 +Subject: [PATCH] cpufreq: imx6q: read OCOTP through nvmem for imx6ul/imx6ull + +On i.MX6UL/i.MX6ULL, accessing OCOTP directly is wrong because +the ocotp clock needs to be enabled first. Add support for reading +OCOTP through the nvmem API, and keep the old method there to +support old dtb. + +Signed-off-by: Anson Huang <Anson.Huang@nxp.com> +Acked-by: Viresh Kumar <viresh.kumar@linaro.org> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +(cherry picked from commit 2733fb0d0699246711cf622e0e2faf02a05b69dc) +--- + drivers/cpufreq/imx6q-cpufreq.c | 52 +++++++++++++++++++++++++++-------------- + 1 file changed, 35 insertions(+), 17 deletions(-) + +diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c +index b2ff423ad7f8..8cfee0ab804b 100644 +--- a/drivers/cpufreq/imx6q-cpufreq.c ++++ b/drivers/cpufreq/imx6q-cpufreq.c +@@ -12,6 +12,7 @@ + #include <linux/cpu_cooling.h> + #include <linux/err.h> + #include <linux/module.h> ++#include <linux/nvmem-consumer.h> + #include <linux/of.h> + #include <linux/of_address.h> + #include <linux/pm_opp.h> +@@ -290,20 +291,32 @@ static void imx6q_opp_check_speed_grading(struct device *dev) + #define OCOTP_CFG3_6ULL_SPEED_792MHZ 0x2 + #define OCOTP_CFG3_6ULL_SPEED_900MHZ 0x3 + +-static void imx6ul_opp_check_speed_grading(struct device *dev) ++static int imx6ul_opp_check_speed_grading(struct device *dev) + { +- struct device_node *np; +- void __iomem *base; + u32 val; ++ int ret = 0; + +- np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp"); +- if (!np) +- return; ++ if (of_find_property(dev->of_node, "nvmem-cells", NULL)) { ++ ret = nvmem_cell_read_u32(dev, "speed_grade", &val); ++ if (ret) ++ return ret; ++ } else { ++ struct device_node *np; ++ void __iomem *base; ++ ++ np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp"); ++ if (!np) ++ return -ENOENT; ++ ++ base = of_iomap(np, 0); ++ of_node_put(np); ++ if (!base) { ++ dev_err(dev, "failed to map ocotp\n"); ++ return -EFAULT; ++ } + +- base = of_iomap(np, 0); +- if (!base) { +- dev_err(dev, "failed to map ocotp\n"); +- goto put_node; ++ val = readl_relaxed(base + OCOTP_CFG3); ++ iounmap(base); + } + + /* +@@ -314,7 +327,6 @@ static void imx6ul_opp_check_speed_grading(struct device *dev) + * 2b'11: 900000000Hz on i.MX6ULL only; + * We need to set the max speed of ARM according to fuse map. + */ +- val = readl_relaxed(base + OCOTP_CFG3); + val >>= OCOTP_CFG3_SPEED_SHIFT; + val &= 0x3; + +@@ -334,9 +346,7 @@ static void imx6ul_opp_check_speed_grading(struct device *dev) + dev_warn(dev, "failed to disable 900MHz OPP\n"); + } + +- iounmap(base); +-put_node: +- of_node_put(np); ++ return ret; + } + + static int imx6q_cpufreq_probe(struct platform_device *pdev) +@@ -394,10 +404,18 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) + } + + if (of_machine_is_compatible("fsl,imx6ul") || +- of_machine_is_compatible("fsl,imx6ull")) +- imx6ul_opp_check_speed_grading(cpu_dev); +- else ++ of_machine_is_compatible("fsl,imx6ull")) { ++ ret = imx6ul_opp_check_speed_grading(cpu_dev); ++ if (ret == -EPROBE_DEFER) ++ return ret; ++ if (ret) { ++ dev_err(cpu_dev, "failed to read ocotp: %d\n", ++ ret); ++ return ret; ++ } ++ } else { + imx6q_opp_check_speed_grading(cpu_dev); ++ } + + /* Because we have added the OPPs here, we must free them */ + free_opp = true; diff --git a/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0003-ARM-dts-imx6ul-use-nvmem-cells-for-cpu-speed-grading.patch b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0003-ARM-dts-imx6ul-use-nvmem-cells-for-cpu-speed-grading.patch new file mode 100644 index 00000000..e8c6d16a --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/ccimx6ul/0003-ARM-dts-imx6ul-use-nvmem-cells-for-cpu-speed-grading.patch @@ -0,0 +1,38 @@ +From: Anson Huang <Anson.Huang@nxp.com> +Date: Fri, 14 Sep 2018 10:59:21 +0800 +Subject: [PATCH] ARM: dts: imx6ul: use nvmem-cells for cpu speed grading + +On i.MX6UL, accessing OCOTP directly is wrong because the ocotp clock +needs to be enabled first, so use the nvmem-cells binding instead. + +Signed-off-by: Anson Huang <Anson.Huang@nxp.com> +Signed-off-by: Shawn Guo <shawnguo@kernel.org> +(cherry picked from commit 92f0eb08c66a73594cf200e65689e767f7f0da5e) +--- + arch/arm/boot/dts/imx6ul.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi +index 6dc0b569acdf..c670d8e4e0a9 100644 +--- a/arch/arm/boot/dts/imx6ul.dtsi ++++ b/arch/arm/boot/dts/imx6ul.dtsi +@@ -89,6 +89,8 @@ + "pll1_sys"; + arm-supply = <®_arm>; + soc-supply = <®_soc>; ++ nvmem-cells = <&cpu_speed_grade>; ++ nvmem-cell-names = "speed_grade"; + }; + }; + +@@ -932,6 +934,10 @@ + tempmon_temp_grade: temp-grade@20 { + reg = <0x20 4>; + }; ++ ++ cpu_speed_grade: speed-grade@10 { ++ reg = <0x10 4>; ++ }; + }; + + lcdif: lcdif@21c8000 { diff --git a/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6q-var-som-vsc.dts b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6q-var-som-vsc.dts new file mode 100644 index 00000000..63be949e --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6q-var-som-vsc.dts @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Support for Variscite VAR-SOM-MX6 Starter Kit + * + * Copyright 2018 + * Author: Andreas Müller <schnitzeltony@gmail.com> + */ + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-var-som.dtsi" +#include <dt-bindings/input/linux-event-codes.h> + +/ { + model = "Variscite i.MX6 VAR-SOM-MX6"; + compatible = "variscite,var-som", "fsl,imx6q"; + + gpio-keys { /* OK */ + compatible = "gpio-keys"; + autorepeat; + + back { + gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + linux,code = <KEY_BACK>; + label = "Key Back"; + linux,input-type = <1>; + debounce-interval = <100>; + wakeup-source; + }; + }; + + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "tlv320aic3106-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_codec>; + simple-audio-card,frame-master = <&sound_codec>; + simple-audio-card,widgets = "Headphone", "Headphone Jack", + "Line", "Line In"; + simple-audio-card,routing = "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + sound_cpu: simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + sound_codec: simple-audio-card,codec { + sound-dai = <&tlv320aic3106>; + clocks = <&clks IMX6QDL_CLK_CKO>; + }; + }; +}; + +&can1 { + status = "okay"; +}; + +&ecspi1 { + cs-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>, + <&gpio4 10 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&fec { /* OK */ + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&i2c3 { /* OK */ + status = "okay"; + rtc@0x68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +/*&ldb { + status = "okay"; + + lvds-channel@1 { + status = "okay"; + + port@4 { + reg = <4>; + + lvds1_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +};*/ + +&pwm2 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usbh1 { + status = "okay"; +}; + +&usbotg { + status = "okay"; +}; + +&usdhc2 { /* OK */ + pinctrl-1 = <&pinctrl_usdhc2cdwp>; + cd-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&iomuxc { + pinctrl_gpio_keys: gpio_keysgrp { + fsl,pins = < + /* user button */ + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x17059 + >; + }; + + pinctrl_usdhc2cdwp: usdhc2cdwpgrp { + fsl,pins = < + /* SDMMC2 CD/WP */ + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x80000000 + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 + >; + }; +}; + + diff --git a/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6qdl-var-som.dtsi b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6qdl-var-som.dtsi new file mode 100644 index 00000000..47949d1c --- /dev/null +++ b/bsp/meta-freescale-3rdparty/recipes-kernel/linux/linux-fslc-lts-4.19/imx6qdl-var-som.dtsi @@ -0,0 +1,626 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Support for Variscite SOM Module + * + * Copyright 2018 + * Author: Andreas Müller <schnitzeltony@gmail.com> + * Based on imx6qdl-var-dart.dtsi + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/sound/fsl-imx-audmux.h> + +/ { + memory@10000000 { + reg = <0x10000000 0x40000000>; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_wl18xx_vmmc: regulator-wl18xx { + compatible = "regulator-fixed"; + regulator-name = "vwl1807"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + startup-delay-us = <70000>; + }; + + reg_usb_h1_vbus: regulator-usbh1vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_usb_otg_vbus: regulator-usbotgvbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&iomuxc { + pinctrl_audmux: audmux { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0 + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0 + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 + /* Audio Clock */ + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 + /* Audio reset */ + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x178b0 + >; + }; + + pinctrl_bt: bt { + fsl,pins = < + /* Bluetooth / Wifi enable */ + MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x1b0b1 + /* Bluetooth Slow Clock */ + MX6QDL_PAD_ENET_RXD0__OSC32K_32K_OUT 0x000b0 + >; + }; + + pinctrl_ecspi3: ecspi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1 + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1 + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x178b0 /* CS */ + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x10030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x10030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x10030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x10030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x10030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x10030 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0 + MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0 + >; + }; + + pinctrl_hdmicec: hdmicecgrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + /* PMIC INT */ + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT9__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD3_DAT4__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT5__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x17059 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + /* WL_EN */ + MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x13059 + /* WL_IRQ */ + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x13059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170B9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100B9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170B9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170B9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170B9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170B9 + /* WL_EN */ + MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x130B9 + /* WL_IRQ */ + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x130B9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170F9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100F9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170F9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170F9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170F9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170F9 + /* WL_EN */ + MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x130F9 + /* WL_IRQ */ + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x130F9 + >; + }; + + pinctrl_gpmi_nand: gpmi-nand { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + >; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_SYN | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(2) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(2)) + IMX_AUDMUX_V2_PDCR_RXDSEL(2) + >; + }; + + aud3 { + fsl,audmux-port = <2>; + fsl,port-config = < + IMX_AUDMUX_V2_PTCR_SYN + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + status = "disabled"; +}; + +&can2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + status = "disabled"; +}; + +&ecspi3 { + pinctrl-names = "default"; + fsl,spi-num-chipselects = <1>; + pinctrl-0 = <&pinctrl_ecspi3>; + cs-gpios = <&gpio4 24 0>; + status = "disabled"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + phy-reset-gpios = <&gpio1 25 0>; + phy-reset-duration=<100>; + status = "disabled"; +}; + +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmicec>; + ddc-i2c-bus = <&i2c2>; + status = "disabled"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "disabled"; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pmic@8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + compatible = "fsl,pfuze100"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3a { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3950000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3b_reg: sw3b { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3950000>; + regulator-boot-on; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3950000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + + tlv320aic3106: codec@1b { + compatible = "ti,tlv320aic3106"; + reg = <0x1b>; + #sound-dai-cells = <0>; + DRVDD-supply = <®_3p3v>; + AVDD-supply = <®_3p3v>; + IOVDD-supply = <®_3p3v>; + DVDD-supply = <®_3p3v>; + ai3x-ocmv = <0>; + reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; + ai3x-gpio-func = < + 0 /* AIC3X_GPIO1_FUNC_DISABLED */ + 5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */ + >; + }; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "disabled"; +}; + +&pcie { + fsl,tx-swing-full = <103>; + fsl,tx-swing-low = <103>; + reset-gpio = <&gpio4 11 GPIO_ACTIVE_LOW>; + status = "disabled"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "disabled"; +}; + +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_pu { + vin-supply = <&sw1c_reg>; +}; + +®_soc { + vin-supply = <&sw1c_reg>; +}; + +&snvs_poweroff { + status = "okay"; +}; + +&ssi2 { /* Onboard audio */ + fsl,mode = "i2s-slave"; + status = "okay"; +}; + +&uart1 { /* Console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "disabled"; +}; + +&uart2 { /* Bluetooth */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2 &pinctrl_bt>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio6 18 GPIO_ACTIVE_HIGH>; + }; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + status = "disabled"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + status = "disabled"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "disabled"; +}; + +&gpmi { /* NAND */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + fsl,legacy-bch-geometry; + status = "okay"; + + /* a 2 MiB partition */ + partition@0 { + label = "spl"; + reg = <0x00000000 0x00200000>; + }; + + /* a 2 MiB partition */ + partition@1 { + label = "bootloader"; + reg = <0x00200000 0x00200000>; + }; + + /* an 8 MiB partition */ + partition@2 { + label = "kernel"; + reg = <0x00400000 0x00800000>; + }; + + /* max 1012 MiB partition - truncated automatically */ + partition@3 { + label = "rootfs"; + reg = <0x00c00000 0x3f400000>; + }; +}; + +&usdhc1 { /* eMMC */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + keep-power-in-suspend; + wakeup-source; + non-removable; + status = "okay"; +}; + +&usdhc2 { /* MMC/SD card */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + no-1-8-v; + keep-power-in-suspend; + wakeup-source; + status = "disabled"; +}; + +&usdhc3 { /* Wilink8 WL18xx*/ + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + + non-removable; + keep-power-in-suspend; + wakeup-source; + bus-width = <4>; + vmmc-supply = <®_wl18xx_vmmc>; + non-removable; + wakeup-source; + keep-power-in-suspend; + cap-power-off-card; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wlcore: wlcore@2 { + compatible = "ti,wl1835"; + reg = <2>; + interrupt-parent = <&gpio6>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; + ref-clock-frequency = <38400000>; + }; +}; + +&snvs_rtc { + status = "disabled"; +}; |