summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Sliwa <dominik.sliwa@toradex.com>2017-09-28 13:19:32 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-03-28 18:32:53 +0200
commit722035cfcd7e238000eafa5803e26072433371c8 (patch)
treeb52892948dc3d84a8bd59c1243588a8c62a1c405
parente83f0920de7882d09816c57a1e78e253cc3dcd7c (diff)
apalis-tk1: move display configuration to device-tree
Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com> Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
-rw-r--r--arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi200
-rw-r--r--arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pinmux.dtsi4
-rw-r--r--arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi201
-rw-r--r--arch/arm/boot/dts/tegra124-soc.dtsi6
-rw-r--r--drivers/video/tegra/dc/dc.c8
-rw-r--r--drivers/video/tegra/dc/of_dc.c490
-rw-r--r--drivers/video/tegra/dc/sor.c37
-rw-r--r--drivers/video/tegra/fb.c34
8 files changed, 850 insertions, 130 deletions
diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi
index d9eeadc9b8da..03b686e7c719 100644
--- a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi
+++ b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi
@@ -1,9 +1,207 @@
+#include <dt-bindings/display/tegra-dc.h>
+
/ {
host1x {
- hdmi {
+
+ sor {
+ status = "okay";
+ };
+
+ lvds:lvds {
+ status = "okay";
+ display {
+ status = "okay";
+ disp-default-out {
+ status = "okay";
+ nvidia,out-type = <TEGRA_DC_OUT_LVDS>;
+ nvidia,out-flags = <TEGRA_DC_OUT_CONTINUOUS_MODE>;
+ nvidia,out-parent-clk = "pll_d_out0";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <1280>;
+ nvidia,out-yres = <800>;
+ };
+ display-timings {
+ timing_1280_800: 1280x800 {
+ clock-frequency = <71100000>;
+ nvidia,h-ref-to-sync = <1>;
+ nvidia,v-ref-to-sync = <1>;
+ hsync-len = <40>;
+ vsync-len = <9>;
+ hback-porch = <60>;
+ vback-porch = <7>;
+ hactive = <1280>;
+ vactive = <800>;
+ hfront-porch = <60>;
+ vfront-porch = <7>;
+ };
+ };
+ out-pins {
+ hsync {
+ pin-name = <TEGRA_DC_OUT_PIN_H_SYNC>;
+ pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
+ };
+ vsync {
+ pin-name = <TEGRA_DC_OUT_PIN_V_SYNC>;
+ pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
+ };
+ pix-clk {
+ pin-name = <TEGRA_DC_OUT_PIN_PIXEL_CLOCK>;
+ pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
+ };
+ data-enable {
+ pin-name = <TEGRA_DC_OUT_PIN_DATA_ENABLE>;
+ pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
+ };
+ };
+ };
+ };
+
+ edp:edp {
+ status = "disabled";
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(FF, 0) 1>;
+ display {
+ status = "okay";
+ disp-default-out {
+ status = "okay";
+ nvidia,out-type = <TEGRA_DC_OUT_DP>;
+ nvidia,out-flags = <TEGRA_DC_OUT_CONTINUOUS_MODE>;
+ nvidia,out-parent-clk = "pll_d";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <1920>;
+ nvidia,out-yres = <1080>;
+ };
+ dp-lt-config {
+ dp-config@0 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <0 0 0 0>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x03>;
+ };
+ dp-config@1 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <0 0 0 0>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x04>;
+ };
+ dp-config@2 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <1 1 1 1>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x06>;
+ };
+ };
+ };
+ };
+
+ hdmi:hdmi {
status = "okay";
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) 1>;
+ display {
+ status = "okay";
+ disp-default-out {
+ nvidia,out-type = <TEGRA_DC_OUT_HDMI>;
+ nvidia,out-flags = <TEGRA_DC_OUT_HOTPLUG_HIGH>;
+ nvidia,out-parent-clk = "pll_d2";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <640>;
+ nvidia,out-yres = <480>;
+ };
+ display-timings {
+ timing_vga: 640x480 {
+ clock-frequency = <25200000>;
+ nvidia,h-ref-to-sync = <1>;
+ nvidia,v-ref-to-sync = <1>;
+ hsync-len = <96>;
+ vsync-len = <2>;
+ hback-porch = <48>;
+ vback-porch = <33>;
+ hactive = <640>;
+ vactive = <480>;
+ hfront-porch = <16>;
+ vfront-porch = <10>;
+ };
+ };
+ tmds-config {
+ tmds-cfg@0 {
+ version = <1 0>;
+ pclk = <27000000>;
+ pll0 = <0x01003010>;
+ pll1 = <0x00301b00>;
+ pe-current = <0x00000000>;
+ drive-current = <0x1f1f1f1f>;
+ peak-current = <0x03030303>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@1 {
+ version = <1 0>;
+ pclk = <74250000>;
+ pll0 = <0x01003110>;
+ pll1 = <0x00301500>;
+ pe-current = <0x00000000>;
+ drive-current = <0x2c2c2c2c>;
+ peak-current = <0x07070707>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@2 {
+ version = <1 0>;
+ pclk = <148500000>;
+ pll0 = <0x01003310>;
+ pll1 = <0x00301500>;
+ pe-current = <0x00000000>;
+ drive-current = <0x33333333>;
+ peak-current = <0x0c0c0c0c>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@3 {
+ version = <1 0>;
+ pclk = <0x7fffffff>;
+ pll0 = <0x01003f10>;
+ pll1 = <0x00300f00>;
+ pe-current = <0x00000000>;
+ drive-current = <0x37373737>;
+ peak-current = <0x17171717>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000600>;
+ };
+ };
+ };
};
+
+ dc@54200000 {
+ status = "okay";
+ nvidia,dc-connection = <&lvds>;
+ nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
+ nvidia,emc-clk-rate = <300000000>;
+ nvidia,fb-bpp = <32>; /* bits per pixel */
+ nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
+ avdd-supply = <&as3722_ldo4>;
+ };
+
+ dc@54240000 {
+ status = "okay";
+ nvidia,dc-connection = <&hdmi>;
+ nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
+ nvidia,emc-clk-rate = <300000000>;
+ nvidia,fb-bpp = <32>; /* bits per pixel */
+ nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
+ avdd_hdmi-supply = <&as3722_sd4>;
+ };
};
hdmi_ddc: i2c@7000c400 {
diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pinmux.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pinmux.dtsi
index 3c45320bf024..52e35caa2745 100644
--- a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pinmux.dtsi
+++ b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pinmux.dtsi
@@ -119,14 +119,14 @@
/* Apalis GPIO */
ddc_scl_pv4 {
nvidia,pins = "ddc_scl_pv4";
- nvidia,function = "rsvd2";
+ nvidia,function = "i2c4";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};
ddc_sda_pv5 {
nvidia,pins = "ddc_sda_pv5";
- nvidia,function = "rsvd2";
+ nvidia,function = "i2c4";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi
index e7141b33e9a3..b1f21a83f0bc 100644
--- a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi
+++ b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi
@@ -1,12 +1,211 @@
+#include <dt-bindings/display/tegra-dc.h>
+
/ {
host1x {
- hdmi {
+
+ sor {
+ status = "okay";
+ };
+
+ lvds:lvds {
+ status = "okay";
+ display {
+ status = "okay";
+ disp-default-out {
+ status = "okay";
+ nvidia,out-type = <TEGRA_DC_OUT_LVDS>;
+ nvidia,out-flags = <TEGRA_DC_OUT_CONTINUOUS_MODE>;
+ nvidia,out-parent-clk = "pll_d_out0";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <1280>;
+ nvidia,out-yres = <800>;
+ };
+ display-timings {
+ timing_1280_800: 1280x800 {
+ clock-frequency = <71100000>;
+ nvidia,h-ref-to-sync = <1>;
+ nvidia,v-ref-to-sync = <1>;
+ hsync-len = <40>;
+ vsync-len = <9>;
+ hback-porch = <60>;
+ vback-porch = <7>;
+ hactive = <1280>;
+ vactive = <800>;
+ hfront-porch = <60>;
+ vfront-porch = <7>;
+ };
+ };
+ out-pins {
+ hsync {
+ pin-name = <TEGRA_DC_OUT_PIN_H_SYNC>;
+ pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
+ };
+ vsync {
+ pin-name = <TEGRA_DC_OUT_PIN_V_SYNC>;
+ pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
+ };
+ pix-clk {
+ pin-name = <TEGRA_DC_OUT_PIN_PIXEL_CLOCK>;
+ pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
+ };
+ data-enable {
+ pin-name = <TEGRA_DC_OUT_PIN_DATA_ENABLE>;
+ pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
+ };
+ };
+ };
+ };
+
+ edp:edp {
+ status = "disabled";
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(FF, 0) 1>;
+ display {
+ status = "okay";
+ disp-default-out {
+ status = "okay";
+ nvidia,out-type = <TEGRA_DC_OUT_DP>;
+ nvidia,out-flags = <TEGRA_DC_OUT_CONTINUOUS_MODE>;
+ nvidia,out-parent-clk = "pll_d";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <1920>;
+ nvidia,out-yres = <1080>;
+ };
+ dp-lt-config {
+ dp-config@0 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <0 0 0 0>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x03>;
+ };
+ dp-config@1 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <0 0 0 0>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x04>;
+ };
+ dp-config@2 {
+ drive-current = <0 0 0 0>;
+ lane-preemphasis = <1 1 1 1>;
+ post-cursor = <0 0 0 0>;
+ tx-pu = <0>;
+ load-adj = <0x06>;
+ };
+ };
+ };
+ };
+
+ hdmi:hdmi {
status = "okay";
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+ nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) 1>;
+ display {
+ status = "okay";
+ disp-default-out {
+ nvidia,out-type = <TEGRA_DC_OUT_HDMI>;
+ nvidia,out-flags = <TEGRA_DC_OUT_HOTPLUG_HIGH>;
+ nvidia,out-parent-clk = "pll_d2";
+ nvidia,out-max-pixclk = <3367>; /* KHZ2PICOS(297000) */
+ nvidia,out-align = <TEGRA_DC_ALIGN_MSB>;
+ nvidia,out-order = <TEGRA_DC_ORDER_RED_BLUE>;
+ nvidia,out-depth = <24>;
+ nvidia,out-xres = <640>;
+ nvidia,out-yres = <480>;
+ };
+ display-timings {
+ timing_vga: 640x480 {
+ clock-frequency = <25200000>;
+ nvidia,h-ref-to-sync = <1>;
+ nvidia,v-ref-to-sync = <1>;
+ hsync-len = <96>;
+ vsync-len = <2>;
+ hback-porch = <48>;
+ vback-porch = <33>;
+ hactive = <640>;
+ vactive = <480>;
+ hfront-porch = <16>;
+ vfront-porch = <10>;
+ };
+ };
+ tmds-config {
+ tmds-cfg@0 {
+ version = <1 0>;
+ pclk = <27000000>;
+ pll0 = <0x01003010>;
+ pll1 = <0x00301b00>;
+ pe-current = <0x00000000>;
+ drive-current = <0x1f1f1f1f>;
+ peak-current = <0x03030303>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@1 {
+ version = <1 0>;
+ pclk = <74250000>;
+ pll0 = <0x01003110>;
+ pll1 = <0x00301500>;
+ pe-current = <0x00000000>;
+ drive-current = <0x2c2c2c2c>;
+ peak-current = <0x07070707>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@2 {
+ version = <1 0>;
+ pclk = <148500000>;
+ pll0 = <0x01003310>;
+ pll1 = <0x00301500>;
+ pe-current = <0x00000000>;
+ drive-current = <0x33333333>;
+ peak-current = <0x0c0c0c0c>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000400>;
+ };
+ tmds-cfg@3 {
+ version = <1 0>;
+ pclk = <0x7fffffff>;
+ pll0 = <0x01003f10>;
+ pll1 = <0x00300f00>;
+ pe-current = <0x00000000>;
+ drive-current = <0x37373737>;
+ peak-current = <0x17171717>;
+ pad-ctls0-mask = <0xfffff0ff>;
+ pad-ctls0-setting = <0x00000600>;
+ };
+ };
+ };
};
+
+ dc@54200000 {
+ status = "okay";
+ nvidia,dc-connection = <&lvds>;
+ nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
+ nvidia,emc-clk-rate = <300000000>;
+ nvidia,fb-bpp = <32>; /* bits per pixel */
+ nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
+ avdd-supply = <&as3722_ldo4>;
+ };
+
+ dc@54240000 {
+ status = "okay";
+ nvidia,dc-connection = <&hdmi>;
+ nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
+ nvidia,emc-clk-rate = <300000000>;
+ nvidia,fb-bpp = <32>; /* bits per pixel */
+ nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
+ avdd_hdmi-supply = <&as3722_sd4>;
+ };
};
hdmi_ddc: i2c@7000c700 {
clock-frequency = <10000>;
};
+
};
diff --git a/arch/arm/boot/dts/tegra124-soc.dtsi b/arch/arm/boot/dts/tegra124-soc.dtsi
index 5c8402329aec..ed90ecf7725e 100644
--- a/arch/arm/boot/dts/tegra124-soc.dtsi
+++ b/arch/arm/boot/dts/tegra124-soc.dtsi
@@ -582,6 +582,12 @@
status = "disabled";
};
+ sor {
+ compatible = "nvidia,tegra124-lvds";
+ reg = <0x54540000 0x00040000>;
+ status = "disabled";
+ };
+
vic {
compatible = "nvidia,tegra124-vic";
reg = <0x54340000 0x00040000>;
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 5fb2e91933f7..f654ae64a957 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -1398,14 +1398,8 @@ static int tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
*/
tegra_dc_cache_cmu(dc, tegra_dc_get_cmu(dc));
#endif
- }
-/* Donot set the mode now, in later stage we parse the vidargs from kernel args
- * and set the mode accordingly
- */
-#if 0
- else if (out->n_modes > 0)
+ } else if (out->n_modes > 0)
tegra_dc_set_mode(dc, &dc->out->modes[0]);
-#endif
switch (out->type) {
case TEGRA_DC_OUT_RGB:
diff --git a/drivers/video/tegra/dc/of_dc.c b/drivers/video/tegra/dc/of_dc.c
index 44bb47060da4..0f047f6388bc 100644
--- a/drivers/video/tegra/dc/of_dc.c
+++ b/drivers/video/tegra/dc/of_dc.c
@@ -69,12 +69,11 @@
#define OF_DC_LOG(fmt, args...)
#endif
-#define DSI_NODE "/host1x/dsi"
-#define HDMI_NODE "/host1x/hdmi"
-
static struct regulator *of_hdmi_vddio;
static struct regulator *of_hdmi_reg;
static struct regulator *of_hdmi_pll;
+static struct regulator *of_lvds_dp_reg;
+static struct regulator *of_lvds_bl_reg;
#ifdef CONFIG_TEGRA_DC_CMU
static struct tegra_dc_cmu default_cmu = {
@@ -145,40 +144,15 @@ static int out_type_from_pn(struct device_node *panel_node)
static int parse_dc_out_type(struct device_node *np,
struct tegra_dc_out *default_out)
{
- const char *temp_str0;
- struct device_node *np_target_disps[2] = {NULL,};
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
int out_type;
-
- np_target_disps[0] = tegra_panel_get_dt_node(NULL);
- np_target_disps[1] = of_get_child_by_name(np_hdmi, "hdmi-display");
-
- if (of_property_read_string(np, "nvidia,dc-connection",
- &temp_str0)) {
- pr_err("no nvidia,dc-connection\n");
- return -EINVAL;
+
+ out_type = out_type_from_pn(
+ of_get_child_by_name(np, "display"));
+ if (out_type >= 0) {
+ default_out->type = out_type;
+ return 0;
}
- if (!strncmp(temp_str0, "internal-lcd",
- strlen(temp_str0))) {
- out_type = out_type_from_pn(np_target_disps[0]);
- if (out_type >= 0) {
- default_out->type = out_type;
- return 0;
- }
- } else if (!strncmp(temp_str0, "external-display",
- strlen(temp_str0))) {
- out_type = out_type_from_pn(np_target_disps[1]);
- if (out_type >= 0) {
- default_out->type = out_type;
- return 0;
- }
- /* TODO: If hdmi/hdmi-display node is not valid,
- * future SoC may need to search DP node
- * for external display
- */
- }
pr_err("invalid nvidia,dc-connection or nvidia,out-type\n");
return -EINVAL;
}
@@ -273,6 +247,62 @@ parse_tmds_fail:
return -EINVAL;
}
+static int parse_dt_lt(struct device_node *np,
+ u8 *addr)
+{
+ u32 temp;
+ struct tegra_dc_dp_lt_settings *dt_lt_cfg_addr;
+ dt_lt_cfg_addr = (struct tegra_dc_dp_lt_settings *)addr;
+
+ if (!of_property_read_u32_array(np, "drive-current",
+ dt_lt_cfg_addr->drive_current, 4)) {
+ OF_DC_LOG("dp drive-current 0x%x 0x%x 0x%x 0x%x\n",
+ dt_lt_cfg_addr->drive_current[0],
+ dt_lt_cfg_addr->drive_current[1],
+ dt_lt_cfg_addr->drive_current[2],
+ dt_lt_cfg_addr->drive_current[3]);
+ } else {
+ goto parse_dt_lt_fail;
+ }
+ if (!of_property_read_u32_array(np, "lane-preemphasis",
+ dt_lt_cfg_addr->lane_preemphasis, 4)) {
+ OF_DC_LOG("dp lane_preemphasis 0x%x 0x%x 0x%x 0x%x\n",
+ dt_lt_cfg_addr->lane_preemphasis[0],
+ dt_lt_cfg_addr->lane_preemphasis[1],
+ dt_lt_cfg_addr->lane_preemphasis[2],
+ dt_lt_cfg_addr->lane_preemphasis[3]);
+ } else {
+ goto parse_dt_lt_fail;
+ }
+ if (!of_property_read_u32_array(np, "post-cursor",
+ dt_lt_cfg_addr->post_cursor, 4)) {
+ OF_DC_LOG("dp post_cursor 0x%x 0x%x 0x%x 0x%x\n",
+ dt_lt_cfg_addr->post_cursor[0],
+ dt_lt_cfg_addr->post_cursor[1],
+ dt_lt_cfg_addr->post_cursor[2],
+ dt_lt_cfg_addr->post_cursor[3]);
+ } else {
+ goto parse_dt_lt_fail;
+ }
+
+ if (!of_property_read_u32(np, "tx-pu", &temp)) {
+ dt_lt_cfg_addr->tx_pu = (u32)temp;
+ OF_DC_LOG("dp tx-pu 0x%x\n", temp);
+ } else {
+ goto parse_dt_lt_fail;
+ }
+ if (!of_property_read_u32(np, "load-adj", &temp)) {
+ dt_lt_cfg_addr->load_adj = (u32)temp;
+ OF_DC_LOG("dp load-adj 0x%x\n", temp);
+ } else {
+ goto parse_dt_lt_fail;
+ }
+ return 0;
+parse_dt_lt_fail:
+ pr_err("parse dp-lt-config fail!\n");
+ return -EINVAL;
+}
+
static bool is_dc_default_out_flag(u32 flag)
{
if ((flag == TEGRA_DC_OUT_HOTPLUG_HIGH) |
@@ -290,40 +320,27 @@ static bool is_dc_default_out_flag(u32 flag)
return false;
}
-static int parse_disp_default_out(struct platform_device *ndev,
+static int parse_disp_extra_attributes(struct platform_device *ndev,
struct device_node *np,
- struct tegra_dc_out *default_out,
- struct tegra_fb_data *fb)
+ struct tegra_dc_out *default_out)
{
- u32 temp;
+ struct device_node *ddc;
+ struct device_node *np_parent;
int hotplug_gpio = 0;
enum of_gpio_flags flags;
- struct device_node *ddc;
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
- struct property *prop;
- const __be32 *p;
- u32 u;
- const char *temp_str0;
- /*
- * construct default_out
- */
- if (!of_property_read_u32(np, "nvidia,out-width", &temp)) {
- default_out->width = (unsigned) temp;
- OF_DC_LOG("out_width %d\n", default_out->width);
- }
- if (!of_property_read_u32(np, "nvidia,out-height", &temp)) {
- default_out->height = (unsigned) temp;
- OF_DC_LOG("out_height %d\n", default_out->height);
- }
- if (np_hdmi && of_device_is_available(np_hdmi) &&
- (default_out->type == TEGRA_DC_OUT_HDMI)) {
+ if (default_out->type == TEGRA_DC_OUT_HDMI) {
int id;
- ddc = of_parse_phandle(np_hdmi, "nvidia,ddc-i2c-bus", 0);
+ np_parent = of_get_parent(np);
+ if (!np_parent) {
+ pr_err("Error getting parent device-tree node\n");
+ return -EINVAL;
+ }
+ ddc = of_parse_phandle(np_parent, "nvidia,ddc-i2c-bus", 0);
if (!ddc) {
pr_err("No ddc device node\n");
+ of_node_put(np_parent);
return -EINVAL;
} else
id = of_alias_get_id(ddc, "i2c");
@@ -333,13 +350,52 @@ static int parse_disp_default_out(struct platform_device *ndev,
OF_DC_LOG("out_dcc bus %d\n", id);
} else {
pr_err("Invalid i2c id\n");
+ of_node_put(np_parent);
return -EINVAL;
}
- hotplug_gpio = of_get_named_gpio_flags(np_hdmi,
+ hotplug_gpio = of_get_named_gpio_flags(np_parent,
"nvidia,hpd-gpio", 0, &flags);
if (hotplug_gpio != 0)
default_out->hotplug_gpio = hotplug_gpio;
+ of_node_put(np_parent);
+ }
+ if (default_out->type == TEGRA_DC_OUT_DP) {
+ np_parent = of_get_parent(np);
+ if (!np_parent) {
+ pr_err("Error getting parent device-tree node\n");
+ return -EINVAL;
+ }
+ hotplug_gpio = of_get_named_gpio_flags(np_parent,
+ "nvidia,hpd-gpio", 0, &flags);
+ if (hotplug_gpio != 0)
+ default_out->hotplug_gpio = hotplug_gpio;
+ of_node_put(np_parent);
+ }
+ return 0;
+}
+
+static int parse_disp_default_out(struct platform_device *ndev,
+ struct device_node *np,
+ struct tegra_dc_out *default_out,
+ struct tegra_fb_data *fb)
+{
+ u32 temp;
+ struct property *prop;
+ const __be32 *p;
+ u32 u;
+ const char *temp_str0;
+
+ /*
+ * construct default_out
+ */
+ if (!of_property_read_u32(np, "nvidia,out-width", &temp)) {
+ default_out->width = (unsigned) temp;
+ OF_DC_LOG("out_width %d\n", default_out->width);
+ }
+ if (!of_property_read_u32(np, "nvidia,out-height", &temp)) {
+ default_out->height = (unsigned) temp;
+ OF_DC_LOG("out_height %d\n", default_out->height);
}
if (!of_property_read_u32(np, "nvidia,out-max-pixclk", &temp)) {
@@ -400,11 +456,12 @@ static int parse_disp_default_out(struct platform_device *ndev,
}
#endif
} else {
- /* default_out->type == TEGRA_DC_OUT_DSI */
+ /* default_out->type == TEGRA_DC_OUT_DSI || TEGRA_DC_OUT_LVDS
+ * || TEGRA_DC_OUT_DP */
if (!of_property_read_u32(np,
"nvidia,out-depth", &temp)) {
default_out->depth = (unsigned) temp;
- OF_DC_LOG("out-depth for DSI display %d\n", temp);
+ OF_DC_LOG("out-depth for DSI/LVDS/DP display %d\n", temp);
}
}
@@ -487,6 +544,61 @@ fail_tmds_config:
return -EINVAL;
}
+int parse_dp_lt_config(struct platform_device *ndev,
+ struct device_node *np, struct tegra_dc_out *default_out)
+{
+ int err = 0;
+ u8 *addr;
+ struct device_node *dp_lt_np = NULL;
+ struct device_node *entry = NULL;
+
+ if (default_out->type == TEGRA_DC_OUT_DP)
+ dp_lt_np = of_get_child_by_name(np, "dp-lt-config");
+
+ if (!dp_lt_np) {
+ pr_info("%s: No dp-lt-config node\n",
+ __func__);
+ } else {
+ int dp_lt_set_count =
+ of_get_child_count(dp_lt_np);
+ if (!dp_lt_set_count) {
+ pr_info("dp lt node exists but no cfg!\n");
+ goto success_dp_lt_config;
+ }
+
+ default_out->dp_out = devm_kzalloc(&ndev->dev,
+ sizeof(struct tegra_dp_out), GFP_KERNEL);
+ if (!default_out->dp_out) {
+ dev_err(&ndev->dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+ default_out->dp_out->n_lt_settings =
+ dp_lt_set_count;
+
+ default_out->dp_out->lt_settings = devm_kzalloc(&ndev->dev,
+ dp_lt_set_count * sizeof(struct tegra_dc_dp_lt_settings),
+ GFP_KERNEL);
+ if (!default_out->dp_out->lt_settings) {
+ dev_err(&ndev->dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+ addr = (u8 *)default_out->dp_out->lt_settings;
+ for_each_child_of_node(dp_lt_np, entry) {
+ err = parse_dt_lt(entry, addr);
+ if (err)
+ goto fail_dp_lt_config;
+ addr += sizeof(struct tegra_dc_dp_lt_settings);
+ }
+ }
+success_dp_lt_config:
+ return 0;
+
+fail_dp_lt_config:
+ pr_err("%s: a parse error\n", __func__);
+ return -EINVAL;
+}
+
+
static int parse_sd_settings(struct device_node *np,
struct tegra_dc_sd_settings *sd_settings)
{
@@ -931,6 +1043,29 @@ static const u32 *tegra_dsi_parse_pkt_seq_dt(struct platform_device *ndev,
return pkt_seq;
}
+static int tegra_parse_lvds_pins(struct device_node *np,
+ struct tegra_dc_out_pin *out_pin)
+{
+ u32 temp;
+
+ if (!of_property_read_u32(np, "pin-name", &temp)) {
+ out_pin->name = temp;
+ OF_DC_LOG("of name %d\n", temp);
+ } else {
+ goto parse_pins_fail;
+ }
+ if (!of_property_read_u32(np, "pol", &temp)) {
+ out_pin->pol = temp;
+ OF_DC_LOG("of pol %d\n", temp);
+ } else {
+ goto parse_pins_fail;
+ }
+ return 0;
+parse_pins_fail:
+ pr_err("a out_pins parameter parse fail!\n");
+ return -EINVAL;
+}
+
struct device_node *parse_dsi_settings(struct platform_device *ndev,
struct device_node *np_dsi,
struct tegra_dc_platform_data *pdata)
@@ -1338,14 +1473,6 @@ static int dc_hdmi_out_enable(struct device *dev)
{
int ret;
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
-
- if (!np_hdmi || !of_device_is_available(np_hdmi)) {
- pr_info("%s: no valid hdmi node\n", __func__);
- return 0;
- }
-
if (!of_hdmi_reg) {
of_hdmi_reg = regulator_get(dev, "avdd_hdmi");
if (IS_ERR_OR_NULL(of_hdmi_reg)) {
@@ -1398,14 +1525,6 @@ static int dc_hdmi_hotplug_init(struct device *dev)
{
int ret = 0;
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
-
- if (!np_hdmi || !of_device_is_available(np_hdmi)) {
- pr_info("%s: no valid hdmi node\n", __func__);
- return 0;
- }
-
if (!of_hdmi_vddio) {
of_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
if (IS_ERR_OR_NULL(of_hdmi_vddio)) {
@@ -1453,15 +1572,117 @@ static void dc_hdmi_hotplug_report(bool state)
}
#endif
+static int dc_dp_enable(struct device *dev)
+{
+ int ret;
+ if (!of_lvds_dp_reg) {
+ of_lvds_dp_reg = regulator_get(dev, "avdd_3v3_dp");
+ if (IS_ERR_OR_NULL(of_lvds_dp_reg)) {
+ pr_err("dp: couldn't get regulator of_lvds_dp_reg\n");
+ of_lvds_dp_reg = NULL;
+ return PTR_ERR(of_lvds_dp_reg);
+ }
+ }
+ ret = regulator_set_voltage(of_lvds_dp_reg, 3300000, 3300000);
+ if (ret < 0) {
+ pr_err("dp: couldn't set regulator of_lvds_dp_reg voltage\n");
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ return ret;
+ }
+ ret = regulator_enable(of_lvds_dp_reg);
+ if (ret < 0) {
+ pr_err("dp: couldn't enable regulator of_lvds_dp_reg\n");
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ }
+
+ return ret;
+}
+
+static int dc_dp_disable(void)
+{
+ if (of_lvds_dp_reg) {
+ regulator_disable(of_lvds_dp_reg);
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ }
+ return 0;
+}
+
+static int dc_dp_postsuspend(void)
+{
+ return 0;
+}
+
+static int dc_lvds_enable(struct device *dev)
+{
+ int ret;
+
+ if (!of_lvds_dp_reg) {
+ of_lvds_dp_reg = regulator_get(dev, "avdd_3v3_dp");
+ if (IS_ERR_OR_NULL(of_lvds_dp_reg)) {
+ pr_err("dp: couldn't get regulator of_lvds_dp_reg\n");
+ of_lvds_dp_reg = NULL;
+ return PTR_ERR(of_lvds_dp_reg);
+ }
+ }
+ ret = regulator_set_voltage(of_lvds_dp_reg, 1800000, 1800000);
+ if (ret < 0) {
+ pr_err("dp: couldn't set regulator of_lvds_dp_reg voltage\n");
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ return ret;
+ }
+ ret = regulator_enable(of_lvds_dp_reg);
+ if (ret < 0) {
+ pr_err("dp: couldn't enable regulator of_lvds_dp_reg\n");
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ return ret;
+ }
+
+ if (!of_lvds_bl_reg) {
+ of_lvds_bl_reg = regulator_get(dev, "vdd_lcd_bl");
+ if (IS_ERR_OR_NULL(of_lvds_bl_reg)) {
+ pr_err("lvds: couldn't get regulator vdd_lcd_bl\n");
+ of_lvds_bl_reg = NULL;
+ }
+ }
+
+ if (of_lvds_bl_reg) {
+ if (regulator_enable(of_lvds_bl_reg) < 0)
+ pr_err("vdd_lcd_bl failed to enable\n");
+ }
+
+ return 0;
+}
+
+static int dc_lvds_disable(void)
+{
+ if (of_lvds_dp_reg) {
+ regulator_disable(of_lvds_dp_reg);
+ regulator_put(of_lvds_dp_reg);
+ of_lvds_dp_reg = NULL;
+ }
+ if (of_lvds_bl_reg) {
+ regulator_disable(of_lvds_bl_reg);
+ regulator_put(of_lvds_bl_reg);
+ of_lvds_bl_reg = NULL;
+ }
+ return 0;
+}
+
struct tegra_dc_platform_data
*of_dc_parse_platform_data(struct platform_device *ndev)
{
struct tegra_dc_platform_data *pdata;
struct device_node *np = ndev->dev.of_node;
- struct device_node *np_dsi = NULL;
- struct device_node *np_dsi_panel = NULL;
+ struct device_node *dc_connection = NULL;
struct device_node *timings_np = NULL;
+ struct device_node *pins_np = NULL;
struct device_node *np_target_disp = NULL;
+ struct device_node *np_dsi_panel = NULL;
struct device_node *sd_np = NULL;
struct device_node *default_out_np = NULL;
struct device_node *entry = NULL;
@@ -1470,7 +1691,6 @@ struct tegra_dc_platform_data
#endif
int err;
u32 temp;
-
/*
* Memory for pdata, pdata->default_out, pdata->fb
* need to be allocated in default
@@ -1497,15 +1717,21 @@ struct tegra_dc_platform_data
dev_err(&ndev->dev, "not enough memory\n");
goto fail_parse;
}
-
/*
* determine dc out type,
* dc node defines nvidia,out-type to indicate
* what out type of display is used for
* current dc id.
*/
+
+ dc_connection = of_parse_phandle(np, "nvidia,dc-connection", 0);
+
+ if (dc_connection == NULL) {
+ pr_err("no nvidia,dc-connection\n");
+ goto fail_parse;
+ }
- err = parse_dc_out_type(np, pdata->default_out);
+ err = parse_dc_out_type(dc_connection, pdata->default_out);
if (err) {
pr_err("parse_dc_out_type err\n");
goto fail_parse;
@@ -1536,19 +1762,15 @@ struct tegra_dc_platform_data
}
if (pdata->default_out->type == TEGRA_DC_OUT_DSI) {
- np_dsi = of_find_node_by_path(DSI_NODE);
- if (!np_dsi) {
- pr_err("%s: could not find dsi node\n", __func__);
- goto fail_parse;
- } else if (of_device_is_available(np_dsi)) {
+ if (of_device_is_available(dc_connection)) {
pdata->default_out->dsi = devm_kzalloc(&ndev->dev,
sizeof(struct tegra_dsi_out), GFP_KERNEL);
if (!pdata->default_out->dsi) {
dev_err(&ndev->dev, "not enough memory\n");
goto fail_parse;
}
- np_dsi_panel = parse_dsi_settings(ndev, np_dsi,
+ np_dsi_panel = parse_dsi_settings(ndev, dc_connection,
pdata);
if (!np_dsi_panel)
goto fail_parse;
@@ -1557,11 +1779,9 @@ struct tegra_dc_platform_data
}
} else if (pdata->default_out->type == TEGRA_DC_OUT_HDMI) {
bool hotplug_report = false;
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
- if (np_hdmi && of_device_is_available(np_hdmi)) {
- if (!of_property_read_u32(np_hdmi,
+ if (dc_connection && of_device_is_available(dc_connection)) {
+ if (!of_property_read_u32(dc_connection,
"nvidia,hotplug-report", &temp)) {
hotplug_report = (bool)temp;
}
@@ -1578,10 +1798,39 @@ struct tegra_dc_platform_data
dc_hdmi_hotplug_report;
#endif
np_target_disp =
- of_get_child_by_name(np_hdmi, "hdmi-display");
+ of_get_child_by_name(dc_connection, "display");
+ if (!np_target_disp ||
+ !of_device_is_available(np_target_disp)) {
+ pr_err("hdmi/display node is NOT valid\n");
+ goto fail_parse;
+ }
+
+ err = parse_tmds_config(ndev, np_target_disp,
+ pdata->default_out);
+ if (err)
+ goto fail_parse;
+ } else if (pdata->default_out->type == TEGRA_DC_OUT_LVDS) {
+ np_target_disp =
+ of_get_child_by_name(dc_connection, "display");
+ if (!np_target_disp ||
+ !of_device_is_available(np_target_disp)) {
+ pr_err("lvds/display node is NOT valid\n");
+ goto fail_parse;
+ }
+ pdata->default_out->enable = dc_lvds_enable;
+ pdata->default_out->disable = dc_lvds_disable;
+
+ } else if (pdata->default_out->type == TEGRA_DC_OUT_DP) {
+
+ pdata->default_out->enable = dc_dp_enable;
+ pdata->default_out->disable = dc_dp_disable;
+ pdata->default_out->postsuspend = dc_dp_postsuspend;
+
+ np_target_disp =
+ of_get_child_by_name(dc_connection, "display");
if (!np_target_disp ||
!of_device_is_available(np_target_disp)) {
- pr_err("/hdmi/hdmi-display node is NOT valid\n");
+ pr_err("dp/display node is NOT valid\n");
goto fail_parse;
}
}
@@ -1599,15 +1848,18 @@ struct tegra_dc_platform_data
goto fail_parse;
}
- err = parse_tmds_config(ndev, np_target_disp,
- pdata->default_out);
- if (err)
- goto fail_parse;
+ if (parse_disp_extra_attributes(ndev, np_target_disp,
+ pdata->default_out) != 0) {
+ pr_err("%s: failed parsing extra arguments\n",
+ __func__);
+ goto fail_parse;
+ }
timings_np = of_get_child_by_name(np_target_disp,
"display-timings");
if (!timings_np) {
- if (pdata->default_out->type == TEGRA_DC_OUT_DSI) {
+ if (pdata->default_out->type == TEGRA_DC_OUT_DSI ||
+ pdata->default_out->type == TEGRA_DC_OUT_LVDS) {
pr_err("%s: could not find display-timings node\n",
__func__);
goto fail_parse;
@@ -1631,7 +1883,6 @@ struct tegra_dc_platform_data
goto fail_parse;
}
} else {
- /* pdata->default_out->type == TEGRA_DC_OUT_HDMI */
pdata->default_out->n_modes = 0;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
pdata->default_out->n_modes =
@@ -1654,6 +1905,43 @@ struct tegra_dc_platform_data
#endif
}
+ pins_np = of_get_child_by_name(np_target_disp,
+ "out-pins");
+ if (!pins_np) {
+ if (pdata->default_out->type == TEGRA_DC_OUT_LVDS) {
+ pr_err("%s: could not find out-pins node\n",
+ __func__);
+ goto fail_parse;
+ }
+ } else if (pdata->default_out->type == TEGRA_DC_OUT_LVDS) {
+ struct tegra_dc_out_pin *cur_pins;
+ pdata->default_out->n_out_pins =
+ of_get_child_count(pins_np);
+ if (pdata->default_out->n_out_pins == 0) {
+ /*
+ * Should never happen !
+ */
+ dev_err(&ndev->dev, "no pins given\n");
+ goto fail_parse;
+ }
+ pdata->default_out->out_pins = devm_kzalloc(&ndev->dev,
+ pdata->default_out->n_out_pins *
+ sizeof(struct tegra_dc_out_pin), GFP_KERNEL);
+
+ if (!pdata->default_out->out_pins) {
+ dev_err(&ndev->dev, "not enough memory\n");
+ goto fail_parse;
+ }
+
+ cur_pins = pdata->default_out->out_pins;
+ for_each_child_of_node(pins_np, entry) {
+ err = tegra_parse_lvds_pins(entry, cur_pins);
+ if (err)
+ goto fail_parse;
+ cur_pins++;
+ }
+ }
+
sd_np = of_get_child_by_name(np_target_disp,
"smartdimmer");
if (!sd_np) {
diff --git a/drivers/video/tegra/dc/sor.c b/drivers/video/tegra/dc/sor.c
index ee75338e4037..65708cffd82f 100644
--- a/drivers/video/tegra/dc/sor.c
+++ b/drivers/video/tegra/dc/sor.c
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/clk/tegra.h>
+#include <linux/of_address.h>
#include <mach/dc.h>
@@ -250,9 +251,19 @@ struct tegra_dc_sor_data *tegra_dc_sor_init(struct tegra_dc *dc,
struct tegra_dc_sor_data *sor;
struct resource *res;
struct resource *base_res;
+
void __iomem *base;
struct clk *clk;
int err;
+ struct resource lvds_res;
+ struct device_node *np = dc->ndev->dev.of_node;
+#ifdef CONFIG_USE_OF
+ struct device_node *np_lvds =
+ of_find_node_by_path("/host1x/sor");
+#else
+ struct device_node *np_lvds = NULL;
+#endif
+
sor = kzalloc(sizeof(*sor), GFP_KERNEL);
if (!sor) {
@@ -260,11 +271,21 @@ struct tegra_dc_sor_data *tegra_dc_sor_init(struct tegra_dc *dc,
goto err_allocate;
}
- res = platform_get_resource_byname(dc->ndev, IORESOURCE_MEM, "sor");
- if (!res) {
- dev_err(&dc->ndev->dev, "sor: no mem resource\n");
- err = -ENOENT;
- goto err_free_sor;
+ if (np) {
+ if (np_lvds && of_device_is_available(np_lvds)) {
+ of_address_to_resource(np_lvds, 0, &lvds_res);
+ res = &lvds_res;
+ } else {
+ err = -ENOENT;
+ goto err_free_sor;
+ }
+ } else {
+ res = platform_get_resource_byname(dc->ndev, IORESOURCE_MEM, "sor");
+ if (!res) {
+ dev_err(&dc->ndev->dev, "sor: no mem resource\n");
+ err = -ENOENT;
+ goto err_free_sor;
+ }
}
base_res = request_mem_region(res->start, resource_size(res),
@@ -1258,9 +1279,13 @@ void tegra_dc_sor_enable_lvds(struct tegra_dc_sor_data *sor,
tegra_sor_writel(sor, NV_SOR_LVDS, reg_val);
tegra_sor_writel(sor, NV_SOR_LANE_DRIVE_CURRENT(sor->portnum),
0x40404040);
- if (!conforming && (sor->dc->pdata->default_out->depth == 24))
+ if (!conforming && (sor->dc->pdata->default_out->depth == 24)) {
+ tegra_sor_write_field(sor, NV_SOR_LVDS,
+ NV_SOR_LVDS_ROTDAT_DEFAULT_MASK,
+ 6 << NV_SOR_LVDS_ROTDAT_SHIFT);
tegra_sor_writel(sor, NV_SOR_LANE4_DRIVE_CURRENT(sor->portnum),
0x40);
+ }
#if 0
tegra_sor_write_field(sor, NV_SOR_LVDS,
diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c
index 61db9fe3bc32..81ba41e1c09b 100644
--- a/drivers/video/tegra/fb.c
+++ b/drivers/video/tegra/fb.c
@@ -673,7 +673,9 @@ struct tegra_fb_info *tegra_fb_register(struct platform_device *ndev,
void __iomem *fb_base = NULL;
phys_addr_t fb_size = 0;
int ret = 0;
+ int mode_idx;
unsigned stride;
+ struct fb_videomode m;
char *param_option = NULL;
const char *option = NULL;
char driver[10];
@@ -732,13 +734,6 @@ struct tegra_fb_info *tegra_fb_register(struct platform_device *ndev,
info->fix.smem_len = fb_size;
info->fix.line_length = stride;
-#if 0
- INIT_LIST_HEAD(&info->modelist);
- /* pick first mode as the default for initialization */
- tegra_dc_to_fb_videomode(&m, &dc->mode);
- fb_videomode_to_var(&info->var, &m);
-#endif
-
info->var.xres_virtual = fb_data->xres;
info->var.yres_virtual = fb_data->yres * 2;
info->var.bits_per_pixel = fb_data->bits_per_pixel;
@@ -773,11 +768,8 @@ struct tegra_fb_info *tegra_fb_register(struct platform_device *ndev,
option = param_option;
dev_info(&ndev->dev, "parse cmd options for %s: %s\n",
driver, option);
- } else {
- option = dc->out->default_mode;
- dev_info(&ndev->dev, "use default mode for %s: %s\n",
- driver, option);
- }
+ } else
+ option = NULL;
if (option != NULL)
{
@@ -789,6 +781,24 @@ struct tegra_fb_info *tegra_fb_register(struct platform_device *ndev,
ret = -EINVAL;
goto err_iounmap_fb;
}
+ } else {
+ tegra_fb->xres = fb_data->xres;
+ tegra_fb->yres = fb_data->yres;
+ INIT_LIST_HEAD(&info->modelist);
+ /* pick first mode as the default for initialization */
+ tegra_dc_to_fb_videomode(&m, &dc->mode);
+ fb_videomode_to_var(&info->var, &m);
+
+ for (mode_idx = 0; mode_idx < dc->out->n_modes; mode_idx++) {
+ struct tegra_dc_mode mode = dc->out->modes[mode_idx];
+ struct fb_videomode vmode;
+
+ mode.pclk = dc->mode.pclk;
+ if (mode.pclk > 1000) {
+ tegra_dc_to_fb_videomode(&vmode, &mode);
+ fb_add_videomode(&vmode, &info->modelist);
+ }
+ }
}
/* activate current settings.. */