2 * Copyright (C) 2004 IBM Corporation
5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Dave Safford <safford@watson.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com>
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net>
12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation, version 2 of the
24 /* National definitions */
25 #define TPM_NSC_BASE 0x360
26 #define TPM_NSC_IRQ 0x07
28 #define NSC_LDN_INDEX 0x07
29 #define NSC_SID_INDEX 0x20
30 #define NSC_LDC_INDEX 0x30
31 #define NSC_DIO_INDEX 0x60
32 #define NSC_CIO_INDEX 0x62
33 #define NSC_IRQ_INDEX 0x70
34 #define NSC_ITS_INDEX 0x71
36 #define NSC_STATUS 0x01
37 #define NSC_COMMAND 0x01
41 #define NSC_STATUS_OBF 0x01 /* output buffer full */
42 #define NSC_STATUS_IBF 0x02 /* input buffer full */
43 #define NSC_STATUS_F0 0x04 /* F0 */
44 #define NSC_STATUS_A2 0x08 /* A2 */
45 #define NSC_STATUS_RDY 0x10 /* ready to receive command */
46 #define NSC_STATUS_IBR 0x20 /* ready to receive data */
49 #define NSC_COMMAND_NORMAL 0x01 /* normal mode */
50 #define NSC_COMMAND_EOC 0x03
51 #define NSC_COMMAND_CANCEL 0x22
54 * Wait for a certain status to appear
56 static int wait_for_stat(struct tpm_chip
*chip
, u8 mask
, u8 val
, u8
* data
)
59 struct timer_list status_timer
=
60 TIMER_INITIALIZER(tpm_time_expired
, jiffies
+ 10 * HZ
,
61 (unsigned long) &expired
);
63 /* status immediately available check */
64 *data
= inb(chip
->vendor
->base
+ NSC_STATUS
);
65 if ((*data
& mask
) == val
)
69 add_timer(&status_timer
);
71 set_current_state(TASK_UNINTERRUPTIBLE
);
72 schedule_timeout(TPM_TIMEOUT
);
73 *data
= inb(chip
->vendor
->base
+ 1);
74 if ((*data
& mask
) == val
) {
75 del_singleshot_timer_sync(&status_timer
);
84 static int nsc_wait_for_ready(struct tpm_chip
*chip
)
88 struct timer_list status_timer
=
89 TIMER_INITIALIZER(tpm_time_expired
, jiffies
+ 100,
90 (unsigned long) &expired
);
92 /* status immediately available check */
93 status
= inb(chip
->vendor
->base
+ NSC_STATUS
);
94 if (status
& NSC_STATUS_OBF
)
95 status
= inb(chip
->vendor
->base
+ NSC_DATA
);
96 if (status
& NSC_STATUS_RDY
)
100 add_timer(&status_timer
);
102 set_current_state(TASK_UNINTERRUPTIBLE
);
103 schedule_timeout(TPM_TIMEOUT
);
104 status
= inb(chip
->vendor
->base
+ NSC_STATUS
);
105 if (status
& NSC_STATUS_OBF
)
106 status
= inb(chip
->vendor
->base
+ NSC_DATA
);
107 if (status
& NSC_STATUS_RDY
) {
108 del_singleshot_timer_sync(&status_timer
);
114 dev_info(&chip
->pci_dev
->dev
, "wait for ready failed\n");
119 static int tpm_nsc_recv(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
129 if (wait_for_stat(chip
, NSC_STATUS_F0
, NSC_STATUS_F0
, &data
) < 0) {
130 dev_err(&chip
->pci_dev
->dev
, "F0 timeout\n");
134 inb(chip
->vendor
->base
+ NSC_DATA
)) != NSC_COMMAND_NORMAL
) {
135 dev_err(&chip
->pci_dev
->dev
, "not in normal mode (0x%x)\n",
140 /* read the whole packet */
141 for (p
= buffer
; p
< &buffer
[count
]; p
++) {
143 (chip
, NSC_STATUS_OBF
, NSC_STATUS_OBF
, &data
) < 0) {
144 dev_err(&chip
->pci_dev
->dev
,
145 "OBF timeout (while reading data)\n");
148 if (data
& NSC_STATUS_F0
)
150 *p
= inb(chip
->vendor
->base
+ NSC_DATA
);
153 if ((data
& NSC_STATUS_F0
) == 0) {
154 dev_err(&chip
->pci_dev
->dev
, "F0 not set\n");
157 if ((data
= inb(chip
->vendor
->base
+ NSC_DATA
)) != NSC_COMMAND_EOC
) {
158 dev_err(&chip
->pci_dev
->dev
,
159 "expected end of command(0x%x)\n", data
);
163 native_size
= (__force __be32
*) (buf
+ 2);
164 size
= be32_to_cpu(*native_size
);
172 static int tpm_nsc_send(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
178 * If we hit the chip with back to back commands it locks up
179 * and never set IBF. Hitting it with this "hammer" seems to
180 * fix it. Not sure why this is needed, we followed the flow
181 * chart in the manual to the letter.
183 outb(NSC_COMMAND_CANCEL
, chip
->vendor
->base
+ NSC_COMMAND
);
185 if (nsc_wait_for_ready(chip
) != 0)
188 if (wait_for_stat(chip
, NSC_STATUS_IBF
, 0, &data
) < 0) {
189 dev_err(&chip
->pci_dev
->dev
, "IBF timeout\n");
193 outb(NSC_COMMAND_NORMAL
, chip
->vendor
->base
+ NSC_COMMAND
);
194 if (wait_for_stat(chip
, NSC_STATUS_IBR
, NSC_STATUS_IBR
, &data
) < 0) {
195 dev_err(&chip
->pci_dev
->dev
, "IBR timeout\n");
199 for (i
= 0; i
< count
; i
++) {
200 if (wait_for_stat(chip
, NSC_STATUS_IBF
, 0, &data
) < 0) {
201 dev_err(&chip
->pci_dev
->dev
,
202 "IBF timeout (while writing data)\n");
205 outb(buf
[i
], chip
->vendor
->base
+ NSC_DATA
);
208 if (wait_for_stat(chip
, NSC_STATUS_IBF
, 0, &data
) < 0) {
209 dev_err(&chip
->pci_dev
->dev
, "IBF timeout\n");
212 outb(NSC_COMMAND_EOC
, chip
->vendor
->base
+ NSC_COMMAND
);
217 static void tpm_nsc_cancel(struct tpm_chip
*chip
)
219 outb(NSC_COMMAND_CANCEL
, chip
->vendor
->base
+ NSC_COMMAND
);
222 static struct file_operations nsc_ops
= {
223 .owner
= THIS_MODULE
,
228 .release
= tpm_release
,
231 static struct tpm_vendor_specific tpm_nsc
= {
232 .recv
= tpm_nsc_recv
,
233 .send
= tpm_nsc_send
,
234 .cancel
= tpm_nsc_cancel
,
235 .req_complete_mask
= NSC_STATUS_OBF
,
236 .req_complete_val
= NSC_STATUS_OBF
,
237 .base
= TPM_NSC_BASE
,
238 .miscdev
= { .fops
= &nsc_ops
, },
242 static int __devinit
tpm_nsc_init(struct pci_dev
*pci_dev
,
243 const struct pci_device_id
*pci_id
)
247 if (pci_enable_device(pci_dev
))
250 if (tpm_lpc_bus_init(pci_dev
, TPM_NSC_BASE
)) {
255 /* verify that it is a National part (SID) */
256 if (tpm_read_index(NSC_SID_INDEX
) != 0xEF) {
261 dev_dbg(&pci_dev
->dev
, "NSC TPM detected\n");
262 dev_dbg(&pci_dev
->dev
,
263 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
264 tpm_read_index(0x07), tpm_read_index(0x20),
265 tpm_read_index(0x27));
266 dev_dbg(&pci_dev
->dev
,
267 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
268 tpm_read_index(0x21), tpm_read_index(0x25),
269 tpm_read_index(0x26), tpm_read_index(0x28));
270 dev_dbg(&pci_dev
->dev
, "NSC IO Base0 0x%x\n",
271 (tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
272 dev_dbg(&pci_dev
->dev
, "NSC IO Base1 0x%x\n",
273 (tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
274 dev_dbg(&pci_dev
->dev
, "NSC Interrupt number and wakeup 0x%x\n",
275 tpm_read_index(0x70));
276 dev_dbg(&pci_dev
->dev
, "NSC IRQ type select 0x%x\n",
277 tpm_read_index(0x71));
278 dev_dbg(&pci_dev
->dev
,
279 "NSC DMA channel select0 0x%x, select1 0x%x\n",
280 tpm_read_index(0x74), tpm_read_index(0x75));
281 dev_dbg(&pci_dev
->dev
,
283 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
284 tpm_read_index(0xF0), tpm_read_index(0xF1),
285 tpm_read_index(0xF2), tpm_read_index(0xF3),
286 tpm_read_index(0xF4), tpm_read_index(0xF5),
287 tpm_read_index(0xF6), tpm_read_index(0xF7),
288 tpm_read_index(0xF8), tpm_read_index(0xF9));
290 dev_info(&pci_dev
->dev
,
291 "NSC PC21100 TPM revision %d\n",
292 tpm_read_index(0x27) & 0x1F);
294 if (tpm_read_index(NSC_LDC_INDEX
) == 0)
295 dev_info(&pci_dev
->dev
, ": NSC TPM not active\n");
297 /* select PM channel 1 */
298 tpm_write_index(NSC_LDN_INDEX
, 0x12);
299 tpm_read_index(NSC_LDN_INDEX
);
301 /* disable the DPM module */
302 tpm_write_index(NSC_LDC_INDEX
, 0);
303 tpm_read_index(NSC_LDC_INDEX
);
305 /* set the data register base addresses */
306 tpm_write_index(NSC_DIO_INDEX
, TPM_NSC_BASE
>> 8);
307 tpm_write_index(NSC_DIO_INDEX
+ 1, TPM_NSC_BASE
);
308 tpm_read_index(NSC_DIO_INDEX
);
309 tpm_read_index(NSC_DIO_INDEX
+ 1);
311 /* set the command register base addresses */
312 tpm_write_index(NSC_CIO_INDEX
, (TPM_NSC_BASE
+ 1) >> 8);
313 tpm_write_index(NSC_CIO_INDEX
+ 1, (TPM_NSC_BASE
+ 1));
314 tpm_read_index(NSC_DIO_INDEX
);
315 tpm_read_index(NSC_DIO_INDEX
+ 1);
317 /* set the interrupt number to be used for the host interface */
318 tpm_write_index(NSC_IRQ_INDEX
, TPM_NSC_IRQ
);
319 tpm_write_index(NSC_ITS_INDEX
, 0x00);
320 tpm_read_index(NSC_IRQ_INDEX
);
322 /* enable the DPM module */
323 tpm_write_index(NSC_LDC_INDEX
, 0x01);
324 tpm_read_index(NSC_LDC_INDEX
);
326 if ((rc
= tpm_register_hardware(pci_dev
, &tpm_nsc
)) < 0)
332 pci_disable_device(pci_dev
);
336 static struct pci_device_id tpm_pci_tbl
[] __devinitdata
= {
337 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82801BA_0
)},
338 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82801CA_12
)},
339 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82801DB_0
)},
340 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82801DB_12
)},
341 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82801EB_0
)},
342 {PCI_DEVICE(PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD_8111_LPC
)},
346 MODULE_DEVICE_TABLE(pci
, tpm_pci_tbl
);
348 static struct pci_driver nsc_pci_driver
= {
350 .id_table
= tpm_pci_tbl
,
351 .probe
= tpm_nsc_init
,
352 .remove
= __devexit_p(tpm_remove
),
353 .suspend
= tpm_pm_suspend
,
354 .resume
= tpm_pm_resume
,
357 static int __init
init_nsc(void)
359 return pci_register_driver(&nsc_pci_driver
);
362 static void __exit
cleanup_nsc(void)
364 pci_unregister_driver(&nsc_pci_driver
);
367 module_init(init_nsc
);
368 module_exit(cleanup_nsc
);
370 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
371 MODULE_DESCRIPTION("TPM Driver");
372 MODULE_VERSION("2.0");
373 MODULE_LICENSE("GPL");