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 <dm/of_access.h> 13 #include <linux/media-bus-format.h> 14 15 #include "rockchip_bridge.h" 16 #include "rockchip_display.h" 17 #include "rockchip_panel.h" 18 19 static void max96755f_mipi_dsi_rx_config(struct max96755f_priv *priv) 20 { 21 struct drm_display_mode *mode = &priv->mode; 22 u32 hfp, hsa, hbp, hact; 23 u32 vact, vsa, vfp, vbp; 24 25 dm_i2c_reg_clrset(priv->dev, 0x0331, NUM_LANES, 26 FIELD_PREP(NUM_LANES, priv->num_lanes - 1)); 27 if (!priv->dpi_deskew_en) 28 return; 29 30 vact = mode->vdisplay; 31 vsa = mode->vsync_end - mode->vsync_start; 32 vfp = mode->vsync_start - mode->vdisplay; 33 vbp = mode->vtotal - mode->vsync_end; 34 hact = mode->hdisplay; 35 hsa = mode->hsync_end - mode->hsync_start; 36 hfp = mode->hsync_start - mode->hdisplay; 37 hbp = mode->htotal - mode->hsync_end; 38 dm_i2c_reg_write(priv->dev, 0x03A4, 0xc1); 39 dm_i2c_reg_write(priv->dev, 0x0385, FIELD_PREP(DPI_HSYNC_WIDTH_L, hsa)); 40 dm_i2c_reg_write(priv->dev, 0x0386, FIELD_PREP(DPI_VYSNC_WIDTH_L, vsa)); 41 dm_i2c_reg_write(priv->dev, 0x0387, 42 FIELD_PREP(DPI_VSYNC_WIDTH_H, (vsa >> 8)) | 43 FIELD_PREP(DPI_HSYNC_WIDTH_H, (hsa >> 8))); 44 dm_i2c_reg_write(priv->dev, 0x03a5, FIELD_PREP(DPI_VFP_L, vfp)); 45 dm_i2c_reg_write(priv->dev, 0x03a6, 46 FIELD_PREP(DPI_VBP_L, vbp) | 47 FIELD_PREP(DPI_VFP_H, (vfp >> 8))); 48 dm_i2c_reg_write(priv->dev, 0x03a7, FIELD_PREP(DPI_VBP_H, (vbp >> 4))); 49 dm_i2c_reg_write(priv->dev, 0x03a8, FIELD_PREP(DPI_VACT_L, vact)); 50 dm_i2c_reg_write(priv->dev, 0x03a9, FIELD_PREP(DPI_VACT_H, (vact >> 8))); 51 dm_i2c_reg_write(priv->dev, 0x03aa, FIELD_PREP(DPI_HFP_L, hfp)); 52 dm_i2c_reg_write(priv->dev, 0x03ab, 53 FIELD_PREP(DPI_HBP_L, hbp) | 54 FIELD_PREP(DPI_HFP_H, (hfp >> 7))); 55 dm_i2c_reg_write(priv->dev, 0x03ac, FIELD_PREP(DPI_HBP_H, (hbp >> 4))); 56 dm_i2c_reg_write(priv->dev, 0x03ad, FIELD_PREP(DPI_HACT_L, hact)); 57 dm_i2c_reg_write(priv->dev, 0x03ae, FIELD_PREP(DPI_HACT_H, (hact >> 8))); 58 } 59 60 static void max96755f_bridge_enable(struct rockchip_bridge *bridge) 61 { 62 struct udevice *dev = bridge->dev; 63 struct max96755f_priv *priv = dev_get_priv(dev->parent); 64 65 max96755f_mipi_dsi_rx_config(priv); 66 if (priv->split_mode) { 67 dm_i2c_reg_clrset(dev->parent, 0x0010, 68 RESET_ONESHOT | AUTO_LINK | LINK_CFG, 69 FIELD_PREP(RESET_ONESHOT, 1) | 70 FIELD_PREP(AUTO_LINK, 0) | 71 FIELD_PREP(LINK_CFG, SPLITTER_MODE)); 72 mdelay(50); 73 dm_i2c_reg_clrset(dev->parent, 0x0053, 74 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL, 75 FIELD_PREP(TX_SPLIT_MASK_B, 0) | 76 FIELD_PREP(TX_SPLIT_MASK_A, 1) | 77 FIELD_PREP(TX_STR_SEL, 0)); 78 dm_i2c_reg_clrset(dev->parent, 0x0057, 79 TX_SPLIT_MASK_B | TX_SPLIT_MASK_A | TX_STR_SEL, 80 FIELD_PREP(TX_SPLIT_MASK_B, 1) | 81 FIELD_PREP(TX_SPLIT_MASK_A, 0) | 82 FIELD_PREP(TX_STR_SEL, 1)); 83 dm_i2c_reg_clrset(dev->parent, 0x032a, 84 DV_SWP_AB | DV_CONV | DV_SPL | DV_EN, 85 FIELD_PREP(DV_SWP_AB, priv->dv_swp_ab) | 86 FIELD_PREP(DV_CONV, 1) | 87 FIELD_PREP(DV_SPL, 1) | 88 FIELD_PREP(DV_EN, 1)); 89 dm_i2c_reg_clrset(dev->parent, 0x0311, 90 START_PORTAX | START_PORTAY, 91 FIELD_PREP(START_PORTAX, 1) | 92 FIELD_PREP(START_PORTAY, 1)); 93 dm_i2c_reg_clrset(dev->parent, 0x0002, 94 VID_TX_EN_X | VID_TX_EN_Y, 95 FIELD_PREP(VID_TX_EN_X, 1) | 96 FIELD_PREP(VID_TX_EN_Y, 1)); 97 98 } else { 99 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X, 100 FIELD_PREP(VID_TX_EN_X, 1)); 101 dm_i2c_reg_clrset(dev->parent, 0x0311, START_PORTAX, 102 FIELD_PREP(START_PORTAX, 1)); 103 } 104 105 dm_i2c_reg_clrset(dev->parent, 0x0010, RESET_ONESHOT, 106 FIELD_PREP(RESET_ONESHOT, 1)); 107 mdelay(100); 108 } 109 110 static void max96755f_bridge_disable(struct rockchip_bridge *bridge) 111 { 112 struct udevice *dev = bridge->dev; 113 struct max96755f_priv *priv = dev_get_priv(dev->parent); 114 115 dm_i2c_reg_clrset(dev->parent, 0x0002, VID_TX_EN_X, 116 FIELD_PREP(VID_TX_EN_X, 0)); 117 118 if (priv->split_mode) 119 dm_i2c_reg_clrset(dev->parent, 0x0010, 120 AUTO_LINK | LINK_CFG, 121 FIELD_PREP(AUTO_LINK, 0) | 122 FIELD_PREP(LINK_CFG, LINKA)); 123 } 124 125 static void max96755f_bridge_mode_set(struct rockchip_bridge *bridge, 126 const struct drm_display_mode *mode) 127 { 128 struct udevice *dev = bridge->dev; 129 struct max96755f_priv *priv = dev_get_priv(dev->parent); 130 131 memcpy(&priv->mode, mode, sizeof(struct drm_display_mode)); 132 } 133 134 static const struct rockchip_bridge_funcs max96755f_bridge_funcs = { 135 .enable = max96755f_bridge_enable, 136 .disable = max96755f_bridge_disable, 137 .mode_set = max96755f_bridge_mode_set, 138 }; 139 140 static int max96755f_bridge_probe(struct udevice *dev) 141 { 142 struct rockchip_bridge *bridge; 143 struct max96755f_priv *priv = dev_get_priv(dev->parent); 144 145 bridge = calloc(1, sizeof(*bridge)); 146 if (!bridge) 147 return -ENOMEM; 148 149 dev->driver_data = (ulong)bridge; 150 bridge->dev = dev; 151 bridge->funcs = &max96755f_bridge_funcs; 152 153 priv->num_lanes = dev_read_u32_default(dev, "dsi,lanes", 4); 154 priv->dv_swp_ab = dev_read_bool(dev, "vd-swap-ab"); 155 priv->dpi_deskew_en = dev_read_bool(dev, "dpi-deskew-en"); 156 157 return 0; 158 } 159 160 static const struct udevice_id max96755f_bridge_of_match[] = { 161 { .compatible = "maxim,max96755f-bridge", }, 162 { } 163 }; 164 165 U_BOOT_DRIVER(max96755f_bridge) = { 166 .name = "max96755f_bridge", 167 .id = UCLASS_VIDEO_BRIDGE, 168 .of_match = max96755f_bridge_of_match, 169 .probe = max96755f_bridge_probe, 170 }; 171