rockchip/*: refactor edp driver
rk3288 and rk3399 use same edp IP, move soc specific setting to soc/display, and move edp driver to common, so rk3399 can reuse this driver. BUG=chrome-os-partner:52460 BRANCH=none TEST= test on jerry and mighty, edp panel can work Change-Id: Ie3f3e8468b2323994af8a002413bf93b3edc8026 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 64bb4b2c7ed373d9730c9aa0b0896a32164fc7ee Original-Change-Id: Ie5c15a81849a02d1c0457e36ed00fbe2d47961fb Original-Signed-off-by: Lin Huang <hl@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/340504 Original-Commit-Ready: Vadim Bendebury <vbendeb@chromium.org> Original-Tested-by: Vadim Bendebury <vbendeb@chromium.org> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/14725 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
f9cbe35319
commit
b9a7877568
|
@ -17,18 +17,16 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
|
#include <device/device.h>
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <soc/addressmap.h>
|
#include <soc/addressmap.h>
|
||||||
|
#include <soc/display.h>
|
||||||
#include <soc/edp.h>
|
#include <soc/edp.h>
|
||||||
#include <soc/grf.h>
|
|
||||||
#include <soc/vop.h>
|
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
|
||||||
#include "chip.h"
|
|
||||||
|
|
||||||
#define edp_debug(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0)
|
#define edp_debug(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0)
|
||||||
|
|
||||||
static struct rk_edp rk_edp;
|
static struct rk_edp rk_edp;
|
||||||
|
@ -285,12 +283,14 @@ static int rk_edp_dpcd_transfer(struct rk_edp *edp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rk_edp_dpcd_read(struct rk_edp *edp, u32 addr, u8 *values, size_t size)
|
static int rk_edp_dpcd_read(struct rk_edp *edp, u32 addr,
|
||||||
|
u8 *values, size_t size)
|
||||||
{
|
{
|
||||||
return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_READ);
|
return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rk_edp_dpcd_write(struct rk_edp *edp, u32 addr, u8 *values, size_t size)
|
static int rk_edp_dpcd_write(struct rk_edp *edp, u32 addr,
|
||||||
|
u8 *values, size_t size)
|
||||||
{
|
{
|
||||||
return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_WRITE);
|
return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_WRITE);
|
||||||
}
|
}
|
||||||
|
@ -361,6 +361,7 @@ static u8 edp_get_lane_status(const u8 *link_status, int lane)
|
||||||
int i = DPCD_LANE0_1_STATUS + (lane >> 1);
|
int i = DPCD_LANE0_1_STATUS + (lane >> 1);
|
||||||
int s = (lane & 1) * 4;
|
int s = (lane & 1) * 4;
|
||||||
u8 l = edp_link_status(link_status, i);
|
u8 l = edp_link_status(link_status, i);
|
||||||
|
|
||||||
return (l >> s) & 0xf;
|
return (l >> s) & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,8 +550,11 @@ static int rk_edp_link_train_ce(struct rk_edp *edp)
|
||||||
channel_eq = 0;
|
channel_eq = 0;
|
||||||
for (tries = 0; tries < 5; tries++) {
|
for (tries = 0; tries < 5; tries++) {
|
||||||
rk_edp_set_link_training(edp, edp->train_set);
|
rk_edp_set_link_training(edp, edp->train_set);
|
||||||
udelay(400);
|
rk_edp_dpcd_write(edp, DPCD_TRAINING_LANE0_SET,
|
||||||
|
edp->train_set,
|
||||||
|
edp->link_train.lane_count);
|
||||||
|
|
||||||
|
udelay(400);
|
||||||
if (rk_edp_dpcd_read_link_status(edp, status) < 0) {
|
if (rk_edp_dpcd_read_link_status(edp, status) < 0) {
|
||||||
printk(BIOS_ERR, "displayport link status failed\n");
|
printk(BIOS_ERR, "displayport link status failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -700,7 +704,7 @@ static int rk_edp_read_bytes_from_i2c(struct rk_edp *edp,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If Rx sends defer, Tx sends only reads
|
* If Rx sends defer, Tx sends only reads
|
||||||
* request without sending addres
|
* request without sending address
|
||||||
*/
|
*/
|
||||||
if (!defer)
|
if (!defer)
|
||||||
retval = rk_edp_select_i2c_device(edp,
|
retval = rk_edp_select_i2c_device(edp,
|
||||||
|
@ -946,16 +950,16 @@ static int rockchip_edp_get_plug_in_status(struct rk_edp *edp)
|
||||||
/*
|
/*
|
||||||
* support edp HPD function
|
* support edp HPD function
|
||||||
* some hardware version do not support edp hdp,
|
* some hardware version do not support edp hdp,
|
||||||
* we use 200ms to try to get the hpd single now,
|
* we use 360ms to try to get the hpd single now,
|
||||||
* if we can not get edp hpd single, it will delay 200ms,
|
* if we can not get edp hpd single, it will delay 360ms,
|
||||||
* also meet the edp power timing request, to compatible
|
* also meet the edp power timing request, to compatible
|
||||||
* all of the hardware version
|
* all of the hardware version
|
||||||
*/
|
*/
|
||||||
static void rockchip_edp_wait_hpd(struct rk_edp *edp)
|
static void rk_edp_wait_hpd(struct rk_edp *edp)
|
||||||
{
|
{
|
||||||
struct stopwatch hpd;
|
struct stopwatch hpd;
|
||||||
|
|
||||||
stopwatch_init_msecs_expire(&hpd, 200);
|
stopwatch_init_msecs_expire(&hpd, 360);
|
||||||
do {
|
do {
|
||||||
if (rockchip_edp_get_plug_in_status(edp))
|
if (rockchip_edp_get_plug_in_status(edp))
|
||||||
return;
|
return;
|
||||||
|
@ -998,20 +1002,11 @@ int rk_edp_enable(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rk_edp_init(u32 vop_id)
|
void rk_edp_init(void)
|
||||||
{
|
{
|
||||||
u32 val;
|
rk_edp.regs = (struct rk_edp_regs *)EDP_BASE;
|
||||||
|
|
||||||
rk_edp.regs = (struct rk3288_edp_regs *)EDP_BASE;
|
rk_edp_wait_hpd(&rk_edp);
|
||||||
|
|
||||||
/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
|
|
||||||
write32(&rk3288_grf->soc_con12, RK_SETBITS(1 << 4));
|
|
||||||
|
|
||||||
/* select epd signal from vop0 or vop1 */
|
|
||||||
val = (vop_id == 1) ? RK_SETBITS(1 << 5) : RK_CLRBITS(1 << 5);
|
|
||||||
write32(&rk3288_grf->soc_con6, val);
|
|
||||||
|
|
||||||
rockchip_edp_wait_hpd(&rk_edp);
|
|
||||||
|
|
||||||
rk_edp_init_refclk(&rk_edp);
|
rk_edp_init_refclk(&rk_edp);
|
||||||
rk_edp_init_interrupt(&rk_edp);
|
rk_edp_init_interrupt(&rk_edp);
|
|
@ -13,13 +13,13 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RK32_DP_H
|
#ifndef __RK_DP_H
|
||||||
#define __RK32_DP_H
|
#define __RK_DP_H
|
||||||
|
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct rk3288_edp_regs {
|
struct rk_edp_regs {
|
||||||
u8 res0[0x10];
|
u8 res0[0x10];
|
||||||
u32 dp_tx_version;
|
u32 dp_tx_version;
|
||||||
u8 res1[0x4];
|
u8 res1[0x4];
|
||||||
|
@ -165,7 +165,7 @@ struct rk3288_edp_regs {
|
||||||
u8 res30[0x10];
|
u8 res30[0x10];
|
||||||
u32 pll_reg_5;
|
u32 pll_reg_5;
|
||||||
};
|
};
|
||||||
check_member(rk3288_edp_regs, pll_reg_5, 0xa00);
|
check_member(rk_edp_regs, pll_reg_5, 0xa00);
|
||||||
|
|
||||||
/* func_en_1 */
|
/* func_en_1 */
|
||||||
#define VID_CAP_FUNC_EN_N (0x1 << 6)
|
#define VID_CAP_FUNC_EN_N (0x1 << 6)
|
||||||
|
@ -243,10 +243,6 @@ check_member(rk3288_edp_regs, pll_reg_5, 0xa00);
|
||||||
#define PD_CH1 (0x1 << 1)
|
#define PD_CH1 (0x1 << 1)
|
||||||
#define PD_CH0 (0x1 << 0)
|
#define PD_CH0 (0x1 << 0)
|
||||||
|
|
||||||
/* pll_reg_1 */
|
|
||||||
#define REF_CLK_24M (0x1 << 1)
|
|
||||||
#define REF_CLK_27M (0x0 << 1)
|
|
||||||
|
|
||||||
/* line_map */
|
/* line_map */
|
||||||
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
|
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
|
||||||
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
|
#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
|
||||||
|
@ -650,13 +646,12 @@ struct link_train {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rk_edp {
|
struct rk_edp {
|
||||||
struct rk3288_edp_regs *regs;
|
struct rk_edp_regs *regs;
|
||||||
struct link_train link_train;
|
struct link_train link_train;
|
||||||
u8 train_set[4];
|
u8 train_set[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
int rk_edp_enable(void);
|
int rk_edp_enable(void);
|
||||||
void rk_edp_init(u32 vop_id);
|
void rk_edp_init(void);
|
||||||
int rk_edp_get_edid(struct edid *edid);
|
int rk_edp_get_edid(struct edid *edid);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -68,7 +68,7 @@ ramstage-y += gpio.c
|
||||||
ramstage-y += ../common/rk808.c
|
ramstage-y += ../common/rk808.c
|
||||||
ramstage-y += ../common/pwm.c
|
ramstage-y += ../common/pwm.c
|
||||||
ramstage-y += vop.c
|
ramstage-y += vop.c
|
||||||
ramstage-y += edp.c
|
ramstage-y += ../common/edp.c
|
||||||
ramstage-y += hdmi.c
|
ramstage-y += hdmi.c
|
||||||
ramstage-y += display.c
|
ramstage-y += display.c
|
||||||
ramstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c
|
ramstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c
|
||||||
|
|
|
@ -39,6 +39,7 @@ void rk_display_init(device_t dev, u32 lcdbase,
|
||||||
unsigned long fb_size)
|
unsigned long fb_size)
|
||||||
{
|
{
|
||||||
struct edid edid;
|
struct edid edid;
|
||||||
|
uint32_t val;
|
||||||
struct soc_rockchip_rk3288_config *conf = dev->chip_info;
|
struct soc_rockchip_rk3288_config *conf = dev->chip_info;
|
||||||
uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
|
uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
|
||||||
uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
|
uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
|
||||||
|
@ -58,7 +59,16 @@ void rk_display_init(device_t dev, u32 lcdbase,
|
||||||
printk(BIOS_DEBUG, "Attempting to setup EDP display.\n");
|
printk(BIOS_DEBUG, "Attempting to setup EDP display.\n");
|
||||||
rkclk_configure_edp();
|
rkclk_configure_edp();
|
||||||
rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz);
|
rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz);
|
||||||
rk_edp_init(conf->vop_id);
|
|
||||||
|
/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
|
||||||
|
write32(&rk3288_grf->soc_con12, RK_SETBITS(1 << 4));
|
||||||
|
|
||||||
|
/* select epd signal from vop0 or vop1 */
|
||||||
|
val = (conf->vop_id == 1) ? RK_SETBITS(1 << 5) :
|
||||||
|
RK_CLRBITS(1 << 5);
|
||||||
|
write32(&rk3288_grf->soc_con6, val);
|
||||||
|
|
||||||
|
rk_edp_init();
|
||||||
|
|
||||||
if (rk_edp_get_edid(&edid) == 0) {
|
if (rk_edp_get_edid(&edid) == 0) {
|
||||||
detected_mode = VOP_MODE_EDP;
|
detected_mode = VOP_MODE_EDP;
|
||||||
|
|
|
@ -16,6 +16,13 @@
|
||||||
#ifndef __SOC_ROCKCHIP_RK3288_DISPLAY_H__
|
#ifndef __SOC_ROCKCHIP_RK3288_DISPLAY_H__
|
||||||
#define __SOC_ROCKCHIP_RK3288_DISPLAY_H__
|
#define __SOC_ROCKCHIP_RK3288_DISPLAY_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this bit select edp phy pll, this bit define different between
|
||||||
|
* rk3288 and rk3399 in edp phy, so implement it in soc specific code
|
||||||
|
*/
|
||||||
|
#define REF_CLK_24M (0x0 << 0)
|
||||||
|
#define REF_CLK_27M (0x1 << 0)
|
||||||
|
|
||||||
void rk_display_init(device_t dev, u32 lcdbase,
|
void rk_display_init(device_t dev, u32 lcdbase,
|
||||||
unsigned long fb_size);
|
unsigned long fb_size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue