tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / superio / smsc / lpc47n207 / early_serial.c
blob175ea83d21956d015292f61ea579b6b725c7929f
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/io.h>
17 #include <device/pnp.h>
18 #include <stdint.h>
19 #include <stdlib.h>
20 #include "lpc47n207.h"
23 * This code tries to discover the SMSC LPC47N207 superio chip which can be
24 * connected over an LPC dongle. The chip could be bootstrap mapped to one of
25 * four LPC addresses: 0x2e, 0x4e, 0x162e, and 0x164e.
27 * Initializing the UART requires accesses to a few control registers. This
28 * structure includes the register offset and the value to write (along with
29 * the mask).
31 typedef struct {
32 u8 conf_reg;
33 u8 value;
34 u8 mask;
35 } uart_conf;
37 /* All regs/values to write to initialize the LPC47N207 UART */
38 static const uart_conf uart_conf_data [] = {
39 {2, (1 << 3), (1 << 3)}, /* cr02, enable Primary UART power */
40 {0xc, (1 << 6), (1 << 6)}, /* cr0c, enable Primary UART high speed */
41 {0x24, (CONFIG_TTYS0_BASE >> 3) << 1, 0xff}, /* cr24, base addr */
44 void try_enabling_LPC47N207_uart(void)
46 u8 reg_value;
47 const uart_conf* conf_item;
48 u16 lpc_ports[] = {0x2e, 0x4e, 0x162e, 0x164e};
49 u16 lpc_port;
50 int i, j;
52 #define CONFIG_ENABLE 0x55
53 #define CONFIG_DISABLE 0xaa
55 for (j = 0; j < ARRAY_SIZE(lpc_ports); j++) {
56 lpc_port = lpc_ports[j];
58 /* enable CONFIG mode */
59 outb(CONFIG_ENABLE, lpc_port);
60 reg_value=inb(lpc_port);
61 if (reg_value != CONFIG_ENABLE) {
62 continue; /* There is no LPC device at this address */
65 do {
67 * Registers 12 and 13 hold config address, look for a
68 * match.
70 outb(0x12, lpc_port);
71 reg_value=inb(lpc_port + 1);
72 if (reg_value != (lpc_port & 0xff))
73 break;
75 outb(0x13, lpc_port);
76 reg_value=inb(lpc_port + 1);
77 if (reg_value != (lpc_port >> 8))
78 break;
80 /* This must be the SMSC LPC 47N207, enable the UART. */
81 for (i = 0; i < ARRAY_SIZE(uart_conf_data); i++) {
82 u8 reg, value, mask;
84 conf_item = uart_conf_data + i;
86 reg = conf_item->conf_reg;
87 value = conf_item->value;
88 mask = conf_item->mask;
90 outb(reg, lpc_port);
91 reg_value = inb(lpc_port + 1);
92 reg_value &= ~mask;
93 reg_value |= (value & mask);
94 outb(reg_value, lpc_port + 1);
96 } while (0);
97 outb(CONFIG_DISABLE, lpc_port);