misc: rk628: add support uboot logo

Type: Function
Redmine ID: #496880 #491750
Associated modifications: NULL
Test: NULL

Change-Id: I311e2c9682f835b377ea9082e1d3a88688167172
Signed-off-by: Guochun Huang <hero.huang@rock-chips.com>
This commit is contained in:
Guochun Huang
2024-07-16 15:11:52 +08:00
committed by Tao Huang
parent 899800bb3e
commit b55833ab45
4 changed files with 82 additions and 16 deletions

View File

@@ -148,14 +148,14 @@ int rk628_panel_info_get(struct rk628 *rk628, struct device_node *np)
return ret;
}
panel->enable_gpio = devm_gpiod_get_optional(dev, "panel-enable", GPIOD_OUT_LOW);
panel->enable_gpio = devm_gpiod_get_optional(dev, "panel-enable", GPIOD_ASIS);
if (IS_ERR(panel->enable_gpio)) {
ret = PTR_ERR(panel->enable_gpio);
dev_err(dev, "failed to request panel enable GPIO: %d\n", ret);
return ret;
}
panel->reset_gpio = devm_gpiod_get_optional(dev, "panel-reset", GPIOD_OUT_LOW);
panel->reset_gpio = devm_gpiod_get_optional(dev, "panel-reset", GPIOD_ASIS);
if (IS_ERR(panel->reset_gpio)) {
ret = PTR_ERR(panel->reset_gpio);
dev_err(dev, "failed to request panel reset GPIO: %d\n", ret);

View File

@@ -383,19 +383,19 @@ static const struct regmap_config rk628_regmap_config[RK628_DEV_MAX] = {
static void rk628_power_on(struct rk628 *rk628, bool on)
{
if (!rk628->display_enabled && on) {
gpiod_set_value(rk628->enable_gpio, 1);
gpiod_direction_output(rk628->enable_gpio, 1);
usleep_range(10000, 11000);
gpiod_set_value(rk628->reset_gpio, 0);
gpiod_direction_output(rk628->reset_gpio, 0);
usleep_range(10000, 11000);
gpiod_set_value(rk628->reset_gpio, 1);
gpiod_direction_output(rk628->reset_gpio, 1);
usleep_range(10000, 11000);
gpiod_set_value(rk628->reset_gpio, 0);
gpiod_direction_output(rk628->reset_gpio, 0);
usleep_range(10000, 11000);
}
if (!on) {
gpiod_set_value(rk628->reset_gpio, 1);
gpiod_set_value(rk628->enable_gpio, 0);
gpiod_direction_output(rk628->reset_gpio, 1);
gpiod_direction_output(rk628->enable_gpio, 0);
}
}
@@ -494,6 +494,9 @@ static void rk628_set_hdmirx_irq(struct rk628 *rk628, u32 reg, bool enable)
static void rk628_pwr_consumption_init(struct rk628 *rk628)
{
if (rk628->display_enabled)
return;
/* set pin as int function to allow output interrupt */
rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x30002000);
@@ -1329,6 +1332,32 @@ static void rk628_debugfs_create(struct rk628 *rk628)
rk628_hdmitx_create_debugfs_file(rk628);
}
static void rk628_loader_protect(struct rk628 *rk628)
{
u32 enabled;
int ret;
ret = rk628_i2c_read(rk628, GRF_SCALER_CON0, &enabled);
if (ret || !(enabled & SCL_EN(1)))
return;
if (rk628_input_is_rgb(rk628) || rk628_input_is_bt1120(rk628))
rk628->display_enabled = true;
if (rk628_input_is_hdmi(rk628)) {
if (!rk628_hdmirx_boot_state_init(rk628))
rk628->display_enabled = true;
}
if (rk628->display_enabled && rk628->panel && rk628->panel->supply) {
ret = regulator_enable(rk628->panel->supply);
if (ret)
dev_info(rk628->dev, "failed to enable panel power supply\n");
dev_info(rk628->dev, "%s:%d show uboot logo\n", __func__, __LINE__);
}
}
static int
rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
@@ -1373,14 +1402,14 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
clk_prepare_enable(rk628->soc_24M);
rk628->enable_gpio = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_LOW);
GPIOD_ASIS);
if (IS_ERR(rk628->enable_gpio)) {
ret = PTR_ERR(rk628->enable_gpio);
dev_err(dev, "failed to request enable GPIO: %d\n", ret);
goto err_clk;
}
rk628->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
rk628->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
if (IS_ERR(rk628->reset_gpio)) {
ret = PTR_ERR(rk628->reset_gpio);
dev_err(dev, "failed to request reset GPIO: %d\n", ret);
@@ -1395,8 +1424,6 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto err_clk;
}
rk628_power_on(rk628, true);
for (i = 0; i < RK628_DEV_MAX; i++) {
const struct regmap_config *config = &rk628_regmap_config[i];
@@ -1412,6 +1439,9 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
rk628_loader_protect(rk628);
rk628_power_on(rk628, true);
ret = rk628_version_info(rk628);
if (ret)
goto err_clk;
@@ -1531,6 +1561,13 @@ static int rk628_i2c_remove(struct i2c_client *client)
#endif
}
static void rk628_i2c_shutdown(struct i2c_client *client)
{
struct rk628 *rk628 = i2c_get_clientdata(client);
rk628_power_on(rk628, false);
}
#ifndef CONFIG_FB
#ifdef CONFIG_PM_SLEEP
static int rk628_suspend(struct device *dev)
@@ -1602,6 +1639,7 @@ static struct i2c_driver rk628_i2c_driver = {
.probe = rk628_i2c_probe,
.remove = rk628_i2c_remove,
.id_table = rk628_i2c_id,
.shutdown = rk628_i2c_shutdown,
};

View File

@@ -1120,11 +1120,7 @@ static int rk628_hdmirx_init(struct rk628 *rk628)
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_INPUT_MODE_MASK, SW_INPUT_MODE(INPUT_MODE_HDMI));
rk628_hdmirx_set_edid(rk628);
/* clear avi rcv interrupt */
rk628_i2c_write(rk628, HDMI_RX_PDEC_ICLR, AVI_RCV_ISTS);
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_I2S_DATA_OEN_MASK, SW_I2S_DATA_OEN(0));
dev_info(rk628->dev, "hdmirx driver version: %s\n", DRIVER_VERSION);
INIT_DELAYED_WORK(&hdmirx->delayed_work_audio, rk628_hdmirx_delayed_work_audio);
return 0;
@@ -1152,6 +1148,27 @@ void rk628_hdmirx_enable_interrupts(struct rk628 *rk628, bool en)
dev_dbg(rk628->dev, "%s MD_IEN:%#x\n", __func__, md_ien);
}
int rk628_hdmirx_boot_state_init(struct rk628 *rk628)
{
struct rk628_hdmirx *hdmirx;
if (!rk628->hdmirx) {
int ret;
ret = rk628_hdmirx_init(rk628);
if (ret < 0 || !rk628->hdmirx)
return ret;
}
hdmirx = rk628->hdmirx;
hdmirx->plugin = true;
hdmirx->phy_lock = true;
rk628_hdmirx_get_timing(rk628);
rk628_hdmirx_get_input_format(rk628);
return 0;
}
int rk628_hdmirx_enable(struct rk628 *rk628)
{
int ret;
@@ -1191,6 +1208,14 @@ int rk628_hdmirx_enable(struct rk628 *rk628)
rk628_hdmirx_reset_control_deassert(rk628);
usleep_range(20, 40);
rk628_hdmirx_set_edid(rk628);
/* clear avi rcv interrupt */
rk628_i2c_write(rk628, HDMI_RX_PDEC_ICLR, AVI_RCV_ISTS);
rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
SW_I2S_DATA_OEN_MASK, SW_I2S_DATA_OEN(0));
rk628_hdmirx_ctrl_enable(rk628);
ret = rk628_hdmirx_phy_setup(rk628);
if (ret < 0)
@@ -1280,6 +1305,7 @@ int rk628_hdmirx_detect(struct rk628 *rk628)
ret |= HDMIRX_PLUGIN;
if (!hdmirx->plugin)
ret |= HDMIRX_CHANGED;
if (rk628_hdmirx_status_change(rk628))
ret |= HDMIRX_CHANGED;
@@ -1291,6 +1317,7 @@ int rk628_hdmirx_detect(struct rk628 *rk628)
if (!hdmirx->phy_lock)
ret |= HDMIRX_NOLOCK;
hdmirx->plugin = true;
} else {
ret |= HDMIRX_PLUGOUT;

View File

@@ -631,6 +631,7 @@
#define HDMIRX_NOSIGNAL BIT(3)
#define HDMIRX_NOLOCK BIT(4)
int rk628_hdmirx_boot_state_init(struct rk628 *rk628);
void rk628_hdmirx_enable_interrupts(struct rk628 *rk628, bool en);
int rk628_hdmirx_enable(struct rk628 *rk628);
void rk628_hdmirx_disable(struct rk628 *rk628);