linux/arch/x86/platform/uv/uv_time.c
<<
>>
Prefs
   1/*
   2 * SGI RTC clock/timer routines.
   3 *
   4 *  This program is free software; you can redistribute it and/or modify
   5 *  it under the terms of the GNU General Public License as published by
   6 *  the Free Software Foundation; either version 2 of the License, or
   7 *  (at your option) any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *  GNU General Public License for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License
  15 *  along with this program; if not, write to the Free Software
  16 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  17 *
  18 *  Copyright (c) 2009-2013 Silicon Graphics, Inc.  All Rights Reserved.
  19 *  Copyright (c) Dimitri Sivanich
  20 */
  21#include <linux/clockchips.h>
  22#include <linux/slab.h>
  23
  24#include <asm/uv/uv_mmrs.h>
  25#include <asm/uv/uv_hub.h>
  26#include <asm/uv/bios.h>
  27#include <asm/uv/uv.h>
  28#include <asm/apic.h>
  29#include <asm/cpu.h>
  30
  31#define RTC_NAME                "sgi_rtc"
  32
  33static u64 uv_read_rtc(struct clocksource *cs);
  34static int uv_rtc_next_event(unsigned long, struct clock_event_device *);
  35static int uv_rtc_shutdown(struct clock_event_device *evt);
  36
  37static struct clocksource clocksource_uv = {
  38        .name           = RTC_NAME,
  39        .rating         = 299,
  40        .read           = uv_read_rtc,
  41        .mask           = (u64)UVH_RTC_REAL_TIME_CLOCK_MASK,
  42        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
  43};
  44
  45static struct clock_event_device clock_event_device_uv = {
  46        .name                   = RTC_NAME,
  47        .features               = CLOCK_EVT_FEAT_ONESHOT,
  48        .shift                  = 20,
  49        .rating                 = 400,
  50        .irq                    = -1,
  51        .set_next_event         = uv_rtc_next_event,
  52        .set_state_shutdown     = uv_rtc_shutdown,
  53        .event_handler          = NULL,
  54};
  55
  56static DEFINE_PER_CPU(struct clock_event_device, cpu_ced);
  57
  58/* There is one of these allocated per node */
  59struct uv_rtc_timer_head {
  60        spinlock_t      lock;
  61        /* next cpu waiting for timer, local node relative: */
  62        int             next_cpu;
  63        /* number of cpus on this node: */
  64        int             ncpus;
  65        struct {
  66                int     lcpu;           /* systemwide logical cpu number */
  67                u64     expires;        /* next timer expiration for this cpu */
  68        } cpu[1];
  69};
  70
  71/*
  72 * Access to uv_rtc_timer_head via blade id.
  73 */
  74static struct uv_rtc_timer_head         **blade_info __read_mostly;
  75
  76static int                              uv_rtc_evt_enable;
  77
  78/*
  79 * Hardware interface routines
  80 */
  81
  82/* Send IPIs to another node */
  83static void uv_rtc_send_IPI(int cpu)
  84{
  85        unsigned long apicid, val;
  86        int pnode;
  87
  88        apicid = cpu_physical_id(cpu);
  89        pnode = uv_apicid_to_pnode(apicid);
  90        apicid |= uv_apicid_hibits;
  91        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
  92              (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
  93              (X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
  94
  95        uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
  96}
  97
  98/* Check for an RTC interrupt pending */
  99static int uv_intr_pending(int pnode)
 100{
 101        if (is_uv1_hub())
 102                return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) &
 103                        UV1H_EVENT_OCCURRED0_RTC1_MASK;
 104        else if (is_uvx_hub())
 105                return uv_read_global_mmr64(pnode, UVXH_EVENT_OCCURRED2) &
 106                        UVXH_EVENT_OCCURRED2_RTC_1_MASK;
 107        return 0;
 108}
 109
 110/* Setup interrupt and return non-zero if early expiration occurred. */
 111static int uv_setup_intr(int cpu, u64 expires)
 112{
 113        u64 val;
 114        unsigned long apicid = cpu_physical_id(cpu) | uv_apicid_hibits;
 115        int pnode = uv_cpu_to_pnode(cpu);
 116
 117        uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
 118                UVH_RTC1_INT_CONFIG_M_MASK);
 119        uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L);
 120
 121        if (is_uv1_hub())
 122                uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
 123                                UV1H_EVENT_OCCURRED0_RTC1_MASK);
 124        else
 125                uv_write_global_mmr64(pnode, UVXH_EVENT_OCCURRED2_ALIAS,
 126                                UVXH_EVENT_OCCURRED2_RTC_1_MASK);
 127
 128        val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
 129                ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
 130
 131        /* Set configuration */
 132        uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val);
 133        /* Initialize comparator value */
 134        uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires);
 135
 136        if (uv_read_rtc(NULL) <= expires)
 137                return 0;
 138
 139        return !uv_intr_pending(pnode);
 140}
 141
 142/*
 143 * Per-cpu timer tracking routines
 144 */
 145
 146static __init void uv_rtc_deallocate_timers(void)
 147{
 148        int bid;
 149
 150        for_each_possible_blade(bid) {
 151                kfree(blade_info[bid]);
 152        }
 153        kfree(blade_info);
 154}
 155
 156/* Allocate per-node list of cpu timer expiration times. */
 157static __init int uv_rtc_allocate_timers(void)
 158{
 159        int cpu;
 160
 161        blade_info = kzalloc(uv_possible_blades * sizeof(void *), GFP_KERNEL);
 162        if (!blade_info)
 163                return -ENOMEM;
 164
 165        for_each_present_cpu(cpu) {
 166                int nid = cpu_to_node(cpu);
 167                int bid = uv_cpu_to_blade_id(cpu);
 168                int bcpu = uv_cpu_blade_processor_id(cpu);
 169                struct uv_rtc_timer_head *head = blade_info[bid];
 170
 171                if (!head) {
 172                        head = kmalloc_node(sizeof(struct uv_rtc_timer_head) +
 173                                (uv_blade_nr_possible_cpus(bid) *
 174                                        2 * sizeof(u64)),
 175                                GFP_KERNEL, nid);
 176                        if (!head) {
 177                                uv_rtc_deallocate_timers();
 178                                return -ENOMEM;
 179                        }
 180                        spin_lock_init(&head->lock);
 181                        head->ncpus = uv_blade_nr_possible_cpus(bid);
 182                        head->next_cpu = -1;
 183                        blade_info[bid] = head;
 184                }
 185
 186                head->cpu[bcpu].lcpu = cpu;
 187                head->cpu[bcpu].expires = ULLONG_MAX;
 188        }
 189
 190        return 0;
 191}
 192
 193/* Find and set the next expiring timer.  */
 194static void uv_rtc_find_next_timer(struct uv_rtc_timer_head *head, int pnode)
 195{
 196        u64 lowest = ULLONG_MAX;
 197        int c, bcpu = -1;
 198
 199        head->next_cpu = -1;
 200        for (c = 0; c < head->ncpus; c++) {
 201                u64 exp = head->cpu[c].expires;
 202                if (exp < lowest) {
 203                        bcpu = c;
 204                        lowest = exp;
 205                }
 206        }
 207        if (bcpu >= 0) {
 208                head->next_cpu = bcpu;
 209                c = head->cpu[bcpu].lcpu;
 210                if (uv_setup_intr(c, lowest))
 211                        /* If we didn't set it up in time, trigger */
 212                        uv_rtc_send_IPI(c);
 213        } else {
 214                uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
 215                        UVH_RTC1_INT_CONFIG_M_MASK);
 216        }
 217}
 218
 219/*
 220 * Set expiration time for current cpu.
 221 *
 222 * Returns 1 if we missed the expiration time.
 223 */
 224static int uv_rtc_set_timer(int cpu, u64 expires)
 225{
 226        int pnode = uv_cpu_to_pnode(cpu);
 227        int bid = uv_cpu_to_blade_id(cpu);
 228        struct uv_rtc_timer_head *head = blade_info[bid];
 229        int bcpu = uv_cpu_blade_processor_id(cpu);
 230        u64 *t = &head->cpu[bcpu].expires;
 231        unsigned long flags;
 232        int next_cpu;
 233
 234        spin_lock_irqsave(&head->lock, flags);
 235
 236        next_cpu = head->next_cpu;
 237        *t = expires;
 238
 239        /* Will this one be next to go off? */
 240        if (next_cpu < 0 || bcpu == next_cpu ||
 241                        expires < head->cpu[next_cpu].expires) {
 242                head->next_cpu = bcpu;
 243                if (uv_setup_intr(cpu, expires)) {
 244                        *t = ULLONG_MAX;
 245                        uv_rtc_find_next_timer(head, pnode);
 246                        spin_unlock_irqrestore(&head->lock, flags);
 247                        return -ETIME;
 248                }
 249        }
 250
 251        spin_unlock_irqrestore(&head->lock, flags);
 252        return 0;
 253}
 254
 255/*
 256 * Unset expiration time for current cpu.
 257 *
 258 * Returns 1 if this timer was pending.
 259 */
 260static int uv_rtc_unset_timer(int cpu, int force)
 261{
 262        int pnode = uv_cpu_to_pnode(cpu);
 263        int bid = uv_cpu_to_blade_id(cpu);
 264        struct uv_rtc_timer_head *head = blade_info[bid];
 265        int bcpu = uv_cpu_blade_processor_id(cpu);
 266        u64 *t = &head->cpu[bcpu].expires;
 267        unsigned long flags;
 268        int rc = 0;
 269
 270        spin_lock_irqsave(&head->lock, flags);
 271
 272        if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force)
 273                rc = 1;
 274
 275        if (rc) {
 276                *t = ULLONG_MAX;
 277                /* Was the hardware setup for this timer? */
 278                if (head->next_cpu == bcpu)
 279                        uv_rtc_find_next_timer(head, pnode);
 280        }
 281
 282        spin_unlock_irqrestore(&head->lock, flags);
 283
 284        return rc;
 285}
 286
 287
 288/*
 289 * Kernel interface routines.
 290 */
 291
 292/*
 293 * Read the RTC.
 294 *
 295 * Starting with HUB rev 2.0, the UV RTC register is replicated across all
 296 * cachelines of it's own page.  This allows faster simultaneous reads
 297 * from a given socket.
 298 */
 299static u64 uv_read_rtc(struct clocksource *cs)
 300{
 301        unsigned long offset;
 302
 303        if (uv_get_min_hub_revision_id() == 1)
 304                offset = 0;
 305        else
 306                offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;
 307
 308        return (u64)uv_read_local_mmr(UVH_RTC | offset);
 309}
 310
 311/*
 312 * Program the next event, relative to now
 313 */
 314static int uv_rtc_next_event(unsigned long delta,
 315                             struct clock_event_device *ced)
 316{
 317        int ced_cpu = cpumask_first(ced->cpumask);
 318
 319        return uv_rtc_set_timer(ced_cpu, delta + uv_read_rtc(NULL));
 320}
 321
 322/*
 323 * Shutdown the RTC timer
 324 */
 325static int uv_rtc_shutdown(struct clock_event_device *evt)
 326{
 327        int ced_cpu = cpumask_first(evt->cpumask);
 328
 329        uv_rtc_unset_timer(ced_cpu, 1);
 330        return 0;
 331}
 332
 333static void uv_rtc_interrupt(void)
 334{
 335        int cpu = smp_processor_id();
 336        struct clock_event_device *ced = &per_cpu(cpu_ced, cpu);
 337
 338        if (!ced || !ced->event_handler)
 339                return;
 340
 341        if (uv_rtc_unset_timer(cpu, 0) != 1)
 342                return;
 343
 344        ced->event_handler(ced);
 345}
 346
 347static int __init uv_enable_evt_rtc(char *str)
 348{
 349        uv_rtc_evt_enable = 1;
 350
 351        return 1;
 352}
 353__setup("uvrtcevt", uv_enable_evt_rtc);
 354
 355static __init void uv_rtc_register_clockevents(struct work_struct *dummy)
 356{
 357        struct clock_event_device *ced = this_cpu_ptr(&cpu_ced);
 358
 359        *ced = clock_event_device_uv;
 360        ced->cpumask = cpumask_of(smp_processor_id());
 361        clockevents_register_device(ced);
 362}
 363
 364static __init int uv_rtc_setup_clock(void)
 365{
 366        int rc;
 367
 368        if (!is_uv_system())
 369                return -ENODEV;
 370
 371        rc = clocksource_register_hz(&clocksource_uv, sn_rtc_cycles_per_second);
 372        if (rc)
 373                printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
 374        else
 375                printk(KERN_INFO "UV RTC clocksource registered freq %lu MHz\n",
 376                        sn_rtc_cycles_per_second/(unsigned long)1E6);
 377
 378        if (rc || !uv_rtc_evt_enable || x86_platform_ipi_callback)
 379                return rc;
 380
 381        /* Setup and register clockevents */
 382        rc = uv_rtc_allocate_timers();
 383        if (rc)
 384                goto error;
 385
 386        x86_platform_ipi_callback = uv_rtc_interrupt;
 387
 388        clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second,
 389                                NSEC_PER_SEC, clock_event_device_uv.shift);
 390
 391        clock_event_device_uv.min_delta_ns = NSEC_PER_SEC /
 392                                                sn_rtc_cycles_per_second;
 393        clock_event_device_uv.min_delta_ticks = 1;
 394
 395        clock_event_device_uv.max_delta_ns = clocksource_uv.mask *
 396                                (NSEC_PER_SEC / sn_rtc_cycles_per_second);
 397        clock_event_device_uv.max_delta_ticks = clocksource_uv.mask;
 398
 399        rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
 400        if (rc) {
 401                x86_platform_ipi_callback = NULL;
 402                uv_rtc_deallocate_timers();
 403                goto error;
 404        }
 405
 406        printk(KERN_INFO "UV RTC clockevents registered\n");
 407
 408        return 0;
 409
 410error:
 411        clocksource_unregister(&clocksource_uv);
 412        printk(KERN_INFO "UV RTC clockevents failed rc %d\n", rc);
 413
 414        return rc;
 415}
 416arch_initcall(uv_rtc_setup_clock);
 417