aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 21:44:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 21:44:08 -0400
commit731c7d3a205ba89b475b2aa71b5f13dd6ae3de56 (patch)
treed2b9c3e0a98b94dfc3e4e60e35622c0143ef4ed4 /drivers/gpu/drm/omapdrm
parent77a87824ed676ca8ff8482e4157d3adb284fd381 (diff)
parent753e7c8cbd8c503b962294303c7b5e9ea8513443 (diff)
Merge tag 'drm-for-v4.8' of git://people.freedesktop.org/~airlied/linux
Merge drm updates from Dave Airlie: "This is the main drm pull request for 4.8. I'm down with a cold at the moment so hopefully this isn't in too bad a state, I finished pulling stuff last week mostly (nouveau fixes just went in today), so only this message should be influenced by illness. Apologies to anyone who's major feature I missed :-) Core: Lockless GEM BO freeing Non-blocking atomic work Documentation changes (rst/sphinx) Prep for new fencing changes Simple display helpers Master/auth changes Register/unregister rework Loads of trivial patches/fixes. New stuff: ARM Mali display driver (not the 3D chip) sii902x RGB->HDMI bridge Panel: Support for new panels Improved backlight support Bridge: Convert ADV7511 to bridge driver ADV7533 support TC358767 (DSI/DPI to eDP) encoder chip support i915: BXT support enabled by default GVT-g infrastructure GuC command submission and fixes BXT workarounds SKL/BKL workarounds Demidlayering device registration Thundering herd fixes Missing pci ids Atomic updates amdgpu/radeon: ATPX improvements for better dGPU power control on PX systems New power features for CZ/BR/ST Pipelined BO moves and evictions in TTM GPU scheduler improvements GPU reset improvements Overclocking on dGPUs with amdgpu Polaris powermanagement enabled nouveau: GK20A/GM20B volt and clock improvements. Initial support for GP100/GP104 GPUs, GP104 will not yet support acceleration due to NVIDIA having not released firmware for them as of yet. exynos: Exynos5433 SoC with IOMMU support. vc4: Shader validation for branching imx-drm: Atomic mode setting conversion Reworked DMFC FIFO allocation External bridge support analogix-dp: RK3399 eDP support Lots of fixes. rockchip: Lots of small fixes. msm: DT bindings cleanups Shrinker and madvise support ASoC HDMI codec support tegra: Host1x driver cleanups SOR reworking for DP support Runtime PM support omapdrm: PLL enhancements Header refactoring Gamma table support arcgpu: Simulator support virtio-gpu: Atomic modesetting fixes. rcar-du: Misc fixes. mediatek: MT8173 HDMI support sti: ASOC HDMI codec support Minor fixes fsl-dcu: Suspend/resume support Bridge support amdkfd: Minor fixes. etnaviv: Enable GPU clock gating hisilicon: Vblank and other fixes" * tag 'drm-for-v4.8' of git://people.freedesktop.org/~airlied/linux: (1575 commits) drm/nouveau/gr/nv3x: fix instobj write offsets in gr setup drm/nouveau/acpi: fix lockup with PCIe runtime PM drm/nouveau/acpi: check for function 0x1B before using it drm/nouveau/acpi: return supported DSM functions drm/nouveau/acpi: ensure matching ACPI handle and supported functions drm/nouveau/fbcon: fix font width not divisible by 8 drm/amd/powerplay: remove enable_clock_power_gatings_tasks from initialize and resume events drm/amd/powerplay: move clockgating to after ungating power in pp for uvd/vce drm/amdgpu: add query device id and revision id into system info entry at CGS drm/amdgpu: add new definition in bif header drm/amd/powerplay: rename smum header guards drm/amdgpu: enable UVD context buffer for older HW drm/amdgpu: fix default UVD context size drm/amdgpu: fix incorrect type of info_id drm/amdgpu: make amdgpu_cgs_call_acpi_method as static drm/amdgpu: comment out unused defaults_staturn_pro static const structure to fix the build drm/amdgpu: enable UVD VM only on polaris drm/amdgpu: increase timeout of IB test drm/amdgpu: add destroy session when generate VCE destroy msg. drm/amd: fix deadlock of job_list_lock V2 ...
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r--drivers/gpu/drm/omapdrm/Kconfig5
-rw-r--r--drivers/gpu/drm/omapdrm/displays/Kconfig28
-rw-r--r--drivers/gpu/drm/omapdrm/displays/Makefile28
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c11
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-dvi.c5
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-hdmi.c4
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-opa362.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c26
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c7
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c22
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c4
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/core.c5
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c471
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.h5
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc_coefs.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/display.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c136
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c57
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss-of.c10
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c255
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h45
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.c46
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.h1
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi.h6
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4.c11
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5.c11
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_common.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_phy.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_pll.c78
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_wp.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h871
-rw-r--r--drivers/gpu/drm/omapdrm/dss/output.c3
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c129
-rw-r--r--drivers/gpu/drm/omapdrm/dss/rfbi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c3
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c10
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c56
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c16
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h14
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c20
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c8
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c15
50 files changed, 1903 insertions, 561 deletions
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 336ad4de9981..556f81f6b2c7 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,11 +4,6 @@ config DRM_OMAP
4 depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM 4 depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
5 select OMAP2_DSS 5 select OMAP2_DSS
6 select DRM_KMS_HELPER 6 select DRM_KMS_HELPER
7 select DRM_KMS_FB_HELPER
8 select FB_SYS_FILLRECT
9 select FB_SYS_COPYAREA
10 select FB_SYS_IMAGEBLIT
11 select FB_SYS_FOPS
12 default n 7 default n
13 help 8 help
14 DRM display driver for OMAP2/3/4 based boards. 9 DRM display driver for OMAP2/3/4 based boards.
diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig b/drivers/gpu/drm/omapdrm/displays/Kconfig
index 2a618afe0f53..c226da145fb3 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -1,80 +1,80 @@
1menu "OMAPDRM External Display Device Drivers" 1menu "OMAPDRM External Display Device Drivers"
2 2
3config DISPLAY_ENCODER_OPA362 3config DRM_OMAP_ENCODER_OPA362
4 tristate "OPA362 external analog amplifier" 4 tristate "OPA362 external analog amplifier"
5 help 5 help
6 Driver for OPA362 external analog TV amplifier controlled 6 Driver for OPA362 external analog TV amplifier controlled
7 through a GPIO. 7 through a GPIO.
8 8
9config DISPLAY_ENCODER_TFP410 9config DRM_OMAP_ENCODER_TFP410
10 tristate "TFP410 DPI to DVI Encoder" 10 tristate "TFP410 DPI to DVI Encoder"
11 help 11 help
12 Driver for TFP410 DPI to DVI encoder. 12 Driver for TFP410 DPI to DVI encoder.
13 13
14config DISPLAY_ENCODER_TPD12S015 14config DRM_OMAP_ENCODER_TPD12S015
15 tristate "TPD12S015 HDMI ESD protection and level shifter" 15 tristate "TPD12S015 HDMI ESD protection and level shifter"
16 help 16 help
17 Driver for TPD12S015, which offers HDMI ESD protection and level 17 Driver for TPD12S015, which offers HDMI ESD protection and level
18 shifting. 18 shifting.
19 19
20config DISPLAY_CONNECTOR_DVI 20config DRM_OMAP_CONNECTOR_DVI
21 tristate "DVI Connector" 21 tristate "DVI Connector"
22 depends on I2C 22 depends on I2C
23 help 23 help
24 Driver for a generic DVI connector. 24 Driver for a generic DVI connector.
25 25
26config DISPLAY_CONNECTOR_HDMI 26config DRM_OMAP_CONNECTOR_HDMI
27 tristate "HDMI Connector" 27 tristate "HDMI Connector"
28 help 28 help
29 Driver for a generic HDMI connector. 29 Driver for a generic HDMI connector.
30 30
31config DISPLAY_CONNECTOR_ANALOG_TV 31config DRM_OMAP_CONNECTOR_ANALOG_TV
32 tristate "Analog TV Connector" 32 tristate "Analog TV Connector"
33 help 33 help
34 Driver for a generic analog TV connector. 34 Driver for a generic analog TV connector.
35 35
36config DISPLAY_PANEL_DPI 36config DRM_OMAP_PANEL_DPI
37 tristate "Generic DPI panel" 37 tristate "Generic DPI panel"
38 help 38 help
39 Driver for generic DPI panels. 39 Driver for generic DPI panels.
40 40
41config DISPLAY_PANEL_DSI_CM 41config DRM_OMAP_PANEL_DSI_CM
42 tristate "Generic DSI Command Mode Panel" 42 tristate "Generic DSI Command Mode Panel"
43 depends on BACKLIGHT_CLASS_DEVICE 43 depends on BACKLIGHT_CLASS_DEVICE
44 help 44 help
45 Driver for generic DSI command mode panels. 45 Driver for generic DSI command mode panels.
46 46
47config DISPLAY_PANEL_SONY_ACX565AKM 47config DRM_OMAP_PANEL_SONY_ACX565AKM
48 tristate "ACX565AKM Panel" 48 tristate "ACX565AKM Panel"
49 depends on SPI && BACKLIGHT_CLASS_DEVICE 49 depends on SPI && BACKLIGHT_CLASS_DEVICE
50 help 50 help
51 This is the LCD panel used on Nokia N900 51 This is the LCD panel used on Nokia N900
52 52
53config DISPLAY_PANEL_LGPHILIPS_LB035Q02 53config DRM_OMAP_PANEL_LGPHILIPS_LB035Q02
54 tristate "LG.Philips LB035Q02 LCD Panel" 54 tristate "LG.Philips LB035Q02 LCD Panel"
55 depends on SPI 55 depends on SPI
56 help 56 help
57 LCD Panel used on the Gumstix Overo Palo35 57 LCD Panel used on the Gumstix Overo Palo35
58 58
59config DISPLAY_PANEL_SHARP_LS037V7DW01 59config DRM_OMAP_PANEL_SHARP_LS037V7DW01
60 tristate "Sharp LS037V7DW01 LCD Panel" 60 tristate "Sharp LS037V7DW01 LCD Panel"
61 depends on BACKLIGHT_CLASS_DEVICE 61 depends on BACKLIGHT_CLASS_DEVICE
62 help 62 help
63 LCD Panel used in TI's SDP3430 and EVM boards 63 LCD Panel used in TI's SDP3430 and EVM boards
64 64
65config DISPLAY_PANEL_TPO_TD028TTEC1 65config DRM_OMAP_PANEL_TPO_TD028TTEC1
66 tristate "TPO TD028TTEC1 LCD Panel" 66 tristate "TPO TD028TTEC1 LCD Panel"
67 depends on SPI 67 depends on SPI
68 help 68 help
69 LCD panel used in Openmoko. 69 LCD panel used in Openmoko.
70 70
71config DISPLAY_PANEL_TPO_TD043MTEA1 71config DRM_OMAP_PANEL_TPO_TD043MTEA1
72 tristate "TPO TD043MTEA1 LCD Panel" 72 tristate "TPO TD043MTEA1 LCD Panel"
73 depends on SPI 73 depends on SPI
74 help 74 help
75 LCD Panel used in OMAP3 Pandora 75 LCD Panel used in OMAP3 Pandora
76 76
77config DISPLAY_PANEL_NEC_NL8048HL11 77config DRM_OMAP_PANEL_NEC_NL8048HL11
78 tristate "NEC NL8048HL11 Panel" 78 tristate "NEC NL8048HL11 Panel"
79 depends on SPI 79 depends on SPI
80 depends on BACKLIGHT_CLASS_DEVICE 80 depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile b/drivers/gpu/drm/omapdrm/displays/Makefile
index 9aa176bfbf2e..46baafb1a83e 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -1,14 +1,14 @@
1obj-$(CONFIG_DISPLAY_ENCODER_OPA362) += encoder-opa362.o 1obj-$(CONFIG_DRM_OMAP_ENCODER_OPA362) += encoder-opa362.o
2obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o 2obj-$(CONFIG_DRM_OMAP_ENCODER_TFP410) += encoder-tfp410.o
3obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o 3obj-$(CONFIG_DRM_OMAP_ENCODER_TPD12S015) += encoder-tpd12s015.o
4obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o 4obj-$(CONFIG_DRM_OMAP_CONNECTOR_DVI) += connector-dvi.o
5obj-$(CONFIG_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o 5obj-$(CONFIG_DRM_OMAP_CONNECTOR_HDMI) += connector-hdmi.o
6obj-$(CONFIG_DISPLAY_CONNECTOR_ANALOG_TV) += connector-analog-tv.o 6obj-$(CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
7obj-$(CONFIG_DISPLAY_PANEL_DPI) += panel-dpi.o 7obj-$(CONFIG_DRM_OMAP_PANEL_DPI) += panel-dpi.o
8obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o 8obj-$(CONFIG_DRM_OMAP_PANEL_DSI_CM) += panel-dsi-cm.o
9obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o 9obj-$(CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
10obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o 10obj-$(CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
11obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 11obj-$(CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
12obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o 12obj-$(CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
13obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o 13obj-$(CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
14obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o 14obj-$(CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 8511c648a15c..3485d1ecd655 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -14,9 +14,10 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/of.h> 15#include <linux/of.h>
16 16
17#include <video/omapdss.h>
18#include <video/omap-panel-data.h> 17#include <video/omap-panel-data.h>
19 18
19#include "../dss/omapdss.h"
20
20struct panel_drv_data { 21struct panel_drv_data {
21 struct omap_dss_device dssdev; 22 struct omap_dss_device dssdev;
22 struct omap_dss_device *in; 23 struct omap_dss_device *in;
@@ -25,7 +26,6 @@ struct panel_drv_data {
25 26
26 struct omap_video_timings timings; 27 struct omap_video_timings timings;
27 28
28 enum omap_dss_venc_type connector_type;
29 bool invert_polarity; 29 bool invert_polarity;
30}; 30};
31 31
@@ -45,10 +45,6 @@ static const struct omap_video_timings tvc_pal_timings = {
45 45
46static const struct of_device_id tvc_of_match[]; 46static const struct of_device_id tvc_of_match[];
47 47
48struct tvc_of_data {
49 enum omap_dss_venc_type connector_type;
50};
51
52#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) 48#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
53 49
54static int tvc_connect(struct omap_dss_device *dssdev) 50static int tvc_connect(struct omap_dss_device *dssdev)
@@ -99,7 +95,7 @@ static int tvc_enable(struct omap_dss_device *dssdev)
99 in->ops.atv->set_timings(in, &ddata->timings); 95 in->ops.atv->set_timings(in, &ddata->timings);
100 96
101 if (!ddata->dev->of_node) { 97 if (!ddata->dev->of_node) {
102 in->ops.atv->set_type(in, ddata->connector_type); 98 in->ops.atv->set_type(in, OMAP_DSS_VENC_TYPE_COMPOSITE);
103 99
104 in->ops.atv->invert_vid_out_polarity(in, 100 in->ops.atv->invert_vid_out_polarity(in,
105 ddata->invert_polarity); 101 ddata->invert_polarity);
@@ -207,7 +203,6 @@ static int tvc_probe_pdata(struct platform_device *pdev)
207 203
208 ddata->in = in; 204 ddata->in = in;
209 205
210 ddata->connector_type = pdata->connector_type;
211 ddata->invert_polarity = pdata->invert_polarity; 206 ddata->invert_polarity = pdata->invert_polarity;
212 207
213 dssdev = &ddata->dssdev; 208 dssdev = &ddata->dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 747f26a55e43..684b7aeda411 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -15,10 +15,10 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16 16
17#include <drm/drm_edid.h> 17#include <drm/drm_edid.h>
18
19#include <video/omapdss.h>
20#include <video/omap-panel-data.h> 18#include <video/omap-panel-data.h>
21 19
20#include "../dss/omapdss.h"
21
22static const struct omap_video_timings dvic_default_timings = { 22static const struct omap_video_timings dvic_default_timings = {
23 .x_res = 640, 23 .x_res = 640,
24 .y_res = 480, 24 .y_res = 480,
@@ -255,6 +255,7 @@ static int dvic_probe_of(struct platform_device *pdev)
255 adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0); 255 adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
256 if (adapter_node) { 256 if (adapter_node) {
257 adapter = of_get_i2c_adapter_by_node(adapter_node); 257 adapter = of_get_i2c_adapter_by_node(adapter_node);
258 of_node_put(adapter_node);
258 if (adapter == NULL) { 259 if (adapter == NULL) {
259 dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n"); 260 dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
260 omap_dss_put_device(ddata->in); 261 omap_dss_put_device(ddata->in);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 667ca4a24ece..7bdf83af9797 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -17,10 +17,10 @@
17#include <linux/of_gpio.h> 17#include <linux/of_gpio.h>
18 18
19#include <drm/drm_edid.h> 19#include <drm/drm_edid.h>
20
21#include <video/omapdss.h>
22#include <video/omap-panel-data.h> 20#include <video/omap-panel-data.h>
23 21
22#include "../dss/omapdss.h"
23
24static const struct omap_video_timings hdmic_default_timings = { 24static const struct omap_video_timings hdmic_default_timings = {
25 .x_res = 640, 25 .x_res = 640,
26 .y_res = 480, 26 .y_res = 480,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 9594ff7a2b0c..fe4e7ec3bab0 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -18,9 +18,8 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/of_gpio.h>
22 21
23#include <video/omapdss.h> 22#include "../dss/omapdss.h"
24 23
25struct panel_drv_data { 24struct panel_drv_data {
26 struct omap_dss_device dssdev; 25 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 671806ca7d6a..d768217cefe0 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -15,8 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/of_gpio.h> 16#include <linux/of_gpio.h>
17 17
18#include <video/omapdss.h> 18#include "../dss/omapdss.h"
19#include <video/omap-panel-data.h>
20 19
21struct panel_drv_data { 20struct panel_drv_data {
22 struct omap_dss_device dssdev; 21 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 916a89978387..46855c8f5cbf 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -16,8 +16,7 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/gpio/consumer.h> 17#include <linux/gpio/consumer.h>
18 18
19#include <video/omapdss.h> 19#include "../dss/omapdss.h"
20#include <video/omap-panel-data.h>
21 20
22struct panel_drv_data { 21struct panel_drv_data {
23 struct omap_dss_device dssdev; 22 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 7c2331be8d15..7f16f985ab22 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -15,11 +15,13 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_gpio.h> 17#include <linux/of_gpio.h>
18#include <linux/regulator/consumer.h>
18 19
19#include <video/omapdss.h>
20#include <video/omap-panel-data.h> 20#include <video/omap-panel-data.h>
21#include <video/of_display_timing.h> 21#include <video/of_display_timing.h>
22 22
23#include "../dss/omapdss.h"
24
23struct panel_drv_data { 25struct panel_drv_data {
24 struct omap_dss_device dssdev; 26 struct omap_dss_device dssdev;
25 struct omap_dss_device *in; 27 struct omap_dss_device *in;
@@ -32,6 +34,7 @@ struct panel_drv_data {
32 int backlight_gpio; 34 int backlight_gpio;
33 35
34 struct gpio_desc *enable_gpio; 36 struct gpio_desc *enable_gpio;
37 struct regulator *vcc_supply;
35}; 38};
36 39
37#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) 40#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
@@ -83,6 +86,12 @@ static int panel_dpi_enable(struct omap_dss_device *dssdev)
83 if (r) 86 if (r)
84 return r; 87 return r;
85 88
89 r = regulator_enable(ddata->vcc_supply);
90 if (r) {
91 in->ops.dpi->disable(in);
92 return r;
93 }
94
86 gpiod_set_value_cansleep(ddata->enable_gpio, 1); 95 gpiod_set_value_cansleep(ddata->enable_gpio, 1);
87 96
88 if (gpio_is_valid(ddata->backlight_gpio)) 97 if (gpio_is_valid(ddata->backlight_gpio))
@@ -105,6 +114,7 @@ static void panel_dpi_disable(struct omap_dss_device *dssdev)
105 gpio_set_value_cansleep(ddata->backlight_gpio, 0); 114 gpio_set_value_cansleep(ddata->backlight_gpio, 0);
106 115
107 gpiod_set_value_cansleep(ddata->enable_gpio, 0); 116 gpiod_set_value_cansleep(ddata->enable_gpio, 0);
117 regulator_disable(ddata->vcc_supply);
108 118
109 in->ops.dpi->disable(in); 119 in->ops.dpi->disable(in);
110 120
@@ -213,6 +223,20 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
213 223
214 ddata->enable_gpio = gpio; 224 ddata->enable_gpio = gpio;
215 225
226 /*
227 * Many different panels are supported by this driver and there are
228 * probably very different needs for their reset pins in regards to
229 * timing and order relative to the enable gpio. So for now it's just
230 * ensured that the reset line isn't active.
231 */
232 gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
233 if (IS_ERR(gpio))
234 return PTR_ERR(gpio);
235
236 ddata->vcc_supply = devm_regulator_get(&pdev->dev, "vcc");
237 if (IS_ERR(ddata->vcc_supply))
238 return PTR_ERR(ddata->vcc_supply);
239
216 ddata->backlight_gpio = -ENOENT; 240 ddata->backlight_gpio = -ENOENT;
217 241
218 r = of_get_display_timing(node, "panel-timing", &timing); 242 r = of_get_display_timing(node, "panel-timing", &timing);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 2b118071b5a1..0eae8afaed90 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -25,10 +25,10 @@
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26#include <linux/of_gpio.h> 26#include <linux/of_gpio.h>
27 27
28#include <video/omapdss.h>
29#include <video/omap-panel-data.h>
30#include <video/mipi_display.h> 28#include <video/mipi_display.h>
31 29
30#include "../dss/omapdss.h"
31
32/* DSI Virtual channel. Hardcoded for now. */ 32/* DSI Virtual channel. Hardcoded for now. */
33#define TCH 0 33#define TCH 0
34 34
@@ -1284,8 +1284,7 @@ static int dsicm_probe(struct platform_device *pdev)
1284 return 0; 1284 return 0;
1285 1285
1286err_sysfs_create: 1286err_sysfs_create:
1287 if (bldev != NULL) 1287 backlight_device_unregister(bldev);
1288 backlight_device_unregister(bldev);
1289err_bl: 1288err_bl:
1290 destroy_workqueue(ddata->workqueue); 1289 destroy_workqueue(ddata->workqueue);
1291err_reg: 1290err_reg:
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index ac680e1de603..6dfb96cea293 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -17,8 +17,7 @@
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/gpio/consumer.h> 18#include <linux/gpio/consumer.h>
19 19
20#include <video/omapdss.h> 20#include "../dss/omapdss.h"
21#include <video/omap-panel-data.h>
22 21
23static struct omap_video_timings lb035q02_timings = { 22static struct omap_video_timings lb035q02_timings = {
24 .x_res = 320, 23 .x_res = 320,
@@ -51,9 +50,6 @@ struct panel_drv_data {
51 50
52 struct omap_video_timings videomode; 51 struct omap_video_timings videomode;
53 52
54 /* used for non-DT boot, to be removed */
55 int backlight_gpio;
56
57 struct gpio_desc *enable_gpio; 53 struct gpio_desc *enable_gpio;
58}; 54};
59 55
@@ -171,9 +167,6 @@ static int lb035q02_enable(struct omap_dss_device *dssdev)
171 if (ddata->enable_gpio) 167 if (ddata->enable_gpio)
172 gpiod_set_value_cansleep(ddata->enable_gpio, 1); 168 gpiod_set_value_cansleep(ddata->enable_gpio, 1);
173 169
174 if (gpio_is_valid(ddata->backlight_gpio))
175 gpio_set_value_cansleep(ddata->backlight_gpio, 1);
176
177 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 170 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
178 171
179 return 0; 172 return 0;
@@ -190,9 +183,6 @@ static void lb035q02_disable(struct omap_dss_device *dssdev)
190 if (ddata->enable_gpio) 183 if (ddata->enable_gpio)
191 gpiod_set_value_cansleep(ddata->enable_gpio, 0); 184 gpiod_set_value_cansleep(ddata->enable_gpio, 0);
192 185
193 if (gpio_is_valid(ddata->backlight_gpio))
194 gpio_set_value_cansleep(ddata->backlight_gpio, 0);
195
196 in->ops.dpi->disable(in); 186 in->ops.dpi->disable(in);
197 187
198 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 188 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -256,8 +246,6 @@ static int lb035q02_probe_of(struct spi_device *spi)
256 246
257 ddata->enable_gpio = gpio; 247 ddata->enable_gpio = gpio;
258 248
259 ddata->backlight_gpio = -ENOENT;
260
261 in = omapdss_of_find_source_for_first_ep(node); 249 in = omapdss_of_find_source_for_first_ep(node);
262 if (IS_ERR(in)) { 250 if (IS_ERR(in)) {
263 dev_err(&spi->dev, "failed to find video source\n"); 251 dev_err(&spi->dev, "failed to find video source\n");
@@ -290,13 +278,6 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
290 if (r) 278 if (r)
291 return r; 279 return r;
292 280
293 if (gpio_is_valid(ddata->backlight_gpio)) {
294 r = devm_gpio_request_one(&spi->dev, ddata->backlight_gpio,
295 GPIOF_OUT_INIT_LOW, "panel backlight");
296 if (r)
297 goto err_gpio;
298 }
299
300 ddata->videomode = lb035q02_timings; 281 ddata->videomode = lb035q02_timings;
301 282
302 dssdev = &ddata->dssdev; 283 dssdev = &ddata->dssdev;
@@ -316,7 +297,6 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
316 return 0; 297 return 0;
317 298
318err_reg: 299err_reg:
319err_gpio:
320 omap_dss_put_device(ddata->in); 300 omap_dss_put_device(ddata->in);
321 return r; 301 return r;
322} 302}
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index 38d2920a95e6..fc4c238c9583 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -18,7 +18,7 @@
18#include <linux/gpio/consumer.h> 18#include <linux/gpio/consumer.h>
19#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
20 20
21#include <video/omapdss.h> 21#include "../dss/omapdss.h"
22 22
23struct panel_drv_data { 23struct panel_drv_data {
24 struct omap_dss_device dssdev; 24 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index 4363fffc87e3..3d3efc561ea9 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -13,11 +13,11 @@
13#include <linux/gpio/consumer.h> 13#include <linux/gpio/consumer.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_gpio.h>
17#include <linux/platform_device.h> 16#include <linux/platform_device.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/regulator/consumer.h> 18#include <linux/regulator/consumer.h>
20#include <video/omapdss.h> 19
20#include "../dss/omapdss.h"
21 21
22struct panel_drv_data { 22struct panel_drv_data {
23 struct omap_dss_device dssdev; 23 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index deb416736aad..157c512205d1 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -33,9 +33,10 @@
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/of_gpio.h> 34#include <linux/of_gpio.h>
35 35
36#include <video/omapdss.h>
37#include <video/omap-panel-data.h> 36#include <video/omap-panel-data.h>
38 37
38#include "../dss/omapdss.h"
39
39#define MIPID_CMD_READ_DISP_ID 0x04 40#define MIPID_CMD_READ_DISP_ID 0x04
40#define MIPID_CMD_READ_RED 0x06 41#define MIPID_CMD_READ_RED 0x06
41#define MIPID_CMD_READ_GREEN 0x07 42#define MIPID_CMD_READ_GREEN 0x07
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index bd8d85041926..e859b3f893f7 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -28,7 +28,8 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <video/omapdss.h> 31
32#include "../dss/omapdss.h"
32 33
33struct panel_drv_data { 34struct panel_drv_data {
34 struct omap_dss_device dssdev; 35 struct omap_dss_device dssdev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index d93175b03a12..66c6bbe6472b 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -19,7 +19,7 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/of_gpio.h> 20#include <linux/of_gpio.h>
21 21
22#include <video/omapdss.h> 22#include "../dss/omapdss.h"
23 23
24#define TPO_R02_MODE(x) ((x) & 7) 24#define TPO_R02_MODE(x) ((x) & 7)
25#define TPO_R02_MODE_800x480 7 25#define TPO_R02_MODE_800x480 7
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index 7e4e5bebabbe..6a3ebfcd7223 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -35,8 +35,7 @@
35#include <linux/suspend.h> 35#include <linux/suspend.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37 37
38#include <video/omapdss.h> 38#include "omapdss.h"
39
40#include "dss.h" 39#include "dss.h"
41#include "dss_features.h" 40#include "dss_features.h"
42 41
@@ -196,8 +195,6 @@ static int __init omap_dss_probe(struct platform_device *pdev)
196 core.default_display_name = def_disp_name; 195 core.default_display_name = def_disp_name;
197 else if (pdata->default_display_name) 196 else if (pdata->default_display_name)
198 core.default_display_name = pdata->default_display_name; 197 core.default_display_name = pdata->default_display_name;
199 else if (pdata->default_device)
200 core.default_display_name = pdata->default_device->name;
201 198
202 return 0; 199 return 0;
203 200
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index f83608b69e68..535240fba671 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -41,8 +41,7 @@
41#include <linux/of.h> 41#include <linux/of.h>
42#include <linux/component.h> 42#include <linux/component.h>
43 43
44#include <video/omapdss.h> 44#include "omapdss.h"
45
46#include "dss.h" 45#include "dss.h"
47#include "dss_features.h" 46#include "dss_features.h"
48#include "dispc.h" 47#include "dispc.h"
@@ -113,9 +112,14 @@ struct dispc_features {
113 * never both, we can just use this flag for now. 112 * never both, we can just use this flag for now.
114 */ 113 */
115 bool reverse_ilace_field_order:1; 114 bool reverse_ilace_field_order:1;
115
116 bool has_gamma_table:1;
117
118 bool has_gamma_i734_bug:1;
116}; 119};
117 120
118#define DISPC_MAX_NR_FIFOS 5 121#define DISPC_MAX_NR_FIFOS 5
122#define DISPC_MAX_CHANNEL_GAMMA 4
119 123
120static struct { 124static struct {
121 struct platform_device *pdev; 125 struct platform_device *pdev;
@@ -135,6 +139,8 @@ static struct {
135 bool ctx_valid; 139 bool ctx_valid;
136 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 140 u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
137 141
142 u32 *gamma_table[DISPC_MAX_CHANNEL_GAMMA];
143
138 const struct dispc_features *feat; 144 const struct dispc_features *feat;
139 145
140 bool is_enabled; 146 bool is_enabled;
@@ -178,11 +184,19 @@ struct dispc_reg_field {
178 u8 low; 184 u8 low;
179}; 185};
180 186
187struct dispc_gamma_desc {
188 u32 len;
189 u32 bits;
190 u16 reg;
191 bool has_index;
192};
193
181static const struct { 194static const struct {
182 const char *name; 195 const char *name;
183 u32 vsync_irq; 196 u32 vsync_irq;
184 u32 framedone_irq; 197 u32 framedone_irq;
185 u32 sync_lost_irq; 198 u32 sync_lost_irq;
199 struct dispc_gamma_desc gamma;
186 struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM]; 200 struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
187} mgr_desc[] = { 201} mgr_desc[] = {
188 [OMAP_DSS_CHANNEL_LCD] = { 202 [OMAP_DSS_CHANNEL_LCD] = {
@@ -190,6 +204,12 @@ static const struct {
190 .vsync_irq = DISPC_IRQ_VSYNC, 204 .vsync_irq = DISPC_IRQ_VSYNC,
191 .framedone_irq = DISPC_IRQ_FRAMEDONE, 205 .framedone_irq = DISPC_IRQ_FRAMEDONE,
192 .sync_lost_irq = DISPC_IRQ_SYNC_LOST, 206 .sync_lost_irq = DISPC_IRQ_SYNC_LOST,
207 .gamma = {
208 .len = 256,
209 .bits = 8,
210 .reg = DISPC_GAMMA_TABLE0,
211 .has_index = true,
212 },
193 .reg_desc = { 213 .reg_desc = {
194 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 0, 0 }, 214 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 0, 0 },
195 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL, 3, 3 }, 215 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL, 3, 3 },
@@ -207,6 +227,12 @@ static const struct {
207 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN, 227 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
208 .framedone_irq = DISPC_IRQ_FRAMEDONETV, 228 .framedone_irq = DISPC_IRQ_FRAMEDONETV,
209 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT, 229 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT,
230 .gamma = {
231 .len = 1024,
232 .bits = 10,
233 .reg = DISPC_GAMMA_TABLE2,
234 .has_index = false,
235 },
210 .reg_desc = { 236 .reg_desc = {
211 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 }, 237 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 },
212 [DISPC_MGR_FLD_STNTFT] = { }, 238 [DISPC_MGR_FLD_STNTFT] = { },
@@ -224,6 +250,12 @@ static const struct {
224 .vsync_irq = DISPC_IRQ_VSYNC2, 250 .vsync_irq = DISPC_IRQ_VSYNC2,
225 .framedone_irq = DISPC_IRQ_FRAMEDONE2, 251 .framedone_irq = DISPC_IRQ_FRAMEDONE2,
226 .sync_lost_irq = DISPC_IRQ_SYNC_LOST2, 252 .sync_lost_irq = DISPC_IRQ_SYNC_LOST2,
253 .gamma = {
254 .len = 256,
255 .bits = 8,
256 .reg = DISPC_GAMMA_TABLE1,
257 .has_index = true,
258 },
227 .reg_desc = { 259 .reg_desc = {
228 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL2, 0, 0 }, 260 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL2, 0, 0 },
229 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL2, 3, 3 }, 261 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL2, 3, 3 },
@@ -241,6 +273,12 @@ static const struct {
241 .vsync_irq = DISPC_IRQ_VSYNC3, 273 .vsync_irq = DISPC_IRQ_VSYNC3,
242 .framedone_irq = DISPC_IRQ_FRAMEDONE3, 274 .framedone_irq = DISPC_IRQ_FRAMEDONE3,
243 .sync_lost_irq = DISPC_IRQ_SYNC_LOST3, 275 .sync_lost_irq = DISPC_IRQ_SYNC_LOST3,
276 .gamma = {
277 .len = 256,
278 .bits = 8,
279 .reg = DISPC_GAMMA_TABLE3,
280 .has_index = true,
281 },
244 .reg_desc = { 282 .reg_desc = {
245 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 }, 283 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 },
246 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 }, 284 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 },
@@ -1084,20 +1122,6 @@ static u32 dispc_ovl_get_burst_size(enum omap_plane plane)
1084 return unit * 8; 1122 return unit * 8;
1085} 1123}
1086 1124
1087void dispc_enable_gamma_table(bool enable)
1088{
1089 /*
1090 * This is partially implemented to support only disabling of
1091 * the gamma table.
1092 */
1093 if (enable) {
1094 DSSWARN("Gamma table enabling for TV not yet supported");
1095 return;
1096 }
1097
1098 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1099}
1100
1101static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) 1125static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
1102{ 1126{
1103 if (channel == OMAP_DSS_CHANNEL_DIGIT) 1127 if (channel == OMAP_DSS_CHANNEL_DIGIT)
@@ -3299,30 +3323,21 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
3299 3323
3300static unsigned long dispc_fclk_rate(void) 3324static unsigned long dispc_fclk_rate(void)
3301{ 3325{
3302 struct dss_pll *pll; 3326 unsigned long r;
3303 unsigned long r = 0; 3327 enum dss_clk_source src;
3328
3329 src = dss_get_dispc_clk_source();
3304 3330
3305 switch (dss_get_dispc_clk_source()) { 3331 if (src == DSS_CLK_SRC_FCK) {
3306 case OMAP_DSS_CLK_SRC_FCK:
3307 r = dss_get_dispc_clk_rate(); 3332 r = dss_get_dispc_clk_rate();
3308 break; 3333 } else {
3309 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3334 struct dss_pll *pll;
3310 pll = dss_pll_find("dsi0"); 3335 unsigned clkout_idx;
3311 if (!pll)
3312 pll = dss_pll_find("video0");
3313 3336
3314 r = pll->cinfo.clkout[0]; 3337 pll = dss_pll_find_by_src(src);
3315 break; 3338 clkout_idx = dss_pll_get_clkout_idx_for_src(src);
3316 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3317 pll = dss_pll_find("dsi1");
3318 if (!pll)
3319 pll = dss_pll_find("video1");
3320 3339
3321 r = pll->cinfo.clkout[0]; 3340 r = pll->cinfo.clkout[clkout_idx];
3322 break;
3323 default:
3324 BUG();
3325 return 0;
3326 } 3341 }
3327 3342
3328 return r; 3343 return r;
@@ -3330,43 +3345,31 @@ static unsigned long dispc_fclk_rate(void)
3330 3345
3331static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) 3346static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3332{ 3347{
3333 struct dss_pll *pll;
3334 int lcd; 3348 int lcd;
3335 unsigned long r; 3349 unsigned long r;
3336 u32 l; 3350 enum dss_clk_source src;
3337
3338 if (dss_mgr_is_lcd(channel)) {
3339 l = dispc_read_reg(DISPC_DIVISORo(channel));
3340 3351
3341 lcd = FLD_GET(l, 23, 16); 3352 /* for TV, LCLK rate is the FCLK rate */
3353 if (!dss_mgr_is_lcd(channel))
3354 return dispc_fclk_rate();
3342 3355
3343 switch (dss_get_lcd_clk_source(channel)) { 3356 src = dss_get_lcd_clk_source(channel);
3344 case OMAP_DSS_CLK_SRC_FCK:
3345 r = dss_get_dispc_clk_rate();
3346 break;
3347 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3348 pll = dss_pll_find("dsi0");
3349 if (!pll)
3350 pll = dss_pll_find("video0");
3351 3357
3352 r = pll->cinfo.clkout[0]; 3358 if (src == DSS_CLK_SRC_FCK) {
3353 break; 3359 r = dss_get_dispc_clk_rate();
3354 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3360 } else {
3355 pll = dss_pll_find("dsi1"); 3361 struct dss_pll *pll;
3356 if (!pll) 3362 unsigned clkout_idx;
3357 pll = dss_pll_find("video1");
3358 3363
3359 r = pll->cinfo.clkout[0]; 3364 pll = dss_pll_find_by_src(src);
3360 break; 3365 clkout_idx = dss_pll_get_clkout_idx_for_src(src);
3361 default:
3362 BUG();
3363 return 0;
3364 }
3365 3366
3366 return r / lcd; 3367 r = pll->cinfo.clkout[clkout_idx];
3367 } else {
3368 return dispc_fclk_rate();
3369 } 3368 }
3369
3370 lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16);
3371
3372 return r / lcd;
3370} 3373}
3371 3374
3372static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) 3375static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3426,15 +3429,14 @@ static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
3426static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) 3429static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
3427{ 3430{
3428 int lcd, pcd; 3431 int lcd, pcd;
3429 enum omap_dss_clk_source lcd_clk_src; 3432 enum dss_clk_source lcd_clk_src;
3430 3433
3431 seq_printf(s, "- %s -\n", mgr_desc[channel].name); 3434 seq_printf(s, "- %s -\n", mgr_desc[channel].name);
3432 3435
3433 lcd_clk_src = dss_get_lcd_clk_source(channel); 3436 lcd_clk_src = dss_get_lcd_clk_source(channel);
3434 3437
3435 seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name, 3438 seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name,
3436 dss_get_generic_clk_source_name(lcd_clk_src), 3439 dss_get_clk_source_name(lcd_clk_src));
3437 dss_feat_get_clk_source_name(lcd_clk_src));
3438 3440
3439 dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd); 3441 dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd);
3440 3442
@@ -3448,16 +3450,15 @@ void dispc_dump_clocks(struct seq_file *s)
3448{ 3450{
3449 int lcd; 3451 int lcd;
3450 u32 l; 3452 u32 l;
3451 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 3453 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
3452 3454
3453 if (dispc_runtime_get()) 3455 if (dispc_runtime_get())
3454 return; 3456 return;
3455 3457
3456 seq_printf(s, "- DISPC -\n"); 3458 seq_printf(s, "- DISPC -\n");
3457 3459
3458 seq_printf(s, "dispc fclk source = %s (%s)\n", 3460 seq_printf(s, "dispc fclk source = %s\n",
3459 dss_get_generic_clk_source_name(dispc_clk_src), 3461 dss_get_clk_source_name(dispc_clk_src));
3460 dss_feat_get_clk_source_name(dispc_clk_src));
3461 3462
3462 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 3463 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
3463 3464
@@ -3814,6 +3815,139 @@ void dispc_disable_sidle(void)
3814 REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ 3815 REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */
3815} 3816}
3816 3817
3818u32 dispc_mgr_gamma_size(enum omap_channel channel)
3819{
3820 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
3821
3822 if (!dispc.feat->has_gamma_table)
3823 return 0;
3824
3825 return gdesc->len;
3826}
3827EXPORT_SYMBOL(dispc_mgr_gamma_size);
3828
3829static void dispc_mgr_write_gamma_table(enum omap_channel channel)
3830{
3831 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
3832 u32 *table = dispc.gamma_table[channel];
3833 unsigned int i;
3834
3835 DSSDBG("%s: channel %d\n", __func__, channel);
3836
3837 for (i = 0; i < gdesc->len; ++i) {
3838 u32 v = table[i];
3839
3840 if (gdesc->has_index)
3841 v |= i << 24;
3842 else if (i == 0)
3843 v |= 1 << 31;
3844
3845 dispc_write_reg(gdesc->reg, v);
3846 }
3847}
3848
3849static void dispc_restore_gamma_tables(void)
3850{
3851 DSSDBG("%s()\n", __func__);
3852
3853 if (!dispc.feat->has_gamma_table)
3854 return;
3855
3856 dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD);
3857
3858 dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_DIGIT);
3859
3860 if (dss_has_feature(FEAT_MGR_LCD2))
3861 dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD2);
3862
3863 if (dss_has_feature(FEAT_MGR_LCD3))
3864 dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD3);
3865}
3866
3867static const struct drm_color_lut dispc_mgr_gamma_default_lut[] = {
3868 { .red = 0, .green = 0, .blue = 0, },
3869 { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, },
3870};
3871
3872void dispc_mgr_set_gamma(enum omap_channel channel,
3873 const struct drm_color_lut *lut,
3874 unsigned int length)
3875{
3876 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
3877 u32 *table = dispc.gamma_table[channel];
3878 uint i;
3879
3880 DSSDBG("%s: channel %d, lut len %u, hw len %u\n", __func__,
3881 channel, length, gdesc->len);
3882
3883 if (!dispc.feat->has_gamma_table)
3884 return;
3885
3886 if (lut == NULL || length < 2) {
3887 lut = dispc_mgr_gamma_default_lut;
3888 length = ARRAY_SIZE(dispc_mgr_gamma_default_lut);
3889 }
3890
3891 for (i = 0; i < length - 1; ++i) {
3892 uint first = i * (gdesc->len - 1) / (length - 1);
3893 uint last = (i + 1) * (gdesc->len - 1) / (length - 1);
3894 uint w = last - first;
3895 u16 r, g, b;
3896 uint j;
3897
3898 if (w == 0)
3899 continue;
3900
3901 for (j = 0; j <= w; j++) {
3902 r = (lut[i].red * (w - j) + lut[i+1].red * j) / w;
3903 g = (lut[i].green * (w - j) + lut[i+1].green * j) / w;
3904 b = (lut[i].blue * (w - j) + lut[i+1].blue * j) / w;
3905
3906 r >>= 16 - gdesc->bits;
3907 g >>= 16 - gdesc->bits;
3908 b >>= 16 - gdesc->bits;
3909
3910 table[first + j] = (r << (gdesc->bits * 2)) |
3911 (g << gdesc->bits) | b;
3912 }
3913 }
3914
3915 if (dispc.is_enabled)
3916 dispc_mgr_write_gamma_table(channel);
3917}
3918EXPORT_SYMBOL(dispc_mgr_set_gamma);
3919
3920static int dispc_init_gamma_tables(void)
3921{
3922 int channel;
3923
3924 if (!dispc.feat->has_gamma_table)
3925 return 0;
3926
3927 for (channel = 0; channel < ARRAY_SIZE(dispc.gamma_table); channel++) {
3928 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
3929 u32 *gt;
3930
3931 if (channel == OMAP_DSS_CHANNEL_LCD2 &&
3932 !dss_has_feature(FEAT_MGR_LCD2))
3933 continue;
3934
3935 if (channel == OMAP_DSS_CHANNEL_LCD3 &&
3936 !dss_has_feature(FEAT_MGR_LCD3))
3937 continue;
3938
3939 gt = devm_kmalloc_array(&dispc.pdev->dev, gdesc->len,
3940 sizeof(u32), GFP_KERNEL);
3941 if (!gt)
3942 return -ENOMEM;
3943
3944 dispc.gamma_table[channel] = gt;
3945
3946 dispc_mgr_set_gamma(channel, NULL, 0);
3947 }
3948 return 0;
3949}
3950
3817static void _omap_dispc_initial_config(void) 3951static void _omap_dispc_initial_config(void)
3818{ 3952{
3819 u32 l; 3953 u32 l;
@@ -3829,8 +3963,15 @@ static void _omap_dispc_initial_config(void)
3829 dispc.core_clk_rate = dispc_fclk_rate(); 3963 dispc.core_clk_rate = dispc_fclk_rate();
3830 } 3964 }
3831 3965
3832 /* FUNCGATED */ 3966 /* Use gamma table mode, instead of palette mode */
3833 if (dss_has_feature(FEAT_FUNCGATED)) 3967 if (dispc.feat->has_gamma_table)
3968 REG_FLD_MOD(DISPC_CONFIG, 1, 3, 3);
3969
3970 /* For older DSS versions (FEAT_FUNCGATED) this enables
3971 * func-clock auto-gating. For newer versions
3972 * (dispc.feat->has_gamma_table) this enables tv-out gamma tables.
3973 */
3974 if (dss_has_feature(FEAT_FUNCGATED) || dispc.feat->has_gamma_table)
3834 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3975 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
3835 3976
3836 dispc_setup_color_conv_coef(); 3977 dispc_setup_color_conv_coef();
@@ -3934,6 +4075,8 @@ static const struct dispc_features omap44xx_dispc_feats = {
3934 .has_writeback = true, 4075 .has_writeback = true,
3935 .supports_double_pixel = true, 4076 .supports_double_pixel = true,
3936 .reverse_ilace_field_order = true, 4077 .reverse_ilace_field_order = true,
4078 .has_gamma_table = true,
4079 .has_gamma_i734_bug = true,
3937}; 4080};
3938 4081
3939static const struct dispc_features omap54xx_dispc_feats = { 4082static const struct dispc_features omap54xx_dispc_feats = {
@@ -3959,6 +4102,8 @@ static const struct dispc_features omap54xx_dispc_feats = {
3959 .has_writeback = true, 4102 .has_writeback = true,
3960 .supports_double_pixel = true, 4103 .supports_double_pixel = true,
3961 .reverse_ilace_field_order = true, 4104 .reverse_ilace_field_order = true,
4105 .has_gamma_table = true,
4106 .has_gamma_i734_bug = true,
3962}; 4107};
3963 4108
3964static int dispc_init_features(struct platform_device *pdev) 4109static int dispc_init_features(struct platform_device *pdev)
@@ -4050,6 +4195,168 @@ void dispc_free_irq(void *dev_id)
4050} 4195}
4051EXPORT_SYMBOL(dispc_free_irq); 4196EXPORT_SYMBOL(dispc_free_irq);
4052 4197
4198/*
4199 * Workaround for errata i734 in DSS dispc
4200 * - LCD1 Gamma Correction Is Not Working When GFX Pipe Is Disabled
4201 *
4202 * For gamma tables to work on LCD1 the GFX plane has to be used at
4203 * least once after DSS HW has come out of reset. The workaround
4204 * sets up a minimal LCD setup with GFX plane and waits for one
4205 * vertical sync irq before disabling the setup and continuing with
4206 * the context restore. The physical outputs are gated during the
4207 * operation. This workaround requires that gamma table's LOADMODE
4208 * is set to 0x2 in DISPC_CONTROL1 register.
4209 *
4210 * For details see:
4211 * OMAP543x Multimedia Device Silicon Revision 2.0 Silicon Errata
4212 * Literature Number: SWPZ037E
4213 * Or some other relevant errata document for the DSS IP version.
4214 */
4215
4216static const struct dispc_errata_i734_data {
4217 struct omap_video_timings timings;
4218 struct omap_overlay_info ovli;
4219 struct omap_overlay_manager_info mgri;
4220 struct dss_lcd_mgr_config lcd_conf;
4221} i734 = {
4222 .timings = {
4223 .x_res = 8, .y_res = 1,
4224 .pixelclock = 16000000,
4225 .hsw = 8, .hfp = 4, .hbp = 4,
4226 .vsw = 1, .vfp = 1, .vbp = 1,
4227 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
4228 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
4229 .interlace = false,
4230 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
4231 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
4232 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
4233 .double_pixel = false,
4234 },
4235 .ovli = {
4236 .screen_width = 1,
4237 .width = 1, .height = 1,
4238 .color_mode = OMAP_DSS_COLOR_RGB24U,
4239 .rotation = OMAP_DSS_ROT_0,
4240 .rotation_type = OMAP_DSS_ROT_DMA,
4241 .mirror = 0,
4242 .pos_x = 0, .pos_y = 0,
4243 .out_width = 0, .out_height = 0,
4244 .global_alpha = 0xff,
4245 .pre_mult_alpha = 0,
4246 .zorder = 0,
4247 },
4248 .mgri = {
4249 .default_color = 0,
4250 .trans_enabled = false,
4251 .partial_alpha_enabled = false,
4252 .cpr_enable = false,
4253 },
4254 .lcd_conf = {
4255 .io_pad_mode = DSS_IO_PAD_MODE_BYPASS,
4256 .stallmode = false,
4257 .fifohandcheck = false,
4258 .clock_info = {
4259 .lck_div = 1,
4260 .pck_div = 2,
4261 },
4262 .video_port_width = 24,
4263 .lcden_sig_polarity = 0,
4264 },
4265};
4266
4267static struct i734_buf {
4268 size_t size;
4269 dma_addr_t paddr;
4270 void *vaddr;
4271} i734_buf;
4272
4273static int dispc_errata_i734_wa_init(void)
4274{
4275 if (!dispc.feat->has_gamma_i734_bug)
4276 return 0;
4277
4278 i734_buf.size = i734.ovli.width * i734.ovli.height *
4279 color_mode_to_bpp(i734.ovli.color_mode) / 8;
4280
4281 i734_buf.vaddr = dma_alloc_writecombine(&dispc.pdev->dev, i734_buf.size,
4282 &i734_buf.paddr, GFP_KERNEL);
4283 if (!i734_buf.vaddr) {
4284 dev_err(&dispc.pdev->dev, "%s: dma_alloc_writecombine failed",
4285 __func__);
4286 return -ENOMEM;
4287 }
4288
4289 return 0;
4290}
4291
4292static void dispc_errata_i734_wa_fini(void)
4293{
4294 if (!dispc.feat->has_gamma_i734_bug)
4295 return;
4296
4297 dma_free_writecombine(&dispc.pdev->dev, i734_buf.size, i734_buf.vaddr,
4298 i734_buf.paddr);
4299}
4300
4301static void dispc_errata_i734_wa(void)
4302{
4303 u32 framedone_irq = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_LCD);
4304 struct omap_overlay_info ovli;
4305 struct dss_lcd_mgr_config lcd_conf;
4306 u32 gatestate;
4307 unsigned int count;
4308
4309 if (!dispc.feat->has_gamma_i734_bug)
4310 return;
4311
4312 gatestate = REG_GET(DISPC_CONFIG, 8, 4);
4313
4314 ovli = i734.ovli;
4315 ovli.paddr = i734_buf.paddr;
4316 lcd_conf = i734.lcd_conf;
4317
4318 /* Gate all LCD1 outputs */
4319 REG_FLD_MOD(DISPC_CONFIG, 0x1f, 8, 4);
4320
4321 /* Setup and enable GFX plane */
4322 dispc_ovl_set_channel_out(OMAP_DSS_GFX, OMAP_DSS_CHANNEL_LCD);
4323 dispc_ovl_setup(OMAP_DSS_GFX, &ovli, false, &i734.timings, false);
4324 dispc_ovl_enable(OMAP_DSS_GFX, true);
4325
4326 /* Set up and enable display manager for LCD1 */
4327 dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri);
4328 dispc_calc_clock_rates(dss_get_dispc_clk_rate(),
4329 &lcd_conf.clock_info);
4330 dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf);
4331 dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.timings);
4332
4333 dispc_clear_irqstatus(framedone_irq);
4334
4335 /* Enable and shut the channel to produce just one frame */
4336 dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, true);
4337 dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, false);
4338
4339 /* Busy wait for framedone. We can't fiddle with irq handlers
4340 * in PM resume. Typically the loop runs less than 5 times and
4341 * waits less than a micro second.
4342 */
4343 count = 0;
4344 while (!(dispc_read_irqstatus() & framedone_irq)) {
4345 if (count++ > 10000) {
4346 dev_err(&dispc.pdev->dev, "%s: framedone timeout\n",
4347 __func__);
4348 break;
4349 }
4350 }
4351 dispc_ovl_enable(OMAP_DSS_GFX, false);
4352
4353 /* Clear all irq bits before continuing */
4354 dispc_clear_irqstatus(0xffffffff);
4355
4356 /* Restore the original state to LCD1 output gates */
4357 REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4);
4358}
4359
4053/* DISPC HW IP initialisation */ 4360/* DISPC HW IP initialisation */
4054static int dispc_bind(struct device *dev, struct device *master, void *data) 4361static int dispc_bind(struct device *dev, struct device *master, void *data)
4055{ 4362{
@@ -4067,6 +4374,10 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
4067 if (r) 4374 if (r)
4068 return r; 4375 return r;
4069 4376
4377 r = dispc_errata_i734_wa_init();
4378 if (r)
4379 return r;
4380
4070 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 4381 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
4071 if (!dispc_mem) { 4382 if (!dispc_mem) {
4072 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 4383 DSSERR("can't get IORESOURCE_MEM DISPC\n");
@@ -4100,6 +4411,10 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
4100 } 4411 }
4101 } 4412 }
4102 4413
4414 r = dispc_init_gamma_tables();
4415 if (r)
4416 return r;
4417
4103 pm_runtime_enable(&pdev->dev); 4418 pm_runtime_enable(&pdev->dev);
4104 4419
4105 r = dispc_runtime_get(); 4420 r = dispc_runtime_get();
@@ -4127,6 +4442,8 @@ static void dispc_unbind(struct device *dev, struct device *master,
4127 void *data) 4442 void *data)
4128{ 4443{
4129 pm_runtime_disable(dev); 4444 pm_runtime_disable(dev);
4445
4446 dispc_errata_i734_wa_fini();
4130} 4447}
4131 4448
4132static const struct component_ops dispc_component_ops = { 4449static const struct component_ops dispc_component_ops = {
@@ -4169,7 +4486,11 @@ static int dispc_runtime_resume(struct device *dev)
4169 if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) { 4486 if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
4170 _omap_dispc_initial_config(); 4487 _omap_dispc_initial_config();
4171 4488
4489 dispc_errata_i734_wa();
4490
4172 dispc_restore_context(); 4491 dispc_restore_context();
4492
4493 dispc_restore_gamma_tables();
4173 } 4494 }
4174 4495
4175 dispc.is_enabled = true; 4496 dispc.is_enabled = true;
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.h b/drivers/gpu/drm/omapdrm/dss/dispc.h
index 483744223dd1..bc1d8126ee87 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.h
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.h
@@ -42,6 +42,11 @@
42#define DISPC_MSTANDBY_CTRL 0x0858 42#define DISPC_MSTANDBY_CTRL 0x0858
43#define DISPC_GLOBAL_MFLAG_ATTRIBUTE 0x085C 43#define DISPC_GLOBAL_MFLAG_ATTRIBUTE 0x085C
44 44
45#define DISPC_GAMMA_TABLE0 0x0630
46#define DISPC_GAMMA_TABLE1 0x0634
47#define DISPC_GAMMA_TABLE2 0x0638
48#define DISPC_GAMMA_TABLE3 0x0850
49
45/* DISPC overlay registers */ 50/* DISPC overlay registers */
46#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ 51#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
47 DISPC_BA0_OFFSET(n)) 52 DISPC_BA0_OFFSET(n))
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc_coefs.c b/drivers/gpu/drm/omapdrm/dss/dispc_coefs.c
index 038c15b04215..34fad2376f8d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc_coefs.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc_coefs.c
@@ -18,8 +18,8 @@
18 */ 18 */
19 19
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <video/omapdss.h>
22 21
22#include "omapdss.h"
23#include "dispc.h" 23#include "dispc.h"
24 24
25static const struct dispc_coef coef3_M8[8] = { 25static const struct dispc_coef coef3_M8[8] = {
diff --git a/drivers/gpu/drm/omapdrm/dss/display.c b/drivers/gpu/drm/omapdrm/dss/display.c
index 9f3dd09b0a6c..8dcdd7cf9937 100644
--- a/drivers/gpu/drm/omapdrm/dss/display.c
+++ b/drivers/gpu/drm/omapdrm/dss/display.c
@@ -28,7 +28,7 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/of.h> 29#include <linux/of.h>
30 30
31#include <video/omapdss.h> 31#include "omapdss.h"
32#include "dss.h" 32#include "dss.h"
33#include "dss_features.h" 33#include "dss_features.h"
34 34
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 97ea60257884..b268295b76cf 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -34,17 +34,15 @@
34#include <linux/clk.h> 34#include <linux/clk.h>
35#include <linux/component.h> 35#include <linux/component.h>
36 36
37#include <video/omapdss.h> 37#include "omapdss.h"
38
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42#define HSDIV_DISPC 0
43
44struct dpi_data { 41struct dpi_data {
45 struct platform_device *pdev; 42 struct platform_device *pdev;
46 43
47 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
45 enum dss_clk_source clk_src;
48 struct dss_pll *pll; 46 struct dss_pll *pll;
49 47
50 struct mutex lock; 48 struct mutex lock;
@@ -69,7 +67,7 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
69 return dev_get_drvdata(&pdev->dev); 67 return dev_get_drvdata(&pdev->dev);
70} 68}
71 69
72static struct dss_pll *dpi_get_pll(enum omap_channel channel) 70static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
73{ 71{
74 /* 72 /*
75 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL 73 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
@@ -83,64 +81,51 @@ static struct dss_pll *dpi_get_pll(enum omap_channel channel)
83 case OMAPDSS_VER_OMAP3630: 81 case OMAPDSS_VER_OMAP3630:
84 case OMAPDSS_VER_AM35xx: 82 case OMAPDSS_VER_AM35xx:
85 case OMAPDSS_VER_AM43xx: 83 case OMAPDSS_VER_AM43xx:
86 return NULL; 84 return DSS_CLK_SRC_FCK;
87 85
88 case OMAPDSS_VER_OMAP4430_ES1: 86 case OMAPDSS_VER_OMAP4430_ES1:
89 case OMAPDSS_VER_OMAP4430_ES2: 87 case OMAPDSS_VER_OMAP4430_ES2:
90 case OMAPDSS_VER_OMAP4: 88 case OMAPDSS_VER_OMAP4:
91 switch (channel) { 89 switch (channel) {
92 case OMAP_DSS_CHANNEL_LCD: 90 case OMAP_DSS_CHANNEL_LCD:
93 return dss_pll_find("dsi0"); 91 return DSS_CLK_SRC_PLL1_1;
94 case OMAP_DSS_CHANNEL_LCD2: 92 case OMAP_DSS_CHANNEL_LCD2:
95 return dss_pll_find("dsi1"); 93 return DSS_CLK_SRC_PLL2_1;
96 default: 94 default:
97 return NULL; 95 return DSS_CLK_SRC_FCK;
98 } 96 }
99 97
100 case OMAPDSS_VER_OMAP5: 98 case OMAPDSS_VER_OMAP5:
101 switch (channel) { 99 switch (channel) {
102 case OMAP_DSS_CHANNEL_LCD: 100 case OMAP_DSS_CHANNEL_LCD:
103 return dss_pll_find("dsi0"); 101 return DSS_CLK_SRC_PLL1_1;
104 case OMAP_DSS_CHANNEL_LCD3: 102 case OMAP_DSS_CHANNEL_LCD3:
105 return dss_pll_find("dsi1"); 103 return DSS_CLK_SRC_PLL2_1;
104 case OMAP_DSS_CHANNEL_LCD2:
106 default: 105 default:
107 return NULL; 106 return DSS_CLK_SRC_FCK;
108 } 107 }
109 108
110 case OMAPDSS_VER_DRA7xx: 109 case OMAPDSS_VER_DRA7xx:
111 switch (channel) { 110 switch (channel) {
112 case OMAP_DSS_CHANNEL_LCD: 111 case OMAP_DSS_CHANNEL_LCD:
112 return DSS_CLK_SRC_PLL1_1;
113 case OMAP_DSS_CHANNEL_LCD2: 113 case OMAP_DSS_CHANNEL_LCD2:
114 return dss_pll_find("video0"); 114 return DSS_CLK_SRC_PLL1_3;
115 case OMAP_DSS_CHANNEL_LCD3: 115 case OMAP_DSS_CHANNEL_LCD3:
116 return dss_pll_find("video1"); 116 return DSS_CLK_SRC_PLL2_1;
117 default: 117 default:
118 return NULL; 118 return DSS_CLK_SRC_FCK;
119 } 119 }
120 120
121 default: 121 default:
122 return NULL; 122 return DSS_CLK_SRC_FCK;
123 }
124}
125
126static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
127{
128 switch (channel) {
129 case OMAP_DSS_CHANNEL_LCD:
130 return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
131 case OMAP_DSS_CHANNEL_LCD2:
132 return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
133 case OMAP_DSS_CHANNEL_LCD3:
134 return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
135 default:
136 /* this shouldn't happen */
137 WARN_ON(1);
138 return OMAP_DSS_CLK_SRC_FCK;
139 } 123 }
140} 124}
141 125
142struct dpi_clk_calc_ctx { 126struct dpi_clk_calc_ctx {
143 struct dss_pll *pll; 127 struct dss_pll *pll;
128 unsigned clkout_idx;
144 129
145 /* inputs */ 130 /* inputs */
146 131
@@ -148,7 +133,7 @@ struct dpi_clk_calc_ctx {
148 133
149 /* outputs */ 134 /* outputs */
150 135
151 struct dss_pll_clock_info dsi_cinfo; 136 struct dss_pll_clock_info pll_cinfo;
152 unsigned long fck; 137 unsigned long fck;
153 struct dispc_clock_info dispc_cinfo; 138 struct dispc_clock_info dispc_cinfo;
154}; 139};
@@ -193,8 +178,8 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
193 if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000) 178 if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
194 return false; 179 return false;
195 180
196 ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc; 181 ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
197 ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc; 182 ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
198 183
199 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, 184 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
200 dpi_calc_dispc_cb, ctx); 185 dpi_calc_dispc_cb, ctx);
@@ -207,12 +192,12 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
207{ 192{
208 struct dpi_clk_calc_ctx *ctx = data; 193 struct dpi_clk_calc_ctx *ctx = data;
209 194
210 ctx->dsi_cinfo.n = n; 195 ctx->pll_cinfo.n = n;
211 ctx->dsi_cinfo.m = m; 196 ctx->pll_cinfo.m = m;
212 ctx->dsi_cinfo.fint = fint; 197 ctx->pll_cinfo.fint = fint;
213 ctx->dsi_cinfo.clkdco = clkdco; 198 ctx->pll_cinfo.clkdco = clkdco;
214 199
215 return dss_pll_hsdiv_calc(ctx->pll, clkdco, 200 return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
216 ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), 201 ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
217 dpi_calc_hsdiv_cb, ctx); 202 dpi_calc_hsdiv_cb, ctx);
218} 203}
@@ -227,25 +212,39 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
227 dpi_calc_dispc_cb, ctx); 212 dpi_calc_dispc_cb, ctx);
228} 213}
229 214
230static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck, 215static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
231 struct dpi_clk_calc_ctx *ctx) 216 struct dpi_clk_calc_ctx *ctx)
232{ 217{
233 unsigned long clkin; 218 unsigned long clkin;
234 unsigned long pll_min, pll_max;
235 219
236 memset(ctx, 0, sizeof(*ctx)); 220 memset(ctx, 0, sizeof(*ctx));
237 ctx->pll = dpi->pll; 221 ctx->pll = dpi->pll;
238 ctx->pck_min = pck - 1000; 222 ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
239 ctx->pck_max = pck + 1000;
240 223
241 pll_min = 0; 224 clkin = clk_get_rate(dpi->pll->clkin);
242 pll_max = 0;
243 225
244 clkin = clk_get_rate(ctx->pll->clkin); 226 if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
227 unsigned long pll_min, pll_max;
245 228
246 return dss_pll_calc(ctx->pll, clkin, 229 ctx->pck_min = pck - 1000;
247 pll_min, pll_max, 230 ctx->pck_max = pck + 1000;
248 dpi_calc_pll_cb, ctx); 231
232 pll_min = 0;
233 pll_max = 0;
234
235 return dss_pll_calc_a(ctx->pll, clkin,
236 pll_min, pll_max,
237 dpi_calc_pll_cb, ctx);
238 } else { /* DSS_PLL_TYPE_B */
239 dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
240
241 ctx->dispc_cinfo.lck_div = 1;
242 ctx->dispc_cinfo.pck_div = 1;
243 ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
244 ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
245
246 return true;
247 }
249} 248}
250 249
251static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) 250static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
@@ -279,7 +278,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
279 278
280 279
281 280
282static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel, 281static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
283 unsigned long pck_req, unsigned long *fck, int *lck_div, 282 unsigned long pck_req, unsigned long *fck, int *lck_div,
284 int *pck_div) 283 int *pck_div)
285{ 284{
@@ -287,20 +286,19 @@ static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
287 int r; 286 int r;
288 bool ok; 287 bool ok;
289 288
290 ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx); 289 ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
291 if (!ok) 290 if (!ok)
292 return -EINVAL; 291 return -EINVAL;
293 292
294 r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo); 293 r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
295 if (r) 294 if (r)
296 return r; 295 return r;
297 296
298 dss_select_lcd_clk_source(channel, 297 dss_select_lcd_clk_source(channel, dpi->clk_src);
299 dpi_get_alt_clk_src(channel));
300 298
301 dpi->mgr_config.clock_info = ctx.dispc_cinfo; 299 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
302 300
303 *fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC]; 301 *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
304 *lck_div = ctx.dispc_cinfo.lck_div; 302 *lck_div = ctx.dispc_cinfo.lck_div;
305 *pck_div = ctx.dispc_cinfo.pck_div; 303 *pck_div = ctx.dispc_cinfo.pck_div;
306 304
@@ -342,7 +340,7 @@ static int dpi_set_mode(struct dpi_data *dpi)
342 int r = 0; 340 int r = 0;
343 341
344 if (dpi->pll) 342 if (dpi->pll)
345 r = dpi_set_dsi_clk(dpi, channel, t->pixelclock, &fck, 343 r = dpi_set_pll_clk(dpi, channel, t->pixelclock, &fck,
346 &lck_div, &pck_div); 344 &lck_div, &pck_div);
347 else 345 else
348 r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck, 346 r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck,
@@ -419,7 +417,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
419 if (dpi->pll) { 417 if (dpi->pll) {
420 r = dss_pll_enable(dpi->pll); 418 r = dss_pll_enable(dpi->pll);
421 if (r) 419 if (r)
422 goto err_dsi_pll_init; 420 goto err_pll_init;
423 } 421 }
424 422
425 r = dpi_set_mode(dpi); 423 r = dpi_set_mode(dpi);
@@ -442,7 +440,7 @@ err_mgr_enable:
442err_set_mode: 440err_set_mode:
443 if (dpi->pll) 441 if (dpi->pll)
444 dss_pll_disable(dpi->pll); 442 dss_pll_disable(dpi->pll);
445err_dsi_pll_init: 443err_pll_init:
446err_src_sel: 444err_src_sel:
447 dispc_runtime_put(); 445 dispc_runtime_put();
448err_get_dispc: 446err_get_dispc:
@@ -465,7 +463,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
465 dss_mgr_disable(channel); 463 dss_mgr_disable(channel);
466 464
467 if (dpi->pll) { 465 if (dpi->pll) {
468 dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); 466 dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
469 dss_pll_disable(dpi->pll); 467 dss_pll_disable(dpi->pll);
470 } 468 }
471 469
@@ -524,11 +522,11 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
524 return -EINVAL; 522 return -EINVAL;
525 523
526 if (dpi->pll) { 524 if (dpi->pll) {
527 ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx); 525 ok = dpi_pll_clk_calc(dpi, timings->pixelclock, &ctx);
528 if (!ok) 526 if (!ok)
529 return -EINVAL; 527 return -EINVAL;
530 528
531 fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC]; 529 fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
532 } else { 530 } else {
533 ok = dpi_dss_clk_calc(timings->pixelclock, &ctx); 531 ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
534 if (!ok) 532 if (!ok)
@@ -558,7 +556,7 @@ static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
558 mutex_unlock(&dpi->lock); 556 mutex_unlock(&dpi->lock);
559} 557}
560 558
561static int dpi_verify_dsi_pll(struct dss_pll *pll) 559static int dpi_verify_pll(struct dss_pll *pll)
562{ 560{
563 int r; 561 int r;
564 562
@@ -602,16 +600,14 @@ static void dpi_init_pll(struct dpi_data *dpi)
602 if (dpi->pll) 600 if (dpi->pll)
603 return; 601 return;
604 602
605 pll = dpi_get_pll(dpi->output.dispc_channel); 603 dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);
604
605 pll = dss_pll_find_by_src(dpi->clk_src);
606 if (!pll) 606 if (!pll)
607 return; 607 return;
608 608
609 /* On DRA7 we need to set a mux to use the PLL */ 609 if (dpi_verify_pll(pll)) {
610 if (omapdss_get_version() == OMAPDSS_VER_DRA7xx) 610 DSSWARN("PLL not operational\n");
611 dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel);
612
613 if (dpi_verify_dsi_pll(pll)) {
614 DSSWARN("DSI PLL not operational\n");
615 return; 611 return;
616 } 612 }
617 613
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 56c43f355ce3..e1be5e795cd8 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -42,9 +42,9 @@
42#include <linux/of_platform.h> 42#include <linux/of_platform.h>
43#include <linux/component.h> 43#include <linux/component.h>
44 44
45#include <video/omapdss.h>
46#include <video/mipi_display.h> 45#include <video/mipi_display.h>
47 46
47#include "omapdss.h"
48#include "dss.h" 48#include "dss.h"
49#include "dss_features.h" 49#include "dss_features.h"
50 50
@@ -1261,7 +1261,7 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1261 unsigned long r; 1261 unsigned long r;
1262 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1262 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1263 1263
1264 if (dss_get_dsi_clk_source(dsi->module_id) == OMAP_DSS_CLK_SRC_FCK) { 1264 if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) {
1265 /* DSI FCLK source is DSS_CLK_FCK */ 1265 /* DSI FCLK source is DSS_CLK_FCK */
1266 r = clk_get_rate(dsi->dss_clk); 1266 r = clk_get_rate(dsi->dss_clk);
1267 } else { 1267 } else {
@@ -1474,7 +1474,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1474{ 1474{
1475 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1475 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1476 struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo; 1476 struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
1477 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; 1477 enum dss_clk_source dispc_clk_src, dsi_clk_src;
1478 int dsi_module = dsi->module_id; 1478 int dsi_module = dsi->module_id;
1479 struct dss_pll *pll = &dsi->pll; 1479 struct dss_pll *pll = &dsi->pll;
1480 1480
@@ -1494,28 +1494,27 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1494 cinfo->clkdco, cinfo->m); 1494 cinfo->clkdco, cinfo->m);
1495 1495
1496 seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n", 1496 seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
1497 dss_feat_get_clk_source_name(dsi_module == 0 ? 1497 dss_get_clk_source_name(dsi_module == 0 ?
1498 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : 1498 DSS_CLK_SRC_PLL1_1 :
1499 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), 1499 DSS_CLK_SRC_PLL2_1),
1500 cinfo->clkout[HSDIV_DISPC], 1500 cinfo->clkout[HSDIV_DISPC],
1501 cinfo->mX[HSDIV_DISPC], 1501 cinfo->mX[HSDIV_DISPC],
1502 dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? 1502 dispc_clk_src == DSS_CLK_SRC_FCK ?
1503 "off" : "on"); 1503 "off" : "on");
1504 1504
1505 seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n", 1505 seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
1506 dss_feat_get_clk_source_name(dsi_module == 0 ? 1506 dss_get_clk_source_name(dsi_module == 0 ?
1507 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : 1507 DSS_CLK_SRC_PLL1_2 :
1508 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), 1508 DSS_CLK_SRC_PLL2_2),
1509 cinfo->clkout[HSDIV_DSI], 1509 cinfo->clkout[HSDIV_DSI],
1510 cinfo->mX[HSDIV_DSI], 1510 cinfo->mX[HSDIV_DSI],
1511 dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? 1511 dsi_clk_src == DSS_CLK_SRC_FCK ?
1512 "off" : "on"); 1512 "off" : "on");
1513 1513
1514 seq_printf(s, "- DSI%d -\n", dsi_module + 1); 1514 seq_printf(s, "- DSI%d -\n", dsi_module + 1);
1515 1515
1516 seq_printf(s, "dsi fclk source = %s (%s)\n", 1516 seq_printf(s, "dsi fclk source = %s\n",
1517 dss_get_generic_clk_source_name(dsi_clk_src), 1517 dss_get_clk_source_name(dsi_clk_src));
1518 dss_feat_get_clk_source_name(dsi_clk_src));
1519 1518
1520 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); 1519 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
1521 1520
@@ -4101,8 +4100,8 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
4101 int r; 4100 int r;
4102 4101
4103 dss_select_lcd_clk_source(channel, dsi->module_id == 0 ? 4102 dss_select_lcd_clk_source(channel, dsi->module_id == 0 ?
4104 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : 4103 DSS_CLK_SRC_PLL1_1 :
4105 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC); 4104 DSS_CLK_SRC_PLL2_1);
4106 4105
4107 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4106 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4108 r = dss_mgr_register_framedone_handler(channel, 4107 r = dss_mgr_register_framedone_handler(channel,
@@ -4149,7 +4148,7 @@ err1:
4149 dss_mgr_unregister_framedone_handler(channel, 4148 dss_mgr_unregister_framedone_handler(channel,
4150 dsi_framedone_irq_callback, dsidev); 4149 dsi_framedone_irq_callback, dsidev);
4151err: 4150err:
4152 dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); 4151 dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
4153 return r; 4152 return r;
4154} 4153}
4155 4154
@@ -4162,7 +4161,7 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
4162 dss_mgr_unregister_framedone_handler(channel, 4161 dss_mgr_unregister_framedone_handler(channel,
4163 dsi_framedone_irq_callback, dsidev); 4162 dsi_framedone_irq_callback, dsidev);
4164 4163
4165 dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); 4164 dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
4166} 4165}
4167 4166
4168static int dsi_configure_dsi_clocks(struct platform_device *dsidev) 4167static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
@@ -4196,8 +4195,8 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
4196 goto err1; 4195 goto err1;
4197 4196
4198 dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ? 4197 dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
4199 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : 4198 DSS_CLK_SRC_PLL1_2 :
4200 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI); 4199 DSS_CLK_SRC_PLL2_2);
4201 4200
4202 DSSDBG("PLL OK\n"); 4201 DSSDBG("PLL OK\n");
4203 4202
@@ -4229,7 +4228,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
4229err3: 4228err3:
4230 dsi_cio_uninit(dsidev); 4229 dsi_cio_uninit(dsidev);
4231err2: 4230err2:
4232 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4231 dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
4233err1: 4232err1:
4234 dss_pll_disable(&dsi->pll); 4233 dss_pll_disable(&dsi->pll);
4235err0: 4234err0:
@@ -4251,7 +4250,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev,
4251 dsi_vc_enable(dsidev, 2, 0); 4250 dsi_vc_enable(dsidev, 2, 0);
4252 dsi_vc_enable(dsidev, 3, 0); 4251 dsi_vc_enable(dsidev, 3, 0);
4253 4252
4254 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4253 dss_select_dsi_clk_source(dsi->module_id, DSS_CLK_SRC_FCK);
4255 dsi_cio_uninit(dsidev); 4254 dsi_cio_uninit(dsidev);
4256 dsi_pll_uninit(dsidev, disconnect_lanes); 4255 dsi_pll_uninit(dsidev, disconnect_lanes);
4257} 4256}
@@ -4452,7 +4451,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
4452 ctx->dsi_cinfo.fint = fint; 4451 ctx->dsi_cinfo.fint = fint;
4453 ctx->dsi_cinfo.clkdco = clkdco; 4452 ctx->dsi_cinfo.clkdco = clkdco;
4454 4453
4455 return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, 4454 return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
4456 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), 4455 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
4457 dsi_cm_calc_hsdiv_cb, ctx); 4456 dsi_cm_calc_hsdiv_cb, ctx);
4458} 4457}
@@ -4491,7 +4490,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
4491 pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); 4490 pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
4492 pll_max = cfg->hs_clk_max * 4; 4491 pll_max = cfg->hs_clk_max * 4;
4493 4492
4494 return dss_pll_calc(ctx->pll, clkin, 4493 return dss_pll_calc_a(ctx->pll, clkin,
4495 pll_min, pll_max, 4494 pll_min, pll_max,
4496 dsi_cm_calc_pll_cb, ctx); 4495 dsi_cm_calc_pll_cb, ctx);
4497} 4496}
@@ -4750,7 +4749,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
4750 ctx->dsi_cinfo.fint = fint; 4749 ctx->dsi_cinfo.fint = fint;
4751 ctx->dsi_cinfo.clkdco = clkdco; 4750 ctx->dsi_cinfo.clkdco = clkdco;
4752 4751
4753 return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min, 4752 return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
4754 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), 4753 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
4755 dsi_vm_calc_hsdiv_cb, ctx); 4754 dsi_vm_calc_hsdiv_cb, ctx);
4756} 4755}
@@ -4792,7 +4791,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
4792 pll_max = byteclk_max * 4 * 4; 4791 pll_max = byteclk_max * 4 * 4;
4793 } 4792 }
4794 4793
4795 return dss_pll_calc(ctx->pll, clkin, 4794 return dss_pll_calc_a(ctx->pll, clkin,
4796 pll_min, pll_max, 4795 pll_min, pll_max,
4797 dsi_vm_calc_pll_cb, ctx); 4796 dsi_vm_calc_pll_cb, ctx);
4798} 4797}
@@ -5138,6 +5137,8 @@ static const struct dss_pll_ops dsi_pll_ops = {
5138}; 5137};
5139 5138
5140static const struct dss_pll_hw dss_omap3_dsi_pll_hw = { 5139static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
5140 .type = DSS_PLL_TYPE_A,
5141
5141 .n_max = (1 << 7) - 1, 5142 .n_max = (1 << 7) - 1,
5142 .m_max = (1 << 11) - 1, 5143 .m_max = (1 << 11) - 1,
5143 .mX_max = (1 << 4) - 1, 5144 .mX_max = (1 << 4) - 1,
@@ -5163,6 +5164,8 @@ static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
5163}; 5164};
5164 5165
5165static const struct dss_pll_hw dss_omap4_dsi_pll_hw = { 5166static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
5167 .type = DSS_PLL_TYPE_A,
5168
5166 .n_max = (1 << 8) - 1, 5169 .n_max = (1 << 8) - 1,
5167 .m_max = (1 << 12) - 1, 5170 .m_max = (1 << 12) - 1,
5168 .mX_max = (1 << 5) - 1, 5171 .mX_max = (1 << 5) - 1,
@@ -5188,6 +5191,8 @@ static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
5188}; 5191};
5189 5192
5190static const struct dss_pll_hw dss_omap5_dsi_pll_hw = { 5193static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
5194 .type = DSS_PLL_TYPE_A,
5195
5191 .n_max = (1 << 8) - 1, 5196 .n_max = (1 << 8) - 1,
5192 .m_max = (1 << 12) - 1, 5197 .m_max = (1 << 12) - 1,
5193 .mX_max = (1 << 5) - 1, 5198 .mX_max = (1 << 5) - 1,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c b/drivers/gpu/drm/omapdrm/dss/dss-of.c
index bf407b6ba15c..e256d879b25c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss-of.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c
@@ -18,8 +18,7 @@
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20 20
21#include <video/omapdss.h> 21#include "omapdss.h"
22
23#include "dss.h" 22#include "dss.h"
24 23
25struct device_node * 24struct device_node *
@@ -126,15 +125,16 @@ u32 dss_of_port_get_port_number(struct device_node *port)
126 125
127static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) 126static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
128{ 127{
129 struct device_node *np; 128 struct device_node *np, *np_parent;
130 129
131 np = of_parse_phandle(node, "remote-endpoint", 0); 130 np = of_parse_phandle(node, "remote-endpoint", 0);
132 if (!np) 131 if (!np)
133 return NULL; 132 return NULL;
134 133
135 np = of_get_next_parent(np); 134 np_parent = of_get_next_parent(np);
135 of_node_put(np);
136 136
137 return np; 137 return np_parent;
138} 138}
139 139
140struct device_node * 140struct device_node *
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 3303cfad4838..14887d5b02e5 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -42,8 +42,7 @@
42#include <linux/suspend.h> 42#include <linux/suspend.h>
43#include <linux/component.h> 43#include <linux/component.h>
44 44
45#include <video/omapdss.h> 45#include "omapdss.h"
46
47#include "dss.h" 46#include "dss.h"
48#include "dss_features.h" 47#include "dss_features.h"
49 48
@@ -76,6 +75,8 @@ struct dss_features {
76 const enum omap_display_type *ports; 75 const enum omap_display_type *ports;
77 int num_ports; 76 int num_ports;
78 int (*dpi_select_source)(int port, enum omap_channel channel); 77 int (*dpi_select_source)(int port, enum omap_channel channel);
78 int (*select_lcd_source)(enum omap_channel channel,
79 enum dss_clk_source clk_src);
79}; 80};
80 81
81static struct { 82static struct {
@@ -92,9 +93,9 @@ static struct {
92 unsigned long cache_prate; 93 unsigned long cache_prate;
93 struct dispc_clock_info cache_dispc_cinfo; 94 struct dispc_clock_info cache_dispc_cinfo;
94 95
95 enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI]; 96 enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
96 enum omap_dss_clk_source dispc_clk_source; 97 enum dss_clk_source dispc_clk_source;
97 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; 98 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
98 99
99 bool ctx_valid; 100 bool ctx_valid;
100 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 101 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
@@ -106,11 +107,14 @@ static struct {
106} dss; 107} dss;
107 108
108static const char * const dss_generic_clk_source_names[] = { 109static const char * const dss_generic_clk_source_names[] = {
109 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", 110 [DSS_CLK_SRC_FCK] = "FCK",
110 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", 111 [DSS_CLK_SRC_PLL1_1] = "PLL1:1",
111 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", 112 [DSS_CLK_SRC_PLL1_2] = "PLL1:2",
112 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC", 113 [DSS_CLK_SRC_PLL1_3] = "PLL1:3",
113 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", 114 [DSS_CLK_SRC_PLL2_1] = "PLL2:1",
115 [DSS_CLK_SRC_PLL2_2] = "PLL2:2",
116 [DSS_CLK_SRC_PLL2_3] = "PLL2:3",
117 [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL",
114}; 118};
115 119
116static bool dss_initialized; 120static bool dss_initialized;
@@ -203,68 +207,70 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
203 1 << shift, val << shift); 207 1 << shift, val << shift);
204} 208}
205 209
206void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id, 210static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
207 enum omap_channel channel) 211 enum omap_channel channel)
208{ 212{
209 unsigned shift, val; 213 unsigned shift, val;
210 214
211 if (!dss.syscon_pll_ctrl) 215 if (!dss.syscon_pll_ctrl)
212 return; 216 return -EINVAL;
213 217
214 switch (channel) { 218 switch (channel) {
215 case OMAP_DSS_CHANNEL_LCD: 219 case OMAP_DSS_CHANNEL_LCD:
216 shift = 3; 220 shift = 3;
217 221
218 switch (pll_id) { 222 switch (clk_src) {
219 case DSS_PLL_VIDEO1: 223 case DSS_CLK_SRC_PLL1_1:
220 val = 0; break; 224 val = 0; break;
221 case DSS_PLL_HDMI: 225 case DSS_CLK_SRC_HDMI_PLL:
222 val = 1; break; 226 val = 1; break;
223 default: 227 default:
224 DSSERR("error in PLL mux config for LCD\n"); 228 DSSERR("error in PLL mux config for LCD\n");
225 return; 229 return -EINVAL;
226 } 230 }
227 231
228 break; 232 break;
229 case OMAP_DSS_CHANNEL_LCD2: 233 case OMAP_DSS_CHANNEL_LCD2:
230 shift = 5; 234 shift = 5;
231 235
232 switch (pll_id) { 236 switch (clk_src) {
233 case DSS_PLL_VIDEO1: 237 case DSS_CLK_SRC_PLL1_3:
234 val = 0; break; 238 val = 0; break;
235 case DSS_PLL_VIDEO2: 239 case DSS_CLK_SRC_PLL2_3:
236 val = 1; break; 240 val = 1; break;
237 case DSS_PLL_HDMI: 241 case DSS_CLK_SRC_HDMI_PLL:
238 val = 2; break; 242 val = 2; break;
239 default: 243 default:
240 DSSERR("error in PLL mux config for LCD2\n"); 244 DSSERR("error in PLL mux config for LCD2\n");
241 return; 245 return -EINVAL;
242 } 246 }
243 247
244 break; 248 break;
245 case OMAP_DSS_CHANNEL_LCD3: 249 case OMAP_DSS_CHANNEL_LCD3:
246 shift = 7; 250 shift = 7;
247 251
248 switch (pll_id) { 252 switch (clk_src) {
249 case DSS_PLL_VIDEO1: 253 case DSS_CLK_SRC_PLL2_1:
250 val = 1; break;
251 case DSS_PLL_VIDEO2:
252 val = 0; break; 254 val = 0; break;
253 case DSS_PLL_HDMI: 255 case DSS_CLK_SRC_PLL1_3:
256 val = 1; break;
257 case DSS_CLK_SRC_HDMI_PLL:
254 val = 2; break; 258 val = 2; break;
255 default: 259 default:
256 DSSERR("error in PLL mux config for LCD3\n"); 260 DSSERR("error in PLL mux config for LCD3\n");
257 return; 261 return -EINVAL;
258 } 262 }
259 263
260 break; 264 break;
261 default: 265 default:
262 DSSERR("error in PLL mux config\n"); 266 DSSERR("error in PLL mux config\n");
263 return; 267 return -EINVAL;
264 } 268 }
265 269
266 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, 270 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
267 0x3 << shift, val << shift); 271 0x3 << shift, val << shift);
272
273 return 0;
268} 274}
269 275
270void dss_sdi_init(int datapairs) 276void dss_sdi_init(int datapairs)
@@ -354,14 +360,14 @@ void dss_sdi_disable(void)
354 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 360 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
355} 361}
356 362
357const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src) 363const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
358{ 364{
359 return dss_generic_clk_source_names[clk_src]; 365 return dss_generic_clk_source_names[clk_src];
360} 366}
361 367
362void dss_dump_clocks(struct seq_file *s) 368void dss_dump_clocks(struct seq_file *s)
363{ 369{
364 const char *fclk_name, *fclk_real_name; 370 const char *fclk_name;
365 unsigned long fclk_rate; 371 unsigned long fclk_rate;
366 372
367 if (dss_runtime_get()) 373 if (dss_runtime_get())
@@ -369,12 +375,11 @@ void dss_dump_clocks(struct seq_file *s)
369 375
370 seq_printf(s, "- DSS -\n"); 376 seq_printf(s, "- DSS -\n");
371 377
372 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK); 378 fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
373 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
374 fclk_rate = clk_get_rate(dss.dss_clk); 379 fclk_rate = clk_get_rate(dss.dss_clk);
375 380
376 seq_printf(s, "%s (%s) = %lu\n", 381 seq_printf(s, "%s = %lu\n",
377 fclk_name, fclk_real_name, 382 fclk_name,
378 fclk_rate); 383 fclk_rate);
379 384
380 dss_runtime_put(); 385 dss_runtime_put();
@@ -403,19 +408,42 @@ static void dss_dump_regs(struct seq_file *s)
403#undef DUMPREG 408#undef DUMPREG
404} 409}
405 410
406static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) 411static int dss_get_channel_index(enum omap_channel channel)
412{
413 switch (channel) {
414 case OMAP_DSS_CHANNEL_LCD:
415 return 0;
416 case OMAP_DSS_CHANNEL_LCD2:
417 return 1;
418 case OMAP_DSS_CHANNEL_LCD3:
419 return 2;
420 default:
421 WARN_ON(1);
422 return 0;
423 }
424}
425
426static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
407{ 427{
408 int b; 428 int b;
409 u8 start, end; 429 u8 start, end;
410 430
431 /*
432 * We always use PRCM clock as the DISPC func clock, except on DSS3,
433 * where we don't have separate DISPC and LCD clock sources.
434 */
435 if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
436 clk_src != DSS_CLK_SRC_FCK))
437 return;
438
411 switch (clk_src) { 439 switch (clk_src) {
412 case OMAP_DSS_CLK_SRC_FCK: 440 case DSS_CLK_SRC_FCK:
413 b = 0; 441 b = 0;
414 break; 442 break;
415 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 443 case DSS_CLK_SRC_PLL1_1:
416 b = 1; 444 b = 1;
417 break; 445 break;
418 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 446 case DSS_CLK_SRC_PLL2_1:
419 b = 2; 447 b = 2;
420 break; 448 break;
421 default: 449 default:
@@ -431,19 +459,19 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
431} 459}
432 460
433void dss_select_dsi_clk_source(int dsi_module, 461void dss_select_dsi_clk_source(int dsi_module,
434 enum omap_dss_clk_source clk_src) 462 enum dss_clk_source clk_src)
435{ 463{
436 int b, pos; 464 int b, pos;
437 465
438 switch (clk_src) { 466 switch (clk_src) {
439 case OMAP_DSS_CLK_SRC_FCK: 467 case DSS_CLK_SRC_FCK:
440 b = 0; 468 b = 0;
441 break; 469 break;
442 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: 470 case DSS_CLK_SRC_PLL1_2:
443 BUG_ON(dsi_module != 0); 471 BUG_ON(dsi_module != 0);
444 b = 1; 472 b = 1;
445 break; 473 break;
446 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI: 474 case DSS_CLK_SRC_PLL2_2:
447 BUG_ON(dsi_module != 1); 475 BUG_ON(dsi_module != 1);
448 b = 1; 476 b = 1;
449 break; 477 break;
@@ -458,59 +486,125 @@ void dss_select_dsi_clk_source(int dsi_module,
458 dss.dsi_clk_source[dsi_module] = clk_src; 486 dss.dsi_clk_source[dsi_module] = clk_src;
459} 487}
460 488
489static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
490 enum dss_clk_source clk_src)
491{
492 const u8 ctrl_bits[] = {
493 [OMAP_DSS_CHANNEL_LCD] = 0,
494 [OMAP_DSS_CHANNEL_LCD2] = 12,
495 [OMAP_DSS_CHANNEL_LCD3] = 19,
496 };
497
498 u8 ctrl_bit = ctrl_bits[channel];
499 int r;
500
501 if (clk_src == DSS_CLK_SRC_FCK) {
502 /* LCDx_CLK_SWITCH */
503 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
504 return -EINVAL;
505 }
506
507 r = dss_ctrl_pll_set_control_mux(clk_src, channel);
508 if (r)
509 return r;
510
511 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
512
513 return 0;
514}
515
516static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
517 enum dss_clk_source clk_src)
518{
519 const u8 ctrl_bits[] = {
520 [OMAP_DSS_CHANNEL_LCD] = 0,
521 [OMAP_DSS_CHANNEL_LCD2] = 12,
522 [OMAP_DSS_CHANNEL_LCD3] = 19,
523 };
524 const enum dss_clk_source allowed_plls[] = {
525 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
526 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK,
527 [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1,
528 };
529
530 u8 ctrl_bit = ctrl_bits[channel];
531
532 if (clk_src == DSS_CLK_SRC_FCK) {
533 /* LCDx_CLK_SWITCH */
534 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
535 return -EINVAL;
536 }
537
538 if (WARN_ON(allowed_plls[channel] != clk_src))
539 return -EINVAL;
540
541 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
542
543 return 0;
544}
545
546static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
547 enum dss_clk_source clk_src)
548{
549 const u8 ctrl_bits[] = {
550 [OMAP_DSS_CHANNEL_LCD] = 0,
551 [OMAP_DSS_CHANNEL_LCD2] = 12,
552 };
553 const enum dss_clk_source allowed_plls[] = {
554 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
555 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1,
556 };
557
558 u8 ctrl_bit = ctrl_bits[channel];
559
560 if (clk_src == DSS_CLK_SRC_FCK) {
561 /* LCDx_CLK_SWITCH */
562 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
563 return 0;
564 }
565
566 if (WARN_ON(allowed_plls[channel] != clk_src))
567 return -EINVAL;
568
569 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
570
571 return 0;
572}
573
461void dss_select_lcd_clk_source(enum omap_channel channel, 574void dss_select_lcd_clk_source(enum omap_channel channel,
462 enum omap_dss_clk_source clk_src) 575 enum dss_clk_source clk_src)
463{ 576{
464 int b, ix, pos; 577 int idx = dss_get_channel_index(channel);
578 int r;
465 579
466 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) { 580 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
467 dss_select_dispc_clk_source(clk_src); 581 dss_select_dispc_clk_source(clk_src);
582 dss.lcd_clk_source[idx] = clk_src;
468 return; 583 return;
469 } 584 }
470 585
471 switch (clk_src) { 586 r = dss.feat->select_lcd_source(channel, clk_src);
472 case OMAP_DSS_CLK_SRC_FCK: 587 if (r)
473 b = 0;
474 break;
475 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
476 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
477 b = 1;
478 break;
479 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
480 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
481 channel != OMAP_DSS_CHANNEL_LCD3);
482 b = 1;
483 break;
484 default:
485 BUG();
486 return; 588 return;
487 }
488
489 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
490 (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
491 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
492 589
493 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 590 dss.lcd_clk_source[idx] = clk_src;
494 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
495 dss.lcd_clk_source[ix] = clk_src;
496} 591}
497 592
498enum omap_dss_clk_source dss_get_dispc_clk_source(void) 593enum dss_clk_source dss_get_dispc_clk_source(void)
499{ 594{
500 return dss.dispc_clk_source; 595 return dss.dispc_clk_source;
501} 596}
502 597
503enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module) 598enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
504{ 599{
505 return dss.dsi_clk_source[dsi_module]; 600 return dss.dsi_clk_source[dsi_module];
506} 601}
507 602
508enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 603enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
509{ 604{
510 if (dss_has_feature(FEAT_LCD_CLK_SRC)) { 605 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
511 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 606 int idx = dss_get_channel_index(channel);
512 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2); 607 return dss.lcd_clk_source[idx];
513 return dss.lcd_clk_source[ix];
514 } else { 608 } else {
515 /* LCD_CLK source is the same as DISPC_FCLK source for 609 /* LCD_CLK source is the same as DISPC_FCLK source for
516 * OMAP2 and OMAP3 */ 610 * OMAP2 and OMAP3 */
@@ -859,6 +953,7 @@ static const struct dss_features omap44xx_dss_feats = {
859 .dpi_select_source = &dss_dpi_select_source_omap4, 953 .dpi_select_source = &dss_dpi_select_source_omap4,
860 .ports = omap2plus_ports, 954 .ports = omap2plus_ports,
861 .num_ports = ARRAY_SIZE(omap2plus_ports), 955 .num_ports = ARRAY_SIZE(omap2plus_ports),
956 .select_lcd_source = &dss_lcd_clk_mux_omap4,
862}; 957};
863 958
864static const struct dss_features omap54xx_dss_feats = { 959static const struct dss_features omap54xx_dss_feats = {
@@ -868,6 +963,7 @@ static const struct dss_features omap54xx_dss_feats = {
868 .dpi_select_source = &dss_dpi_select_source_omap5, 963 .dpi_select_source = &dss_dpi_select_source_omap5,
869 .ports = omap2plus_ports, 964 .ports = omap2plus_ports,
870 .num_ports = ARRAY_SIZE(omap2plus_ports), 965 .num_ports = ARRAY_SIZE(omap2plus_ports),
966 .select_lcd_source = &dss_lcd_clk_mux_omap5,
871}; 967};
872 968
873static const struct dss_features am43xx_dss_feats = { 969static const struct dss_features am43xx_dss_feats = {
@@ -886,6 +982,7 @@ static const struct dss_features dra7xx_dss_feats = {
886 .dpi_select_source = &dss_dpi_select_source_dra7xx, 982 .dpi_select_source = &dss_dpi_select_source_dra7xx,
887 .ports = dra7xx_ports, 983 .ports = dra7xx_ports,
888 .num_ports = ARRAY_SIZE(dra7xx_ports), 984 .num_ports = ARRAY_SIZE(dra7xx_ports),
985 .select_lcd_source = &dss_lcd_clk_mux_dra7,
889}; 986};
890 987
891static int dss_init_features(struct platform_device *pdev) 988static int dss_init_features(struct platform_device *pdev)
@@ -1143,18 +1240,18 @@ static int dss_bind(struct device *dev)
1143 /* Select DPLL */ 1240 /* Select DPLL */
1144 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); 1241 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1145 1242
1146 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 1243 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1147 1244
1148#ifdef CONFIG_OMAP2_DSS_VENC 1245#ifdef CONFIG_OMAP2_DSS_VENC
1149 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ 1246 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
1150 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 1247 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
1151 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 1248 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
1152#endif 1249#endif
1153 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 1250 dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
1154 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 1251 dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
1155 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK; 1252 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
1156 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 1253 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
1157 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 1254 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
1158 1255
1159 rev = dss_read_reg(DSS_REVISION); 1256 rev = dss_read_reg(DSS_REVISION);
1160 printk(KERN_INFO "OMAP DSS rev %d.%d\n", 1257 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 38e6ab50142d..4fd06dc41cb3 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -102,6 +102,20 @@ enum dss_writeback_channel {
102 DSS_WB_LCD3_MGR = 7, 102 DSS_WB_LCD3_MGR = 7,
103}; 103};
104 104
105enum dss_clk_source {
106 DSS_CLK_SRC_FCK = 0,
107
108 DSS_CLK_SRC_PLL1_1,
109 DSS_CLK_SRC_PLL1_2,
110 DSS_CLK_SRC_PLL1_3,
111
112 DSS_CLK_SRC_PLL2_1,
113 DSS_CLK_SRC_PLL2_2,
114 DSS_CLK_SRC_PLL2_3,
115
116 DSS_CLK_SRC_HDMI_PLL,
117};
118
105enum dss_pll_id { 119enum dss_pll_id {
106 DSS_PLL_DSI1, 120 DSS_PLL_DSI1,
107 DSS_PLL_DSI2, 121 DSS_PLL_DSI2,
@@ -114,6 +128,11 @@ struct dss_pll;
114 128
115#define DSS_PLL_MAX_HSDIVS 4 129#define DSS_PLL_MAX_HSDIVS 4
116 130
131enum dss_pll_type {
132 DSS_PLL_TYPE_A,
133 DSS_PLL_TYPE_B,
134};
135
117/* 136/*
118 * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7. 137 * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
119 * Type-B PLLs: clkout[0] refers to m2. 138 * Type-B PLLs: clkout[0] refers to m2.
@@ -140,6 +159,8 @@ struct dss_pll_ops {
140}; 159};
141 160
142struct dss_pll_hw { 161struct dss_pll_hw {
162 enum dss_pll_type type;
163
143 unsigned n_max; 164 unsigned n_max;
144 unsigned m_min; 165 unsigned m_min;
145 unsigned m_max; 166 unsigned m_max;
@@ -227,7 +248,7 @@ unsigned long dss_get_dispc_clk_rate(void);
227int dss_dpi_select_source(int port, enum omap_channel channel); 248int dss_dpi_select_source(int port, enum omap_channel channel);
228void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 249void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
229enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 250enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
230const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 251const char *dss_get_clk_source_name(enum dss_clk_source clk_src);
231void dss_dump_clocks(struct seq_file *s); 252void dss_dump_clocks(struct seq_file *s);
232 253
233/* DSS VIDEO PLL */ 254/* DSS VIDEO PLL */
@@ -244,20 +265,18 @@ void dss_debug_dump_clocks(struct seq_file *s);
244#endif 265#endif
245 266
246void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); 267void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
247void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
248 enum omap_channel channel);
249 268
250void dss_sdi_init(int datapairs); 269void dss_sdi_init(int datapairs);
251int dss_sdi_enable(void); 270int dss_sdi_enable(void);
252void dss_sdi_disable(void); 271void dss_sdi_disable(void);
253 272
254void dss_select_dsi_clk_source(int dsi_module, 273void dss_select_dsi_clk_source(int dsi_module,
255 enum omap_dss_clk_source clk_src); 274 enum dss_clk_source clk_src);
256void dss_select_lcd_clk_source(enum omap_channel channel, 275void dss_select_lcd_clk_source(enum omap_channel channel,
257 enum omap_dss_clk_source clk_src); 276 enum dss_clk_source clk_src);
258enum omap_dss_clk_source dss_get_dispc_clk_source(void); 277enum dss_clk_source dss_get_dispc_clk_source(void);
259enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module); 278enum dss_clk_source dss_get_dsi_clk_source(int dsi_module);
260enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); 279enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
261 280
262void dss_set_venc_output(enum omap_dss_venc_type type); 281void dss_set_venc_output(enum omap_dss_venc_type type);
263void dss_set_dac_pwrdn_bgz(bool enable); 282void dss_set_dac_pwrdn_bgz(bool enable);
@@ -409,17 +428,23 @@ typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
409int dss_pll_register(struct dss_pll *pll); 428int dss_pll_register(struct dss_pll *pll);
410void dss_pll_unregister(struct dss_pll *pll); 429void dss_pll_unregister(struct dss_pll *pll);
411struct dss_pll *dss_pll_find(const char *name); 430struct dss_pll *dss_pll_find(const char *name);
431struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src);
432unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src);
412int dss_pll_enable(struct dss_pll *pll); 433int dss_pll_enable(struct dss_pll *pll);
413void dss_pll_disable(struct dss_pll *pll); 434void dss_pll_disable(struct dss_pll *pll);
414int dss_pll_set_config(struct dss_pll *pll, 435int dss_pll_set_config(struct dss_pll *pll,
415 const struct dss_pll_clock_info *cinfo); 436 const struct dss_pll_clock_info *cinfo);
416 437
417bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, 438bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
418 unsigned long out_min, unsigned long out_max, 439 unsigned long out_min, unsigned long out_max,
419 dss_hsdiv_calc_func func, void *data); 440 dss_hsdiv_calc_func func, void *data);
420bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, 441bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
421 unsigned long pll_min, unsigned long pll_max, 442 unsigned long pll_min, unsigned long pll_max,
422 dss_pll_calc_func func, void *data); 443 dss_pll_calc_func func, void *data);
444
445bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
446 unsigned long target_clkout, struct dss_pll_clock_info *cinfo);
447
423int dss_pll_write_config_type_a(struct dss_pll *pll, 448int dss_pll_write_config_type_a(struct dss_pll *pll,
424 const struct dss_pll_clock_info *cinfo); 449 const struct dss_pll_clock_info *cinfo);
425int dss_pll_write_config_type_b(struct dss_pll *pll, 450int dss_pll_write_config_type_b(struct dss_pll *pll,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c
index c886a2927f73..ee5b93ce2763 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss_features.c
@@ -23,8 +23,7 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25 25
26#include <video/omapdss.h> 26#include "omapdss.h"
27
28#include "dss.h" 27#include "dss.h"
29#include "dss_features.h" 28#include "dss_features.h"
30 29
@@ -50,7 +49,6 @@ struct omap_dss_features {
50 const enum omap_dss_output_id *supported_outputs; 49 const enum omap_dss_output_id *supported_outputs;
51 const enum omap_color_mode *supported_color_modes; 50 const enum omap_color_mode *supported_color_modes;
52 const enum omap_overlay_caps *overlay_caps; 51 const enum omap_overlay_caps *overlay_caps;
53 const char * const *clksrc_names;
54 const struct dss_param_range *dss_params; 52 const struct dss_param_range *dss_params;
55 53
56 const enum omap_dss_rotation_type supported_rotation_types; 54 const enum omap_dss_rotation_type supported_rotation_types;
@@ -389,34 +387,6 @@ static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
389 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, 387 OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
390}; 388};
391 389
392static const char * const omap2_dss_clk_source_names[] = {
393 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
394 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
395 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1",
396};
397
398static const char * const omap3_dss_clk_source_names[] = {
399 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
400 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
401 [OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
402};
403
404static const char * const omap4_dss_clk_source_names[] = {
405 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
406 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
407 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK",
408 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1",
409 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
410};
411
412static const char * const omap5_dss_clk_source_names[] = {
413 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1",
414 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2",
415 [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK",
416 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1",
417 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2",
418};
419
420static const struct dss_param_range omap2_dss_param_range[] = { 390static const struct dss_param_range omap2_dss_param_range[] = {
421 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, 391 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
422 [FEAT_PARAM_DSS_PCD] = { 2, 255 }, 392 [FEAT_PARAM_DSS_PCD] = { 2, 255 },
@@ -631,7 +601,6 @@ static const struct omap_dss_features omap2_dss_features = {
631 .supported_outputs = omap2_dss_supported_outputs, 601 .supported_outputs = omap2_dss_supported_outputs,
632 .supported_color_modes = omap2_dss_supported_color_modes, 602 .supported_color_modes = omap2_dss_supported_color_modes,
633 .overlay_caps = omap2_dss_overlay_caps, 603 .overlay_caps = omap2_dss_overlay_caps,
634 .clksrc_names = omap2_dss_clk_source_names,
635 .dss_params = omap2_dss_param_range, 604 .dss_params = omap2_dss_param_range,
636 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 605 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
637 .buffer_size_unit = 1, 606 .buffer_size_unit = 1,
@@ -652,7 +621,6 @@ static const struct omap_dss_features omap3430_dss_features = {
652 .supported_outputs = omap3430_dss_supported_outputs, 621 .supported_outputs = omap3430_dss_supported_outputs,
653 .supported_color_modes = omap3_dss_supported_color_modes, 622 .supported_color_modes = omap3_dss_supported_color_modes,
654 .overlay_caps = omap3430_dss_overlay_caps, 623 .overlay_caps = omap3430_dss_overlay_caps,
655 .clksrc_names = omap3_dss_clk_source_names,
656 .dss_params = omap3_dss_param_range, 624 .dss_params = omap3_dss_param_range,
657 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 625 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
658 .buffer_size_unit = 1, 626 .buffer_size_unit = 1,
@@ -676,7 +644,6 @@ static const struct omap_dss_features am35xx_dss_features = {
676 .supported_outputs = omap3430_dss_supported_outputs, 644 .supported_outputs = omap3430_dss_supported_outputs,
677 .supported_color_modes = omap3_dss_supported_color_modes, 645 .supported_color_modes = omap3_dss_supported_color_modes,
678 .overlay_caps = omap3430_dss_overlay_caps, 646 .overlay_caps = omap3430_dss_overlay_caps,
679 .clksrc_names = omap3_dss_clk_source_names,
680 .dss_params = omap3_dss_param_range, 647 .dss_params = omap3_dss_param_range,
681 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 648 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
682 .buffer_size_unit = 1, 649 .buffer_size_unit = 1,
@@ -696,7 +663,6 @@ static const struct omap_dss_features am43xx_dss_features = {
696 .supported_outputs = am43xx_dss_supported_outputs, 663 .supported_outputs = am43xx_dss_supported_outputs,
697 .supported_color_modes = omap3_dss_supported_color_modes, 664 .supported_color_modes = omap3_dss_supported_color_modes,
698 .overlay_caps = omap3430_dss_overlay_caps, 665 .overlay_caps = omap3430_dss_overlay_caps,
699 .clksrc_names = omap2_dss_clk_source_names,
700 .dss_params = am43xx_dss_param_range, 666 .dss_params = am43xx_dss_param_range,
701 .supported_rotation_types = OMAP_DSS_ROT_DMA, 667 .supported_rotation_types = OMAP_DSS_ROT_DMA,
702 .buffer_size_unit = 1, 668 .buffer_size_unit = 1,
@@ -716,7 +682,6 @@ static const struct omap_dss_features omap3630_dss_features = {
716 .supported_outputs = omap3630_dss_supported_outputs, 682 .supported_outputs = omap3630_dss_supported_outputs,
717 .supported_color_modes = omap3_dss_supported_color_modes, 683 .supported_color_modes = omap3_dss_supported_color_modes,
718 .overlay_caps = omap3630_dss_overlay_caps, 684 .overlay_caps = omap3630_dss_overlay_caps,
719 .clksrc_names = omap3_dss_clk_source_names,
720 .dss_params = omap3_dss_param_range, 685 .dss_params = omap3_dss_param_range,
721 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB, 686 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
722 .buffer_size_unit = 1, 687 .buffer_size_unit = 1,
@@ -738,7 +703,6 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
738 .supported_outputs = omap4_dss_supported_outputs, 703 .supported_outputs = omap4_dss_supported_outputs,
739 .supported_color_modes = omap4_dss_supported_color_modes, 704 .supported_color_modes = omap4_dss_supported_color_modes,
740 .overlay_caps = omap4_dss_overlay_caps, 705 .overlay_caps = omap4_dss_overlay_caps,
741 .clksrc_names = omap4_dss_clk_source_names,
742 .dss_params = omap4_dss_param_range, 706 .dss_params = omap4_dss_param_range,
743 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 707 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
744 .buffer_size_unit = 16, 708 .buffer_size_unit = 16,
@@ -759,7 +723,6 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
759 .supported_outputs = omap4_dss_supported_outputs, 723 .supported_outputs = omap4_dss_supported_outputs,
760 .supported_color_modes = omap4_dss_supported_color_modes, 724 .supported_color_modes = omap4_dss_supported_color_modes,
761 .overlay_caps = omap4_dss_overlay_caps, 725 .overlay_caps = omap4_dss_overlay_caps,
762 .clksrc_names = omap4_dss_clk_source_names,
763 .dss_params = omap4_dss_param_range, 726 .dss_params = omap4_dss_param_range,
764 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 727 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
765 .buffer_size_unit = 16, 728 .buffer_size_unit = 16,
@@ -780,7 +743,6 @@ static const struct omap_dss_features omap4_dss_features = {
780 .supported_outputs = omap4_dss_supported_outputs, 743 .supported_outputs = omap4_dss_supported_outputs,
781 .supported_color_modes = omap4_dss_supported_color_modes, 744 .supported_color_modes = omap4_dss_supported_color_modes,
782 .overlay_caps = omap4_dss_overlay_caps, 745 .overlay_caps = omap4_dss_overlay_caps,
783 .clksrc_names = omap4_dss_clk_source_names,
784 .dss_params = omap4_dss_param_range, 746 .dss_params = omap4_dss_param_range,
785 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 747 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
786 .buffer_size_unit = 16, 748 .buffer_size_unit = 16,
@@ -801,7 +763,6 @@ static const struct omap_dss_features omap5_dss_features = {
801 .supported_outputs = omap5_dss_supported_outputs, 763 .supported_outputs = omap5_dss_supported_outputs,
802 .supported_color_modes = omap4_dss_supported_color_modes, 764 .supported_color_modes = omap4_dss_supported_color_modes,
803 .overlay_caps = omap4_dss_overlay_caps, 765 .overlay_caps = omap4_dss_overlay_caps,
804 .clksrc_names = omap5_dss_clk_source_names,
805 .dss_params = omap5_dss_param_range, 766 .dss_params = omap5_dss_param_range,
806 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, 767 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
807 .buffer_size_unit = 16, 768 .buffer_size_unit = 16,
@@ -859,11 +820,6 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
859 color_mode; 820 color_mode;
860} 821}
861 822
862const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
863{
864 return omap_current_dss_features->clksrc_names[id];
865}
866
867u32 dss_feat_get_buffer_size_unit(void) 823u32 dss_feat_get_buffer_size_unit(void)
868{ 824{
869 return omap_current_dss_features->buffer_size_unit; 825 return omap_current_dss_features->buffer_size_unit;
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h
index 3d67d39f192f..bb4b7f0e642b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss_features.h
@@ -91,7 +91,6 @@ unsigned long dss_feat_get_param_max(enum dss_range_param param);
91enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); 91enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
92bool dss_feat_color_mode_supported(enum omap_plane plane, 92bool dss_feat_color_mode_supported(enum omap_plane plane,
93 enum omap_color_mode color_mode); 93 enum omap_color_mode color_mode);
94const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
95 94
96u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 95u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
97u32 dss_feat_get_burst_size_unit(void); /* in bytes */ 96u32 dss_feat_get_burst_size_unit(void); /* in bytes */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index 53616b02b613..63e711545865 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -23,8 +23,9 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/hdmi.h> 25#include <linux/hdmi.h>
26#include <video/omapdss.h> 26#include <sound/omap-hdmi-audio.h>
27 27
28#include "omapdss.h"
28#include "dss.h" 29#include "dss.h"
29 30
30/* HDMI Wrapper */ 31/* HDMI Wrapper */
@@ -240,6 +241,7 @@ struct hdmi_pll_data {
240 241
241 void __iomem *base; 242 void __iomem *base;
242 243
244 struct platform_device *pdev;
243 struct hdmi_wp_data *wp; 245 struct hdmi_wp_data *wp;
244}; 246};
245 247
@@ -306,8 +308,6 @@ phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
306 308
307/* HDMI PLL funcs */ 309/* HDMI PLL funcs */
308void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); 310void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
309void hdmi_pll_compute(struct hdmi_pll_data *pll,
310 unsigned long target_tmds, struct dss_pll_clock_info *pi);
311int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, 311int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
312 struct hdmi_wp_data *wp); 312 struct hdmi_wp_data *wp);
313void hdmi_pll_uninit(struct hdmi_pll_data *hpll); 313void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 4d46cdf7a037..cbd28dfdb86a 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -34,9 +34,9 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <linux/component.h> 35#include <linux/component.h>
36#include <linux/of.h> 36#include <linux/of.h>
37#include <video/omapdss.h>
38#include <sound/omap-hdmi-audio.h> 37#include <sound/omap-hdmi-audio.h>
39 38
39#include "omapdss.h"
40#include "hdmi4_core.h" 40#include "hdmi4_core.h"
41#include "dss.h" 41#include "dss.h"
42#include "dss_features.h" 42#include "dss_features.h"
@@ -177,7 +177,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
177 if (p->double_pixel) 177 if (p->double_pixel)
178 pc *= 2; 178 pc *= 2;
179 179
180 hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); 180 /* DSS_HDMI_TCLK is bitclk / 10 */
181 pc *= 10;
182
183 dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
184 pc, &hdmi_cinfo);
181 185
182 r = dss_pll_enable(&hdmi.pll.pll); 186 r = dss_pll_enable(&hdmi.pll.pll);
183 if (r) { 187 if (r) {
@@ -204,9 +208,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
204 208
205 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 209 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
206 210
207 /* bypass TV gamma table */
208 dispc_enable_gamma_table(0);
209
210 /* tv size */ 211 /* tv size */
211 dss_mgr_set_timings(channel, p); 212 dss_mgr_set_timings(channel, p);
212 213
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 9255c0e1e4a7..0c0a5139a301 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -39,9 +39,9 @@
39#include <linux/regulator/consumer.h> 39#include <linux/regulator/consumer.h>
40#include <linux/component.h> 40#include <linux/component.h>
41#include <linux/of.h> 41#include <linux/of.h>
42#include <video/omapdss.h>
43#include <sound/omap-hdmi-audio.h> 42#include <sound/omap-hdmi-audio.h>
44 43
44#include "omapdss.h"
45#include "hdmi5_core.h" 45#include "hdmi5_core.h"
46#include "dss.h" 46#include "dss.h"
47#include "dss_features.h" 47#include "dss_features.h"
@@ -189,7 +189,11 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
189 if (p->double_pixel) 189 if (p->double_pixel)
190 pc *= 2; 190 pc *= 2;
191 191
192 hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); 192 /* DSS_HDMI_TCLK is bitclk / 10 */
193 pc *= 10;
194
195 dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
196 pc, &hdmi_cinfo);
193 197
194 /* disable and clear irqs */ 198 /* disable and clear irqs */
195 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 199 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
@@ -221,9 +225,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
221 225
222 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 226 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
223 227
224 /* bypass TV gamma table */
225 dispc_enable_gamma_table(0);
226
227 /* tv size */ 228 /* tv size */
228 dss_mgr_set_timings(channel, p); 229 dss_mgr_set_timings(channel, p);
229 230
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_common.c b/drivers/gpu/drm/omapdrm/dss/hdmi_common.c
index 1b8fcc6c4ba1..4dfb67fe5f6d 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_common.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_common.c
@@ -4,8 +4,8 @@
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/err.h> 5#include <linux/err.h>
6#include <linux/of.h> 6#include <linux/of.h>
7#include <video/omapdss.h>
8 7
8#include "omapdss.h"
9#include "hdmi.h" 9#include "hdmi.h"
10 10
11int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, 11int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
index f98b750fc499..3ead47cccac5 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
@@ -14,8 +14,8 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/seq_file.h> 16#include <linux/seq_file.h>
17#include <video/omapdss.h>
18 17
18#include "omapdss.h"
19#include "dss.h" 19#include "dss.h"
20#include "hdmi.h" 20#include "hdmi.h"
21 21
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
index f1015e8b8267..b8bf6a9e5557 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
@@ -17,9 +17,9 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/pm_runtime.h>
20 21
21#include <video/omapdss.h> 22#include "omapdss.h"
22
23#include "dss.h" 23#include "dss.h"
24#include "hdmi.h" 24#include "hdmi.h"
25 25
@@ -39,71 +39,14 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
39 DUMPPLL(PLLCTRL_CFG4); 39 DUMPPLL(PLLCTRL_CFG4);
40} 40}
41 41
42void hdmi_pll_compute(struct hdmi_pll_data *pll,
43 unsigned long target_tmds, struct dss_pll_clock_info *pi)
44{
45 unsigned long fint, clkdco, clkout;
46 unsigned long target_bitclk, target_clkdco;
47 unsigned long min_dco;
48 unsigned n, m, mf, m2, sd;
49 unsigned long clkin;
50 const struct dss_pll_hw *hw = pll->pll.hw;
51
52 clkin = clk_get_rate(pll->pll.clkin);
53
54 DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
55
56 target_bitclk = target_tmds * 10;
57
58 /* Fint */
59 n = DIV_ROUND_UP(clkin, hw->fint_max);
60 fint = clkin / n;
61
62 /* adjust m2 so that the clkdco will be high enough */
63 min_dco = roundup(hw->clkdco_min, fint);
64 m2 = DIV_ROUND_UP(min_dco, target_bitclk);
65 if (m2 == 0)
66 m2 = 1;
67
68 target_clkdco = target_bitclk * m2;
69 m = target_clkdco / fint;
70
71 clkdco = fint * m;
72
73 /* adjust clkdco with fractional mf */
74 if (WARN_ON(target_clkdco - clkdco > fint))
75 mf = 0;
76 else
77 mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
78
79 if (mf > 0)
80 clkdco += (u32)div_u64((u64)mf * fint, 262144);
81
82 clkout = clkdco / m2;
83
84 /* sigma-delta */
85 sd = DIV_ROUND_UP(fint * m, 250000000);
86
87 DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
88 n, m, mf, m2, sd);
89 DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
90
91 pi->n = n;
92 pi->m = m;
93 pi->mf = mf;
94 pi->mX[0] = m2;
95 pi->sd = sd;
96
97 pi->fint = fint;
98 pi->clkdco = clkdco;
99 pi->clkout[0] = clkout;
100}
101
102static int hdmi_pll_enable(struct dss_pll *dsspll) 42static int hdmi_pll_enable(struct dss_pll *dsspll)
103{ 43{
104 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); 44 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
105 struct hdmi_wp_data *wp = pll->wp; 45 struct hdmi_wp_data *wp = pll->wp;
106 u16 r = 0; 46 int r;
47
48 r = pm_runtime_get_sync(&pll->pdev->dev);
49 WARN_ON(r < 0);
107 50
108 dss_ctrl_pll_enable(DSS_PLL_HDMI, true); 51 dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
109 52
@@ -118,10 +61,14 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
118{ 61{
119 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); 62 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
120 struct hdmi_wp_data *wp = pll->wp; 63 struct hdmi_wp_data *wp = pll->wp;
64 int r;
121 65
122 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 66 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
123 67
124 dss_ctrl_pll_enable(DSS_PLL_HDMI, false); 68 dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
69
70 r = pm_runtime_put_sync(&pll->pdev->dev);
71 WARN_ON(r < 0 && r != -ENOSYS);
125} 72}
126 73
127static const struct dss_pll_ops dsi_pll_ops = { 74static const struct dss_pll_ops dsi_pll_ops = {
@@ -131,6 +78,8 @@ static const struct dss_pll_ops dsi_pll_ops = {
131}; 78};
132 79
133static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { 80static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
81 .type = DSS_PLL_TYPE_B,
82
134 .n_max = 255, 83 .n_max = 255,
135 .m_min = 20, 84 .m_min = 20,
136 .m_max = 4095, 85 .m_max = 4095,
@@ -154,6 +103,8 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
154}; 103};
155 104
156static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { 105static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
106 .type = DSS_PLL_TYPE_B,
107
157 .n_max = 255, 108 .n_max = 255,
158 .m_min = 20, 109 .m_min = 20,
159 .m_max = 2045, 110 .m_max = 2045,
@@ -225,6 +176,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
225 int r; 176 int r;
226 struct resource *res; 177 struct resource *res;
227 178
179 pll->pdev = pdev;
228 pll->wp = wp; 180 pll->wp = wp;
229 181
230 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 182 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
index 055f62fca5dc..203694a52d18 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
@@ -15,8 +15,8 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <video/omapdss.h>
19 18
19#include "omapdss.h"
20#include "dss.h" 20#include "dss.h"
21#include "hdmi.h" 21#include "hdmi.h"
22 22
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index d7e7c909bbc2..6eaf1adbd606 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -18,7 +18,872 @@
18#ifndef __OMAP_DRM_DSS_H 18#ifndef __OMAP_DRM_DSS_H
19#define __OMAP_DRM_DSS_H 19#define __OMAP_DRM_DSS_H
20 20
21#include <video/omapdss.h> 21#include <linux/list.h>
22#include <linux/kobject.h>
23#include <linux/device.h>
24#include <linux/interrupt.h>
25#include <video/videomode.h>
26#include <linux/platform_data/omapdss.h>
27#include <uapi/drm/drm_mode.h>
28
29#define DISPC_IRQ_FRAMEDONE (1 << 0)
30#define DISPC_IRQ_VSYNC (1 << 1)
31#define DISPC_IRQ_EVSYNC_EVEN (1 << 2)
32#define DISPC_IRQ_EVSYNC_ODD (1 << 3)
33#define DISPC_IRQ_ACBIAS_COUNT_STAT (1 << 4)
34#define DISPC_IRQ_PROG_LINE_NUM (1 << 5)
35#define DISPC_IRQ_GFX_FIFO_UNDERFLOW (1 << 6)
36#define DISPC_IRQ_GFX_END_WIN (1 << 7)
37#define DISPC_IRQ_PAL_GAMMA_MASK (1 << 8)
38#define DISPC_IRQ_OCP_ERR (1 << 9)
39#define DISPC_IRQ_VID1_FIFO_UNDERFLOW (1 << 10)
40#define DISPC_IRQ_VID1_END_WIN (1 << 11)
41#define DISPC_IRQ_VID2_FIFO_UNDERFLOW (1 << 12)
42#define DISPC_IRQ_VID2_END_WIN (1 << 13)
43#define DISPC_IRQ_SYNC_LOST (1 << 14)
44#define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15)
45#define DISPC_IRQ_WAKEUP (1 << 16)
46#define DISPC_IRQ_SYNC_LOST2 (1 << 17)
47#define DISPC_IRQ_VSYNC2 (1 << 18)
48#define DISPC_IRQ_VID3_END_WIN (1 << 19)
49#define DISPC_IRQ_VID3_FIFO_UNDERFLOW (1 << 20)
50#define DISPC_IRQ_ACBIAS_COUNT_STAT2 (1 << 21)
51#define DISPC_IRQ_FRAMEDONE2 (1 << 22)
52#define DISPC_IRQ_FRAMEDONEWB (1 << 23)
53#define DISPC_IRQ_FRAMEDONETV (1 << 24)
54#define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25)
55#define DISPC_IRQ_WBUNCOMPLETEERROR (1 << 26)
56#define DISPC_IRQ_SYNC_LOST3 (1 << 27)
57#define DISPC_IRQ_VSYNC3 (1 << 28)
58#define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29)
59#define DISPC_IRQ_FRAMEDONE3 (1 << 30)
60
61struct omap_dss_device;
62struct omap_overlay_manager;
63struct dss_lcd_mgr_config;
64struct snd_aes_iec958;
65struct snd_cea_861_aud_if;
66struct hdmi_avi_infoframe;
67
68enum omap_display_type {
69 OMAP_DISPLAY_TYPE_NONE = 0,
70 OMAP_DISPLAY_TYPE_DPI = 1 << 0,
71 OMAP_DISPLAY_TYPE_DBI = 1 << 1,
72 OMAP_DISPLAY_TYPE_SDI = 1 << 2,
73 OMAP_DISPLAY_TYPE_DSI = 1 << 3,
74 OMAP_DISPLAY_TYPE_VENC = 1 << 4,
75 OMAP_DISPLAY_TYPE_HDMI = 1 << 5,
76 OMAP_DISPLAY_TYPE_DVI = 1 << 6,
77};
78
79enum omap_plane {
80 OMAP_DSS_GFX = 0,
81 OMAP_DSS_VIDEO1 = 1,
82 OMAP_DSS_VIDEO2 = 2,
83 OMAP_DSS_VIDEO3 = 3,
84 OMAP_DSS_WB = 4,
85};
86
87enum omap_channel {
88 OMAP_DSS_CHANNEL_LCD = 0,
89 OMAP_DSS_CHANNEL_DIGIT = 1,
90 OMAP_DSS_CHANNEL_LCD2 = 2,
91 OMAP_DSS_CHANNEL_LCD3 = 3,
92 OMAP_DSS_CHANNEL_WB = 4,
93};
94
95enum omap_color_mode {
96 OMAP_DSS_COLOR_CLUT1 = 1 << 0, /* BITMAP 1 */
97 OMAP_DSS_COLOR_CLUT2 = 1 << 1, /* BITMAP 2 */
98 OMAP_DSS_COLOR_CLUT4 = 1 << 2, /* BITMAP 4 */
99 OMAP_DSS_COLOR_CLUT8 = 1 << 3, /* BITMAP 8 */
100 OMAP_DSS_COLOR_RGB12U = 1 << 4, /* RGB12, 16-bit container */
101 OMAP_DSS_COLOR_ARGB16 = 1 << 5, /* ARGB16 */
102 OMAP_DSS_COLOR_RGB16 = 1 << 6, /* RGB16 */
103 OMAP_DSS_COLOR_RGB24U = 1 << 7, /* RGB24, 32-bit container */
104 OMAP_DSS_COLOR_RGB24P = 1 << 8, /* RGB24, 24-bit container */
105 OMAP_DSS_COLOR_YUV2 = 1 << 9, /* YUV2 4:2:2 co-sited */
106 OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */
107 OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32 */
108 OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32 */
109 OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32 */
110 OMAP_DSS_COLOR_NV12 = 1 << 14, /* NV12 format: YUV 4:2:0 */
111 OMAP_DSS_COLOR_RGBA16 = 1 << 15, /* RGBA16 - 4444 */
112 OMAP_DSS_COLOR_RGBX16 = 1 << 16, /* RGBx16 - 4444 */
113 OMAP_DSS_COLOR_ARGB16_1555 = 1 << 17, /* ARGB16 - 1555 */
114 OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16 - 1555 */
115};
116
117enum omap_dss_load_mode {
118 OMAP_DSS_LOAD_CLUT_AND_FRAME = 0,
119 OMAP_DSS_LOAD_CLUT_ONLY = 1,
120 OMAP_DSS_LOAD_FRAME_ONLY = 2,
121 OMAP_DSS_LOAD_CLUT_ONCE_FRAME = 3,
122};
123
124enum omap_dss_trans_key_type {
125 OMAP_DSS_COLOR_KEY_GFX_DST = 0,
126 OMAP_DSS_COLOR_KEY_VID_SRC = 1,
127};
128
129enum omap_rfbi_te_mode {
130 OMAP_DSS_RFBI_TE_MODE_1 = 1,
131 OMAP_DSS_RFBI_TE_MODE_2 = 2,
132};
133
134enum omap_dss_signal_level {
135 OMAPDSS_SIG_ACTIVE_LOW,
136 OMAPDSS_SIG_ACTIVE_HIGH,
137};
138
139enum omap_dss_signal_edge {
140 OMAPDSS_DRIVE_SIG_FALLING_EDGE,
141 OMAPDSS_DRIVE_SIG_RISING_EDGE,
142};
143
144enum omap_dss_venc_type {
145 OMAP_DSS_VENC_TYPE_COMPOSITE,
146 OMAP_DSS_VENC_TYPE_SVIDEO,
147};
148
149enum omap_dss_dsi_pixel_format {
150 OMAP_DSS_DSI_FMT_RGB888,
151 OMAP_DSS_DSI_FMT_RGB666,
152 OMAP_DSS_DSI_FMT_RGB666_PACKED,
153 OMAP_DSS_DSI_FMT_RGB565,
154};
155
156enum omap_dss_dsi_mode {
157 OMAP_DSS_DSI_CMD_MODE = 0,
158 OMAP_DSS_DSI_VIDEO_MODE,
159};
160
161enum omap_display_caps {
162 OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0,
163 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM = 1 << 1,
164};
165
166enum omap_dss_display_state {
167 OMAP_DSS_DISPLAY_DISABLED = 0,
168 OMAP_DSS_DISPLAY_ACTIVE,
169};
170
171enum omap_dss_rotation_type {
172 OMAP_DSS_ROT_DMA = 1 << 0,
173 OMAP_DSS_ROT_VRFB = 1 << 1,
174 OMAP_DSS_ROT_TILER = 1 << 2,
175};
176
177/* clockwise rotation angle */
178enum omap_dss_rotation_angle {
179 OMAP_DSS_ROT_0 = 0,
180 OMAP_DSS_ROT_90 = 1,
181 OMAP_DSS_ROT_180 = 2,
182 OMAP_DSS_ROT_270 = 3,
183};
184
185enum omap_overlay_caps {
186 OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
187 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
188 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
189 OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
190 OMAP_DSS_OVL_CAP_POS = 1 << 4,
191 OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
192};
193
194enum omap_overlay_manager_caps {
195 OMAP_DSS_DUMMY_VALUE, /* add a dummy value to prevent compiler error */
196};
197
198enum omap_dss_clk_source {
199 OMAP_DSS_CLK_SRC_FCK = 0, /* OMAP2/3: DSS1_ALWON_FCLK
200 * OMAP4: DSS_FCLK */
201 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
202 * OMAP4: PLL1_CLK1 */
203 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
204 * OMAP4: PLL1_CLK2 */
205 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC, /* OMAP4: PLL2_CLK1 */
206 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */
207};
208
209enum omap_hdmi_flags {
210 OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
211};
212
213enum omap_dss_output_id {
214 OMAP_DSS_OUTPUT_DPI = 1 << 0,
215 OMAP_DSS_OUTPUT_DBI = 1 << 1,
216 OMAP_DSS_OUTPUT_SDI = 1 << 2,
217 OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
218 OMAP_DSS_OUTPUT_DSI2 = 1 << 4,
219 OMAP_DSS_OUTPUT_VENC = 1 << 5,
220 OMAP_DSS_OUTPUT_HDMI = 1 << 6,
221};
222
223/* RFBI */
224
225struct rfbi_timings {
226 int cs_on_time;
227 int cs_off_time;
228 int we_on_time;
229 int we_off_time;
230 int re_on_time;
231 int re_off_time;
232 int we_cycle_time;
233 int re_cycle_time;
234 int cs_pulse_width;
235 int access_time;
236
237 int clk_div;
238
239 u32 tim[5]; /* set by rfbi_convert_timings() */
240
241 int converted;
242};
243
244/* DSI */
245
246enum omap_dss_dsi_trans_mode {
247 /* Sync Pulses: both sync start and end packets sent */
248 OMAP_DSS_DSI_PULSE_MODE,
249 /* Sync Events: only sync start packets sent */
250 OMAP_DSS_DSI_EVENT_MODE,
251 /* Burst: only sync start packets sent, pixels are time compressed */
252 OMAP_DSS_DSI_BURST_MODE,
253};
254
255struct omap_dss_dsi_videomode_timings {
256 unsigned long hsclk;
257
258 unsigned ndl;
259 unsigned bitspp;
260
261 /* pixels */
262 u16 hact;
263 /* lines */
264 u16 vact;
265
266 /* DSI video mode blanking data */
267 /* Unit: byte clock cycles */
268 u16 hss;
269 u16 hsa;
270 u16 hse;
271 u16 hfp;
272 u16 hbp;
273 /* Unit: line clocks */
274 u16 vsa;
275 u16 vfp;
276 u16 vbp;
277
278 /* DSI blanking modes */
279 int blanking_mode;
280 int hsa_blanking_mode;
281 int hbp_blanking_mode;
282 int hfp_blanking_mode;
283
284 enum omap_dss_dsi_trans_mode trans_mode;
285
286 bool ddr_clk_always_on;
287 int window_sync;
288};
289
290struct omap_dss_dsi_config {
291 enum omap_dss_dsi_mode mode;
292 enum omap_dss_dsi_pixel_format pixel_format;
293 const struct omap_video_timings *timings;
294
295 unsigned long hs_clk_min, hs_clk_max;
296 unsigned long lp_clk_min, lp_clk_max;
297
298 bool ddr_clk_always_on;
299 enum omap_dss_dsi_trans_mode trans_mode;
300};
301
302struct omap_video_timings {
303 /* Unit: pixels */
304 u16 x_res;
305 /* Unit: pixels */
306 u16 y_res;
307 /* Unit: Hz */
308 u32 pixelclock;
309 /* Unit: pixel clocks */
310 u16 hsw; /* Horizontal synchronization pulse width */
311 /* Unit: pixel clocks */
312 u16 hfp; /* Horizontal front porch */
313 /* Unit: pixel clocks */
314 u16 hbp; /* Horizontal back porch */
315 /* Unit: line clocks */
316 u16 vsw; /* Vertical synchronization pulse width */
317 /* Unit: line clocks */
318 u16 vfp; /* Vertical front porch */
319 /* Unit: line clocks */
320 u16 vbp; /* Vertical back porch */
321
322 /* Vsync logic level */
323 enum omap_dss_signal_level vsync_level;
324 /* Hsync logic level */
325 enum omap_dss_signal_level hsync_level;
326 /* Interlaced or Progressive timings */
327 bool interlace;
328 /* Pixel clock edge to drive LCD data */
329 enum omap_dss_signal_edge data_pclk_edge;
330 /* Data enable logic level */
331 enum omap_dss_signal_level de_level;
332 /* Pixel clock edges to drive HSYNC and VSYNC signals */
333 enum omap_dss_signal_edge sync_pclk_edge;
334
335 bool double_pixel;
336};
337
338/* Hardcoded timings for tv modes. Venc only uses these to
339 * identify the mode, and does not actually use the configs
340 * itself. However, the configs should be something that
341 * a normal monitor can also show */
342extern const struct omap_video_timings omap_dss_pal_timings;
343extern const struct omap_video_timings omap_dss_ntsc_timings;
344
345struct omap_dss_cpr_coefs {
346 s16 rr, rg, rb;
347 s16 gr, gg, gb;
348 s16 br, bg, bb;
349};
350
351struct omap_overlay_info {
352 dma_addr_t paddr;
353 dma_addr_t p_uv_addr; /* for NV12 format */
354 u16 screen_width;
355 u16 width;
356 u16 height;
357 enum omap_color_mode color_mode;
358 u8 rotation;
359 enum omap_dss_rotation_type rotation_type;
360 bool mirror;
361
362 u16 pos_x;
363 u16 pos_y;
364 u16 out_width; /* if 0, out_width == width */
365 u16 out_height; /* if 0, out_height == height */
366 u8 global_alpha;
367 u8 pre_mult_alpha;
368 u8 zorder;
369};
370
371struct omap_overlay {
372 struct kobject kobj;
373 struct list_head list;
374
375 /* static fields */
376 const char *name;
377 enum omap_plane id;
378 enum omap_color_mode supported_modes;
379 enum omap_overlay_caps caps;
380
381 /* dynamic fields */
382 struct omap_overlay_manager *manager;
383
384 /*
385 * The following functions do not block:
386 *
387 * is_enabled
388 * set_overlay_info
389 * get_overlay_info
390 *
391 * The rest of the functions may block and cannot be called from
392 * interrupt context
393 */
394
395 int (*enable)(struct omap_overlay *ovl);
396 int (*disable)(struct omap_overlay *ovl);
397 bool (*is_enabled)(struct omap_overlay *ovl);
398
399 int (*set_manager)(struct omap_overlay *ovl,
400 struct omap_overlay_manager *mgr);
401 int (*unset_manager)(struct omap_overlay *ovl);
402
403 int (*set_overlay_info)(struct omap_overlay *ovl,
404 struct omap_overlay_info *info);
405 void (*get_overlay_info)(struct omap_overlay *ovl,
406 struct omap_overlay_info *info);
407
408 int (*wait_for_go)(struct omap_overlay *ovl);
409
410 struct omap_dss_device *(*get_device)(struct omap_overlay *ovl);
411};
412
413struct omap_overlay_manager_info {
414 u32 default_color;
415
416 enum omap_dss_trans_key_type trans_key_type;
417 u32 trans_key;
418 bool trans_enabled;
419
420 bool partial_alpha_enabled;
421
422 bool cpr_enable;
423 struct omap_dss_cpr_coefs cpr_coefs;
424};
425
426struct omap_overlay_manager {
427 struct kobject kobj;
428
429 /* static fields */
430 const char *name;
431 enum omap_channel id;
432 enum omap_overlay_manager_caps caps;
433 struct list_head overlays;
434 enum omap_display_type supported_displays;
435 enum omap_dss_output_id supported_outputs;
436
437 /* dynamic fields */
438 struct omap_dss_device *output;
439
440 /*
441 * The following functions do not block:
442 *
443 * set_manager_info
444 * get_manager_info
445 * apply
446 *
447 * The rest of the functions may block and cannot be called from
448 * interrupt context
449 */
450
451 int (*set_output)(struct omap_overlay_manager *mgr,
452 struct omap_dss_device *output);
453 int (*unset_output)(struct omap_overlay_manager *mgr);
454
455 int (*set_manager_info)(struct omap_overlay_manager *mgr,
456 struct omap_overlay_manager_info *info);
457 void (*get_manager_info)(struct omap_overlay_manager *mgr,
458 struct omap_overlay_manager_info *info);
459
460 int (*apply)(struct omap_overlay_manager *mgr);
461 int (*wait_for_go)(struct omap_overlay_manager *mgr);
462 int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
463
464 struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
465};
466
467/* 22 pins means 1 clk lane and 10 data lanes */
468#define OMAP_DSS_MAX_DSI_PINS 22
469
470struct omap_dsi_pin_config {
471 int num_pins;
472 /*
473 * pin numbers in the following order:
474 * clk+, clk-
475 * data1+, data1-
476 * data2+, data2-
477 * ...
478 */
479 int pins[OMAP_DSS_MAX_DSI_PINS];
480};
481
482struct omap_dss_writeback_info {
483 u32 paddr;
484 u32 p_uv_addr;
485 u16 buf_width;
486 u16 width;
487 u16 height;
488 enum omap_color_mode color_mode;
489 u8 rotation;
490 enum omap_dss_rotation_type rotation_type;
491 bool mirror;
492 u8 pre_mult_alpha;
493};
494
495struct omapdss_dpi_ops {
496 int (*connect)(struct omap_dss_device *dssdev,
497 struct omap_dss_device *dst);
498 void (*disconnect)(struct omap_dss_device *dssdev,
499 struct omap_dss_device *dst);
500
501 int (*enable)(struct omap_dss_device *dssdev);
502 void (*disable)(struct omap_dss_device *dssdev);
503
504 int (*check_timings)(struct omap_dss_device *dssdev,
505 struct omap_video_timings *timings);
506 void (*set_timings)(struct omap_dss_device *dssdev,
507 struct omap_video_timings *timings);
508 void (*get_timings)(struct omap_dss_device *dssdev,
509 struct omap_video_timings *timings);
510
511 void (*set_data_lines)(struct omap_dss_device *dssdev, int data_lines);
512};
513
514struct omapdss_sdi_ops {
515 int (*connect)(struct omap_dss_device *dssdev,
516 struct omap_dss_device *dst);
517 void (*disconnect)(struct omap_dss_device *dssdev,
518 struct omap_dss_device *dst);
519
520 int (*enable)(struct omap_dss_device *dssdev);
521 void (*disable)(struct omap_dss_device *dssdev);
522
523 int (*check_timings)(struct omap_dss_device *dssdev,
524 struct omap_video_timings *timings);
525 void (*set_timings)(struct omap_dss_device *dssdev,
526 struct omap_video_timings *timings);
527 void (*get_timings)(struct omap_dss_device *dssdev,
528 struct omap_video_timings *timings);
529
530 void (*set_datapairs)(struct omap_dss_device *dssdev, int datapairs);
531};
532
533struct omapdss_dvi_ops {
534 int (*connect)(struct omap_dss_device *dssdev,
535 struct omap_dss_device *dst);
536 void (*disconnect)(struct omap_dss_device *dssdev,
537 struct omap_dss_device *dst);
538
539 int (*enable)(struct omap_dss_device *dssdev);
540 void (*disable)(struct omap_dss_device *dssdev);
541
542 int (*check_timings)(struct omap_dss_device *dssdev,
543 struct omap_video_timings *timings);
544 void (*set_timings)(struct omap_dss_device *dssdev,
545 struct omap_video_timings *timings);
546 void (*get_timings)(struct omap_dss_device *dssdev,
547 struct omap_video_timings *timings);
548};
549
550struct omapdss_atv_ops {
551 int (*connect)(struct omap_dss_device *dssdev,
552 struct omap_dss_device *dst);
553 void (*disconnect)(struct omap_dss_device *dssdev,
554 struct omap_dss_device *dst);
555
556 int (*enable)(struct omap_dss_device *dssdev);
557 void (*disable)(struct omap_dss_device *dssdev);
558
559 int (*check_timings)(struct omap_dss_device *dssdev,
560 struct omap_video_timings *timings);
561 void (*set_timings)(struct omap_dss_device *dssdev,
562 struct omap_video_timings *timings);
563 void (*get_timings)(struct omap_dss_device *dssdev,
564 struct omap_video_timings *timings);
565
566 void (*set_type)(struct omap_dss_device *dssdev,
567 enum omap_dss_venc_type type);
568 void (*invert_vid_out_polarity)(struct omap_dss_device *dssdev,
569 bool invert_polarity);
570
571 int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
572 u32 (*get_wss)(struct omap_dss_device *dssdev);
573};
574
575struct omapdss_hdmi_ops {
576 int (*connect)(struct omap_dss_device *dssdev,
577 struct omap_dss_device *dst);
578 void (*disconnect)(struct omap_dss_device *dssdev,
579 struct omap_dss_device *dst);
580
581 int (*enable)(struct omap_dss_device *dssdev);
582 void (*disable)(struct omap_dss_device *dssdev);
583
584 int (*check_timings)(struct omap_dss_device *dssdev,
585 struct omap_video_timings *timings);
586 void (*set_timings)(struct omap_dss_device *dssdev,
587 struct omap_video_timings *timings);
588 void (*get_timings)(struct omap_dss_device *dssdev,
589 struct omap_video_timings *timings);
590
591 int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
592 bool (*detect)(struct omap_dss_device *dssdev);
593
594 int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
595 int (*set_infoframe)(struct omap_dss_device *dssdev,
596 const struct hdmi_avi_infoframe *avi);
597};
598
599struct omapdss_dsi_ops {
600 int (*connect)(struct omap_dss_device *dssdev,
601 struct omap_dss_device *dst);
602 void (*disconnect)(struct omap_dss_device *dssdev,
603 struct omap_dss_device *dst);
604
605 int (*enable)(struct omap_dss_device *dssdev);
606 void (*disable)(struct omap_dss_device *dssdev, bool disconnect_lanes,
607 bool enter_ulps);
608
609 /* bus configuration */
610 int (*set_config)(struct omap_dss_device *dssdev,
611 const struct omap_dss_dsi_config *cfg);
612 int (*configure_pins)(struct omap_dss_device *dssdev,
613 const struct omap_dsi_pin_config *pin_cfg);
614
615 void (*enable_hs)(struct omap_dss_device *dssdev, int channel,
616 bool enable);
617 int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
618
619 int (*update)(struct omap_dss_device *dssdev, int channel,
620 void (*callback)(int, void *), void *data);
621
622 void (*bus_lock)(struct omap_dss_device *dssdev);
623 void (*bus_unlock)(struct omap_dss_device *dssdev);
624
625 int (*enable_video_output)(struct omap_dss_device *dssdev, int channel);
626 void (*disable_video_output)(struct omap_dss_device *dssdev,
627 int channel);
628
629 int (*request_vc)(struct omap_dss_device *dssdev, int *channel);
630 int (*set_vc_id)(struct omap_dss_device *dssdev, int channel,
631 int vc_id);
632 void (*release_vc)(struct omap_dss_device *dssdev, int channel);
633
634 /* data transfer */
635 int (*dcs_write)(struct omap_dss_device *dssdev, int channel,
636 u8 *data, int len);
637 int (*dcs_write_nosync)(struct omap_dss_device *dssdev, int channel,
638 u8 *data, int len);
639 int (*dcs_read)(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
640 u8 *data, int len);
641
642 int (*gen_write)(struct omap_dss_device *dssdev, int channel,
643 u8 *data, int len);
644 int (*gen_write_nosync)(struct omap_dss_device *dssdev, int channel,
645 u8 *data, int len);
646 int (*gen_read)(struct omap_dss_device *dssdev, int channel,
647 u8 *reqdata, int reqlen,
648 u8 *data, int len);
649
650 int (*bta_sync)(struct omap_dss_device *dssdev, int channel);
651
652 int (*set_max_rx_packet_size)(struct omap_dss_device *dssdev,
653 int channel, u16 plen);
654};
655
656struct omap_dss_device {
657 struct kobject kobj;
658 struct device *dev;
659
660 struct module *owner;
661
662 struct list_head panel_list;
663
664 /* alias in the form of "display%d" */
665 char alias[16];
666
667 enum omap_display_type type;
668 enum omap_display_type output_type;
669
670 union {
671 struct {
672 u8 data_lines;
673 } dpi;
674
675 struct {
676 u8 channel;
677 u8 data_lines;
678 } rfbi;
679
680 struct {
681 u8 datapairs;
682 } sdi;
683
684 struct {
685 int module;
686 } dsi;
687
688 struct {
689 enum omap_dss_venc_type type;
690 bool invert_polarity;
691 } venc;
692 } phy;
693
694 struct {
695 struct omap_video_timings timings;
696
697 enum omap_dss_dsi_pixel_format dsi_pix_fmt;
698 enum omap_dss_dsi_mode dsi_mode;
699 } panel;
700
701 struct {
702 u8 pixel_size;
703 struct rfbi_timings rfbi_timings;
704 } ctrl;
705
706 const char *name;
707
708 /* used to match device to driver */
709 const char *driver_name;
710
711 void *data;
712
713 struct omap_dss_driver *driver;
714
715 union {
716 const struct omapdss_dpi_ops *dpi;
717 const struct omapdss_sdi_ops *sdi;
718 const struct omapdss_dvi_ops *dvi;
719 const struct omapdss_hdmi_ops *hdmi;
720 const struct omapdss_atv_ops *atv;
721 const struct omapdss_dsi_ops *dsi;
722 } ops;
723
724 /* helper variable for driver suspend/resume */
725 bool activate_after_resume;
726
727 enum omap_display_caps caps;
728
729 struct omap_dss_device *src;
730
731 enum omap_dss_display_state state;
732
733 /* OMAP DSS output specific fields */
734
735 struct list_head list;
736
737 /* DISPC channel for this output */
738 enum omap_channel dispc_channel;
739 bool dispc_channel_connected;
740
741 /* output instance */
742 enum omap_dss_output_id id;
743
744 /* the port number in the DT node */
745 int port_num;
746
747 /* dynamic fields */
748 struct omap_overlay_manager *manager;
749
750 struct omap_dss_device *dst;
751};
752
753struct omap_dss_driver {
754 int (*probe)(struct omap_dss_device *);
755 void (*remove)(struct omap_dss_device *);
756
757 int (*connect)(struct omap_dss_device *dssdev);
758 void (*disconnect)(struct omap_dss_device *dssdev);
759
760 int (*enable)(struct omap_dss_device *display);
761 void (*disable)(struct omap_dss_device *display);
762 int (*run_test)(struct omap_dss_device *display, int test);
763
764 int (*update)(struct omap_dss_device *dssdev,
765 u16 x, u16 y, u16 w, u16 h);
766 int (*sync)(struct omap_dss_device *dssdev);
767
768 int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
769 int (*get_te)(struct omap_dss_device *dssdev);
770
771 u8 (*get_rotate)(struct omap_dss_device *dssdev);
772 int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
773
774 bool (*get_mirror)(struct omap_dss_device *dssdev);
775 int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
776
777 int (*memory_read)(struct omap_dss_device *dssdev,
778 void *buf, size_t size,
779 u16 x, u16 y, u16 w, u16 h);
780
781 void (*get_resolution)(struct omap_dss_device *dssdev,
782 u16 *xres, u16 *yres);
783 void (*get_dimensions)(struct omap_dss_device *dssdev,
784 u32 *width, u32 *height);
785 int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
786
787 int (*check_timings)(struct omap_dss_device *dssdev,
788 struct omap_video_timings *timings);
789 void (*set_timings)(struct omap_dss_device *dssdev,
790 struct omap_video_timings *timings);
791 void (*get_timings)(struct omap_dss_device *dssdev,
792 struct omap_video_timings *timings);
793
794 int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
795 u32 (*get_wss)(struct omap_dss_device *dssdev);
796
797 int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
798 bool (*detect)(struct omap_dss_device *dssdev);
799
800 int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
801 int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
802 const struct hdmi_avi_infoframe *avi);
803};
804
805enum omapdss_version omapdss_get_version(void);
806bool omapdss_is_initialized(void);
807
808int omap_dss_register_driver(struct omap_dss_driver *);
809void omap_dss_unregister_driver(struct omap_dss_driver *);
810
811int omapdss_register_display(struct omap_dss_device *dssdev);
812void omapdss_unregister_display(struct omap_dss_device *dssdev);
813
814struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev);
815void omap_dss_put_device(struct omap_dss_device *dssdev);
816#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
817struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
818struct omap_dss_device *omap_dss_find_device(void *data,
819 int (*match)(struct omap_dss_device *dssdev, void *data));
820const char *omapdss_get_default_display_name(void);
821
822void videomode_to_omap_video_timings(const struct videomode *vm,
823 struct omap_video_timings *ovt);
824void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
825 struct videomode *vm);
826
827int dss_feat_get_num_mgrs(void);
828int dss_feat_get_num_ovls(void);
829enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
830
831
832
833int omap_dss_get_num_overlay_managers(void);
834struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
835
836int omap_dss_get_num_overlays(void);
837struct omap_overlay *omap_dss_get_overlay(int num);
838
839int omapdss_register_output(struct omap_dss_device *output);
840void omapdss_unregister_output(struct omap_dss_device *output);
841struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id);
842struct omap_dss_device *omap_dss_find_output(const char *name);
843struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port);
844int omapdss_output_set_device(struct omap_dss_device *out,
845 struct omap_dss_device *dssdev);
846int omapdss_output_unset_device(struct omap_dss_device *out);
847
848struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev);
849struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev);
850
851void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
852 u16 *xres, u16 *yres);
853int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
854void omapdss_default_get_timings(struct omap_dss_device *dssdev,
855 struct omap_video_timings *timings);
856
857typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
858int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
859int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
860
861int omapdss_compat_init(void);
862void omapdss_compat_uninit(void);
863
864static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
865{
866 return dssdev->src;
867}
868
869static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
870{
871 return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
872}
873
874struct device_node *
875omapdss_of_get_next_port(const struct device_node *parent,
876 struct device_node *prev);
877
878struct device_node *
879omapdss_of_get_next_endpoint(const struct device_node *parent,
880 struct device_node *prev);
881
882struct device_node *
883omapdss_of_get_first_endpoint(const struct device_node *parent);
884
885struct omap_dss_device *
886omapdss_of_find_source_for_first_ep(struct device_node *node);
22 887
23u32 dispc_read_irqstatus(void); 888u32 dispc_read_irqstatus(void);
24void dispc_clear_irqstatus(u32 mask); 889void dispc_clear_irqstatus(u32 mask);
@@ -44,6 +909,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,
44 const struct omap_video_timings *timings); 909 const struct omap_video_timings *timings);
45void dispc_mgr_setup(enum omap_channel channel, 910void dispc_mgr_setup(enum omap_channel channel,
46 const struct omap_overlay_manager_info *info); 911 const struct omap_overlay_manager_info *info);
912u32 dispc_mgr_gamma_size(enum omap_channel channel);
913void dispc_mgr_set_gamma(enum omap_channel channel,
914 const struct drm_color_lut *lut,
915 unsigned int length);
47 916
48int dispc_ovl_enable(enum omap_plane plane, bool enable); 917int dispc_ovl_enable(enum omap_plane plane, bool enable);
49bool dispc_ovl_enabled(enum omap_plane plane); 918bool dispc_ovl_enabled(enum omap_plane plane);
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index 829232ad8c81..24f859488201 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -21,8 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of.h> 22#include <linux/of.h>
23 23
24#include <video/omapdss.h> 24#include "omapdss.h"
25
26#include "dss.h" 25#include "dss.h"
27 26
28static LIST_HEAD(output_list); 27static LIST_HEAD(output_list);
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index f974ddcd3b6e..0a76c89cdc2e 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -22,8 +22,7 @@
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24 24
25#include <video/omapdss.h> 25#include "omapdss.h"
26
27#include "dss.h" 26#include "dss.h"
28 27
29#define PLL_CONTROL 0x0000 28#define PLL_CONTROL 0x0000
@@ -76,6 +75,59 @@ struct dss_pll *dss_pll_find(const char *name)
76 return NULL; 75 return NULL;
77} 76}
78 77
78struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src)
79{
80 struct dss_pll *pll;
81
82 switch (src) {
83 default:
84 case DSS_CLK_SRC_FCK:
85 return NULL;
86
87 case DSS_CLK_SRC_HDMI_PLL:
88 return dss_pll_find("hdmi");
89
90 case DSS_CLK_SRC_PLL1_1:
91 case DSS_CLK_SRC_PLL1_2:
92 case DSS_CLK_SRC_PLL1_3:
93 pll = dss_pll_find("dsi0");
94 if (!pll)
95 pll = dss_pll_find("video0");
96 return pll;
97
98 case DSS_CLK_SRC_PLL2_1:
99 case DSS_CLK_SRC_PLL2_2:
100 case DSS_CLK_SRC_PLL2_3:
101 pll = dss_pll_find("dsi1");
102 if (!pll)
103 pll = dss_pll_find("video1");
104 return pll;
105 }
106}
107
108unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src)
109{
110 switch (src) {
111 case DSS_CLK_SRC_HDMI_PLL:
112 return 0;
113
114 case DSS_CLK_SRC_PLL1_1:
115 case DSS_CLK_SRC_PLL2_1:
116 return 0;
117
118 case DSS_CLK_SRC_PLL1_2:
119 case DSS_CLK_SRC_PLL2_2:
120 return 1;
121
122 case DSS_CLK_SRC_PLL1_3:
123 case DSS_CLK_SRC_PLL2_3:
124 return 2;
125
126 default:
127 return 0;
128 }
129}
130
79int dss_pll_enable(struct dss_pll *pll) 131int dss_pll_enable(struct dss_pll *pll)
80{ 132{
81 int r; 133 int r;
@@ -129,7 +181,7 @@ int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cin
129 return 0; 181 return 0;
130} 182}
131 183
132bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco, 184bool dss_pll_hsdiv_calc_a(const struct dss_pll *pll, unsigned long clkdco,
133 unsigned long out_min, unsigned long out_max, 185 unsigned long out_min, unsigned long out_max,
134 dss_hsdiv_calc_func func, void *data) 186 dss_hsdiv_calc_func func, void *data)
135{ 187{
@@ -154,7 +206,11 @@ bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
154 return false; 206 return false;
155} 207}
156 208
157bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin, 209/*
210 * clkdco = clkin / n * m * 2
211 * clkoutX = clkdco / mX
212 */
213bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
158 unsigned long pll_min, unsigned long pll_max, 214 unsigned long pll_min, unsigned long pll_max,
159 dss_pll_calc_func func, void *data) 215 dss_pll_calc_func func, void *data)
160{ 216{
@@ -195,6 +251,71 @@ bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
195 return false; 251 return false;
196} 252}
197 253
254/*
255 * This calculates a PLL config that will provide the target_clkout rate
256 * for clkout. Additionally clkdco rate will be the same as clkout rate
257 * when clkout rate is >= min_clkdco.
258 *
259 * clkdco = clkin / n * m + clkin / n * mf / 262144
260 * clkout = clkdco / m2
261 */
262bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
263 unsigned long target_clkout, struct dss_pll_clock_info *cinfo)
264{
265 unsigned long fint, clkdco, clkout;
266 unsigned long target_clkdco;
267 unsigned long min_dco;
268 unsigned n, m, mf, m2, sd;
269 const struct dss_pll_hw *hw = pll->hw;
270
271 DSSDBG("clkin %lu, target clkout %lu\n", clkin, target_clkout);
272
273 /* Fint */
274 n = DIV_ROUND_UP(clkin, hw->fint_max);
275 fint = clkin / n;
276
277 /* adjust m2 so that the clkdco will be high enough */
278 min_dco = roundup(hw->clkdco_min, fint);
279 m2 = DIV_ROUND_UP(min_dco, target_clkout);
280 if (m2 == 0)
281 m2 = 1;
282
283 target_clkdco = target_clkout * m2;
284 m = target_clkdco / fint;
285
286 clkdco = fint * m;
287
288 /* adjust clkdco with fractional mf */
289 if (WARN_ON(target_clkdco - clkdco > fint))
290 mf = 0;
291 else
292 mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
293
294 if (mf > 0)
295 clkdco += (u32)div_u64((u64)mf * fint, 262144);
296
297 clkout = clkdco / m2;
298
299 /* sigma-delta */
300 sd = DIV_ROUND_UP(fint * m, 250000000);
301
302 DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
303 n, m, mf, m2, sd);
304 DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
305
306 cinfo->n = n;
307 cinfo->m = m;
308 cinfo->mf = mf;
309 cinfo->mX[0] = m2;
310 cinfo->sd = sd;
311
312 cinfo->fint = fint;
313 cinfo->clkdco = clkdco;
314 cinfo->clkout[0] = clkout;
315
316 return true;
317}
318
198static int wait_for_bit_change(void __iomem *reg, int bitnum, int value) 319static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
199{ 320{
200 unsigned long timeout; 321 unsigned long timeout;
diff --git a/drivers/gpu/drm/omapdrm/dss/rfbi.c b/drivers/gpu/drm/omapdrm/dss/rfbi.c
index 3796576dfadf..cd53566d75eb 100644
--- a/drivers/gpu/drm/omapdrm/dss/rfbi.c
+++ b/drivers/gpu/drm/omapdrm/dss/rfbi.c
@@ -38,7 +38,7 @@
38#include <linux/pm_runtime.h> 38#include <linux/pm_runtime.h>
39#include <linux/component.h> 39#include <linux/component.h>
40 40
41#include <video/omapdss.h> 41#include "omapdss.h"
42#include "dss.h" 42#include "dss.h"
43 43
44struct rfbi_reg { u16 idx; }; 44struct rfbi_reg { u16 idx; };
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index cd6d3bfb041d..0a96c321ce62 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -29,7 +29,7 @@
29#include <linux/of.h> 29#include <linux/of.h>
30#include <linux/component.h> 30#include <linux/component.h>
31 31
32#include <video/omapdss.h> 32#include "omapdss.h"
33#include "dss.h" 33#include "dss.h"
34 34
35static struct { 35static struct {
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index 08a2cc778ba9..6eedf2118708 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -37,8 +37,7 @@
37#include <linux/of.h> 37#include <linux/of.h>
38#include <linux/component.h> 38#include <linux/component.h>
39 39
40#include <video/omapdss.h> 40#include "omapdss.h"
41
42#include "dss.h" 41#include "dss.h"
43#include "dss_features.h" 42#include "dss_features.h"
44 43
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index b1ec59e42940..7429de928d4e 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -17,8 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19 19
20#include <video/omapdss.h> 20#include "omapdss.h"
21
22#include "dss.h" 21#include "dss.h"
23#include "dss_features.h" 22#include "dss_features.h"
24 23
@@ -108,6 +107,8 @@ static const struct dss_pll_ops dss_pll_ops = {
108}; 107};
109 108
110static const struct dss_pll_hw dss_dra7_video_pll_hw = { 109static const struct dss_pll_hw dss_dra7_video_pll_hw = {
110 .type = DSS_PLL_TYPE_A,
111
111 .n_max = (1 << 8) - 1, 112 .n_max = (1 << 8) - 1,
112 .m_max = (1 << 12) - 1, 113 .m_max = (1 << 12) - 1,
113 .mX_max = (1 << 5) - 1, 114 .mX_max = (1 << 5) - 1,
@@ -124,6 +125,10 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
124 .mX_lsb[0] = 21, 125 .mX_lsb[0] = 21,
125 .mX_msb[1] = 30, 126 .mX_msb[1] = 30,
126 .mX_lsb[1] = 26, 127 .mX_lsb[1] = 26,
128 .mX_msb[2] = 4,
129 .mX_lsb[2] = 0,
130 .mX_msb[3] = 9,
131 .mX_lsb[3] = 5,
127 132
128 .has_refsel = true, 133 .has_refsel = true,
129}; 134};
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index ce2d67b6a8c7..137fe690a0da 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -32,7 +32,6 @@
32struct omap_connector { 32struct omap_connector {
33 struct drm_connector base; 33 struct drm_connector base;
34 struct omap_dss_device *dssdev; 34 struct omap_dss_device *dssdev;
35 struct drm_encoder *encoder;
36 bool hdmi_mode; 35 bool hdmi_mode;
37}; 36};
38 37
@@ -256,13 +255,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
256 return ret; 255 return ret;
257} 256}
258 257
259struct drm_encoder *omap_connector_attached_encoder(
260 struct drm_connector *connector)
261{
262 struct omap_connector *omap_connector = to_omap_connector(connector);
263 return omap_connector->encoder;
264}
265
266static const struct drm_connector_funcs omap_connector_funcs = { 258static const struct drm_connector_funcs omap_connector_funcs = {
267 .dpms = drm_atomic_helper_connector_dpms, 259 .dpms = drm_atomic_helper_connector_dpms,
268 .reset = drm_atomic_helper_connector_reset, 260 .reset = drm_atomic_helper_connector_reset,
@@ -276,7 +268,6 @@ static const struct drm_connector_funcs omap_connector_funcs = {
276static const struct drm_connector_helper_funcs omap_connector_helper_funcs = { 268static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
277 .get_modes = omap_connector_get_modes, 269 .get_modes = omap_connector_get_modes,
278 .mode_valid = omap_connector_mode_valid, 270 .mode_valid = omap_connector_mode_valid,
279 .best_encoder = omap_connector_attached_encoder,
280}; 271};
281 272
282/* initialize connector */ 273/* initialize connector */
@@ -296,7 +287,6 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
296 goto fail; 287 goto fail;
297 288
298 omap_connector->dssdev = dssdev; 289 omap_connector->dssdev = dssdev;
299 omap_connector->encoder = encoder;
300 290
301 connector = &omap_connector->base; 291 connector = &omap_connector->base;
302 292
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 075f2bb44867..180f644e861e 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -372,6 +372,20 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
372 copy_timings_drm_to_omap(&omap_crtc->timings, mode); 372 copy_timings_drm_to_omap(&omap_crtc->timings, mode);
373} 373}
374 374
375static int omap_crtc_atomic_check(struct drm_crtc *crtc,
376 struct drm_crtc_state *state)
377{
378 if (state->color_mgmt_changed && state->gamma_lut) {
379 uint length = state->gamma_lut->length /
380 sizeof(struct drm_color_lut);
381
382 if (length < 2)
383 return -EINVAL;
384 }
385
386 return 0;
387}
388
375static void omap_crtc_atomic_begin(struct drm_crtc *crtc, 389static void omap_crtc_atomic_begin(struct drm_crtc *crtc,
376 struct drm_crtc_state *old_crtc_state) 390 struct drm_crtc_state *old_crtc_state)
377{ 391{
@@ -384,6 +398,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
384 398
385 WARN_ON(omap_crtc->vblank_irq.registered); 399 WARN_ON(omap_crtc->vblank_irq.registered);
386 400
401 if (crtc->state->color_mgmt_changed) {
402 struct drm_color_lut *lut = NULL;
403 uint length = 0;
404
405 if (crtc->state->gamma_lut) {
406 lut = (struct drm_color_lut *)
407 crtc->state->gamma_lut->data;
408 length = crtc->state->gamma_lut->length /
409 sizeof(*lut);
410 }
411 dispc_mgr_set_gamma(omap_crtc->channel, lut, length);
412 }
413
414 if (crtc->state->color_mgmt_changed) {
415 struct drm_color_lut *lut = NULL;
416 uint length = 0;
417
418 if (crtc->state->gamma_lut) {
419 lut = (struct drm_color_lut *)
420 crtc->state->gamma_lut->data;
421 length = crtc->state->gamma_lut->length /
422 sizeof(*lut);
423 }
424 dispc_mgr_set_gamma(omap_crtc->channel, lut, length);
425 }
426
387 if (dispc_mgr_is_enabled(omap_crtc->channel)) { 427 if (dispc_mgr_is_enabled(omap_crtc->channel)) {
388 428
389 DBG("%s: GO", omap_crtc->name); 429 DBG("%s: GO", omap_crtc->name);
@@ -460,6 +500,7 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
460 .set_config = drm_atomic_helper_set_config, 500 .set_config = drm_atomic_helper_set_config,
461 .destroy = omap_crtc_destroy, 501 .destroy = omap_crtc_destroy,
462 .page_flip = drm_atomic_helper_page_flip, 502 .page_flip = drm_atomic_helper_page_flip,
503 .gamma_set = drm_atomic_helper_legacy_gamma_set,
463 .set_property = drm_atomic_helper_crtc_set_property, 504 .set_property = drm_atomic_helper_crtc_set_property,
464 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 505 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
465 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 506 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
@@ -471,6 +512,7 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
471 .mode_set_nofb = omap_crtc_mode_set_nofb, 512 .mode_set_nofb = omap_crtc_mode_set_nofb,
472 .disable = omap_crtc_disable, 513 .disable = omap_crtc_disable,
473 .enable = omap_crtc_enable, 514 .enable = omap_crtc_enable,
515 .atomic_check = omap_crtc_atomic_check,
474 .atomic_begin = omap_crtc_atomic_begin, 516 .atomic_begin = omap_crtc_atomic_begin,
475 .atomic_flush = omap_crtc_atomic_flush, 517 .atomic_flush = omap_crtc_atomic_flush,
476}; 518};
@@ -534,6 +576,20 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
534 576
535 drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); 577 drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
536 578
579 /* The dispc API adapts to what ever size, but the HW supports
580 * 256 element gamma table for LCDs and 1024 element table for
581 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
582 * tables so lets use that. Size of HW gamma table can be
583 * extracted with dispc_mgr_gamma_size(). If it returns 0
584 * gamma table is not supprted.
585 */
586 if (dispc_mgr_gamma_size(channel)) {
587 uint gamma_lut_size = 256;
588
589 drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
590 drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
591 }
592
537 omap_plane_install_properties(crtc->primary, &crtc->base); 593 omap_plane_install_properties(crtc->primary, &crtc->base);
538 594
539 omap_crtcs[channel] = omap_crtc; 595 omap_crtcs[channel] = omap_crtc;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index d86f5479345b..26c6134eb744 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
142{ 142{
143 struct omap_drm_private *priv = dev->dev_private; 143 struct omap_drm_private *priv = dev->dev_private;
144 struct omap_atomic_state_commit *commit; 144 struct omap_atomic_state_commit *commit;
145 unsigned int i; 145 struct drm_crtc *crtc;
146 int ret; 146 struct drm_crtc_state *crtc_state;
147 int i, ret;
147 148
148 ret = drm_atomic_helper_prepare_planes(dev, state); 149 ret = drm_atomic_helper_prepare_planes(dev, state);
149 if (ret) 150 if (ret)
@@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
163 /* Wait until all affected CRTCs have completed previous commits and 164 /* Wait until all affected CRTCs have completed previous commits and
164 * mark them as pending. 165 * mark them as pending.
165 */ 166 */
166 for (i = 0; i < dev->mode_config.num_crtc; ++i) { 167 for_each_crtc_in_state(state, crtc, crtc_state, i)
167 if (state->crtcs[i]) 168 commit->crtcs |= drm_crtc_mask(crtc);
168 commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
169 }
170 169
171 wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit)); 170 wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
172 171
@@ -175,7 +174,7 @@ static int omap_atomic_commit(struct drm_device *dev,
175 spin_unlock(&priv->commit.lock); 174 spin_unlock(&priv->commit.lock);
176 175
177 /* Swap the state, this is the point of no return. */ 176 /* Swap the state, this is the point of no return. */
178 drm_atomic_helper_swap_state(dev, state); 177 drm_atomic_helper_swap_state(state, true);
179 178
180 if (nonblock) 179 if (nonblock)
181 schedule_work(&commit->work); 180 schedule_work(&commit->work);
@@ -203,6 +202,8 @@ static int get_connector_type(struct omap_dss_device *dssdev)
203 return DRM_MODE_CONNECTOR_HDMIA; 202 return DRM_MODE_CONNECTOR_HDMIA;
204 case OMAP_DISPLAY_TYPE_DVI: 203 case OMAP_DISPLAY_TYPE_DVI:
205 return DRM_MODE_CONNECTOR_DVID; 204 return DRM_MODE_CONNECTOR_DVID;
205 case OMAP_DISPLAY_TYPE_DSI:
206 return DRM_MODE_CONNECTOR_DSI;
206 default: 207 default:
207 return DRM_MODE_CONNECTOR_Unknown; 208 return DRM_MODE_CONNECTOR_Unknown;
208 } 209 }
@@ -800,7 +801,6 @@ static struct drm_driver omap_drm_driver = {
800 .unload = dev_unload, 801 .unload = dev_unload,
801 .open = dev_open, 802 .open = dev_open,
802 .lastclose = dev_lastclose, 803 .lastclose = dev_lastclose,
803 .set_busid = drm_platform_set_busid,
804 .get_vblank_counter = drm_vblank_no_hw_counter, 804 .get_vblank_counter = drm_vblank_no_hw_counter,
805 .enable_vblank = omap_irq_enable_vblank, 805 .enable_vblank = omap_irq_enable_vblank,
806 .disable_vblank = omap_irq_disable_vblank, 806 .disable_vblank = omap_irq_disable_vblank,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 3f823c368912..dcc30a98b9d4 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -24,7 +24,6 @@
24#include <linux/platform_data/omap_drm.h> 24#include <linux/platform_data/omap_drm.h>
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/wait.h> 26#include <linux/wait.h>
27#include <video/omapdss.h>
28 27
29#include <drm/drmP.h> 28#include <drm/drmP.h>
30#include <drm/drm_crtc_helper.h> 29#include <drm/drm_crtc_helper.h>
@@ -183,7 +182,6 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
183 struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd); 182 struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
184struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, 183struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
185 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos); 184 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
186struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p);
187int omap_framebuffer_pin(struct drm_framebuffer *fb); 185int omap_framebuffer_pin(struct drm_framebuffer *fb);
188void omap_framebuffer_unpin(struct drm_framebuffer *fb); 186void omap_framebuffer_unpin(struct drm_framebuffer *fb);
189void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, 187void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
@@ -231,7 +229,6 @@ int omap_gem_rotated_paddr(struct drm_gem_object *obj, uint32_t orient,
231 int x, int y, dma_addr_t *paddr); 229 int x, int y, dma_addr_t *paddr);
232uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj); 230uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
233size_t omap_gem_mmap_size(struct drm_gem_object *obj); 231size_t omap_gem_mmap_size(struct drm_gem_object *obj);
234int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h);
235int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient); 232int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient);
236 233
237struct dma_buf *omap_gem_prime_export(struct drm_device *dev, 234struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
@@ -239,17 +236,6 @@ struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
239struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, 236struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
240 struct dma_buf *buffer); 237 struct dma_buf *buffer);
241 238
242static inline int align_pitch(int pitch, int width, int bpp)
243{
244 int bytespp = (bpp + 7) / 8;
245 /* in case someone tries to feed us a completely bogus stride: */
246 pitch = max(pitch, width * bytespp);
247 /* PVR needs alignment to 8 pixels.. right now that is the most
248 * restrictive stride requirement..
249 */
250 return roundup(pitch, 8 * bytespp);
251}
252
253/* map crtc to vblank mask */ 239/* map crtc to vblank mask */
254uint32_t pipe2vbl(struct drm_crtc *crtc); 240uint32_t pipe2vbl(struct drm_crtc *crtc);
255struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); 241struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index f84570d1636c..31f5178c22c7 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -115,24 +115,16 @@ static void omap_framebuffer_destroy(struct drm_framebuffer *fb)
115 115
116 for (i = 0; i < n; i++) { 116 for (i = 0; i < n; i++) {
117 struct plane *plane = &omap_fb->planes[i]; 117 struct plane *plane = &omap_fb->planes[i];
118 if (plane->bo) 118
119 drm_gem_object_unreference_unlocked(plane->bo); 119 drm_gem_object_unreference_unlocked(plane->bo);
120 } 120 }
121 121
122 kfree(omap_fb); 122 kfree(omap_fb);
123} 123}
124 124
125static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
126 struct drm_file *file_priv, unsigned flags, unsigned color,
127 struct drm_clip_rect *clips, unsigned num_clips)
128{
129 return 0;
130}
131
132static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { 125static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
133 .create_handle = omap_framebuffer_create_handle, 126 .create_handle = omap_framebuffer_create_handle,
134 .destroy = omap_framebuffer_destroy, 127 .destroy = omap_framebuffer_destroy,
135 .dirty = omap_framebuffer_dirty,
136}; 128};
137 129
138static uint32_t get_linear_addr(struct plane *plane, 130static uint32_t get_linear_addr(struct plane *plane,
@@ -320,14 +312,6 @@ void omap_framebuffer_unpin(struct drm_framebuffer *fb)
320 mutex_unlock(&omap_fb->lock); 312 mutex_unlock(&omap_fb->lock);
321} 313}
322 314
323struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p)
324{
325 struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
326 if (p >= drm_format_num_planes(fb->pixel_format))
327 return NULL;
328 return omap_fb->planes[p].bo;
329}
330
331/* iterate thru all the connectors, returning ones that are attached 315/* iterate thru all the connectors, returning ones that are attached
332 * to the same fb.. 316 * to the same fb..
333 */ 317 */
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 89da41ac64d2..adb10fbe918d 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -125,9 +125,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
125 mode_cmd.width = sizes->surface_width; 125 mode_cmd.width = sizes->surface_width;
126 mode_cmd.height = sizes->surface_height; 126 mode_cmd.height = sizes->surface_height;
127 127
128 mode_cmd.pitches[0] = align_pitch( 128 mode_cmd.pitches[0] =
129 mode_cmd.width * ((sizes->surface_bpp + 7) / 8), 129 DIV_ROUND_UP(mode_cmd.width * sizes->surface_bpp, 8);
130 mode_cmd.width, sizes->surface_bpp);
131 130
132 fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled; 131 fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled;
133 if (fbdev->ywrap_enabled) { 132 if (fbdev->ywrap_enabled) {
@@ -280,9 +279,6 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
280 if (ret) 279 if (ret)
281 goto fini; 280 goto fini;
282 281
283 /* disable all the possible outputs/crtcs before entering KMS mode */
284 drm_helper_disable_unused_functions(dev);
285
286 ret = drm_fb_helper_initial_config(helper, 32); 282 ret = drm_fb_helper_initial_config(helper, 32);
287 if (ret) 283 if (ret)
288 goto fini; 284 goto fini;
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 0dbd0f03f9bd..505dee0db973 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -383,18 +383,6 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj)
383 return size; 383 return size;
384} 384}
385 385
386/* get tiled size, returns -EINVAL if not tiled buffer */
387int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h)
388{
389 struct omap_gem_object *omap_obj = to_omap_bo(obj);
390 if (omap_obj->flags & OMAP_BO_TILED) {
391 *w = omap_obj->width;
392 *h = omap_obj->height;
393 return 0;
394 }
395 return -EINVAL;
396}
397
398/* ----------------------------------------------------------------------------- 386/* -----------------------------------------------------------------------------
399 * Fault Handling 387 * Fault Handling
400 */ 388 */
@@ -661,7 +649,8 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
661{ 649{
662 union omap_gem_size gsize; 650 union omap_gem_size gsize;
663 651
664 args->pitch = align_pitch(0, args->width, args->bpp); 652 args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
653
665 args->size = PAGE_ALIGN(args->pitch * args->height); 654 args->size = PAGE_ALIGN(args->pitch * args->height);
666 655
667 gsize = (union omap_gem_size){ 656 gsize = (union omap_gem_size){