diff --git a/drivers/gpu/drm/bridge/maxim-max96755f.c b/drivers/gpu/drm/bridge/maxim-max96755f.c index b2d50ad400c7..7cb7a60f51f9 100644 --- a/drivers/gpu/drm/bridge/maxim-max96755f.c +++ b/drivers/gpu/drm/bridge/maxim-max96755f.c @@ -39,6 +39,8 @@ struct max96755f_bridge { bool dv_swp_ab; bool dpi_deskew_en; bool split_mode; + u32 dsi_lane_map[4]; + struct { struct gpio_desc *gpio; int irq; @@ -196,6 +198,7 @@ static void max96755f_mipi_dsi_rx_config(struct max96755f_bridge *ser) struct drm_display_mode *mode = &ser->mode; u32 hfp, hsa, hbp, hact; u32 vact, vsa, vfp, vbp; + u8 lane_map; regmap_update_bits(ser->regmap, 0x330, MIPI_RX_RESET, FIELD_PREP(MIPI_RX_RESET, 1)); @@ -207,6 +210,12 @@ static void max96755f_mipi_dsi_rx_config(struct max96755f_bridge *ser) regmap_update_bits(ser->regmap, 0x331, NUM_LANES, FIELD_PREP(NUM_LANES, ser->num_lanes - 1)); + lane_map = (ser->dsi_lane_map[0] & 0xff) << 4 | + (ser->dsi_lane_map[1] & 0xff) << 6 | + (ser->dsi_lane_map[2] & 0xff) << 0 | + (ser->dsi_lane_map[3] & 0xff) << 2; + regmap_write(ser->regmap, 0x332, lane_map); + if (!ser->dpi_deskew_en) return; @@ -405,17 +414,39 @@ static const struct drm_bridge_funcs max96755f_bridge_funcs = { static int max96755f_link_parse(struct max96755f_bridge *ser) { struct device *dev = ser->dev; + struct device_node *np = dev->of_node; struct device *parent = dev->parent; struct device_node *child; u32 val; int ret = 0; unsigned int nr = 0; + int i, len; - ser->dpi_deskew_en = of_property_read_bool(dev->of_node, "dpi-deskew-en"); - ser->dv_swp_ab = of_property_read_bool(dev->of_node, "vd-swap-ab"); + ser->dpi_deskew_en = of_property_read_bool(np, "dpi-deskew-en"); + ser->dv_swp_ab = of_property_read_bool(np, "vd-swap-ab"); - if (!of_property_read_u32(dev->of_node, "dsi,lanes", &val)) + if (!of_property_read_u32(np, "dsi,lanes", &val)) ser->num_lanes = val; + else + ser->num_lanes = 4; + + for (i = 0; i < ser->num_lanes; i++) + ser->dsi_lane_map[i] = i; + + if (of_find_property(np, "maxim,dsi-lane-map", &len)) { + len /= sizeof(u32); + if (ser->num_lanes != len) { + dev_err(dev, "invalid number of lane map\n"); + return -EINVAL; + } + + ret = of_property_read_u32_array(np, "maxim,dsi-lane-map", + ser->dsi_lane_map, len); + if (ret) { + dev_err(dev, "get dsi lane map failed\n"); + return -EINVAL; + } + } for_each_available_child_of_node(parent->of_node, child) { if (!of_find_property(child, "reg", NULL))