0001
0002
0003
0004
0005
0006 #include "dp_panel.h"
0007
0008 #include <drm/drm_connector.h>
0009 #include <drm/drm_edid.h>
0010 #include <drm/drm_print.h>
0011
0012 struct dp_panel_private {
0013 struct device *dev;
0014 struct drm_device *drm_dev;
0015 struct dp_panel dp_panel;
0016 struct drm_dp_aux *aux;
0017 struct dp_link *link;
0018 struct dp_catalog *catalog;
0019 bool panel_on;
0020 bool aux_cfg_update_done;
0021 };
0022
0023 static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
0024 {
0025 int rc = 0;
0026 size_t len;
0027 ssize_t rlen;
0028 struct dp_panel_private *panel;
0029 struct dp_link_info *link_info;
0030 u8 *dpcd, major = 0, minor = 0, temp;
0031 u32 offset = DP_DPCD_REV;
0032
0033 dpcd = dp_panel->dpcd;
0034
0035 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0036 link_info = &dp_panel->link_info;
0037
0038 rlen = drm_dp_dpcd_read(panel->aux, offset,
0039 dpcd, (DP_RECEIVER_CAP_SIZE + 1));
0040 if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) {
0041 DRM_ERROR("dpcd read failed, rlen=%zd\n", rlen);
0042 if (rlen == -ETIMEDOUT)
0043 rc = rlen;
0044 else
0045 rc = -EINVAL;
0046
0047 goto end;
0048 }
0049
0050 temp = dpcd[DP_TRAINING_AUX_RD_INTERVAL];
0051
0052
0053 if (temp & BIT(7)) {
0054 drm_dbg_dp(panel->drm_dev,
0055 "using EXTENDED_RECEIVER_CAPABILITY_FIELD\n");
0056 offset = DPRX_EXTENDED_DPCD_FIELD;
0057 }
0058
0059 rlen = drm_dp_dpcd_read(panel->aux, offset,
0060 dpcd, (DP_RECEIVER_CAP_SIZE + 1));
0061 if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) {
0062 DRM_ERROR("dpcd read failed, rlen=%zd\n", rlen);
0063 if (rlen == -ETIMEDOUT)
0064 rc = rlen;
0065 else
0066 rc = -EINVAL;
0067
0068 goto end;
0069 }
0070
0071 link_info->revision = dpcd[DP_DPCD_REV];
0072 major = (link_info->revision >> 4) & 0x0f;
0073 minor = link_info->revision & 0x0f;
0074
0075 link_info->rate = drm_dp_bw_code_to_link_rate(dpcd[DP_MAX_LINK_RATE]);
0076 link_info->num_lanes = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
0077
0078 if (link_info->num_lanes > dp_panel->max_dp_lanes)
0079 link_info->num_lanes = dp_panel->max_dp_lanes;
0080
0081
0082 if (link_info->rate >= (drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4)))
0083 link_info->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
0084
0085 drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
0086 drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
0087 drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);
0088
0089 if (drm_dp_enhanced_frame_cap(dpcd))
0090 link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
0091
0092 dp_panel->dfp_present = dpcd[DP_DOWNSTREAMPORT_PRESENT];
0093 dp_panel->dfp_present &= DP_DWN_STRM_PORT_PRESENT;
0094
0095 if (dp_panel->dfp_present && (dpcd[DP_DPCD_REV] > 0x10)) {
0096 dp_panel->ds_port_cnt = dpcd[DP_DOWN_STREAM_PORT_COUNT];
0097 dp_panel->ds_port_cnt &= DP_PORT_COUNT_MASK;
0098 len = DP_DOWNSTREAM_PORTS * DP_DOWNSTREAM_CAP_SIZE;
0099
0100 rlen = drm_dp_dpcd_read(panel->aux,
0101 DP_DOWNSTREAM_PORT_0, dp_panel->ds_cap_info, len);
0102 if (rlen < len) {
0103 DRM_ERROR("ds port status failed, rlen=%zd\n", rlen);
0104 rc = -EINVAL;
0105 goto end;
0106 }
0107 }
0108
0109 end:
0110 return rc;
0111 }
0112
0113 static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
0114 u32 mode_edid_bpp, u32 mode_pclk_khz)
0115 {
0116 struct dp_link_info *link_info;
0117 const u32 max_supported_bpp = 30, min_supported_bpp = 18;
0118 u32 bpp = 0, data_rate_khz = 0;
0119
0120 bpp = min_t(u32, mode_edid_bpp, max_supported_bpp);
0121
0122 link_info = &dp_panel->link_info;
0123 data_rate_khz = link_info->num_lanes * link_info->rate * 8;
0124
0125 while (bpp > min_supported_bpp) {
0126 if (mode_pclk_khz * bpp <= data_rate_khz)
0127 break;
0128 bpp -= 6;
0129 }
0130
0131 return bpp;
0132 }
0133
0134 static int dp_panel_update_modes(struct drm_connector *connector,
0135 struct edid *edid)
0136 {
0137 int rc = 0;
0138
0139 if (edid) {
0140 rc = drm_connector_update_edid_property(connector, edid);
0141 if (rc) {
0142 DRM_ERROR("failed to update edid property %d\n", rc);
0143 return rc;
0144 }
0145 rc = drm_add_edid_modes(connector, edid);
0146 return rc;
0147 }
0148
0149 rc = drm_connector_update_edid_property(connector, NULL);
0150 if (rc)
0151 DRM_ERROR("failed to update edid property %d\n", rc);
0152
0153 return rc;
0154 }
0155
0156 int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
0157 struct drm_connector *connector)
0158 {
0159 int rc = 0, bw_code;
0160 int rlen, count;
0161 struct dp_panel_private *panel;
0162
0163 if (!dp_panel || !connector) {
0164 DRM_ERROR("invalid input\n");
0165 return -EINVAL;
0166 }
0167
0168 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0169
0170 rc = dp_panel_read_dpcd(dp_panel);
0171 if (rc) {
0172 DRM_ERROR("read dpcd failed %d\n", rc);
0173 return rc;
0174 }
0175
0176 bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate);
0177 if (!is_link_rate_valid(bw_code) ||
0178 !is_lane_count_valid(dp_panel->link_info.num_lanes) ||
0179 (bw_code > dp_panel->max_bw_code)) {
0180 DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate,
0181 dp_panel->link_info.num_lanes);
0182 return -EINVAL;
0183 }
0184
0185 if (dp_panel->dfp_present) {
0186 rlen = drm_dp_dpcd_read(panel->aux, DP_SINK_COUNT,
0187 &count, 1);
0188 if (rlen == 1) {
0189 count = DP_GET_SINK_COUNT(count);
0190 if (!count) {
0191 DRM_ERROR("no downstream ports connected\n");
0192 panel->link->sink_count = 0;
0193 rc = -ENOTCONN;
0194 goto end;
0195 }
0196 }
0197 }
0198
0199 kfree(dp_panel->edid);
0200 dp_panel->edid = NULL;
0201
0202 dp_panel->edid = drm_get_edid(connector,
0203 &panel->aux->ddc);
0204 if (!dp_panel->edid) {
0205 DRM_ERROR("panel edid read failed\n");
0206
0207 if (!dp_catalog_link_is_connected(panel->catalog)) {
0208 rc = -ETIMEDOUT;
0209 goto end;
0210 }
0211 }
0212
0213 if (panel->aux_cfg_update_done) {
0214 drm_dbg_dp(panel->drm_dev,
0215 "read DPCD with updated AUX config\n");
0216 rc = dp_panel_read_dpcd(dp_panel);
0217 bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate);
0218 if (rc || !is_link_rate_valid(bw_code) ||
0219 !is_lane_count_valid(dp_panel->link_info.num_lanes)
0220 || (bw_code > dp_panel->max_bw_code)) {
0221 DRM_ERROR("read dpcd failed %d\n", rc);
0222 return rc;
0223 }
0224 panel->aux_cfg_update_done = false;
0225 }
0226 end:
0227 return rc;
0228 }
0229
0230 u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel,
0231 u32 mode_edid_bpp, u32 mode_pclk_khz)
0232 {
0233 struct dp_panel_private *panel;
0234 u32 bpp;
0235
0236 if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
0237 DRM_ERROR("invalid input\n");
0238 return 0;
0239 }
0240
0241 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0242
0243 if (dp_panel->video_test)
0244 bpp = dp_link_bit_depth_to_bpp(
0245 panel->link->test_video.test_bit_depth);
0246 else
0247 bpp = dp_panel_get_supported_bpp(dp_panel, mode_edid_bpp,
0248 mode_pclk_khz);
0249
0250 return bpp;
0251 }
0252
0253 int dp_panel_get_modes(struct dp_panel *dp_panel,
0254 struct drm_connector *connector)
0255 {
0256 if (!dp_panel) {
0257 DRM_ERROR("invalid input\n");
0258 return -EINVAL;
0259 }
0260
0261 if (dp_panel->edid)
0262 return dp_panel_update_modes(connector, dp_panel->edid);
0263
0264 return 0;
0265 }
0266
0267 static u8 dp_panel_get_edid_checksum(struct edid *edid)
0268 {
0269 struct edid *last_block;
0270 u8 *raw_edid;
0271 bool is_edid_corrupt = false;
0272
0273 if (!edid) {
0274 DRM_ERROR("invalid edid input\n");
0275 return 0;
0276 }
0277
0278 raw_edid = (u8 *)edid;
0279 raw_edid += (edid->extensions * EDID_LENGTH);
0280 last_block = (struct edid *)raw_edid;
0281
0282
0283 drm_edid_block_valid(raw_edid, 1, false, &is_edid_corrupt);
0284 if (!is_edid_corrupt)
0285 return last_block->checksum;
0286
0287 DRM_ERROR("Invalid block, no checksum\n");
0288 return 0;
0289 }
0290
0291 void dp_panel_handle_sink_request(struct dp_panel *dp_panel)
0292 {
0293 struct dp_panel_private *panel;
0294
0295 if (!dp_panel) {
0296 DRM_ERROR("invalid input\n");
0297 return;
0298 }
0299
0300 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0301
0302 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
0303 u8 checksum;
0304
0305 if (dp_panel->edid)
0306 checksum = dp_panel_get_edid_checksum(dp_panel->edid);
0307 else
0308 checksum = dp_panel->connector->real_edid_checksum;
0309
0310 dp_link_send_edid_checksum(panel->link, checksum);
0311 dp_link_send_test_response(panel->link);
0312 }
0313 }
0314
0315 void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable)
0316 {
0317 struct dp_catalog *catalog;
0318 struct dp_panel_private *panel;
0319
0320 if (!dp_panel) {
0321 DRM_ERROR("invalid input\n");
0322 return;
0323 }
0324
0325 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0326 catalog = panel->catalog;
0327
0328 if (!panel->panel_on) {
0329 drm_dbg_dp(panel->drm_dev,
0330 "DP panel not enabled, handle TPG on next on\n");
0331 return;
0332 }
0333
0334 if (!enable) {
0335 dp_catalog_panel_tpg_disable(catalog);
0336 return;
0337 }
0338
0339 drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");
0340 dp_catalog_panel_tpg_enable(catalog, &panel->dp_panel.dp_mode.drm_mode);
0341 }
0342
0343 void dp_panel_dump_regs(struct dp_panel *dp_panel)
0344 {
0345 struct dp_catalog *catalog;
0346 struct dp_panel_private *panel;
0347
0348 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0349 catalog = panel->catalog;
0350
0351 dp_catalog_dump_regs(catalog);
0352 }
0353
0354 int dp_panel_timing_cfg(struct dp_panel *dp_panel)
0355 {
0356 u32 data, total_ver, total_hor;
0357 struct dp_catalog *catalog;
0358 struct dp_panel_private *panel;
0359 struct drm_display_mode *drm_mode;
0360
0361 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0362 catalog = panel->catalog;
0363 drm_mode = &panel->dp_panel.dp_mode.drm_mode;
0364
0365 drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",
0366 drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,
0367 drm_mode->hsync_start - drm_mode->hdisplay,
0368 drm_mode->hsync_end - drm_mode->hsync_start);
0369
0370 drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n",
0371 drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end,
0372 drm_mode->vsync_start - drm_mode->vdisplay,
0373 drm_mode->vsync_end - drm_mode->vsync_start);
0374
0375 total_hor = drm_mode->htotal;
0376
0377 total_ver = drm_mode->vtotal;
0378
0379 data = total_ver;
0380 data <<= 16;
0381 data |= total_hor;
0382
0383 catalog->total = data;
0384
0385 data = (drm_mode->vtotal - drm_mode->vsync_start);
0386 data <<= 16;
0387 data |= (drm_mode->htotal - drm_mode->hsync_start);
0388
0389 catalog->sync_start = data;
0390
0391 data = drm_mode->vsync_end - drm_mode->vsync_start;
0392 data <<= 16;
0393 data |= (panel->dp_panel.dp_mode.v_active_low << 31);
0394 data |= drm_mode->hsync_end - drm_mode->hsync_start;
0395 data |= (panel->dp_panel.dp_mode.h_active_low << 15);
0396
0397 catalog->width_blanking = data;
0398
0399 data = drm_mode->vdisplay;
0400 data <<= 16;
0401 data |= drm_mode->hdisplay;
0402
0403 catalog->dp_active = data;
0404
0405 dp_catalog_panel_timing_cfg(catalog);
0406 panel->panel_on = true;
0407
0408 return 0;
0409 }
0410
0411 int dp_panel_init_panel_info(struct dp_panel *dp_panel)
0412 {
0413 struct drm_display_mode *drm_mode;
0414 struct dp_panel_private *panel;
0415
0416 drm_mode = &dp_panel->dp_mode.drm_mode;
0417
0418 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
0419
0420
0421
0422
0423
0424 drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n");
0425 drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n",
0426 drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode));
0427 drm_dbg_dp(panel->drm_dev,
0428 "h_porches(back|front|width) = (%d|%d|%d)\n",
0429 drm_mode->htotal - drm_mode->hsync_end,
0430 drm_mode->hsync_start - drm_mode->hdisplay,
0431 drm_mode->hsync_end - drm_mode->hsync_start);
0432 drm_dbg_dp(panel->drm_dev,
0433 "v_porches(back|front|width) = (%d|%d|%d)\n",
0434 drm_mode->vtotal - drm_mode->vsync_end,
0435 drm_mode->vsync_start - drm_mode->vdisplay,
0436 drm_mode->vsync_end - drm_mode->vsync_start);
0437 drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",
0438 drm_mode->clock);
0439 drm_dbg_dp(panel->drm_dev, "bpp = %d\n", dp_panel->dp_mode.bpp);
0440
0441 dp_panel->dp_mode.bpp = max_t(u32, 18,
0442 min_t(u32, dp_panel->dp_mode.bpp, 30));
0443 drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
0444 dp_panel->dp_mode.bpp);
0445
0446 return 0;
0447 }
0448
0449 struct dp_panel *dp_panel_get(struct dp_panel_in *in)
0450 {
0451 struct dp_panel_private *panel;
0452 struct dp_panel *dp_panel;
0453
0454 if (!in->dev || !in->catalog || !in->aux || !in->link) {
0455 DRM_ERROR("invalid input\n");
0456 return ERR_PTR(-EINVAL);
0457 }
0458
0459 panel = devm_kzalloc(in->dev, sizeof(*panel), GFP_KERNEL);
0460 if (!panel)
0461 return ERR_PTR(-ENOMEM);
0462
0463 panel->dev = in->dev;
0464 panel->aux = in->aux;
0465 panel->catalog = in->catalog;
0466 panel->link = in->link;
0467
0468 dp_panel = &panel->dp_panel;
0469 dp_panel->max_bw_code = DP_LINK_BW_8_1;
0470 panel->aux_cfg_update_done = false;
0471
0472 return dp_panel;
0473 }
0474
0475 void dp_panel_put(struct dp_panel *dp_panel)
0476 {
0477 if (!dp_panel)
0478 return;
0479
0480 kfree(dp_panel->edid);
0481 }