root/arch/x86/platform/intel-mid/intel-mid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. intel_mid_power_off
  2. intel_mid_reboot
  3. intel_mid_setup_bp_timer
  4. intel_mid_time_init
  5. intel_mid_arch_setup
  6. intel_mid_get_nmi_reason
  7. x86_intel_mid_early_setup
  8. setup_x86_intel_mid_timer

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * intel-mid.c: Intel MID platform setup code
   4  *
   5  * (C) Copyright 2008, 2012 Intel Corporation
   6  * Author: Jacob Pan (jacob.jun.pan@intel.com)
   7  * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
   8  */
   9 
  10 #define pr_fmt(fmt) "intel_mid: " fmt
  11 
  12 #include <linux/init.h>
  13 #include <linux/kernel.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/regulator/machine.h>
  16 #include <linux/scatterlist.h>
  17 #include <linux/sfi.h>
  18 #include <linux/irq.h>
  19 #include <linux/export.h>
  20 #include <linux/notifier.h>
  21 
  22 #include <asm/setup.h>
  23 #include <asm/mpspec_def.h>
  24 #include <asm/hw_irq.h>
  25 #include <asm/apic.h>
  26 #include <asm/io_apic.h>
  27 #include <asm/intel-mid.h>
  28 #include <asm/intel_mid_vrtc.h>
  29 #include <asm/io.h>
  30 #include <asm/i8259.h>
  31 #include <asm/intel_scu_ipc.h>
  32 #include <asm/apb_timer.h>
  33 #include <asm/reboot.h>
  34 
  35 /*
  36  * the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock,
  37  * cmdline option x86_intel_mid_timer can be used to override the configuration
  38  * to prefer one or the other.
  39  * at runtime, there are basically three timer configurations:
  40  * 1. per cpu apbt clock only
  41  * 2. per cpu always-on lapic clocks only, this is Penwell/Medfield only
  42  * 3. per cpu lapic clock (C3STOP) and one apbt clock, with broadcast.
  43  *
  44  * by default (without cmdline option), platform code first detects cpu type
  45  * to see if we are on lincroft or penwell, then set up both lapic or apbt
  46  * clocks accordingly.
  47  * i.e. by default, medfield uses configuration #2, moorestown uses #1.
  48  * config #3 is supported but not recommended on medfield.
  49  *
  50  * rating and feature summary:
  51  * lapic (with C3STOP) --------- 100
  52  * apbt (always-on) ------------ 110
  53  * lapic (always-on,ARAT) ------ 150
  54  */
  55 
  56 enum intel_mid_timer_options intel_mid_timer_options;
  57 
  58 enum intel_mid_cpu_type __intel_mid_cpu_chip;
  59 EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
  60 
  61 static void intel_mid_power_off(void)
  62 {
  63         /* Shut down South Complex via PWRMU */
  64         intel_mid_pwr_power_off();
  65 
  66         /* Only for Tangier, the rest will ignore this command */
  67         intel_scu_ipc_simple_command(IPCMSG_COLD_OFF, 1);
  68 };
  69 
  70 static void intel_mid_reboot(void)
  71 {
  72         intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
  73 }
  74 
  75 static void __init intel_mid_setup_bp_timer(void)
  76 {
  77         apbt_time_init();
  78         setup_boot_APIC_clock();
  79 }
  80 
  81 static void __init intel_mid_time_init(void)
  82 {
  83         sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
  84 
  85         switch (intel_mid_timer_options) {
  86         case INTEL_MID_TIMER_APBT_ONLY:
  87                 break;
  88         case INTEL_MID_TIMER_LAPIC_APBT:
  89                 /* Use apbt and local apic */
  90                 x86_init.timers.setup_percpu_clockev = intel_mid_setup_bp_timer;
  91                 x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
  92                 return;
  93         default:
  94                 if (!boot_cpu_has(X86_FEATURE_ARAT))
  95                         break;
  96                 /* Lapic only, no apbt */
  97                 x86_init.timers.setup_percpu_clockev = setup_boot_APIC_clock;
  98                 x86_cpuinit.setup_percpu_clockev = setup_secondary_APIC_clock;
  99                 return;
 100         }
 101 
 102         x86_init.timers.setup_percpu_clockev = apbt_time_init;
 103 }
 104 
 105 static void intel_mid_arch_setup(void)
 106 {
 107         if (boot_cpu_data.x86 != 6) {
 108                 pr_err("Unknown Intel MID CPU (%d:%d), default to Penwell\n",
 109                         boot_cpu_data.x86, boot_cpu_data.x86_model);
 110                 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
 111                 goto out;
 112         }
 113 
 114         switch (boot_cpu_data.x86_model) {
 115         case 0x35:
 116                 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_CLOVERVIEW;
 117                 break;
 118         case 0x3C:
 119         case 0x4A:
 120                 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_TANGIER;
 121                 x86_platform.legacy.rtc = 1;
 122                 break;
 123         case 0x27:
 124         default:
 125                 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
 126                 break;
 127         }
 128 
 129 out:
 130         /*
 131          * Intel MID platforms are using explicitly defined regulators.
 132          *
 133          * Let the regulator core know that we do not have any additional
 134          * regulators left. This lets it substitute unprovided regulators with
 135          * dummy ones:
 136          */
 137         regulator_has_full_constraints();
 138 }
 139 
 140 /*
 141  * Moorestown does not have external NMI source nor port 0x61 to report
 142  * NMI status. The possible NMI sources are from pmu as a result of NMI
 143  * watchdog or lock debug. Reading io port 0x61 results in 0xff which
 144  * misled NMI handler.
 145  */
 146 static unsigned char intel_mid_get_nmi_reason(void)
 147 {
 148         return 0;
 149 }
 150 
 151 /*
 152  * Moorestown specific x86_init function overrides and early setup
 153  * calls.
 154  */
 155 void __init x86_intel_mid_early_setup(void)
 156 {
 157         x86_init.resources.probe_roms = x86_init_noop;
 158         x86_init.resources.reserve_resources = x86_init_noop;
 159 
 160         x86_init.timers.timer_init = intel_mid_time_init;
 161         x86_init.timers.setup_percpu_clockev = x86_init_noop;
 162         x86_init.timers.wallclock_init = intel_mid_rtc_init;
 163 
 164         x86_init.irqs.pre_vector_init = x86_init_noop;
 165 
 166         x86_init.oem.arch_setup = intel_mid_arch_setup;
 167 
 168         x86_cpuinit.setup_percpu_clockev = apbt_setup_secondary_clock;
 169 
 170         x86_platform.get_nmi_reason = intel_mid_get_nmi_reason;
 171 
 172         x86_init.pci.arch_init = intel_mid_pci_init;
 173         x86_init.pci.fixup_irqs = x86_init_noop;
 174 
 175         legacy_pic = &null_legacy_pic;
 176 
 177         /*
 178          * Do nothing for now as everything needed done in
 179          * x86_intel_mid_early_setup() below.
 180          */
 181         x86_init.acpi.reduced_hw_early_init = x86_init_noop;
 182 
 183         pm_power_off = intel_mid_power_off;
 184         machine_ops.emergency_restart  = intel_mid_reboot;
 185 
 186         /* Avoid searching for BIOS MP tables */
 187         x86_init.mpparse.find_smp_config = x86_init_noop;
 188         x86_init.mpparse.get_smp_config = x86_init_uint_noop;
 189         set_bit(MP_BUS_ISA, mp_bus_not_pci);
 190 }
 191 
 192 /*
 193  * if user does not want to use per CPU apb timer, just give it a lower rating
 194  * than local apic timer and skip the late per cpu timer init.
 195  */
 196 static inline int __init setup_x86_intel_mid_timer(char *arg)
 197 {
 198         if (!arg)
 199                 return -EINVAL;
 200 
 201         if (strcmp("apbt_only", arg) == 0)
 202                 intel_mid_timer_options = INTEL_MID_TIMER_APBT_ONLY;
 203         else if (strcmp("lapic_and_apbt", arg) == 0)
 204                 intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT;
 205         else {
 206                 pr_warn("X86 INTEL_MID timer option %s not recognised use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n",
 207                         arg);
 208                 return -EINVAL;
 209         }
 210         return 0;
 211 }
 212 __setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer);

/* [<][>][^][v][top][bottom][index][help] */