| 1 | --- /dev/null |
| 2 | +++ b/Documentation/x86/rdc.txt |
| 3 | @@ -0,0 +1,69 @@ |
| 4 | + |
| 5 | +Introduction |
| 6 | +============ |
| 7 | + |
| 8 | +RDC (http://www.rdc.com.tw) have been manufacturing x86-compatible SoC |
| 9 | +(system-on-chips) for a number of years. They are not the fastest of |
| 10 | +CPUs (clock speeds ranging from 133-150MHz) but 486SX compatibility |
| 11 | +coupled with very low power consumption[1] and low cost make them ideal |
| 12 | +for embedded applications. |
| 13 | + |
| 14 | + |
| 15 | +Where to find |
| 16 | +============= |
| 17 | + |
| 18 | +RDC chips show up in numerous embedded devices, but be careful since |
| 19 | +many of them will not run Linux 2.6 without significant expertise. |
| 20 | + |
| 21 | +There are several variants of what the linux kernel refers to generically |
| 22 | +as RDC321X: R8610, R321x, S3282 and AMRISC20000. |
| 23 | + |
| 24 | +R321x: Found in various routers, see the OpenWrt project for details, |
| 25 | + http://wiki.openwrt.org/oldwiki/rdcport |
| 26 | + |
| 27 | +R8610: Found on the RDC evaluation board |
| 28 | + http://www.ivankuten.com/system-on-chip-soc/rdc-r8610/ |
| 29 | + |
| 30 | +AMRISC20000: Found in the MGB-100 wireless hard disk |
| 31 | + http://tintuc.no-ip.com/linux/tipps/mgb100/ |
| 32 | + |
| 33 | +S3282: Found in various NAS devices, including the Bifferboard |
| 34 | + http://www.bifferos.com |
| 35 | + |
| 36 | + |
| 37 | +Kernel Configuration |
| 38 | +==================== |
| 39 | + |
| 40 | +Add support for this CPU with CONFIG_X86_RDC321X. Ensure that maths |
| 41 | +emulation is included (CONFIG_MATH_EMULATION selected) and avoid MCE |
| 42 | +(CONFIG_X86_MCE not selected). |
| 43 | + |
| 44 | + |
| 45 | +CPU detection |
| 46 | +============= |
| 47 | + |
| 48 | +None of these chips support the cpuid instruction, so as with some |
| 49 | +other x86 compatible SoCs, we must check the north bridge and look |
| 50 | +for specific 'signature' PCI device config. |
| 51 | + |
| 52 | +The current detection code has been tested only on the Bifferboard |
| 53 | +(S3282 CPU), please send bug reports or success stories with |
| 54 | +other devices to bifferos@yahoo.co.uk. |
| 55 | + |
| 56 | + |
| 57 | +Credits |
| 58 | +======= |
| 59 | + |
| 60 | +Many thanks to RDC for providing the customer codes to allow |
| 61 | +detection of all known variants, without which this detection code |
| 62 | +would have been very hard to ascertain. |
| 63 | + |
| 64 | + |
| 65 | +References |
| 66 | +========== |
| 67 | + |
| 68 | +[1] S3282 in certain NAS solutions consumes less than 1W |
| 69 | + |
| 70 | + |
| 71 | +mark@bifferos.com 2009 |
| 72 | + |
| 73 | --- a/arch/x86/Kconfig |
| 74 | +++ b/arch/x86/Kconfig |
| 75 | @@ -378,6 +378,7 @@ config X86_RDC321X |
| 76 | bool "RDC R-321x SoC" |
| 77 | depends on X86_32 |
| 78 | depends on X86_EXTENDED_PLATFORM |
| 79 | + select PCI |
| 80 | select M486 |
| 81 | select X86_REBOOTFIXUPS |
| 82 | select EMBEDDED |
| 83 | --- a/arch/x86/include/asm/processor.h |
| 84 | +++ b/arch/x86/include/asm/processor.h |
| 85 | @@ -121,7 +121,8 @@ struct cpuinfo_x86 { |
| 86 | #define X86_VENDOR_CENTAUR 5 |
| 87 | #define X86_VENDOR_TRANSMETA 7 |
| 88 | #define X86_VENDOR_NSC 8 |
| 89 | -#define X86_VENDOR_NUM 9 |
| 90 | +#define X86_VENDOR_RDC 9 |
| 91 | +#define X86_VENDOR_NUM 10 |
| 92 | |
| 93 | #define X86_VENDOR_UNKNOWN 0xff |
| 94 | |
| 95 | --- a/arch/x86/kernel/cpu/Makefile |
| 96 | +++ b/arch/x86/kernel/cpu/Makefile |
| 97 | @@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix |
| 98 | obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o |
| 99 | obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o |
| 100 | obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o |
| 101 | +obj-$(CONFIG_X86_RDC321X) += rdc.o |
| 102 | |
| 103 | obj-$(CONFIG_X86_MCE) += mcheck/ |
| 104 | obj-$(CONFIG_MTRR) += mtrr/ |
| 105 | --- /dev/null |
| 106 | +++ b/arch/x86/kernel/cpu/rdc.c |
| 107 | @@ -0,0 +1,69 @@ |
| 108 | +/* |
| 109 | + * See Documentation/x86/rdc.txt |
| 110 | + * |
| 111 | + * mark@bifferos.com |
| 112 | + */ |
| 113 | + |
| 114 | +#include <linux/pci.h> |
| 115 | +#include <asm/pci-direct.h> |
| 116 | +#include "cpu.h" |
| 117 | + |
| 118 | + |
| 119 | +static void __cpuinit rdc_identify(struct cpuinfo_x86 *c) |
| 120 | +{ |
| 121 | + u16 vendor, device; |
| 122 | + u32 customer_id; |
| 123 | + |
| 124 | + if (!early_pci_allowed()) |
| 125 | + return; |
| 126 | + |
| 127 | + /* RDC CPU is SoC (system-on-chip), Northbridge is always present */ |
| 128 | + vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); |
| 129 | + device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); |
| 130 | + |
| 131 | + if (vendor != PCI_VENDOR_ID_RDC || device != PCI_DEVICE_ID_RDC_R6020) |
| 132 | + return; /* not RDC */ |
| 133 | + /* |
| 134 | + * NB: We could go on and check other devices, e.g. r6040 NIC, but |
| 135 | + * that's probably overkill |
| 136 | + */ |
| 137 | + |
| 138 | + customer_id = read_pci_config(0, 0, 0, 0x90); |
| 139 | + |
| 140 | + switch (customer_id) { |
| 141 | + /* id names are from RDC */ |
| 142 | + case 0x00321000: |
| 143 | + strcpy(c->x86_model_id, "R3210/R3211"); |
| 144 | + break; |
| 145 | + case 0x00321001: |
| 146 | + strcpy(c->x86_model_id, "AMITRISC20000/20010"); |
| 147 | + break; |
| 148 | + case 0x00321002: |
| 149 | + strcpy(c->x86_model_id, "R3210X/Edimax"); |
| 150 | + break; |
| 151 | + case 0x00321003: |
| 152 | + strcpy(c->x86_model_id, "R3210/Kcodes"); |
| 153 | + break; |
| 154 | + case 0x00321004: /* tested */ |
| 155 | + strcpy(c->x86_model_id, "S3282/CodeTek"); |
| 156 | + break; |
| 157 | + case 0x00321007: |
| 158 | + strcpy(c->x86_model_id, "R8610"); |
| 159 | + break; |
| 160 | + default: |
| 161 | + pr_info("RDC CPU: Unrecognised Customer ID (0x%x) please report to linux-kernel@vger.kernel.org\n", customer_id); |
| 162 | + return; |
| 163 | + } |
| 164 | + |
| 165 | + strcpy(c->x86_vendor_id, "RDC"); |
| 166 | + c->x86_vendor = X86_VENDOR_RDC; |
| 167 | +} |
| 168 | + |
| 169 | +static const struct cpu_dev __cpuinitconst rdc_cpu_dev = { |
| 170 | + .c_vendor = "RDC", |
| 171 | + .c_ident = { "RDC" }, |
| 172 | + .c_identify = rdc_identify, |
| 173 | + .c_x86_vendor = X86_VENDOR_RDC, |
| 174 | +}; |
| 175 | + |
| 176 | +cpu_dev_register(rdc_cpu_dev); |
| 177 | |