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 <linux/iopoll.h> 11 12 #include "rk628.h" 13 #include "rk628_cru.h" 14 #include "rk628_combtxphy.h" 15 #include "rk628_gvi.h" 16 #include "panel.h" 17 18 #define GVI_RETRY_TIMEOUT 10 19 20 int rk628_gvi_parse(struct rk628 *rk628, ofnode gvi_np) 21 { 22 const char *string; 23 u32 val; 24 int ret; 25 26 if (!ofnode_valid(gvi_np)) 27 return -EINVAL; 28 29 if (!ofnode_read_u32(gvi_np, "gvi,lanes", &val)) 30 rk628->gvi.lanes = val; 31 32 if (ofnode_read_bool(gvi_np, "rockchip,division-mode")) 33 rk628->gvi.division_mode = true; 34 else 35 rk628->gvi.division_mode = false; 36 37 if (ofnode_read_bool(gvi_np, "rockchip,gvi-frm-rst")) 38 rk628->gvi.frm_rst = true; 39 else 40 rk628->gvi.frm_rst = false; 41 42 string = ofnode_read_string(gvi_np, "bus-format"); 43 if (string) { 44 if (!strcmp(string, "rgb666")) 45 rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB666_1X18; 46 else if (!strcmp(string, "rgb101010")) 47 rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB101010_1X30; 48 else if (!strcmp(string, "yuyv8")) 49 rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV8_1X16; 50 else if (!strcmp(string, "yuyv10")) 51 rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_YUYV10_1X20; 52 else 53 rk628->gvi.bus_format = GVI_MEDIA_BUS_FMT_RGB888_1X24; 54 } 55 56 ret = rk628_panel_info_get(rk628, gvi_np); 57 if (ret) 58 return ret; 59 60 return 0; 61 } 62 63 static void rk628_gvi_get_info(struct rk628_gvi *gvi) 64 { 65 switch (gvi->bus_format) { 66 case GVI_MEDIA_BUS_FMT_RGB666_1X18: 67 gvi->byte_mode = 3; 68 gvi->color_depth = COLOR_DEPTH_RGB_YUV444_18BIT; 69 break; 70 case GVI_MEDIA_BUS_FMT_RGB888_1X24: 71 gvi->byte_mode = 4; 72 gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT; 73 break; 74 case GVI_MEDIA_BUS_FMT_RGB101010_1X30: 75 gvi->byte_mode = 4; 76 gvi->color_depth = COLOR_DEPTH_RGB_YUV444_30BIT; 77 break; 78 case GVI_MEDIA_BUS_FMT_YUYV8_1X16: 79 gvi->byte_mode = 3; 80 gvi->color_depth = COLOR_DEPTH_YUV422_16BIT; 81 break; 82 case GVI_MEDIA_BUS_FMT_YUYV10_1X20: 83 gvi->byte_mode = 3; 84 gvi->color_depth = COLOR_DEPTH_YUV422_20BIT; 85 break; 86 default: 87 gvi->byte_mode = 3; 88 gvi->color_depth = COLOR_DEPTH_RGB_YUV444_24BIT; 89 pr_err("unsupported bus_format: 0x%x\n", gvi->bus_format); 90 break; 91 } 92 } 93 94 static unsigned int rk628_gvi_get_lane_rate(struct rk628 *rk628) 95 { 96 struct rk628_gvi *gvi = &rk628->gvi; 97 u32 lane_bit_rate, min_lane_rate = 500000, max_lane_rate = 4000000; 98 u64 total_bw; 99 struct drm_display_mode *src = &rk628->src_mode; 100 const struct drm_display_mode *dst = &rk628->dst_mode; 101 u64 dst_rate, src_rate; 102 103 src_rate = src->clock * 1000; 104 dst_rate = src_rate * dst->vtotal * dst->htotal; 105 do_div(dst_rate, (src->vtotal * src->htotal)); 106 do_div(dst_rate, 1000); 107 108 /** 109 * [ENCODER TOTAL BIT-RATE](bps) = [byte mode](byte) x 10 / [pixel clock](HZ) 110 * 111 * lane_bit_rate = [total bit-rate](bps) / [lane number] 112 * 113 * 500Mbps <= lane_bit_rate <= 4Gbps 114 */ 115 total_bw = (u64)gvi->byte_mode * 10 * dst_rate;/* Kbps */ 116 do_div(total_bw, gvi->lanes); 117 lane_bit_rate = total_bw; 118 119 if (lane_bit_rate < min_lane_rate) 120 lane_bit_rate = min_lane_rate; 121 if (lane_bit_rate > max_lane_rate) 122 lane_bit_rate = max_lane_rate; 123 124 return lane_bit_rate; 125 } 126 127 static void rk628_gvi_pre_enable(struct rk628 *rk628, struct rk628_gvi *gvi) 128 { 129 /* gvi reset */ 130 rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST, 131 SYS_RST_SOFT_RST); 132 udelay(10); 133 rk628_i2c_update_bits(rk628, GVI_SYS_RST, SYS_RST_SOFT_RST, 0); 134 udelay(10); 135 136 rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_8_PIXEL_ALIGN(1)); 137 138 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_LANE_NUM_MASK, 139 SYS_CTRL0_LANE_NUM(gvi->lanes - 1)); 140 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_BYTE_MODE_MASK, 141 SYS_CTRL0_BYTE_MODE(gvi->byte_mode == 142 3 ? 0 : (gvi->byte_mode == 4 ? 1 : 2))); 143 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_SECTION_NUM_MASK, 144 SYS_CTRL0_SECTION_NUM(gvi->division_mode)); 145 rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON, SW_SPLIT_EN, 146 gvi->division_mode ? SW_SPLIT_EN : 0); 147 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_DUAL_PIXEL_EN, 148 gvi->division_mode ? SYS_CTRL1_DUAL_PIXEL_EN : 0); 149 150 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_FRM_RST_EN, 151 gvi->frm_rst ? SYS_CTRL0_FRM_RST_EN : 0); 152 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_LANE_ALIGN_EN, 0); 153 154 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL1, SYS_CTRL1_COLOR_DEPTH_MASK, 155 SYS_CTRL1_COLOR_DEPTH(gvi->color_depth)); 156 } 157 158 static void rk628_gvi_enable_color_bar(struct rk628 *rk628, 159 struct rk628_gvi *gvi) 160 { 161 const struct drm_display_mode *mode = &rk628->dst_mode; 162 u16 vm_hactive, vm_hback_porch, vm_hsync_len; 163 u16 vm_vactive, vm_vback_porch, vm_vsync_len; 164 u16 hsync_len, hact_st, hact_end, htotal; 165 u16 vsync_len, vact_st, vact_end, vtotal; 166 167 vm_hactive = mode->hdisplay; 168 vm_hsync_len = mode->hsync_end - mode->hsync_start; 169 vm_hback_porch = mode->htotal - mode->hsync_end; 170 171 vm_vactive = mode->vdisplay; 172 vm_vsync_len = mode->vsync_end - mode->vsync_start; 173 vm_vback_porch = mode->vtotal - mode->vsync_end; 174 175 if (gvi->division_mode) { 176 hsync_len = vm_hsync_len / 2; 177 hact_st = (vm_hsync_len + vm_hback_porch) / 2; 178 hact_end = (vm_hsync_len + vm_hback_porch + vm_hactive) / 2; 179 htotal = mode->htotal / 2; 180 } else { 181 hsync_len = vm_hsync_len; 182 hact_st = vm_hsync_len + vm_hback_porch; 183 hact_end = vm_hsync_len + vm_hback_porch + vm_hactive; 184 htotal = mode->htotal; 185 } 186 vsync_len = vm_vsync_len; 187 vact_st = vsync_len + vm_vback_porch; 188 vact_end = vact_st + vm_vactive; 189 vtotal = mode->vtotal; 190 191 rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING0, 192 hact_st << 16 | hsync_len); 193 rk628_i2c_write(rk628, GVI_COLOR_BAR_HTIMING1, 194 (htotal - 1) << 16 | hact_end); 195 rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING0, 196 vact_st << 16 | vsync_len); 197 rk628_i2c_write(rk628, GVI_COLOR_BAR_VTIMING1, 198 (vtotal - 1) << 16 | vact_end); 199 rk628_i2c_update_bits(rk628, GVI_COLOR_BAR_CTRL, COLOR_BAR_EN, 0); 200 } 201 202 static void rk628_gvi_post_enable(struct rk628 *rk628, struct rk628_gvi *gvi) 203 { 204 u32 val; 205 206 val = SYS_CTRL0_GVI_EN | SYS_CTRL0_AUTO_GATING; 207 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, val, 3); 208 } 209 210 void rk628_gvi_enable(struct rk628 *rk628) 211 { 212 struct rk628_gvi *gvi = &rk628->gvi; 213 unsigned int rate; 214 u32 mask = SW_OUTPUT_MODE_MASK; 215 u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_GVI); 216 int i = 0; 217 218 rk628_gvi_get_info(gvi); 219 rate = rk628_gvi_get_lane_rate(rk628); 220 221 /* set gvi_hpd and gvi_lock mux */ 222 rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x06000600); 223 224 if (rk628->version == RK628F_VERSION) { 225 mask = SW_OUTPUT_COMBTX_MODE_MASK; 226 val = SW_OUTPUT_COMBTX_MODE(OUTPUT_MODE_GVI); 227 } 228 229 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, mask, val); 230 rk628_combtxphy_set_bus_width(rk628, rate); 231 rk628_combtxphy_set_gvi_division_mode(rk628, gvi->division_mode); 232 rk628_combtxphy_set_mode(rk628, RK628_PHY_MODE_VIDEO_GVI); 233 rate = rk628_combtxphy_get_bus_width(rk628); 234 rk628_combtxphy_power_on(rk628); 235 rk628_gvi_pre_enable(rk628, gvi); 236 rk628_panel_prepare(rk628); 237 rk628_gvi_enable_color_bar(rk628, gvi); 238 rk628_gvi_post_enable(rk628, gvi); 239 240 for (i = 0; i < 100; i++) { 241 rk628_i2c_read(rk628, GVI_STATUS, &val); 242 if ((val & GVI_LOCKED_MASK) == GVI_LOCKED_STATUS) 243 break; 244 udelay(1000); 245 } 246 247 if (i == 100 && gvi->retry_times < GVI_RETRY_TIMEOUT) { 248 dev_info(rk628->dev, "GVI Lock failed: 0x%x, try again: %d\n", val, gvi->retry_times); 249 gvi->retry_times++; 250 rk628_gvi_disable(rk628); 251 udelay(50000); 252 rk628_gvi_enable(rk628); 253 } 254 255 if (gvi->retry_times >= GVI_RETRY_TIMEOUT && i == 100) { 256 dev_info(rk628->dev, "GVI Lock failed, please check hardware!\n"); 257 return; 258 } 259 rk628_panel_enable(rk628); 260 261 if (i != 100) 262 gvi->retry_times = 0; 263 264 printf("rk628 GVI-Link bandwidth: %d x %d Mbps, Byte mode: %d, Color Depty: %d, %s division mode\n", 265 rate, gvi->lanes, gvi->byte_mode, gvi->color_depth, 266 gvi->division_mode ? "two" : "one"); 267 } 268 269 void rk628_gvi_disable(struct rk628 *rk628) 270 { 271 rk628_panel_disable(rk628); 272 rk628_panel_unprepare(rk628); 273 rk628_i2c_update_bits(rk628, GVI_SYS_CTRL0, SYS_CTRL0_GVI_EN, 0); 274 rk628_combtxphy_power_off(rk628); 275 } 276 277