summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-10-24 16:50:45 +1000
committerDave Airlie <airlied@redhat.com>2017-10-24 16:50:45 +1000
commit3b677e43c1191de4717357ffeb85a30b967045e4 (patch)
tree076e053e367e3b6525614808f3d8c81e77b434ca /drivers/gpu/drm
parent3064abfa932bd09faf8da01741d171d476cf7193 (diff)
parentfb83be8873909ba7c089d1c5cb72873cc2cce7d1 (diff)
downloadlinux-3b677e43c1191de4717357ffeb85a30b967045e4.tar.bz2
Merge tag 'drm/tegra/for-4.15-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next
drm/tegra: Changes for v4.15-rc1 This contains a bit of cleanup and some minor fixes for the host1x and Tegra DRM drivers. There's also some more preparatory work for Tegra186 support which I'm not quite ready to send upstream because the GPIO driver needed for HDMI support has been stuck for months, and we can't do much without it. Hopefully that driver will land in v4.15, which would mean we could go ahead with Tegra186 display support in v4.16. * tag 'drm/tegra/for-4.15-rc1' of git://anongit.freedesktop.org/tegra/linux: (21 commits) drm/tegra: hdmi: Add cec-notifier support drm/tegra: dc: Perform a complete reset sequence drm/tegra: dc: Make sure to set the module clock rate drm/tegra: dc: Simplify atomic plane helper functions drm/tegra: dc: Move some declarations to dc.h drm/tegra: vic: Use of_device_get_match_data() drm/tegra: sor: Use of_device_get_match_data() drm/tegra: hdmi: Use of_device_get_match_data() drm/tegra: dc: Use of_device_get_match_data() drm/tegra: Use u64_to_user_ptr helper gpu: host1x: Fix incorrect comment for channel_request gpu: host1x: Disassemble more instructions gpu: host1x: Improve debug disassembly formatting gpu: host1x: Enable gather filter gpu: host1x: Enable Tegra186 syncpoint protection gpu: host1x: Call of_dma_configure() after setting bus drm/tegra: Add Tegra186 support for VIC gpu: host1x: Add Tegra186 support dt-bindings: host1x: Add Tegra186 information gpu: host1x: syncpt: Request syncpoints per client ...
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/tegra/Kconfig1
-rw-r--r--drivers/gpu/drm/tegra/dc.c84
-rw-r--r--drivers/gpu/drm/tegra/dc.h120
-rw-r--r--drivers/gpu/drm/tegra/drm.c30
-rw-r--r--drivers/gpu/drm/tegra/drm.h106
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c2
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c2
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c17
-rw-r--r--drivers/gpu/drm/tegra/output.c6
-rw-r--r--drivers/gpu/drm/tegra/sor.c5
-rw-r--r--drivers/gpu/drm/tegra/vic.c22
11 files changed, 211 insertions, 184 deletions
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index dc58ab140151..cf54847a8bd1 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -9,6 +9,7 @@ config DRM_TEGRA
select DRM_PANEL
select TEGRA_HOST1X
select IOMMU_IOVA if IOMMU_SUPPORT
+ select CEC_CORE if CEC_NOTIFIER
help
Choose this option if you have an NVIDIA Tegra SoC.
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 4df39112e38e..24a5ef4f5bb8 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/iommu.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
@@ -23,16 +24,6 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
-struct tegra_dc_soc_info {
- bool supports_border_color;
- bool supports_interlacing;
- bool supports_cursor;
- bool supports_block_linear;
- unsigned int pitch_align;
- bool has_powergate;
- bool broken_reset;
-};
-
struct tegra_plane {
struct drm_plane base;
unsigned int index;
@@ -559,14 +550,21 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
return 0;
}
-static void tegra_dc_disable_window(struct tegra_dc *dc, int index)
+static void tegra_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
+ struct tegra_dc *dc = to_tegra_dc(old_state->crtc);
+ struct tegra_plane *p = to_tegra_plane(plane);
unsigned long flags;
u32 value;
+ /* rien ne va plus */
+ if (!old_state || !old_state->crtc)
+ return;
+
spin_lock_irqsave(&dc->lock, flags);
- value = WINDOW_A_SELECT << index;
+ value = WINDOW_A_SELECT << p->index;
tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
@@ -591,7 +589,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
return;
if (!plane->state->visible)
- return tegra_dc_disable_window(dc, p->index);
+ return tegra_plane_atomic_disable(plane, old_state);
memset(&window, 0, sizeof(window));
window.src.x = plane->state->src.x1 >> 16;
@@ -627,25 +625,10 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
tegra_dc_setup_window(dc, p->index, &window);
}
-static void tegra_plane_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
-{
- struct tegra_plane *p = to_tegra_plane(plane);
- struct tegra_dc *dc;
-
- /* rien ne va plus */
- if (!old_state || !old_state->crtc)
- return;
-
- dc = to_tegra_dc(old_state->crtc);
-
- tegra_dc_disable_window(dc, p->index);
-}
-
-static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = {
+static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
.atomic_check = tegra_plane_atomic_check,
- .atomic_update = tegra_plane_atomic_update,
.atomic_disable = tegra_plane_atomic_disable,
+ .atomic_update = tegra_plane_atomic_update,
};
static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
@@ -685,7 +668,7 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
return ERR_PTR(err);
}
- drm_plane_helper_add(&plane->base, &tegra_primary_plane_helper_funcs);
+ drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
return &plane->base;
}
@@ -880,12 +863,6 @@ static const uint32_t tegra_overlay_plane_formats[] = {
DRM_FORMAT_YUV422,
};
-static const struct drm_plane_helper_funcs tegra_overlay_plane_helper_funcs = {
- .atomic_check = tegra_plane_atomic_check,
- .atomic_update = tegra_plane_atomic_update,
- .atomic_disable = tegra_plane_atomic_disable,
-};
-
static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
struct tegra_dc *dc,
unsigned int index)
@@ -913,7 +890,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
return ERR_PTR(err);
}
- drm_plane_helper_add(&plane->base, &tegra_overlay_plane_helper_funcs);
+ drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
return &plane->base;
}
@@ -1161,6 +1138,11 @@ static void tegra_dc_commit_state(struct tegra_dc *dc,
value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1;
tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
+
+ err = clk_set_rate(dc->clk, state->pclk);
+ if (err < 0)
+ dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n",
+ dc->clk, state->pclk, err);
}
static void tegra_dc_stop(struct tegra_dc *dc)
@@ -1756,7 +1738,7 @@ static int tegra_dc_init(struct host1x_client *client)
struct drm_plane *cursor = NULL;
int err;
- dc->syncpt = host1x_syncpt_request(dc->dev, flags);
+ dc->syncpt = host1x_syncpt_request(client, flags);
if (!dc->syncpt)
dev_warn(dc->dev, "failed to allocate syncpoint\n");
@@ -1985,7 +1967,6 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
static int tegra_dc_probe(struct platform_device *pdev)
{
- const struct of_device_id *id;
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1994,14 +1975,11 @@ 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;
+ dc->soc = of_device_get_match_data(&pdev->dev);
spin_lock_init(&dc->lock);
INIT_LIST_HEAD(&dc->list);
dc->dev = &pdev->dev;
- dc->soc = id->data;
err = tegra_dc_parse_dt(dc);
if (err < 0)
@@ -2019,8 +1997,22 @@ static int tegra_dc_probe(struct platform_device *pdev)
return PTR_ERR(dc->rst);
}
- if (!dc->soc->broken_reset)
- reset_control_assert(dc->rst);
+ /* assert reset and disable clock */
+ if (!dc->soc->broken_reset) {
+ err = clk_prepare_enable(dc->clk);
+ if (err < 0)
+ return err;
+
+ usleep_range(2000, 4000);
+
+ err = reset_control_assert(dc->rst);
+ if (err < 0)
+ return err;
+
+ usleep_range(2000, 4000);
+
+ clk_disable_unprepare(dc->clk);
+ }
if (dc->soc->has_powergate) {
if (dc->pipe == 0)
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 4a268635749b..cb100b6e3282 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -10,6 +10,126 @@
#ifndef TEGRA_DC_H
#define TEGRA_DC_H 1
+#include <linux/host1x.h>
+
+#include <drm/drm_crtc.h>
+
+#include "drm.h"
+
+struct tegra_output;
+
+struct tegra_dc_stats {
+ unsigned long frames;
+ unsigned long vblank;
+ unsigned long underflow;
+ unsigned long overflow;
+};
+
+struct tegra_dc_soc_info {
+ bool supports_border_color;
+ bool supports_interlacing;
+ bool supports_cursor;
+ bool supports_block_linear;
+ unsigned int pitch_align;
+ bool has_powergate;
+ bool broken_reset;
+};
+
+struct tegra_dc {
+ struct host1x_client client;
+ struct host1x_syncpt *syncpt;
+ struct device *dev;
+ spinlock_t lock;
+
+ struct drm_crtc base;
+ unsigned int powergate;
+ int pipe;
+
+ struct clk *clk;
+ struct reset_control *rst;
+ void __iomem *regs;
+ int irq;
+
+ struct tegra_output *rgb;
+
+ struct tegra_dc_stats stats;
+ struct list_head list;
+
+ struct drm_info_list *debugfs_files;
+ struct drm_minor *minor;
+ struct dentry *debugfs;
+
+ /* page-flip handling */
+ struct drm_pending_vblank_event *event;
+
+ const struct tegra_dc_soc_info *soc;
+
+ struct iommu_domain *domain;
+};
+
+static inline struct tegra_dc *
+host1x_client_to_dc(struct host1x_client *client)
+{
+ return container_of(client, struct tegra_dc, client);
+}
+
+static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
+{
+ return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
+}
+
+static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value,
+ unsigned int offset)
+{
+ trace_dc_writel(dc->dev, offset, value);
+ writel(value, dc->regs + (offset << 2));
+}
+
+static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset)
+{
+ u32 value = readl(dc->regs + (offset << 2));
+
+ trace_dc_readl(dc->dev, offset, value);
+
+ return value;
+}
+
+struct tegra_dc_window {
+ struct {
+ unsigned int x;
+ unsigned int y;
+ unsigned int w;
+ unsigned int h;
+ } src;
+ struct {
+ unsigned int x;
+ unsigned int y;
+ unsigned int w;
+ unsigned int h;
+ } dst;
+ unsigned int bits_per_pixel;
+ unsigned int stride[2];
+ unsigned long base[3];
+ bool bottom_up;
+
+ struct tegra_bo_tiling tiling;
+ u32 format;
+ u32 swap;
+};
+
+/* from dc.c */
+void tegra_dc_commit(struct tegra_dc *dc);
+int tegra_dc_state_setup_clock(struct tegra_dc *dc,
+ struct drm_crtc_state *crtc_state,
+ struct clk *clk, unsigned long pclk,
+ unsigned int div);
+
+/* from rgb.c */
+int tegra_dc_rgb_probe(struct tegra_dc *dc);
+int tegra_dc_rgb_remove(struct tegra_dc *dc);
+int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc);
+int tegra_dc_rgb_exit(struct tegra_dc *dc);
+
#define DC_CMD_GENERAL_INCR_SYNCPT 0x000
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 597d563d636a..943bdf88c4a2 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -386,12 +386,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
unsigned int num_cmdbufs = args->num_cmdbufs;
unsigned int num_relocs = args->num_relocs;
unsigned int num_waitchks = args->num_waitchks;
- struct drm_tegra_cmdbuf __user *cmdbufs =
- (void __user *)(uintptr_t)args->cmdbufs;
- struct drm_tegra_reloc __user *relocs =
- (void __user *)(uintptr_t)args->relocs;
- struct drm_tegra_waitchk __user *waitchks =
- (void __user *)(uintptr_t)args->waitchks;
+ struct drm_tegra_cmdbuf __user *user_cmdbufs;
+ struct drm_tegra_reloc __user *user_relocs;
+ struct drm_tegra_waitchk __user *user_waitchks;
+ struct drm_tegra_syncpt __user *user_syncpt;
struct drm_tegra_syncpt syncpt;
struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
struct drm_gem_object **refs;
@@ -400,6 +398,11 @@ int tegra_drm_submit(struct tegra_drm_context *context,
unsigned int num_refs;
int err;
+ user_cmdbufs = u64_to_user_ptr(args->cmdbufs);
+ user_relocs = u64_to_user_ptr(args->relocs);
+ user_waitchks = u64_to_user_ptr(args->waitchks);
+ user_syncpt = u64_to_user_ptr(args->syncpts);
+
/* We don't yet support other than one syncpt_incr struct per submit */
if (args->num_syncpts != 1)
return -EINVAL;
@@ -440,7 +443,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
struct tegra_bo *obj;
u64 offset;
- if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) {
+ if (copy_from_user(&cmdbuf, user_cmdbufs, sizeof(cmdbuf))) {
err = -EFAULT;
goto fail;
}
@@ -476,7 +479,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
num_cmdbufs--;
- cmdbufs++;
+ user_cmdbufs++;
}
/* copy and resolve relocations from submit */
@@ -485,7 +488,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
struct tegra_bo *obj;
err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs],
- &relocs[num_relocs], drm,
+ &user_relocs[num_relocs], drm,
file);
if (err < 0)
goto fail;
@@ -519,9 +522,8 @@ int tegra_drm_submit(struct tegra_drm_context *context,
struct host1x_waitchk *wait = &job->waitchk[num_waitchks];
struct tegra_bo *obj;
- err = host1x_waitchk_copy_from_user(wait,
- &waitchks[num_waitchks],
- file);
+ err = host1x_waitchk_copy_from_user(
+ wait, &user_waitchks[num_waitchks], file);
if (err < 0)
goto fail;
@@ -539,8 +541,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
}
}
- if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
- sizeof(syncpt))) {
+ if (copy_from_user(&syncpt, user_syncpt, sizeof(syncpt))) {
err = -EFAULT;
goto fail;
}
@@ -1317,6 +1318,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra210-sor", },
{ .compatible = "nvidia,tegra210-sor1", },
{ .compatible = "nvidia,tegra210-vic", },
+ { .compatible = "nvidia,tegra186-vic", },
{ /* sentinel */ }
};
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 063f5d397526..ddae331ad8b6 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -119,104 +119,7 @@ void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *iova);
void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt,
dma_addr_t iova);
-struct tegra_dc_soc_info;
-struct tegra_output;
-
-struct tegra_dc_stats {
- unsigned long frames;
- unsigned long vblank;
- unsigned long underflow;
- unsigned long overflow;
-};
-
-struct tegra_dc {
- struct host1x_client client;
- struct host1x_syncpt *syncpt;
- struct device *dev;
- spinlock_t lock;
-
- struct drm_crtc base;
- unsigned int powergate;
- int pipe;
-
- struct clk *clk;
- struct reset_control *rst;
- void __iomem *regs;
- int irq;
-
- struct tegra_output *rgb;
-
- struct tegra_dc_stats stats;
- struct list_head list;
-
- struct drm_info_list *debugfs_files;
- struct drm_minor *minor;
- struct dentry *debugfs;
-
- /* page-flip handling */
- struct drm_pending_vblank_event *event;
-
- const struct tegra_dc_soc_info *soc;
-
- struct iommu_domain *domain;
-};
-
-static inline struct tegra_dc *
-host1x_client_to_dc(struct host1x_client *client)
-{
- return container_of(client, struct tegra_dc, client);
-}
-
-static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
-{
- return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
-}
-
-static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value,
- unsigned int offset)
-{
- trace_dc_writel(dc->dev, offset, value);
- writel(value, dc->regs + (offset << 2));
-}
-
-static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset)
-{
- u32 value = readl(dc->regs + (offset << 2));
-
- trace_dc_readl(dc->dev, offset, value);
-
- return value;
-}
-
-struct tegra_dc_window {
- struct {
- unsigned int x;
- unsigned int y;
- unsigned int w;
- unsigned int h;
- } src;
- struct {
- unsigned int x;
- unsigned int y;
- unsigned int w;
- unsigned int h;
- } dst;
- unsigned int bits_per_pixel;
- unsigned int stride[2];
- unsigned long base[3];
- bool bottom_up;
-
- struct tegra_bo_tiling tiling;
- u32 format;
- u32 swap;
-};
-
-/* from dc.c */
-void tegra_dc_commit(struct tegra_dc *dc);
-int tegra_dc_state_setup_clock(struct tegra_dc *dc,
- struct drm_crtc_state *crtc_state,
- struct clk *clk, unsigned long pclk,
- unsigned int div);
+struct cec_notifier;
struct tegra_output {
struct device_node *of_node;
@@ -225,6 +128,7 @@ struct tegra_output {
struct drm_panel *panel;
struct i2c_adapter *ddc;
const struct edid *edid;
+ struct cec_notifier *notifier;
unsigned int hpd_irq;
int hpd_gpio;
enum of_gpio_flags hpd_gpio_flags;
@@ -243,12 +147,6 @@ static inline struct tegra_output *connector_to_output(struct drm_connector *c)
return container_of(c, struct tegra_output, connector);
}
-/* from rgb.c */
-int tegra_dc_rgb_probe(struct tegra_dc *dc);
-int tegra_dc_rgb_remove(struct tegra_dc *dc);
-int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc);
-int tegra_dc_rgb_exit(struct tegra_dc *dc);
-
/* from output.c */
int tegra_output_probe(struct tegra_output *output);
void tegra_output_remove(struct tegra_output *output);
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 6ea070da7718..9a8ea93016a9 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -36,7 +36,7 @@ static int gr2d_init(struct host1x_client *client)
if (!gr2d->channel)
return -ENOMEM;
- client->syncpts[0] = host1x_syncpt_request(client->dev, flags);
+ client->syncpts[0] = host1x_syncpt_request(client, flags);
if (!client->syncpts[0]) {
host1x_channel_put(gr2d->channel);
return -ENOMEM;
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index cee2ab645cde..28c4ef63065b 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -46,7 +46,7 @@ static int gr3d_init(struct host1x_client *client)
if (!gr3d->channel)
return -ENOMEM;
- client->syncpts[0] = host1x_syncpt_request(client->dev, flags);
+ client->syncpts[0] = host1x_syncpt_request(client, flags);
if (!client->syncpts[0]) {
host1x_channel_put(gr3d->channel);
return -ENOMEM;
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 5b9d83b71943..6434b3d3d1ba 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -11,6 +11,7 @@
#include <linux/debugfs.h>
#include <linux/gpio.h>
#include <linux/hdmi.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
@@ -21,6 +22,8 @@
#include <sound/hda_verbs.h>
+#include <media/cec-notifier.h>
+
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
@@ -1663,20 +1666,15 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data)
static int tegra_hdmi_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
struct tegra_hdmi *hdmi;
struct resource *regs;
int err;
- match = of_match_node(tegra_hdmi_of_match, pdev->dev.of_node);
- if (!match)
- return -ENODEV;
-
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
- hdmi->config = match->data;
+ hdmi->config = of_device_get_match_data(&pdev->dev);
hdmi->dev = &pdev->dev;
hdmi->audio_source = AUTO;
@@ -1725,6 +1723,10 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
return PTR_ERR(hdmi->vdd);
}
+ hdmi->output.notifier = cec_notifier_get(&pdev->dev);
+ if (hdmi->output.notifier == NULL)
+ return -ENOMEM;
+
hdmi->output.dev = &pdev->dev;
err = tegra_output_probe(&hdmi->output);
@@ -1783,6 +1785,9 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
tegra_output_remove(&hdmi->output);
+ if (hdmi->output.notifier)
+ cec_notifier_put(hdmi->output.notifier);
+
return 0;
}
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index 595d1ec3e02e..1cfbacea8113 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -11,6 +11,8 @@
#include <drm/drm_panel.h>
#include "drm.h"
+#include <media/cec-notifier.h>
+
int tegra_output_connector_get_modes(struct drm_connector *connector)
{
struct tegra_output *output = connector_to_output(connector);
@@ -32,6 +34,7 @@ int tegra_output_connector_get_modes(struct drm_connector *connector)
else if (output->ddc)
edid = drm_get_edid(connector, output->ddc);
+ cec_notifier_set_phys_addr_from_edid(output->notifier, edid);
drm_mode_connector_update_edid_property(connector, edid);
if (edid) {
@@ -68,6 +71,9 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force)
status = connector_status_connected;
}
+ if (status != connector_status_connected)
+ cec_notifier_phys_addr_invalidate(output->notifier);
+
return status;
}
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 7ab1d1dc7cd7..4bcacd3f4861 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -2536,20 +2536,17 @@ MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
static int tegra_sor_probe(struct platform_device *pdev)
{
- const struct of_device_id *match;
struct device_node *np;
struct tegra_sor *sor;
struct resource *regs;
int err;
- match = of_match_device(tegra_sor_of_match, &pdev->dev);
-
sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL);
if (!sor)
return -ENOMEM;
+ sor->soc = of_device_get_match_data(&pdev->dev);
sor->output.dev = sor->dev = &pdev->dev;
- sor->soc = match->data;
sor->settings = devm_kmemdup(&pdev->dev, sor->soc->settings,
sor->soc->num_settings *
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 2448229fa653..18024183aa2b 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -167,7 +167,7 @@ static int vic_init(struct host1x_client *client)
goto detach_device;
}
- client->syncpts[0] = host1x_syncpt_request(client->dev, 0);
+ client->syncpts[0] = host1x_syncpt_request(client, 0);
if (!client->syncpts[0]) {
err = -ENOMEM;
goto free_channel;
@@ -270,29 +270,33 @@ static const struct vic_config vic_t210_config = {
.firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE,
};
+#define NVIDIA_TEGRA_186_VIC_FIRMWARE "nvidia/tegra186/vic04_ucode.bin"
+
+static const struct vic_config vic_t186_config = {
+ .firmware = NVIDIA_TEGRA_186_VIC_FIRMWARE,
+};
+
static const struct of_device_id vic_match[] = {
{ .compatible = "nvidia,tegra124-vic", .data = &vic_t124_config },
{ .compatible = "nvidia,tegra210-vic", .data = &vic_t210_config },
+ { .compatible = "nvidia,tegra186-vic", .data = &vic_t186_config },
{ },
};
static int vic_probe(struct platform_device *pdev)
{
- struct vic_config *vic_config = NULL;
struct device *dev = &pdev->dev;
struct host1x_syncpt **syncpts;
struct resource *regs;
- const struct of_device_id *match;
struct vic *vic;
int err;
- match = of_match_device(vic_match, dev);
- vic_config = (struct vic_config *)match->data;
-
vic = devm_kzalloc(dev, sizeof(*vic), GFP_KERNEL);
if (!vic)
return -ENOMEM;
+ vic->config = of_device_get_match_data(dev);
+
syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL);
if (!syncpts)
return -ENOMEM;
@@ -321,7 +325,7 @@ static int vic_probe(struct platform_device *pdev)
if (err < 0)
return err;
- err = falcon_read_firmware(&vic->falcon, vic_config->firmware);
+ err = falcon_read_firmware(&vic->falcon, vic->config->firmware);
if (err < 0)
goto exit_falcon;
@@ -334,7 +338,6 @@ static int vic_probe(struct platform_device *pdev)
vic->client.base.syncpts = syncpts;
vic->client.base.num_syncpts = 1;
vic->dev = dev;
- vic->config = vic_config;
INIT_LIST_HEAD(&vic->client.list);
vic->client.ops = &vic_ops;
@@ -405,3 +408,6 @@ MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE);
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE);
#endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_186_VIC_FIRMWARE);
+#endif