aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c5
-rw-r--r--drivers/memory/omap-gpmc.c143
-rw-r--r--drivers/mtd/nand/omap2.c134
-rw-r--r--include/linux/platform_data/mtd-nand-omap2.h3
4 files changed, 153 insertions, 132 deletions
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 04e6998c1529..f6ac027f3c3b 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -97,10 +97,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
97 gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT); 97 gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
98 98
99 memset(&s, 0, sizeof(struct gpmc_settings)); 99 memset(&s, 0, sizeof(struct gpmc_settings));
100 if (gpmc_nand_data->of_node) 100 gpmc_set_legacy(gpmc_nand_data, &s);
101 gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
102 else
103 gpmc_set_legacy(gpmc_nand_data, &s);
104 101
105 s.device_nand = true; 102 s.device_nand = true;
106 103
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index e28d6bc2500a..8dc6e3b1c44a 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -30,7 +30,6 @@
30#include <linux/of_device.h> 30#include <linux/of_device.h>
31#include <linux/of_platform.h> 31#include <linux/of_platform.h>
32#include <linux/omap-gpmc.h> 32#include <linux/omap-gpmc.h>
33#include <linux/mtd/nand.h>
34#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
35 34
36#include <linux/platform_data/mtd-nand-omap2.h> 35#include <linux/platform_data/mtd-nand-omap2.h>
@@ -1852,105 +1851,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
1852 of_property_read_bool(np, "gpmc,time-para-granularity"); 1851 of_property_read_bool(np, "gpmc,time-para-granularity");
1853} 1852}
1854 1853
1855#if IS_ENABLED(CONFIG_MTD_NAND)
1856
1857static const char * const nand_xfer_types[] = {
1858 [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
1859 [NAND_OMAP_POLLED] = "polled",
1860 [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
1861 [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
1862};
1863
1864static int gpmc_probe_nand_child(struct platform_device *pdev,
1865 struct device_node *child)
1866{
1867 u32 val;
1868 const char *s;
1869 struct gpmc_timings gpmc_t;
1870 struct omap_nand_platform_data *gpmc_nand_data;
1871
1872 if (of_property_read_u32(child, "reg", &val) < 0) {
1873 dev_err(&pdev->dev, "%s has no 'reg' property\n",
1874 child->full_name);
1875 return -ENODEV;
1876 }
1877
1878 gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
1879 GFP_KERNEL);
1880 if (!gpmc_nand_data)
1881 return -ENOMEM;
1882
1883 gpmc_nand_data->cs = val;
1884 gpmc_nand_data->of_node = child;
1885
1886 /* Detect availability of ELM module */
1887 gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
1888 if (gpmc_nand_data->elm_of_node == NULL)
1889 gpmc_nand_data->elm_of_node =
1890 of_parse_phandle(child, "elm_id", 0);
1891
1892 /* select ecc-scheme for NAND */
1893 if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
1894 pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
1895 return -ENODEV;
1896 }
1897
1898 if (!strcmp(s, "sw"))
1899 gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
1900 else if (!strcmp(s, "ham1") ||
1901 !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
1902 gpmc_nand_data->ecc_opt =
1903 OMAP_ECC_HAM1_CODE_HW;
1904 else if (!strcmp(s, "bch4"))
1905 if (gpmc_nand_data->elm_of_node)
1906 gpmc_nand_data->ecc_opt =
1907 OMAP_ECC_BCH4_CODE_HW;
1908 else
1909 gpmc_nand_data->ecc_opt =
1910 OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
1911 else if (!strcmp(s, "bch8"))
1912 if (gpmc_nand_data->elm_of_node)
1913 gpmc_nand_data->ecc_opt =
1914 OMAP_ECC_BCH8_CODE_HW;
1915 else
1916 gpmc_nand_data->ecc_opt =
1917 OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
1918 else if (!strcmp(s, "bch16"))
1919 if (gpmc_nand_data->elm_of_node)
1920 gpmc_nand_data->ecc_opt =
1921 OMAP_ECC_BCH16_CODE_HW;
1922 else
1923 pr_err("%s: BCH16 requires ELM support\n", __func__);
1924 else
1925 pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
1926
1927 /* select data transfer mode for NAND controller */
1928 if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
1929 for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
1930 if (!strcasecmp(s, nand_xfer_types[val])) {
1931 gpmc_nand_data->xfer_type = val;
1932 break;
1933 }
1934
1935 gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child);
1936
1937 val = of_get_nand_bus_width(child);
1938 if (val == 16)
1939 gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
1940
1941 gpmc_read_timings_dt(child, &gpmc_t);
1942 gpmc_nand_init(gpmc_nand_data, &gpmc_t);
1943
1944 return 0;
1945}
1946#else
1947static int gpmc_probe_nand_child(struct platform_device *pdev,
1948 struct device_node *child)
1949{
1950 return 0;
1951}
1952#endif
1953
1954#if IS_ENABLED(CONFIG_MTD_ONENAND) 1854#if IS_ENABLED(CONFIG_MTD_ONENAND)
1955static int gpmc_probe_onenand_child(struct platform_device *pdev, 1855static int gpmc_probe_onenand_child(struct platform_device *pdev,
1956 struct device_node *child) 1856 struct device_node *child)
@@ -2069,9 +1969,42 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
2069 goto err; 1969 goto err;
2070 } 1970 }
2071 1971
2072 ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); 1972 if (of_node_cmp(child->name, "nand") == 0) {
2073 if (ret < 0) 1973 /* Warn about older DT blobs with no compatible property */
2074 goto err; 1974 if (!of_property_read_bool(child, "compatible")) {
1975 dev_warn(&pdev->dev,
1976 "Incompatible NAND node: missing compatible");
1977 ret = -EINVAL;
1978 goto err;
1979 }
1980 }
1981
1982 if (of_device_is_compatible(child, "ti,omap2-nand")) {
1983 /* NAND specific setup */
1984 val = of_get_nand_bus_width(child);
1985 switch (val) {
1986 case 8:
1987 gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
1988 break;
1989 case 16:
1990 gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
1991 break;
1992 default:
1993 dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n",
1994 child->name);
1995 ret = -EINVAL;
1996 goto err;
1997 }
1998
1999 /* disable write protect */
2000 gpmc_configure(GPMC_CONFIG_WP, 0);
2001 gpmc_s.device_nand = true;
2002 } else {
2003 ret = of_property_read_u32(child, "bank-width",
2004 &gpmc_s.device_width);
2005 if (ret < 0)
2006 goto err;
2007 }
2075 2008
2076 gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings"); 2009 gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
2077 ret = gpmc_cs_program_settings(cs, &gpmc_s); 2010 ret = gpmc_cs_program_settings(cs, &gpmc_s);
@@ -2155,9 +2088,7 @@ static int gpmc_probe_dt(struct platform_device *pdev)
2155 if (!child->name) 2088 if (!child->name)
2156 continue; 2089 continue;
2157 2090
2158 if (of_node_cmp(child->name, "nand") == 0) 2091 if (of_node_cmp(child->name, "onenand") == 0)
2159 ret = gpmc_probe_nand_child(pdev, child);
2160 else if (of_node_cmp(child->name, "onenand") == 0)
2161 ret = gpmc_probe_onenand_child(pdev, child); 2092 ret = gpmc_probe_onenand_child(pdev, child);
2162 else 2093 else
2163 ret = gpmc_probe_generic_child(pdev, child); 2094 ret = gpmc_probe_generic_child(pdev, child);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 7e4e263c7d9c..35b8f3359c17 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/of_mtd.h>
27 28
28#include <linux/mtd/nand_bch.h> 29#include <linux/mtd/nand_bch.h>
29#include <linux/platform_data/elm.h> 30#include <linux/platform_data/elm.h>
@@ -176,11 +177,11 @@ struct omap_nand_info {
176 /* Interface to GPMC */ 177 /* Interface to GPMC */
177 struct gpmc_nand_regs reg; 178 struct gpmc_nand_regs reg;
178 struct gpmc_nand_ops *ops; 179 struct gpmc_nand_ops *ops;
180 bool flash_bbt;
179 /* generated at runtime depending on ECC algorithm and layout selected */ 181 /* generated at runtime depending on ECC algorithm and layout selected */
180 struct nand_ecclayout oobinfo; 182 struct nand_ecclayout oobinfo;
181 /* fields specific for BCHx_HW ECC scheme */ 183 /* fields specific for BCHx_HW ECC scheme */
182 struct device *elm_dev; 184 struct device *elm_dev;
183 struct device_node *of_node;
184}; 185};
185 186
186static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd) 187static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1643,10 +1644,86 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
1643 return true; 1644 return true;
1644} 1645}
1645 1646
1647static const char * const nand_xfer_types[] = {
1648 [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
1649 [NAND_OMAP_POLLED] = "polled",
1650 [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
1651 [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
1652};
1653
1654static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
1655{
1656 struct device_node *child = dev->of_node;
1657 int i;
1658 const char *s;
1659 u32 cs;
1660
1661 if (of_property_read_u32(child, "reg", &cs) < 0) {
1662 dev_err(dev, "reg not found in DT\n");
1663 return -EINVAL;
1664 }
1665
1666 info->gpmc_cs = cs;
1667
1668 /* detect availability of ELM module. Won't be present pre-OMAP4 */
1669 info->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
1670 if (!info->elm_of_node)
1671 dev_dbg(dev, "ti,elm-id not in DT\n");
1672
1673 /* select ecc-scheme for NAND */
1674 if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
1675 dev_err(dev, "ti,nand-ecc-opt not found\n");
1676 return -EINVAL;
1677 }
1678
1679 if (!strcmp(s, "sw")) {
1680 info->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
1681 } else if (!strcmp(s, "ham1") ||
1682 !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) {
1683 info->ecc_opt = OMAP_ECC_HAM1_CODE_HW;
1684 } else if (!strcmp(s, "bch4")) {
1685 if (info->elm_of_node)
1686 info->ecc_opt = OMAP_ECC_BCH4_CODE_HW;
1687 else
1688 info->ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
1689 } else if (!strcmp(s, "bch8")) {
1690 if (info->elm_of_node)
1691 info->ecc_opt = OMAP_ECC_BCH8_CODE_HW;
1692 else
1693 info->ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
1694 } else if (!strcmp(s, "bch16")) {
1695 info->ecc_opt = OMAP_ECC_BCH16_CODE_HW;
1696 } else {
1697 dev_err(dev, "unrecognized value for ti,nand-ecc-opt\n");
1698 return -EINVAL;
1699 }
1700
1701 /* select data transfer mode */
1702 if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) {
1703 for (i = 0; i < ARRAY_SIZE(nand_xfer_types); i++) {
1704 if (!strcasecmp(s, nand_xfer_types[i])) {
1705 info->xfer_type = i;
1706 goto next;
1707 }
1708 }
1709
1710 dev_err(dev, "unrecognized value for ti,nand-xfer-type\n");
1711 return -EINVAL;
1712 }
1713
1714next:
1715 of_get_nand_on_flash_bbt(child);
1716
1717 if (of_get_nand_bus_width(child) == 16)
1718 info->devsize = NAND_BUSWIDTH_16;
1719
1720 return 0;
1721}
1722
1646static int omap_nand_probe(struct platform_device *pdev) 1723static int omap_nand_probe(struct platform_device *pdev)
1647{ 1724{
1648 struct omap_nand_info *info; 1725 struct omap_nand_info *info;
1649 struct omap_nand_platform_data *pdata; 1726 struct omap_nand_platform_data *pdata = NULL;
1650 struct mtd_info *mtd; 1727 struct mtd_info *mtd;
1651 struct nand_chip *nand_chip; 1728 struct nand_chip *nand_chip;
1652 struct nand_ecclayout *ecclayout; 1729 struct nand_ecclayout *ecclayout;
@@ -1656,39 +1733,47 @@ static int omap_nand_probe(struct platform_device *pdev)
1656 unsigned sig; 1733 unsigned sig;
1657 unsigned oob_index; 1734 unsigned oob_index;
1658 struct resource *res; 1735 struct resource *res;
1659 1736 struct device *dev = &pdev->dev;
1660 pdata = dev_get_platdata(&pdev->dev);
1661 if (pdata == NULL) {
1662 dev_err(&pdev->dev, "platform data missing\n");
1663 return -ENODEV;
1664 }
1665 1737
1666 info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info), 1738 info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
1667 GFP_KERNEL); 1739 GFP_KERNEL);
1668 if (!info) 1740 if (!info)
1669 return -ENOMEM; 1741 return -ENOMEM;
1670 1742
1671 platform_set_drvdata(pdev, info); 1743 info->pdev = pdev;
1672 1744
1745 if (dev->of_node) {
1746 if (omap_get_dt_info(dev, info))
1747 return -EINVAL;
1748 } else {
1749 pdata = dev_get_platdata(&pdev->dev);
1750 if (!pdata) {
1751 dev_err(&pdev->dev, "platform data missing\n");
1752 return -EINVAL;
1753 }
1754
1755 info->gpmc_cs = pdata->cs;
1756 info->reg = pdata->reg;
1757 info->ecc_opt = pdata->ecc_opt;
1758 info->dev_ready = pdata->dev_ready;
1759 info->xfer_type = pdata->xfer_type;
1760 info->devsize = pdata->devsize;
1761 info->elm_of_node = pdata->elm_of_node;
1762 info->flash_bbt = pdata->flash_bbt;
1763 }
1764
1765 platform_set_drvdata(pdev, info);
1673 info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs); 1766 info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
1674 if (!info->ops) { 1767 if (!info->ops) {
1675 dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n"); 1768 dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
1676 return -ENODEV; 1769 return -ENODEV;
1677 } 1770 }
1678 info->pdev = pdev;
1679 info->gpmc_cs = pdata->cs;
1680 info->of_node = pdata->of_node;
1681 info->ecc_opt = pdata->ecc_opt;
1682 info->dev_ready = pdata->dev_ready;
1683 info->xfer_type = pdata->xfer_type;
1684 info->devsize = pdata->devsize;
1685 info->elm_of_node = pdata->elm_of_node;
1686 1771
1687 nand_chip = &info->nand; 1772 nand_chip = &info->nand;
1688 mtd = nand_to_mtd(nand_chip); 1773 mtd = nand_to_mtd(nand_chip);
1689 mtd->dev.parent = &pdev->dev; 1774 mtd->dev.parent = &pdev->dev;
1690 nand_chip->ecc.priv = NULL; 1775 nand_chip->ecc.priv = NULL;
1691 nand_set_flash_node(nand_chip, pdata->of_node); 1776 nand_set_flash_node(nand_chip, dev->of_node);
1692 1777
1693 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1778 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1694 nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); 1779 nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res);
@@ -1717,7 +1802,7 @@ static int omap_nand_probe(struct platform_device *pdev)
1717 nand_chip->chip_delay = 50; 1802 nand_chip->chip_delay = 50;
1718 } 1803 }
1719 1804
1720 if (pdata->flash_bbt) 1805 if (info->flash_bbt)
1721 nand_chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; 1806 nand_chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
1722 else 1807 else
1723 nand_chip->options |= NAND_SKIP_BBTSCAN; 1808 nand_chip->options |= NAND_SKIP_BBTSCAN;
@@ -2035,7 +2120,10 @@ scan_tail:
2035 goto return_error; 2120 goto return_error;
2036 } 2121 }
2037 2122
2038 mtd_device_register(mtd, pdata->parts, pdata->nr_parts); 2123 if (dev->of_node)
2124 mtd_device_register(mtd, NULL, 0);
2125 else
2126 mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
2039 2127
2040 platform_set_drvdata(pdev, mtd); 2128 platform_set_drvdata(pdev, mtd);
2041 2129
@@ -2066,11 +2154,17 @@ static int omap_nand_remove(struct platform_device *pdev)
2066 return 0; 2154 return 0;
2067} 2155}
2068 2156
2157static const struct of_device_id omap_nand_ids[] = {
2158 { .compatible = "ti,omap2-nand", },
2159 {},
2160};
2161
2069static struct platform_driver omap_nand_driver = { 2162static struct platform_driver omap_nand_driver = {
2070 .probe = omap_nand_probe, 2163 .probe = omap_nand_probe,
2071 .remove = omap_nand_remove, 2164 .remove = omap_nand_remove,
2072 .driver = { 2165 .driver = {
2073 .name = DRIVER_NAME, 2166 .name = DRIVER_NAME,
2167 .of_match_table = of_match_ptr(omap_nand_ids),
2074 }, 2168 },
2075}; 2169};
2076 2170
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index a067f581e938..ff27e5a77e03 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -76,11 +76,10 @@ struct omap_nand_platform_data {
76 int devsize; 76 int devsize;
77 enum omap_ecc ecc_opt; 77 enum omap_ecc ecc_opt;
78 78
79 /* for passing the partitions */
80 struct device_node *of_node;
81 struct device_node *elm_of_node; 79 struct device_node *elm_of_node;
82 80
83 /* deprecated */ 81 /* deprecated */
84 struct gpmc_nand_regs reg; 82 struct gpmc_nand_regs reg;
83 struct device_node *of_node;
85}; 84};
86#endif 85#endif