.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * apb_timer.c: Driver for Langwell APB timers |
---|
3 | 4 | * |
---|
4 | 5 | * (C) Copyright 2009 Intel Corporation |
---|
5 | 6 | * Author: Jacob Pan (jacob.jun.pan@intel.com) |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or |
---|
8 | | - * modify it under the terms of the GNU General Public License |
---|
9 | | - * as published by the Free Software Foundation; version 2 |
---|
10 | | - * of the License. |
---|
11 | 7 | * |
---|
12 | 8 | * Note: |
---|
13 | 9 | * Langwell is the south complex of Intel Moorestown MID platform. There are |
---|
.. | .. |
---|
99 | 95 | printk(KERN_WARNING "No timer base from SFI, use default\n"); |
---|
100 | 96 | apbt_address = APBT_DEFAULT_BASE; |
---|
101 | 97 | } |
---|
102 | | - apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE); |
---|
| 98 | + apbt_virt_address = ioremap(apbt_address, APBT_MMAP_SIZE); |
---|
103 | 99 | if (!apbt_virt_address) { |
---|
104 | 100 | pr_debug("Failed mapping APBT phy address at %lu\n",\ |
---|
105 | 101 | (unsigned long)apbt_address); |
---|
.. | .. |
---|
348 | 344 | apbt_clear_mapping(); |
---|
349 | 345 | apb_timer_block_enabled = 0; |
---|
350 | 346 | panic("failed to enable APB timer\n"); |
---|
351 | | -} |
---|
352 | | - |
---|
353 | | -/* called before apb_timer_enable, use early map */ |
---|
354 | | -unsigned long apbt_quick_calibrate(void) |
---|
355 | | -{ |
---|
356 | | - int i, scale; |
---|
357 | | - u64 old, new; |
---|
358 | | - u64 t1, t2; |
---|
359 | | - unsigned long khz = 0; |
---|
360 | | - u32 loop, shift; |
---|
361 | | - |
---|
362 | | - apbt_set_mapping(); |
---|
363 | | - dw_apb_clocksource_start(clocksource_apbt); |
---|
364 | | - |
---|
365 | | - /* check if the timer can count down, otherwise return */ |
---|
366 | | - old = dw_apb_clocksource_read(clocksource_apbt); |
---|
367 | | - i = 10000; |
---|
368 | | - while (--i) { |
---|
369 | | - if (old != dw_apb_clocksource_read(clocksource_apbt)) |
---|
370 | | - break; |
---|
371 | | - } |
---|
372 | | - if (!i) |
---|
373 | | - goto failed; |
---|
374 | | - |
---|
375 | | - /* count 16 ms */ |
---|
376 | | - loop = (apbt_freq / 1000) << 4; |
---|
377 | | - |
---|
378 | | - /* restart the timer to ensure it won't get to 0 in the calibration */ |
---|
379 | | - dw_apb_clocksource_start(clocksource_apbt); |
---|
380 | | - |
---|
381 | | - old = dw_apb_clocksource_read(clocksource_apbt); |
---|
382 | | - old += loop; |
---|
383 | | - |
---|
384 | | - t1 = rdtsc(); |
---|
385 | | - |
---|
386 | | - do { |
---|
387 | | - new = dw_apb_clocksource_read(clocksource_apbt); |
---|
388 | | - } while (new < old); |
---|
389 | | - |
---|
390 | | - t2 = rdtsc(); |
---|
391 | | - |
---|
392 | | - shift = 5; |
---|
393 | | - if (unlikely(loop >> shift == 0)) { |
---|
394 | | - printk(KERN_INFO |
---|
395 | | - "APBT TSC calibration failed, not enough resolution\n"); |
---|
396 | | - return 0; |
---|
397 | | - } |
---|
398 | | - scale = (int)div_u64((t2 - t1), loop >> shift); |
---|
399 | | - khz = (scale * (apbt_freq / 1000)) >> shift; |
---|
400 | | - printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz); |
---|
401 | | - return khz; |
---|
402 | | -failed: |
---|
403 | | - return 0; |
---|
404 | 347 | } |
---|