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-or-later */
2 
3 /* Pre-RAM driver for SMSC LPC47N217 Super I/O chip. */
4 
5 #include <arch/io.h>
6 #include <device/pnp_ops.h>
7 #include <assert.h>
8 #include "lpc47n217.h"
9 
11 {
12  u16 port = dev >> 8;
13  outb(0x55, port);
14 }
15 
17 {
18  u16 port = dev >> 8;
19  outb(0xaa, port);
20 }
21 
22 /**
23  * Program the base I/O port for the specified logical device.
24  *
25  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
26  * @param iobase Base I/O port for the logical device.
27  */
28 static void lpc47n217_pnp_set_iobase(pnp_devfn_t dev, u16 iobase)
29 {
30  /* LPC47N217 requires base ports to be a multiple of 4. */
31  ASSERT(!(iobase & 0x3));
32 
33  switch (dev & 0xFF) {
34  case LPC47N217_PP:
35  pnp_write_config(dev, 0x23, (iobase >> 2) & 0xff);
36  break;
37  case LPC47N217_SP1:
38  pnp_write_config(dev, 0x24, (iobase >> 2) & 0xff);
39  break;
40  case LPC47N217_SP2:
41  pnp_write_config(dev, 0x25, (iobase >> 2) & 0xff);
42  break;
43  default:
44  break;
45  }
46 }
47 
48 /**
49  * Enable or disable the specified logical device.
50  *
51  * Technically, a full disable requires setting the device's base I/O port
52  * below 0x100. We don't do that here, because we don't have access to a data
53  * structure that specifies what the 'real' base port is (when asked to enable
54  * the device). Also the function is used only to disable the device while its
55  * true base port is programmed (see lpc47n217_enable_serial() below).
56  *
57  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
58  * @param enable 0 to disable, anything else to enable.
59  */
60 static void lpc47n217_pnp_set_enable(pnp_devfn_t dev, int enable)
61 {
62  u8 power_register = 0, power_mask = 0, current_power, new_power;
63 
64  switch (dev & 0xFF) {
65  case LPC47N217_PP:
66  power_register = 0x01;
67  power_mask = 0x04;
68  break;
69  case LPC47N217_SP1:
70  power_register = 0x02;
71  power_mask = 0x08;
72  break;
73  case LPC47N217_SP2:
74  power_register = 0x02;
75  power_mask = 0x80;
76  break;
77  default:
78  return;
79  }
80 
81  current_power = pnp_read_config(dev, power_register);
82  new_power = current_power & ~power_mask; /* Disable by default. */
83  if (enable)
84  new_power |= power_mask; /* Enable. */
85  pnp_write_config(dev, power_register, new_power);
86 }
87 
88 /**
89  * Configure the base I/O port of the specified serial device and enable the
90  * serial device.
91  *
92  * @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
93  * @param iobase Processor I/O port address to assign to this serial device.
94  */
96 {
97  /*
98  * NOTE: Cannot use pnp_set_XXX() here because they assume chip
99  * support for logical devices, which the LPC47N217 doesn't have.
100  */
102  lpc47n217_pnp_set_enable(dev, 0);
103  lpc47n217_pnp_set_iobase(dev, iobase);
104  lpc47n217_pnp_set_enable(dev, 1);
105  pnp_exit_conf_state(dev);
106 }
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
#define ASSERT(x)
Definition: assert.h:44
void outb(u8 val, u16 port)
port
Definition: i915.h:29
#define LPC47N217_PP
Definition: lpc47n217.h:13
#define LPC47N217_SP2
Definition: lpc47n217.h:15
#define LPC47N217_SP1
Definition: lpc47n217.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 lpc47n217_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:95
static void lpc47n217_pnp_set_iobase(pnp_devfn_t dev, u16 iobase)
Program the base I/O port for the specified logical device.
Definition: early_serial.c:28
static void lpc47n217_pnp_set_enable(pnp_devfn_t dev, int enable)
Enable or disable the specified logical device.
Definition: early_serial.c:60
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45