root/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mdp4_lvds_connector_detect
  2. mdp4_lvds_connector_destroy
  3. mdp4_lvds_connector_get_modes
  4. mdp4_lvds_connector_mode_valid
  5. mdp4_lvds_connector_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2014 Red Hat
   4  * Author: Rob Clark <robdclark@gmail.com>
   5  * Author: Vinay Simha <vinaysimha@inforcecomputing.com>
   6  */
   7 
   8 #include "mdp4_kms.h"
   9 
  10 struct mdp4_lvds_connector {
  11         struct drm_connector base;
  12         struct drm_encoder *encoder;
  13         struct device_node *panel_node;
  14         struct drm_panel *panel;
  15 };
  16 #define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connector, base)
  17 
  18 static enum drm_connector_status mdp4_lvds_connector_detect(
  19                 struct drm_connector *connector, bool force)
  20 {
  21         struct mdp4_lvds_connector *mdp4_lvds_connector =
  22                         to_mdp4_lvds_connector(connector);
  23 
  24         if (!mdp4_lvds_connector->panel) {
  25                 mdp4_lvds_connector->panel =
  26                         of_drm_find_panel(mdp4_lvds_connector->panel_node);
  27                 if (IS_ERR(mdp4_lvds_connector->panel))
  28                         mdp4_lvds_connector->panel = NULL;
  29         }
  30 
  31         return mdp4_lvds_connector->panel ?
  32                         connector_status_connected :
  33                         connector_status_disconnected;
  34 }
  35 
  36 static void mdp4_lvds_connector_destroy(struct drm_connector *connector)
  37 {
  38         struct mdp4_lvds_connector *mdp4_lvds_connector =
  39                         to_mdp4_lvds_connector(connector);
  40 
  41         drm_connector_cleanup(connector);
  42 
  43         kfree(mdp4_lvds_connector);
  44 }
  45 
  46 static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
  47 {
  48         struct mdp4_lvds_connector *mdp4_lvds_connector =
  49                         to_mdp4_lvds_connector(connector);
  50         struct drm_panel *panel = mdp4_lvds_connector->panel;
  51         int ret = 0;
  52 
  53         if (panel) {
  54                 drm_panel_attach(panel, connector);
  55 
  56                 ret = panel->funcs->get_modes(panel);
  57 
  58                 drm_panel_detach(panel);
  59         }
  60 
  61         return ret;
  62 }
  63 
  64 static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
  65                                  struct drm_display_mode *mode)
  66 {
  67         struct mdp4_lvds_connector *mdp4_lvds_connector =
  68                         to_mdp4_lvds_connector(connector);
  69         struct drm_encoder *encoder = mdp4_lvds_connector->encoder;
  70         long actual, requested;
  71 
  72         requested = 1000 * mode->clock;
  73         actual = mdp4_lcdc_round_pixclk(encoder, requested);
  74 
  75         DBG("requested=%ld, actual=%ld", requested, actual);
  76 
  77         if (actual != requested)
  78                 return MODE_CLOCK_RANGE;
  79 
  80         return MODE_OK;
  81 }
  82 
  83 static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
  84         .detect = mdp4_lvds_connector_detect,
  85         .fill_modes = drm_helper_probe_single_connector_modes,
  86         .destroy = mdp4_lvds_connector_destroy,
  87         .reset = drm_atomic_helper_connector_reset,
  88         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  89         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  90 };
  91 
  92 static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = {
  93         .get_modes = mdp4_lvds_connector_get_modes,
  94         .mode_valid = mdp4_lvds_connector_mode_valid,
  95 };
  96 
  97 /* initialize connector */
  98 struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
  99                 struct device_node *panel_node, struct drm_encoder *encoder)
 100 {
 101         struct drm_connector *connector = NULL;
 102         struct mdp4_lvds_connector *mdp4_lvds_connector;
 103 
 104         mdp4_lvds_connector = kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL);
 105         if (!mdp4_lvds_connector)
 106                 return ERR_PTR(-ENOMEM);
 107 
 108         mdp4_lvds_connector->encoder = encoder;
 109         mdp4_lvds_connector->panel_node = panel_node;
 110 
 111         connector = &mdp4_lvds_connector->base;
 112 
 113         drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs,
 114                         DRM_MODE_CONNECTOR_LVDS);
 115         drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs);
 116 
 117         connector->polled = 0;
 118 
 119         connector->interlace_allowed = 0;
 120         connector->doublescan_allowed = 0;
 121 
 122         drm_connector_attach_encoder(connector, encoder);
 123 
 124         return connector;
 125 }

/* [<][>][^][v][top][bottom][index][help] */