aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Cohen <david.a.cohen@linux.intel.com>2013-12-16 15:07:38 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2014-01-15 17:38:58 -0500
commitbc20aa48bbb3068224a1c91f8332971fdb689fad (patch)
treef1a4b0e72b921027c590e56d215638c402b625b3
parent85611e3febe78955a519f5f9eb47b941525c8c76 (diff)
x86, intel-mid: Add Merrifield platform support
This code was partially based on Mark Brown's previous work. Signed-off-by: David Cohen <david.a.cohen@linux.intel.com> Link: http://lkml.kernel.org/r/1387224459-25746-4-git-send-email-david.a.cohen@linux.intel.com Signed-off-by: Fei Yang <fei.yang@intel.com> Cc: Mark F. Brown <mark.f.brown@intel.com> Cc: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/include/asm/intel-mid.h2
-rw-r--r--arch/x86/pci/intel_mid_pci.c6
-rw-r--r--arch/x86/platform/intel-mid/Makefile2
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c4
-rw-r--r--arch/x86/platform/intel-mid/intel_mid_weak_decls.h1
-rw-r--r--arch/x86/platform/intel-mid/mrfl.c103
-rw-r--r--arch/x86/platform/intel-mid/sfi.c34
7 files changed, 144 insertions, 8 deletions
diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h
index f8a831431fe0..e34e097b6f9d 100644
--- a/arch/x86/include/asm/intel-mid.h
+++ b/arch/x86/include/asm/intel-mid.h
@@ -52,6 +52,7 @@ enum intel_mid_cpu_type {
52 /* 1 was Moorestown */ 52 /* 1 was Moorestown */
53 INTEL_MID_CPU_CHIP_PENWELL = 2, 53 INTEL_MID_CPU_CHIP_PENWELL = 2,
54 INTEL_MID_CPU_CHIP_CLOVERVIEW, 54 INTEL_MID_CPU_CHIP_CLOVERVIEW,
55 INTEL_MID_CPU_CHIP_TANGIER,
55}; 56};
56 57
57extern enum intel_mid_cpu_type __intel_mid_cpu_chip; 58extern enum intel_mid_cpu_type __intel_mid_cpu_chip;
@@ -82,6 +83,7 @@ struct intel_mid_ops {
82#define INTEL_MID_OPS_INIT {\ 83#define INTEL_MID_OPS_INIT {\
83 DECLARE_INTEL_MID_OPS_INIT(penwell, INTEL_MID_CPU_CHIP_PENWELL), \ 84 DECLARE_INTEL_MID_OPS_INIT(penwell, INTEL_MID_CPU_CHIP_PENWELL), \
84 DECLARE_INTEL_MID_OPS_INIT(cloverview, INTEL_MID_CPU_CHIP_CLOVERVIEW), \ 85 DECLARE_INTEL_MID_OPS_INIT(cloverview, INTEL_MID_CPU_CHIP_CLOVERVIEW), \
86 DECLARE_INTEL_MID_OPS_INIT(tangier, INTEL_MID_CPU_CHIP_TANGIER) \
85}; 87};
86 88
87#ifdef CONFIG_X86_INTEL_MID 89#ifdef CONFIG_X86_INTEL_MID
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c
index 51384ca727ad..84b9d672843d 100644
--- a/arch/x86/pci/intel_mid_pci.c
+++ b/arch/x86/pci/intel_mid_pci.c
@@ -31,6 +31,7 @@
31#include <asm/pci_x86.h> 31#include <asm/pci_x86.h>
32#include <asm/hw_irq.h> 32#include <asm/hw_irq.h>
33#include <asm/io_apic.h> 33#include <asm/io_apic.h>
34#include <asm/intel-mid.h>
34 35
35#define PCIE_CAP_OFFSET 0x100 36#define PCIE_CAP_OFFSET 0x100
36 37
@@ -219,7 +220,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
219 irq_attr.ioapic = mp_find_ioapic(dev->irq); 220 irq_attr.ioapic = mp_find_ioapic(dev->irq);
220 irq_attr.ioapic_pin = dev->irq; 221 irq_attr.ioapic_pin = dev->irq;
221 irq_attr.trigger = 1; /* level */ 222 irq_attr.trigger = 1; /* level */
222 irq_attr.polarity = 1; /* active low */ 223 if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
224 irq_attr.polarity = 0; /* active high */
225 else
226 irq_attr.polarity = 1; /* active low */
223 io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr); 227 io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
224 228
225 return 0; 229 return 0;
diff --git a/arch/x86/platform/intel-mid/Makefile b/arch/x86/platform/intel-mid/Makefile
index 78a14ba0e0db..0a8ee703b9fa 100644
--- a/arch/x86/platform/intel-mid/Makefile
+++ b/arch/x86/platform/intel-mid/Makefile
@@ -1,4 +1,4 @@
1obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o intel_mid_vrtc.o mfld.o 1obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o intel_mid_vrtc.o mfld.o mrfl.o
2obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o 2obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o
3 3
4# SFI specific code 4# SFI specific code
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 40955841bb32..1bbedc4b0f88 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -116,6 +116,10 @@ static void intel_mid_arch_setup(void)
116 case 0x35: 116 case 0x35:
117 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_CLOVERVIEW; 117 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_CLOVERVIEW;
118 break; 118 break;
119 case 0x3C:
120 case 0x4A:
121 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_TANGIER;
122 break;
119 case 0x27: 123 case 0x27:
120 default: 124 default:
121 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL; 125 __intel_mid_cpu_chip = INTEL_MID_CPU_CHIP_PENWELL;
diff --git a/arch/x86/platform/intel-mid/intel_mid_weak_decls.h b/arch/x86/platform/intel-mid/intel_mid_weak_decls.h
index 9ebce0447edf..a537ffc16299 100644
--- a/arch/x86/platform/intel-mid/intel_mid_weak_decls.h
+++ b/arch/x86/platform/intel-mid/intel_mid_weak_decls.h
@@ -16,3 +16,4 @@
16 */ 16 */
17extern void * __cpuinit get_penwell_ops(void) __attribute__((weak)); 17extern void * __cpuinit get_penwell_ops(void) __attribute__((weak));
18extern void * __cpuinit get_cloverview_ops(void) __attribute__((weak)); 18extern void * __cpuinit get_cloverview_ops(void) __attribute__((weak));
19extern void * __init get_tangier_ops(void) __attribute__((weak));
diff --git a/arch/x86/platform/intel-mid/mrfl.c b/arch/x86/platform/intel-mid/mrfl.c
new file mode 100644
index 000000000000..09d10159e7b7
--- /dev/null
+++ b/arch/x86/platform/intel-mid/mrfl.c
@@ -0,0 +1,103 @@
1/*
2 * mrfl.c: Intel Merrifield platform specific setup code
3 *
4 * (C) Copyright 2013 Intel Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; version 2
9 * of the License.
10 */
11
12#include <linux/init.h>
13
14#include <asm/apic.h>
15#include <asm/intel-mid.h>
16
17#include "intel_mid_weak_decls.h"
18
19static unsigned long __init tangier_calibrate_tsc(void)
20{
21 unsigned long fast_calibrate;
22 u32 lo, hi, ratio, fsb, bus_freq;
23
24 /* *********************** */
25 /* Compute TSC:Ratio * FSB */
26 /* *********************** */
27
28 /* Compute Ratio */
29 rdmsr(MSR_PLATFORM_INFO, lo, hi);
30 pr_debug("IA32 PLATFORM_INFO is 0x%x : %x\n", hi, lo);
31
32 ratio = (lo >> 8) & 0xFF;
33 pr_debug("ratio is %d\n", ratio);
34 if (!ratio) {
35 pr_err("Read a zero ratio, force tsc ratio to 4 ...\n");
36 ratio = 4;
37 }
38
39 /* Compute FSB */
40 rdmsr(MSR_FSB_FREQ, lo, hi);
41 pr_debug("Actual FSB frequency detected by SOC 0x%x : %x\n",
42 hi, lo);
43
44 bus_freq = lo & 0x7;
45 pr_debug("bus_freq = 0x%x\n", bus_freq);
46
47 if (bus_freq == 0)
48 fsb = FSB_FREQ_100SKU;
49 else if (bus_freq == 1)
50 fsb = FSB_FREQ_100SKU;
51 else if (bus_freq == 2)
52 fsb = FSB_FREQ_133SKU;
53 else if (bus_freq == 3)
54 fsb = FSB_FREQ_167SKU;
55 else if (bus_freq == 4)
56 fsb = FSB_FREQ_83SKU;
57 else if (bus_freq == 5)
58 fsb = FSB_FREQ_400SKU;
59 else if (bus_freq == 6)
60 fsb = FSB_FREQ_267SKU;
61 else if (bus_freq == 7)
62 fsb = FSB_FREQ_333SKU;
63 else {
64 BUG();
65 pr_err("Invalid bus_freq! Setting to minimal value!\n");
66 fsb = FSB_FREQ_100SKU;
67 }
68
69 /* TSC = FSB Freq * Resolved HFM Ratio */
70 fast_calibrate = ratio * fsb;
71 pr_debug("calculate tangier tsc %lu KHz\n", fast_calibrate);
72
73 /* ************************************ */
74 /* Calculate Local APIC Timer Frequency */
75 /* ************************************ */
76 lapic_timer_frequency = (fsb * 1000) / HZ;
77
78 pr_debug("Setting lapic_timer_frequency = %d\n",
79 lapic_timer_frequency);
80
81 /* mark tsc clocksource as reliable */
82 set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
83
84 if (fast_calibrate)
85 return fast_calibrate;
86
87 return 0;
88}
89
90static void __init tangier_arch_setup(void)
91{
92 x86_platform.calibrate_tsc = tangier_calibrate_tsc;
93}
94
95/* tangier arch ops */
96static struct intel_mid_ops tangier_ops = {
97 .arch_setup = tangier_arch_setup,
98};
99
100void * __cpuinit get_tangier_ops()
101{
102 return &tangier_ops;
103}
diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c
index c84c1ca396bf..80a52288555c 100644
--- a/arch/x86/platform/intel-mid/sfi.c
+++ b/arch/x86/platform/intel-mid/sfi.c
@@ -443,13 +443,35 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
443 * so we have to enable them one by one here 443 * so we have to enable them one by one here
444 */ 444 */
445 ioapic = mp_find_ioapic(irq); 445 ioapic = mp_find_ioapic(irq);
446 irq_attr.ioapic = ioapic; 446 if (ioapic >= 0) {
447 irq_attr.ioapic_pin = irq; 447 irq_attr.ioapic = ioapic;
448 irq_attr.trigger = 1; 448 irq_attr.ioapic_pin = irq;
449 irq_attr.polarity = 1; 449 irq_attr.trigger = 1;
450 io_apic_set_pci_routing(NULL, irq, &irq_attr); 450 if (intel_mid_identify_cpu() ==
451 } else 451 INTEL_MID_CPU_CHIP_TANGIER) {
452 if (!strncmp(pentry->name,
453 "r69001-ts-i2c", 13))
454 /* active low */
455 irq_attr.polarity = 1;
456 else if (!strncmp(pentry->name,
457 "synaptics_3202", 14))
458 /* active low */
459 irq_attr.polarity = 1;
460 else if (irq == 41)
461 /* fast_int_1 */
462 irq_attr.polarity = 1;
463 else
464 /* active high */
465 irq_attr.polarity = 0;
466 } else {
467 /* PNW and CLV go with active low */
468 irq_attr.polarity = 1;
469 }
470 io_apic_set_pci_routing(NULL, irq, &irq_attr);
471 }
472 } else {
452 irq = 0; /* No irq */ 473 irq = 0; /* No irq */
474 }
453 475
454 dev = get_device_id(pentry->type, pentry->name); 476 dev = get_device_id(pentry->type, pentry->name);
455 477