summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ast
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2022-02-25 05:30:17 +1000
committerDave Airlie <airlied@redhat.com>2022-02-25 05:50:18 +1000
commit54f43c17d681f6d9523fcfaeefc9df77993802e1 (patch)
treea1b3807e26d05b9b17aea43b7725caf3757522ca /drivers/gpu/drm/ast
parent7f44571b53fd07e36ae4d2537a6fb40d79b39462 (diff)
parentf915686bd97a9c234602426e6d132b74a112a8d6 (diff)
Merge tag 'drm-misc-next-2022-02-23' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.18: UAPI Changes: Cross-subsystem Changes: - Split out panel-lvds and lvds dt bindings . - Put yes/no on/off disabled/enabled strings in linux/string_helpers.h and use it in drivers and tomoyo. - Clarify dma_fence_chain and dma_fence_array should never include eachother. - Flatten chains in syncobj's. - Don't double add in fbdev/defio when page is already enlisted. - Don't sort deferred-I/O pages by default in fbdev. Core Changes: - Fix missing pm_runtime_put_sync in bridge. - Set modifier support to only linear fb modifier if drivers don't advertise support. - As a result, we remove allow_fb_modifiers. - Add missing clear for EDID Deep Color Modes in drm_reset_display_info. - Assorted documentation updates. - Warn once in drm_clflush if there is no arch support. - Add missing select for dp helper in drm_panel_edp. - Assorted small fixes. - Improve fb-helper's clipping handling. - Don't dump shmem mmaps in a core dump. - Add accounting to ttm resource manager, and use it in amdgpu. - Allow querying the detected eDP panel through debugfs. - Add helpers for xrgb8888 to 8 and 1 bits gray. - Improve drm's buddy allocator. - Add selftests for the buddy allocator. Driver Changes: - Add support for nomodeset to a lot of drm drivers. - Use drm_module_*_driver in a lot of drm drivers. - Assorted small fixes to bridge/lt9611, v3d, vc4, vmwgfx, mxsfb, nouveau, bridge/dw-hdmi, panfrost, lima, ingenic, sprd, bridge/anx7625, ti-sn65dsi86. - Add bridge/it6505. - Create DP and DVI-I connectors in ast. - Assorted nouveau backlight fixes. - Rework amdgpu reset handling. - Add dt bindings for ingenic,jz4780-dw-hdmi. - Support reading edid through aux channel in ingenic. - Add a drm driver for Solomon SSD130x OLED displays. - Add simple support for sharp LQ140M1JW46. - Add more panels to nt35560. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/686ec871-e77f-c230-22e5-9e3bb80f064a@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c58
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h37
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c413
3 files changed, 331 insertions, 177 deletions
diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
index cd93c44f2662..204c926a18ea 100644
--- a/drivers/gpu/drm/ast/ast_dp501.c
+++ b/drivers/gpu/drm/ast/ast_dp501.c
@@ -272,64 +272,6 @@ static bool ast_launch_m68k(struct drm_device *dev)
return true;
}
-u8 ast_get_dp501_max_clk(struct drm_device *dev)
-{
- struct ast_private *ast = to_ast_private(dev);
- u32 boot_address, offset, data;
- u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
- u32 *plinkcap;
-
- if (ast->config_mode == ast_use_p2a) {
- boot_address = get_fw_base(ast);
-
- /* validate FW version */
- offset = AST_DP501_GBL_VERSION;
- data = ast_mindwm(ast, boot_address + offset);
- if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
- return maxclk;
-
- /* Read Link Capability */
- offset = AST_DP501_LINKRATE;
- plinkcap = (u32 *)linkcap;
- *plinkcap = ast_mindwm(ast, boot_address + offset);
- if (linkcap[2] == 0) {
- linkrate = linkcap[0];
- linklanes = linkcap[1];
- data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
- if (data > 0xff)
- data = 0xff;
- maxclk = (u8)data;
- }
- } else {
- if (!ast->dp501_fw_buf)
- return AST_DP501_DEFAULT_DCLK; /* 1024x768 as default */
-
- /* dummy read */
- offset = 0x0000;
- data = readl(ast->dp501_fw_buf + offset);
-
- /* validate FW version */
- offset = AST_DP501_GBL_VERSION;
- data = readl(ast->dp501_fw_buf + offset);
- if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
- return maxclk;
-
- /* Read Link Capability */
- offset = AST_DP501_LINKRATE;
- plinkcap = (u32 *)linkcap;
- *plinkcap = readl(ast->dp501_fw_buf + offset);
- if (linkcap[2] == 0) {
- linkrate = linkcap[0];
- linklanes = linkcap[1];
- data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
- if (data > 0xff)
- data = 0xff;
- maxclk = (u8)data;
- }
- }
- return maxclk;
-}
-
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
{
struct ast_private *ast = to_ast_private(dev);
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 9c8d56b0a41b..a19315b2f7e5 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -69,7 +69,6 @@ enum ast_chip {
enum ast_tx_chip {
AST_TX_NONE,
AST_TX_SIL164,
- AST_TX_ITE66121,
AST_TX_DP501,
};
@@ -130,15 +129,26 @@ struct ast_i2c_chan {
struct i2c_algo_bit_data bit;
};
-struct ast_connector {
+struct ast_vga_connector {
struct drm_connector base;
struct ast_i2c_chan *i2c;
};
-static inline struct ast_connector *
-to_ast_connector(struct drm_connector *connector)
+static inline struct ast_vga_connector *
+to_ast_vga_connector(struct drm_connector *connector)
{
- return container_of(connector, struct ast_connector, base);
+ return container_of(connector, struct ast_vga_connector, base);
+}
+
+struct ast_sil164_connector {
+ struct drm_connector base;
+ struct ast_i2c_chan *i2c;
+};
+
+static inline struct ast_sil164_connector *
+to_ast_sil164_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct ast_sil164_connector, base);
}
/*
@@ -161,8 +171,20 @@ struct ast_private {
struct drm_plane primary_plane;
struct ast_cursor_plane cursor_plane;
struct drm_crtc crtc;
- struct drm_encoder encoder;
- struct ast_connector connector;
+ union {
+ struct {
+ struct drm_encoder encoder;
+ struct ast_vga_connector vga_connector;
+ } vga;
+ struct {
+ struct drm_encoder encoder;
+ struct ast_sil164_connector sil164_connector;
+ } sil164;
+ struct {
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+ } dp501;
+ } output;
bool support_wide_screen;
enum {
@@ -172,7 +194,6 @@ struct ast_private {
} config_mode;
enum ast_tx_chip tx_chip_type;
- u8 dp501_maxclk;
u8 *dp501_fw_addr;
const struct firmware *dp501_fw; /* dp501 fw */
};
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 2c7115a4d81f..45b56b39ad47 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -40,6 +40,7 @@
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_vram_helper.h>
+#include <drm/drm_managed.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
@@ -1005,6 +1006,71 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
}
}
+static enum drm_mode_status
+ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+ struct ast_private *ast = to_ast_private(crtc->dev);
+ enum drm_mode_status status;
+ uint32_t jtemp;
+
+ if (ast->support_wide_screen) {
+ if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
+ return MODE_OK;
+ if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
+ return MODE_OK;
+ if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
+ return MODE_OK;
+ if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
+ return MODE_OK;
+ if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
+ return MODE_OK;
+
+ if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
+ (ast->chip == AST2300) || (ast->chip == AST2400) ||
+ (ast->chip == AST2500)) {
+ if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
+ return MODE_OK;
+
+ if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
+ if (jtemp & 0x01)
+ return MODE_NOMODE;
+ else
+ return MODE_OK;
+ }
+ }
+ }
+
+ status = MODE_NOMODE;
+
+ switch (mode->hdisplay) {
+ case 640:
+ if (mode->vdisplay == 480)
+ status = MODE_OK;
+ break;
+ case 800:
+ if (mode->vdisplay == 600)
+ status = MODE_OK;
+ break;
+ case 1024:
+ if (mode->vdisplay == 768)
+ status = MODE_OK;
+ break;
+ case 1280:
+ if (mode->vdisplay == 1024)
+ status = MODE_OK;
+ break;
+ case 1600:
+ if (mode->vdisplay == 1200)
+ status = MODE_OK;
+ break;
+ default:
+ break;
+ }
+
+ return status;
+}
+
static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
@@ -1107,6 +1173,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
+ .mode_valid = ast_crtc_helper_mode_valid,
.atomic_check = ast_crtc_helper_atomic_check,
.atomic_flush = ast_crtc_helper_atomic_flush,
.atomic_enable = ast_crtc_helper_atomic_enable,
@@ -1187,128 +1254,229 @@ static int ast_crtc_init(struct drm_device *dev)
}
/*
- * Encoder
+ * VGA Connector
*/
-static int ast_encoder_init(struct drm_device *dev)
+static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
{
- struct ast_private *ast = to_ast_private(dev);
- struct drm_encoder *encoder = &ast->encoder;
+ struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector);
+ struct edid *edid;
+ int count;
+
+ if (!ast_vga_connector->i2c)
+ goto err_drm_connector_update_edid_property;
+
+ edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter);
+ if (!edid)
+ goto err_drm_connector_update_edid_property;
+
+ count = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+
+ return count;
+
+err_drm_connector_update_edid_property:
+ drm_connector_update_edid_property(connector, NULL);
+ return 0;
+}
+
+static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {
+ .get_modes = ast_vga_connector_helper_get_modes,
+};
+
+static const struct drm_connector_funcs ast_vga_connector_funcs = {
+ .reset = drm_atomic_helper_connector_reset,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int ast_vga_connector_init(struct drm_device *dev,
+ struct ast_vga_connector *ast_vga_connector)
+{
+ struct drm_connector *connector = &ast_vga_connector->base;
+ int ret;
+
+ ast_vga_connector->i2c = ast_i2c_create(dev);
+ if (!ast_vga_connector->i2c)
+ drm_err(dev, "failed to add ddc bus for connector\n");
+
+ if (ast_vga_connector->i2c)
+ ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA,
+ &ast_vga_connector->i2c->adapter);
+ else
+ ret = drm_connector_init(dev, connector, &ast_vga_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA);
+ if (ret)
+ return ret;
+
+ drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs);
+
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+
+ return 0;
+}
+
+static int ast_vga_output_init(struct ast_private *ast)
+{
+ struct drm_device *dev = &ast->base;
+ struct drm_crtc *crtc = &ast->crtc;
+ struct drm_encoder *encoder = &ast->output.vga.encoder;
+ struct ast_vga_connector *ast_vga_connector = &ast->output.vga.vga_connector;
+ struct drm_connector *connector = &ast_vga_connector->base;
int ret;
ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
if (ret)
return ret;
+ encoder->possible_crtcs = drm_crtc_mask(crtc);
- encoder->possible_crtcs = 1;
+ ret = ast_vga_connector_init(dev, ast_vga_connector);
+ if (ret)
+ return ret;
+
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret)
+ return ret;
return 0;
}
/*
- * Connector
+ * SIL164 Connector
*/
-static int ast_get_modes(struct drm_connector *connector)
+static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector)
+{
+ struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector);
+ struct edid *edid;
+ int count;
+
+ if (!ast_sil164_connector->i2c)
+ goto err_drm_connector_update_edid_property;
+
+ edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter);
+ if (!edid)
+ goto err_drm_connector_update_edid_property;
+
+ count = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+
+ return count;
+
+err_drm_connector_update_edid_property:
+ drm_connector_update_edid_property(connector, NULL);
+ return 0;
+}
+
+static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = {
+ .get_modes = ast_sil164_connector_helper_get_modes,
+};
+
+static const struct drm_connector_funcs ast_sil164_connector_funcs = {
+ .reset = drm_atomic_helper_connector_reset,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int ast_sil164_connector_init(struct drm_device *dev,
+ struct ast_sil164_connector *ast_sil164_connector)
{
- struct ast_connector *ast_connector = to_ast_connector(connector);
- struct ast_private *ast = to_ast_private(connector->dev);
- struct edid *edid = NULL;
- bool flags = false;
+ struct drm_connector *connector = &ast_sil164_connector->base;
int ret;
- if (ast->tx_chip_type == AST_TX_DP501) {
- ast->dp501_maxclk = 0xff;
- edid = kmalloc(128, GFP_KERNEL);
- if (!edid)
- return -ENOMEM;
+ ast_sil164_connector->i2c = ast_i2c_create(dev);
+ if (!ast_sil164_connector->i2c)
+ drm_err(dev, "failed to add ddc bus for connector\n");
- flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
- if (flags)
- ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
- else
- kfree(edid);
- }
- if (!flags && ast_connector->i2c)
- edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
- if (edid) {
- drm_connector_update_edid_property(&ast_connector->base, edid);
- ret = drm_add_edid_modes(connector, edid);
- kfree(edid);
+ if (ast_sil164_connector->i2c)
+ ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs,
+ DRM_MODE_CONNECTOR_DVII,
+ &ast_sil164_connector->i2c->adapter);
+ else
+ ret = drm_connector_init(dev, connector, &ast_sil164_connector_funcs,
+ DRM_MODE_CONNECTOR_DVII);
+ if (ret)
return ret;
- }
- drm_connector_update_edid_property(&ast_connector->base, NULL);
+
+ drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs);
+
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+
return 0;
}
-static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
+static int ast_sil164_output_init(struct ast_private *ast)
{
- struct ast_private *ast = to_ast_private(connector->dev);
- int flags = MODE_NOMODE;
- uint32_t jtemp;
+ struct drm_device *dev = &ast->base;
+ struct drm_crtc *crtc = &ast->crtc;
+ struct drm_encoder *encoder = &ast->output.sil164.encoder;
+ struct ast_sil164_connector *ast_sil164_connector = &ast->output.sil164.sil164_connector;
+ struct drm_connector *connector = &ast_sil164_connector->base;
+ int ret;
- if (ast->support_wide_screen) {
- if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
- return MODE_OK;
- if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
- return MODE_OK;
- if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
- return MODE_OK;
- if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
- return MODE_OK;
- if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
- return MODE_OK;
+ ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
+ if (ret)
+ return ret;
+ encoder->possible_crtcs = drm_crtc_mask(crtc);
- if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
- (ast->chip == AST2300) || (ast->chip == AST2400) ||
- (ast->chip == AST2500)) {
- if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
- return MODE_OK;
+ ret = ast_sil164_connector_init(dev, ast_sil164_connector);
+ if (ret)
+ return ret;
- if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
- jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
- if (jtemp & 0x01)
- return MODE_NOMODE;
- else
- return MODE_OK;
- }
- }
- }
- switch (mode->hdisplay) {
- case 640:
- if (mode->vdisplay == 480)
- flags = MODE_OK;
- break;
- case 800:
- if (mode->vdisplay == 600)
- flags = MODE_OK;
- break;
- case 1024:
- if (mode->vdisplay == 768)
- flags = MODE_OK;
- break;
- case 1280:
- if (mode->vdisplay == 1024)
- flags = MODE_OK;
- break;
- case 1600:
- if (mode->vdisplay == 1200)
- flags = MODE_OK;
- break;
- default:
- return flags;
- }
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret)
+ return ret;
- return flags;
+ return 0;
}
-static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
- .get_modes = ast_get_modes,
- .mode_valid = ast_mode_valid,
+/*
+ * DP501 Connector
+ */
+
+static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector)
+{
+ void *edid;
+ bool succ;
+ int count;
+
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!edid)
+ goto err_drm_connector_update_edid_property;
+
+ succ = ast_dp501_read_edid(connector->dev, edid);
+ if (!succ)
+ goto err_kfree;
+
+ drm_connector_update_edid_property(connector, edid);
+ count = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+
+ return count;
+
+err_kfree:
+ kfree(edid);
+err_drm_connector_update_edid_property:
+ drm_connector_update_edid_property(connector, NULL);
+ return 0;
+}
+
+static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = {
+ .get_modes = ast_dp501_connector_helper_get_modes,
};
-static const struct drm_connector_funcs ast_connector_funcs = {
+static const struct drm_connector_funcs ast_dp501_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -1316,33 +1484,45 @@ static const struct drm_connector_funcs ast_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
-static int ast_connector_init(struct drm_device *dev)
+static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector)
{
- struct ast_private *ast = to_ast_private(dev);
- struct ast_connector *ast_connector = &ast->connector;
- struct drm_connector *connector = &ast_connector->base;
- struct drm_encoder *encoder = &ast->encoder;
-
- ast_connector->i2c = ast_i2c_create(dev);
- if (!ast_connector->i2c)
- drm_err(dev, "failed to add ddc bus for connector\n");
+ int ret;
- if (ast_connector->i2c)
- drm_connector_init_with_ddc(dev, connector, &ast_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &ast_connector->i2c->adapter);
- else
- drm_connector_init(dev, connector, &ast_connector_funcs,
- DRM_MODE_CONNECTOR_VGA);
+ ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ if (ret)
+ return ret;
- drm_connector_helper_add(connector, &ast_connector_helper_funcs);
+ drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs);
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
- drm_connector_attach_encoder(connector, encoder);
+ return 0;
+}
+
+static int ast_dp501_output_init(struct ast_private *ast)
+{
+ struct drm_device *dev = &ast->base;
+ struct drm_crtc *crtc = &ast->crtc;
+ struct drm_encoder *encoder = &ast->output.dp501.encoder;
+ struct drm_connector *connector = &ast->output.dp501.connector;
+ int ret;
+
+ ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
+ if (ret)
+ return ret;
+ encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+ ret = ast_dp501_connector_init(dev, connector);
+ if (ret)
+ return ret;
+
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret)
+ return ret;
return 0;
}
@@ -1351,8 +1531,7 @@ static int ast_connector_init(struct drm_device *dev)
* Mode config
*/
-static const struct drm_mode_config_helper_funcs
-ast_mode_config_helper_funcs = {
+static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = {
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
@@ -1404,8 +1583,20 @@ int ast_mode_config_init(struct ast_private *ast)
return ret;
ast_crtc_init(dev);
- ast_encoder_init(dev);
- ast_connector_init(dev);
+
+ switch (ast->tx_chip_type) {
+ case AST_TX_NONE:
+ ret = ast_vga_output_init(ast);
+ break;
+ case AST_TX_SIL164:
+ ret = ast_sil164_output_init(ast);
+ break;
+ case AST_TX_DP501:
+ ret = ast_dp501_output_init(ast);
+ break;
+ }
+ if (ret)
+ return ret;
drm_mode_config_reset(dev);