AM62xx开发板将GPMC总线引出到P34引脚。添加GPMC NOR FLASH应用方法如下
index 5d4923bff..ad5228be3 100644 --- a/arch/arm64/boot/dts/ti/OK6254-C.dts +++ b/arch/arm64/boot/dts/ti/OK6254-C.dts @@ -525,6 +525,32 @@ AM62X_IOPAD(0x128, PIN_OUTPUT, 7) /* (B23) CSI_PWDN.GPIO0_72 */ >; }; + + gpmc0_pins_default: gpmc0-pins-default { + pinctrl-single,pins = < + AM62X_IOPAD(0x078, PIN_INPUT, 0) /* (U24) GPMC0_AD15.GPMC0_AD15 */ + AM62X_IOPAD(0x074, PIN_INPUT, 0) /* (U25) GPMC0_AD14.GPMC0_AD14 */ + AM62X_IOPAD(0x070, PIN_INPUT, 0) /* (T24) GPMC0_AD13.GPMC0_AD13 */ + AM62X_IOPAD(0x06C, PIN_INPUT, 0) /* (T22) GPMC0_AD12.GPMC0_AD12 */ + AM62X_IOPAD(0x068, PIN_INPUT, 0) /* (R21) GPMC0_AD11.GPMC0_AD11 */ + AM62X_IOPAD(0x064, PIN_INPUT, 0) /* (T25) GPMC0_AD10.GPMC0_AD10 */ + AM62X_IOPAD(0x060, PIN_INPUT, 0) /* (R25) GPMC0_AD9.GPMC0_AD9 */ + AM62X_IOPAD(0x05C, PIN_INPUT, 0) /* (R24) GPMC0_AD8.GPMC0_AD8 */ + AM62X_IOPAD(0x058, PIN_INPUT, 0) /* (R23) GPMC0_AD7.GPMC0_AD7 */ + AM62X_IOPAD(0x054, PIN_INPUT, 0) /* (P21) GPMC0_AD6.GPMC0_AD6 */ + AM62X_IOPAD(0x050, PIN_INPUT, 0) /* (P22) GPMC0_AD5.GPMC0_AD5 */ + AM62X_IOPAD(0x04C, PIN_INPUT, 0) /* (P24) GPMC0_AD4.GPMC0_AD4 */ + AM62X_IOPAD(0x048, PIN_INPUT, 0) /* (N25) GPMC0_AD3.GPMC0_AD3 */ + AM62X_IOPAD(0x044, PIN_INPUT, 0) /* (N24) GPMC0_AD2.GPMC0_AD2 */ + AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (N23) GPMC0_AD1.GPMC0_AD1 */ + AM62X_IOPAD(0x03C, PIN_INPUT, 0) /* (M25) GPMC0_AD0.GPMC0_AD0 */ + AM62X_IOPAD(0x084, PIN_OUTPUT, 0) /* (L23) GPMC0_ADVn_ALE.GPMC0_ADVn_ALE */ + AM62X_IOPAD(0x088, PIN_OUTPUT, 0) /* (L24) GPMC0_OEn_REn.GPMC0_OEn_REn */ + AM62X_IOPAD(0x08C, PIN_OUTPUT, 0) /* (L25) GPMC0_WEn.GPMC0_WEn */ + AM62X_IOPAD(0x098, PIN_INPUT_PULLUP, 0) /* (U23) GPMC0_WAIT0.GPMC0_WAIT0 */ + AM62X_IOPAD(0x0A8, PIN_OUTPUT, 0) /* (M21) GPMC0_CSn0.GPMC0_CSn0 */ + >; + }; }; &mcu_pmx0 { @@ -937,3 +963,52 @@ ti,system-suspend-controller; ti,ctx-memory-region = <&lpm_ctx_ddr>; }; + +&gpmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&gpmc0_pins_default>; + ranges = <0 0 0x00 0x50000000 0x02000000>; + + nor@0,0 { + compatible = "fl,gpmc-nor"; + + reg = <0 0x0 0x02000000>; + linux,mtd-name = "cfi_probe"; + probe-type = "CFI"; /* CFI or JEDEC */ + //big-endian; + + bank-width = <2>; + gpmc,mux-add-data = <2>; + gpmc,burst-length = <16>; //16words + gpmc,burst-read; + gpmc,burst-write; + gpmc,page-burst-access-ns = <0>; + + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <7>; + gpmc,cs-rd-off-ns = <120>; + gpmc,cs-wr-off-ns = <120>; + + gpmc,adv-on-ns = <7>; + gpmc,adv-rd-off-ns = <15>; + gpmc,adv-wr-off-ns = <15>; + + gpmc,we-on-ns = <30>; + gpmc,we-off-ns = <93>; + + gpmc,oe-on-ns = <28>; + gpmc,oe-off-ns = <120>; + + gpmc,access-ns = <120>; + + gpmc,rd-cycle-ns = <120>; + gpmc,wr-cycle-ns = <120>; + + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wr-access-ns = <112>; + + gpmc,wr-data-mux-bus-ns = <52>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi index e23350dce..cbc9bb54b 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi @@ -981,4 +981,32 @@ reg-names = "esm"; forlinx,esm-pins = <5>; }; + + gpmc0: memory-controller@3b000000 { + compatible = "ti,am64-gpmc"; + power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 80 0>; + clock-names = "fck"; + reg = <0x00 0x03b000000 0x00 0x400>, + <0x00 0x050000000 0x00 0x08000000>; + reg-names = "cfg", "data"; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + gpmc,num-cs = <3>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + }; + + elm0: ecc@25010000 { + compatible = "ti,am3352-elm"; + reg = <0x00 0x25010000 0x00 0x2000>; + interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&k3_pds 54 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 54 0>; + clock-names = "fck"; + }; }; diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi index 71665fa1f..d1f11ffd7 100644 --- a/arch/arm64/boot/dts/ti/k3-am62.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi @@ -79,6 +79,8 @@ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */ + <0x00 0x3b000000 0x00 0x3b000000 0x00 0x00000400>, /* GPMC0_CFG */ + <0x00 0x50000000 0x00 0x50000000 0x00 0x08000000>, /* GPMC0_DATA */ <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* sa3 sproxy data */ <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */ <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* sa3 sproxy config */ 2.驱动修改及添加 diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index d9bf1c2ac..874298ffb 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -165,7 +165,7 @@ #define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) #define GPMC_CONFIG7_CSVALID (1 << 6) -#define GPMC_CONFIG7_BASEADDRESS_MASK 0x3f +#define GPMC_CONFIG7_BASEADDRESS_MASK 0x5f #define GPMC_CONFIG7_CSVALID_MASK BIT(6) #define GPMC_CONFIG7_MASKADDRESS_OFFSET 8 #define GPMC_CONFIG7_MASKADDRESS_MASK (0xf << GPMC_CONFIG7_MASKADDRESS_OFFSET) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 96a27e064..d2137cb72 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -432,6 +432,15 @@ static void fixup_s29ns512p_sectors(struct mtd_info *mtd) mtd->name); } + +static void fixup_s29gl**s_sectors(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + cfi->cfiq->DevSize = 26; + cfi->cfiq->EraseRegionInfo[0] = 0x020001ff; +} + /* Used to fix CFI-Tables of chips without Extended Query Tables */ static struct cfi_fixup cfi_nopri_fixup_table[] = { { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ @@ -463,6 +472,7 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors }, { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors }, { CFI_MFR_AMD, 0x3f00, fixup_s29ns512p_sectors }, + { CFI_MFR_AMD, 0x2201, fixup_s29gl**s_sectors }, { CFI_MFR_SST, 0x536a, fixup_sst38vf640x_sectorsize }, /* SST38VF6402 */ { CFI_MFR_SST, 0x536b, fixup_sst38vf640x_sectorsize }, /* SST38VF6401 */ { CFI_MFR_SST, 0x536c, fixup_sst38vf640x_sectorsize }, /* SST38VF6404 */ diff --git a/drivers/mtd/gpmc_nor.c b/drivers/mtd/gpmc_nor.c new file mode 100755 index 000000000..0e3d70e77 --- /dev/null +++ b/drivers/mtd/gpmc_nor.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Normal mappings of chips in omap-nor memory + */ + +#include <linux/err.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/cfi.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/of.h> +#include <linux/omap-gpmc.h> + +struct gpmc_nor_mtd { + struct mtd_info *mtd; + struct map_info *map; + struct resource *res; + const char *probe_type; + + /* gpmc */ + int gpmc_cs; +}; + + +#define DRIVER_NAME "gpmc-nor" + +static struct mtd_partition board_nor_parts[] = { + [0] = { + .name = DRIVER_NAME, + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static const char *gpmc_nor_select_probe_type(struct platform_device *dev) +{ + struct device_node *dp = dev->dev.of_node; + const char *probe_type; + + of_property_read_string(dp, "probe-type", &probe_type); + if (!probe_type) + return NULL; + + if (!strcmp(probe_type, "CFI")) { + probe_type = "cfi_probe"; + } else if (!strcmp(probe_type, "JEDEC")) { + probe_type = "jedec_probe"; + } else if (!strcmp(probe_type, "ROM")) { + probe_type = "map_rom"; + } else { + dev_warn(&dev->dev, + "obsolete_probe: don't know probe type '%s', mapping as cfi\n", + probe_type); + probe_type = "cfi_probe"; + } + + return probe_type; +} + +static int gpmc_nor_parse_dt(struct platform_device *dev) +{ + struct gpmc_nor_mtd *gpmc_nor_mtd = platform_get_drvdata(dev); + struct device_node *dp = dev->dev.of_node; + int err; + u32 bankwidth; + u32 cs; + int swap = CFI_LITTLE_ENDIAN; + + if (!dp) + return -EINVAL; + + gpmc_nor_mtd->probe_type = gpmc_nor_select_probe_type(dev); + + err = of_property_read_u32(dp, "reg", &cs); + if (err) { + dev_err(&dev->dev, "reg not found in DT\n"); + return -EINVAL; + } + gpmc_nor_mtd->gpmc_cs = cs; + + err = of_property_read_u32(dp, "bank-width", &bankwidth); + if (err) { + dev_err(&dev->dev, "Can't get bank width from device tree\n"); + return err; + } + + if (of_property_read_bool(dp, "big-endian")) + swap = CFI_BIG_ENDIAN; + else if (of_property_read_bool(dp, "little-endian")) + swap = CFI_LITTLE_ENDIAN; + + gpmc_nor_mtd->map->name = gpmc_nor_mtd->probe_type; + gpmc_nor_mtd->map->bankwidth = bankwidth; + gpmc_nor_mtd->map->swap = swap; + gpmc_nor_mtd->map->device_node = dp; + + /* + * On some platforms (e.g. MPC5200) a direct 1:1 mapping + * may cause problems with JFFS2 usage, as the local bus (LPB) + * doesn't support unaligned accesses as implemented in the + * JFFS2 code via memcpy(). By setting NO_XIP, the + * flash will not be exposed directly to the MTD users + * (e.g. JFFS2) any more. + */ + if (of_property_read_bool(dp, "no-unaligned-direct-access")) + gpmc_nor_mtd->map->phys = NO_XIP; + else + gpmc_nor_mtd->map->phys = 0; + return 0; +} + +static int gpmc_nor_remove(struct platform_device *pdev) +{ + struct gpmc_nor_mtd *gpmc_nor_mtd = platform_get_drvdata(pdev); + + if (gpmc_nor_mtd && gpmc_nor_mtd->mtd) { + mtd_device_unregister(gpmc_nor_mtd->mtd); + map_destroy(gpmc_nor_mtd->mtd); + } + + return 0; +} + +static int gpmc_nor_probe(struct platform_device *pdev) +{ + struct gpmc_nor_mtd *gpmc_nor_mtd; + int err; + + if (! pdev->dev.of_node) { + dev_err(&pdev->dev, "failed to find of node\n"); + return -ENOMEM; + } + + gpmc_nor_mtd = devm_kzalloc(&pdev->dev, sizeof(struct gpmc_nor_mtd), GFP_KERNEL); + if (!gpmc_nor_mtd) + return -ENOMEM; + + platform_set_drvdata(pdev, gpmc_nor_mtd); + + gpmc_nor_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info), GFP_KERNEL); + if (!gpmc_nor_mtd->map) + return -ENOMEM; + + err = gpmc_nor_parse_dt(pdev); + if (err) { + dev_err(&pdev->dev, "failed to parse dt\n"); + return -ENOMEM; + } + + gpmc_nor_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!gpmc_nor_mtd->res) { + dev_err(&pdev->dev, "failed to get memory resource\n"); + return -ENOENT; + } + + gpmc_nor_mtd->map->phys = gpmc_nor_mtd->res->start; + gpmc_nor_mtd->map->size = resource_size(gpmc_nor_mtd->res); + gpmc_nor_mtd->map->virt = devm_ioremap_resource(&pdev->dev, gpmc_nor_mtd->res); + if (IS_ERR(gpmc_nor_mtd->map->virt)) + return PTR_ERR(gpmc_nor_mtd->map->virt); + + printk("gpmc map phys:%x virt:%x size:%x\n", gpmc_nor_mtd->map->phys, gpmc_nor_mtd->map->virt, + gpmc_nor_mtd->map->size); + **_map_init(gpmc_nor_mtd->map); + + gpmc_cs_write_reg(0, 0x00,(2 << 23)|(0 << 22)|(0 << 21)|(0 << 18)|(1 << 12)|(2 << 8)); + gpmc_nor_mtd->mtd = do_map_probe(gpmc_nor_mtd->probe_type, gpmc_nor_mtd->map); + if (!gpmc_nor_mtd->mtd) { + dev_err(&pdev->dev, "probing failed\n"); + return -ENXIO; + } + + gpmc_nor_mtd->mtd->dev.parent = &pdev->dev; + + mtd_set_of_node(gpmc_nor_mtd->mtd, pdev->dev.of_node); + + err = mtd_device_register(gpmc_nor_mtd->mtd, board_nor_parts, 1); + if (err) { + dev_err(&pdev->dev, "failed to add partitions\n"); + goto err_destroy; + } + + return 0; + +err_destroy: + gpmc_nor_remove(pdev); + return err; +} + +static const struct of_device_id gpmc_nor_ids[] = { + { .compatible = "fl,gpmc-nor" }, + {}, +}; +MODULE_DEVICE_TABLE(of, gpmc_nor_ids); + +static struct platform_driver gpmc_nor_driver = { + .probe = gpmc_nor_probe, + .remove = gpmc_nor_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = gpmc_nor_ids, + }, +}; + +module_platform_driver(gpmc_nor_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ZZY <zzy@forlinx>"); +MODULE_DESCRIPTION("FL gpmc NOR"); + 3.makefile添加编译 diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 593d0593a..92bc1c1b3 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -31,3 +31,4 @@ obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ obj-$(CONFIG_MTD_UBI) += ubi/ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ +obj-y += gpmc_nor.o |
|小黑屋|
飞凌嵌入式
( 冀ICP备12004394号-1 )
GMT+8, 2025-4-12 17:11
Powered by Discuz! X3.4
© 2001-2013 Comsenz Inc.