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:
Lin Huang 2016-04-25 18:50:55 +08:00 committed by Patrick Georgi
parent f9cbe35319
commit b9a7877568
5 changed files with 44 additions and 37 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);