Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "I realise this a bit bigger than I would want at this point. Exynos is a large chunk, I got them to half what they wanted already, and hey its ARM based, so not going to hurt many people. Radeon has only two fixes, but the PLL fixes were a bit bigger, but required for a lot of scenarios, the fence fix is really urgent. vmwgfx: I've pulled in a dumb ioctl support patch that I was going to shove in later and cc stable, but we need it asap, its mainly to stop mesa growing a really ugly dependency in userspace to run stuff on vmware, and if I don't stick it in the kernel now, everyone will have to ship ugly userspace libs to workaround it. nouveau: single urgent fix found in F18 testing, causes X to not start properly when f18 plymouth is used i915: smattering of fixes and debug quieting gma500: single regression fix So as I said a bit large, but its fairly well scattered and its all stuff I'll be shipping in F18's 3.6 kernel." * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (26 commits) drm/nouveau: fix booting with plymouth + dumb support drm/radeon: make 64bit fences more robust v3 drm/radeon: rework pll selection (v3) drm: Drop the NV12M and YUV420M formats drm/exynos: remove DRM_FORMAT_NV12M from plane module drm/exynos: fix double call of drm_prime_(init/destroy)_file_private drm/exynos: add dummy support for dmabuf-mmap drm/exynos: Add missing braces around sizeof in exynos_mixer.c drm/exynos: Add missing braces around sizeof in exynos_hdmi.c drm/exynos: Make g2d_pm_ops static drm/exynos: Add dependency for G2D in Kconfig drm/exynos: fixed page align bug. drm/exynos: Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(.. [1] drm/exynos: Use devm_* functions in exynos_drm_g2d.c file drm/exynos: Use devm_kzalloc in exynos_drm_hdmi.c file drm/exynos: Use devm_kzalloc in exynos_drm_vidi.c file drm/exynos: Remove redundant check in exynos_drm_fimd.c file drm/exynos: Remove redundant check in exynos_hdmi.c file vmwgfx: add dumb ioctl support gma500: Fix regression on Oaktrail devices ...
This commit is contained in:
Коммит
dd383af6aa
|
@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI
|
|||
|
||||
config DRM_EXYNOS_G2D
|
||||
bool "Exynos DRM G2D"
|
||||
depends on DRM_EXYNOS
|
||||
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D
|
||||
help
|
||||
Choose this option if you want to use Exynos G2D for DRM.
|
||||
|
|
|
@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
static struct dma_buf_ops exynos_dmabuf_ops = {
|
||||
.map_dma_buf = exynos_gem_map_dma_buf,
|
||||
.unmap_dma_buf = exynos_gem_unmap_dma_buf,
|
||||
|
@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = {
|
|||
.kmap_atomic = exynos_gem_dmabuf_kmap_atomic,
|
||||
.kunmap = exynos_gem_dmabuf_kunmap,
|
||||
.kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic,
|
||||
.mmap = exynos_gem_dmabuf_mmap,
|
||||
.release = exynos_dmabuf_release,
|
||||
};
|
||||
|
||||
|
|
|
@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
|
|||
if (!file_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_prime_init_file_private(&file->prime);
|
||||
file->driver_priv = file_priv;
|
||||
|
||||
return exynos_drm_subdrv_open(dev, file);
|
||||
|
@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
|
|||
e->base.destroy(&e->base);
|
||||
}
|
||||
}
|
||||
drm_prime_destroy_file_private(&file->prime);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
||||
exynos_drm_subdrv_close(dev, file);
|
||||
|
|
|
@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to find registers\n");
|
||||
ret = -ENOENT;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
ctx->regs = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!ctx->regs) {
|
||||
|
|
|
@ -129,7 +129,6 @@ struct g2d_runqueue_node {
|
|||
struct g2d_data {
|
||||
struct device *dev;
|
||||
struct clk *gate_clk;
|
||||
struct resource *regs_res;
|
||||
void __iomem *regs;
|
||||
int irq;
|
||||
struct workqueue_struct *g2d_workq;
|
||||
|
@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)
|
|||
struct exynos_drm_subdrv *subdrv;
|
||||
int ret;
|
||||
|
||||
g2d = kzalloc(sizeof(*g2d), GFP_KERNEL);
|
||||
g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL);
|
||||
if (!g2d) {
|
||||
dev_err(dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev)
|
|||
|
||||
g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
|
||||
sizeof(struct g2d_runqueue_node), 0, 0, NULL);
|
||||
if (!g2d->runqueue_slab) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
if (!g2d->runqueue_slab)
|
||||
return -ENOMEM;
|
||||
|
||||
g2d->dev = dev;
|
||||
|
||||
|
@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev)
|
|||
pm_runtime_enable(dev);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "failed to get I/O memory\n");
|
||||
ret = -ENOENT;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
g2d->regs_res = request_mem_region(res->start, resource_size(res),
|
||||
dev_name(dev));
|
||||
if (!g2d->regs_res) {
|
||||
dev_err(dev, "failed to request I/O memory\n");
|
||||
ret = -ENOENT;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
g2d->regs = ioremap(res->start, resource_size(res));
|
||||
g2d->regs = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!g2d->regs) {
|
||||
dev_err(dev, "failed to remap I/O memory\n");
|
||||
ret = -ENXIO;
|
||||
goto err_release_res;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
g2d->irq = platform_get_irq(pdev, 0);
|
||||
if (g2d->irq < 0) {
|
||||
dev_err(dev, "failed to get irq\n");
|
||||
ret = g2d->irq;
|
||||
goto err_unmap_base;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d);
|
||||
ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0,
|
||||
"drm_g2d", g2d);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "irq request failed\n");
|
||||
goto err_unmap_base;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, g2d);
|
||||
|
@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)
|
|||
ret = exynos_drm_subdrv_register(subdrv);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to register drm g2d device\n");
|
||||
goto err_free_irq;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n",
|
||||
|
@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev)
|
|||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(g2d->irq, g2d);
|
||||
err_unmap_base:
|
||||
iounmap(g2d->regs);
|
||||
err_release_res:
|
||||
release_resource(g2d->regs_res);
|
||||
kfree(g2d->regs_res);
|
||||
err_put_clk:
|
||||
pm_runtime_disable(dev);
|
||||
clk_put(g2d->gate_clk);
|
||||
|
@ -862,8 +840,6 @@ err_destroy_workqueue:
|
|||
destroy_workqueue(g2d->g2d_workq);
|
||||
err_destroy_slab:
|
||||
kmem_cache_destroy(g2d->runqueue_slab);
|
||||
err_free_mem:
|
||||
kfree(g2d);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev)
|
|||
|
||||
cancel_work_sync(&g2d->runqueue_work);
|
||||
exynos_drm_subdrv_unregister(&g2d->subdrv);
|
||||
free_irq(g2d->irq, g2d);
|
||||
|
||||
while (g2d->runqueue_node) {
|
||||
g2d_free_runqueue_node(g2d, g2d->runqueue_node);
|
||||
g2d->runqueue_node = g2d_get_runqueue_node(g2d);
|
||||
}
|
||||
|
||||
iounmap(g2d->regs);
|
||||
release_resource(g2d->regs_res);
|
||||
kfree(g2d->regs_res);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_put(g2d->gate_clk);
|
||||
|
||||
g2d_fini_cmdlist(g2d);
|
||||
destroy_workqueue(g2d->g2d_workq);
|
||||
kmem_cache_destroy(g2d->runqueue_slab);
|
||||
kfree(g2d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);
|
||||
static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);
|
||||
|
||||
struct platform_driver g2d_driver = {
|
||||
.probe = g2d_probe,
|
||||
|
|
|
@ -122,7 +122,7 @@ fail:
|
|||
__free_page(pages[i]);
|
||||
|
||||
drm_free_large(pages);
|
||||
return ERR_PTR(PTR_ERR(p));
|
||||
return ERR_CAST(p);
|
||||
}
|
||||
|
||||
static void exynos_gem_put_pages(struct drm_gem_object *obj,
|
||||
|
@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
|
|||
*/
|
||||
|
||||
args->pitch = args->width * ((args->bpp + 7) / 8);
|
||||
args->size = PAGE_ALIGN(args->pitch * args->height);
|
||||
args->size = args->pitch * args->height;
|
||||
|
||||
exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
|
||||
if (IS_ERR(exynos_gem_obj))
|
||||
|
|
|
@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
|
|||
|
||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx) {
|
||||
DRM_LOG_KMS("failed to alloc common hdmi context.\n");
|
||||
return -ENOMEM;
|
||||
|
@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)
|
|||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||
|
||||
exynos_drm_subdrv_unregister(&ctx->subdrv);
|
||||
kfree(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ static const uint32_t formats[] = {
|
|||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_NV12M,
|
||||
DRM_FORMAT_NV12MT,
|
||||
};
|
||||
|
||||
|
|
|
@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev)
|
|||
|
||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev)
|
|||
ctx->raw_edid = NULL;
|
||||
}
|
||||
|
||||
kfree(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
|
|||
|
||||
DRM_DEBUG_KMS("HDMI resource init\n");
|
||||
|
||||
memset(res, 0, sizeof *res);
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
/* get clocks, power */
|
||||
res->hdmi = clk_get(dev, "hdmi");
|
||||
|
@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
|
|||
clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
|
||||
|
||||
res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
|
||||
sizeof res->regul_bulk[0], GFP_KERNEL);
|
||||
sizeof(res->regul_bulk[0]), GFP_KERNEL);
|
||||
if (!res->regul_bulk) {
|
||||
DRM_ERROR("failed to get memory for regulators\n");
|
||||
goto fail;
|
||||
|
@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata)
|
|||
clk_put(res->sclk_hdmi);
|
||||
if (!IS_ERR_OR_NULL(res->hdmi))
|
||||
clk_put(res->hdmi);
|
||||
memset(res, 0, sizeof *res);
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DRM_ERROR("failed to find registers\n");
|
||||
ret = -ENOENT;
|
||||
goto err_resource;
|
||||
}
|
||||
|
||||
hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!hdata->regs) {
|
||||
|
|
|
@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res,
|
|||
static void vp_default_filter(struct mixer_resources *res)
|
||||
{
|
||||
vp_filter_set(res, VP_POLY8_Y0_LL,
|
||||
filter_y_horiz_tap8, sizeof filter_y_horiz_tap8);
|
||||
filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
|
||||
vp_filter_set(res, VP_POLY4_Y0_LL,
|
||||
filter_y_vert_tap4, sizeof filter_y_vert_tap4);
|
||||
filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
|
||||
vp_filter_set(res, VP_POLY4_C0_LL,
|
||||
filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4);
|
||||
filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
|
||||
}
|
||||
|
||||
static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
|
||||
|
|
|
@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = {
|
|||
.pos = DSPAPOS,
|
||||
.surf = DSPASURF,
|
||||
.addr = MRST_DSPABASE,
|
||||
.base = MRST_DSPABASE,
|
||||
.status = PIPEASTAT,
|
||||
.linoff = DSPALINOFF,
|
||||
.tileoff = DSPATILEOFF,
|
||||
|
@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = {
|
|||
.pos = DSPBPOS,
|
||||
.surf = DSPBSURF,
|
||||
.addr = DSPBBASE,
|
||||
.base = DSPBBASE,
|
||||
.status = PIPEBSTAT,
|
||||
.linoff = DSPBLINOFF,
|
||||
.tileoff = DSPBTILEOFF,
|
||||
|
|
|
@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
spin_lock_init(&dev_priv->irq_lock);
|
||||
spin_lock_init(&dev_priv->error_lock);
|
||||
spin_lock_init(&dev_priv->rps_lock);
|
||||
spin_lock_init(&dev_priv->dpio_lock);
|
||||
|
||||
if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
|
||||
dev_priv->num_pipe = 3;
|
||||
|
|
|
@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev)
|
|||
dev->driver->irq_handler = i8xx_irq_handler;
|
||||
dev->driver->irq_uninstall = i8xx_irq_uninstall;
|
||||
} else if (INTEL_INFO(dev)->gen == 3) {
|
||||
/* IIR "flip pending" means done if this bit is set */
|
||||
I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));
|
||||
|
||||
dev->driver->irq_preinstall = i915_irq_preinstall;
|
||||
dev->driver->irq_postinstall = i915_irq_postinstall;
|
||||
dev->driver->irq_uninstall = i915_irq_uninstall;
|
||||
|
|
|
@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
|
|||
"PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
|
||||
reg, pipe_name(pipe));
|
||||
|
||||
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
|
||||
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
|
||||
&& (val & DP_PIPEB_SELECT),
|
||||
"IBX PCH dp port still using transcoder B\n");
|
||||
}
|
||||
|
||||
|
@ -1388,7 +1389,8 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
|
|||
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
|
||||
reg, pipe_name(pipe));
|
||||
|
||||
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT),
|
||||
WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0
|
||||
&& (val & SDVO_PIPE_B_SELECT),
|
||||
"IBX PCH hdmi port still using transcoder B\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
|||
break;
|
||||
}
|
||||
|
||||
intel_dp_i2c_init(intel_dp, intel_connector, name);
|
||||
|
||||
/* Cache some DPCD data in the eDP case */
|
||||
if (is_edp(intel_dp)) {
|
||||
bool ret;
|
||||
struct edp_power_seq cur, vbt;
|
||||
u32 pp_on, pp_off, pp_div;
|
||||
struct edid *edid;
|
||||
|
||||
pp_on = I915_READ(PCH_PP_ON_DELAYS);
|
||||
pp_off = I915_READ(PCH_PP_OFF_DELAYS);
|
||||
|
@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
|||
|
||||
DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
|
||||
intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
|
||||
}
|
||||
|
||||
intel_dp_i2c_init(intel_dp, intel_connector, name);
|
||||
|
||||
if (is_edp(intel_dp)) {
|
||||
bool ret;
|
||||
struct edid *edid;
|
||||
|
||||
ironlake_edp_panel_vdd_on(intel_dp);
|
||||
ret = intel_dp_get_dpcd(intel_dp);
|
||||
|
|
|
@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv)
|
|||
return val;
|
||||
}
|
||||
|
||||
u32 intel_panel_get_max_backlight(struct drm_device *dev)
|
||||
static u32 _intel_panel_get_max_backlight(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 max;
|
||||
|
||||
max = i915_read_blc_pwm_ctl(dev_priv);
|
||||
if (max == 0) {
|
||||
/* XXX add code here to query mode clock or hardware clock
|
||||
* and program max PWM appropriately.
|
||||
*/
|
||||
pr_warn_once("fixme: max PWM is zero\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
max >>= 16;
|
||||
|
@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)
|
|||
max *= 0xff;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
u32 intel_panel_get_max_backlight(struct drm_device *dev)
|
||||
{
|
||||
u32 max;
|
||||
|
||||
max = _intel_panel_get_max_backlight(dev);
|
||||
if (max == 0) {
|
||||
/* XXX add code here to query mode clock or hardware clock
|
||||
* and program max PWM appropriately.
|
||||
*/
|
||||
pr_warn_once("fixme: max PWM is zero\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
|
||||
return max;
|
||||
}
|
||||
|
@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev)
|
|||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.type = BACKLIGHT_RAW;
|
||||
props.max_brightness = intel_panel_get_max_backlight(dev);
|
||||
props.max_brightness = _intel_panel_get_max_backlight(dev);
|
||||
if (props.max_brightness == 0) {
|
||||
DRM_ERROR("Failed to get maximum backlight value\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
dev_priv->backlight =
|
||||
backlight_device_register("intel_backlight",
|
||||
&connector->kdev, dev,
|
||||
|
|
|
@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev)
|
|||
|
||||
if (IS_PINEVIEW(dev))
|
||||
I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY));
|
||||
|
||||
/* IIR "flip pending" means done if this bit is set */
|
||||
I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));
|
||||
}
|
||||
|
||||
static void i85x_init_clock_gating(struct drm_device *dev)
|
||||
|
|
|
@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
|||
hotplug_mask = intel_sdvo->is_sdvob ?
|
||||
SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
|
||||
}
|
||||
dev_priv->hotplug_supported_mask |= hotplug_mask;
|
||||
|
||||
drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
|
||||
|
||||
|
@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
|||
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
|
||||
goto err;
|
||||
|
||||
/* Set up hotplug command - note paranoia about contents of reply.
|
||||
* We assume that the hardware is in a sane state, and only touch
|
||||
* the bits we think we understand.
|
||||
*/
|
||||
intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG,
|
||||
&intel_sdvo->hotplug_active, 2);
|
||||
intel_sdvo->hotplug_active[0] &= ~0x3;
|
||||
|
||||
if (intel_sdvo_output_setup(intel_sdvo,
|
||||
intel_sdvo->caps.output_flags) != true) {
|
||||
DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
|
||||
|
@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* Only enable the hotplug irq if we need it, to work around noisy
|
||||
* hotplug lines.
|
||||
*/
|
||||
if (intel_sdvo->hotplug_active[0])
|
||||
dev_priv->hotplug_supported_mask |= hotplug_mask;
|
||||
|
||||
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
|
|
|
@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
|
|||
args->size = args->pitch * args->height;
|
||||
args->size = roundup(args->size, PAGE_SIZE);
|
||||
|
||||
ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo);
|
||||
ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1479,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_get_pll_use_mask - look up a mask of which pplls are in use
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the mask of which PPLLs (Pixel PLLs) are in use.
|
||||
*/
|
||||
static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_crtc *test_crtc;
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
u32 pll_in_use = 0;
|
||||
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
return pll_in_use;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
|
||||
* also in DP mode. For DP, a single PPLL can be used for all DP
|
||||
* crtcs/encoders.
|
||||
*/
|
||||
static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_encoder *test_encoder;
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
/* for DP use the same PLL for all */
|
||||
radeon_test_crtc = to_radeon_crtc(test_encoder->crtc);
|
||||
if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
|
||||
return radeon_test_crtc->pll_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ATOM_PPLL_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
|
||||
*
|
||||
* @crtc: drm crtc
|
||||
*
|
||||
* Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
|
||||
* a single PPLL can be used for all DP crtcs/encoders. For non-DP
|
||||
* monitors a dedicated PPLL must be used. If a particular board has
|
||||
* an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
|
||||
* as there is no need to program the PLL itself. If we are not able to
|
||||
* allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
|
||||
* avoid messing up an existing monitor.
|
||||
*
|
||||
* Asic specific PLL information
|
||||
*
|
||||
* DCE 6.1
|
||||
* - PPLL2 is only available to UNIPHYA (both DP and non-DP)
|
||||
* - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
|
||||
*
|
||||
* DCE 6.0
|
||||
* - PPLL0 is available to all UNIPHY (DP only)
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
* DCE 5.0
|
||||
* - DCPLL is available to all UNIPHY (DP only)
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
* DCE 3.0/4.0/4.1
|
||||
* - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
|
||||
*
|
||||
*/
|
||||
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *test_encoder;
|
||||
struct drm_crtc *test_crtc;
|
||||
uint32_t pll_in_use = 0;
|
||||
u32 pll_in_use;
|
||||
int pll;
|
||||
|
||||
if (ASIC_IS_DCE61(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
@ -1498,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
|
||||
if ((test_radeon_encoder->encoder_id ==
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
|
||||
(dig->linkb == false)) /* UNIPHY A uses PPLL2 */
|
||||
(dig->linkb == false))
|
||||
/* UNIPHY A uses PPLL2 */
|
||||
return ATOM_PPLL2;
|
||||
else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
/* UNIPHY B/C/D/E/F */
|
||||
if (rdev->clock.dp_extclk)
|
||||
/* skip PPLL programming if using ext clock */
|
||||
return ATOM_PPLL_INVALID;
|
||||
else {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* UNIPHY B/C/D/E/F */
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
|
||||
(radeon_test_crtc->pll_id == ATOM_PPLL1))
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
if (!(pll_in_use & 4))
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL0)))
|
||||
return ATOM_PPLL0;
|
||||
return ATOM_PPLL1;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
|
||||
/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
|
||||
* depending on the asic:
|
||||
* DCE4: PPLL or ext clock
|
||||
* DCE5: DCPLL or ext clock
|
||||
* DCE5: PPLL, DCPLL, or ext clock
|
||||
* DCE6: PPLL, PPLL0, or ext clock
|
||||
*
|
||||
* Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
|
||||
* PPLL/DCPLL programming and only program the DP DTO for the
|
||||
|
@ -1531,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
*/
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
|
||||
if (rdev->clock.dp_extclk)
|
||||
/* skip PPLL programming if using ext clock */
|
||||
return ATOM_PPLL_INVALID;
|
||||
else if (ASIC_IS_DCE6(rdev))
|
||||
/* use PPLL0 for all DP */
|
||||
return ATOM_PPLL0;
|
||||
else if (ASIC_IS_DCE5(rdev))
|
||||
/* use DCPLL for all DP */
|
||||
return ATOM_DCPLL;
|
||||
else {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, pick one of the plls */
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
|
||||
(radeon_test_crtc->pll_id <= ATOM_PPLL2))
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
if (!(pll_in_use & 1))
|
||||
/* all other cases */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
return ATOM_PPLL2;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else
|
||||
/* use PPLL1 or PPLL2 */
|
||||
return radeon_crtc->crtc_id;
|
||||
|
||||
}
|
||||
|
@ -1697,7 +1792,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
|
|||
break;
|
||||
}
|
||||
done:
|
||||
radeon_crtc->pll_id = -1;
|
||||
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
|
||||
|
@ -1746,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
|
|||
else
|
||||
radeon_crtc->crtc_offset = 0;
|
||||
}
|
||||
radeon_crtc->pll_id = -1;
|
||||
radeon_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev,
|
|||
*/
|
||||
void radeon_fence_process(struct radeon_device *rdev, int ring)
|
||||
{
|
||||
uint64_t seq, last_seq;
|
||||
uint64_t seq, last_seq, last_emitted;
|
||||
unsigned count_loop = 0;
|
||||
bool wake = false;
|
||||
|
||||
|
@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)
|
|||
*/
|
||||
last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);
|
||||
do {
|
||||
last_emitted = rdev->fence_drv[ring].sync_seq[ring];
|
||||
seq = radeon_fence_read(rdev, ring);
|
||||
seq |= last_seq & 0xffffffff00000000LL;
|
||||
if (seq < last_seq) {
|
||||
seq += 0x100000000LL;
|
||||
seq &= 0xffffffff;
|
||||
seq |= last_emitted & 0xffffffff00000000LL;
|
||||
}
|
||||
|
||||
if (seq == last_seq) {
|
||||
if (seq <= last_seq || seq > last_emitted) {
|
||||
break;
|
||||
}
|
||||
/* If we loop over we don't want to return without
|
||||
|
|
|
@ -1155,6 +1155,11 @@ static struct drm_driver driver = {
|
|||
.open = vmw_driver_open,
|
||||
.preclose = vmw_preclose,
|
||||
.postclose = vmw_postclose,
|
||||
|
||||
.dumb_create = vmw_dumb_create,
|
||||
.dumb_map_offset = vmw_dumb_map_offset,
|
||||
.dumb_destroy = vmw_dumb_destroy,
|
||||
|
||||
.fops = &vmwgfx_driver_fops,
|
||||
.name = VMWGFX_DRIVER_NAME,
|
||||
.desc = VMWGFX_DRIVER_DESC,
|
||||
|
|
|
@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
|
|||
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
int vmw_dumb_create(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
struct drm_mode_create_dumb *args);
|
||||
|
||||
int vmw_dumb_map_offset(struct drm_file *file_priv,
|
||||
struct drm_device *dev, uint32_t handle,
|
||||
uint64_t *offset);
|
||||
int vmw_dumb_destroy(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
uint32_t handle);
|
||||
/**
|
||||
* Overlay control - vmwgfx_overlay.c
|
||||
*/
|
||||
|
|
|
@ -1917,3 +1917,76 @@ err_ref:
|
|||
vmw_resource_unreference(&res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int vmw_dumb_create(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
struct drm_mode_create_dumb *args)
|
||||
{
|
||||
struct vmw_private *dev_priv = vmw_priv(dev);
|
||||
struct vmw_master *vmaster = vmw_master(file_priv->master);
|
||||
struct vmw_user_dma_buffer *vmw_user_bo;
|
||||
struct ttm_buffer_object *tmp;
|
||||
int ret;
|
||||
|
||||
args->pitch = args->width * ((args->bpp + 7) / 8);
|
||||
args->size = args->pitch * args->height;
|
||||
|
||||
vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
|
||||
if (vmw_user_bo == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = ttm_read_lock(&vmaster->lock, true);
|
||||
if (ret != 0) {
|
||||
kfree(vmw_user_bo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size,
|
||||
&vmw_vram_sys_placement, true,
|
||||
&vmw_user_dmabuf_destroy);
|
||||
if (ret != 0)
|
||||
goto out_no_dmabuf;
|
||||
|
||||
tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
|
||||
ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
|
||||
&vmw_user_bo->base,
|
||||
false,
|
||||
ttm_buffer_type,
|
||||
&vmw_user_dmabuf_release, NULL);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_no_base_object;
|
||||
|
||||
args->handle = vmw_user_bo->base.hash.key;
|
||||
|
||||
out_no_base_object:
|
||||
ttm_bo_unref(&tmp);
|
||||
out_no_dmabuf:
|
||||
ttm_read_unlock(&vmaster->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vmw_dumb_map_offset(struct drm_file *file_priv,
|
||||
struct drm_device *dev, uint32_t handle,
|
||||
uint64_t *offset)
|
||||
{
|
||||
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
||||
struct vmw_dma_buffer *out_buf;
|
||||
int ret;
|
||||
|
||||
ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf);
|
||||
if (ret != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*offset = out_buf->base.addr_space_offset;
|
||||
vmw_dmabuf_unreference(&out_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vmw_dumb_destroy(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
uint32_t handle)
|
||||
{
|
||||
return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
|
||||
handle, TTM_REF_USAGE);
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@
|
|||
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */
|
||||
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
|
||||
|
||||
/* 2 non contiguous plane YCbCr */
|
||||
#define DRM_FORMAT_NV12M fourcc_code('N', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane */
|
||||
/* special NV12 tiled format */
|
||||
#define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */
|
||||
|
||||
/*
|
||||
|
@ -131,7 +130,4 @@
|
|||
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
|
||||
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
|
||||
|
||||
/* 3 non contiguous plane YCbCr */
|
||||
#define DRM_FORMAT_YUV420M fourcc_code('Y', 'M', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
|
||||
|
||||
#endif /* DRM_FOURCC_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче