diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/output.c')
-rw-r--r-- | drivers/gpu/drm/tegra/output.c | 168 |
1 files changed, 16 insertions, 152 deletions
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 6a5c7b8..37db479 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -9,10 +9,11 @@ #include <linux/of_gpio.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_panel.h> #include "drm.h" -static int tegra_connector_get_modes(struct drm_connector *connector) +int tegra_output_connector_get_modes(struct drm_connector *connector) { struct tegra_output *output = connector_to_output(connector); struct edid *edid = NULL; @@ -43,43 +44,20 @@ static int tegra_connector_get_modes(struct drm_connector *connector) return err; } -static int tegra_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct tegra_output *output = connector_to_output(connector); - enum drm_mode_status status = MODE_OK; - int err; - - err = tegra_output_check_mode(output, mode, &status); - if (err < 0) - return MODE_ERROR; - - return status; -} - -static struct drm_encoder * -tegra_connector_best_encoder(struct drm_connector *connector) +struct drm_encoder * +tegra_output_connector_best_encoder(struct drm_connector *connector) { struct tegra_output *output = connector_to_output(connector); return &output->encoder; } -static const struct drm_connector_helper_funcs connector_helper_funcs = { - .get_modes = tegra_connector_get_modes, - .mode_valid = tegra_connector_mode_valid, - .best_encoder = tegra_connector_best_encoder, -}; - -static enum drm_connector_status -tegra_connector_detect(struct drm_connector *connector, bool force) +enum drm_connector_status +tegra_output_connector_detect(struct drm_connector *connector, bool force) { struct tegra_output *output = connector_to_output(connector); enum drm_connector_status status = connector_status_unknown; - if (output->ops->detect) - return output->ops->detect(output); - if (gpio_is_valid(output->hpd_gpio)) { if (gpio_get_value(output->hpd_gpio) == 0) status = connector_status_disconnected; @@ -90,95 +68,22 @@ tegra_connector_detect(struct drm_connector *connector, bool force) status = connector_status_disconnected; else status = connector_status_connected; - - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) - status = connector_status_connected; } return status; } -static void drm_connector_clear(struct drm_connector *connector) -{ - memset(connector, 0, sizeof(*connector)); -} - -static void tegra_connector_destroy(struct drm_connector *connector) +void tegra_output_connector_destroy(struct drm_connector *connector) { drm_connector_unregister(connector); drm_connector_cleanup(connector); - drm_connector_clear(connector); } -static const struct drm_connector_funcs connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = tegra_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = tegra_connector_destroy, -}; - -static void drm_encoder_clear(struct drm_encoder *encoder) -{ - memset(encoder, 0, sizeof(*encoder)); -} - -static void tegra_encoder_destroy(struct drm_encoder *encoder) +void tegra_output_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); - drm_encoder_clear(encoder); } -static const struct drm_encoder_funcs encoder_funcs = { - .destroy = tegra_encoder_destroy, -}; - -static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct tegra_output *output = encoder_to_output(encoder); - struct drm_panel *panel = output->panel; - - if (mode != DRM_MODE_DPMS_ON) { - drm_panel_disable(panel); - tegra_output_disable(output); - drm_panel_unprepare(panel); - } else { - drm_panel_prepare(panel); - tegra_output_enable(output); - drm_panel_enable(panel); - } -} - -static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted) -{ - return true; -} - -static void tegra_encoder_prepare(struct drm_encoder *encoder) -{ - tegra_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void tegra_encoder_commit(struct drm_encoder *encoder) -{ - tegra_encoder_dpms(encoder, DRM_MODE_DPMS_ON); -} - -static void tegra_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted) -{ -} - -static const struct drm_encoder_helper_funcs encoder_helper_funcs = { - .dpms = tegra_encoder_dpms, - .mode_fixup = tegra_encoder_mode_fixup, - .prepare = tegra_encoder_prepare, - .commit = tegra_encoder_commit, - .mode_set = tegra_encoder_mode_set, -}; - static irqreturn_t hpd_irq(int irq, void *data) { struct tegra_output *output = data; @@ -268,7 +173,7 @@ int tegra_output_probe(struct tegra_output *output) return 0; } -int tegra_output_remove(struct tegra_output *output) +void tegra_output_remove(struct tegra_output *output) { if (gpio_is_valid(output->hpd_gpio)) { free_irq(output->hpd_irq, output); @@ -277,56 +182,17 @@ int tegra_output_remove(struct tegra_output *output) if (output->ddc) put_device(&output->ddc->dev); - - return 0; } int tegra_output_init(struct drm_device *drm, struct tegra_output *output) { - int connector, encoder; - - switch (output->type) { - case TEGRA_OUTPUT_RGB: - connector = DRM_MODE_CONNECTOR_LVDS; - encoder = DRM_MODE_ENCODER_LVDS; - break; - - case TEGRA_OUTPUT_HDMI: - connector = DRM_MODE_CONNECTOR_HDMIA; - encoder = DRM_MODE_ENCODER_TMDS; - break; - - case TEGRA_OUTPUT_DSI: - connector = DRM_MODE_CONNECTOR_DSI; - encoder = DRM_MODE_ENCODER_DSI; - break; - - case TEGRA_OUTPUT_EDP: - connector = DRM_MODE_CONNECTOR_eDP; - encoder = DRM_MODE_ENCODER_TMDS; - break; - - default: - connector = DRM_MODE_CONNECTOR_Unknown; - encoder = DRM_MODE_ENCODER_NONE; - break; - } - - drm_connector_init(drm, &output->connector, &connector_funcs, - connector); - drm_connector_helper_add(&output->connector, &connector_helper_funcs); - output->connector.dpms = DRM_MODE_DPMS_OFF; - - if (output->panel) - drm_panel_attach(output->panel, &output->connector); - - drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder); - drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs); - - drm_mode_connector_attach_encoder(&output->connector, &output->encoder); - drm_connector_register(&output->connector); + int err; - output->encoder.possible_crtcs = 0x3; + if (output->panel) { + err = drm_panel_attach(output->panel, &output->connector); + if (err < 0) + return err; + } /* * The connector is now registered and ready to receive hotplug events @@ -338,7 +204,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) return 0; } -int tegra_output_exit(struct tegra_output *output) +void tegra_output_exit(struct tegra_output *output) { /* * The connector is going away, so the interrupt must be disabled to @@ -349,6 +215,4 @@ int tegra_output_exit(struct tegra_output *output) if (output->panel) drm_panel_detach(output->panel); - - return 0; } |