From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c | 474 ++++++++++++++++++++++++++++------------------------------ 1 files changed, 229 insertions(+), 245 deletions(-) diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c index 95d875b..ee9e962 100644 --- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c +++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c @@ -10,9 +10,12 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/i2c.h> +#include <linux/irq.h> #include <linux/gpio/consumer.h> +#include <linux/regulator/consumer.h> #include <linux/mfd/core.h> #include "rkx110_x120.h" +#include "rkx110_x120_display.h" #include "rkx110_reg.h" #include "rkx110_dsi_rx.h" #include "rkx120_dsi_tx.h" @@ -22,8 +25,44 @@ static const struct mfd_cell rkx110_x120_devs[] = { /* 2 panel device for rkx110_x120 drm panel */ { - .name = "serdes-panel", + .name = "rockchip-serdes-panel", .of_compatible = "rockchip,serdes-panel", + }, + { + .name = "rockchip-serdes-panel1", + .of_compatible = "rockchip,serdes-panel", + }, + { + .name = "rkx120-pwm0", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm1", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm2", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm3", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm4", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm5", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm6", + .of_compatible = "rockchip,rkx120-pwm", + }, + { + .name = "rkx120-pwm7", + .of_compatible = "rockchip,rkx120-pwm", }, }; @@ -111,26 +150,40 @@ return serdes->rkx110_debug || serdes->rkx120_debug; } -static void rk_serdes_wait_link_ready(struct rk_serdes *serdes) +static int rk_serdes_wait_link_ready(struct rk_serdes *serdes) { + int ret; + if (serdes->stream_type == STREAM_DISPLAY) { - rkx110_linktx_wait_link_ready(serdes, 0); - if (serdes->route_flag & ROUTE_MULTI_LANE) { + ret = rkx110_linktx_wait_link_ready(serdes, 0); + if (ret) + return ret; + + if (serdes->lane_nr == 2) { rkx110_ser_pma_enable(serdes, true, 1, DEVICE_LOCAL); - if (!(serdes->route_flag & ROUTE_MULTI_REMOTE)) + if (!(serdes->remote_nr == 2)) rkx120_des_pma_enable(serdes, true, 1, DEVICE_REMOTE0); - rkx110_linktx_wait_link_ready(serdes, 1); + ret = rkx110_linktx_wait_link_ready(serdes, 1); + if (ret) + return ret; } } else { - rkx120_linkrx_wait_link_ready(serdes, 0); - if (serdes->route_flag & ROUTE_MULTI_LANE) { + ret = rkx120_linkrx_wait_link_ready(serdes, 0); + if (ret) + return ret; + + if (serdes->lane_nr == 2) { rkx120_des_pma_enable(serdes, true, 1, DEVICE_LOCAL); - if (!(serdes->route_flag & ROUTE_MULTI_REMOTE)) + if (!(serdes->remote_nr == 2)) rkx110_ser_pma_enable(serdes, true, 1, DEVICE_REMOTE0); - rkx120_linkrx_wait_link_ready(serdes, 1); + ret = rkx120_linkrx_wait_link_ready(serdes, 1); + if (ret) + return ret; } } + + return 0; } static void rk_serdes_print_rate(struct rk_serdes *serdes, enum rk_serdes_rate rate) @@ -302,9 +355,9 @@ if (serdes->stream_type == STREAM_DISPLAY) { rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_LOCAL); rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE0); - if (serdes->route_flag & ROUTE_MULTI_LANE) { + if (serdes->lane_nr == 2) { rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_LOCAL); - if (serdes->route_flag & ROUTE_MULTI_REMOTE) + if (serdes->remote_nr == 2) rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE1); else rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_REMOTE0); @@ -315,9 +368,9 @@ } else { rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_LOCAL); rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE0); - if (serdes->route_flag & ROUTE_MULTI_LANE) { + if (serdes->lane_nr == 2) { rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_LOCAL); - if (serdes->route_flag & ROUTE_MULTI_REMOTE) + if (serdes->remote_nr == 2) rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE1); else rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_REMOTE0); @@ -330,225 +383,6 @@ rk_serdes_wait_link_ready(serdes); serdes->rate = rate; -} - -static int rk_serdes_route_prepare(struct rk_serdes *serdes, struct rk_serdes_route *route) -{ - if (rk_serdes_debug_mode(serdes)) - return 0; - - if (route->stream_type == STREAM_DISPLAY) { - switch (route->local_port0) { - case RK_SERDES_RGB_RX: - rkx110_rgb_rx_enable(serdes, route); - break; - case RK_SERDES_LVDS_RX0: - rkx110_lvds_rx_enable(serdes, route, 0); - if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT) - rkx110_lvds_rx_enable(serdes, route, 1); - break; - case RK_SERDES_LVDS_RX1: - rkx110_lvds_rx_enable(serdes, route, 1); - if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT) - rkx110_lvds_rx_enable(serdes, route, 0); - break; - case RK_SERDES_DUAL_LVDS_RX: - rkx110_lvds_rx_enable(serdes, route, 0); - rkx110_lvds_rx_enable(serdes, route, 1); - break; - case RK_SERDES_DSI_RX0: - rkx110_dsi_rx_enable(serdes, route, 0); - if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT) - rkx110_dsi_rx_enable(serdes, route, 1); - break; - case RK_SERDES_DSI_RX1: - rkx110_dsi_rx_enable(serdes, route, 1); - if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT) - rkx110_dsi_rx_enable(serdes, route, 0); - break; - default: - dev_info(serdes->dev, "undefined local port0"); - return -EINVAL; - } - - rkx110_linktx_enable(serdes, route); - - rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE0); - if (serdes->route_flag & ROUTE_MULTI_REMOTE) - rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE1); - - if (route->remote0_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE0); - if (route->remote1_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE1); - } else { - /* for camera stream */ - } - - return 0; -} - -static int rk_serdes_route_enable(struct rk_serdes *serdes, struct rk_serdes_route *route) -{ - if (rk_serdes_debug_mode(serdes)) - return 0; - - if (route->stream_type == STREAM_DISPLAY) { - switch (route->remote0_port0) { - case RK_SERDES_RGB_TX: - rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE0); - break; - case RK_SERDES_LVDS_TX0: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0); - break; - case RK_SERDES_LVDS_TX1: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1); - break; - case RK_SERDES_DUAL_LVDS_TX: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0); - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1); - break; - case RK_SERDES_DSI_TX0: - rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE0); - break; - default: - dev_err(serdes->dev, "undefined remote0_port0\n"); - return -EINVAL; - } - - if (serdes->route_flag & ROUTE_MULTI_REMOTE) { - switch (route->remote1_port0) { - case RK_SERDES_RGB_TX: - rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE1); - break; - case RK_SERDES_LVDS_TX0: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0); - break; - case RK_SERDES_LVDS_TX1: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1); - break; - case RK_SERDES_DUAL_LVDS_TX: - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0); - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1); - break; - case RK_SERDES_DSI_TX0: - rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE1); - break; - default: - dev_err(serdes->dev, "undefined remote1_port0\n"); - return -EINVAL; - } - } else if (serdes->route_flag & ROUTE_MULTI_CHANNEL) { - if (route->remote0_port1 & RK_SERDES_LVDS_TX0) { - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0); - } else if (route->remote0_port1 & RK_SERDES_LVDS_TX1) { - rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1); - } else { - dev_err(serdes->dev, "undefined remote0_port1\n"); - return -EINVAL; - } - } - - if (serdes->version == SERDES_V1) { - rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, true); - rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, true); - } - - rkx110_linktx_video_enable(serdes, DEVICE_LOCAL, true); - } else { - /* for camera stream */ - } - - return 0; -} - -static int rk_serdes_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route) -{ - if (route->stream_type == STREAM_DISPLAY) { - if (route->remote0_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0); - - if (serdes->version == SERDES_V1) { - rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, false); - rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, false); - - if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) { - rkx110_set_stream_source(serdes, RK_SERDES_RGB_RX, - DEVICE_LOCAL); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX); - } - - if ((route->local_port0 == RK_SERDES_DSI_RX0) || - (route->local_port1 == RK_SERDES_DSI_RX0)) { - serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314, - 0x1400140); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX); - } - - if ((route->local_port0 == RK_SERDES_DSI_RX1) || - (route->local_port1 == RK_SERDES_DSI_RX1)) { - serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314, - 0x2800280); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX); - hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX); - } - } - } - - return 0; -} - -static int rk_serdes_route_unprepare(struct rk_serdes *serdes, struct rk_serdes_route *route) -{ - if (route->stream_type == STREAM_DISPLAY) { - if (route->remote0_port0 & RK_SERDES_DSI_TX0) - rkx120_dsi_tx_post_disable(serdes, route, DEVICE_REMOTE0); - - if (serdes->version == SERDES_V1) { - if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) { - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX); - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX); - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX); - rkx110_set_stream_source(serdes, RK_SERDES_DUAL_LVDS_RX, - DEVICE_LOCAL); - } - - if ((route->local_port0 == RK_SERDES_DSI_RX0) || - (route->local_port1 == RK_SERDES_DSI_RX0)) { - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX); - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX); - serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314, - 0x1400000); - } - - if ((route->local_port0 == RK_SERDES_DSI_RX1) || - (route->local_port1 == RK_SERDES_DSI_RX1)) { - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX); - hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk, - RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX); - serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314, - 0x2800000); - } - } - } - - return 0; } static int rk_serdes_set_hwpin(struct rk_serdes *serdes, struct i2c_client *client, @@ -576,11 +410,17 @@ serdes->i2c_read_reg = rk_serdes_i2c_read; serdes->i2c_write_reg = rk_serdes_i2c_write; serdes->i2c_update_bits = rk_serdes_i2c_update_bits; - serdes->route_prepare = rk_serdes_route_prepare; - serdes->route_enable = rk_serdes_route_enable; - serdes->route_disable = rk_serdes_route_disable; - serdes->route_unprepare = rk_serdes_route_unprepare; serdes->set_hwpin = rk_serdes_set_hwpin; + + if (rk_serdes_debug_mode(serdes)) + return; + + if (serdes->stream_type == STREAM_DISPLAY) { + serdes->route_prepare = rk_serdes_display_route_prepare; + serdes->route_enable = rk_serdes_display_route_enable; + serdes->route_disable = rk_serdes_display_route_disable; + serdes->route_unprepare = rk_serdes_display_route_unprepare; + } } static int rk_serdes_passthrough_init(struct rk_serdes *serdes) @@ -649,6 +489,25 @@ } kfree(configs); + } + + /* config irq passthrough */ + if (serdes->stream_type == STREAM_DISPLAY) { + rkx110_linktx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ, + false); + rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ, + true); + if (serdes->remote_nr == 2) + rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE1, + RK_SERDES_PASSTHROUGH_IRQ, true); + } else { + rkx120_linkrx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ, + false); + rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ, + true); + if (serdes->remote_nr == 2) + rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE1, + RK_SERDES_PASSTHROUGH_IRQ, true); } return 0; @@ -903,6 +762,9 @@ i2c_set_clientdata(client, serdes); } + if (serdes->remote_nr == 2) + serdes->lane_nr = 2; + if (serdes->remote_nr == 0) return -ENODEV; @@ -952,14 +814,73 @@ kfree(configs); } + /* config irq pinctrl */ + if (serdes->stream_type == STREAM_DISPLAY) { + serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX110, + RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC2); + serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX120, + RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC0); + if (serdes->remote_nr == 2) + serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX120, + RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC0); + } else { + serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX110, + RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC0); + serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX120, + RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC2); + if (serdes->remote_nr == 2) + serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX110, + RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4, + RK_SERDES_PIN_CONFIG_MUX_FUNC2); + } + return 0; +} + +static int rk_serdes_irq_enable(struct rk_serdes *serdes) +{ + if (serdes->stream_type == STREAM_DISPLAY) + rkx110_irq_enable(serdes, DEVICE_LOCAL); + else + rkx120_irq_enable(serdes, DEVICE_LOCAL); + + return 0; +} + +__maybe_unused static int rk_serdes_irq_disable(struct rk_serdes *serdes) +{ + if (serdes->stream_type == STREAM_DISPLAY) + rkx110_irq_disable(serdes, DEVICE_LOCAL); + else + rkx120_irq_disable(serdes, DEVICE_LOCAL); + + return 0; +} + +static irqreturn_t rk_serdes_irq_handler(int irq, void *arg) +{ + struct rk_serdes *serdes = arg; + + if (serdes->stream_type == STREAM_DISPLAY) + rkx110_irq_handler(serdes, DEVICE_LOCAL); + else + rkx120_irq_handler(serdes, DEVICE_LOCAL); + + return IRQ_HANDLED; } static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; + struct device_node *disp_np; struct rk_serdes *serdes; int ret; + bool dual_lane; serdes = devm_kzalloc(dev, sizeof(*serdes), GFP_KERNEL); if (!serdes) @@ -988,6 +909,16 @@ serdes->rate = RATE_2GBPS_83M; + serdes->supply = devm_regulator_get_optional(dev, "power"); + if (IS_ERR(serdes->supply)) { + ret = PTR_ERR(serdes->supply); + + if (ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to request regulator\n"); + + serdes->supply = NULL; + } + serdes->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(serdes->enable)) { ret = PTR_ERR(serdes->enable); @@ -1002,15 +933,34 @@ return ret; } - gpiod_set_value(serdes->enable, 1); + serdes->irq_gpio = devm_gpiod_get_optional(dev, "irq", GPIOD_IN); + if (IS_ERR(serdes->irq_gpio)) { + ret = PTR_ERR(serdes->irq_gpio); + dev_err(dev, "failed to request irq GPIO: %d\n", ret); + return ret; + } + if (serdes->irq_gpio) { + serdes->irq = gpiod_to_irq(serdes->irq_gpio); + if (serdes->irq < 0) + return dev_err_probe(dev, serdes->irq, "failed to get irq\n"); - gpiod_set_value(serdes->reset, 1); - usleep_range(10000, 11000); - gpiod_set_value(serdes->reset, 0); + irq_set_status_flags(serdes->irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(dev, serdes->irq, NULL, + rk_serdes_irq_handler, + IRQF_TRIGGER_LOW | + IRQF_ONESHOT, "serdes-irq", serdes); + if (ret) { + dev_err(dev, "failed to request serdes interrupt\n"); + return ret; + } + } else { + dev_warn(dev, "no support serdes irq function\n"); + } - if (of_get_child_by_name(dev->of_node, "serdes-panel")) { + disp_np = of_get_child_by_name(dev->of_node, "serdes-panel"); + if (disp_np) { serdes->stream_type = STREAM_DISPLAY; - of_node_put(dev->of_node); + of_node_put(disp_np); dev_info(dev, "serdes display stream"); } else { serdes->stream_type = STREAM_CAMERA; @@ -1021,7 +971,10 @@ if (ret) return ret; - msleep(20); + if (serdes->remote_nr != 2) { + dual_lane = device_property_read_bool(dev, "dual-lane"); + serdes->lane_nr = dual_lane ? 2 : 1; + } ret = mfd_add_devices(dev, -1, rkx110_x120_devs, ARRAY_SIZE(rkx110_x120_devs), NULL, 0, NULL); @@ -1030,27 +983,58 @@ return ret; } + if (serdes->supply) { + ret = regulator_enable(serdes->supply); + if (ret < 0) { + dev_err(serdes->dev, "failed to enable supply: %d\n", ret); + return ret; + } + } + + gpiod_set_value(serdes->enable, 1); + + gpiod_set_value(serdes->reset, 1); + usleep_range(10000, 11000); + gpiod_set_value(serdes->reset, 0); + + msleep(20); + rk_serdes_wait_link_ready(serdes); rk_serdes_read_chip_id(serdes); ret = rk_serdes_add_hwclk(serdes); if (ret < 0) - return ret; + goto err; rk_serdes_set_rate(serdes, RATE_4GBPS_83M); rk_serdes_pinctrl_init(serdes); rk_serdes_passthrough_init(serdes); + rk_serdes_irq_enable(serdes); + enable_irq(serdes->irq); + + if (serdes->stream_type == STREAM_DISPLAY) + rk_serdes_display_route_init(serdes); + out: rk_serdes_debugfs_init(serdes); return 0; + +err: + if (serdes->supply) + ret = regulator_disable(serdes->supply); + + return ret; } static int rk_serdes_i2c_remove(struct i2c_client *client) { struct rk_serdes *rk_serdes = i2c_get_clientdata(client); + if (rk_serdes->supply) + regulator_disable(rk_serdes->supply); + mfd_remove_devices(rk_serdes->dev); return 0; -- Gitblit v1.6.2