Uwe Poeche has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
drivers/i2c/ptn3460: Provide chip driver for PTN3460
This patch provides a chip driver for the DP-2-LVDS bridge PTN3460. The bridge is configured via I2C. As the mainboard has all the information regarding the attached LCD type, there are three hooks into mainboard code to get the information like EDID data and PTN config.
TEST=Display is working on Siemens mainboards (e.g. mc_tcu3, mc_apl1, ...).
Change-Id: Ie4c8176cd16836fa5b8fd2f72faf7a55723b82f6 Signed-off-by: Uwe Poeche uwe.poeche@siemens.com --- A src/drivers/i2c/ptn3460/Kconfig A src/drivers/i2c/ptn3460/Makefile.inc A src/drivers/i2c/ptn3460/chip.h A src/drivers/i2c/ptn3460/ptn3460.c A src/drivers/i2c/ptn3460/ptn3460.h 5 files changed, 223 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/42/36642/1
diff --git a/src/drivers/i2c/ptn3460/Kconfig b/src/drivers/i2c/ptn3460/Kconfig new file mode 100644 index 0000000..6dcdbc0 --- /dev/null +++ b/src/drivers/i2c/ptn3460/Kconfig @@ -0,0 +1,5 @@ +config DRIVERS_I2C_PTN3460 + bool + default n + help + Enable support for external display bridge (eDP to LVDS) PTN3460. diff --git a/src/drivers/i2c/ptn3460/Makefile.inc b/src/drivers/i2c/ptn3460/Makefile.inc new file mode 100644 index 0000000..abe9a05 --- /dev/null +++ b/src/drivers/i2c/ptn3460/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_I2C_PTN3460) += ptn3460.c diff --git a/src/drivers/i2c/ptn3460/chip.h b/src/drivers/i2c/ptn3460/chip.h new file mode 100644 index 0000000..8bd6d9e --- /dev/null +++ b/src/drivers/i2c/ptn3460/chip.h @@ -0,0 +1,3 @@ +struct drivers_i2c_ptn3460_config { + +}; diff --git a/src/drivers/i2c/ptn3460/ptn3460.c b/src/drivers/i2c/ptn3460/ptn3460.c new file mode 100644 index 0000000..95fbed9 --- /dev/null +++ b/src/drivers/i2c/ptn3460/ptn3460.c @@ -0,0 +1,143 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <console/console.h> +#include <device/i2c_bus.h> +#include <types.h> + +#include "ptn3460.h" + +/** \brief This functions selects one of 7 EDID-tables inside PTN3460 + * which should be emulated on display port and turn emulation ON + * @param *dev Pointer to the relevant I2C controller + * @param edid_num Number of EDID to emulate (0..6) + * @return 0 on success or error code + */ +static int ptn_select_edid(struct device *dev, uint8_t edid_num) +{ + int status = 0; + u8 val; + + if (edid_num > PTN_MAX_EDID_NUM) + return PTN_INVALID_EDID; + /* Enable emulation of the desired EDID table */ + val = (edid_num << 1) | PTN_ENABLE_EMULATION; + status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 4, val); + if (status) + return (PTN_BUS_ERROR | status); + else + return PTN_NO_ERROR; +} + +/** \brief This functions writes one EDID data structure to PTN3460 + * @param *dev Pointer to the relevant I2C controller + * @param edid_num Number of EDID that must be written (0..6) + * @param *data Pointer to a buffer where data to write is stored in + * @return 0 on success or error code + */ +static int ptn3460_write_edid(struct device *dev, u8 edid_num, u8 *data) +{ + int status; + int i; + + if (edid_num > PTN_MAX_EDID_NUM) + return PTN_INVALID_EDID; + + /* First enable access to the desired EDID table */ + status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 5, edid_num); + if (status) + return (PTN_BUS_ERROR | status); + + /* Now we can simply write EDID-data to ptn3460 */ + for (i = 0; i < PTN_EDID_LEN; i++) { + status = i2c_dev_writeb_at(dev, PTN_EDID_OFF + i, data[i]); + if (status) + return (PTN_BUS_ERROR | status); + } + return PTN_NO_ERROR; +} + +/** \brief This functions sets up the DP2LVDS-converter to be used with the + * appropriate EDID data + * @param *dev Pointer to the I2C controller where PTN3460 is attached + */ +static void ptn3460_init(struct device *dev) +{ + struct ptn_3460_config cfg; + uint8_t edid_data[PTN_EDID_LEN], edid_tab, *ptr = (uint8_t *) &cfg; + int status, i; + + /* Mainboard provides EDID data. */ + if (mb_get_edid(edid_data) != CB_SUCCESS) { + printk(BIOS_ERR, "PTN3460 error: Not able to get EDID data from mainboard.\n"); + return; + } + + /* Mainboard decides which EDID table has to be used. */ + edid_tab = mb_select_edid_table(); + if (edid_tab > PTN_MAX_EDID_NUM) { + printk(BIOS_ERR, "PTN3460 error: invalid EDID table (%d).\n", edid_tab); + return; + } + /* Writing EDID data into PTN. */ + status = ptn3460_write_edid(dev, edid_tab, edid_data); + if (status != PTN_NO_ERROR) { + printk(BIOS_ERR, "PTN3460 error: writing EDID data into device failed.\n"); + return; + } + /* Activate the selected EDID block. */ + ptn_select_edid(dev, edid_tab); + /* Read out PTN configuration data. */ + for (i = 0; i < sizeof(struct ptn_3460_config); i++) { + status = i2c_dev_readb_at(dev, PTN_CONFIG_OFF + i); + if (status < 0) { + printk(BIOS_ERR, "PTN3460 error: Not able to read config data.\n"); + return; + } + *ptr++ = (uint8_t)status; /* fill config structure via ptr */ + } + /* Mainboard can modify the configuration data. + Write back configuration data to PTN3460 if modified by mainboard */ + if (mb_adjust_cfg(&cfg) == PTN_CFG_MODIFIED) { + ptr = (uint8_t *) &cfg; + for (i = 0; i < sizeof(struct ptn_3460_config); i++) { + status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + i, *ptr++); + if (status < 0) { + printk(BIOS_ERR, + "PTN3460 error: Not able to write config data.\n"); + return; + } + } + } +} + +static struct device_operations ptn3460_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, + .init = ptn3460_init, + .final = DEVICE_NOOP +}; + +static void ptn3460_enable(struct device *dev) +{ + dev->ops = &ptn3460_ops; +} + +struct chip_operations drivers_i2c_ptn3460_ops = { + CHIP_NAME("PTN3460") + .enable_dev = ptn3460_enable +}; diff --git a/src/drivers/i2c/ptn3460/ptn3460.h b/src/drivers/i2c/ptn3460/ptn3460.h new file mode 100644 index 0000000..3ca0d69 --- /dev/null +++ b/src/drivers/i2c/ptn3460/ptn3460.h @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _I2C_PTN3460_H_ +#define _I2C_PTN3460_H_ + +#define PTN_EDID_OFF 0x00 +#define PTN_EDID_LEN 0x80 +#define PTN_CONFIG_OFF 0x80 +#define PTN_CONFIG_LEN 0x19 +#define PTN_FLASH_CFG_OFF 0xE8 +#define PTN_FLASH_CFG_LEN 0x04 +#define PTN_MAX_EDID_NUM 6 +#define PTN_ENABLE_EMULATION (1 << 0) + +/* Define some error codes that can be used */ +#define PTN_NO_ERROR 0x00000000 +#define PTN_CFG_MODIFIED 0x00000001 +#define PTN_BUS_ERROR 0x10000000 +#define PTN_INVALID_EDID 0x20000000 +#define PTN_INVALID_EDID_BLOCK 0x30000000 +#define PTN_ERROR 0x40000000 + +struct ptn_3460_config { + u8 dp_interface_ctrl; /* DisplayPort interface control */ + u8 lvds_interface_ctrl1; /* LVDS interface control register 1 */ + u8 lvds_interface_ctrl2; /* LVDS interface control register 2 */ + u8 lvds_interface_ctrl3; /* LVDS interface control register 3 */ + u8 edid_rom_emulation; /* select which EDID-block is emulated */ + u8 edid_rom_access_ctrl; /* select which EDID block to map to 0..0x7F */ + u8 pwm_min[3]; /* smallest PWM frequency for back light */ + u8 pwm_max[3]; /* biggest PWM frequency for back light */ + u8 fast_link_ctrl; /* Fast link training control register */ + u8 pin_cfg_ctrl1; /* Pin configuration control register 1 */ + u8 pin_cfg_ctrl2; /* Pin configuration control register 2 */ + u8 pwm_default; /* Default PWM bit count in DPCD register */ + u16 pwm_value; /* Current PWM bit count in DPCD register */ + u8 pwm_default_freq; /* Default PWM frequency in DPCD register */ + u8 t3_timing; /* Panel T3 timing value */ + u8 t12_timing; /* Panel T12 timing value */ + u8 backlight_ctrl; /* Back light control register */ + u8 t2_delay; /* Panel T2 delay */ + u8 t4_timing; /* Panel T4 timing value */ + u8 t5_delay; /* Panel T5 delay */ +} __packed; + +struct ptn_3460_flash { + u8 cmd; /* Flash command (erase or erase and flash) */ + u16 magic; /* Magic number needed by the flash algorithm */ + u8 trigger; /* Trigger for starting flash operation */ +} __packed; + +/* We need functions which we can call to get mainboard specific data */ +/* This functions can be coded somewhere else but must exist. */ +extern enum cb_err mb_get_edid(uint8_t edid_data[0x80]); +extern uint8_t mb_select_edid_table(void); +extern int mb_adjust_cfg(struct ptn_3460_config *cfg_ptr); + +#endif /* _I2C_PTN3460_H_ */
Mario Scheithauer has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 1: Code-Review+1
(1 comment)
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... File src/drivers/i2c/ptn3460/chip.h:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... PS1, Line 1: struct Do we need a header in this file?
Werner Zeh has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... File src/drivers/i2c/ptn3460/chip.h:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... PS1, Line 1: struct
Do we need a header in this file?
I guess not since here the structure is defined (which is empty as the parameters are handled differently). This definition is mandatory to make the chip construct work.
Paul Menzel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 1:
(17 comments)
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.h:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 29: PTN_NO_ERROR PTN_SUCCESS?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 34: #define PTN_ERROR 0x40000000 Better use an enum or extend `cb_err` in `src/include/types.h`.
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 66: This These
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 66: coded implemented
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.c:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 23: functions function
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 23: /** \brief This functions selects one of 7 EDID-tables inside PTN3460 Please format it like below.
``` /** * \brief … * ```
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 26: * @param edid_num Number of EDID to emulate (0..6) Alignement of *Number* and *Pointer*?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 27: * @return 0 on success or error code PTN_NO_ERROR is returned, isn’t it?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 36: /* Enable emulation of the desired EDID table */ Could be removed, as the code is self-explanatory?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 42: return PTN_NO_ERROR; One line?
return status ? (PTN_BUS_ERROR | status) : PTN_NO_ERROR
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 45: functions function
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 64: EDID-data EDID data
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 69: } How long does this loop need?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 85: Not able Unable
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 95: Writing Write
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 105: status position?
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 110: *ptr++ = (uint8_t)status; /* fill config structure via ptr */ Is pointer arithmetic really needed?
Werner Zeh has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.c:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 69: }
How long does this loop need?
We are writing 128 bytes byte-per-byte here. So per EDID byte there will be a full I2C transfer which consists of 1 slave address byte, 1 register address byte and one value for this register (in total 3). So in total there will be 128 * 3 bytes transferred over I2C, which should take ~4ms@100 kHz I2C speed. You can add some overhead here due to function calls and the like, but that should be small.
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 110: *ptr++ = (uint8_t)status; /* fill config structure via ptr */
Is pointer arithmetic really needed?
We have this structure (struct ptn_3460_config cfg) which needs to be read byte-per-byte over I2C. Any better approaches than using pointers in mind?
Hello Werner Zeh, Mario Scheithauer, uwe.poeche@siemens.com, Paul Menzel, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/36642
to look at the new patch set (#2).
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
drivers/i2c/ptn3460: Provide chip driver for PTN3460
This patch provides a chip driver for the DP-2-LVDS bridge PTN3460. The bridge is configured via I2C. As the mainboard has all the information regarding the attached LCD type, there are three hooks into mainboard code to get the information like EDID data and PTN config.
TEST=Display is working on Siemens mainboards (e.g. mc_tcu3, mc_apl1, ...).
Change-Id: Ie4c8176cd16836fa5b8fd2f72faf7a55723b82f6 Signed-off-by: Uwe Poeche uwe.poeche@siemens.com --- A src/drivers/i2c/ptn3460/Kconfig A src/drivers/i2c/ptn3460/Makefile.inc A src/drivers/i2c/ptn3460/chip.h A src/drivers/i2c/ptn3460/ptn3460.c A src/drivers/i2c/ptn3460/ptn3460.h 5 files changed, 235 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/42/36642/2
uwe.poeche@siemens.com has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 2:
(18 comments)
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... File src/drivers/i2c/ptn3460/chip.h:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/chi... PS1, Line 1: struct
I guess not since here the structure is defined (which is empty as the parameters are handled differ […]
Ack
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.h:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 29: PTN_NO_ERROR
PTN_SUCCESS?
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 34: #define PTN_ERROR 0x40000000
Better use an enum or extend `cb_err` in `src/include/types.h`.
We had in mind to use this to combine status and information (via or) as return values. I think enum is not helpfull for this. Using types.h is also not helpfull because of not included special PTN return values.
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 66: This
These
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 66: coded
implemented
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.c:
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 23: functions
function
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 23: /** \brief This functions selects one of 7 EDID-tables inside PTN3460
Please format it like below. […]
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 26: * @param edid_num Number of EDID to emulate (0..6)
Alignement of *Number* and *Pointer*?
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 27: * @return 0 on success or error code
PTN_NO_ERROR is returned, isn’t it?
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 36: /* Enable emulation of the desired EDID table */
Could be removed, as the code is self-explanatory?
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 42: return PTN_NO_ERROR;
One line? […]
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 45: functions
function
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 64: EDID-data
EDID data
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 69: }
We are writing 128 bytes byte-per-byte here. […]
Ack
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 85: Not able
Unable
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 95: Writing
Write
Done
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 105: status
position?
You are right. The return value is the read value in lower 8 Bits with status in upper bit. So I changed to val.
https://review.coreboot.org/c/coreboot/+/36642/1/src/drivers/i2c/ptn3460/ptn... PS1, Line 110: *ptr++ = (uint8_t)status; /* fill config structure via ptr */
We have this structure (struct ptn_3460_config cfg) which needs to be read byte-per-byte over I2C. […]
Ack
HAOUAS Elyes has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 2:
(1 comment)
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.h:
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 68: uint8_t #include <stdint.h> ?
Werner Zeh has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 2: Code-Review+1
(2 comments)
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.c:
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 80: status, i, val You could have used "val" for every call to the ptn3460_xxx-functions (so even for ptn3460_write_edid) and get rid of status at all. Your decision.
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 106: Not able This could have been 'Unable' to sync with the case above. But I do not have a strong objection.
Hello Werner Zeh, Mario Scheithauer, uwe.poeche@siemens.com, Paul Menzel, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/36642
to look at the new patch set (#3).
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
drivers/i2c/ptn3460: Provide chip driver for PTN3460
This patch provides a chip driver for the DP-2-LVDS bridge PTN3460. The bridge is configured via I2C. As the mainboard has all the information regarding the attached LCD type, there are three hooks into mainboard code to get the information like EDID data and PTN config.
TEST=Display is working on Siemens mainboards (e.g. mc_tcu3, mc_apl1, ...).
Change-Id: Ie4c8176cd16836fa5b8fd2f72faf7a55723b82f6 Signed-off-by: Uwe Poeche uwe.poeche@siemens.com --- A src/drivers/i2c/ptn3460/Kconfig A src/drivers/i2c/ptn3460/Makefile.inc A src/drivers/i2c/ptn3460/chip.h A src/drivers/i2c/ptn3460/ptn3460.c A src/drivers/i2c/ptn3460/ptn3460.h 5 files changed, 239 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/42/36642/3
uwe.poeche@siemens.com has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 3:
(3 comments)
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.h:
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 68: uint8_t
#include <stdint. […]
Done
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... File src/drivers/i2c/ptn3460/ptn3460.c:
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 80: status, i, val
You could have used "val" for every call to the ptn3460_xxx-functions (so even for ptn3460_write_edi […]
Done
https://review.coreboot.org/c/coreboot/+/36642/2/src/drivers/i2c/ptn3460/ptn... PS2, Line 106: Not able
This could have been 'Unable' to sync with the case above. But I do not have a strong objection.
Done
Werner Zeh has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
Patch Set 3: Code-Review+2
Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/36642 )
Change subject: drivers/i2c/ptn3460: Provide chip driver for PTN3460 ......................................................................
drivers/i2c/ptn3460: Provide chip driver for PTN3460
This patch provides a chip driver for the DP-2-LVDS bridge PTN3460. The bridge is configured via I2C. As the mainboard has all the information regarding the attached LCD type, there are three hooks into mainboard code to get the information like EDID data and PTN config.
TEST=Display is working on Siemens mainboards (e.g. mc_tcu3, mc_apl1, ...).
Change-Id: Ie4c8176cd16836fa5b8fd2f72faf7a55723b82f6 Signed-off-by: Uwe Poeche uwe.poeche@siemens.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/36642 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Werner Zeh werner.zeh@siemens.com --- A src/drivers/i2c/ptn3460/Kconfig A src/drivers/i2c/ptn3460/Makefile.inc A src/drivers/i2c/ptn3460/chip.h A src/drivers/i2c/ptn3460/ptn3460.c A src/drivers/i2c/ptn3460/ptn3460.h 5 files changed, 239 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Werner Zeh: Looks good to me, approved
diff --git a/src/drivers/i2c/ptn3460/Kconfig b/src/drivers/i2c/ptn3460/Kconfig new file mode 100644 index 0000000..6dcdbc0 --- /dev/null +++ b/src/drivers/i2c/ptn3460/Kconfig @@ -0,0 +1,5 @@ +config DRIVERS_I2C_PTN3460 + bool + default n + help + Enable support for external display bridge (eDP to LVDS) PTN3460. diff --git a/src/drivers/i2c/ptn3460/Makefile.inc b/src/drivers/i2c/ptn3460/Makefile.inc new file mode 100644 index 0000000..abe9a05 --- /dev/null +++ b/src/drivers/i2c/ptn3460/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_I2C_PTN3460) += ptn3460.c diff --git a/src/drivers/i2c/ptn3460/chip.h b/src/drivers/i2c/ptn3460/chip.h new file mode 100644 index 0000000..8bd6d9e --- /dev/null +++ b/src/drivers/i2c/ptn3460/chip.h @@ -0,0 +1,3 @@ +struct drivers_i2c_ptn3460_config { + +}; diff --git a/src/drivers/i2c/ptn3460/ptn3460.c b/src/drivers/i2c/ptn3460/ptn3460.c new file mode 100644 index 0000000..ef25745 --- /dev/null +++ b/src/drivers/i2c/ptn3460/ptn3460.c @@ -0,0 +1,157 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <console/console.h> +#include <device/i2c_bus.h> +#include <types.h> + +#include "ptn3460.h" + +/** + * \brief This function selects one of 7 EDID-tables inside PTN3460 + * which should be emulated on display port and turn emulation ON + * @param *dev Pointer to the relevant I2C controller + * @param edid_num Number of EDID to emulate (0..6) + * @return PTN_SUCCESS or error code + */ +static int ptn_select_edid(struct device *dev, uint8_t edid_num) +{ + int status = 0; + u8 val; + + if (edid_num > PTN_MAX_EDID_NUM) + return PTN_INVALID_EDID; + val = (edid_num << 1) | PTN_ENABLE_EMULATION; + status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 4, val); + return status ? (PTN_BUS_ERROR | status) : PTN_SUCCESS; +} + +/** + * \brief This function writes one EDID data structure to PTN3460 + * @param *dev Pointer to the relevant I2C controller + * @param edid_num Number of EDID that must be written (0..6) + * @param *data Pointer to a buffer where data to write is stored in + * @return PTN_SUCCESS on success or error code + */ +static int ptn3460_write_edid(struct device *dev, u8 edid_num, u8 *data) +{ + int status; + int i; + + if (edid_num > PTN_MAX_EDID_NUM) + return PTN_INVALID_EDID; + + /* First enable access to the desired EDID table */ + status = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + 5, edid_num); + if (status) + return (PTN_BUS_ERROR | status); + + /* Now we can simply write EDID data to ptn3460 */ + for (i = 0; i < PTN_EDID_LEN; i++) { + status = i2c_dev_writeb_at(dev, PTN_EDID_OFF + i, data[i]); + if (status) + return (PTN_BUS_ERROR | status); + } + return PTN_SUCCESS; +} + +/** + * \brief This function sets up the DP2LVDS-converter to be used with the + * appropriate EDID data + * @param *dev Pointer to the I2C controller where PTN3460 is attached + */ +static void ptn3460_init(struct device *dev) +{ + struct ptn_3460_config cfg; + uint8_t edid_data[PTN_EDID_LEN], edid_tab, *ptr = (uint8_t *) &cfg; + int i, val; + + /* Mainboard provides EDID data. */ + if (mb_get_edid(edid_data) != CB_SUCCESS) { + printk(BIOS_ERR, "PTN3460 error: Unable to get EDID data from mainboard.\n"); + return; + } + + /* Mainboard decides which EDID table has to be used. */ + edid_tab = mb_select_edid_table(); + if (edid_tab > PTN_MAX_EDID_NUM) { + printk(BIOS_ERR, "PTN3460 error: invalid EDID table (%d) selected.\n", + edid_tab); + return; + } + /* Write EDID data into PTN. */ + val = ptn3460_write_edid(dev, edid_tab, edid_data); + if (val != PTN_SUCCESS) { + printk(BIOS_ERR, "PTN3460 error: writing EDID data into device failed.\n"); + return; + } + /* Activate the selected EDID block. */ + ptn_select_edid(dev, edid_tab); + /* Read out PTN configuration data. */ + for (i = 0; i < sizeof(struct ptn_3460_config); i++) { + val = i2c_dev_readb_at(dev, PTN_CONFIG_OFF + i); + if (val < 0) { + printk(BIOS_ERR, + "PTN3460 error: Unable to read config data from device.\n"); + return; + } + *ptr++ = (uint8_t)val; /* fill config structure via ptr */ + } + /* Mainboard can modify the configuration data. + Write back configuration data to PTN3460 if modified by mainboard */ + if (mb_adjust_cfg(&cfg) == PTN_CFG_MODIFIED) { + ptr = (uint8_t *) &cfg; + for (i = 0; i < sizeof(struct ptn_3460_config); i++) { + val = i2c_dev_writeb_at(dev, PTN_CONFIG_OFF + i, *ptr++); + if (val < 0) { + printk(BIOS_ERR, + "PTN3460 error: Unable to write config data.\n"); + return; + } + } + } +} + +__weak enum cb_err mb_get_edid(uint8_t edid_data[0x80]) +{ + return CB_ERR; +} +__weak uint8_t mb_select_edid_table(void) +{ + return 0; +} +__weak int mb_adjust_cfg(struct ptn_3460_config *cfg_ptr) +{ + return 0; +} + +static struct device_operations ptn3460_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, + .init = ptn3460_init, + .final = DEVICE_NOOP +}; + +static void ptn3460_enable(struct device *dev) +{ + dev->ops = &ptn3460_ops; +} + +struct chip_operations drivers_i2c_ptn3460_ops = { + CHIP_NAME("PTN3460") + .enable_dev = ptn3460_enable +}; diff --git a/src/drivers/i2c/ptn3460/ptn3460.h b/src/drivers/i2c/ptn3460/ptn3460.h new file mode 100644 index 0000000..4b9834e --- /dev/null +++ b/src/drivers/i2c/ptn3460/ptn3460.h @@ -0,0 +1,73 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Siemens AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _I2C_PTN3460_H_ +#define _I2C_PTN3460_H_ + +#include <stdint.h> + +#define PTN_EDID_OFF 0x00 +#define PTN_EDID_LEN 0x80 +#define PTN_CONFIG_OFF 0x80 +#define PTN_CONFIG_LEN 0x19 +#define PTN_FLASH_CFG_OFF 0xE8 +#define PTN_FLASH_CFG_LEN 0x04 +#define PTN_MAX_EDID_NUM 6 +#define PTN_ENABLE_EMULATION (1 << 0) + +/* Define some error codes that can be used */ +#define PTN_SUCCESS 0x00000000 +#define PTN_CFG_MODIFIED 0x00000001 +#define PTN_BUS_ERROR 0x10000000 +#define PTN_INVALID_EDID 0x20000000 +#define PTN_INVALID_EDID_BLOCK 0x30000000 +#define PTN_ERROR 0x40000000 + +struct ptn_3460_config { + u8 dp_interface_ctrl; /* DisplayPort interface control */ + u8 lvds_interface_ctrl1; /* LVDS interface control register 1 */ + u8 lvds_interface_ctrl2; /* LVDS interface control register 2 */ + u8 lvds_interface_ctrl3; /* LVDS interface control register 3 */ + u8 edid_rom_emulation; /* select which EDID-block is emulated */ + u8 edid_rom_access_ctrl; /* select which EDID block to map to 0..0x7F */ + u8 pwm_min[3]; /* smallest PWM frequency for back light */ + u8 pwm_max[3]; /* biggest PWM frequency for back light */ + u8 fast_link_ctrl; /* Fast link training control register */ + u8 pin_cfg_ctrl1; /* Pin configuration control register 1 */ + u8 pin_cfg_ctrl2; /* Pin configuration control register 2 */ + u8 pwm_default; /* Default PWM bit count in DPCD register */ + u16 pwm_value; /* Current PWM bit count in DPCD register */ + u8 pwm_default_freq; /* Default PWM frequency in DPCD register */ + u8 t3_timing; /* Panel T3 timing value */ + u8 t12_timing; /* Panel T12 timing value */ + u8 backlight_ctrl; /* Back light control register */ + u8 t2_delay; /* Panel T2 delay */ + u8 t4_timing; /* Panel T4 timing value */ + u8 t5_delay; /* Panel T5 delay */ +} __packed; + +struct ptn_3460_flash { + u8 cmd; /* Flash command (erase or erase and flash) */ + u16 magic; /* Magic number needed by the flash algorithm */ + u8 trigger; /* Trigger for starting flash operation */ +} __packed; + +/* We need functions which we can call to get mainboard specific data */ +/* These functions can be implemented somewhere else but must exist. */ +extern enum cb_err mb_get_edid(uint8_t edid_data[0x80]); +extern uint8_t mb_select_edid_table(void); +extern int mb_adjust_cfg(struct ptn_3460_config *cfg_ptr); + +#endif /* _I2C_PTN3460_H_ */