coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ptn3460.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/i2c_bus.h>
5 #include <types.h>
6 
7 #include "ptn3460.h"
8 
9 /**
10  * \brief This function selects one of 7 EDID-tables inside PTN3460
11  * which should be emulated on display port and turn emulation ON
12  * @param *dev Pointer to the relevant I2C controller
13  * @param edid_num Number of EDID to emulate (0..6)
14  * @return PTN_SUCCESS or error code
15  */
16 static int ptn_select_edid(struct device *dev, uint8_t edid_num)
17 {
18  int status = 0;
19  u8 val;
20 
21  if (edid_num > PTN_MAX_EDID_NUM)
22  return PTN_INVALID_EDID;
23  val = (edid_num << 1) | PTN_ENABLE_EMULATION;
24  status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 4, val);
25  return status ? (PTN_BUS_ERROR | status) : PTN_SUCCESS;
26 }
27 
28 /**
29  * \brief This function writes one EDID data structure to PTN3460
30  * @param *dev Pointer to the relevant I2C controller
31  * @param edid_num Number of EDID that must be written (0..6)
32  * @param *data Pointer to a buffer where data to write is stored in
33  * @return PTN_SUCCESS on success or error code
34  */
35 static int ptn3460_write_edid(struct device *dev, u8 edid_num, u8 *data)
36 {
37  int status;
38  int i;
39 
40  if (edid_num > PTN_MAX_EDID_NUM)
41  return PTN_INVALID_EDID;
42 
43  /* First enable access to the desired EDID table */
44  status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 5, edid_num);
45  if (status)
46  return (PTN_BUS_ERROR | status);
47 
48  /* Now we can simply write EDID data to ptn3460 */
49  for (i = 0; i < PTN_EDID_LEN; i++) {
50  status = i2c_dev_writeb_at(dev, PTN_EDID_OFF + i, data[i]);
51  if (status)
52  return (PTN_BUS_ERROR | status);
53  }
54  return PTN_SUCCESS;
55 }
56 
57 /**
58  * \brief This function sets up the DP2LVDS-converter to be used with the
59  * appropriate EDID data
60  * @param *dev Pointer to the I2C controller where PTN3460 is attached
61  */
62 static void ptn3460_init(struct device *dev)
63 {
64  struct ptn_3460_config cfg;
65  uint8_t edid_data[PTN_EDID_LEN], edid_tab, *ptr = (uint8_t *) &cfg;
66  int i, val;
67 
68  /* Mainboard provides EDID data. */
69  if (mb_get_edid(edid_data) != CB_SUCCESS) {
70  printk(BIOS_ERR, "PTN3460 error: Unable to get EDID data from mainboard.\n");
71  return;
72  }
73 
74  /* Mainboard decides which EDID table has to be used. */
75  edid_tab = mb_select_edid_table();
76  if (edid_tab > PTN_MAX_EDID_NUM) {
77  printk(BIOS_ERR, "PTN3460 error: invalid EDID table (%d) selected.\n",
78  edid_tab);
79  return;
80  }
81  /* Write EDID data into PTN. */
82  val = ptn3460_write_edid(dev, edid_tab, edid_data);
83  if (val != PTN_SUCCESS) {
84  printk(BIOS_ERR, "PTN3460 error: writing EDID data into device failed.\n");
85  return;
86  }
87  /* Activate the selected EDID block. */
88  ptn_select_edid(dev, edid_tab);
89  /* Read out PTN configuration data. */
90  for (i = 0; i < sizeof(struct ptn_3460_config); i++) {
92  if (val < 0) {
94  "PTN3460 error: Unable to read config data from device.\n");
95  return;
96  }
97  *ptr++ = (uint8_t)val; /* fill config structure via ptr */
98  }
99  /* Mainboard can modify the configuration data.
100  Write back configuration data to PTN3460 if modified by mainboard */
101  if (mb_adjust_cfg(&cfg) == PTN_CFG_MODIFIED) {
102  ptr = (uint8_t *) &cfg;
103  for (i = 0; i < sizeof(struct ptn_3460_config); i++) {
104  val = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + i, *ptr++);
105  if (val < 0) {
107  "PTN3460 error: Unable to write config data.\n");
108  return;
109  }
110  }
111  }
112 }
113 
114 __weak enum cb_err mb_get_edid(uint8_t edid_data[0x80])
115 {
116  return CB_ERR;
117 }
119 {
120  return 0;
121 }
123 {
124  return 0;
125 }
126 
127 static struct device_operations ptn3460_ops = {
129  .set_resources = noop_set_resources,
130  .init = ptn3460_init,
131 };
132 
133 static void ptn3460_enable(struct device *dev)
134 {
135  dev->ops = &ptn3460_ops;
136 }
137 
139  CHIP_NAME("PTN3460")
140  .enable_dev = ptn3460_enable
141 };
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_ERR
Generic error code.
Definition: cb_err.h:17
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
#define printk(level,...)
Definition: stdlib.h:16
int i2c_dev_writeb_at(struct device *const dev, const uint8_t off, const uint8_t val)
Definition: i2c_bus.c:121
int i2c_dev_readb_at(struct device *const dev, uint8_t off)
Definition: i2c_bus.c:84
#define CHIP_NAME(X)
Definition: device.h:32
static void noop_read_resources(struct device *dev)
Standard device operations function pointers shims.
Definition: device.h:73
static void noop_set_resources(struct device *dev)
Definition: device.h:74
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static void ptn3460_init(struct device *dev)
This function sets up the DP2LVDS-converter to be used with the appropriate EDID data.
Definition: ptn3460.c:62
__weak enum cb_err mb_get_edid(uint8_t edid_data[0x80])
Definition: ptn3460.c:114
static void ptn3460_enable(struct device *dev)
Definition: ptn3460.c:133
static int ptn_select_edid(struct device *dev, uint8_t edid_num)
This function selects one of 7 EDID-tables inside PTN3460 which should be emulated on display port an...
Definition: ptn3460.c:16
__weak int mb_adjust_cfg(struct ptn_3460_config *cfg_ptr)
Definition: ptn3460.c:122
struct chip_operations drivers_i2c_ptn3460_ops
Definition: ptn3460.c:138
static struct device_operations ptn3460_ops
Definition: ptn3460.c:127
__weak uint8_t mb_select_edid_table(void)
Definition: ptn3460.c:118
static int ptn3460_write_edid(struct device *dev, u8 edid_num, u8 *data)
This function writes one EDID data structure to PTN3460.
Definition: ptn3460.c:35
#define PTN_ENABLE_EMULATION
Definition: ptn3460.h:15
#define PTN_MAX_EDID_NUM
Definition: ptn3460.h:14
#define PTN_EDID_LEN
Definition: ptn3460.h:9
#define PTN_CFG_MODIFIED
Definition: ptn3460.h:19
#define PTN_SUCCESS
Definition: ptn3460.h:18
#define PTN_EDID_OFF
Definition: ptn3460.h:8
#define PTN_INVALID_EDID
Definition: ptn3460.h:21
#define PTN_BUS_ERROR
Definition: ptn3460.h:20
#define PTN_CONFIG_OFF
Definition: ptn3460.h:10
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
u8 val
Definition: sys.c:300