Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions drivers/gpu/drm/amd/amdgpu/ps4_bridge.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Panasonic MN86471A DP->HDMI bridge driver (via PS4 Aeolia ICC interface)
* Panasonic MN86471A / MN864729 DP->HDMI bridge driver (via PS4 Aeolia ICC interface)
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
Expand All @@ -15,6 +15,20 @@
// TODO (ps4patches): Make functions atomic,
// https://lore.kernel.org/linux-arm-kernel/20211020181901.2114645-5-sam@ravnborg.org/

/*
* Forward-ported patches from https://github.com/rancido,
* in https://github.com/Ps3itaTeam/ps4-linux/
* Maybe the problem is no one is putting a "Copyright"
* in their files ... We don't know who introduced what change or where,
* since there is often no centralized repository.. Patches thrown around
* everywhere.
* But that goes against the whole nature of tinkery/RE work..?
* But does it really? No.
*
*
* Copyright: .....
*
*/
#include <asm/ps4.h>

#include <drm/drm_crtc.h>
Expand Down Expand Up @@ -247,7 +261,7 @@ static void cq_mask(struct i2c_cmdqueue *q, u16 addr, u8 value, u8 mask)
*q->p++ = mask;
}

#if 1
#if 0
static void cq_delay(struct i2c_cmdqueue *q, u16 time)
{
cq_cmd(q, CMD_DELAY);
Expand Down Expand Up @@ -524,9 +538,12 @@ static void ps4_bridge_enable(struct drm_bridge *bridge)
cq_mask(&mn_bridge->cq, 0x1e00, 0x00, 0x21);
cq_mask(&mn_bridge->cq, 0x1e02, 0x00, 0x70);
// 03 08 01 01 00 2c 01 00
cq_delay(&mn_bridge->cq, 0x012c);
//rancido has no delay here vvv
//cq_delay(&mn_bridge->cq, 0x012c);
cq_writereg(&mn_bridge->cq, 0x6020, 0x00);
cq_delay(&mn_bridge->cq, 0x0032);

//rancido has no delay here vvv
//cq_delay(&mn_bridge->cq, 0x0032);
cq_writereg(&mn_bridge->cq, 0x7402, 0x1c);
cq_writereg(&mn_bridge->cq, 0x6020, 0x04);
cq_writereg(&mn_bridge->cq, TSYSCTRL, TSYSCTRL_HDMI);
Expand Down Expand Up @@ -569,7 +586,8 @@ static void ps4_bridge_enable(struct drm_bridge *bridge)
cq_wait_set(&mn_bridge->cq, 0x10f6, 0x80);
cq_mask(&mn_bridge->cq, 0x7226, 0x00, 0x80);
cq_mask(&mn_bridge->cq, 0x7228, 0x00, 0xFF);
cq_delay(&mn_bridge->cq, 0x012c);
// rancido has no delay here vvv
//cq_delay(&mn_bridge->cq, 0x012c);
cq_writereg(&mn_bridge->cq, 0x7204, 0x40);
cq_wait_clear(&mn_bridge->cq, 0x7204, 0x40);
cq_writereg(&mn_bridge->cq, 0x7a8b, 0x05);
Expand Down Expand Up @@ -670,11 +688,18 @@ static const struct drm_display_mode mode_720p = {
};
/* 16 - 1920x1080@60Hz */
static const struct drm_display_mode mode_1080p = {
DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 148500, 1920, 2008,
2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
.picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9
};
/* Having a 120Hz modeline causes incorrect mode selection
* by GUI / Display Manager, causing a 60Hz monitor to try
* with a 120Hz mode - leading to a blackscreen.
* Only fix seems to be having a xorg.conf in /usr/share/X11/xorg.conf.d/
*
* Try setting a TYPE_PREFFERED mode
*/
/* 63 - 1920x1080@120Hz */
static const struct drm_display_mode mode_1080p120 = {
DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
Expand Down Expand Up @@ -743,9 +768,13 @@ enum drm_mode_status ps4_bridge_mode_valid(struct drm_connector *connector,

/* Allow anything that we can match up to a VIC (CEA modes) */
if (!vic || (vic != 16 && vic != 4 && vic != 63)) {
// Might need to disable 63 (1920x1080-120Hz)

/*
if (!vic || (vic != 16 && vic != 4)) {
*/
return MODE_BAD;
}

return MODE_OK;
}

Expand Down Expand Up @@ -780,7 +809,11 @@ int ps4_bridge_register(struct drm_connector *connector,
// TODO (ps4patches): This seems to be the new way of adding bridges
drm_bridge_add(&mn_bridge->bridge);

ret = drm_bridge_attach(mn_bridge->encoder, &mn_bridge->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
//ret = drm_bridge_attach(mn_bridge->encoder, &mn_bridge->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

// Allow the bridge to create its own connectors with last parameter = 0.
// There seemms to be a blackscreen when this is NO_CONNECTOR :
ret = drm_bridge_attach(mn_bridge->encoder, &mn_bridge->bridge, NULL, 0);
if (ret) {
DRM_ERROR("Failed to initialize bridge with drm\n");
return -EINVAL;
Expand Down