Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:09

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  ckinit.c
0004  *
0005  *  This file provides a template for the clock device driver initialization.
0006  *
0007  *  Modified for sun4v - niagara
0008  */
0009 
0010 /*
0011  *  Copyright (c) 2010 Gedare Bloom.
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #include <stdlib.h>
0036 
0037 #include <rtems.h>
0038 #include <bsp.h>
0039 #include <bspopts.h>
0040 #include <boot/ofw.h>
0041 #include <rtems/bspIo.h>
0042 
0043 /* This is default frequency for simics simulator of niagara. Use the
0044  * get_Frequency function to determine the CPU clock frequency at runtime.
0045  */
0046 #define CPU_FREQ (5000000)
0047 
0048 uint64_t sparc64_cycles_per_tick;
0049 
0050 /* TICK_CMPR and STICK_CMPR trigger soft interrupt 14 */
0051 #define CLOCK_VECTOR SPARC_SYNCHRONOUS_TRAP(0x4E)
0052 
0053 static unsigned int get_Frequency(void)
0054 {
0055   phandle root = ofw_find_device("/");
0056   unsigned int freq;
0057 
0058   if (ofw_get_property(root, "clock-frequency", &freq, sizeof(freq)) <= 0) {
0059     printk("Unable to determine frequency, default: 0x%x\n",CPU_FREQ);
0060     return CPU_FREQ;
0061   }
0062 
0063   return freq;
0064 }
0065 
0066 #define Clock_driver_support_at_tick(arg) \
0067   Clock_driver_support_at_tick_helper()
0068 
0069 static void Clock_driver_support_at_tick_helper(void)
0070 {
0071   uint64_t tick_reg;
0072   int bit_mask;
0073   uint64_t pil_reg;
0074 
0075   bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
0076   sparc64_clear_interrupt_bits(bit_mask);
0077 
0078   sparc64_get_pil(pil_reg);
0079   if(pil_reg == 0xe) { /* 0xe is the tick compare interrupt (softint(14)) */
0080     pil_reg--;
0081     sparc64_set_pil(pil_reg); /* enable the next timer interrupt */
0082   }
0083   /* Note: sun4v uses stick_cmpr for clock driver for M5 simulator, which 
0084    * does not currently have tick_cmpr implemented */
0085   /* TODO: this could be more efficiently implemented as a single assembly 
0086    * inline */
0087 #if defined (SUN4U)
0088   sparc64_read_tick(tick_reg);
0089 #elif defined (SUN4V)
0090   sparc64_read_stick(tick_reg);
0091 #endif
0092   tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
0093 
0094   tick_reg += sparc64_cycles_per_tick;
0095 
0096 #if defined (SUN4U)
0097   sparc64_write_tick_cmpr(tick_reg);
0098 #elif defined (SUN4V)
0099   sparc64_write_stick_cmpr(tick_reg);
0100 #endif
0101 }
0102 
0103 #define Clock_driver_support_install_isr(_new) \
0104   set_vector( _new, CLOCK_VECTOR, 1 )
0105 
0106 static void Clock_driver_support_initialize_hardware(void)
0107 {
0108   uint64_t tick_reg;
0109   int bit_mask;
0110 
0111   bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
0112   sparc64_clear_interrupt_bits(bit_mask);
0113 
0114   sparc64_cycles_per_tick =
0115     rtems_configuration_get_microseconds_per_tick()*(get_Frequency()/1000000);
0116 
0117 #if defined (SUN4U)
0118   sparc64_read_tick(tick_reg);
0119 #elif defined (SUN4V)
0120   sparc64_read_stick(tick_reg);
0121 #endif
0122 
0123   tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
0124   tick_reg += sparc64_cycles_per_tick;
0125 
0126 #if defined (SUN4U)
0127   sparc64_write_tick_cmpr(tick_reg);
0128 #elif defined (SUN4V)
0129   sparc64_write_stick_cmpr(tick_reg);
0130 #endif
0131 }
0132 
0133 #define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
0134 
0135 #include "../../../shared/dev/clock/clockimpl.h"
0136