aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory/omap-gpmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memory/omap-gpmc.c')
-rw-r--r--drivers/memory/omap-gpmc.c143
1 files changed, 37 insertions, 106 deletions
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);