aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tegra/dc.c')
-rw-r--r--drivers/gpu/drm/tegra/dc.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ae1cb31ead7..386f3b4b009 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -8,13 +8,17 @@
*/
#include <linux/clk.h>
-#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
+#include <linux/reset.h>
#include "dc.h"
#include "drm.h"
#include "gem.h"
+struct tegra_dc_soc_info {
+ bool supports_interlacing;
+};
+
struct tegra_plane {
struct drm_plane base;
unsigned int index;
@@ -658,19 +662,12 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
/* program display mode */
tegra_dc_set_timings(dc, mode);
- value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
- tegra_dc_writel(dc, value, DC_DISP_DATA_ENABLE_OPTIONS);
-
- value = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY(1));
- value &= ~LVS_OUTPUT_POLARITY_LOW;
- value &= ~LHS_OUTPUT_POLARITY_LOW;
- tegra_dc_writel(dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));
-
- value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB |
- DISP_ORDER_RED_BLUE;
- tegra_dc_writel(dc, value, DC_DISP_DISP_INTERFACE_CONTROL);
-
- tegra_dc_writel(dc, 0x00010001, DC_DISP_SHIFT_CLOCK_OPTIONS);
+ /* interlacing isn't supported yet, so disable it */
+ if (dc->soc->supports_interlacing) {
+ value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
+ value &= ~INTERLACE_ENABLE;
+ tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
+ }
value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
@@ -712,7 +709,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
unsigned long value;
/* hardware initialization */
- tegra_periph_reset_deassert(dc->clk);
+ reset_control_deassert(dc->rst);
usleep_range(10000, 20000);
if (dc->pipe)
@@ -735,10 +732,6 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value |= DISP_CTRL_MODE_C_DISPLAY;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
/* initialize timer */
value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
@@ -1167,8 +1160,36 @@ static const struct host1x_client_ops dc_client_ops = {
.exit = tegra_dc_exit,
};
+static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
+ .supports_interlacing = false,
+};
+
+static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
+ .supports_interlacing = false,
+};
+
+static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
+ .supports_interlacing = true,
+};
+
+static const struct of_device_id tegra_dc_of_match[] = {
+ {
+ .compatible = "nvidia,tegra124-dc",
+ .data = &tegra124_dc_soc_info,
+ }, {
+ .compatible = "nvidia,tegra30-dc",
+ .data = &tegra30_dc_soc_info,
+ }, {
+ .compatible = "nvidia,tegra20-dc",
+ .data = &tegra20_dc_soc_info,
+ }, {
+ /* sentinel */
+ }
+};
+
static int tegra_dc_probe(struct platform_device *pdev)
{
+ const struct of_device_id *id;
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1177,9 +1198,14 @@ static int tegra_dc_probe(struct platform_device *pdev)
if (!dc)
return -ENOMEM;
+ id = of_match_node(tegra_dc_of_match, pdev->dev.of_node);
+ if (!id)
+ return -ENODEV;
+
spin_lock_init(&dc->lock);
INIT_LIST_HEAD(&dc->list);
dc->dev = &pdev->dev;
+ dc->soc = id->data;
dc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dc->clk)) {
@@ -1187,6 +1213,12 @@ static int tegra_dc_probe(struct platform_device *pdev)
return PTR_ERR(dc->clk);
}
+ dc->rst = devm_reset_control_get(&pdev->dev, "dc");
+ if (IS_ERR(dc->rst)) {
+ dev_err(&pdev->dev, "failed to get reset\n");
+ return PTR_ERR(dc->rst);
+ }
+
err = clk_prepare_enable(dc->clk);
if (err < 0)
return err;
@@ -1247,12 +1279,6 @@ static int tegra_dc_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id tegra_dc_of_match[] = {
- { .compatible = "nvidia,tegra30-dc", },
- { .compatible = "nvidia,tegra20-dc", },
- { },
-};
-
struct platform_driver tegra_dc_driver = {
.driver = {
.name = "tegra-dc",