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/display-serdes/maxim/maxim-max96772.c | 642 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 543 insertions(+), 99 deletions(-) diff --git a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c index c9b1394..2059962 100644 --- a/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c +++ b/kernel/drivers/mfd/display-serdes/maxim/maxim-max96772.c @@ -32,23 +32,34 @@ .rd_table = &max96772_readable_table, }; -static int MAX96772_MFP0_pins[] = {0}; -static int MAX96772_MFP1_pins[] = {1}; -static int MAX96772_MFP2_pins[] = {2}; -static int MAX96772_MFP3_pins[] = {3}; -static int MAX96772_MFP4_pins[] = {4}; -static int MAX96772_MFP5_pins[] = {5}; -static int MAX96772_MFP6_pins[] = {6}; -static int MAX96772_MFP7_pins[] = {7}; +struct config_desc { + u16 reg; + u8 mask; + u8 val; +}; -static int MAX96772_MFP8_pins[] = {8}; -static int MAX96772_MFP9_pins[] = {9}; -static int MAX96772_MFP10_pins[] = {10}; -static int MAX96772_MFP11_pins[] = {11}; -static int MAX96772_MFP12_pins[] = {12}; -static int MAX96772_MFP13_pins[] = {13}; -static int MAX96772_MFP14_pins[] = {14}; -static int MAX96772_MFP15_pins[] = {15}; +struct serdes_group_data { + const struct config_desc *configs; + int num_configs; +}; + +static int MAX96772_GPIO0_pins[] = {0}; +static int MAX96772_GPIO1_pins[] = {1}; +static int MAX96772_GPIO2_pins[] = {2}; +static int MAX96772_GPIO3_pins[] = {3}; +static int MAX96772_GPIO4_pins[] = {4}; +static int MAX96772_GPIO5_pins[] = {5}; +static int MAX96772_GPIO6_pins[] = {6}; +static int MAX96772_GPIO7_pins[] = {7}; + +static int MAX96772_GPIO8_pins[] = {8}; +static int MAX96772_GPIO9_pins[] = {9}; +static int MAX96772_GPIO10_pins[] = {10}; +static int MAX96772_GPIO11_pins[] = {11}; +static int MAX96772_GPIO12_pins[] = {12}; +static int MAX96772_GPIO13_pins[] = {13}; +static int MAX96772_GPIO14_pins[] = {14}; +static int MAX96772_GPIO15_pins[] = {15}; #define GROUP_DESC(nm) \ { \ @@ -61,21 +72,24 @@ u8 gpio_out_dis:1; u8 gpio_tx_en:1; u8 gpio_rx_en:1; + u8 gpio_in_level:1; + u8 gpio_out_level:1; u8 gpio_tx_id; u8 gpio_rx_id; + u16 mdelay; }; static const char *serdes_gpio_groups[] = { - "MAX96772_MFP0", "MAX96772_MFP1", "MAX96772_MFP2", "MAX96772_MFP3", - "MAX96772_MFP4", "MAX96772_MFP5", "MAX96772_MFP6", "MAX96772_MFP7", + "MAX96772_GPIO0", "MAX96772_GPIO1", "MAX96772_GPIO2", "MAX96772_GPIO3", + "MAX96772_GPIO4", "MAX96772_GPIO5", "MAX96772_GPIO6", "MAX96772_GPIO7", - "MAX96772_MFP8", "MAX96772_MFP9", "MAX96772_MFP10", "MAX96772_MFP11", - "MAX96772_MFP12", "MAX96772_MFP13", "MAX96772_MFP14", "MAX96772_MFP15", + "MAX96772_GPIO8", "MAX96772_GPIO9", "MAX96772_GPIO10", "MAX96772_GPIO11", + "MAX96772_GPIO12", "MAX96772_GPIO13", "MAX96772_GPIO14", "MAX96772_GPIO15", }; -#define FUNCTION_DESC_GPIO_INPUT(id) \ +#define FUNCTION_DESC_GPIO_INPUT_BYPASS(id) \ { \ - .name = "MFP"#id"_INPUT", \ + .name = "SER_TO_DES_RXID"#id, \ .group_names = serdes_gpio_groups, \ .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \ .data = (void *)(const struct serdes_function_data []) { \ @@ -83,9 +97,9 @@ }, \ } \ -#define FUNCTION_DESC_GPIO_OUTPUT(id) \ +#define FUNCTION_DESC_GPIO_OUTPUT_BYPASS(id) \ { \ - .name = "MFP"#id"_OUTPUT", \ + .name = "DES_TXID"#id"_TO_SER", \ .group_names = serdes_gpio_groups, \ .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \ .data = (void *)(const struct serdes_function_data []) { \ @@ -93,83 +107,156 @@ }, \ } \ -static struct pinctrl_pin_desc max96772_pins_desc[] = { - PINCTRL_PIN(MAXIM_MAX96772_MFP0, "MAX96772_MFP0"), - PINCTRL_PIN(MAXIM_MAX96772_MFP1, "MAX96772_MFP1"), - PINCTRL_PIN(MAXIM_MAX96772_MFP2, "MAX96772_MFP2"), - PINCTRL_PIN(MAXIM_MAX96772_MFP3, "MAX96772_MFP3"), - PINCTRL_PIN(MAXIM_MAX96772_MFP4, "MAX96772_MFP4"), - PINCTRL_PIN(MAXIM_MAX96772_MFP5, "MAX96772_MFP5"), - PINCTRL_PIN(MAXIM_MAX96772_MFP6, "MAX96772_MFP6"), - PINCTRL_PIN(MAXIM_MAX96772_MFP7, "MAX96772_MFP7"), +#define FUNCTION_DESC_GPIO_OUTPUT_LOW(id) \ +{ \ + .name = "DES_TXID"#id"_OUTPUT_LOW", \ + .group_names = serdes_gpio_groups, \ + .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \ + .data = (void *)(const struct serdes_function_data []) { \ + { .gpio_out_dis = 0, .gpio_tx_en = 0, \ + .gpio_rx_en = 0, .gpio_out_level = 0, .gpio_tx_id = id } \ + }, \ +} \ - PINCTRL_PIN(MAXIM_MAX96772_MFP8, "MAX96772_MFP8"), - PINCTRL_PIN(MAXIM_MAX96772_MFP9, "MAX96772_MFP9"), - PINCTRL_PIN(MAXIM_MAX96772_MFP10, "MAX96772_MFP10"), - PINCTRL_PIN(MAXIM_MAX96772_MFP11, "MAX96772_MFP11"), - PINCTRL_PIN(MAXIM_MAX96772_MFP12, "MAX96772_MFP12"), - PINCTRL_PIN(MAXIM_MAX96772_MFP13, "MAX96772_MFP13"), - PINCTRL_PIN(MAXIM_MAX96772_MFP14, "MAX96772_MFP14"), - PINCTRL_PIN(MAXIM_MAX96772_MFP15, "MAX96772_MFP15"), +#define FUNCTION_DESC_GPIO_OUTPUT_HIGH(id) \ +{ \ + .name = "DES_TXID"#id"_OUTPUT_HIGH", \ + .group_names = serdes_gpio_groups, \ + .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \ + .data = (void *)(const struct serdes_function_data []) { \ + { .gpio_out_dis = 0, .gpio_tx_en = 0, \ + .gpio_rx_en = 0, .gpio_out_level = 1, .gpio_tx_id = id } \ + }, \ +} \ + +#define FUNCTION_DES_DELAY_MS(ms) \ +{ \ + .name = "DELAY_"#ms"MS", \ + .group_names = serdes_gpio_groups, \ + .num_group_names = ARRAY_SIZE(serdes_gpio_groups), \ + .data = (void *)(const struct serdes_function_data []) { \ + { .mdelay = ms, } \ + }, \ +} \ + +static struct pinctrl_pin_desc max96772_pins_desc[] = { + PINCTRL_PIN(MAXIM_MAX96772_GPIO0, "MAX96772_GPIO0"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO1, "MAX96772_GPIO1"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO2, "MAX96772_GPIO2"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO3, "MAX96772_GPIO3"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO4, "MAX96772_GPIO4"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO5, "MAX96772_GPIO5"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO6, "MAX96772_GPIO6"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO7, "MAX96772_GPIO7"), + + PINCTRL_PIN(MAXIM_MAX96772_GPIO8, "MAX96772_GPIO8"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO9, "MAX96772_GPIO9"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO10, "MAX96772_GPIO10"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO11, "MAX96772_GPIO11"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO12, "MAX96772_GPIO12"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO13, "MAX96772_GPIO13"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO14, "MAX96772_GPIO14"), + PINCTRL_PIN(MAXIM_MAX96772_GPIO15, "MAX96772_GPIO15"), }; static struct group_desc max96772_groups_desc[] = { - GROUP_DESC(MAX96772_MFP0), - GROUP_DESC(MAX96772_MFP1), - GROUP_DESC(MAX96772_MFP2), - GROUP_DESC(MAX96772_MFP3), - GROUP_DESC(MAX96772_MFP4), - GROUP_DESC(MAX96772_MFP5), - GROUP_DESC(MAX96772_MFP6), - GROUP_DESC(MAX96772_MFP7), + GROUP_DESC(MAX96772_GPIO0), + GROUP_DESC(MAX96772_GPIO1), + GROUP_DESC(MAX96772_GPIO2), + GROUP_DESC(MAX96772_GPIO3), + GROUP_DESC(MAX96772_GPIO4), + GROUP_DESC(MAX96772_GPIO5), + GROUP_DESC(MAX96772_GPIO6), + GROUP_DESC(MAX96772_GPIO7), - GROUP_DESC(MAX96772_MFP8), - GROUP_DESC(MAX96772_MFP9), - GROUP_DESC(MAX96772_MFP10), - GROUP_DESC(MAX96772_MFP11), - GROUP_DESC(MAX96772_MFP12), - GROUP_DESC(MAX96772_MFP13), - GROUP_DESC(MAX96772_MFP14), - GROUP_DESC(MAX96772_MFP15), + GROUP_DESC(MAX96772_GPIO8), + GROUP_DESC(MAX96772_GPIO9), + GROUP_DESC(MAX96772_GPIO10), + GROUP_DESC(MAX96772_GPIO11), + GROUP_DESC(MAX96772_GPIO12), + GROUP_DESC(MAX96772_GPIO13), + GROUP_DESC(MAX96772_GPIO14), + GROUP_DESC(MAX96772_GPIO15), }; static struct function_desc max96772_functions_desc[] = { - FUNCTION_DESC_GPIO_INPUT(0), - FUNCTION_DESC_GPIO_INPUT(1), - FUNCTION_DESC_GPIO_INPUT(2), - FUNCTION_DESC_GPIO_INPUT(3), - FUNCTION_DESC_GPIO_INPUT(4), - FUNCTION_DESC_GPIO_INPUT(5), - FUNCTION_DESC_GPIO_INPUT(6), - FUNCTION_DESC_GPIO_INPUT(7), + FUNCTION_DESC_GPIO_INPUT_BYPASS(0), + FUNCTION_DESC_GPIO_INPUT_BYPASS(1), + FUNCTION_DESC_GPIO_INPUT_BYPASS(2), + FUNCTION_DESC_GPIO_INPUT_BYPASS(3), + FUNCTION_DESC_GPIO_INPUT_BYPASS(4), + FUNCTION_DESC_GPIO_INPUT_BYPASS(5), + FUNCTION_DESC_GPIO_INPUT_BYPASS(6), + FUNCTION_DESC_GPIO_INPUT_BYPASS(7), - FUNCTION_DESC_GPIO_INPUT(8), - FUNCTION_DESC_GPIO_INPUT(9), - FUNCTION_DESC_GPIO_INPUT(10), - FUNCTION_DESC_GPIO_INPUT(11), - FUNCTION_DESC_GPIO_INPUT(12), - FUNCTION_DESC_GPIO_INPUT(13), - FUNCTION_DESC_GPIO_INPUT(14), - FUNCTION_DESC_GPIO_INPUT(15), + FUNCTION_DESC_GPIO_INPUT_BYPASS(8), + FUNCTION_DESC_GPIO_INPUT_BYPASS(9), + FUNCTION_DESC_GPIO_INPUT_BYPASS(10), + FUNCTION_DESC_GPIO_INPUT_BYPASS(11), + FUNCTION_DESC_GPIO_INPUT_BYPASS(12), + FUNCTION_DESC_GPIO_INPUT_BYPASS(13), + FUNCTION_DESC_GPIO_INPUT_BYPASS(14), + FUNCTION_DESC_GPIO_INPUT_BYPASS(15), - FUNCTION_DESC_GPIO_OUTPUT(0), - FUNCTION_DESC_GPIO_OUTPUT(1), - FUNCTION_DESC_GPIO_OUTPUT(2), - FUNCTION_DESC_GPIO_OUTPUT(3), - FUNCTION_DESC_GPIO_OUTPUT(4), - FUNCTION_DESC_GPIO_OUTPUT(5), - FUNCTION_DESC_GPIO_OUTPUT(6), - FUNCTION_DESC_GPIO_OUTPUT(7), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(0), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(1), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(2), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(3), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(4), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(5), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(6), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(7), - FUNCTION_DESC_GPIO_OUTPUT(8), - FUNCTION_DESC_GPIO_OUTPUT(9), - FUNCTION_DESC_GPIO_OUTPUT(10), - FUNCTION_DESC_GPIO_OUTPUT(11), - FUNCTION_DESC_GPIO_OUTPUT(12), - FUNCTION_DESC_GPIO_OUTPUT(13), - FUNCTION_DESC_GPIO_OUTPUT(14), - FUNCTION_DESC_GPIO_OUTPUT(15), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(8), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(9), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(10), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(11), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(12), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(13), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(14), + FUNCTION_DESC_GPIO_OUTPUT_BYPASS(15), + FUNCTION_DESC_GPIO_OUTPUT_LOW(0), + FUNCTION_DESC_GPIO_OUTPUT_LOW(1), + FUNCTION_DESC_GPIO_OUTPUT_LOW(2), + FUNCTION_DESC_GPIO_OUTPUT_LOW(3), + FUNCTION_DESC_GPIO_OUTPUT_LOW(4), + FUNCTION_DESC_GPIO_OUTPUT_LOW(5), + FUNCTION_DESC_GPIO_OUTPUT_LOW(6), + FUNCTION_DESC_GPIO_OUTPUT_LOW(7), + + FUNCTION_DESC_GPIO_OUTPUT_LOW(8), + FUNCTION_DESC_GPIO_OUTPUT_LOW(9), + FUNCTION_DESC_GPIO_OUTPUT_LOW(10), + FUNCTION_DESC_GPIO_OUTPUT_LOW(11), + FUNCTION_DESC_GPIO_OUTPUT_LOW(12), + FUNCTION_DESC_GPIO_OUTPUT_LOW(13), + FUNCTION_DESC_GPIO_OUTPUT_LOW(14), + FUNCTION_DESC_GPIO_OUTPUT_LOW(15), + + FUNCTION_DESC_GPIO_OUTPUT_HIGH(0), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(1), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(2), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(3), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(4), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(5), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(6), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(7), + + FUNCTION_DESC_GPIO_OUTPUT_HIGH(8), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(9), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(10), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(11), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(12), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(13), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(14), + FUNCTION_DESC_GPIO_OUTPUT_HIGH(15), + + FUNCTION_DES_DELAY_MS(10), + FUNCTION_DES_DELAY_MS(50), + FUNCTION_DES_DELAY_MS(100), + FUNCTION_DES_DELAY_MS(200), + FUNCTION_DES_DELAY_MS(500), }; static struct serdes_chip_pinctrl_info max96772_pinctrl_info = { @@ -181,6 +268,69 @@ .num_functions = ARRAY_SIZE(max96772_functions_desc), }; +static const struct reg_sequence max96772_clk_ref[3][14] = { + { + { 0xe7b2, 0x50 }, + { 0xe7b3, 0x00 }, + { 0xe7b4, 0xcc }, + { 0xe7b5, 0x44 }, + { 0xe7b6, 0x81 }, + { 0xe7b7, 0x30 }, + { 0xe7b8, 0x07 }, + { 0xe7b9, 0x10 }, + { 0xe7ba, 0x01 }, + { 0xe7bb, 0x00 }, + { 0xe7bc, 0x00 }, + { 0xe7bd, 0x00 }, + { 0xe7be, 0x52 }, + { 0xe7bf, 0x00 }, + }, { + { 0xe7b2, 0x50 }, + { 0xe7b3, 0x00 }, + { 0xe7b4, 0x00 }, + { 0xe7b5, 0x40 }, + { 0xe7b6, 0x6c }, + { 0xe7b7, 0x20 }, + { 0xe7b8, 0x07 }, + { 0xe7b9, 0x00 }, + { 0xe7ba, 0x01 }, + { 0xe7bb, 0x00 }, + { 0xe7bc, 0x00 }, + { 0xe7bd, 0x00 }, + { 0xe7be, 0x52 }, + { 0xe7bf, 0x00 }, + }, { + { 0xe7b2, 0x30 }, + { 0xe7b3, 0x00 }, + { 0xe7b4, 0x00 }, + { 0xe7b5, 0x40 }, + { 0xe7b6, 0x6c }, + { 0xe7b7, 0x20 }, + { 0xe7b8, 0x14 }, + { 0xe7b9, 0x00 }, + { 0xe7ba, 0x2e }, + { 0xe7bb, 0x00 }, + { 0xe7bc, 0x00 }, + { 0xe7bd, 0x01 }, + { 0xe7be, 0x32 }, + { 0xe7bf, 0x00 }, + } +}; + +static int max96772_aux_dpcd_read(struct serdes *serdes, unsigned int reg, unsigned int *value) +{ + serdes_reg_write(serdes, 0xe778, reg & 0xff); + serdes_reg_write(serdes, 0xe779, (reg >> 8) & 0xff); + serdes_reg_write(serdes, 0xe77c, (reg >> 16) & 0xff); + serdes_reg_write(serdes, 0xe776, 0x10); + serdes_reg_write(serdes, 0xe777, 0x80); + /* FIXME */ + msleep(50); + serdes_reg_read(serdes, 0xe77a, value); + + return 0; +} + static int max96772_panel_init(struct serdes *serdes) { return 0; @@ -188,6 +338,86 @@ static int max96772_panel_prepare(struct serdes *serdes) { + const struct drm_display_mode *mode = &serdes->serdes_panel->mode; + u32 hfp, hsa, hbp, hact; + u32 vact, vsa, vfp, vbp; + u64 hwords, mvid; + bool hsync_pol, vsync_pol; + + serdes_reg_write(serdes, 0xe790, serdes->serdes_panel->link_rate); + serdes_reg_write(serdes, 0xe792, serdes->serdes_panel->lane_count); + + if (serdes->serdes_panel->ssc) { + serdes_reg_write(serdes, 0xe7b0, 0x01); + serdes_reg_write(serdes, 0xe7b1, 0x10); + } else { + serdes_reg_write(serdes, 0xe7b1, 0x00); + } + + switch (serdes->serdes_panel->link_rate) { + case DP_LINK_BW_5_4: + serdes_multi_reg_write(serdes, max96772_clk_ref[2], + ARRAY_SIZE(max96772_clk_ref[2])); + break; + case DP_LINK_BW_2_7: + serdes_multi_reg_write(serdes, max96772_clk_ref[1], + ARRAY_SIZE(max96772_clk_ref[1])); + break; + case DP_LINK_BW_1_62: + default: + serdes_multi_reg_write(serdes, max96772_clk_ref[0], + ARRAY_SIZE(max96772_clk_ref[0])); + break; + } + + vact = mode->vdisplay; + vsa = mode->vsync_end - mode->vsync_start; + vfp = mode->vsync_start - mode->vdisplay; + vbp = mode->vtotal - mode->vsync_end; + hact = mode->hdisplay; + hsa = mode->hsync_end - mode->hsync_start; + hfp = mode->hsync_start - mode->hdisplay; + hbp = mode->htotal - mode->hsync_end; + + serdes_reg_write(serdes, 0xe794, hact & 0xff); + serdes_reg_write(serdes, 0xe795, (hact >> 8) & 0xff); + serdes_reg_write(serdes, 0xe796, hfp & 0xff); + serdes_reg_write(serdes, 0xe797, (hfp >> 8) & 0xff); + serdes_reg_write(serdes, 0xe798, hsa & 0xff); + serdes_reg_write(serdes, 0xe799, (hsa >> 8) & 0xff); + serdes_reg_write(serdes, 0xe79a, hbp & 0xff); + serdes_reg_write(serdes, 0xe79b, (hbp >> 8) & 0xff); + serdes_reg_write(serdes, 0xe79c, vact & 0xff); + serdes_reg_write(serdes, 0xe79d, (vact >> 8) & 0xff); + serdes_reg_write(serdes, 0xe79e, vfp & 0xff); + serdes_reg_write(serdes, 0xe79f, (vfp >> 8) & 0xff); + serdes_reg_write(serdes, 0xe7a0, vsa & 0xff); + serdes_reg_write(serdes, 0xe7a1, (vsa >> 8) & 0xff); + serdes_reg_write(serdes, 0xe7a2, vbp & 0xff); + serdes_reg_write(serdes, 0xe7a3, (vbp >> 8) & 0xff); + + hsync_pol = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); + vsync_pol = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); + serdes_reg_write(serdes, 0xe7ac, hsync_pol | (vsync_pol << 1)); + + /* NVID should always be set to 0x8000 */ + serdes_reg_write(serdes, 0xe7a8, 0); + serdes_reg_write(serdes, 0xe7a9, 0x80); + + /* HWORDS = ((HRES x bits / pixel) / 16) - LANE_COUNT */ + hwords = DIV_ROUND_CLOSEST_ULL(hact * 24, 16) - serdes->serdes_panel->lane_count; + serdes_reg_write(serdes, 0xe7a4, hwords); + serdes_reg_write(serdes, 0xe7a5, hwords >> 8); + + /* MVID = (PCLK x NVID) x 10 / Link Rate */ + mvid = DIV_ROUND_CLOSEST_ULL((u64)mode->clock * 32768, + drm_dp_bw_code_to_link_rate(serdes->serdes_panel->link_rate)); + serdes_reg_write(serdes, 0xe7a6, mvid & 0xff); + serdes_reg_write(serdes, 0xe7a7, (mvid >> 8) & 0xff); + + serdes_reg_write(serdes, 0xe7aa, 0x40); + serdes_reg_write(serdes, 0xe7ab, 0x00); + return 0; } @@ -198,6 +428,31 @@ static int max96772_panel_enable(struct serdes *serdes) { + u32 status[2]; + u32 val; + int ret; + + /* Run link training */ + serdes_reg_write(serdes, 0xe776, 0x02); + serdes_reg_write(serdes, 0xe777, 0x80); + + ret = regmap_read_poll_timeout(serdes->regmap, 0x07f0, val, + val & 0x01, MSEC_PER_SEC, + 500 * MSEC_PER_SEC); + if (!ret) + return 0; + + ret = max96772_aux_dpcd_read(serdes, DP_LANE0_1_STATUS, &status[0]); + if (ret) + return ret; + + ret = max96772_aux_dpcd_read(serdes, DP_LANE2_3_STATUS, &status[1]); + if (ret) + return ret; + + dev_err(serdes->dev, "Link Training failed: LANE0_1_STATUS=0x%02x, LANE2_3_STATUS=0x%02x\n", + status[0], status[1]); + return 0; } @@ -214,24 +469,213 @@ .disable = max96772_panel_disable, }; -static int max96772_pinctrl_config_get(struct serdes *serdes, - unsigned int pin, - unsigned long *config) +static int max96772_pinctrl_set_mux(struct serdes *serdes, + unsigned int function, unsigned int group) { + struct serdes_pinctrl *pinctrl = serdes->pinctrl; + struct function_desc *func; + struct group_desc *grp; + int i; + u16 ms; + + func = pinmux_generic_get_function(pinctrl->pctl, function); + if (!func) + return -EINVAL; + + grp = pinctrl_generic_get_group(pinctrl->pctl, group); + if (!grp) + return -EINVAL; + + SERDES_DBG_CHIP("%s: serdes chip %s func=%s data=%p group=%s data=%p, num_pin=%d\n", + __func__, serdes->chip_data->name, func->name, + func->data, grp->name, grp->data, grp->num_pins); + + if (func->data) { + struct serdes_function_data *fdata = func->data; + + ms = fdata->mdelay; + for (i = 0; i < grp->num_pins; i++) { + if (!ms) { + serdes_set_bits(serdes, GPIO_A_REG(grp->pins[i] - pinctrl->pin_base), + GPIO_OUT_DIS | GPIO_RX_EN | GPIO_TX_EN | GPIO_OUT, + FIELD_PREP(GPIO_OUT_DIS, fdata->gpio_out_dis) | + FIELD_PREP(GPIO_RX_EN, fdata->gpio_rx_en) | + FIELD_PREP(GPIO_TX_EN, fdata->gpio_tx_en) | + FIELD_PREP(GPIO_OUT, fdata->gpio_out_level)); + if (fdata->gpio_tx_en) + serdes_set_bits(serdes, + GPIO_B_REG(grp->pins[i] - pinctrl->pin_base), + GPIO_TX_ID, + FIELD_PREP(GPIO_TX_ID, fdata->gpio_tx_id)); + if (fdata->gpio_rx_en) + serdes_set_bits(serdes, + GPIO_C_REG(grp->pins[i] - pinctrl->pin_base), + GPIO_RX_ID, + FIELD_PREP(GPIO_RX_ID, fdata->gpio_rx_id)); + } else { + mdelay(ms); + SERDES_DBG_CHIP("%s: delay %d ms\n", + __func__, ms); + } + } + } + + if (grp->data) { + struct serdes_group_data *gdata = grp->data; + + for (i = 0; i < gdata->num_configs; i++) { + const struct config_desc *config = &gdata->configs[i]; + + serdes_set_bits(serdes, config->reg, + config->mask, config->val); + } + } + + return 0; +} + +static int max96772_pinctrl_config_get(struct serdes *serdes, + unsigned int pin, unsigned long *config) +{ + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned int gpio_a_reg, gpio_b_reg; + u16 arg = 0; + + serdes_reg_read(serdes, GPIO_A_REG(pin), &gpio_a_reg); + serdes_reg_read(serdes, GPIO_B_REG(pin), &gpio_b_reg); + + SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__, + serdes->chip_data->name, pin, param); + + switch (param) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (FIELD_GET(OUT_TYPE, gpio_b_reg)) + return -EINVAL; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (!FIELD_GET(OUT_TYPE, gpio_b_reg)) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_DISABLE: + if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 0) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 1) + return -EINVAL; + switch (FIELD_GET(RES_CFG, gpio_a_reg)) { + case 0: + arg = 40000; + break; + case 1: + arg = 10000; + break; + } + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (FIELD_GET(PULL_UPDN_SEL, gpio_b_reg) != 2) + return -EINVAL; + switch (FIELD_GET(RES_CFG, gpio_a_reg)) { + case 0: + arg = 40000; + break; + case 1: + arg = 10000; + break; + } + break; + case PIN_CONFIG_OUTPUT: + if (FIELD_GET(GPIO_OUT_DIS, gpio_a_reg)) + return -EINVAL; + + arg = FIELD_GET(GPIO_OUT, gpio_a_reg); + break; + default: + return -EOPNOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; } static int max96772_pinctrl_config_set(struct serdes *serdes, - unsigned int pin, - unsigned long *configs, + unsigned int pin, unsigned long *configs, unsigned int num_configs) { - return 0; -} + enum pin_config_param param; + u32 arg; + u8 res_cfg; + int i; -static int max96772_pinctrl_set_mux(struct serdes *serdes, unsigned int func_selector, - unsigned int group_selector) -{ + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + SERDES_DBG_CHIP("%s: serdes chip %s pin=%d param=%d\n", __func__, + serdes->chip_data->name, pin, param); + + switch (param) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + serdes_set_bits(serdes, GPIO_B_REG(pin), + OUT_TYPE, FIELD_PREP(OUT_TYPE, 0)); + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + serdes_set_bits(serdes, GPIO_B_REG(pin), + OUT_TYPE, FIELD_PREP(OUT_TYPE, 1)); + break; + case PIN_CONFIG_BIAS_DISABLE: + serdes_set_bits(serdes, GPIO_C_REG(pin), + PULL_UPDN_SEL, + FIELD_PREP(PULL_UPDN_SEL, 0)); + break; + case PIN_CONFIG_BIAS_PULL_UP: + switch (arg) { + case 40000: + res_cfg = 0; + break; + case 1000000: + res_cfg = 1; + break; + default: + return -EINVAL; + } + + serdes_set_bits(serdes, GPIO_A_REG(pin), + RES_CFG, FIELD_PREP(RES_CFG, res_cfg)); + serdes_set_bits(serdes, GPIO_C_REG(pin), + PULL_UPDN_SEL, + FIELD_PREP(PULL_UPDN_SEL, 1)); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + switch (arg) { + case 40000: + res_cfg = 0; + break; + case 1000000: + res_cfg = 1; + break; + default: + return -EINVAL; + } + + serdes_set_bits(serdes, GPIO_A_REG(pin), + RES_CFG, FIELD_PREP(RES_CFG, res_cfg)); + serdes_set_bits(serdes, GPIO_C_REG(pin), + PULL_UPDN_SEL, + FIELD_PREP(PULL_UPDN_SEL, 2)); + break; + case PIN_CONFIG_OUTPUT: + serdes_set_bits(serdes, GPIO_A_REG(pin), + GPIO_OUT_DIS | GPIO_OUT, + FIELD_PREP(GPIO_OUT_DIS, 0) | + FIELD_PREP(GPIO_OUT, arg)); + break; + default: + return -EOPNOTSUPP; + } + } + return 0; } -- Gitblit v1.6.2