2 * AMD Geode southbridge support code
3 * Copyright (C) 2006, Advanced Micro Devices, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public License
7 * as published by the Free Software Foundation.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/ioport.h>
15 #include <asm/geode.h>
23 { "geode-pms", MSR_LBAR_PMS, LBAR_PMS_SIZE, 0 },
24 { "geode-acpi", MSR_LBAR_ACPI, LBAR_ACPI_SIZE, 0 },
25 { "geode-gpio", MSR_LBAR_GPIO, LBAR_GPIO_SIZE, 0 },
26 { "geode-mfgpt", MSR_LBAR_MFGPT, LBAR_MFGPT_SIZE, 0 }
29 static void __init init_lbars(void)
34 for (i = 0; i < ARRAY_SIZE(lbars); i++) {
35 rdmsr(lbars[i].msr, lo, hi);
37 lbars[i].base = lo & 0x0000ffff;
39 if (lbars[i].base == 0)
40 printk(KERN_ERR "geode: Couldn't initialize '%s'\n",
45 int geode_get_dev_base(unsigned int dev)
47 BUG_ON(dev >= ARRAY_SIZE(lbars));
48 return lbars[dev].base;
50 EXPORT_SYMBOL_GPL(geode_get_dev_base);
52 /* === GPIO API === */
54 void geode_gpio_set(unsigned int gpio, unsigned int reg)
56 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
62 outl(1 << gpio, base + reg);
64 outl(1 << (gpio - 16), base + 0x80 + reg);
66 EXPORT_SYMBOL_GPL(geode_gpio_set);
68 void geode_gpio_clear(unsigned int gpio, unsigned int reg)
70 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
76 outl(1 << (gpio + 16), base + reg);
78 outl(1 << gpio, base + 0x80 + reg);
80 EXPORT_SYMBOL_GPL(geode_gpio_clear);
82 int geode_gpio_isset(unsigned int gpio, unsigned int reg)
84 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
90 return (inl(base + reg) & (1 << gpio)) ? 1 : 0;
92 return (inl(base + 0x80 + reg) & (1 << (gpio - 16))) ? 1 : 0;
94 EXPORT_SYMBOL_GPL(geode_gpio_isset);
96 void geode_gpio_set_irq(unsigned int group, unsigned int irq)
100 if (group > 7 || irq > 15)
103 rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
105 lo &= ~(0xF << (group * 4));
106 lo |= (irq & 0xF) << (group * 4);
108 wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
110 EXPORT_SYMBOL_GPL(geode_gpio_set_irq);
112 void geode_gpio_setup_event(unsigned int gpio, int pair, int pme)
114 u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
115 u32 offset, shift, val;
126 shift = (gpio % 8) * 4;
128 val = inl(base + offset);
130 /* Clear whatever was there before */
131 val &= ~(0xF << shift);
133 /* And set the new value */
135 val |= ((pair & 7) << shift);
137 /* Set the PME bit if this is a PME event */
140 val |= (1 << (shift + 3));
142 outl(val, base + offset);
144 EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
146 static int __init geode_southbridge_init(void)
155 postcore_initcall(geode_southbridge_init);