coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
early_serial.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /* Pre-RAM driver for SMSC LPC47N227 Super I/O chip. */
4 
5 #include <arch/io.h>
6 #include <assert.h>
7 #include <device/pnp_ops.h>
8 
9 #include "lpc47n227.h"
10 
12 {
13  u16 port = dev >> 8;
14  outb(0x55, port);
15 }
16 
18 {
19  u16 port = dev >> 8;
20  outb(0xaa, port);
21 }
22 
23 /**
24  * Program the base I/O port for the specified logical device.
25  *
26  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
27  * @param iobase Base I/O port for the logical device.
28  */
29 static void lpc47n227_pnp_set_iobase(pnp_devfn_t dev, u16 iobase)
30 {
31  /* LPC47N227 requires base ports to be a multiple of 4. */
32  /* it's not very useful to do an ASSERT here: if it trips,
33  * there's no console to report it.
34  ASSERT(!(iobase & 0x3));
35  */
36 
37  switch (dev & 0xFF) {
38  case LPC47N227_PP:
39  pnp_write_config(dev, 0x23, (iobase >> 2) & 0xff);
40  break;
41  case LPC47N227_SP1:
42  pnp_write_config(dev, 0x24, (iobase >> 2) & 0xff);
43  break;
44  case LPC47N227_SP2:
45  pnp_write_config(dev, 0x25, (iobase >> 2) & 0xff);
46  break;
47  default:
48  break;
49  }
50 }
51 
52 /**
53  * Enable or disable the specified logical device.
54  *
55  * Technically, a full disable requires setting the device's base I/O port
56  * below 0x100. We don't do that here, because we don't have access to a data
57  * structure that specifies what the 'real' base port is (when asked to enable
58  * the device). Also the function is used only to disable the device while its
59  * true base port is programmed (see lpc47n227_enable_serial() below).
60  *
61  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
62  * @param enable 0 to disable, anything else to enable.
63  */
64 static void lpc47n227_pnp_set_enable(pnp_devfn_t dev, int enable)
65 {
66  u8 power_register = 0, power_mask = 0, current_power, new_power;
67 
68  switch (dev & 0xFF) {
69  case LPC47N227_PP:
70  power_register = 0x01;
71  power_mask = 0x04;
72  break;
73  case LPC47N227_SP1:
74  power_register = 0x02;
75  power_mask = 0x08;
76  break;
77  case LPC47N227_SP2:
78  power_register = 0x02;
79  power_mask = 0x80;
80  break;
81  default:
82  return;
83  }
84 
85  current_power = pnp_read_config(dev, power_register);
86  new_power = current_power & ~power_mask; /* Disable by default. */
87  if (enable)
88  new_power |= power_mask; /* Enable. */
89  pnp_write_config(dev, power_register, new_power);
90 }
91 
92 /**
93  * Configure the base I/O port of the specified serial device and enable the
94  * serial device.
95  *
96  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
97  * @param iobase Processor I/O port address to assign to this serial device.
98  */
100 {
101  /*
102  * NOTE: Cannot use pnp_set_XXX() here because they assume chip
103  * support for logical devices, which the LPC47N227 doesn't have.
104  */
106  lpc47n227_pnp_set_enable(dev, 0);
107  lpc47n227_pnp_set_iobase(dev, iobase);
108  lpc47n227_pnp_set_enable(dev, 1);
109  pnp_exit_conf_state(dev);
110 }
void pnp_exit_conf_state(pnp_devfn_t dev)
Definition: early_serial.c:38
void pnp_enter_conf_state(pnp_devfn_t dev)
Definition: early_serial.c:30
void outb(u8 val, u16 port)
port
Definition: i915.h:29
#define LPC47N227_SP2
Definition: lpc47n227.h:15
#define LPC47N227_PP
Definition: lpc47n227.h:13
#define LPC47N227_SP1
Definition: lpc47n227.h:14
u8 pnp_read_config(struct device *dev, u8 reg)
Definition: pnp_device.c:44
void pnp_write_config(struct device *dev, u8 reg, u8 value)
Definition: pnp_device.c:38
u32 pnp_devfn_t
Definition: pnp_type.h:8
void lpc47n227_enable_serial(pnp_devfn_t dev, u16 iobase)
Configure the base I/O port of the specified serial device and enable the serial device.
Definition: early_serial.c:99
static void lpc47n227_pnp_set_iobase(pnp_devfn_t dev, u16 iobase)
Program the base I/O port for the specified logical device.
Definition: early_serial.c:29
static void lpc47n227_pnp_set_enable(pnp_devfn_t dev, int enable)
Enable or disable the specified logical device.
Definition: early_serial.c:64
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45