mirror of https://gitee.com/openkylin/linux.git
drm/tegra: Changes for v4.20-rc1
This contains initial Tegra194 support as well as a couple of fixes for DMA/IOMMU integration. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAlutQZcTHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zoS1QD/48ft2dEY9xa7fB2z/jXQ3krtGX0OMv aWaR4Wb30FJxwT5B8u6hIrzxXZFIk5kU9IANErdYwFe95mjQNIpxNgUdfvK5xA7b hG4MQkUsYm/xNitnbAfNDEaZ3GK4Z3OTMC0k6Hk9EIY3gMfwirmG51ge7fMF1+l2 0ZHmWP5E6ONiRJB5HByT635un71icvLQfpfl5FhCNva0LjXZvIrxB68F+X8O8PMR ZrQ/7bcfYMsgZA9B1TI3NjfKeb3IZbbTVFgrmvww/ZtOJnZR4wbMdr6TavQlJ2Yc Sbg3/q/jSMH8TzBcdMd6lLfi2xkOHig/pL8het+JpzzvZJb/fW6536o4mQYSfqlq B8Hep8vhHIP+/oOcH5V35184xCKDeZrk67yj4GMak27vSJXEREZMidVwyK6G4zbx v0Sx8MV7YQbdYLOS9plSRnqha62isFUfN3dEg4+k0SwFFuedkX2RFQNgpja2ZsLo OKQeUFDa1dEs/hePR6RcmWVIPxl+dhmEyU4plFmGzY/MjyrndqBhew1DrUa1GaLJ 9QOmOXhoQSZLB0DIim/CkcuuSMpqv4TmP4mHJrRVgu+mBkyhvBtdW9ANhsRaM7LF O7MPs+vypCyxrNukKNoWdG2VZBtXJ8Uuk4jVtSu1ttY/cSD92Ygd/0B38jmqHQxW 22bIZJv9YcR3mg== =1zNu -----END PGP SIGNATURE----- Merge tag 'drm/tegra/for-4.20-rc1' of git://anongit.freedesktop.org/tegra/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
This commit is contained in:
commit
2de0b0a158
|
@ -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");
|
||||
|
@ -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,
|
||||
}, {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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", },
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */ }
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
@ -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
|
||||
}, {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -282,6 +282,85 @@ static const struct tegra_sor_hdmi_settings tegra186_sor_hdmi_defaults[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct tegra_sor_hdmi_settings tegra194_sor_hdmi_defaults[] = {
|
||||
{
|
||||
.frequency = 54000000,
|
||||
.vcocap = 0,
|
||||
.filter = 5,
|
||||
.ichpmp = 5,
|
||||
.loadadj = 3,
|
||||
.tmds_termadj = 0xf,
|
||||
.tx_pu_value = 0,
|
||||
.bg_temp_coef = 3,
|
||||
.bg_vref_level = 8,
|
||||
.avdd10_level = 4,
|
||||
.avdd14_level = 4,
|
||||
.sparepll = 0x54,
|
||||
.drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },
|
||||
.preemphasis = { 0x00, 0x00, 0x00, 0x00 },
|
||||
}, {
|
||||
.frequency = 75000000,
|
||||
.vcocap = 1,
|
||||
.filter = 5,
|
||||
.ichpmp = 5,
|
||||
.loadadj = 3,
|
||||
.tmds_termadj = 0xf,
|
||||
.tx_pu_value = 0,
|
||||
.bg_temp_coef = 3,
|
||||
.bg_vref_level = 8,
|
||||
.avdd10_level = 4,
|
||||
.avdd14_level = 4,
|
||||
.sparepll = 0x44,
|
||||
.drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },
|
||||
.preemphasis = { 0x00, 0x00, 0x00, 0x00 },
|
||||
}, {
|
||||
.frequency = 150000000,
|
||||
.vcocap = 3,
|
||||
.filter = 5,
|
||||
.ichpmp = 5,
|
||||
.loadadj = 3,
|
||||
.tmds_termadj = 15,
|
||||
.tx_pu_value = 0x66 /* 0 */,
|
||||
.bg_temp_coef = 3,
|
||||
.bg_vref_level = 8,
|
||||
.avdd10_level = 4,
|
||||
.avdd14_level = 4,
|
||||
.sparepll = 0x00, /* 0x34 */
|
||||
.drive_current = { 0x3a, 0x3a, 0x3a, 0x37 },
|
||||
.preemphasis = { 0x00, 0x00, 0x00, 0x00 },
|
||||
}, {
|
||||
.frequency = 300000000,
|
||||
.vcocap = 3,
|
||||
.filter = 5,
|
||||
.ichpmp = 5,
|
||||
.loadadj = 3,
|
||||
.tmds_termadj = 15,
|
||||
.tx_pu_value = 64,
|
||||
.bg_temp_coef = 3,
|
||||
.bg_vref_level = 8,
|
||||
.avdd10_level = 4,
|
||||
.avdd14_level = 4,
|
||||
.sparepll = 0x34,
|
||||
.drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },
|
||||
.preemphasis = { 0x00, 0x00, 0x00, 0x00 },
|
||||
}, {
|
||||
.frequency = 600000000,
|
||||
.vcocap = 3,
|
||||
.filter = 5,
|
||||
.ichpmp = 5,
|
||||
.loadadj = 3,
|
||||
.tmds_termadj = 12,
|
||||
.tx_pu_value = 96,
|
||||
.bg_temp_coef = 3,
|
||||
.bg_vref_level = 8,
|
||||
.avdd10_level = 4,
|
||||
.avdd14_level = 4,
|
||||
.sparepll = 0x34,
|
||||
.drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },
|
||||
.preemphasis = { 0x00, 0x00, 0x00, 0x00 },
|
||||
}
|
||||
};
|
||||
|
||||
struct tegra_sor_regs {
|
||||
unsigned int head_state0;
|
||||
unsigned int head_state1;
|
||||
|
@ -2894,7 +2973,38 @@ static const struct tegra_sor_soc tegra186_sor1 = {
|
|||
.xbar_cfg = tegra124_sor_xbar_cfg,
|
||||
};
|
||||
|
||||
static const struct tegra_sor_regs tegra194_sor_regs = {
|
||||
.head_state0 = 0x151,
|
||||
.head_state1 = 0x155,
|
||||
.head_state2 = 0x159,
|
||||
.head_state3 = 0x15d,
|
||||
.head_state4 = 0x161,
|
||||
.head_state5 = 0x165,
|
||||
.pll0 = 0x169,
|
||||
.pll1 = 0x16a,
|
||||
.pll2 = 0x16b,
|
||||
.pll3 = 0x16c,
|
||||
.dp_padctl0 = 0x16e,
|
||||
.dp_padctl2 = 0x16f,
|
||||
};
|
||||
|
||||
static const struct tegra_sor_soc tegra194_sor = {
|
||||
.supports_edp = true,
|
||||
.supports_lvds = false,
|
||||
.supports_hdmi = true,
|
||||
.supports_dp = true,
|
||||
|
||||
.regs = &tegra194_sor_regs,
|
||||
.has_nvdisplay = true,
|
||||
|
||||
.num_settings = ARRAY_SIZE(tegra194_sor_hdmi_defaults),
|
||||
.settings = tegra194_sor_hdmi_defaults,
|
||||
|
||||
.xbar_cfg = tegra210_sor_xbar_cfg,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_sor_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra194-sor", .data = &tegra194_sor },
|
||||
{ .compatible = "nvidia,tegra186-sor1", .data = &tegra186_sor1 },
|
||||
{ .compatible = "nvidia,tegra186-sor", .data = &tegra186_sor },
|
||||
{ .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 },
|
||||
|
|
|
@ -331,7 +331,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
|
|||
struct bus_type host1x_bus_type = {
|
||||
.name = "host1x",
|
||||
.match = host1x_device_match,
|
||||
.dma_configure = host1x_dma_configure,
|
||||
.dma_configure = host1x_dma_configure,
|
||||
.pm = &host1x_device_pm_ops,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include <trace/events/host1x.h>
|
||||
#undef CREATE_TRACE_POINTS
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
|
||||
#include <asm/dma-iommu.h>
|
||||
#endif
|
||||
|
||||
#include "bus.h"
|
||||
#include "channel.h"
|
||||
#include "debug.h"
|
||||
|
@ -217,7 +221,14 @@ static int host1x_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "failed to get reset: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
|
||||
if (host->dev->archdata.mapping) {
|
||||
struct dma_iommu_mapping *mapping =
|
||||
to_dma_iommu_mapping(host->dev);
|
||||
arm_iommu_detach_device(host->dev);
|
||||
arm_iommu_release_mapping(mapping);
|
||||
}
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
|
||||
goto skip_iommu;
|
||||
|
||||
|
|
Loading…
Reference in New Issue