Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
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     /* check for EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT */
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     /* Limit support upto HBR2 until HBR3 support is added */
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         /* check edid read fail is due to unplug */
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     /* block type extension */
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      * print resolution info as this is a result
0422      * of user initiated action of cable connection
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 }