summaryrefslogtreecommitdiffstats
path: root/src/superio/ite/common/early_serial.c
blob: 6b05a382e7f73b7154f338fe27bb19298fede2c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <arch/io.h>
#include <device/pnp_ops.h>
#include <device/pnp.h>
#include <stdint.h>
#include "ite.h"

/* Global configuration registers. */
#define ITE_CONFIG_REG_CC	0x02 /* Configure Control (write-only). */
#define ITE_CONFIG_REG_LDN	0x07 /* Logical Device Number. */
#define ITE_CONFIG_REG_CLOCKSEL	0x23 /* Clock Selection. */
#define ITE_CONFIG_REG_SWSUSP	0x24 /* Software Suspend, Flash I/F. */
#define ITE_CONFIG_REG_MFC	0x2a /* multi function pin */
#define ITE_CONFIG_REG_WATCHDOG	0x72 /* watchdog config */

/* Helper procedure */
static void ite_sio_write(pnp_devfn_t dev, u8 reg, u8 value)
{
	pnp_set_logical_device(dev);
	pnp_write_config(dev, reg, value);
}

/* Enable configuration */
void pnp_enter_conf_state(pnp_devfn_t dev)
{
	u16 port = dev >> 8;

	outb(0x87, port);
	outb(0x01, port);
	outb(0x55, port);
	outb((port == 0x4e) ? 0xaa : 0x55, port);
}

/* Disable configuration */
void pnp_exit_conf_state(pnp_devfn_t dev)
{
	ite_sio_write(dev, ITE_CONFIG_REG_CC, 0x02);
}

void ite_reg_write(pnp_devfn_t dev, u8 reg, u8 value)
{
	pnp_enter_conf_state(dev);
	ite_sio_write(dev, reg, value);
	pnp_exit_conf_state(dev);
}

/*
 * in romstage.c
 * #define CLKIN_DEV PNP_DEV(0x2e, ITE_GPIO)
 * and pass: CLKIN_DEV
 * ITE_UART_CLK_PREDIVIDE_24
 * ITE_UART_CLK_PREDIVIDE_48 (default)
 */
void ite_conf_clkin(pnp_devfn_t dev, u8 predivide)
{
	ite_reg_write(dev, ITE_CONFIG_REG_CLOCKSEL, (0x1 & predivide));
}

/* Bring up early serial debugging output before the RAM is initialized. */
void ite_enable_serial(pnp_devfn_t dev, u16 iobase)
{
	pnp_enter_conf_state(dev);
	pnp_set_logical_device(dev);
	pnp_set_enable(dev, 0);
	pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
	pnp_set_enable(dev, 1);
	pnp_exit_conf_state(dev);
}

/*
 *
 * LDN 7, reg 0x2a - needed for S3, or memory power will be cut off
 * this was documented only in IT8712F_V0.9.2!
 *
 * Enable 3VSBSW#. (For System Suspend-to-RAM)
 * 0: 3VSBSW# will be always inactive.
 * 1: 3VSBSW# enabled. It will be (NOT SUSB#) NAND SUSC#.
 *
 * in romstage.c
 * #define GPIO_DEV PNP_DEV(0x2e, ITE_GPIO)
 * and pass: GPIO_DEV
 */

void ite_enable_3vsbsw(pnp_devfn_t dev)
{
	u8 tmp;
	pnp_enter_conf_state(dev);
	pnp_set_logical_device(dev);
	tmp = pnp_read_config(dev, ITE_CONFIG_REG_MFC);
	tmp |= 0x80;
	pnp_write_config(dev, ITE_CONFIG_REG_MFC, tmp);
	pnp_exit_conf_state(dev);
}

/*
 *
 * LDN 7, reg 0x2a, bit 0 - delay PWRGD3 rising edge after 3VSBSW# rising edge
 * This can be needed for S3 resume.
 * Documented in IT8728F V0.4.2 but also applies to IT8720F where it is marked
 * as reserved.
 *
 * Delay PWRGD3 assertion after setting 3VSBSW#.
 * 0: There will be no extra delay before PWRGD3 is set.
 * 1: The delay after 3VSBSW# rising edge before PWRGD3 is set is increased.
 *
 * in romstage.c
 * #define GPIO_DEV PNP_DEV(0x2e, ITE_GPIO)
 * and pass: GPIO_DEV
 */

void ite_delay_pwrgd3(pnp_devfn_t dev)
{
	u8 tmp;
	pnp_enter_conf_state(dev);
	pnp_set_logical_device(dev);
	tmp = pnp_read_config(dev, ITE_CONFIG_REG_MFC);
	tmp |= 0x01;
	pnp_write_config(dev, ITE_CONFIG_REG_MFC, tmp);
	pnp_exit_conf_state(dev);
}

/*
 * in romstage.c
 * #define GPIO_DEV PNP_DEV(0x2e, ITE_GPIO)
 * and pass: GPIO_DEV
*/

void ite_kill_watchdog(pnp_devfn_t dev)
{
	pnp_enter_conf_state(dev);
	ite_sio_write(dev, ITE_CONFIG_REG_WATCHDOG, 0x00);
	pnp_exit_conf_state(dev);
}