aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2016-11-28 10:17:56 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-14 22:02:45 -0400
commit1f2ca141ec53a9c43ea0852f013907d19c435986 (patch)
tree40f88c5aa8382c1e0e121b84b875e7c79874173a
parentb2b0f6ffd3f97953044e909ca311d2a580ae8575 (diff)
memory/atmel-ebi: Fix ns <-> cycles conversions
commit ee194289502a6901cc77dc9a893bf2afd351ac5e upstream. at91sam9_ebi_get_config() is incorrectly converting timings in clock cycles into timings in nanoseconds by multiplying the cycle values by the clk rate instead of the clk period. at91sam9_ebi_xslate_config() has the same problem for the tdf_ns -> tdf_cycles conversion. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reported-by: Chris Leahy <leahycm@gmail.com> Fixes: 6a4ec4cd0888 ("memory: add Atmel EBI (External Bus Interface) driver") Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/memory/atmel-ebi.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
index b5ed3bd082b5..e9ebc4f31d16 100644
--- a/drivers/memory/atmel-ebi.c
+++ b/drivers/memory/atmel-ebi.c
@@ -93,7 +93,7 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
93 struct at91_ebi_dev_config *conf) 93 struct at91_ebi_dev_config *conf)
94{ 94{
95 struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; 95 struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
96 unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); 96 unsigned int clk_period = NSEC_PER_SEC / clk_get_rate(ebid->ebi->clk);
97 struct at91sam9_ebi_dev_config *config = &conf->sam9; 97 struct at91sam9_ebi_dev_config *config = &conf->sam9;
98 struct at91sam9_smc_timings *timings = &config->timings; 98 struct at91sam9_smc_timings *timings = &config->timings;
99 unsigned int val; 99 unsigned int val;
@@ -102,43 +102,43 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
102 config->mode = val & ~AT91_SMC_TDF; 102 config->mode = val & ~AT91_SMC_TDF;
103 103
104 val = (val & AT91_SMC_TDF) >> 16; 104 val = (val & AT91_SMC_TDF) >> 16;
105 timings->tdf_ns = clk_rate * val; 105 timings->tdf_ns = clk_period * val;
106 106
107 regmap_fields_read(fields->setup, conf->cs, &val); 107 regmap_fields_read(fields->setup, conf->cs, &val);
108 timings->ncs_rd_setup_ns = (val >> 24) & 0x1f; 108 timings->ncs_rd_setup_ns = (val >> 24) & 0x1f;
109 timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128; 109 timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128;
110 timings->ncs_rd_setup_ns *= clk_rate; 110 timings->ncs_rd_setup_ns *= clk_period;
111 timings->nrd_setup_ns = (val >> 16) & 0x1f; 111 timings->nrd_setup_ns = (val >> 16) & 0x1f;
112 timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128; 112 timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128;
113 timings->nrd_setup_ns *= clk_rate; 113 timings->nrd_setup_ns *= clk_period;
114 timings->ncs_wr_setup_ns = (val >> 8) & 0x1f; 114 timings->ncs_wr_setup_ns = (val >> 8) & 0x1f;
115 timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128; 115 timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128;
116 timings->ncs_wr_setup_ns *= clk_rate; 116 timings->ncs_wr_setup_ns *= clk_period;
117 timings->nwe_setup_ns = val & 0x1f; 117 timings->nwe_setup_ns = val & 0x1f;
118 timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128; 118 timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128;
119 timings->nwe_setup_ns *= clk_rate; 119 timings->nwe_setup_ns *= clk_period;
120 120
121 regmap_fields_read(fields->pulse, conf->cs, &val); 121 regmap_fields_read(fields->pulse, conf->cs, &val);
122 timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f; 122 timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f;
123 timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256; 123 timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256;
124 timings->ncs_rd_pulse_ns *= clk_rate; 124 timings->ncs_rd_pulse_ns *= clk_period;
125 timings->nrd_pulse_ns = (val >> 16) & 0x3f; 125 timings->nrd_pulse_ns = (val >> 16) & 0x3f;
126 timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256; 126 timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256;
127 timings->nrd_pulse_ns *= clk_rate; 127 timings->nrd_pulse_ns *= clk_period;
128 timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f; 128 timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f;
129 timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256; 129 timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256;
130 timings->ncs_wr_pulse_ns *= clk_rate; 130 timings->ncs_wr_pulse_ns *= clk_period;
131 timings->nwe_pulse_ns = val & 0x3f; 131 timings->nwe_pulse_ns = val & 0x3f;
132 timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256; 132 timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256;
133 timings->nwe_pulse_ns *= clk_rate; 133 timings->nwe_pulse_ns *= clk_period;
134 134
135 regmap_fields_read(fields->cycle, conf->cs, &val); 135 regmap_fields_read(fields->cycle, conf->cs, &val);
136 timings->nrd_cycle_ns = (val >> 16) & 0x7f; 136 timings->nrd_cycle_ns = (val >> 16) & 0x7f;
137 timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256; 137 timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256;
138 timings->nrd_cycle_ns *= clk_rate; 138 timings->nrd_cycle_ns *= clk_period;
139 timings->nwe_cycle_ns = val & 0x7f; 139 timings->nwe_cycle_ns = val & 0x7f;
140 timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256; 140 timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256;
141 timings->nwe_cycle_ns *= clk_rate; 141 timings->nwe_cycle_ns *= clk_period;
142} 142}
143 143
144static int at91_xlate_timing(struct device_node *np, const char *prop, 144static int at91_xlate_timing(struct device_node *np, const char *prop,
@@ -334,6 +334,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
334 struct at91_ebi_dev_config *conf) 334 struct at91_ebi_dev_config *conf)
335{ 335{
336 unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); 336 unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
337 unsigned int clk_period = NSEC_PER_SEC / clk_rate;
337 struct at91sam9_ebi_dev_config *config = &conf->sam9; 338 struct at91sam9_ebi_dev_config *config = &conf->sam9;
338 struct at91sam9_smc_timings *timings = &config->timings; 339 struct at91sam9_smc_timings *timings = &config->timings;
339 struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; 340 struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
@@ -376,7 +377,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
376 val |= AT91SAM9_SMC_NWECYCLE(coded_val); 377 val |= AT91SAM9_SMC_NWECYCLE(coded_val);
377 regmap_fields_write(fields->cycle, conf->cs, val); 378 regmap_fields_write(fields->cycle, conf->cs, val);
378 379
379 val = DIV_ROUND_UP(timings->tdf_ns, clk_rate); 380 val = DIV_ROUND_UP(timings->tdf_ns, clk_period);
380 if (val > AT91_SMC_TDF_MAX) 381 if (val > AT91_SMC_TDF_MAX)
381 val = AT91_SMC_TDF_MAX; 382 val = AT91_SMC_TDF_MAX;
382 regmap_fields_write(fields->mode, conf->cs, 383 regmap_fields_write(fields->mode, conf->cs,