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)
154 timers
= geode_mfgpt_detect();
155 printk(KERN_INFO
"geode: %d MFGPT timers available.\n", timers
);
159 postcore_initcall(geode_southbridge_init
);