coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ast_i2c.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copied from Linux drivers/gpu/drm/ast/ast_mode.c
4  */
5 #include <delay.h>
6 #include <device/i2c_simple.h>
7 
8 #include "ast_drv.h"
9 
10 static struct ast_private *ast;
11 
12 #define _GET_INDEX_REG(x) ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, (x))
13 #define ASPEED_BUS 0
14 
15 static int get_clock(unsigned int bus)
16 {
17  uint32_t val, val2, count, pass;
18 
19  count = 0;
20  pass = 0;
21  val = (_GET_INDEX_REG(0x10) >> 4) & 0x01;
22  do {
23  val2 = (_GET_INDEX_REG(0x10) >> 4) & 0x01;
24  if (val == val2) {
25  pass++;
26  } else {
27  pass = 0;
28  val = (_GET_INDEX_REG(0x10) >> 4) & 0x01;
29  }
30  } while ((pass < 5) && (count++ < 0x10000));
31 
32  return val & 1 ? 1 : 0;
33 }
34 
35 static int get_data(unsigned int bus)
36 {
37  uint32_t val, val2, count, pass;
38 
39  count = 0;
40  pass = 0;
41  val = (_GET_INDEX_REG(0x20) >> 5) & 0x01;
42  do {
43  val2 = (_GET_INDEX_REG(0x20) >> 5) & 0x01;
44  if (val == val2) {
45  pass++;
46  } else {
47  pass = 0;
48  val = (_GET_INDEX_REG(0x20) >> 5) & 0x01;
49  }
50  } while ((pass < 5) && (count++ < 0x10000));
51 
52  return val & 1 ? 1 : 0;
53 }
54 
55 static void set_clock(unsigned int bus, int clock)
56 {
57  int i;
58  u8 ujcrb7, jtemp;
59 
60  for (i = 0; i < 0x10000; i++) {
61  ujcrb7 = ((clock & 0x01) ? 0 : 1);
62  ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
63  jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
64  if (ujcrb7 == jtemp)
65  break;
66  }
67 }
68 
69 static void set_data(unsigned int bus, int data)
70 {
71  int i;
72  u8 ujcrb7, jtemp;
73 
74  for (i = 0; i < 0x10000; i++) {
75  ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
76  ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
77  jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
78  if (ujcrb7 == jtemp)
79  break;
80  }
81 }
82 
83 static struct software_i2c_ops ast_ops = {
84  .set_sda = set_data,
85  .set_scl = set_clock,
86  .get_sda = get_data,
87  .get_scl = get_clock,
88 };
89 
90 int ast_software_i2c_read(struct ast_private *ast_priv, uint8_t edid[128])
91 {
92  struct software_i2c_ops *backup;
93  int ret;
94 
95  backup = software_i2c[ASPEED_BUS];
96 
98 
99  ast = ast_priv;
100 
101  /* Ast POST pulled SDA and SCL low, recover the bus to a known state */
102  set_clock(ASPEED_BUS, 1);
103  set_data(ASPEED_BUS, 1);
104 
105  udelay(100);
106 
107  /* Need to reset internal EEPROM counter to 0 */
108  ret = i2c_read_bytes(ASPEED_BUS, 0x50, 0, edid, 128);
109 
110  software_i2c[ASPEED_BUS] = backup;
111 
112  return ret;
113 }
uint8_t ast_get_index_reg_mask(struct ast_private *ast, uint32_t base, uint8_t index, uint8_t mask)
Definition: ast_main.c:30
#define AST_IO_CRTC_PORT
Definition: ast_drv.h:89
void ast_set_index_reg_mask(struct ast_private *ast, uint32_t base, uint8_t index, uint8_t mask, uint8_t val)
Definition: ast_main.c:11
static struct ast_private * ast
Definition: ast_i2c.c:10
static int get_data(unsigned int bus)
Definition: ast_i2c.c:35
static void set_data(unsigned int bus, int data)
Definition: ast_i2c.c:69
int ast_software_i2c_read(struct ast_private *ast_priv, uint8_t edid[128])
Definition: ast_i2c.c:90
static struct software_i2c_ops ast_ops
Definition: ast_i2c.c:83
static int get_clock(unsigned int bus)
Definition: ast_i2c.c:15
static void set_clock(unsigned int bus, int clock)
Definition: ast_i2c.c:55
#define _GET_INDEX_REG(x)
Definition: ast_i2c.c:12
#define ASPEED_BUS
Definition: ast_i2c.c:13
struct software_i2c_ops * software_i2c[SOFTWARE_I2C_MAX_BUS]
Definition: software_i2c.c:24
static int i2c_read_bytes(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data, int len)
Read multi-bytes with two segments in one frame.
Definition: i2c_simple.h:87
unsigned int uint32_t
Definition: stdint.h:14
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
Definition: device.h:76
Definition: edid.h:49
void(* set_sda)(unsigned int bus, int high)
Definition: i2c_simple.h:16
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15
#define count