* [PATCH 1/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
@ 2005-10-28 15:44 ` Jordan Crouse
2005-10-30 22:39 ` Alan Cox
2005-10-28 15:46 ` [PATCH 2/6] " Jordan Crouse
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:44 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux
This is the base GX/LX support patch. Prior changelog:
* fixed up the MGEODEGX1 cache line size to the correct value.
* Removed GEODE_LX restrictions from IOAPIC and HIGHMEM (Alan Cox and others)
* Removed GEODE_LX define from the 3DNOW config option pending conclusive
benchmark results that it increases performance (Alan Cox)
* Fix up the GX1/GX cpu init function so that it is cleaner and more
correct. If anybody gets a NSC branded GX1 processor, it should jump
into the init_cyrix and do the right thing. (Alan Cox)
* Updated the MAINTAINERS information (Adrian Bunk)
MAINTAINERS | 7 +++++++
arch/i386/Kconfig | 12 +++++++++---
arch/i386/kernel/cpu/amd.c | 7 +++++++
arch/i386/kernel/cpu/cyrix.c | 32 +++++++++++++++++++++++++++++++-
include/asm-i386/module.h | 4 +++-
include/linux/pci_ids.h | 10 ++++++++++
6 files changed, 67 insertions(+), 5 deletions(-)
Index: linux-2.6.14/arch/i386/Kconfig
===================================================================
--- linux-2.6.14.orig/arch/i386/Kconfig
+++ linux-2.6.14/arch/i386/Kconfig
@@ -191,6 +191,7 @@ config M386
- "Winchip-2" for IDT Winchip 2.
- "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
- "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+ - "Geode GX/LX" For AMD Geode GX and LX processors.
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
- "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
@@ -323,6 +324,11 @@ config MGEODEGX1
help
Select this for a Geode GX1 (Cyrix MediaGX) chip.
+config MGEODE_LX
+ bool "Geode GX/LX"
+ help
+ Select this for AMD Geode GX and LX processors.
+
config MCYRIXIII
bool "CyrixIII/VIA-C3"
help
@@ -372,8 +378,8 @@ config X86_XADD
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || X86_GENERIC
- default "4" if X86_ELAN || M486 || M386
- default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+ default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
+ default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
default "6" if MK7 || MK8 || MPENTIUMM
config RWSEM_GENERIC_SPINLOCK
@@ -437,7 +443,7 @@ config X86_INTEL_USERCOPY
config X86_USE_PPRO_CHECKSUM
bool
- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
default y
config X86_USE_3DNOW
Index: linux-2.6.14/arch/i386/kernel/cpu/amd.c
===================================================================
--- linux-2.6.14.orig/arch/i386/kernel/cpu/amd.c
+++ linux-2.6.14/arch/i386/kernel/cpu/amd.c
@@ -161,6 +161,13 @@ static void __init init_amd(struct cpuin
set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
break;
}
+
+ if ( c->x86_model == 10 ) {
+ /* AMD Geode LX is model 10 */
+ /* placeholder for any needed mods */
+ break;
+ }
+
break;
case 6: /* An Athlon/Duron */
Index: linux-2.6.14/include/linux/pci_ids.h
===================================================================
--- linux-2.6.14.orig/include/linux/pci_ids.h
+++ linux-2.6.14/include/linux/pci_ids.h
@@ -405,6 +405,13 @@
#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515
#define PCI_DEVICE_ID_NS_87410 0xd001
+#define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028
+#define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b
+#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d
+#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
+#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f
+#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030
+
#define PCI_VENDOR_ID_TSENG 0x100c
#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
@@ -536,6 +543,9 @@
#define PCI_DEVICE_ID_AMD_8151_0 0x7454
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450
+#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
+#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
+
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
Index: linux-2.6.14/MAINTAINERS
===================================================================
--- linux-2.6.14.orig/MAINTAINERS
+++ linux-2.6.14/MAINTAINERS
@@ -252,6 +252,13 @@ P: Ivan Kokshaysky
M: ink@jurassic.park.msu.ru
S: Maintained for 2.4; PCI support for 2.6.
+AMD GEODE PROCESSOR/CHIPSET SUPPORT
+P: Jordan Crouse
+M: info-linux@geode.amd.com
+L: info-linux@geode.amd.com
+W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
+S: Supported
+
APM DRIVER
P: Stephen Rothwell
M: sfr@canb.auug.org.au
Index: linux-2.6.14/arch/i386/kernel/cpu/cyrix.c
===================================================================
--- linux-2.6.14.orig/arch/i386/kernel/cpu/cyrix.c
+++ linux-2.6.14/arch/i386/kernel/cpu/cyrix.c
@@ -342,6 +342,36 @@ static void __init init_cyrix(struct cpu
return;
}
+
+/* This function handles National Semiconductor branded processors */
+
+static void __init init_nsc(struct cpuinfo_x86 *c)
+{
+ int r;
+
+ /* There may be GX1 processors in the wild that are branded
+ * NSC and not Cyrix.
+ *
+ * This function only handles the GX processor, and kicks every
+ * thing else to the Cyrix init function above - that should
+ * cover any processors that might have been branded differently
+ * after NSC aquired Cyrix.
+ *
+ * If this breaks your GX1 horribly, please e-mail
+ * info-linux@ldcmail.amd.com to tell us.
+ */
+
+ /* Handle the GX (Formally known as the GX2) */
+
+ if ((c->x86 == 5) && (c->x86_model == 5)) {
+ r = get_model_name(c);
+ display_cacheinfo(c);
+ }
+ else
+ init_cyrix(c);
+}
+
+
/*
* Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
* by the fact that they preserve the flags across the division of 5/2.
@@ -422,7 +452,7 @@ int __init cyrix_init_cpu(void)
static struct cpu_dev nsc_cpu_dev __initdata = {
.c_vendor = "NSC",
.c_ident = { "Geode by NSC" },
- .c_init = init_cyrix,
+ .c_init = init_nsc,
.c_identify = generic_identify,
};
Index: linux-2.6.14/include/asm-i386/module.h
===================================================================
--- linux-2.6.14.orig/include/asm-i386/module.h
+++ linux-2.6.14/include/asm-i386/module.h
@@ -52,8 +52,10 @@ struct mod_arch_specific
#define MODULE_PROC_FAMILY "CYRIXIII "
#elif defined CONFIG_MVIAC3_2
#define MODULE_PROC_FAMILY "VIAC3-2 "
-#elif CONFIG_MGEODEGX1
+#elif defined CONFIG_MGEODEGX1
#define MODULE_PROC_FAMILY "GEODEGX1 "
+#elif defined CONFIG_MGEODE_LX
+#define MODULE_PROC_FAMILY "GEODE "
#else
#error unknown processor family
#endif
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 1/6] AMD Geode GX/LX Support (Refreshed)
2005-10-28 15:44 ` [PATCH 1/6] AMD Geode GX/LX Support (Refreshed) Jordan Crouse
@ 2005-10-30 22:39 ` Alan Cox
2005-10-31 15:37 ` Jordan Crouse
2005-11-01 23:10 ` Jordan Crouse
0 siblings, 2 replies; 12+ messages in thread
From: Alan Cox @ 2005-10-30 22:39 UTC (permalink / raw)
To: Jordan Crouse; +Cc: linux-kernel, info-linux
6_INTEL_USERCOPY
>
> config X86_USE_PPRO_CHECKSUM
> bool
> - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
> + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
> default y
Does this mean you've now done actual performance analysis on whether
this is a good idea for Geode GX/LX ?
> config X86_USE_3DNOW
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AMD Geode GX/LX Support (Refreshed)
2005-10-30 22:39 ` Alan Cox
@ 2005-10-31 15:37 ` Jordan Crouse
2005-11-01 23:10 ` Jordan Crouse
1 sibling, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2005-10-31 15:37 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-kernel, info-linux
> Does this mean you've now done actual performance analysis on whether
> this is a good idea for Geode GX/LX ?
I'm fairly sure that the ppro checksum is faster, but you're exactly right,
we should publish some numbers. Mia culpa.
Jordan
--
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AMD Geode GX/LX Support (Refreshed)
2005-10-30 22:39 ` Alan Cox
2005-10-31 15:37 ` Jordan Crouse
@ 2005-11-01 23:10 ` Jordan Crouse
2005-11-01 23:53 ` Alan Cox
1 sibling, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2005-11-01 23:10 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-kernel, info-linux
> > config X86_USE_PPRO_CHECKSUM
> Does this mean you've now done actual performance analysis on whether
> this is a good idea for Geode GX/LX ?
Ok - here is some data that should put your mind at ease. I pulled
the checksum functions from the kernel, stuck them in userland, and
ran each one N times at a variety of byte sizes (where N=10,000), took the
start and stop times with gettimeofday(), and added it all up. The results
for the Geode LX platfrom are below.
I think the data shows that the ppro checksum is indeed useful on the
Geode LX platform (and the GX should have similar results, since the
pipelines are pretty close). Unless I made a really boneheaded mistake
in my app, I think we should leave X86_USE_PPRO_CHECKSUM enabled for Geode
GX/LX.
Jordan
Starting non-ppro test....
Bytes Time Avg (usec/run)
----------------------------
16 2029 0.202900
32 1666 0.166600
64 2548 0.254800
128 3429 0.342900
256 5268 0.526800
512 8781 0.878100
1024 16031 1.603100
2048 30548 3.054800
4096 59265 5.926500
Total time: 129565
Starting ppro test....
Bytes Time Avg (usec/run)
----------------------------
16 1579 0.157900
32 1655 0.165500
64 1841 0.184100
128 2721 0.272100
256 3582 0.358200
512 5264 0.526400
1024 8900 0.890000
2048 15919 1.591900
4096 29369 2.936900
Total time: 70830
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
2005-10-28 15:44 ` [PATCH 1/6] AMD Geode GX/LX Support (Refreshed) Jordan Crouse
@ 2005-10-28 15:46 ` Jordan Crouse
2005-10-28 15:48 ` [PATCH 3/6] " Jordan Crouse
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:46 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux
This is a simple patch that fixes console APM blanking on the GX/LX
platforms with BIOSes that still support APM.
apm.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
Index: linux-2.6.14/arch/i386/kernel/apm.c
===================================================================
--- linux-2.6.14.orig/arch/i386/kernel/apm.c
+++ linux-2.6.14/arch/i386/kernel/apm.c
@@ -1054,22 +1054,23 @@ static int apm_engage_power_management(u
static int apm_console_blank(int blank)
{
- int error;
- u_short state;
+ int error, i;
+ u_short state;
+ u_short dev[3] = { 0x100, 0x1FF, 0x101 };
state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
- /* Blank the first display device */
- error = set_power_state(0x100, state);
- if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) {
- /* try to blank them all instead */
- error = set_power_state(0x1ff, state);
- if ((error != APM_SUCCESS) && (error != APM_NO_ERROR))
- /* try to blank device one instead */
- error = set_power_state(0x101, state);
+
+ for (i = 0; i < 3; i++) {
+ error = set_power_state(dev[i], state);
+
+ if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+ return 1;
+
+ if (error == APM_NOT_ENGAGED)
+ break;
}
- if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
- return 1;
- if (error == APM_NOT_ENGAGED) {
+
+ if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
static int tried;
int eng_error;
if (tried++ == 0) {
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 3/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
2005-10-28 15:44 ` [PATCH 1/6] AMD Geode GX/LX Support (Refreshed) Jordan Crouse
2005-10-28 15:46 ` [PATCH 2/6] " Jordan Crouse
@ 2005-10-28 15:48 ` Jordan Crouse
2005-10-28 15:51 ` [PATCH 4/6] " Jordan Crouse
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:48 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux
The 5535 has a muxed serial port that can either be used to drive GPIO pins
or a second 16550 UART. This code enables that UART via a command line
option.
This is most often used with a dongle attached to the VGA port to provide a
a serial port on boards with no dedicated serial goesouta.
Kconfig | 11 +++++++
Makefile | 1
cs5535_uart.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
Index: linux-2.6.14/drivers/serial/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/serial/Kconfig
+++ linux-2.6.14/drivers/serial/Kconfig
@@ -608,6 +608,17 @@ config SERIAL_AU1X00_CONSOLE
If you have an Alchemy AU1X00 processor (MIPS based) and you want
to use a console on a serial port, say Y. Otherwise, say N.
+config SERIAL_GEODE_UART2
+ bool "Enable AMD CS5535 UART2 as a serial port"
+ depends on MGEODE_LX
+ default y
+ select SERIAL_CORE
+ help
+ Select this to allow the user to select the secondary CS5535 UART
+ as a 16550 serial port instead of the default DDC interface. The
+ UART2 can be selected by specifying geodeuart2 on the command
+ line.
+
config SERIAL_CORE
tristate
Index: linux-2.6.14/drivers/serial/Makefile
===================================================================
--- linux-2.6.14.orig/drivers/serial/Makefile
+++ linux-2.6.14/drivers/serial/Makefile
@@ -56,3 +56,4 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_GEODE_UART2) += cs5535_uart.o
Index: linux-2.6.14/drivers/serial/cs5535_uart.c
===================================================================
--- /dev/null
+++ linux-2.6.14/drivers/serial/cs5535_uart.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2005 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+/* The CS5535 companion chip has two UARTs. This code enables the second
+ UART so other devices can use it. We do it here so we can expose the
+ port early enough for serial debugging
+*/
+
+/* Note - this does not check to see if the CS5535 actually exists */
+
+#define LO(b) (((1 << b) << 16) | 0x0000)
+#define HI(b) ((0x0000 << 16) | (1 << b))
+
+static u32 outtab[16] __initdata =
+{
+ 0x00,HI(4), 0x04,HI(4), 0x08,HI(4),
+ 0x0c,LO(4), 0x10,HI(4), 0x14,LO(4),
+ 0x18,LO(4), 0x1C,LO(4)
+};
+
+static u32 intab[16] __initdata = {
+ 0x20,HI(3), 0x24,LO(3), 0x28,LO(3),
+ 0x2C,LO(3), 0x34,HI(3), 0x38,LO(3),
+ 0x40,LO(3), 0x44,LO(3)
+};
+
+static int __init init_cs5535_uart2(char *str)
+{
+ u32 lo = 0, hi = 0;
+ u32 base; u32 i;
+
+ /* Enable UART2 instead of DDC */
+
+ rdmsr(0x51400014, lo, hi);
+ lo &= 0xFF8FFFFF;
+ lo |= 0x00500000; /* 0x2F8 ttyS1 */
+ wrmsr(0x51400014, lo, hi);
+
+ /* Set up the UART registers */
+ wrmsr(0x5140003E, 0x12, 0x00);
+
+ rdmsr(0x5140000C, lo, hi);
+ base = (u32)(lo & 0xFF00);
+
+ /* Enable the GPIO pins (in and out) */
+
+ for(i = 0; i < 16; i += 2) {
+ outl(outtab[i + 1], base + outtab[i]);
+ outl(intab[i + 1], base + intab[i]);
+ }
+
+ /* Enable the IRQ */
+
+ rdmsr(0x51400021,lo,hi);
+ lo &= 0x0FFFFFFF;
+ lo |= 0x30000000; /* IRQ 3 */
+ wrmsr(0x51400021,lo,hi);
+}
+
+__setup("geodeuart2", init_cs5535_uart2);
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 4/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
` (2 preceding siblings ...)
2005-10-28 15:48 ` [PATCH 3/6] " Jordan Crouse
@ 2005-10-28 15:51 ` Jordan Crouse
2005-11-09 23:00 ` Bartlomiej Zolnierkiewicz
2005-10-28 15:53 ` [PATCH 5/6] " Jordan Crouse
2005-10-28 15:55 ` [6/6] " Jordan Crouse
5 siblings, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:51 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux, linux-ide
This is a refresh of Jaya Kumar's patch for the CS5535 IDE on the linux-ide
list for 2.6.16 - All glory should go to him, I'm just including it here to
complete the set.
Kconfig | 9 +
pci/Makefile | 1
pci/cs5535.c | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 315 insertions(+)
Index: linux-2.6.14/drivers/ide/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/ide/Kconfig
+++ linux-2.6.14/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
It is safe to say Y to this question.
+config BLK_DEV_CS5535
+ tristate "AMD CS5535 chipset support"
+ depends on X86 && !X86_64
+ help
+ Include support for UDMA on the NSC/AMD CS5535 companion chipset.
+ This will automatically be detected and configured if found.
+
+ It is safe to say Y to this question.
+
config BLK_DEV_HPT34X
tristate "HPT34X chipset support"
help
Index: linux-2.6.14/drivers/ide/pci/cs5535.c
===================================================================
--- /dev/null
+++ linux-2.6.14/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
+/*
+ * linux/drivers/ide/pci/cs5535.c
+ *
+ * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
+ *
+ * History:
+ * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
+ * - Reworked tuneproc, set_drive, misc mods to prep for mainline
+ * - Work was sponsored by CIS (M) Sdn Bhd.
+ * Ported to Kernel 2.6.11 on June 26, 2005 by
+ * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
+ * Alexander Kiausch <alex.kiausch@t-online.de>
+ * Originally developed by AMD for 2.4/2.6
+ *
+ * Development of this chipset driver was funded
+ * by the nice folks at National Semiconductor/AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Documentation:
+ * CS5535 documentation available from AMD
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include "ide-timing.h"
+
+#define MSR_ATAC_BASE 0x51300000
+#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
+#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
+#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
+#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
+#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
+#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
+#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
+#define ATAC_RESET (MSR_ATAC_BASE+0x10)
+#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
+#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
+#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
+#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
+#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
+#define ATAC_BM0_CMD_PRIM 0x00
+#define ATAC_BM0_STS_PRIM 0x02
+#define ATAC_BM0_PRD 0x04
+#define CS5535_CABLE_DETECT 0x48
+
+/* Format I PIO settings. We seperate out cmd and data for safer timings */
+
+static unsigned int cs5535_pio_cmd_timings[5] =
+{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
+static unsigned int cs5535_pio_dta_timings[5] =
+{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
+
+static unsigned int cs5535_mwdma_timings[3] =
+{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
+
+static unsigned int cs5535_udma_timings[5] =
+{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
+
+/* Macros to check if the register is the reset value - reset value is an
+ invalid timing and indicates the register has not been set previously */
+
+#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
+#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
+
+/****
+ * cs5535_set_speed - Configure the chipset to the new speed
+ * @drive: Drive to set up
+ * @speed: desired speed
+ *
+ * cs5535_set_speed() configures the chipset to a new speed.
+ */
+static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
+{
+
+ u32 reg = 0, dummy;
+ int unit = drive->select.b.unit;
+
+
+ /* Set the PIO timings */
+ if ((speed & XFER_MODE) == XFER_PIO) {
+ u8 pioa;
+ u8 piob;
+ u8 cmd;
+
+ pioa = speed - XFER_PIO_0;
+ piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
+ 255, 4, NULL);
+ cmd = pioa < piob ? pioa : piob;
+
+ /* Write the speed of the current drive */
+ reg = (cs5535_pio_cmd_timings[cmd] << 16) |
+ cs5535_pio_dta_timings[pioa];
+ wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
+
+ /* And if nessesary - change the speed of the other drive */
+ rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
+
+ if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
+ cs5535_pio_cmd_timings[cmd]) {
+ reg &= 0x0000FFFF;
+ reg |= cs5535_pio_cmd_timings[cmd] << 16;
+ wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
+ }
+
+ /* Set bit 31 of the DMA register for PIO format 1 timings */
+ rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
+ wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
+ reg | 0x80000000UL, 0);
+ } else {
+ rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
+
+ reg &= 0x80000000UL; /* Preserve the PIO format bit */
+
+ if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
+ reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
+ else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+ reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
+ else
+ return;
+
+ wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
+ }
+}
+
+static u8 cs5535_ratemask(ide_drive_t *drive)
+{
+ /* eighty93 will return 1 if it's 80core and capable of
+ exceeding udma2, 0 otherwise. we need ratemask to set
+ the max speed and if we can > udma2 then we return 2
+ which selects speed_max as udma4 which is the 5535's max
+ speed, and 1 selects udma2 which is the max for 40c */
+ if (!eighty_ninty_three(drive))
+ return 1;
+
+ return 2;
+}
+
+
+/****
+ * cs5535_set_drive - Configure the drive to the new speed
+ * @drive: Drive to set up
+ * @speed: desired speed
+ *
+ * cs5535_set_drive() configures the drive and the chipset to a
+ * new speed. It also can be called by upper layers.
+ */
+static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
+{
+ speed = ide_rate_filter(cs5535_ratemask(drive), speed);
+ ide_config_drive_speed(drive, speed);
+ cs5535_set_speed(drive, speed);
+
+ return 0;
+}
+
+/****
+ * cs5535_tuneproc - PIO setup
+ * @drive: drive to set up
+ * @pio: mode to use (255 for 'best possible')
+ *
+ * A callback from the upper layers for PIO-only tuning.
+ */
+static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
+{
+ u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
+ XFER_PIO_4 };
+
+ /* cs5535 max pio is pio 4, best_pio will check the blacklist.
+ i think we don't need to rate_filter the incoming xferspeed
+ since we know we're only going to choose pio */
+ xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
+ ide_config_drive_speed(drive, modes[xferspeed]);
+ cs5535_set_speed(drive, xferspeed);
+}
+
+static int cs5535_config_drive_for_dma(ide_drive_t *drive)
+{
+ u8 speed;
+
+ speed = ide_dma_speed(drive, cs5535_ratemask(drive));
+
+ /* If no DMA speed was available then let dma_check hit pio */
+ if (!speed) {
+ return 0;
+ }
+
+ cs5535_set_drive(drive, speed);
+ return ide_dma_enable(drive);
+}
+
+static int cs5535_dma_check(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct hd_driveid *id = drive->id;
+ u8 speed;
+
+ drive->init_speed = 0;
+
+ if ((id->capability & 1) && drive->autodma) {
+ if (ide_use_dma(drive)) {
+ if (cs5535_config_drive_for_dma(drive))
+ return hwif->ide_dma_on(drive);
+ }
+
+ goto fast_ata_pio;
+
+ } else if ((id->capability & 8) || (id->field_valid & 2)) {
+fast_ata_pio:
+ speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
+ cs5535_set_drive(drive, speed);
+ return hwif->ide_dma_off_quietly(drive);
+ }
+ /* IORDY not supported */
+ return 0;
+}
+
+static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
+{
+ u8 bit;
+
+ /* if a 80 wire cable was detected */
+ pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
+ return (bit & 1);
+}
+
+/****
+ * init_hwif_cs5535 - Initialize one ide cannel
+ * @hwif: Channel descriptor
+ *
+ * This gets invoked by the IDE driver once for each channel. It
+ * performs channel-specific pre-initialization before drive probing.
+ *
+ */
+static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
+{
+ int i;
+
+ hwif->autodma = 0;
+
+ hwif->tuneproc = &cs5535_tuneproc;
+ hwif->speedproc = &cs5535_set_drive;
+ hwif->ide_dma_check = &cs5535_dma_check;
+
+ hwif->atapi_dma = 1;
+ hwif->ultra_mask = 0x1F;
+ hwif->mwdma_mask = 0x07;
+
+
+ hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
+
+ if (!noautodma)
+ hwif->autodma = 1;
+
+ /* just setting autotune and not worrying about bios timings */
+ for (i = 0; i < 2; i++) {
+ hwif->drives[i].autotune = 1;
+ hwif->drives[i].autodma = hwif->autodma;
+ }
+}
+
+static ide_pci_device_t cs5535_chipset __devinitdata = {
+ .name = "CS5535",
+ .init_hwif = init_hwif_cs5535,
+ .channels = 1,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+};
+
+static int __devinit cs5535_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return ide_setup_pci_device(dev, &cs5535_chipset);
+}
+
+static struct pci_device_id cs5535_pci_tbl[] =
+{
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
+
+static struct pci_driver driver = {
+ .name = "CS5535_IDE",
+ .id_table = cs5535_pci_tbl,
+ .probe = cs5535_init_one,
+};
+
+static int __init cs5535_ide_init(void)
+{
+ return ide_pci_register_driver(&driver);
+}
+
+module_init(cs5535_ide_init);
+
+MODULE_AUTHOR("AMD");
+MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
+MODULE_LICENSE("GPL");
Index: linux-2.6.14/drivers/ide/pci/Makefile
===================================================================
--- linux-2.6.14.orig/drivers/ide/pci/Makefile
+++ linux-2.6.14/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.
obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
+obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
--
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 5/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
` (3 preceding siblings ...)
2005-10-28 15:51 ` [PATCH 4/6] " Jordan Crouse
@ 2005-10-28 15:53 ` Jordan Crouse
2005-10-28 15:55 ` [6/6] " Jordan Crouse
5 siblings, 0 replies; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:53 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux
Patch for the AMD LX RNG device. Allow me to say at this point that even
though I'm patching the current file, I am in favor of the recent RNG rewrite
that was proposed a few weeks ago. Changelog:
* Remove defines, style cleanups (Vladis Kletnieks, Alan Cox, Andi Kleen)
* Replace pointer derefrences with readl (Vladis, Alan and Andi again)
* Add asserts to protect against NULL dereferences (Vladis)
hw_random.c | 66
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
Index: linux-2.6.14/drivers/char/hw_random.c
===================================================================
--- linux-2.6.14.orig/drivers/char/hw_random.c
+++ linux-2.6.14/drivers/char/hw_random.c
@@ -1,4 +1,9 @@
/*
+ Added support for the AMD Geode LX RNG
+ (c) Copyright 2004-2005 Advanced Micro Devices, Inc.
+
+ derived from
+
Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
@@ -95,6 +100,11 @@ static unsigned int via_data_present (vo
static u32 via_data_read (void);
#endif
+static int __init geode_init(struct pci_dev *dev);
+static void geode_cleanup(void);
+static unsigned int geode_data_present (void);
+static u32 geode_data_read (void);
+
struct rng_operations {
int (*init) (struct pci_dev *dev);
void (*cleanup) (void);
@@ -122,6 +132,7 @@ enum {
rng_hw_intel,
rng_hw_amd,
rng_hw_via,
+ rng_hw_geode,
};
static struct rng_operations rng_vendor_ops[] = {
@@ -139,6 +150,9 @@ static struct rng_operations rng_vendor_
/* rng_hw_via */
{ via_init, via_cleanup, via_data_present, via_data_read, 1 },
#endif
+
+ /* rng_hw_geode */
+ { geode_init, geode_cleanup, geode_data_present, geode_data_read, 4 }
};
/*
@@ -159,6 +173,9 @@ static struct pci_device_id rng_pci_tbl[
{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_geode },
+
{ 0, }, /* terminate list */
};
MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
@@ -460,6 +477,53 @@ static void via_cleanup(void)
}
#endif
+/***********************************************************************
+ *
+ * AMD Geode RNG operations
+ *
+ */
+
+static void __iomem *geode_rng_base = NULL;
+
+#define GEODE_RNG_DATA_REG 0x50
+#define GEODE_RNG_STATUS_REG 0x54
+
+static u32 geode_data_read(void)
+{
+ u32 val;
+ assert(geode_rng_base != NULL);
+ val = readl(geode_rng_base + GEODE_RNG_DATA_REG);
+ return val;
+}
+
+static unsigned int geode_data_present(void)
+{
+ u32 val;
+ assert(geode_rng_base != NULL);
+ val = readl(geode_rng_base + GEODE_RNG_STATUS_REG);
+ return val;
+}
+
+static void geode_cleanup(void)
+{
+ iounmap(geode_rng_base);
+ geode_rng_base = NULL;
+}
+
+static int geode_init(struct pci_dev *dev)
+{
+ unsigned long rng_base = pci_resource_start(dev, 0);
+ if (rng_base == NULL) return 1;
+
+ geode_rng_base = ioremap(rng_base, 0x58);
+
+ if (geode_rng_base == NULL) {
+ printk(KERN_ERR PFX "Cannot ioremap RNG memory\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
/***********************************************************************
*
@@ -574,7 +638,7 @@ static int __init rng_init (void)
DPRINTK ("ENTER\n");
- /* Probe for Intel, AMD RNGs */
+ /* Probe for Intel, AMD, Geode RNGs */
for_each_pci_dev(pdev) {
ent = pci_match_id(rng_pci_tbl, pdev);
if (ent) {
^ permalink raw reply [flat|nested] 12+ messages in thread* [6/6] AMD Geode GX/LX Support (Refreshed)
[not found] <LYRIS-4270-74122-2005.10.28-09.38.17--jordan.crouse#amd.com@whitestar.amd.com>
` (4 preceding siblings ...)
2005-10-28 15:53 ` [PATCH 5/6] " Jordan Crouse
@ 2005-10-28 15:55 ` Jordan Crouse
2005-11-09 22:25 ` Bartlomiej Zolnierkiewicz
5 siblings, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2005-10-28 15:55 UTC (permalink / raw)
To: linux-kernel; +Cc: info-linux, linux-ide
The core IDE engine on the CS5536 is the same as the other AMD southbridges,
so unlike the CS5535, we can simply add the appropriate PCI headers to
the existing amd74xx code.
drivers/ide/pci/amd74xx.c | 3 +++
include/linux/pci_ids.h | 9 +++++++++
2 files changed, 12 insertions(+)
Index: linux-2.6.14/drivers/ide/pci/amd74xx.c
===================================================================
--- linux-2.6.14.orig/drivers/ide/pci/amd74xx.c
+++ linux-2.6.14/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
{ 0 }
};
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets
/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
/* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
/* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
+ /* 17 */ DECLARE_AMD_DEV("AMD5536"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
Index: linux-2.6.14/include/linux/pci_ids.h
===================================================================
--- linux-2.6.14.orig/include/linux/pci_ids.h
+++ linux-2.6.14/include/linux/pci_ids.h
@@ -546,6 +546,15 @@
#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
+#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090
+#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091
+#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
+#define PCI_DEVICE_ID_AMD_CS5536_OHC 0x2094
+#define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095
+#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096
+#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097
+#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
+
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
^ permalink raw reply [flat|nested] 12+ messages in thread