Skip to content

Commit

Permalink
Merge tag 'drm/tegra/for-4.20-rc1' of git://anongit.freedesktop.org/t…
Browse files Browse the repository at this point in the history
…egra/linux into drm-next

drm/tegra: Changes for v4.20-rc1

This contains initial Tegra194 support as well as a couple of fixes for
DMA/IOMMU integration.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thierry Reding <thierry.reding@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180927205051.30017-1-thierry.reding@gmail.com
  • Loading branch information
Dave Airlie committed Sep 27, 2018
2 parents db9825c + 5ac93f8 commit 2de0b0a
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 53 deletions.
73 changes: 73 additions & 0 deletions drivers/gpu/drm/tegra/dc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1988,6 +1988,28 @@ static int tegra_dc_init(struct host1x_client *client)
struct drm_plane *cursor = NULL;
int err;

/*
* XXX do not register DCs with no window groups because we cannot
* assign a primary plane to them, which in turn will cause KMS to
* crash.
*/
if (dc->soc->wgrps) {
bool has_wgrps = false;
unsigned int i;

for (i = 0; i < dc->soc->num_wgrps; i++) {
const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i];

if (wgrp->dc == dc->pipe && wgrp->num_windows > 0) {
has_wgrps = true;
break;
}
}

if (!has_wgrps)
return 0;
}

dc->syncpt = host1x_syncpt_request(client, flags);
if (!dc->syncpt)
dev_warn(dc->dev, "failed to allocate syncpoint\n");
Expand Down Expand Up @@ -2234,8 +2256,59 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
.num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
};

static const struct tegra_windowgroup_soc tegra194_dc_wgrps[] = {
{
.index = 0,
.dc = 0,
.windows = (const unsigned int[]) { 0 },
.num_windows = 1,
}, {
.index = 1,
.dc = 1,
.windows = (const unsigned int[]) { 1 },
.num_windows = 1,
}, {
.index = 2,
.dc = 1,
.windows = (const unsigned int[]) { 2 },
.num_windows = 1,
}, {
.index = 3,
.dc = 2,
.windows = (const unsigned int[]) { 3 },
.num_windows = 1,
}, {
.index = 4,
.dc = 2,
.windows = (const unsigned int[]) { 4 },
.num_windows = 1,
}, {
.index = 5,
.dc = 2,
.windows = (const unsigned int[]) { 5 },
.num_windows = 1,
},
};

static const struct tegra_dc_soc_info tegra194_dc_soc_info = {
.supports_background_color = true,
.supports_interlacing = true,
.supports_cursor = true,
.supports_block_linear = true,
.has_legacy_blending = false,
.pitch_align = 64,
.has_powergate = false,
.coupled_pm = false,
.has_nvdisplay = true,
.wgrps = tegra194_dc_wgrps,
.num_wgrps = ARRAY_SIZE(tegra194_dc_wgrps),
};

static const struct of_device_id tegra_dc_of_match[] = {
{
.compatible = "nvidia,tegra194-dc",
.data = &tegra194_dc_soc_info,
}, {
.compatible = "nvidia,tegra186-dc",
.data = &tegra186_dc_soc_info,
}, {
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/tegra/dc.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
#define SOR1_TIMING_CYA (1 << 27)
#define CURSOR_ENABLE (1 << 16)

#define SOR_ENABLE(x) (1 << (25 + (x)))
#define SOR_ENABLE(x) (1 << (25 + (((x) > 1) ? ((x) + 1) : (x))))

#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define CURSOR_THRESHOLD(x) (((x) & 0x03) << 24)
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/tegra/dpaux.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
* is no possibility to perform the I2C mode configuration in the
* HDMI path.
*/
err = tegra_dpaux_pad_config(dpaux, DPAUX_HYBRID_PADCTL_MODE_I2C);
err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
if (err < 0)
return err;

Expand Down Expand Up @@ -639,6 +639,7 @@ static const struct dev_pm_ops tegra_dpaux_pm_ops = {
};

static const struct of_device_id tegra_dpaux_of_match[] = {
{ .compatible = "nvidia,tegra194-dpaux", },
{ .compatible = "nvidia,tegra186-dpaux", },
{ .compatible = "nvidia,tegra210-dpaux", },
{ .compatible = "nvidia,tegra124-dpaux", },
Expand Down
35 changes: 17 additions & 18 deletions drivers/gpu/drm/tegra/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>

#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
#include <asm/dma-iommu.h>
#endif

#include "drm.h"
#include "gem.h"

Expand Down Expand Up @@ -1068,6 +1072,14 @@ struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client,
}

if (!shared || (shared && (group != tegra->group))) {
#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
if (client->dev->archdata.mapping) {
struct dma_iommu_mapping *mapping =
to_dma_iommu_mapping(client->dev);
arm_iommu_detach_device(client->dev);
arm_iommu_release_mapping(mapping);
}
#endif
err = iommu_attach_group(tegra->domain, group);
if (err < 0) {
iommu_group_put(group);
Expand Down Expand Up @@ -1216,31 +1228,15 @@ static int host1x_drm_remove(struct host1x_device *dev)
static int host1x_drm_suspend(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct tegra_drm *tegra = drm->dev_private;

drm_kms_helper_poll_disable(drm);
tegra_drm_fb_suspend(drm);

tegra->state = drm_atomic_helper_suspend(drm);
if (IS_ERR(tegra->state)) {
tegra_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm);
return PTR_ERR(tegra->state);
}

return 0;
return drm_mode_config_helper_suspend(drm);
}

static int host1x_drm_resume(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct tegra_drm *tegra = drm->dev_private;

drm_atomic_helper_resume(drm, tegra->state);
tegra_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm);

return 0;
return drm_mode_config_helper_resume(drm);
}
#endif

Expand Down Expand Up @@ -1275,6 +1271,9 @@ static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra186-sor", },
{ .compatible = "nvidia,tegra186-sor1", },
{ .compatible = "nvidia,tegra186-vic", },
{ .compatible = "nvidia,tegra194-display", },
{ .compatible = "nvidia,tegra194-dc", },
{ .compatible = "nvidia,tegra194-sor", },
{ /* sentinel */ }
};

Expand Down
4 changes: 0 additions & 4 deletions drivers/gpu/drm/tegra/drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ struct tegra_drm {
unsigned int pitch_align;

struct tegra_display_hub *hub;

struct drm_atomic_state *state;
};

struct tegra_drm_client;
Expand Down Expand Up @@ -186,8 +184,6 @@ int tegra_drm_fb_prepare(struct drm_device *drm);
void tegra_drm_fb_free(struct drm_device *drm);
int tegra_drm_fb_init(struct drm_device *drm);
void tegra_drm_fb_exit(struct drm_device *drm);
void tegra_drm_fb_suspend(struct drm_device *drm);
void tegra_drm_fb_resume(struct drm_device *drm);

extern struct platform_driver tegra_display_hub_driver;
extern struct platform_driver tegra_dc_driver;
Expand Down
24 changes: 1 addition & 23 deletions drivers/gpu/drm/tegra/fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ static void tegra_fbdev_exit(struct tegra_fbdev *fbdev)
/* Undo the special mapping we made in fbdev probe. */
if (bo && bo->pages) {
vunmap(bo->vaddr);
bo->vaddr = 0;
bo->vaddr = NULL;
}

drm_framebuffer_remove(fbdev->fb);
Expand Down Expand Up @@ -412,25 +412,3 @@ void tegra_drm_fb_exit(struct drm_device *drm)
tegra_fbdev_exit(tegra->fbdev);
#endif
}

void tegra_drm_fb_suspend(struct drm_device *drm)
{
#ifdef CONFIG_DRM_FBDEV_EMULATION
struct tegra_drm *tegra = drm->dev_private;

console_lock();
drm_fb_helper_set_suspend(&tegra->fbdev->base, 1);
console_unlock();
#endif
}

void tegra_drm_fb_resume(struct drm_device *drm)
{
#ifdef CONFIG_DRM_FBDEV_EMULATION
struct tegra_drm *tegra = drm->dev_private;

console_lock();
drm_fb_helper_set_suspend(&tegra->fbdev->base, 0);
console_unlock();
#endif
}
19 changes: 15 additions & 4 deletions drivers/gpu/drm/tegra/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,10 +758,12 @@ static int tegra_display_hub_probe(struct platform_device *pdev)
return err;
}

hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc");
if (IS_ERR(hub->clk_dsc)) {
err = PTR_ERR(hub->clk_dsc);
return err;
if (hub->soc->supports_dsc) {
hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc");
if (IS_ERR(hub->clk_dsc)) {
err = PTR_ERR(hub->clk_dsc);
return err;
}
}

hub->clk_hub = devm_clk_get(&pdev->dev, "hub");
Expand Down Expand Up @@ -890,10 +892,19 @@ static const struct dev_pm_ops tegra_display_hub_pm_ops = {

static const struct tegra_display_hub_soc tegra186_display_hub = {
.num_wgrps = 6,
.supports_dsc = true,
};

static const struct tegra_display_hub_soc tegra194_display_hub = {
.num_wgrps = 6,
.supports_dsc = false,
};

static const struct of_device_id tegra_display_hub_of_match[] = {
{
.compatible = "nvidia,tegra194-display",
.data = &tegra194_display_hub
}, {
.compatible = "nvidia,tegra186-display",
.data = &tegra186_display_hub
}, {
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/tegra/hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ to_tegra_shared_plane(struct drm_plane *plane)

struct tegra_display_hub_soc {
unsigned int num_wgrps;
bool supports_dsc;
};

struct tegra_display_hub {
Expand Down
Loading

0 comments on commit 2de0b0a

Please sign in to comment.