Commit d00b39c1 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux into drm-next

This pull request want to land the analogix_dp driver into drm/bridge directory,
which reused the Exynos DP code, and add Rockchip DP support. And those
patches have been:

* 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux:
  drm: bridge: analogix/dp: Fix the possible dead lock in bridge disable time
  drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time
  drm: bridge: analogix/dp: add edid modes parse in get_modes method
  drm: bridge: analogix/dp: move hpd detect to connector detect function
  drm: bridge: analogix/dp: try force hpd after plug in lookup failed
  drm: bridge: analogix/dp: add max link rate and lane count limit for RK3288
  drm: bridge: analogix/dp: add some rk3288 special registers setting
  dt-bindings: add document for rockchip variant of analogix_dp
  drm: rockchip: dp: add rockchip platform dp driver
  ARM: dts: exynos/dp: remove some properties that deprecated by analogix_dp driver
  dt-bindings: add document for analogix display port driver
  drm: bridge: analogix/dp: dynamic parse sync_pol & interlace & dynamic_range
  drm: bridge: analogix/dp: remove duplicate configuration of link rate and link count
  drm: bridge: analogix/dp: fix some obvious code style
  drm: bridge: analogix/dp: rename register constants
  drm/exynos: dp: rename implementation specific driver part
  drm: bridge: analogix/dp: split exynos dp driver to bridge directory
parents 85bd5ac3 7b4b7a8d
Analogix Display Port bridge bindings
Required properties for dp-controller:
-compatible:
platform specific such as:
* "samsung,exynos5-dp"
* "rockchip,rk3288-dp"
-reg:
physical base address of the controller and length
of memory mapped region.
-interrupts:
interrupt combiner values.
-clocks:
from common clock binding: handle to dp clock.
-clock-names:
from common clock binding: Shall be "dp".
-interrupt-parent:
phandle to Interrupt combiner node.
-phys:
from general PHY binding: the phandle for the PHY device.
-phy-names:
from general PHY binding: Should be "dp".
Optional properties for dp-controller:
-force-hpd:
Indicate driver need force hpd when hpd detect failed, this
is used for some eDP screen which don't have hpd signal.
-hpd-gpios:
Hotplug detect GPIO.
Indicates which GPIO should be used for hotplug detection
-port@[X]: SoC specific port nodes with endpoint definitions as defined
in Documentation/devicetree/bindings/media/video-interfaces.txt,
please refer to the SoC specific binding document:
* Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
-------------------------------------------------------------------------------
Example:
dp-controller {
compatible = "samsung,exynos5-dp";
reg = <0x145b0000 0x10000>;
interrupts = <10 3>;
interrupt-parent = <&combiner>;
clocks = <&clock 342>;
clock-names = "dp";
phys = <&dp_phy>;
phy-names = "dp";
};
Device-Tree bindings for Samsung Exynos Embedded DisplayPort Transmitter(eDP)
DisplayPort is industry standard to accommodate the growing board adoption
of digital display technology within the PC and CE industries.
It consolidates the internal and external connection methods to reduce device
complexity and cost. It also supports necessary features for important cross
industry applications and provides performance scalability to enable the next
generation of displays that feature higher color depths, refresh rates, and
display resolutions.
eDP (embedded display port) device is compliant with Embedded DisplayPort
standard as follows,
- DisplayPort standard 1.1a for Exynos5250 and Exynos5260.
- DisplayPort standard 1.3 for Exynos5422s and Exynos5800.
eDP resides between FIMD and panel or FIMD and bridge such as LVDS.
The Exynos display port interface should be configured based on The Exynos display port interface should be configured based on
the type of panel connected to it. the type of panel connected to it.
...@@ -48,26 +31,6 @@ Required properties for dp-controller: ...@@ -48,26 +31,6 @@ Required properties for dp-controller:
from general PHY binding: the phandle for the PHY device. from general PHY binding: the phandle for the PHY device.
-phy-names: -phy-names:
from general PHY binding: Should be "dp". from general PHY binding: Should be "dp".
-samsung,color-space:
input video data format.
COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
-samsung,dynamic-range:
dynamic range for input video data.
VESA = 0, CEA = 1
-samsung,ycbcr-coeff:
YCbCr co-efficients for input video.
COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
-samsung,color-depth:
number of bits per colour component.
COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
-samsung,link-rate:
link rate supported by the panel.
LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
-samsung,lane-count:
number of lanes supported by the panel.
LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
- display-timings: timings for the connected panel as described by
Documentation/devicetree/bindings/display/display-timing.txt
Optional properties for dp-controller: Optional properties for dp-controller:
-interlaced: -interlaced:
...@@ -83,17 +46,31 @@ Optional properties for dp-controller: ...@@ -83,17 +46,31 @@ Optional properties for dp-controller:
Hotplug detect GPIO. Hotplug detect GPIO.
Indicates which GPIO should be used for hotplug Indicates which GPIO should be used for hotplug
detection detection
Video interfaces: -video interfaces: Device node can contain video interface port
Device node can contain video interface port nodes according to [1]. nodes according to [1].
The following are properties specific to those nodes: - display-timings: timings for the connected panel as described by
Documentation/devicetree/bindings/display/panel/display-timing.txt
endpoint node connected to bridge or panel node:
- remote-endpoint: specifies the endpoint in panel or bridge node. For the below properties, please refer to Analogix DP binding document:
This node is required in all kinds of exynos dp * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
to represent the connection between dp and bridge -phys (required)
or dp and panel. -phy-names (required)
-hpd-gpios (optional)
[1]: Documentation/devicetree/bindings/media/video-interfaces.txt force-hpd (optional)
Deprecated properties for DisplayPort:
-interlaced: deprecated prop that can parsed from drm_display_mode.
-vsync-active-high: deprecated prop that can parsed from drm_display_mode.
-hsync-active-high: deprecated prop that can parsed from drm_display_mode.
-samsung,ycbcr-coeff: deprecated prop that can parsed from drm_display_mode.
-samsung,dynamic-range: deprecated prop that can parsed from drm_display_mode.
-samsung,color-space: deprecated prop that can parsed from drm_display_info.
-samsung,color-depth: deprecated prop that can parsed from drm_display_info.
-samsung,link-rate: deprecated prop that can reading from monitor by dpcd method.
-samsung,lane-count: deprecated prop that can reading from monitor by dpcd method.
-samsung,hpd-gpio: deprecated name for hpd-gpios.
-------------------------------------------------------------------------------
Example: Example:
...@@ -112,13 +89,6 @@ SOC specific portion: ...@@ -112,13 +89,6 @@ SOC specific portion:
Board Specific portion: Board Specific portion:
dp-controller { dp-controller {
samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>;
samsung,link-rate = <0x0a>;
samsung,lane-count = <4>;
display-timings { display-timings {
native-mode = <&lcd_timing>; native-mode = <&lcd_timing>;
lcd_timing: 1366x768 { lcd_timing: 1366x768 {
...@@ -135,18 +105,9 @@ Board Specific portion: ...@@ -135,18 +105,9 @@ Board Specific portion:
}; };
ports { ports {
port { port@0 {
dp_out: endpoint { dp_out: endpoint {
remote-endpoint = <&dp_in>; remote-endpoint = <&bridge_in>;
};
};
};
panel {
...
port {
dp_in: endpoint {
remote-endpoint = <&dp_out>;
}; };
}; };
}; };
......
Rockchip RK3288 specific extensions to the Analogix Display Port
================================
Required properties:
- compatible: "rockchip,rk3288-edp";
- reg: physical base address of the controller and length
- clocks: from common clock binding: handle to dp clock.
of memory mapped region.
- clock-names: from common clock binding:
Required elements: "dp" "pclk"
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- pinctrl-names: Names corresponding to the chip hotplug pinctrl states.
- pinctrl-0: pin-control mode. should be <&edp_hpd>
- reset-names: Must include the name "dp"
- rockchip,grf: this soc should set GRF regs, so need get grf here.
- ports: there are 2 port nodes with endpoint definitions as defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
Port 0: contained 2 endpoints, connecting to the output of vop.
Port 1: contained 1 endpoint, connecting to the input of panel.
For the below properties, please refer to Analogix DP binding document:
* Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
- phys (required)
- phy-names (required)
- hpd-gpios (optional)
- force-hpd (optional)
-------------------------------------------------------------------------------
Example:
dp-controller: dp@ff970000 {
compatible = "rockchip,rk3288-dp";
reg = <0xff970000 0x4000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
clock-names = "dp", "pclk";
phys = <&dp_phy>;
phy-names = "dp";
rockchip,grf = <&grf>;
resets = <&cru 111>;
reset-names = "dp";
pinctrl-names = "default";
pinctrl-0 = <&edp_hpd>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
edp_in: port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
edp_in_vopb: endpoint@0 {
reg = <0>;
remote-endpoint = <&vopb_out_edp>;
};
edp_in_vopl: endpoint@1 {
reg = <1>;
remote-endpoint = <&vopl_out_edp>;
};
};
edp_out: port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
edp_out_panel: endpoint {
reg = <0>;
remote-endpoint = <&panel_in_edp>
};
};
};
};
pinctrl {
edp {
edp_hpd: edp-hpd {
rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_none>;
};
};
};
...@@ -124,8 +124,6 @@ &cpu0 { ...@@ -124,8 +124,6 @@ &cpu0 {
&dp { &dp {
status = "okay"; status = "okay";
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <4>; samsung,lane-count = <4>;
......
...@@ -80,8 +80,6 @@ &cpu0 { ...@@ -80,8 +80,6 @@ &cpu0 {
&dp { &dp {
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <4>; samsung,lane-count = <4>;
......
...@@ -236,12 +236,10 @@ &dp { ...@@ -236,12 +236,10 @@ &dp {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>; pinctrl-0 = <&dp_hpd>;
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <2>; samsung,lane-count = <2>;
samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>; hpd-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
ports { ports {
port@0 { port@0 {
......
...@@ -74,12 +74,10 @@ &dp { ...@@ -74,12 +74,10 @@ &dp {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>; pinctrl-0 = <&dp_hpd_gpio>;
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <1>; samsung,lane-count = <1>;
samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>; hpd-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>;
}; };
&ehci { &ehci {
......
...@@ -157,12 +157,10 @@ &dp { ...@@ -157,12 +157,10 @@ &dp {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>; pinctrl-0 = <&dp_hpd_gpio>;
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x06>; samsung,link-rate = <0x06>;
samsung,lane-count = <2>; samsung,lane-count = <2>;
samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
ports { ports {
port@0 { port@0 {
......
...@@ -102,8 +102,6 @@ &dp { ...@@ -102,8 +102,6 @@ &dp {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&dp_hpd>; pinctrl-0 = <&dp_hpd>;
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <4>; samsung,lane-count = <4>;
......
...@@ -157,8 +157,6 @@ &dp { ...@@ -157,8 +157,6 @@ &dp {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&dp_hpd_gpio>; pinctrl-0 = <&dp_hpd_gpio>;
samsung,color-space = <0>; samsung,color-space = <0>;
samsung,dynamic-range = <0>;
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>; samsung,color-depth = <1>;
samsung,link-rate = <0x0a>; samsung,link-rate = <0x0a>;
samsung,lane-count = <2>; samsung,lane-count = <2>;
......
...@@ -40,4 +40,6 @@ config DRM_PARADE_PS8622 ...@@ -40,4 +40,6 @@ config DRM_PARADE_PS8622
---help--- ---help---
Parade eDP-LVDS bridge chip driver. Parade eDP-LVDS bridge chip driver.
source "drivers/gpu/drm/bridge/analogix/Kconfig"
endmenu endmenu
...@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o ...@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
config DRM_ANALOGIX_DP
tristate
depends on DRM
analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o
obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
...@@ -71,8 +71,9 @@ config DRM_EXYNOS_DSI ...@@ -71,8 +71,9 @@ config DRM_EXYNOS_DSI
This enables support for Exynos MIPI-DSI device. This enables support for Exynos MIPI-DSI device.
config DRM_EXYNOS_DP config DRM_EXYNOS_DP
bool "Display Port" bool "EXYNOS specific extensions for Analogix DP driver"
depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
select DRM_ANALOGIX_DP
default DRM_EXYNOS default DRM_EXYNOS
select DRM_PANEL select DRM_PANEL
help help
......
...@@ -12,7 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o ...@@ -12,7 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp.o
exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o
exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
......
/*
* Samsung SoC DP (Display Port) interface driver.
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
* Author: Jingoo Han <jg1.han@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/of_graph.h>
#include <linux/component.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_panel.h>
#include <drm/bridge/analogix_dp.h>
#include <drm/exynos_drm.h>
#include "exynos_drm_crtc.h"
#define to_dp(nm) container_of(nm, struct exynos_dp_device, nm)
struct exynos_dp_device {
struct drm_encoder encoder;
struct drm_connector connector;
struct drm_bridge *ptn_bridge;
struct drm_device *drm_dev;
struct device *dev;
struct videomode vm;
struct analogix_dp_plat_data plat_data;
};
int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
bool enable)
{
struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_encoder *encoder = &dp->encoder;
struct exynos_drm_crtc *crtc;
if (!encoder)
return -1;
crtc = to_exynos_crtc(encoder->crtc);
if (crtc && crtc->ops && crtc->ops->clock_enable)
crtc->ops->clock_enable(crtc, enable);
return 0;
}
static int exynos_dp_poweron(struct analogix_dp_plat_data *plat_data)
{
return exynos_dp_crtc_clock_enable(plat_data, true);
}
static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
{
return exynos_dp_crtc_clock_enable(plat_data, false);
}
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data)
{
struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_connector *connector = &dp->connector;
struct drm_display_mode *mode;
int num_modes = 0;
if (dp->plat_data.panel)
return num_modes;
mode = drm_mode_create(connector->dev);
if (!mode) {
DRM_ERROR("failed to create a new display mode.\n");
return num_modes;
}
drm_display_mode_from_videomode(&dp->vm, mode);
connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm;
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
return num_modes + 1;
}
static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
struct drm_bridge *bridge,
struct drm_connector *connector)
{
struct exynos_dp_device *dp = to_dp(plat_data);
struct drm_encoder *encoder = &dp->encoder;
int ret;
drm_connector_register(connector);
/* Pre-empt DP connector creation if there's a bridge */
if (dp->ptn_bridge) {
bridge->next = dp->ptn_bridge;
dp->ptn_bridge->encoder = encoder;
ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
if (ret) {
DRM_ERROR("Failed to attach bridge to drm\n");
bridge->next = NULL;
return ret;
}
}
return 0;
}
static void exynos_dp_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
}
static void exynos_dp_nop(struct drm_encoder *encoder)
{
/* do nothing */
}
static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
.mode_set = exynos_dp_mode_set,
.enable = exynos_dp_nop,
.disable = exynos_dp_nop,
};
static const struct drm_encoder_funcs exynos_dp_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
{
int ret;
ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
if (ret) {
DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
return ret;
}
return 0;
}
static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
{
struct exynos_dp_device *dp = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dp->encoder;
struct drm_device *drm_dev = data;
int pipe, ret;
/*
* Just like the probe function said, we don't need the
* device drvrate anymore, we should leave the charge to
* analogix dp driver, set the device drvdata to NULL.
*/
dev_set_drvdata(dev, NULL);
dp->dev = dev;
dp->drm_dev = drm_dev;
dp->plat_data.dev_type = EXYNOS_DP;
dp->plat_data.power_on = exynos_dp_poweron;
dp->plat_data.power_off = exynos_dp_poweroff;
dp->plat_data.attach = exynos_dp_bridge_attach;
dp->plat_data.get_modes = exynos_dp_get_modes;
if (!dp->plat_data.panel && !dp->ptn_bridge) {
ret = exynos_dp_dt_parse_panel(dp);
if (ret)
return ret;
}
pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
EXYNOS_DISPLAY_TYPE_LCD);
if (pipe < 0)
return pipe;
encoder->possible_crtcs = 1 << pipe;
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
dp->plat_data.encoder = encoder;
return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
}
static void exynos_dp_unbind(struct device *dev, struct device *master,
void *data)
{
return analogix_dp_unbind(dev, master, data);
}
static const struct component_ops exynos_dp_ops = {
.bind = exynos_dp_bind,
.unbind = exynos_dp_unbind,
};
static int exynos_dp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = NULL, *endpoint = NULL;
struct exynos_dp_device *dp;
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp)
return -ENOMEM;
/*
* We just use the drvdata until driver run into component
* add function, and then we would set drvdata to null, so
* that analogix dp driver would take charge of the drvdata.
*/
platform_set_drvdata(pdev, dp);
/* This is for the backward compatibility. */
np = of_parse_phandle(dev->of_node, "panel", 0);
if (np) {
dp->plat_data.panel = of_drm_find_panel(np);
of_node_put(np);
if (!dp->plat_data.panel)
return -EPROBE_DEFER;
goto out;
}
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
if (endpoint) {
np = of_graph_get_remote_port_parent(endpoint);
if (np) {
/* The remote port can be either a panel or a bridge */
dp->plat_data.panel = of_drm_find_panel(np);
if (!dp->plat_data.panel) {
dp->ptn_bridge = of_drm_find_bridge(np);
if (!dp->ptn_bridge) {
of_node_put(np);
return -EPROBE_DEFER;
}
}
of_node_put(np);
} else {
DRM_ERROR("no remote endpoint device node found.\n");
return -EINVAL;
}
} else {
DRM_ERROR("no port endpoint subnode found.\n");
return -EINVAL;
}
out:
return component_add(&pdev->dev, &exynos_dp_ops);
}
static int exynos_dp_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &exynos_dp_ops);
return 0;
}
#ifdef CONFIG_PM
static int exynos_dp_suspend(struct device *dev)
{
return analogix_dp_suspend(dev);
}
static int exynos_dp_resume(struct device *dev)
{
return analogix_dp_resume(dev);
}
#endif
static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL)
};
static const struct of_device_id exynos_dp_match[] = {
{ .compatible = "samsung,exynos5-dp" },
{},
};
MODULE_DEVICE_TABLE(of, exynos_dp_match);
struct platform_driver dp_driver = {
.probe = exynos_dp_probe,
.remove = exynos_dp_remove,
.driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
.of_match_table = exynos_dp_match,
},
};
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
MODULE_DESCRIPTION("Samsung Specific Analogix-DP Driver Extension");
MODULE_LICENSE("GPL v2");
...@@ -16,6 +16,15 @@ config DRM_ROCKCHIP ...@@ -16,6 +16,15 @@ config DRM_ROCKCHIP
2D or 3D acceleration; acceleration is performed by other 2D or 3D acceleration; acceleration is performed by other
IP found on the SoC. IP found on the SoC.
config ROCKCHIP_ANALOGIX_DP
tristate "Rockchip specific extensions for Analogix DP driver"
depends on DRM_ROCKCHIP
select DRM_ANALOGIX_DP
help
This selects support for Rockchip SoC specific extensions
for the Analogix Core DP driver. If you want to enable DP
on RK3288 based SoC, you should selet this option.
config ROCKCHIP_DW_HDMI config ROCKCHIP_DW_HDMI
tristate "Rockchip specific extensions for Synopsys DW HDMI" tristate "Rockchip specific extensions for Synopsys DW HDMI"
depends on DRM_ROCKCHIP depends on DRM_ROCKCHIP
......
...@@ -6,6 +6,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ ...@@ -6,6 +6,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o rockchip_drm_vop.o rockchip_drm_gem.o rockchip_drm_vop.o
rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
......
This diff is collapsed.
/*
* Analogix DP (Display Port) Core interface driver.
*
* Copyright (C) 2015 Rockchip Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _ANALOGIX_DP_H_
#define _ANALOGIX_DP_H_
#include <drm/drm_crtc.h>
enum analogix_dp_devtype {
EXYNOS_DP,
RK3288_DP,
};
struct analogix_dp_plat_data {
enum analogix_dp_devtype dev_type;
struct drm_panel *panel;
struct drm_encoder *encoder;
struct drm_connector *connector;
int (*power_on)(struct analogix_dp_plat_data *);
int (*power_off)(struct analogix_dp_plat_data *);
int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
struct drm_connector *);
int (*get_modes)(struct analogix_dp_plat_data *);
};
int analogix_dp_resume(struct device *dev);
int analogix_dp_suspend(struct device *dev);
int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
struct analogix_dp_plat_data *plat_data);
void analogix_dp_unbind(struct device *dev, struct device *master, void *data);
#endif /* _ANALOGIX_DP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment