1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2022 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <i2c.h> 10 #include <max96755f.h> 11 #include <video_bridge.h> 12 #include <drm/drm_mipi_dsi.h> 13 #include <dm/of_access.h> 14 #include <linux/media-bus-format.h> 15 16 #include "rockchip_bridge.h" 17 #include "rockchip_display.h" 18 #include "rockchip_panel.h" 19 20 static void max96755f_mipi_dsi_rx_config(struct max96755f_priv *priv) 21 { 22 struct drm_display_mode *mode = &priv->mode; 23 u32 hfp, hsa, hbp, hact; 24 u32 vact, vsa, vfp, vbp; 25 26 dm_i2c_reg_clrset(priv->dev, 0x0331, NUM_LANES, 27 FIELD_PREP(NUM_LANES, priv->num_lanes - 1)); 28 if (!priv->dpi_deskew_en) 29 return; 30 31 vact = mode->vdisplay; 32 vsa = mode->vsync_end - mode->vsync_start; 33 vfp = mode->vsync_start - mode->vdisplay; 34 vbp = mode->vtotal - mode->vsync_end; 35 hact = mode->hdisplay; 36 hsa = mode->hsync_end - mode->hsync_start; 37 hfp = mode->hsync_start - mode->hdisplay; 38 hbp = mode->htotal - mode->hsync_end; 39 dm_i2c_reg_write(priv->dev, 0x03A4, 0xc1); 40 dm_i2c_reg_write(priv->dev, 0x0385, FIELD_PREP(DPI_HSYNC_WIDTH_L, hsa)); 41 dm_i2c_reg_write(priv->dev, 0x0386, FIELD_PREP(DPI_VYSNC_WIDTH_L, vsa)); 42 dm_i2c_reg_write(priv->dev, 0x0387, 43 FIELD_PREP(DPI_VSYNC_WIDTH_H, (vsa >> 8)) | 44 FIELD_PREP(DPI_HSYNC_WIDTH_H, (hsa >> 8))); 45 dm_i2c_reg_write(priv->dev, 0x03a5, FIELD_PREP(DPI_VFP_L, vfp)); 46 dm_i2c_reg_write(priv->dev, 0x03a6, 47 FIELD_PREP(DPI_VBP_L, vbp) | 48 FIELD_PREP(DPI_VFP_H, (vfp >> 8))); 49 dm_i2c_reg_write(priv->dev, 0x03a7, FIELD_PREP(DPI_VBP_H, (vbp >> 4))); 50 dm_i2c_reg_write(priv->dev, 0x03a8, FIELD_PREP(DPI_VACT_L, vact)); 51 dm_i2c_reg_write(priv->dev, 0x03a9, FIELD_PREP(DPI_VACT_H, (vact >> 8))); 52 dm_i2c_reg_write(priv->dev, 0x03aa, FIELD_PREP(DPI_HFP_L, hfp)); 53 dm_i2c_reg_write(priv->dev, 0x03ab, 54 FIELD_PREP(DPI_HBP_L, hbp) | 55 FIELD_PREP(DPI_HFP_H, (hfp >> 7))); 56 dm_i2c_reg_write(priv->dev, 0x03ac, FIELD_PREP(DPI_HBP_H, (hbp >> 4))); 57 dm_i2c_reg_write(priv->dev, 0x03ad, FIELD_PREP(DPI_HACT_L, hact)); 58 dm_i2c_reg_write(priv->dev, 0x03ae, FIELD_PREP(DPI_HACT_H, (hact >> 8))); 59 } 60 61 static void max96755f_bridge_enable(struct rockchip_bridge *bridge) 62 { 63 struct udevice *dev = bridge->dev; 64 struct max96755f_priv *priv = dev_get_priv(dev->parent); 65 66 max96755f_mipi_dsi_rx_config(priv); 67 if (priv->split_mode) { 68 dm_i2c_reg_clrset(dev->parent, 0x0010, 69 RESET_ONESHOT | AUTO_LINK | LINK_CFG, 70 FIELD_PREP(RESET_ONESHOT, 1) | 71 FIELD_PREP(AUTO_LINK, 0) | 72 FIELD_PREP(LINK_CFG, SPLITTER_MODE)); 73 mdelay(50); 74 dm_i2c_reg_clrset(dev->parent, 0x0053, 75 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL, 76 FIELD_PREP(TX_SPLIT_MASK_B, 0) | 77 FIELD_PREP(TX_SPLIT_MASK_A, 1) | 78 FIELD_PREP(TX_STR_SEL, 0)); 79 dm_i2c_reg_clrset(dev->parent, 0x0057, 80 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL, 81 FIELD_PREP(TX_SPLIT_MASK_B, 1) | 82 FIELD_PREP(TX_SPLIT_MASK_A, 0) | 83 FIELD_PREP(TX_STR_SEL, 1)); 84 dm_i2c_reg_clrset(dev->parent, 0x032a, 85 DV_SWP_AB | DV_CONV | DV_SPL | DV_EN, 86 FIELD_PREP(DV_SWP_AB, priv->dv_swp_ab) | 87 FIELD_PREP(DV_CONV, 1) | 88 FIELD_PREP(DV_SPL, 1) | 89 FIELD_PREP(DV_EN, 1)); 90 dm_i2c_reg_clrset(dev->parent, 0x0311, 91 START_PORTAX | START_PORTAY, 92 FIELD_PREP(START_PORTAX, 1) | 93 FIELD_PREP(START_PORTAY, 1)); 94 dm_i2c_reg_clrset(dev->parent, 0x0002, 95 VID_TX_EN_X | VID_TX_EN_Y, 96 FIELD_PREP(VID_TX_EN_X, 1) | 97 FIELD_PREP(VID_TX_EN_Y, 1)); 98 99 } else { 100 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X, 101 FIELD_PREP(VID_TX_EN_X, 1)); 102 dm_i2c_reg_clrset(dev->parent, 0x0311, START_PORTAX, 103 FIELD_PREP(START_PORTAX, 1)); 104 } 105 106 dm_i2c_reg_clrset(dev->parent, 0x0010, RESET_ONESHOT, 107 FIELD_PREP(RESET_ONESHOT, 1)); 108 mdelay(100); 109 } 110 111 static void max96755f_bridge_disable(struct rockchip_bridge *bridge) 112 { 113 struct udevice *dev = bridge->dev; 114 struct max96755f_priv *priv = dev_get_priv(dev->parent); 115 116 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X, 117 FIELD_PREP(VID_TX_EN_X, 0)); 118 119 if (priv->split_mode) 120 dm_i2c_reg_clrset(dev->parent, 0x0010, 121 AUTO_LINK | LINK_CFG, 122 FIELD_PREP(AUTO_LINK, 0) | 123 FIELD_PREP(LINK_CFG, LINKA)); 124 } 125 126 static void max96755f_bridge_mode_set(struct rockchip_bridge *bridge, 127 const struct drm_display_mode *mode) 128 { 129 struct udevice *dev = bridge->dev; 130 struct max96755f_priv *priv = dev_get_priv(dev->parent); 131 132 memcpy(&priv->mode, mode, sizeof(struct drm_display_mode)); 133 } 134 135 static bool max96755f_bridge_detect(struct rockchip_bridge *bridge) 136 { 137 struct max96755f_priv *priv = dev_get_priv(bridge->dev->parent); 138 139 if (!dm_gpio_get_value(&priv->lock_gpio)) 140 return false; 141 142 return true; 143 } 144 145 static const struct rockchip_bridge_funcs max96755f_bridge_funcs = { 146 .enable = max96755f_bridge_enable, 147 .disable = max96755f_bridge_disable, 148 .mode_set = max96755f_bridge_mode_set, 149 .detect = max96755f_bridge_detect, 150 }; 151 152 static int max96755f_bridge_bind(struct udevice *dev) 153 { 154 struct mipi_dsi_device *device = dev_get_platdata(dev); 155 156 device->dev = dev; 157 device->lanes = dev_read_u32_default(dev, "dsi,lanes", 4); 158 device->format = dev_read_u32_default(dev, "dsi,format", 159 MIPI_DSI_FMT_RGB888); 160 device->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 161 device->channel = dev_read_u32_default(dev, "reg", 0); 162 163 return 0; 164 } 165 166 static int max96755f_bridge_probe(struct udevice *dev) 167 { 168 struct rockchip_bridge *bridge; 169 struct max96755f_priv *priv = dev_get_priv(dev->parent); 170 int ret; 171 172 bridge = calloc(1, sizeof(*bridge)); 173 if (!bridge) 174 return -ENOMEM; 175 176 dev->driver_data = (ulong)bridge; 177 bridge->dev = dev; 178 bridge->funcs = &max96755f_bridge_funcs; 179 180 priv->num_lanes = dev_read_u32_default(dev, "dsi,lanes", 4); 181 priv->dv_swp_ab = dev_read_bool(dev, "vd-swap-ab"); 182 priv->dpi_deskew_en = dev_read_bool(dev, "dpi-deskew-en"); 183 184 ret = gpio_request_by_name(dev, "lock-gpios", 0, &priv->lock_gpio, 185 GPIOD_IS_IN); 186 if (ret) { 187 dev_err(dev, "failed to get lock GPIO: %d\n", ret); 188 return ret; 189 } 190 191 return 0; 192 } 193 194 static const struct udevice_id max96755f_bridge_of_match[] = { 195 { .compatible = "maxim,max96755f-bridge", }, 196 { } 197 }; 198 199 U_BOOT_DRIVER(max96755f_bridge) = { 200 .name = "max96755f_bridge", 201 .id = UCLASS_VIDEO_BRIDGE, 202 .of_match = max96755f_bridge_of_match, 203 .probe = max96755f_bridge_probe, 204 .bind = max96755f_bridge_bind, 205 .platdata_auto_alloc_size = sizeof(struct mipi_dsi_device), 206 }; 207