Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memory: ti-aemif: Store timings parameter in number of cycles - 1

The CS configuration register expects timings to be expressed in
'number of cycles - 1' but they are stored in ns in the struct
aemif_cs_data. So at init, the timings currently set are converted to ns
by aemif_get_hw_params(), updated with values from the device-tree
properties, and then converted back to 'number of cycles - 1' before
being applied.

Store the timings directly in 'number of cycles - 1' instead of
nanoseconds.
Perform the conversion from nanosecond during the device-tree parsing.
Remove aemif_cycles_to_nsec() as it isn't used anymore.

Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20241204094319.1050826-2-bastien.curutchet@bootlin.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

authored by

Bastien Curutchet and committed by
Krzysztof Kozlowski
1ec0fa90 40384c84

+79 -56
+79 -56
drivers/memory/ti-aemif.c
··· 82 82 /** 83 83 * struct aemif_cs_data: structure to hold cs parameters 84 84 * @cs: chip-select number 85 - * @wstrobe: write strobe width, ns 86 - * @rstrobe: read strobe width, ns 87 - * @wsetup: write setup width, ns 88 - * @whold: write hold width, ns 89 - * @rsetup: read setup width, ns 90 - * @rhold: read hold width, ns 91 - * @ta: minimum turn around time, ns 85 + * @wstrobe: write strobe width, number of cycles - 1 86 + * @rstrobe: read strobe width, number of cycles - 1 87 + * @wsetup: write setup width, number of cycles - 1 88 + * @whold: write hold width, number of cycles - 1 89 + * @rsetup: read setup width, number of cycles - 1 90 + * @rhold: read hold width, number of cycles - 1 91 + * @ta: minimum turn around time, number of cycles - 1 92 92 * @enable_ss: enable/disable select strobe mode 93 93 * @enable_ew: enable/disable extended wait mode 94 94 * @asize: width of the asynchronous device's data bus 95 95 */ 96 96 struct aemif_cs_data { 97 97 u8 cs; 98 - u16 wstrobe; 99 - u16 rstrobe; 100 - u8 wsetup; 101 - u8 whold; 102 - u8 rsetup; 103 - u8 rhold; 104 - u8 ta; 98 + u32 wstrobe; 99 + u32 rstrobe; 100 + u32 wsetup; 101 + u32 whold; 102 + u32 rsetup; 103 + u32 rhold; 104 + u32 ta; 105 105 u8 enable_ss; 106 106 u8 enable_ew; 107 107 u8 asize; ··· 175 175 struct aemif_device *aemif = platform_get_drvdata(pdev); 176 176 struct aemif_cs_data *data = &aemif->cs_data[csnum]; 177 177 int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; 178 - unsigned long clk_rate = aemif->clk_rate; 179 178 unsigned offset; 180 179 u32 set, val; 181 180 182 181 offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4; 183 182 184 - ta = aemif_calc_rate(pdev, data->ta, clk_rate, TA_MAX); 185 - rhold = aemif_calc_rate(pdev, data->rhold, clk_rate, RHOLD_MAX); 186 - rstrobe = aemif_calc_rate(pdev, data->rstrobe, clk_rate, RSTROBE_MAX); 187 - rsetup = aemif_calc_rate(pdev, data->rsetup, clk_rate, RSETUP_MAX); 188 - whold = aemif_calc_rate(pdev, data->whold, clk_rate, WHOLD_MAX); 189 - wstrobe = aemif_calc_rate(pdev, data->wstrobe, clk_rate, WSTROBE_MAX); 190 - wsetup = aemif_calc_rate(pdev, data->wsetup, clk_rate, WSETUP_MAX); 191 - 192 - if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 || 193 - whold < 0 || wstrobe < 0 || wsetup < 0) { 194 - dev_err(&pdev->dev, "%s: cannot get suitable timings\n", 195 - __func__); 196 - return -EINVAL; 197 - } 183 + ta = data->ta; 184 + rhold = data->rhold; 185 + rstrobe = data->rstrobe; 186 + rsetup = data->rsetup; 187 + whold = data->whold; 188 + wstrobe = data->wstrobe; 189 + wsetup = data->wsetup; 198 190 199 191 set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) | 200 192 WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup); ··· 205 213 return 0; 206 214 } 207 215 208 - static inline int aemif_cycles_to_nsec(int val, unsigned long clk_rate) 209 - { 210 - return ((val + 1) * NSEC_PER_MSEC) / clk_rate; 211 - } 212 - 213 216 /** 214 217 * aemif_get_hw_params - function to read hw register values 215 218 * @pdev: platform device to read for ··· 218 231 { 219 232 struct aemif_device *aemif = platform_get_drvdata(pdev); 220 233 struct aemif_cs_data *data = &aemif->cs_data[csnum]; 221 - unsigned long clk_rate = aemif->clk_rate; 222 234 u32 val, offset; 223 235 224 236 offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4; 225 237 val = readl(aemif->base + offset); 226 238 227 - data->ta = aemif_cycles_to_nsec(TA_VAL(val), clk_rate); 228 - data->rhold = aemif_cycles_to_nsec(RHOLD_VAL(val), clk_rate); 229 - data->rstrobe = aemif_cycles_to_nsec(RSTROBE_VAL(val), clk_rate); 230 - data->rsetup = aemif_cycles_to_nsec(RSETUP_VAL(val), clk_rate); 231 - data->whold = aemif_cycles_to_nsec(WHOLD_VAL(val), clk_rate); 232 - data->wstrobe = aemif_cycles_to_nsec(WSTROBE_VAL(val), clk_rate); 233 - data->wsetup = aemif_cycles_to_nsec(WSETUP_VAL(val), clk_rate); 239 + data->ta = TA_VAL(val); 240 + data->rhold = RHOLD_VAL(val); 241 + data->rstrobe = RSTROBE_VAL(val); 242 + data->rsetup = RSETUP_VAL(val); 243 + data->whold = WHOLD_VAL(val); 244 + data->wstrobe = WSTROBE_VAL(val); 245 + data->wsetup = WSETUP_VAL(val); 234 246 data->enable_ew = EW_VAL(val); 235 247 data->enable_ss = SSTROBE_VAL(val); 236 248 data->asize = val & ASIZE_MAX; ··· 247 261 struct device_node *np) 248 262 { 249 263 struct aemif_device *aemif = platform_get_drvdata(pdev); 264 + unsigned long clk_rate = aemif->clk_rate; 250 265 struct aemif_cs_data *data; 266 + int ret; 251 267 u32 cs; 252 268 u32 val; 253 269 ··· 275 287 aemif_get_hw_params(pdev, aemif->num_cs++); 276 288 277 289 /* override the values from device node */ 278 - if (!of_property_read_u32(np, "ti,cs-min-turnaround-ns", &val)) 279 - data->ta = val; 290 + if (!of_property_read_u32(np, "ti,cs-min-turnaround-ns", &val)) { 291 + ret = aemif_calc_rate(pdev, val, clk_rate, TA_MAX); 292 + if (ret < 0) 293 + return ret; 280 294 281 - if (!of_property_read_u32(np, "ti,cs-read-hold-ns", &val)) 282 - data->rhold = val; 295 + data->ta = ret; 296 + } 283 297 284 - if (!of_property_read_u32(np, "ti,cs-read-strobe-ns", &val)) 285 - data->rstrobe = val; 298 + if (!of_property_read_u32(np, "ti,cs-read-hold-ns", &val)) { 299 + ret = aemif_calc_rate(pdev, val, clk_rate, RHOLD_MAX); 300 + if (ret < 0) 301 + return ret; 286 302 287 - if (!of_property_read_u32(np, "ti,cs-read-setup-ns", &val)) 288 - data->rsetup = val; 303 + data->rhold = ret; 304 + } 289 305 290 - if (!of_property_read_u32(np, "ti,cs-write-hold-ns", &val)) 291 - data->whold = val; 306 + if (!of_property_read_u32(np, "ti,cs-read-strobe-ns", &val)) { 307 + ret = aemif_calc_rate(pdev, val, clk_rate, RSTROBE_MAX); 308 + if (ret < 0) 309 + return ret; 292 310 293 - if (!of_property_read_u32(np, "ti,cs-write-strobe-ns", &val)) 294 - data->wstrobe = val; 311 + data->rstrobe = ret; 312 + } 295 313 296 - if (!of_property_read_u32(np, "ti,cs-write-setup-ns", &val)) 297 - data->wsetup = val; 314 + if (!of_property_read_u32(np, "ti,cs-read-setup-ns", &val)) { 315 + ret = aemif_calc_rate(pdev, val, clk_rate, RSETUP_MAX); 316 + if (ret < 0) 317 + return ret; 318 + 319 + data->rsetup = ret; 320 + } 321 + 322 + if (!of_property_read_u32(np, "ti,cs-write-hold-ns", &val)) { 323 + ret = aemif_calc_rate(pdev, val, clk_rate, WHOLD_MAX); 324 + if (ret < 0) 325 + return ret; 326 + 327 + data->whold = ret; 328 + } 329 + 330 + if (!of_property_read_u32(np, "ti,cs-write-strobe-ns", &val)) { 331 + ret = aemif_calc_rate(pdev, val, clk_rate, WSTROBE_MAX); 332 + if (ret < 0) 333 + return ret; 334 + 335 + data->wstrobe = ret; 336 + } 337 + 338 + if (!of_property_read_u32(np, "ti,cs-write-setup-ns", &val)) { 339 + ret = aemif_calc_rate(pdev, val, clk_rate, WSETUP_MAX); 340 + if (ret < 0) 341 + return ret; 342 + 343 + data->wsetup = ret; 344 + } 298 345 299 346 if (!of_property_read_u32(np, "ti,cs-bus-width", &val)) 300 347 if (val == 16)