summaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorLadislav Michl <ladis@linux-mips.org>2018-01-12 08:17:25 -0500
committerBoris Brezillon <boris.brezillon@free-electrons.com>2018-01-12 10:41:15 -0500
commita758f50f10cfcf863f95372ff52e0d8d22fda9ba (patch)
tree294a2badeec6d690b68db82d8dbd29637c6edec7 /drivers/memory
parentbdaca9345d41fd9420995469d27603ea62054691 (diff)
mtd: onenand: omap2: Configure driver from DT
Move away from platform data configuration and use pure DT approach. Use generic probe function to deal with OneNAND node and remove now useless gpmc_probe_onenand_child function. Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c Signed-off-by: Ladislav Michl <ladis@linux-mips.org> Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Tony Lindgren <tony@atomide.com> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi> Acked-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/omap-gpmc.c158
1 files changed, 117 insertions, 41 deletions
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 0e30ee1c8677..90a66b3f7ae1 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -32,7 +32,6 @@
32#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
33 33
34#include <linux/platform_data/mtd-nand-omap2.h> 34#include <linux/platform_data/mtd-nand-omap2.h>
35#include <linux/platform_data/mtd-onenand-omap2.h>
36 35
37#include <asm/mach-types.h> 36#include <asm/mach-types.h>
38 37
@@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
1138} 1137}
1139EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops); 1138EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
1140 1139
1140static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
1141 struct gpmc_settings *s,
1142 int freq, int latency)
1143{
1144 struct gpmc_device_timings dev_t;
1145 const int t_cer = 15;
1146 const int t_avdp = 12;
1147 const int t_cez = 20; /* max of t_cez, t_oez */
1148 const int t_wpl = 40;
1149 const int t_wph = 30;
1150 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
1151
1152 switch (freq) {
1153 case 104:
1154 min_gpmc_clk_period = 9600; /* 104 MHz */
1155 t_ces = 3;
1156 t_avds = 4;
1157 t_avdh = 2;
1158 t_ach = 3;
1159 t_aavdh = 6;
1160 t_rdyo = 6;
1161 break;
1162 case 83:
1163 min_gpmc_clk_period = 12000; /* 83 MHz */
1164 t_ces = 5;
1165 t_avds = 4;
1166 t_avdh = 2;
1167 t_ach = 6;
1168 t_aavdh = 6;
1169 t_rdyo = 9;
1170 break;
1171 case 66:
1172 min_gpmc_clk_period = 15000; /* 66 MHz */
1173 t_ces = 6;
1174 t_avds = 5;
1175 t_avdh = 2;
1176 t_ach = 6;
1177 t_aavdh = 6;
1178 t_rdyo = 11;
1179 break;
1180 default:
1181 min_gpmc_clk_period = 18500; /* 54 MHz */
1182 t_ces = 7;
1183 t_avds = 7;
1184 t_avdh = 7;
1185 t_ach = 9;
1186 t_aavdh = 7;
1187 t_rdyo = 15;
1188 break;
1189 }
1190
1191 /* Set synchronous read timings */
1192 memset(&dev_t, 0, sizeof(dev_t));
1193
1194 if (!s->sync_write) {
1195 dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
1196 dev_t.t_wpl = t_wpl * 1000;
1197 dev_t.t_wph = t_wph * 1000;
1198 dev_t.t_aavdh = t_aavdh * 1000;
1199 }
1200 dev_t.ce_xdelay = true;
1201 dev_t.avd_xdelay = true;
1202 dev_t.oe_xdelay = true;
1203 dev_t.we_xdelay = true;
1204 dev_t.clk = min_gpmc_clk_period;
1205 dev_t.t_bacc = dev_t.clk;
1206 dev_t.t_ces = t_ces * 1000;
1207 dev_t.t_avds = t_avds * 1000;
1208 dev_t.t_avdh = t_avdh * 1000;
1209 dev_t.t_ach = t_ach * 1000;
1210 dev_t.cyc_iaa = (latency + 1);
1211 dev_t.t_cez_r = t_cez * 1000;
1212 dev_t.t_cez_w = dev_t.t_cez_r;
1213 dev_t.cyc_aavdh_oe = 1;
1214 dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
1215
1216 gpmc_calc_timings(t, s, &dev_t);
1217}
1218
1219int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
1220 int latency,
1221 struct gpmc_onenand_info *info)
1222{
1223 int ret;
1224 struct gpmc_timings gpmc_t;
1225 struct gpmc_settings gpmc_s;
1226
1227 gpmc_read_settings_dt(dev->of_node, &gpmc_s);
1228
1229 info->sync_read = gpmc_s.sync_read;
1230 info->sync_write = gpmc_s.sync_write;
1231 info->burst_len = gpmc_s.burst_len;
1232
1233 if (!gpmc_s.sync_read && !gpmc_s.sync_write)
1234 return 0;
1235
1236 gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
1237
1238 ret = gpmc_cs_program_settings(cs, &gpmc_s);
1239 if (ret < 0)
1240 return ret;
1241
1242 return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
1243}
1244EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
1245
1141int gpmc_get_client_irq(unsigned irq_config) 1246int gpmc_get_client_irq(unsigned irq_config)
1142{ 1247{
1143 if (!gpmc_irq_domain) { 1248 if (!gpmc_irq_domain) {
@@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
1916 of_property_read_bool(np, "gpmc,time-para-granularity"); 2021 of_property_read_bool(np, "gpmc,time-para-granularity");
1917} 2022}
1918 2023
1919#if IS_ENABLED(CONFIG_MTD_ONENAND)
1920static int gpmc_probe_onenand_child(struct platform_device *pdev,
1921 struct device_node *child)
1922{
1923 u32 val;
1924 struct omap_onenand_platform_data *gpmc_onenand_data;
1925
1926 if (of_property_read_u32(child, "reg", &val) < 0) {
1927 dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
1928 child);
1929 return -ENODEV;
1930 }
1931
1932 gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
1933 GFP_KERNEL);
1934 if (!gpmc_onenand_data)
1935 return -ENOMEM;
1936
1937 gpmc_onenand_data->cs = val;
1938 gpmc_onenand_data->of_node = child;
1939 gpmc_onenand_data->dma_channel = -1;
1940
1941 if (!of_property_read_u32(child, "dma-channel", &val))
1942 gpmc_onenand_data->dma_channel = val;
1943
1944 return gpmc_onenand_init(gpmc_onenand_data);
1945}
1946#else
1947static int gpmc_probe_onenand_child(struct platform_device *pdev,
1948 struct device_node *child)
1949{
1950 return 0;
1951}
1952#endif
1953
1954/** 2024/**
1955 * gpmc_probe_generic_child - configures the gpmc for a child device 2025 * gpmc_probe_generic_child - configures the gpmc for a child device
1956 * @pdev: pointer to gpmc platform device 2026 * @pdev: pointer to gpmc platform device
@@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
2053 } 2123 }
2054 } 2124 }
2055 2125
2126 if (of_node_cmp(child->name, "onenand") == 0) {
2127 /* Warn about older DT blobs with no compatible property */
2128 if (!of_property_read_bool(child, "compatible")) {
2129 dev_warn(&pdev->dev,
2130 "Incompatible OneNAND node: missing compatible");
2131 ret = -EINVAL;
2132 goto err;
2133 }
2134 }
2135
2056 if (of_device_is_compatible(child, "ti,omap2-nand")) { 2136 if (of_device_is_compatible(child, "ti,omap2-nand")) {
2057 /* NAND specific setup */ 2137 /* NAND specific setup */
2058 val = 8; 2138 val = 8;
@@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
2189 if (!child->name) 2269 if (!child->name)
2190 continue; 2270 continue;
2191 2271
2192 if (of_node_cmp(child->name, "onenand") == 0) 2272 ret = gpmc_probe_generic_child(pdev, child);
2193 ret = gpmc_probe_onenand_child(pdev, child);
2194 else
2195 ret = gpmc_probe_generic_child(pdev, child);
2196
2197 if (ret) { 2273 if (ret) {
2198 dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", 2274 dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
2199 child->name, ret); 2275 child->name, ret);