- avdd_hdmi_pll-supply: phandle to the regulator device tree node for HDMI pll supply.
- vdd_hdmi_5v0-supply: phandle to the regulator device tree node for HDMI 5V source.
+ Optional properties:
+ - nvidia,dc-or-node: Specifies which OR this DC is connected to. Can be either "/host1x/sor" or
+ "/host1x/sor1".
+
Example
host1x {
- avdd_hdmi_pll-supply: phandle to the regulator device tree node for HDMI pll supply.
- vdd_hdmi_5v0-supply: phandle to the regulator device tree node for HDMI 5V source.
+ Optional properties:
+ - nvidia,dc-or-node: Specifies which OR this DC is connected to. Can be either "/host1x/sor" or
+ "/host1x/sor1".
+
Example
host1x {
/*
- * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
#include <linux/platform/tegra/dvfs.h>
#include <linux/platform_data/lp855x.h>
+#define DC0_ID 0
+#define DC1_ID 1
+
#define PRISM_THRESHOLD 50
#define HYST_VAL 25
}
if (!np_panel) {
- np_sor = of_find_node_by_path(SOR_NODE);
+ np_sor = of_find_node_by_path(dc_or_node_names[DC0_ID]);
if (np_sor) {
for_each_available_child_of_node(np_sor, np_panel) {
if (np_panel && of_get_child_by_name(
{
struct device_node *np_panel = NULL;
struct tegra_dc_out *dc_out = NULL;
- struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
+ struct device_node *np_hdmi = tegra_dc_get_hdmi_node(DC0_ID);
if (pdata)
dc_out = pdata->default_out;
tegra_panel_register_ops(dc_out,
fixed_secondary_panel_ops);
} else {
- np_display = of_find_node_by_path(SOR1_NODE);
+ np_display = of_find_node_by_path(dc_or_node_names[DC1_ID]);
if (!of_property_read_string(np_display,
"nvidia,sor1-output-type", &sor1_output_type)) {
if (strcmp(sor1_output_type, "dp") == 0) {
}
of_node_put(np_display);
- np_display = of_find_node_by_path(HDMI_NODE);
+ np_display = tegra_dc_get_hdmi_node(DC1_ID);
np_panel = of_get_child_by_name(np_display, "hdmi-display");
success:
* Author:
* Erik Gilling <konkers@google.com>
*
- * Copyright (c) 2010-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
extern struct fb_videomode tegra_dc_vga_mode;
+extern char dc_or_node_names[][13];
+
enum {
TEGRA_HPD_STATE_FORCE_DEASSERT = -1,
TEGRA_HPD_STATE_NORMAL = 0,
int tegra_dc_get_head(const struct tegra_dc *dc);
int tegra_dc_get_out(const struct tegra_dc *dc);
+struct device_node *tegra_dc_get_hdmi_node(int id);
+
struct device_node *tegra_primary_panel_get_dt_node(
struct tegra_dc_platform_data *pdata);
struct device_node *tegra_secondary_panel_get_dt_node(
/*
* arch/arm64/boot/dts/tegra210-foster-e-p2530-common.dtsi
*
- * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
nvidia,cmu-enable = <1>;
nvidia,fb-bpp = <32>; /* bits per pixel */
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
+ nvidia,dc-or-node = "/host1x/sor1";
};
sor1 {
hdmi-display {
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
- * Copyright (c) 2010-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
tegra_dvfs_set_rate(dc->clk, 0);
}
+static void tegra_dc_set_sor_instance(struct tegra_dc *dc, int out_type)
+{
+ /* Fake DP should always be on SOR0. */
+ if (!strcmp(dc_or_node_names[dc->ndev->id], "/host1x/sor") ||
+ out_type == TEGRA_DC_OUT_FAKE_DP)
+ dc->sor_instance = 0;
+ else
+ dc->sor_instance = 1;
+}
+
void tegra_dc_get(struct tegra_dc *dc)
{
tegra_dc_io_start(dc);
dc->out = out;
+ tegra_dc_set_sor_instance(dc, dc->out->type);
+
if (dc->out->type == TEGRA_DC_OUT_HDMI &&
tegra_is_bl_display_initialized(dc->ndev->id)) {
/*
return false;
}
-#if !defined(CONFIG_ARCH_TEGRA_21x_SOC)
if (dc->out->type != TEGRA_DC_OUT_DP) {
+#if !defined(CONFIG_ARCH_TEGRA_21x_SOC)
+ int sor_num = tegra_dc_which_sor(dc);
np_dpaux = of_find_node_by_path(
- dc->ndev->id ? DPAUX1_NODE : DPAUX_NODE);
+ sor_num ? DPAUX1_NODE : DPAUX_NODE);
if (np_dpaux || !dc->ndev->dev.of_node)
tegra_dpaux_pad_power(dc,
- dc->ndev->id ? TEGRA_DPAUX_INSTANCE_1 :
+ sor_num ? TEGRA_DPAUX_INSTANCE_1 :
TEGRA_DPAUX_INSTANCE_0, false);
of_node_put(np_dpaux);
- }
#endif
+ }
if (dc->out_ops && dc->out_ops->enable)
dc->out_ops->enable(dc);
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
- * Copyright (c) 2010-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT;
}
+static inline int tegra_dc_which_sor(struct tegra_dc *dc)
+{
+ return dc->sor_instance;
+}
+
static inline int tegra_dc_fmt_bpp(int fmt)
{
switch (tegra_dc_fmt(fmt)) {
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
- * Copyright (c) 2010-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2016, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
struct tegra_dc_shift_clk_div shift_clk_div;
u32 powergate_id;
+ int sor_instance;
bool connected;
bool enabled;
DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV_ENABLE);
tegra_dpaux_pad_power(dp->dc,
- dp->dc->ndev->id == 0 ? TEGRA_DPAUX_INSTANCE_0 :
- TEGRA_DPAUX_INSTANCE_1, true);
+ tegra_dc_which_sor(dp->dc) ? TEGRA_DPAUX_INSTANCE_1 :
+ TEGRA_DPAUX_INSTANCE_0, true);
}
static int tegra_dp_panel_power_state(struct tegra_dc_dp_data *dp, u8 state)
{
BUG_ON(!dp->dc || !dp);
- tegra_set_dpaux_addr(dp->aux_base, dp->dc->ndev->id);
+ tegra_set_dpaux_addr(dp->aux_base, tegra_dc_which_sor(dp->dc));
_tegra_dpaux_init(dp);
int err;
u32 irq;
struct device_node *np = dc->ndev->dev.of_node;
-
+ int dp_num = tegra_dc_which_sor(dc);
struct device_node *np_dp =
- (dc->ndev->id) ? of_find_node_by_path(DPAUX1_NODE)
+ dp_num ? of_find_node_by_path(DPAUX1_NODE)
: of_find_node_by_path(DPAUX_NODE);
struct device_node *np_panel = NULL;
clk = tegra_disp_of_clk_get_by_name(np_dp,
dc->ndev->id ? "dpaux1" : "dpaux");
#else
- clk = clk_get_sys(dc->ndev->id ? "dpaux1" : "dpaux", NULL);
+ clk = clk_get_sys(dp_num ? "dpaux1" : "dpaux", NULL);
#endif
if (IS_ERR_OR_NULL(clk)) {
dev_err(&dc->ndev->dev, "dp: dc clock %s.edp unavailable\n",
static void tegra_dc_dp_destroy(struct tegra_dc *dc)
{
struct device_node *np_dp =
- (dc->ndev->id) ? of_find_node_by_path(DPAUX1_NODE) :
+ tegra_dc_which_sor(dc) ? of_find_node_by_path(DPAUX1_NODE) :
of_find_node_by_path(DPAUX_NODE);
struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
}
#ifdef CONFIG_TEGRA_NVHDCP
- hdmi->nvhdcp = tegra_nvhdcp_create(hdmi, dc->ndev->id,
+ hdmi->nvhdcp = tegra_nvhdcp_create(hdmi, tegra_dc_which_sor(dc),
dc->out->ddc_bus);
if (IS_ERR_OR_NULL(hdmi->nvhdcp)) {
dev_err(&dc->ndev->dev, "hdmi: can't create nvhdcp\n");
atomic_set(&hdmi->suspended, 0);
#ifdef CONFIG_TEGRA_HDMIHDCP
- hdmi->nvhdcp = tegra_nvhdcp_create(hdmi, dc->ndev->id,
+ hdmi->nvhdcp = tegra_nvhdcp_create(hdmi, tegra_dc_which_sor(dc),
dc->out->ddc_bus);
if (IS_ERR_OR_NULL(hdmi->nvhdcp)) {
err = PTR_ERR(hdmi->nvhdcp);
/*
* drivers/video/tegra/dc/of_dc.c
*
- * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
static struct regulator *of_dp_pad;
static struct regulator *of_dp_hdmi_5v0;
+char dc_or_node_names[TEGRA_MAX_DC][13];
+
#ifdef CONFIG_TEGRA_DC_CMU
static struct tegra_dc_cmu default_cmu = {
/* lut1 maps sRGB to linear space. */
return false;
}
+static struct device_node *dc_get_or_node(struct device *dev)
+{
+ struct device_node *np = NULL;
+ const struct platform_device *pdev;
+ struct tegra_dc *dc;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ BUG_ON(!pdev);
+ dc = platform_get_drvdata(pdev);
+ BUG_ON(!dc);
+
+ np = of_find_node_by_path(dc_or_node_names[dc->ndev->id]);
+ return np;
+}
+
+struct device_node *tegra_dc_get_hdmi_node(int id)
+{
+#ifdef CONFIG_ARCH_TEGRA_21x_SOC
+ return of_find_node_by_path(dc_or_node_names[id]);
+#else
+ return of_find_node_by_path(HDMI_NODE);
+#endif
+}
+
static int parse_disp_default_out(struct platform_device *ndev,
struct device_node *np,
struct tegra_dc_out *default_out,
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 device_node *np_hdmi = tegra_dc_get_hdmi_node(ndev->id);
struct device_node *np_sor =
- (ndev->id) ? of_find_node_by_path(SOR1_NODE) :
- of_find_node_by_path(SOR_NODE);
+ of_find_node_by_path(dc_or_node_names[ndev->id]);
struct property *prop;
const __be32 *p;
u32 u;
const struct platform_device *pdev;
struct tegra_dc *dc;
int gpio;
- struct device_node *np_dp =
- of_find_node_by_path(SOR1_NODE);
+ struct device_node *np_dp = dc_get_or_node(dev);
pdev = container_of(dev, struct platform_device, dev);
BUG_ON(!pdev);
static int dc_hdmi_out_enable(struct device *dev)
{
int err = 0;
-
struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
+ tegra_dc_get_hdmi_node(to_platform_device(dev)->id);
if (!np_hdmi || !of_device_is_available(np_hdmi)) {
pr_info("%s: no valid hdmi node\n", __func__);
int err = 0;
struct device_node *np_hdmi =
- of_find_node_by_path(HDMI_NODE);
+ tegra_dc_get_hdmi_node(to_platform_device(dev)->id);
if (!np_hdmi || !of_device_is_available(np_hdmi)) {
pr_info("%s: no valid hdmi node\n", __func__);
const __be32 *p;
int err;
u32 temp;
+ const char *dc_or_node;
/*
* Memory for pdata, pdata->default_out, pdata->fb
goto fail_parse;
}
+ err = of_property_read_string(np, "nvidia,dc-or-node", &dc_or_node);
+ if (err)
+ pr_info("%s: No dc-or-node is defined in DT\n", __func__);
+ else
+ pr_info("%s: DC OR node is connected to %s\n", __func__,
+ dc_or_node);
+
+ if (!err && (!strcmp(dc_or_node, "/host1x/sor") ||
+ !strcmp(dc_or_node, "/host1x/sor1")))
+ strncpy(dc_or_node_names[ndev->id], dc_or_node, 13);
+ else
+ strncpy(dc_or_node_names[ndev->id],
+ ndev->id ? "/host1x/sor1" : "/host1x/sor", 13);
+
/*
* determine dc out type,
* dc node defines nvidia,out-type to indicate
} else if (pdata->default_out->type == TEGRA_DC_OUT_DP ||
pdata->default_out->type == TEGRA_DC_OUT_NVSR_DP ||
pdata->default_out->type == TEGRA_DC_OUT_FAKE_DP) {
- np_sor = (ndev->id) ? of_find_node_by_path(SOR1_NODE) :
- of_find_node_by_path(SOR_NODE);
+ np_sor = of_find_node_by_path(dc_or_node_names[ndev->id]);
if (!np_sor) {
pr_err("%s: could not find sor node\n", __func__);
}
} else if (pdata->default_out->type == TEGRA_DC_OUT_HDMI) {
bool hotplug_report = false;
- np_hdmi = of_find_node_by_path(HDMI_NODE);
+ np_hdmi = tegra_dc_get_hdmi_node(ndev->id);
if (ndev->id == 0)
np_target_disp
dc_hdmi_hotplug_report;
}
} else if (pdata->default_out->type == TEGRA_DC_OUT_LVDS) {
- np_sor = of_find_node_by_path(SOR_NODE);
+ np_sor = of_find_node_by_path(dc_or_node_names[ndev->id]);
if (!np_sor) {
pr_err("%s: could not find sor node\n", __func__);
/*
* drivers/video/tegra/dc/sor.c
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
if (tegra_platform_is_linsim())
DUMP_REG(NV_SOR_FPGA_HDMI_HEAD_SEL);
#endif
- if (sor->dc->ndev->id == 1) { /* sor1 */
+ if (sor->instance) { /* sor1 */
DUMP_REG(NV_SOR_DP_AUDIO_CTRL);
DUMP_REG(NV_SOR_DP_AUDIO_HBLANK_SYMBOLS);
DUMP_REG(NV_SOR_DP_AUDIO_VBLANK_SYMBOLS);
struct clk *brick_clk = NULL;
struct clk *src_clk = NULL;
struct device_node *np = dc->ndev->dev.of_node;
+ int sor_num = tegra_dc_which_sor(dc);
struct device_node *np_sor =
- dc->ndev->id ? of_find_node_by_path(SOR1_NODE) :
+ sor_num ? of_find_node_by_path(SOR1_NODE) :
of_find_node_by_path(SOR_NODE);
- const char *res_name = dc->ndev->id ? "sor1" : "sor0";
-
- if (dc->out->type == TEGRA_DC_OUT_HDMI) {
- of_node_put(np_sor);
- np_sor = of_find_node_by_path(SOR1_NODE);
- res_name = "sor1";
- }
+ const char *res_name = sor_num ? "sor1" : "sor0";
sor = devm_kzalloc(&dc->ndev->dev, sizeof(*sor), GFP_KERNEL);
if (!sor) {
err = -ENOMEM;
goto err_allocate;
}
+ sor->instance = sor_num;
if (np) {
if (np_sor && (of_device_is_available(np_sor) ||
void tegra_dc_sor_destroy(struct tegra_dc_sor_data *sor)
{
- struct device_node *np_sor = (sor->dc->ndev->id) ?
+ struct device_node *np_sor = sor->instance ?
of_find_node_by_path(SOR1_NODE) :
of_find_node_by_path(SOR_NODE);
static void tegra_dc_sor_enable_sor(struct tegra_dc_sor_data *sor, bool enable)
{
struct tegra_dc *dc = sor->dc;
+ int sor_num = sor->instance;
u32 reg_val = tegra_dc_readl(sor->dc, DC_DISP_DISP_WIN_OPTIONS);
- u32 enb = dc->ndev->id ? SOR1_ENABLE : SOR_ENABLE;
+ u32 enb = sor_num ? SOR1_ENABLE : SOR_ENABLE;
/* Do not disable SOR during seamless boot */
if (sor->dc->initialized && !enable)
return;
if (sor->dc->out->type == TEGRA_DC_OUT_HDMI)
- enb = SOR1_ENABLE;
+ enb = sor_num ? SOR1_ENABLE : SOR_ENABLE;
if (dc->out->type == TEGRA_DC_OUT_HDMI)
enb |= SOR1_TIMING_CYA;
/*
* drivers/video/tegra/dc/sor.h
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2011-2016, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
struct tegra_dc *dc;
void __iomem *base;
+ int instance; /* SOR0 or SOR1 */
struct resource *res;
struct resource *base_res;
struct clk *sor_clk;