summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 13:40:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 13:40:25 -0800
commit984065055e6e39f8dd812529e11922374bd39352 (patch)
treea8f1bcbd81e0fadce0cef39ab5ce09ab84b261fe /drivers/gpu/drm/amd/amdgpu/atombios_dp.c
parent12768c1e2c83b05ea1658470045789a14b6edf4c (diff)
parent1df59b8497f47495e873c23abd6d3d290c730505 (diff)
downloadop-kernel-dev-984065055e6e39f8dd812529e11922374bd39352.zip
op-kernel-dev-984065055e6e39f8dd812529e11922374bd39352.tar.gz
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is the main drm pull request for 4.5. I don't think I've missed anything too major, I'm mostly back at work now but I'll probably get some sleep in 5 years time. Summary: New drivers: - etnaviv: GPU driver for the 3D core on the Vivante core used in numerous ARM boards. Highlights: Core: - Atomic suspend/resume helpers - Move the headers to using userspace friendlier types. - Documentation updates - Lots of struct_mutex removal. - Bunch of DP MST fixes from AMD. Panel: - More DSI helpers - Support for some new basic panels i915: - Basic Kabylake support - DP link training and detect code refactoring - fbc/psr fixes - FIFO underrun fixes - SDE interrupt handling fixes - dma-buf/fence support in pageflip path. - GPU side for MST audio support radeon/amdgpu: - Drop UMS support - GPUVM/Scheduler optimisations - Initial Powerplay support for Tonga/Fiji/CZ/ST - ACP audio prerequisites nouveau: - GK20a instmem improvements - PCIE link speed change support msm: - DSI support for msm8960/apq8064 tegra: - Host1X support for Tegra210 SoC vc4: - 3D acceleration support armada: - Get rid of struct mutex tda998x: - Atomic modesetting support - TMDS clock limitations omapdrm: - Atomic modesetting support - improved TILER performance rockchip: - RK3036 VOP support - Atomic modesetting support - Synopsys DW MIPI DSI support exynos: - Runtime PM support - of_graph binding for DP panels - Cleanup of IPP code - Configurable plane support - Kernel panic fixes at release time" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (711 commits) drm/fb_cma_helper: Remove implicit call to disable_unused_functions drm/amdgpu: add missing irq.h include drm/vmwgfx: Fix a width / pitch mismatch on framebuffer updates drm/vmwgfx: Fix an incorrect lock check drm: nouveau: fix nouveau_debugfs_init prototype drm/nouveau/pci: fix check in nvkm_pcie_set_link drm/amdgpu: validate duplicates first drm/amdgpu: move VM page tables to the LRU end on CS v2 drm/ttm: add ttm_bo_move_to_lru_tail function v2 drm/ttm: fix adding foreign BOs to the swap LRU drm/ttm: fix adding foreign BOs to the LRU during init v2 drm/radeon: use kobj_to_dev() drm/amdgpu: use kobj_to_dev() drm/amdgpu/cz: force vce clocks when sclks are forced drm/amdgpu/cz: force uvd clocks when sclks are forced drm/amdgpu/cz: add code to enable forcing VCE clocks drm/amdgpu/cz: add code to enable forcing UVD clocks drm/amdgpu: fix lost sync_to if scheduler is enabled. drm/amd/powerplay: fix static checker warning for return meaningless value. drm/sysfs: use kobj_to_dev() ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/atombios_dp.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atombios_dp.c96
1 files changed, 36 insertions, 60 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
index 92b6aca..21aacc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -243,7 +243,7 @@ static void amdgpu_atombios_dp_get_adjust_train(const u8 link_status[DP_LINK_STA
/* convert bits per color to bits per pixel */
/* get bpc from the EDID */
-static int amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc)
+static unsigned amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc)
{
if (bpc == 0)
return 24;
@@ -251,64 +251,32 @@ static int amdgpu_atombios_dp_convert_bpc_to_bpp(int bpc)
return bpc * 3;
}
-/* get the max pix clock supported by the link rate and lane num */
-static int amdgpu_atombios_dp_get_max_dp_pix_clock(int link_rate,
- int lane_num,
- int bpp)
-{
- return (link_rate * lane_num * 8) / bpp;
-}
-
/***** amdgpu specific DP functions *****/
-/* First get the min lane# when low rate is used according to pixel clock
- * (prefer low rate), second check max lane# supported by DP panel,
- * if the max lane# < low rate lane# then use max lane# instead.
- */
-static int amdgpu_atombios_dp_get_dp_lane_number(struct drm_connector *connector,
+static int amdgpu_atombios_dp_get_dp_link_config(struct drm_connector *connector,
const u8 dpcd[DP_DPCD_SIZE],
- int pix_clock)
-{
- int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
- int max_link_rate = drm_dp_max_link_rate(dpcd);
- int max_lane_num = drm_dp_max_lane_count(dpcd);
- int lane_num;
- int max_dp_pix_clock;
-
- for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
- max_dp_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
- if (pix_clock <= max_dp_pix_clock)
- break;
- }
-
- return lane_num;
-}
-
-static int amdgpu_atombios_dp_get_dp_link_clock(struct drm_connector *connector,
- const u8 dpcd[DP_DPCD_SIZE],
- int pix_clock)
+ unsigned pix_clock,
+ unsigned *dp_lanes, unsigned *dp_rate)
{
- int bpp = amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
- int lane_num, max_pix_clock;
-
- if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) ==
- ENCODER_OBJECT_ID_NUTMEG)
- return 270000;
-
- lane_num = amdgpu_atombios_dp_get_dp_lane_number(connector, dpcd, pix_clock);
- max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(162000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 162000;
- max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(270000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 270000;
- if (amdgpu_connector_is_dp12_capable(connector)) {
- max_pix_clock = amdgpu_atombios_dp_get_max_dp_pix_clock(540000, lane_num, bpp);
- if (pix_clock <= max_pix_clock)
- return 540000;
+ unsigned bpp =
+ amdgpu_atombios_dp_convert_bpc_to_bpp(amdgpu_connector_get_monitor_bpc(connector));
+ static const unsigned link_rates[3] = { 162000, 270000, 540000 };
+ unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
+ unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
+ unsigned lane_num, i, max_pix_clock;
+
+ for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
+ for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
+ max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
+ if (max_pix_clock >= pix_clock) {
+ *dp_lanes = lane_num;
+ *dp_rate = link_rates[i];
+ return 0;
+ }
+ }
}
- return drm_dp_max_link_rate(dpcd);
+ return -EINVAL;
}
static u8 amdgpu_atombios_dp_encoder_service(struct amdgpu_device *adev,
@@ -422,6 +390,7 @@ void amdgpu_atombios_dp_set_link_config(struct drm_connector *connector,
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
struct amdgpu_connector_atom_dig *dig_connector;
+ int ret;
if (!amdgpu_connector->con_priv)
return;
@@ -429,10 +398,14 @@ void amdgpu_atombios_dp_set_link_config(struct drm_connector *connector,
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
- dig_connector->dp_clock =
- amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
- dig_connector->dp_lane_count =
- amdgpu_atombios_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+ ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd,
+ mode->clock,
+ &dig_connector->dp_lane_count,
+ &dig_connector->dp_clock);
+ if (ret) {
+ dig_connector->dp_clock = 0;
+ dig_connector->dp_lane_count = 0;
+ }
}
}
@@ -441,14 +414,17 @@ int amdgpu_atombios_dp_mode_valid_helper(struct drm_connector *connector,
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
struct amdgpu_connector_atom_dig *dig_connector;
- int dp_clock;
+ unsigned dp_lanes, dp_clock;
+ int ret;
if (!amdgpu_connector->con_priv)
return MODE_CLOCK_HIGH;
dig_connector = amdgpu_connector->con_priv;
- dp_clock =
- amdgpu_atombios_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+ ret = amdgpu_atombios_dp_get_dp_link_config(connector, dig_connector->dpcd,
+ mode->clock, &dp_lanes, &dp_clock);
+ if (ret)
+ return MODE_CLOCK_HIGH;
if ((dp_clock == 540000) &&
(!amdgpu_connector_is_dp12_capable(connector)))
OpenPOWER on IntegriCloud