Commit 049ffa8a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux

Pull drm updates from Dave Airlie:
 "This is a combo of -next and some -fixes that came in in the
  intervening time.

  Highlights:

  New drivers:
    ARM Armada driver for Marvell Armada 510 SOCs

  Intel:
    Broadwell initial support under a default off switch,
    Stereo/3D HDMI mode support
    Valleyview improvements
    Displayport improvements
    Haswell fixes
    initial mipi dsi panel support
    CRC support for debugging
    build with CONFIG_FB=n

  Radeon:
    enable DPM on a number of GPUs by default
    secondary GPU powerdown support
    enable HDMI audio by default
    Hawaii support

  Nouveau:
    dynamic pm code infrastructure reworked, does nothing major yet
    GK208 modesetting support
    MSI fixes, on by default again
    PMPEG improvements
    pageflipping fixes

  GMA500:
    minnowboard SDVO support

  VMware:
    misc fixes

  MSM:
    prime, plane and rendernodes support

  Tegra:
    rearchitected to put the drm driver into the drm subsystem.
    HDMI and gr2d support for tegra 114 SoC

  QXL:
    oops fix, and multi-head fixes

  DRM core:
    sysfs lifetime fixes
    client capability ioctl
    further cleanups to device midlayer
    more vblank timestamp fixes"

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (789 commits)
  drm/nouveau: do not map evicted vram buffers in nouveau_bo_vma_add
  drm/nvc0-/gr: shift wrapping bug in nvc0_grctx_generate_r406800
  drm/nouveau/pwr: fix missing mutex unlock in a failure path
  drm/nv40/therm: fix slowing down fan when pstate undefined
  drm/nv11-: synchronise flips to vblank, unless async flip requested
  drm/nvc0-: remove nasty fifo swmthd hack for flip completion method
  drm/nv10-: we no longer need to create nvsw object on user channels
  drm/nouveau: always queue flips relative to kernel channel activity
  drm/nouveau: there is no need to reserve/fence the new fb when flipping
  drm/nouveau: when bailing out of a pushbuf ioctl, do not remove previous fence
  drm/nouveau: allow nouveau_fence_ref() to be a noop
  drm/nvc8/mc: msi rearm is via the nvc0 method
  drm/ttm: Fix vma page_prot bit manipulation
  drm/vmwgfx: Fix a couple of compile / sparse warnings and errors
  drm/vmwgfx: Resource evict fixes
  drm/edid: compare actual vrefresh for all modes for quirks
  drm: shmob_drm: Convert to clk_prepare/unprepare
  drm/nouveau: fix 32-bit build
  drm/i915/opregion: fix build error on CONFIG_ACPI=n
  Revert "drm/radeon/audio: don't set speaker allocation on DCE4+"
  ...
parents c681427e 0846c728
...@@ -2849,7 +2849,9 @@ L: dri-devel@lists.freedesktop.org ...@@ -2849,7 +2849,9 @@ L: dri-devel@lists.freedesktop.org
L: linux-tegra@vger.kernel.org L: linux-tegra@vger.kernel.org
T: git git://anongit.freedesktop.org/tegra/linux.git T: git git://anongit.freedesktop.org/tegra/linux.git
S: Supported S: Supported
F: drivers/gpu/drm/tegra/
F: drivers/gpu/host1x/ F: drivers/gpu/host1x/
F: include/linux/host1x.h
F: include/uapi/drm/tegra_drm.h F: include/uapi/drm/tegra_drm.h
F: Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt F: Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
......
...@@ -313,6 +313,16 @@ static size_t __init gen6_stolen_size(int num, int slot, int func) ...@@ -313,6 +313,16 @@ static size_t __init gen6_stolen_size(int num, int slot, int func)
return gmch_ctrl << 25; /* 32 MB units */ return gmch_ctrl << 25; /* 32 MB units */
} }
static inline size_t gen8_stolen_size(int num, int slot, int func)
{
u16 gmch_ctrl;
gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
gmch_ctrl >>= BDW_GMCH_GMS_SHIFT;
gmch_ctrl &= BDW_GMCH_GMS_MASK;
return gmch_ctrl << 25; /* 32 MB units */
}
typedef size_t (*stolen_size_fn)(int num, int slot, int func); typedef size_t (*stolen_size_fn)(int num, int slot, int func);
static struct pci_device_id intel_stolen_ids[] __initdata = { static struct pci_device_id intel_stolen_ids[] __initdata = {
...@@ -336,6 +346,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = { ...@@ -336,6 +346,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = {
INTEL_IVB_D_IDS(gen6_stolen_size), INTEL_IVB_D_IDS(gen6_stolen_size),
INTEL_HSW_D_IDS(gen6_stolen_size), INTEL_HSW_D_IDS(gen6_stolen_size),
INTEL_HSW_M_IDS(gen6_stolen_size), INTEL_HSW_M_IDS(gen6_stolen_size),
INTEL_BDW_M_IDS(gen8_stolen_size),
INTEL_BDW_D_IDS(gen8_stolen_size)
}; };
static void __init intel_graphics_stolen(int num, int slot, int func) static void __init intel_graphics_stolen(int num, int slot, int func)
......
...@@ -29,11 +29,17 @@ config DRM_USB ...@@ -29,11 +29,17 @@ config DRM_USB
config DRM_KMS_HELPER config DRM_KMS_HELPER
tristate tristate
depends on DRM depends on DRM
help
CRTC helpers for KMS drivers.
config DRM_KMS_FB_HELPER
bool
depends on DRM_KMS_HELPER
select FB select FB
select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
help help
FB and CRTC helpers for KMS drivers. FBDEV helpers for KMS drivers.
config DRM_LOAD_EDID_FIRMWARE config DRM_LOAD_EDID_FIRMWARE
bool "Allow to specify an EDID data set instead of probing for it" bool "Allow to specify an EDID data set instead of probing for it"
...@@ -64,6 +70,7 @@ config DRM_GEM_CMA_HELPER ...@@ -64,6 +70,7 @@ config DRM_GEM_CMA_HELPER
config DRM_KMS_CMA_HELPER config DRM_KMS_CMA_HELPER
bool bool
select DRM_GEM_CMA_HELPER select DRM_GEM_CMA_HELPER
select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
...@@ -96,6 +103,7 @@ config DRM_RADEON ...@@ -96,6 +103,7 @@ config DRM_RADEON
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
select FW_LOADER select FW_LOADER
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_TTM select DRM_TTM
select POWER_SUPPLY select POWER_SUPPLY
select HWMON select HWMON
...@@ -120,64 +128,7 @@ config DRM_I810 ...@@ -120,64 +128,7 @@ config DRM_I810
selected, the module will be called i810. AGP support is required selected, the module will be called i810. AGP support is required
for this driver to work. for this driver to work.
config DRM_I915 source "drivers/gpu/drm/i915/Kconfig"
tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
depends on DRM
depends on AGP
depends on AGP_INTEL
# we need shmfs for the swappable backing store, and in particular
# the shmem_readpage() which depends upon tmpfs
select SHMEM
select TMPFS
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
select BACKLIGHT_LCD_SUPPORT if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select VIDEO_OUTPUT_CONTROL if ACPI
select INPUT if ACPI
select THERMAL if ACPI
select ACPI_VIDEO if ACPI
select ACPI_BUTTON if ACPI
help
Choose this option if you have a system that has "Intel Graphics
Media Accelerator" or "HD Graphics" integrated graphics,
including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G,
G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3,
Core i5, Core i7 as well as Atom CPUs with integrated graphics.
If M is selected, the module will be called i915. AGP support
is required for this driver to work. This driver is used by
the Intel driver in X.org 6.8 and XFree86 4.4 and above. It
replaces the older i830 module that supported a subset of the
hardware in older X.org releases.
Note that the older i810/i815 chipsets require the use of the
i810 driver instead, and the Atom z5xx series has an entirely
different implementation.
config DRM_I915_KMS
bool "Enable modesetting on intel by default"
depends on DRM_I915
help
Choose this option if you want kernel modesetting enabled by default,
and you have a new enough userspace to support this. Running old
userspaces with this enabled will cause pain. Note that this causes
the driver to bind to PCI devices, which precludes loading things
like intelfb.
config DRM_I915_PRELIMINARY_HW_SUPPORT
bool "Enable preliminary support for prerelease Intel hardware by default"
depends on DRM_I915
help
Choose this option if you have prerelease Intel hardware and want the
i915 driver to support it by default. You can enable such support at
runtime with the module option i915.preliminary_hw_support=1; this
option changes the default for that module option.
If in doubt, say "N".
config DRM_MGA config DRM_MGA
tristate "Matrox g200/g400" tristate "Matrox g200/g400"
...@@ -225,6 +176,8 @@ source "drivers/gpu/drm/mgag200/Kconfig" ...@@ -225,6 +176,8 @@ source "drivers/gpu/drm/mgag200/Kconfig"
source "drivers/gpu/drm/cirrus/Kconfig" source "drivers/gpu/drm/cirrus/Kconfig"
source "drivers/gpu/drm/armada/Kconfig"
source "drivers/gpu/drm/rcar-du/Kconfig" source "drivers/gpu/drm/rcar-du/Kconfig"
source "drivers/gpu/drm/shmobile/Kconfig" source "drivers/gpu/drm/shmobile/Kconfig"
...@@ -236,3 +189,5 @@ source "drivers/gpu/drm/tilcdc/Kconfig" ...@@ -236,3 +189,5 @@ source "drivers/gpu/drm/tilcdc/Kconfig"
source "drivers/gpu/drm/qxl/Kconfig" source "drivers/gpu/drm/qxl/Kconfig"
source "drivers/gpu/drm/msm/Kconfig" source "drivers/gpu/drm/msm/Kconfig"
source "drivers/gpu/drm/tegra/Kconfig"
...@@ -21,8 +21,9 @@ drm-$(CONFIG_PCI) += ati_pcigart.o ...@@ -21,8 +21,9 @@ drm-$(CONFIG_PCI) += ati_pcigart.o
drm-usb-y := drm_usb.o drm-usb-y := drm_usb.o
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_helper.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
...@@ -49,10 +50,12 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ ...@@ -49,10 +50,12 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_GMA500) += gma500/ obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_AST) += ast/
obj-$(CONFIG_DRM_ARMADA) += armada/
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_DRM_TILCDC) += tilcdc/ obj-$(CONFIG_DRM_TILCDC) += tilcdc/
obj-$(CONFIG_DRM_QXL) += qxl/ obj-$(CONFIG_DRM_QXL) += qxl/
obj-$(CONFIG_DRM_MSM) += msm/ obj-$(CONFIG_DRM_MSM) += msm/
obj-$(CONFIG_DRM_TEGRA) += tegra/
obj-y += i2c/ obj-y += i2c/
config DRM_ARMADA
tristate "DRM support for Marvell Armada SoCs"
depends on DRM && HAVE_CLK && ARM
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select DRM_KMS_HELPER
help
Support the "LCD" controllers found on the Marvell Armada 510
devices. There are two controllers on the device, each controller
supports graphics and video overlays.
This driver provides no built-in acceleration; acceleration is
performed by other IP found on the SoC. This driver provides
kernel mode setting and buffer management to userspace.
config DRM_ARMADA_TDA1998X
bool "Support TDA1998X HDMI output"
depends on DRM_ARMADA != n
depends on I2C && DRM_I2C_NXP_TDA998X = y
default y
help
Support the TDA1998x HDMI output device found on the Solid-Run
CuBox.
armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
armada_gem.o armada_output.o armada_overlay.o \
armada_slave.o
armada-y += armada_510.o
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
obj-$(CONFIG_DRM_ARMADA) := armada.o
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Armada 510 (aka Dove) variant support
*/
#include <linux/clk.h>
#include <linux/io.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_hw.h"
static int armada510_init(struct armada_private *priv, struct device *dev)
{
priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1");
if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT)
priv->extclk[0] = ERR_PTR(-EPROBE_DEFER);
return PTR_RET(priv->extclk[0]);
}
static int armada510_crtc_init(struct armada_crtc *dcrtc)
{
/* Lower the watermark so to eliminate jitter at higher bandwidths */
armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
return 0;
}
/*
* Armada510 specific SCLK register selection.
* This gets called with sclk = NULL to test whether the mode is
* supportable, and again with sclk != NULL to set the clocks up for
* that. The former can return an error, but the latter is expected
* not to.
*
* We currently are pretty rudimentary here, always selecting
* EXT_REF_CLK_1 for LCD0 and erroring LCD1. This needs improvement!
*/
static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
const struct drm_display_mode *mode, uint32_t *sclk)
{
struct armada_private *priv = dcrtc->crtc.dev->dev_private;
struct clk *clk = priv->extclk[0];
int ret;
if (dcrtc->num == 1)
return -EINVAL;
if (IS_ERR(clk))
return PTR_ERR(clk);
if (dcrtc->clk != clk) {
ret = clk_prepare_enable(clk);
if (ret)
return ret;
dcrtc->clk = clk;
}
if (sclk) {
uint32_t rate, ref, div;
rate = mode->clock * 1000;
ref = clk_round_rate(clk, rate);
div = DIV_ROUND_UP(ref, rate);
if (div < 1)
div = 1;
clk_set_rate(clk, ref);
*sclk = div | SCLK_510_EXTCLK1;
}
return 0;
}
const struct armada_variant armada510_ops = {
.has_spu_adv_reg = true,
.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
.init = armada510_init,
.crtc_init = armada510_crtc_init,
.crtc_compute_clock = armada510_crtc_compute_clock,
};
This diff is collapsed.
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_CRTC_H
#define ARMADA_CRTC_H
struct armada_gem_object;
struct armada_regs {
uint32_t offset;
uint32_t mask;
uint32_t val;
};
#define armada_reg_queue_mod(_r, _i, _v, _m, _o) \
do { \
struct armada_regs *__reg = _r; \
__reg[_i].offset = _o; \
__reg[_i].mask = ~(_m); \
__reg[_i].val = _v; \
_i++; \
} while (0)
#define armada_reg_queue_set(_r, _i, _v, _o) \
armada_reg_queue_mod(_r, _i, _v, ~0, _o)
#define armada_reg_queue_end(_r, _i) \
armada_reg_queue_mod(_r, _i, 0, 0, ~0)
struct armada_frame_work;
struct armada_crtc {
struct drm_crtc crtc;
unsigned num;
void __iomem *base;
struct clk *clk;
struct {
uint32_t spu_v_h_total;
uint32_t spu_v_porch;
uint32_t spu_adv_reg;
} v[2];
bool interlaced;
bool cursor_update;
uint8_t csc_yuv_mode;
uint8_t csc_rgb_mode;
struct drm_plane *plane;
struct armada_gem_object *cursor_obj;
int cursor_x;
int cursor_y;
uint32_t cursor_hw_pos;
uint32_t cursor_hw_sz;
uint32_t cursor_w;
uint32_t cursor_h;
int dpms;
uint32_t cfg_dumb_ctrl;
uint32_t dumb_ctrl;
uint32_t spu_iopad_ctrl;
wait_queue_head_t frame_wait;
struct armada_frame_work *frame_work;
spinlock_t irq_lock;
uint32_t irq_ena;
struct list_head vbl_list;
};
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *);
void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
void armada_drm_crtc_irq(struct armada_crtc *, u32);
void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
#endif
/*
* Copyright (C) 2012 Russell King
* Rewritten from the dovefb driver, and Armada510 manuals.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <drm/drmP.h>
#include "armada_crtc.h"
#include "armada_drm.h"
static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data)
{
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct armada_private *priv = dev->dev_private;
int ret;
mutex_lock(&dev->struct_mutex);
ret = drm_mm_dump_table(m, &priv->linear);
mutex_unlock(&dev->struct_mutex);
return ret;
}
static int armada_debugfs_reg_show(struct seq_file *m, void *data)
{
struct drm_device *dev = m->private;
struct armada_private *priv = dev->dev_private;
int n, i;
if (priv) {
for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
struct armada_crtc *dcrtc = priv->dcrtc[n];
if (!dcrtc)
continue;
for (i = 0x84; i <= 0x1c4; i += 4) {
uint32_t v = readl_relaxed(dcrtc->base + i);
seq_printf(m, "%u: 0x%04x: 0x%08x\n", n, i, v);
}
}
}
return 0;
}
static int armada_debugfs_reg_r_open(struct inode *inode, struct file *file)
{
return single_open(file, armada_debugfs_reg_show, inode->i_private);
}
static const struct file_operations fops_reg_r = {
.owner = THIS_MODULE,
.open = armada_debugfs_reg_r_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int armada_debugfs_write(struct file *file, const char __user *ptr,
size_t len, loff_t *off)
{
struct drm_device *dev = file->private_data;
struct armada_private *priv = dev->dev_private;
struct armada_crtc *dcrtc = priv->dcrtc[0];
char buf[32], *p;
uint32_t reg, val;
int ret;
if (*off != 0)
return 0;
if (len > sizeof(buf) - 1)
len = sizeof(buf) - 1;
ret = strncpy_from_user(buf, ptr, len);
if (ret < 0)
return ret;
buf[len] = '\0';
reg = simple_strtoul(buf, &p, 16);
if (!isspace(*p))
return -EINVAL;
val = simple_strtoul(p + 1, NULL, 16);
if (reg >= 0x84 && reg <= 0x1c4)
writel(val, dcrtc->base + reg);
return len;
}
static const struct file_operations fops_reg_w = {
.owner = THIS_MODULE,
.open = simple_open,
.write = armada_debugfs_write,
.llseek = noop_llseek,
};
static struct drm_info_list armada_debugfs_list[] = {
{ "gem_linear", armada_debugfs_gem_linear_show, 0 },
};
#define ARMADA_DEBUGFS_ENTRIES ARRAY_SIZE(armada_debugfs_list)
static int drm_add_fake_info_node(struct drm_minor *minor, struct dentry *ent,
const void *key)
{
struct drm_info_node *node;
node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
if (node == NULL) {
debugfs_remove(ent);
return -ENOMEM;
}
node->minor = minor;
node->dent = ent;
node->info_ent = (void *) key;
mutex_lock(&minor->debugfs_lock);
list_add(&node->list, &minor->debugfs_list);
mutex_unlock(&minor->debugfs_lock);
return 0;
}
static int armada_debugfs_create(struct dentry *root, struct drm_minor *minor,
const char *name, umode_t mode, const struct file_operations *fops)
{
struct dentry *de;
de = debugfs_create_file(name, mode, root, minor->dev, fops);
return drm_add_fake_info_node(minor, de, fops);
}
int armada_drm_debugfs_init(struct drm_minor *minor)
{
int ret;
ret = drm_debugfs_create_files(armada_debugfs_list,
ARMADA_DEBUGFS_ENTRIES,
minor->debugfs_root, minor);
if (ret)
return ret;
ret = armada_debugfs_create(minor->debugfs_root, minor,
"reg", S_IFREG | S_IRUSR, &fops_reg_r);
if (ret)
goto err_1;
ret = armada_debugfs_create(minor->debugfs_root, minor,
"reg_wr", S_IFREG | S_IWUSR, &fops_reg_w);
if (ret)
goto err_2;
return ret;
err_2:
drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_r, 1, minor);
err_1:
drm_debugfs_remove_files(armada_debugfs_list, ARMADA_DEBUGFS_ENTRIES,
minor);
return ret;
}
void armada_drm_debugfs_cleanup(struct drm_minor *minor)
{
drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_w, 1, minor);
drm_debugfs_remove_files((struct drm_info_list *)&fops_reg_r, 1, minor);
drm_debugfs_remove_files(armada_debugfs_list, ARMADA_DEBUGFS_ENTRIES,
minor);
}
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_DRM_H
#define ARMADA_DRM_H
#include <linux/kfifo.h>
#include <linux/io.h>
#include <linux/workqueue.h>
#include <drm/drmP.h>
struct armada_crtc;
struct armada_gem_object;
struct clk;
struct drm_fb_helper;
static inline void
armada_updatel(uint32_t val, uint32_t mask, void __iomem *ptr)
{
uint32_t ov, v;
ov = v = readl_relaxed(ptr);
v = (v & ~mask) | val;
if (ov != v)
writel_relaxed(v, ptr);
}
static inline uint32_t armada_pitch(uint32_t width, uint32_t bpp)
{
uint32_t pitch = bpp != 4 ? width * ((bpp + 7) / 8) : width / 2;
/* 88AP510 spec recommends pitch be a multiple of 128 */
return ALIGN(pitch, 128);
}
struct armada_vbl_event {
struct list_head node;
void *data;
void (*fn)(struct armada_crtc *, void *);
};
void armada_drm_vbl_event_add(struct armada_crtc *,
struct armada_vbl_event *);
void armada_drm_vbl_event_remove(struct armada_crtc *,
struct armada_vbl_event *);
void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *,
struct armada_vbl_event *);
#define armada_drm_vbl_event_init(_e, _f, _d) do { \
struct armada_vbl_event *__e = _e; \
INIT_LIST_HEAD(&__e->node); \
__e->data = _d; \
__e->fn = _f; \
} while (0)
struct armada_private;
struct armada_variant {
bool has_spu_adv_reg;
uint32_t spu_adv_reg;
int (*init)(struct armada_private *, struct device *);
int (*crtc_init)(struct armada_crtc *);
int (*crtc_compute_clock)(struct armada_crtc *,
const struct drm_display_mode *,
uint32_t *);
};
/* Variant ops */
extern const struct armada_variant armada510_ops;
struct armada_private {
const struct armada_variant *variant;
struct work_struct fb_unref_work;
DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
struct drm_fb_helper *fbdev;
struct armada_crtc *dcrtc[2];
struct drm_mm linear;
struct clk *extclk[2];
struct drm_property *csc_yuv_prop;
struct drm_property *csc_rgb_prop;
struct drm_property *colorkey_prop;
struct drm_property *colorkey_min_prop;
struct drm_property *colorkey_max_prop;
struct drm_property *colorkey_val_prop;
struct drm_property *colorkey_alpha_prop;
struct drm_property *colorkey_mode_prop;
struct drm_property *brightness_prop;
struct drm_property *contrast_prop;
struct drm_property *saturation_prop;
#ifdef CONFIG_DEBUG_FS
struct dentry *de;
#endif
};
void __armada_drm_queue_unref_work(struct drm_device *,
struct drm_framebuffer *);
void armada_drm_queue_unref_work(struct drm_device *,
struct drm_framebuffer *);
extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs;
int armada_fbdev_init(struct drm_device *);
void armada_fbdev_fini(struct drm_device *);
int armada_overlay_plane_create(struct drm_device *, unsigned long);
int armada_drm_debugfs_init(struct drm_minor *);
void armada_drm_debugfs_cleanup(struct drm_minor *);
#endif
This diff is collapsed.
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include "armada_drm.h"
#include "armada_fb.h"
#include "armada_gem.h"
#include "armada_hw.h"
static void armada_fb_destroy(struct drm_framebuffer *fb)
{
struct armada_framebuffer *dfb = drm_fb_to_armada_fb(fb);
drm_framebuffer_cleanup(&dfb->fb);
drm_gem_object_unreference_unlocked(&dfb->obj->obj);
kfree(dfb);
}
static int armada_fb_create_handle(struct drm_framebuffer *fb,
struct drm_file *dfile, unsigned int *handle)
{
struct armada_framebuffer *dfb = drm_fb_to_armada_fb(fb);
return drm_gem_handle_create(dfile, &dfb->obj->obj, handle);
}
static const struct drm_framebuffer_funcs armada_fb_funcs = {
.destroy = armada_fb_destroy,
.create_handle = armada_fb_create_handle,
};
struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode, struct armada_gem_object *obj)
{
struct armada_framebuffer *dfb;
uint8_t format, config;
int ret;
switch (mode->pixel_format) {
#define FMT(drm, fmt, mod) \
case DRM_FORMAT_##drm: \
format = CFG_##fmt; \
config = mod; \
break
FMT(RGB565, 565, CFG_SWAPRB);
FMT(BGR565, 565, 0);
FMT(ARGB1555, 1555, CFG_SWAPRB);
FMT(ABGR1555, 1555, 0);
FMT(RGB888, 888PACK, CFG_SWAPRB);
FMT(BGR888, 888PACK, 0);
FMT(XRGB8888, X888, CFG_SWAPRB);
FMT(XBGR8888, X888, 0);
FMT(ARGB8888, 8888, CFG_SWAPRB);
FMT(ABGR8888, 8888, 0);
FMT(YUYV, 422PACK, CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV);
FMT(UYVY, 422PACK, CFG_YUV2RGB);
FMT(VYUY, 422PACK, CFG_YUV2RGB | CFG_SWAPUV);
FMT(YVYU, 422PACK, CFG_YUV2RGB | CFG_SWAPYU);
FMT(YUV422, 422, CFG_YUV2RGB);
FMT(YVU422, 422, CFG_YUV2RGB | CFG_SWAPUV);
FMT(YUV420, 420, CFG_YUV2RGB);
FMT(YVU420, 420, CFG_YUV2RGB | CFG_SWAPUV);
FMT(C8, PSEUDO8, 0);
#undef FMT
default:
return ERR_PTR(-EINVAL);
}
dfb = kzalloc(sizeof(*dfb), GFP_KERNEL);
if (!dfb) {
DRM_ERROR("failed to allocate Armada fb object\n");
return ERR_PTR(-ENOMEM);
}
dfb->fmt = format;
dfb->mod = config;
dfb->obj = obj;
drm_helper_mode_fill_fb_struct(&dfb->fb, mode);
ret = drm_framebuffer_init(dev, &dfb->fb, &armada_fb_funcs);
if (ret) {
kfree(dfb);
return ERR_PTR(ret);
}
/*
* Take a reference on our object as we're successful - the
* caller already holds a reference, which keeps us safe for
* the above call, but the caller will drop their reference
* to it. Hence we need to take our own reference.
*/
drm_gem_object_reference(&obj->obj);
return dfb;
}
static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
struct drm_file *dfile, struct drm_mode_fb_cmd2 *mode)
{
struct armada_gem_object *obj;
struct armada_framebuffer *dfb;
int ret;
DRM_DEBUG_DRIVER("w%u h%u pf%08x f%u p%u,%u,%u\n",
mode->width, mode->height, mode->pixel_format,
mode->flags, mode->pitches[0], mode->pitches[1],
mode->pitches[2]);
/* We can only handle a single plane at the moment */
if (drm_format_num_planes(mode->pixel_format) > 1 &&
(mode->handles[0] != mode->handles[1] ||
mode->handles[0] != mode->handles[2])) {
ret = -EINVAL;
goto err;
}
obj = armada_gem_object_lookup(dev, dfile, mode->handles[0]);
if (!obj) {
ret = -ENOENT;
goto err;
}
if (obj->obj.import_attach && !obj->sgt) {
ret = armada_gem_map_import(obj);
if (ret)
goto err_unref;
}
/* Framebuffer objects must have a valid device address for scanout */
if (obj->dev_addr == DMA_ERROR_CODE) {
ret = -EINVAL;
goto err_unref;
}
dfb = armada_framebuffer_create(dev, mode, obj);
if (IS_ERR(dfb)) {
ret = PTR_ERR(dfb);
goto err;
}
drm_gem_object_unreference_unlocked(&obj->obj);
return &dfb->fb;
err_unref:
drm_gem_object_unreference_unlocked(&obj->obj);
err:
DRM_ERROR("failed to initialize framebuffer: %d\n", ret);
return ERR_PTR(ret);
}
static void armada_output_poll_changed(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
struct drm_fb_helper *fbh = priv->fbdev;
if (fbh)
drm_fb_helper_hotplug_event(fbh);
}
const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
.fb_create = armada_fb_create,
.output_poll_changed = armada_output_poll_changed,
};
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_FB_H
#define ARMADA_FB_H
struct armada_framebuffer {
struct drm_framebuffer fb;
struct armada_gem_object *obj;
uint8_t fmt;
uint8_t mod;
};
#define drm_fb_to_armada_fb(dfb) \
container_of(dfb, struct armada_framebuffer, fb)
#define drm_fb_obj(fb) drm_fb_to_armada_fb(fb)->obj
struct armada_framebuffer *armada_framebuffer_create(struct drm_device *,
struct drm_mode_fb_cmd2 *, struct armada_gem_object *);
#endif
/*
* Copyright (C) 2012 Russell King
* Written from the i915 driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <drm/drmP.h>
#include <drm/drm_fb_helper.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_fb.h"
#include "armada_gem.h"
static /*const*/ struct fb_ops armada_fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
};
static int armada_fb_create(struct drm_fb_helper *fbh,
struct drm_fb_helper_surface_size *sizes)
{
struct drm_device *dev = fbh->dev;
struct drm_mode_fb_cmd2 mode;
struct armada_framebuffer *dfb;
struct armada_gem_object *obj;
struct fb_info *info;
int size, ret;
void *ptr;
memset(&mode, 0, sizeof(mode));
mode.width = sizes->surface_width;
mode.height = sizes->surface_height;
mode.pitches[0] = armada_pitch(mode.width, sizes->surface_bpp);
mode.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);
size = mode.pitches[0] * mode.height;
obj = armada_gem_alloc_private_object(dev, size);
if (!obj) {
DRM_ERROR("failed to allocate fb memory\n");
return -ENOMEM;
}
ret = armada_gem_linear_back(dev, obj);
if (ret) {
drm_gem_object_unreference_unlocked(&obj->obj);
return ret;
}
ptr = armada_gem_map_object(dev, obj);
if (!ptr) {
drm_gem_object_unreference_unlocked(&obj->obj);
return -ENOMEM;
}
dfb = armada_framebuffer_create(dev, &mode, obj);
/*
* A reference is now held by the framebuffer object if
* successful, otherwise this drops the ref for the error path.
*/
drm_gem_object_unreference_unlocked(&obj->obj);
if (IS_ERR(dfb))
return PTR_ERR(dfb);
info = framebuffer_alloc(0, dev->dev);
if (!info) {
ret = -ENOMEM;
goto err_fballoc;
}
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
ret = -ENOMEM;
goto err_fbcmap;
}
strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id));
info->par = fbh;
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &armada_fb_ops;
info->fix.smem_start = obj->phys_addr;
info->fix.smem_len = obj->obj.size;
info->screen_size = obj->obj.size;
info->screen_base = ptr;
fbh->fb = &dfb->fb;
fbh->fbdev = info;
drm_fb_helper_fill_fix(info, dfb->fb.pitches[0], dfb->fb.depth);
drm_fb_helper_fill_var(info, fbh, sizes->fb_width, sizes->fb_height);
DRM_DEBUG_KMS("allocated %dx%d %dbpp fb: 0x%08x\n",
dfb->fb.width, dfb->fb.height,
dfb->fb.bits_per_pixel, obj->phys_addr);
return 0;
err_fbcmap:
framebuffer_release(info);
err_fballoc:
dfb->fb.funcs->destroy(&dfb->fb);
return ret;
}
static int armada_fb_probe(struct drm_fb_helper *fbh,
struct drm_fb_helper_surface_size *sizes)
{
int ret = 0;
if (!fbh->fb) {
ret = armada_fb_create(fbh, sizes);
if (ret == 0)
ret = 1;
}
return ret;
}
static struct drm_fb_helper_funcs armada_fb_helper_funcs = {
.gamma_set = armada_drm_crtc_gamma_set,
.gamma_get = armada_drm_crtc_gamma_get,
.fb_probe = armada_fb_probe,
};
int armada_fbdev_init(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
struct drm_fb_helper *fbh;
int ret;
fbh = devm_kzalloc(dev->dev, sizeof(*fbh), GFP_KERNEL);
if (!fbh)
return -ENOMEM;
priv->fbdev = fbh;
fbh->funcs = &armada_fb_helper_funcs;
ret = drm_fb_helper_init(dev, fbh, 1, 1);
if (ret) {
DRM_ERROR("failed to initialize drm fb helper\n");
goto err_fb_helper;
}
ret = drm_fb_helper_single_add_all_connectors(fbh);
if (ret) {
DRM_ERROR("failed to add fb connectors\n");
goto err_fb_setup;
}
ret = drm_fb_helper_initial_config(fbh, 32);
if (ret) {
DRM_ERROR("failed to set initial config\n");
goto err_fb_setup;
}
return 0;
err_fb_setup:
drm_fb_helper_fini(fbh);
err_fb_helper:
priv->fbdev = NULL;
return ret;
}
void armada_fbdev_fini(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
struct drm_fb_helper *fbh = priv->fbdev;
if (fbh) {
struct fb_info *info = fbh->fbdev;
if (info) {
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
if (fbh->fb)
fbh->fb->funcs->destroy(fbh->fb);
drm_fb_helper_fini(fbh);
priv->fbdev = NULL;
}
}
This diff is collapsed.
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_GEM_H
#define ARMADA_GEM_H
/* GEM */
struct armada_gem_object {
struct drm_gem_object obj;
void *addr;
phys_addr_t phys_addr;
resource_size_t dev_addr;
struct drm_mm_node *linear; /* for linear backed */
struct page *page; /* for page backed */
struct sg_table *sgt; /* for imported */
void (*update)(void *);
void *update_data;
};
extern const struct vm_operations_struct armada_gem_vm_ops;
#define drm_to_armada_gem(o) container_of(o, struct armada_gem_object, obj)
void armada_gem_free_object(struct drm_gem_object *);
int armada_gem_linear_back(struct drm_device *, struct armada_gem_object *);
void *armada_gem_map_object(struct drm_device *, struct armada_gem_object *);
struct armada_gem_object *armada_gem_alloc_private_object(struct drm_device *,
size_t);
int armada_gem_dumb_create(struct drm_file *, struct drm_device *,
struct drm_mode_create_dumb *);
int armada_gem_dumb_map_offset(struct drm_file *, struct drm_device *,
uint32_t, uint64_t *);
int armada_gem_dumb_destroy(struct drm_file *, struct drm_device *,
uint32_t);
struct dma_buf *armada_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
struct drm_gem_object *armada_gem_prime_import(struct drm_device *,
struct dma_buf *);
int armada_gem_map_import(struct armada_gem_object *);
static inline struct armada_gem_object *armada_gem_object_lookup(
struct drm_device *dev, struct drm_file *dfile, unsigned handle)
{
struct drm_gem_object *obj = drm_gem_object_lookup(dev, dfile, handle);
return obj ? drm_to_armada_gem(obj) : NULL;
}
#endif
/*
* Copyright (C) 2012 Russell King
* Rewritten from the dovefb driver, and Armada510 manuals.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_HW_H
#define ARMADA_HW_H
/*
* Note: the following registers are written from IRQ context:
* LCD_SPU_V_PORCH, LCD_SPU_ADV_REG, LCD_SPUT_V_H_TOTAL
* LCD_SPU_DMA_START_ADDR_[YUV][01], LCD_SPU_DMA_PITCH_YC,
* LCD_SPU_DMA_PITCH_UV, LCD_SPU_DMA_OVSA_HPXL_VLN,
* LCD_SPU_DMA_HPXL_VLN, LCD_SPU_DZM_HPXL_VLN, LCD_SPU_DMA_CTRL0
*/
enum {
LCD_SPU_ADV_REG = 0x0084, /* Armada 510 */
LCD_SPU_DMA_START_ADDR_Y0 = 0x00c0,
LCD_SPU_DMA_START_ADDR_U0 = 0x00c4,
LCD_SPU_DMA_START_ADDR_V0 = 0x00c8,
LCD_CFG_DMA_START_ADDR_0 = 0x00cc,
LCD_SPU_DMA_START_ADDR_Y1 = 0x00d0,
LCD_SPU_DMA_START_ADDR_U1 = 0x00d4,
LCD_SPU_DMA_START_ADDR_V1 = 0x00d8,
LCD_CFG_DMA_START_ADDR_1 = 0x00dc,
LCD_SPU_DMA_PITCH_YC = 0x00e0,
LCD_SPU_DMA_PITCH_UV = 0x00e4,
LCD_SPU_DMA_OVSA_HPXL_VLN = 0x00e8,
LCD_SPU_DMA_HPXL_VLN = 0x00ec,
LCD_SPU_DZM_HPXL_VLN = 0x00f0,
LCD_CFG_GRA_START_ADDR0 = 0x00f4,
LCD_CFG_GRA_START_ADDR1 = 0x00f8,
LCD_CFG_GRA_PITCH = 0x00fc,
LCD_SPU_GRA_OVSA_HPXL_VLN = 0x0100,
LCD_SPU_GRA_HPXL_VLN = 0x0104,
LCD_SPU_GZM_HPXL_VLN = 0x0108,
LCD_SPU_HWC_OVSA_HPXL_VLN = 0x010c,
LCD_SPU_HWC_HPXL_VLN = 0x0110,
LCD_SPUT_V_H_TOTAL = 0x0114,
LCD_SPU_V_H_ACTIVE = 0x0118,
LCD_SPU_H_PORCH = 0x011c,
LCD_SPU_V_PORCH = 0x0120,
LCD_SPU_BLANKCOLOR = 0x0124,
LCD_SPU_ALPHA_COLOR1 = 0x0128,
LCD_SPU_ALPHA_COLOR2 = 0x012c,
LCD_SPU_COLORKEY_Y = 0x0130,
LCD_SPU_COLORKEY_U = 0x0134,
LCD_SPU_COLORKEY_V = 0x0138,
LCD_CFG_RDREG4F = 0x013c, /* Armada 510 */
LCD_SPU_SPI_RXDATA = 0x0140,
LCD_SPU_ISA_RXDATA = 0x0144,
LCD_SPU_HWC_RDDAT = 0x0158,
LCD_SPU_GAMMA_RDDAT = 0x015c,
LCD_SPU_PALETTE_RDDAT = 0x0160,
LCD_SPU_IOPAD_IN = 0x0178,
LCD_CFG_RDREG5F = 0x017c,
LCD_SPU_SPI_CTRL = 0x0180,
LCD_SPU_SPI_TXDATA = 0x0184,
LCD_SPU_SMPN_CTRL = 0x0188,
LCD_SPU_DMA_CTRL0 = 0x0190,
LCD_SPU_DMA_CTRL1 = 0x0194,
LCD_SPU_SRAM_CTRL = 0x0198,
LCD_SPU_SRAM_WRDAT = 0x019c,
LCD_SPU_SRAM_PARA0 = 0x01a0, /* Armada 510 */
LCD_SPU_SRAM_PARA1 = 0x01a4,
LCD_CFG_SCLK_DIV = 0x01a8,
LCD_SPU_CONTRAST = 0x01ac,
LCD_SPU_SATURATION = 0x01b0,
LCD_SPU_CBSH_HUE = 0x01b4,
LCD_SPU_DUMB_CTRL = 0x01b8,
LCD_SPU_IOPAD_CONTROL = 0x01bc,
LCD_SPU_IRQ_ENA = 0x01c0,
LCD_SPU_IRQ_ISR = 0x01c4,
};
/* For LCD_SPU_ADV_REG */
enum {
ADV_VSYNC_L_OFF = 0xfff << 20,
ADV_GRACOLORKEY = 1 << 19,
ADV_VIDCOLORKEY = 1 << 18,
ADV_HWC32BLEND = 1 << 15,
ADV_HWC32ARGB = 1 << 14,
ADV_HWC32ENABLE = 1 << 13,
ADV_VSYNCOFFEN = 1 << 12,
ADV_VSYNC_H_OFF = 0xfff << 0,
};
enum {
CFG_565 = 0,
CFG_1555 = 1,
CFG_888PACK = 2,
CFG_X888 = 3,
CFG_8888 = 4,
CFG_422PACK = 5,
CFG_422 = 6,
CFG_420 = 7,
CFG_PSEUDO4 = 9,
CFG_PSEUDO8 = 10,
CFG_SWAPRB = 1 << 4,
CFG_SWAPUV = 1 << 3,
CFG_SWAPYU = 1 << 2,
CFG_YUV2RGB = 1 << 1,
};
/* For LCD_SPU_DMA_CTRL0 */
enum {
CFG_NOBLENDING = 1 << 31,
CFG_GAMMA_ENA = 1 << 30,
CFG_CBSH_ENA = 1 << 29,
CFG_PALETTE_ENA = 1 << 28,
CFG_ARBFAST_ENA = 1 << 27,
CFG_HWC_1BITMOD = 1 << 26,
CFG_HWC_1BITENA = 1 << 25,
CFG_HWC_ENA = 1 << 24,
CFG_DMAFORMAT = 0xf << 20,
#define CFG_DMA_FMT(x) ((x) << 20)
CFG_GRAFORMAT = 0xf << 16,
#define CFG_GRA_FMT(x) ((x) << 16)
#define CFG_GRA_MOD(x) ((x) << 8)
CFG_GRA_FTOGGLE = 1 << 15,
CFG_GRA_HSMOOTH = 1 << 14,
CFG_GRA_TSTMODE = 1 << 13,
CFG_GRA_ENA = 1 << 8,
#define CFG_DMA_MOD(x) ((x) << 0)
CFG_DMA_FTOGGLE = 1 << 7,
CFG_DMA_HSMOOTH = 1 << 6,
CFG_DMA_TSTMODE = 1 << 5,
CFG_DMA_ENA = 1 << 0,
};
enum {
CKMODE_DISABLE = 0,
CKMODE_Y = 1,
CKMODE_U = 2,
CKMODE_RGB = 3,
CKMODE_V = 4,
CKMODE_R = 5,
CKMODE_G = 6,
CKMODE_B = 7,
};
/* For LCD_SPU_DMA_CTRL1 */
enum {
CFG_FRAME_TRIG = 1 << 31,
CFG_VSYNC_INV = 1 << 27,
CFG_CKMODE_MASK = 0x7 << 24,
#define CFG_CKMODE(x) ((x) << 24)
CFG_CARRY = 1 << 23,
CFG_GATED_CLK = 1 << 21,
CFG_PWRDN_ENA = 1 << 20,
CFG_DSCALE_MASK = 0x3 << 18,
CFG_DSCALE_NONE = 0x0 << 18,
CFG_DSCALE_HALF = 0x1 << 18,
CFG_DSCALE_QUAR = 0x2 << 18,
CFG_ALPHAM_MASK = 0x3 << 16,
CFG_ALPHAM_VIDEO = 0x0 << 16,
CFG_ALPHAM_GRA = 0x1 << 16,
CFG_ALPHAM_CFG = 0x2 << 16,
CFG_ALPHA_MASK = 0xff << 8,
CFG_PIXCMD_MASK = 0xff,
};
/* For LCD_SPU_SRAM_CTRL */
enum {
SRAM_READ = 0 << 14,
SRAM_WRITE = 2 << 14,
SRAM_INIT = 3 << 14,
SRAM_HWC32_RAM1 = 0xc << 8,
SRAM_HWC32_RAM2 = 0xd << 8,
SRAM_HWC32_RAMR = SRAM_HWC32_RAM1,
SRAM_HWC32_RAMG = SRAM_HWC32_RAM2,
SRAM_HWC32_RAMB = 0xe << 8,
SRAM_HWC32_TRAN = 0xf << 8,
SRAM_HWC = 0xf << 8,
};
/* For LCD_SPU_SRAM_PARA1 */
enum {
CFG_CSB_256x32 = 1 << 15, /* cursor */
CFG_CSB_256x24 = 1 << 14, /* palette */
CFG_CSB_256x8 = 1 << 13, /* gamma */
CFG_PDWN1920x32 = 1 << 8, /* Armada 510: power down vscale ram */
CFG_PDWN256x32 = 1 << 7, /* power down cursor */
CFG_PDWN256x24 = 1 << 6, /* power down palette */
CFG_PDWN256x8 = 1 << 5, /* power down gamma */
CFG_PDWNHWC = 1 << 4, /* Armada 510: power down all hwc ram */
CFG_PDWN32x32 = 1 << 3, /* power down slave->smart ram */
CFG_PDWN16x66 = 1 << 2, /* power down UV fifo */
CFG_PDWN32x66 = 1 << 1, /* power down Y fifo */
CFG_PDWN64x66 = 1 << 0, /* power down graphic fifo */
};
/* For LCD_CFG_SCLK_DIV */
enum {
/* Armada 510 */
SCLK_510_AXI = 0x0 << 30,
SCLK_510_EXTCLK0 = 0x1 << 30,
SCLK_510_PLL = 0x2 << 30,
SCLK_510_EXTCLK1 = 0x3 << 30,
SCLK_510_DIV_CHANGE = 1 << 29,
SCLK_510_FRAC_DIV_MASK = 0xfff << 16,
SCLK_510_INT_DIV_MASK = 0xffff << 0,
/* Armada 16x */
SCLK_16X_AHB = 0x0 << 28,
SCLK_16X_PCLK = 0x1 << 28,
SCLK_16X_AXI = 0x4 << 28,
SCLK_16X_PLL = 0x8 << 28,
SCLK_16X_FRAC_DIV_MASK = 0xfff << 16,
SCLK_16X_INT_DIV_MASK = 0xffff << 0,
};
/* For LCD_SPU_DUMB_CTRL */
enum {
DUMB16_RGB565_0 = 0x0 << 28,
DUMB16_RGB565_1 = 0x1 << 28,
DUMB18_RGB666_0 = 0x2 << 28,
DUMB18_RGB666_1 = 0x3 << 28,
DUMB12_RGB444_0 = 0x4 << 28,
DUMB12_RGB444_1 = 0x5 << 28,
DUMB24_RGB888_0 = 0x6 << 28,
DUMB_BLANK = 0x7 << 28,
DUMB_MASK = 0xf << 28,
CFG_BIAS_OUT = 1 << 8,
CFG_REV_RGB = 1 << 7,
CFG_INV_CBLANK = 1 << 6,
CFG_INV_CSYNC = 1 << 5, /* Normally active high */
CFG_INV_HENA = 1 << 4,
CFG_INV_VSYNC = 1 << 3, /* Normally active high */
CFG_INV_HSYNC = 1 << 2, /* Normally active high */
CFG_INV_PCLK = 1 << 1,
CFG_DUMB_ENA = 1 << 0,
};
/* For LCD_SPU_IOPAD_CONTROL */
enum {
CFG_VSCALE_LN_EN = 3 << 18,
CFG_GRA_VM_ENA = 1 << 15,
CFG_DMA_VM_ENA = 1 << 13,
CFG_CMD_VM_ENA = 1 << 11,
CFG_CSC_MASK = 3 << 8,
CFG_CSC_YUV_CCIR709 = 1 << 9,
CFG_CSC_YUV_CCIR601 = 0 << 9,
CFG_CSC_RGB_STUDIO = 1 << 8,
CFG_CSC_RGB_COMPUTER = 0 << 8,
CFG_IOPAD_MASK = 0xf << 0,
CFG_IOPAD_DUMB24 = 0x0 << 0,
CFG_IOPAD_DUMB18SPI = 0x1 << 0,
CFG_IOPAD_DUMB18GPIO = 0x2 << 0,
CFG_IOPAD_DUMB16SPI = 0x3 << 0,
CFG_IOPAD_DUMB16GPIO = 0x4 << 0,
CFG_IOPAD_DUMB12GPIO = 0x5 << 0,
CFG_IOPAD_SMART18 = 0x6 << 0,
CFG_IOPAD_SMART16 = 0x7 << 0,
CFG_IOPAD_SMART8 = 0x8 << 0,
};
#define IOPAD_DUMB24 0x0
/* For LCD_SPU_IRQ_ENA */
enum {
DMA_FRAME_IRQ0_ENA = 1 << 31,
DMA_FRAME_IRQ1_ENA = 1 << 30,
DMA_FRAME_IRQ_ENA = DMA_FRAME_IRQ0_ENA | DMA_FRAME_IRQ1_ENA,
DMA_FF_UNDERFLOW_ENA = 1 << 29,
GRA_FRAME_IRQ0_ENA = 1 << 27,
GRA_FRAME_IRQ1_ENA = 1 << 26,
GRA_FRAME_IRQ_ENA = GRA_FRAME_IRQ0_ENA | GRA_FRAME_IRQ1_ENA,
GRA_FF_UNDERFLOW_ENA = 1 << 25,
VSYNC_IRQ_ENA = 1 << 23,
DUMB_FRAMEDONE_ENA = 1 << 22,
TWC_FRAMEDONE_ENA = 1 << 21,
HWC_FRAMEDONE_ENA = 1 << 20,
SLV_IRQ_ENA = 1 << 19,
SPI_IRQ_ENA = 1 << 18,
PWRDN_IRQ_ENA = 1 << 17,
ERR_IRQ_ENA = 1 << 16,
CLEAN_SPU_IRQ_ISR = 0xffff,
};
/* For LCD_SPU_IRQ_ISR */
enum {
DMA_FRAME_IRQ0 = 1 << 31,
DMA_FRAME_IRQ1 = 1 << 30,
DMA_FRAME_IRQ = DMA_FRAME_IRQ0 | DMA_FRAME_IRQ1,
DMA_FF_UNDERFLOW = 1 << 29,
GRA_FRAME_IRQ0 = 1 << 27,
GRA_FRAME_IRQ1 = 1 << 26,
GRA_FRAME_IRQ = GRA_FRAME_IRQ0 | GRA_FRAME_IRQ1,
GRA_FF_UNDERFLOW = 1 << 25,
VSYNC_IRQ = 1 << 23,
DUMB_FRAMEDONE = 1 << 22,
TWC_FRAMEDONE = 1 << 21,
HWC_FRAMEDONE = 1 << 20,
SLV_IRQ = 1 << 19,
SPI_IRQ = 1 << 18,
PWRDN_IRQ = 1 << 17,
ERR_IRQ = 1 << 16,
DMA_FRAME_IRQ0_LEVEL = 1 << 15,
DMA_FRAME_IRQ1_LEVEL = 1 << 14,
DMA_FRAME_CNT_ISR = 3 << 12,
GRA_FRAME_IRQ0_LEVEL = 1 << 11,
GRA_FRAME_IRQ1_LEVEL = 1 << 10,
GRA_FRAME_CNT_ISR = 3 << 8,
VSYNC_IRQ_LEVEL = 1 << 7,
DUMB_FRAMEDONE_LEVEL = 1 << 6,
TWC_FRAMEDONE_LEVEL = 1 << 5,
HWC_FRAMEDONE_LEVEL = 1 << 4,
SLV_FF_EMPTY = 1 << 3,
DMA_FF_ALLEMPTY = 1 << 2,
GRA_FF_ALLEMPTY = 1 << 1,
PWRDN_IRQ_LEVEL = 1 << 0,
};
#endif
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_IOCTLP_H
#define ARMADA_IOCTLP_H
#define ARMADA_IOCTL_PROTO(name)\
extern int armada_##name##_ioctl(struct drm_device *, void *, struct drm_file *)
ARMADA_IOCTL_PROTO(gem_create);
ARMADA_IOCTL_PROTO(gem_mmap);
ARMADA_IOCTL_PROTO(gem_pwrite);
#endif
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "armada_output.h"
#include "armada_drm.h"
struct armada_connector {
struct drm_connector conn;
const struct armada_output_type *type;
};
#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)
struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
{
struct drm_encoder *enc = conn->encoder;
return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
}
static enum drm_connector_status armada_drm_connector_detect(
struct drm_connector *conn, bool force)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
enum drm_connector_status status = connector_status_disconnected;
if (dconn->type->detect) {
status = dconn->type->detect(conn, force);
} else {
struct drm_encoder *enc = armada_drm_connector_encoder(conn);
if (enc)
status = encoder_helper_funcs(enc)->detect(enc, conn);
}
return status;
}
static void armada_drm_connector_destroy(struct drm_connector *conn)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
drm_sysfs_connector_remove(conn);
drm_connector_cleanup(conn);
kfree(dconn);
}
static int armada_drm_connector_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
if (!dconn->type->set_property)
return -EINVAL;
return dconn->type->set_property(conn, property, value);
}
static const struct drm_connector_funcs armada_drm_conn_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = armada_drm_connector_detect,
.destroy = armada_drm_connector_destroy,
.set_property = armada_drm_connector_set_property,
};
void armada_drm_encoder_prepare(struct drm_encoder *encoder)
{
encoder_helper_funcs(encoder)->dpms(encoder, DRM_MODE_DPMS_OFF);
}
void armada_drm_encoder_commit(struct drm_encoder *encoder)
{
encoder_helper_funcs(encoder)->dpms(encoder, DRM_MODE_DPMS_ON);
}
bool armada_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode, struct drm_display_mode *adjusted)
{
return true;
}
/* Shouldn't this be a generic helper function? */
int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
int valid = MODE_BAD;
if (encoder) {
struct drm_encoder_slave *slave = to_encoder_slave(encoder);
valid = slave->slave_funcs->mode_valid(encoder, mode);
}
return valid;
}
int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value)
{
struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
int rc = -EINVAL;
if (encoder) {
struct drm_encoder_slave *slave = to_encoder_slave(encoder);
rc = slave->slave_funcs->set_property(encoder, conn, property,
value);
}
return rc;
}
int armada_output_create(struct drm_device *dev,
const struct armada_output_type *type, const void *data)
{
struct armada_connector *dconn;
int ret;
dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
if (!dconn)
return -ENOMEM;
dconn->type = type;
ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
type->connector_type);
if (ret) {
DRM_ERROR("unable to init connector\n");
goto err_destroy_dconn;
}
ret = type->create(&dconn->conn, data);
if (ret)
goto err_conn;
ret = drm_sysfs_connector_add(&dconn->conn);
if (ret)
goto err_sysfs;
return 0;
err_sysfs:
if (dconn->conn.encoder)
dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
err_conn:
drm_connector_cleanup(&dconn->conn);
err_destroy_dconn:
kfree(dconn);
return ret;
}
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_CONNETOR_H
#define ARMADA_CONNETOR_H
#define encoder_helper_funcs(encoder) \
((struct drm_encoder_helper_funcs *)encoder->helper_private)
struct armada_output_type {
int connector_type;
enum drm_connector_status (*detect)(struct drm_connector *, bool);
int (*create)(struct drm_connector *, const void *);
int (*set_property)(struct drm_connector *, struct drm_property *,
uint64_t);
};
struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn);
void armada_drm_encoder_prepare(struct drm_encoder *encoder);
void armada_drm_encoder_commit(struct drm_encoder *encoder);
bool armada_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode, struct drm_display_mode *adj);
int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
struct drm_display_mode *mode);
int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value);
int armada_output_create(struct drm_device *dev,
const struct armada_output_type *type, const void *data);
#endif
This diff is collapsed.
/*
* Copyright (C) 2012 Russell King
* Rewritten from the dovefb driver, and Armada510 manuals.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "armada_drm.h"
#include "armada_output.h"
#include "armada_slave.h"
static int armada_drm_slave_get_modes(struct drm_connector *conn)
{
struct drm_encoder *enc = armada_drm_connector_encoder(conn);
int count = 0;
if (enc) {
struct drm_encoder_slave *slave = to_encoder_slave(enc);
count = slave->slave_funcs->get_modes(enc, conn);
}
return count;
}
static void armada_drm_slave_destroy(struct drm_encoder *enc)
{
struct drm_encoder_slave *slave = to_encoder_slave(enc);
struct i2c_client *client = drm_i2c_encoder_get_client(enc);
if (slave->slave_funcs)
slave->slave_funcs->destroy(enc);
if (client)
i2c_put_adapter(client->adapter);
drm_encoder_cleanup(&slave->base);
kfree(slave);
}
static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs = {
.destroy = armada_drm_slave_destroy,
};
static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs = {
.get_modes = armada_drm_slave_get_modes,
.mode_valid = armada_drm_slave_encoder_mode_valid,
.best_encoder = armada_drm_connector_encoder,
};
static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers = {
.dpms = drm_i2c_encoder_dpms,
.save = drm_i2c_encoder_save,
.restore = drm_i2c_encoder_restore,
.mode_fixup = drm_i2c_encoder_mode_fixup,
.prepare = drm_i2c_encoder_prepare,
.commit = drm_i2c_encoder_commit,
.mode_set = drm_i2c_encoder_mode_set,
.detect = drm_i2c_encoder_detect,
};
static int
armada_drm_conn_slave_create(struct drm_connector *conn, const void *data)
{
const struct armada_drm_slave_config *config = data;
struct drm_encoder_slave *slave;
struct i2c_adapter *adap;
int ret;
conn->interlace_allowed = config->interlace_allowed;
conn->doublescan_allowed = config->doublescan_allowed;
conn->polled = config->polled;
drm_connector_helper_add(conn, &armada_drm_slave_helper_funcs);
slave = kzalloc(sizeof(*slave), GFP_KERNEL);
if (!slave)
return -ENOMEM;
slave->base.possible_crtcs = config->crtcs;
adap = i2c_get_adapter(config->i2c_adapter_id);
if (!adap) {
kfree(slave);
return -EPROBE_DEFER;
}
ret = drm_encoder_init(conn->dev, &slave->base,
&armada_drm_slave_encoder_funcs,
DRM_MODE_ENCODER_TMDS);
if (ret) {
DRM_ERROR("unable to init encoder\n");
i2c_put_adapter(adap);
kfree(slave);
return ret;
}
ret = drm_i2c_encoder_init(conn->dev, slave, adap, &config->info);
i2c_put_adapter(adap);
if (ret) {
DRM_ERROR("unable to init encoder slave\n");
armada_drm_slave_destroy(&slave->base);
return ret;
}
drm_encoder_helper_add(&slave->base, &drm_slave_encoder_helpers);
ret = slave->slave_funcs->create_resources(&slave->base, conn);
if (ret) {
armada_drm_slave_destroy(&slave->base);
return ret;
}
ret = drm_mode_connector_attach_encoder(conn, &slave->base);
if (ret) {
armada_drm_slave_destroy(&slave->base);
return ret;
}
conn->encoder = &slave->base;
return ret;
}
static const struct armada_output_type armada_drm_conn_slave = {
.connector_type = DRM_MODE_CONNECTOR_HDMIA,
.create = armada_drm_conn_slave_create,
.set_property = armada_drm_slave_encoder_set_property,
};
int armada_drm_connector_slave_create(struct drm_device *dev,
const struct armada_drm_slave_config *config)
{
return armada_output_create(dev, &armada_drm_conn_slave, config);
}
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_SLAVE_H
#define ARMADA_SLAVE_H
#include <linux/i2c.h>
#include <drm/drmP.h>
struct armada_drm_slave_config {
int i2c_adapter_id;
uint32_t crtcs;
uint8_t polled;
bool interlace_allowed;
bool doublescan_allowed;
struct i2c_board_info info;
};
int armada_drm_connector_slave_create(struct drm_device *dev,
const struct armada_drm_slave_config *);
#endif
...@@ -6,6 +6,7 @@ config DRM_AST ...@@ -6,6 +6,7 @@ config DRM_AST
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_TTM select DRM_TTM
help help
Say yes for experimental AST GPU driver. Do not enable Say yes for experimental AST GPU driver. Do not enable
......
...@@ -211,7 +211,6 @@ static struct drm_driver driver = { ...@@ -211,7 +211,6 @@ static struct drm_driver driver = {
.minor = DRIVER_MINOR, .minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL, .patchlevel = DRIVER_PATCHLEVEL,
.gem_init_object = ast_gem_init_object,
.gem_free_object = ast_gem_free_object, .gem_free_object = ast_gem_free_object,
.dumb_create = ast_dumb_create, .dumb_create = ast_dumb_create,
.dumb_map_offset = ast_dumb_mmap_offset, .dumb_map_offset = ast_dumb_mmap_offset,
......
...@@ -323,7 +323,6 @@ extern int ast_dumb_create(struct drm_file *file, ...@@ -323,7 +323,6 @@ extern int ast_dumb_create(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
struct drm_mode_create_dumb *args); struct drm_mode_create_dumb *args);
extern int ast_gem_init_object(struct drm_gem_object *obj);
extern void ast_gem_free_object(struct drm_gem_object *obj); extern void ast_gem_free_object(struct drm_gem_object *obj);
extern int ast_dumb_mmap_offset(struct drm_file *file, extern int ast_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
......
...@@ -449,12 +449,6 @@ int ast_dumb_create(struct drm_file *file, ...@@ -449,12 +449,6 @@ int ast_dumb_create(struct drm_file *file,
return 0; return 0;
} }
int ast_gem_init_object(struct drm_gem_object *obj)
{
BUG();
return 0;
}
void ast_bo_unref(struct ast_bo **bo) void ast_bo_unref(struct ast_bo **bo)
{ {
struct ttm_buffer_object *tbo; struct ttm_buffer_object *tbo;
......
...@@ -5,6 +5,7 @@ config DRM_CIRRUS_QEMU ...@@ -5,6 +5,7 @@ config DRM_CIRRUS_QEMU
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_TTM select DRM_TTM
help help
This is a KMS driver for emulated cirrus device in qemu. This is a KMS driver for emulated cirrus device in qemu.
......
...@@ -97,7 +97,6 @@ static struct drm_driver driver = { ...@@ -97,7 +97,6 @@ static struct drm_driver driver = {
.major = DRIVER_MAJOR, .major = DRIVER_MAJOR,
.minor = DRIVER_MINOR, .minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL, .patchlevel = DRIVER_PATCHLEVEL,
.gem_init_object = cirrus_gem_init_object,
.gem_free_object = cirrus_gem_free_object, .gem_free_object = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create, .dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset, .dumb_map_offset = cirrus_dumb_mmap_offset,
......
...@@ -191,7 +191,6 @@ int cirrus_device_init(struct cirrus_device *cdev, ...@@ -191,7 +191,6 @@ int cirrus_device_init(struct cirrus_device *cdev,
struct pci_dev *pdev, struct pci_dev *pdev,
uint32_t flags); uint32_t flags);
void cirrus_device_fini(struct cirrus_device *cdev); void cirrus_device_fini(struct cirrus_device *cdev);
int cirrus_gem_init_object(struct drm_gem_object *obj);
void cirrus_gem_free_object(struct drm_gem_object *obj); void cirrus_gem_free_object(struct drm_gem_object *obj);
int cirrus_dumb_mmap_offset(struct drm_file *file, int cirrus_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev, struct drm_device *dev,
......
...@@ -255,12 +255,6 @@ int cirrus_dumb_create(struct drm_file *file, ...@@ -255,12 +255,6 @@ int cirrus_dumb_create(struct drm_file *file,
return 0; return 0;
} }
int cirrus_gem_init_object(struct drm_gem_object *obj)
{
BUG();
return 0;
}
void cirrus_bo_unref(struct cirrus_bo **bo) void cirrus_bo_unref(struct cirrus_bo **bo)
{ {
struct ttm_buffer_object *tbo; struct ttm_buffer_object *tbo;
......
...@@ -494,13 +494,12 @@ static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev) ...@@ -494,13 +494,12 @@ static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev)
int cirrus_vga_get_modes(struct drm_connector *connector) int cirrus_vga_get_modes(struct drm_connector *connector)
{ {
/* Just add a static list of modes */ int count;
drm_add_modes_noedid(connector, 640, 480);
drm_add_modes_noedid(connector, 800, 600);
drm_add_modes_noedid(connector, 1024, 768);
drm_add_modes_noedid(connector, 1280, 1024);
return 4; /* Just add a static list of modes */
count = drm_add_modes_noedid(connector, 1280, 1024);
drm_set_preferred_mode(connector, 1024, 768);
return count;
} }
static int cirrus_vga_mode_valid(struct drm_connector *connector, static int cirrus_vga_mode_valid(struct drm_connector *connector,
......
...@@ -334,7 +334,6 @@ int drm_addctx(struct drm_device *dev, void *data, ...@@ -334,7 +334,6 @@ int drm_addctx(struct drm_device *dev, void *data,
mutex_lock(&dev->ctxlist_mutex); mutex_lock(&dev->ctxlist_mutex);
list_add(&ctx_entry->head, &dev->ctxlist); list_add(&ctx_entry->head, &dev->ctxlist);
++dev->ctx_count;
mutex_unlock(&dev->ctxlist_mutex); mutex_unlock(&dev->ctxlist_mutex);
return 0; return 0;
...@@ -432,7 +431,6 @@ int drm_rmctx(struct drm_device *dev, void *data, ...@@ -432,7 +431,6 @@ int drm_rmctx(struct drm_device *dev, void *data,
if (pos->handle == ctx->handle) { if (pos->handle == ctx->handle) {
list_del(&pos->head); list_del(&pos->head);
kfree(pos); kfree(pos);
--dev->ctx_count;
} }
} }
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* Initialization, etc. * Initialization, etc.
**************************************************/ **************************************************/
static struct drm_info_list drm_debugfs_list[] = { static const struct drm_info_list drm_debugfs_list[] = {
{"name", drm_name_info, 0}, {"name", drm_name_info, 0},
{"vm", drm_vm_info, 0}, {"vm", drm_vm_info, 0},
{"clients", drm_clients_info, 0}, {"clients", drm_clients_info, 0},
...@@ -84,7 +84,7 @@ static const struct file_operations drm_debugfs_fops = { ...@@ -84,7 +84,7 @@ static const struct file_operations drm_debugfs_fops = {
* Create a given set of debugfs files represented by an array of * Create a given set of debugfs files represented by an array of
* gdm_debugfs_lists in the given root directory. * gdm_debugfs_lists in the given root directory.
*/ */
int drm_debugfs_create_files(struct drm_info_list *files, int count, int drm_debugfs_create_files(const struct drm_info_list *files, int count,
struct dentry *root, struct drm_minor *minor) struct dentry *root, struct drm_minor *minor)
{ {
struct drm_device *dev = minor->dev; struct drm_device *dev = minor->dev;
...@@ -188,7 +188,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, ...@@ -188,7 +188,7 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
* *
* Remove all debugfs entries created by debugfs_init(). * Remove all debugfs entries created by debugfs_init().
*/ */
int drm_debugfs_remove_files(struct drm_info_list *files, int count, int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
struct drm_minor *minor) struct drm_minor *minor)
{ {
struct list_head *pos, *q; struct list_head *pos, *q;
......
...@@ -228,12 +228,12 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter) ...@@ -228,12 +228,12 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
EXPORT_SYMBOL(i2c_dp_aux_add_bus); EXPORT_SYMBOL(i2c_dp_aux_add_bus);
/* Helpers for DP link training */ /* Helpers for DP link training */
static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
{ {
return link_status[r - DP_LANE0_1_STATUS]; return link_status[r - DP_LANE0_1_STATUS];
} }
static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_LANE0_1_STATUS + (lane >> 1); int i = DP_LANE0_1_STATUS + (lane >> 1);
...@@ -242,7 +242,7 @@ static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -242,7 +242,7 @@ static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
return (l >> s) & 0xf; return (l >> s) & 0xf;
} }
bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count) int lane_count)
{ {
u8 lane_align; u8 lane_align;
...@@ -262,7 +262,7 @@ bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -262,7 +262,7 @@ bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_channel_eq_ok); EXPORT_SYMBOL(drm_dp_channel_eq_ok);
bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count) int lane_count)
{ {
int lane; int lane;
...@@ -277,7 +277,7 @@ bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -277,7 +277,7 @@ bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_clock_recovery_ok); EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
...@@ -290,7 +290,7 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -290,7 +290,7 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage); EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane) int lane)
{ {
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
...@@ -303,7 +303,7 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -303,7 +303,7 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(100); udelay(100);
else else
...@@ -311,7 +311,7 @@ void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { ...@@ -311,7 +311,7 @@ void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
} }
EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay); EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) { void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0) if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(400); udelay(400);
else else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -160,35 +160,6 @@ void drm_gem_private_object_init(struct drm_device *dev, ...@@ -160,35 +160,6 @@ void drm_gem_private_object_init(struct drm_device *dev,
} }
EXPORT_SYMBOL(drm_gem_private_object_init); EXPORT_SYMBOL(drm_gem_private_object_init);
/**
* Allocate a GEM object of the specified size with shmfs backing store
*/
struct drm_gem_object *
drm_gem_object_alloc(struct drm_device *dev, size_t size)
{
struct drm_gem_object *obj;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj)
goto free;
if (drm_gem_object_init(dev, obj, size) != 0)
goto free;
if (dev->driver->gem_init_object != NULL &&
dev->driver->gem_init_object(obj) != 0) {
goto fput;
}
return obj;
fput:
/* Object_init mangles the global counters - readjust them. */
fput(obj->filp);
free:
kfree(obj);
return NULL;
}
EXPORT_SYMBOL(drm_gem_object_alloc);
static void static void
drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp)
{ {
......
...@@ -67,7 +67,6 @@ int drm_global_item_ref(struct drm_global_reference *ref) ...@@ -67,7 +67,6 @@ int drm_global_item_ref(struct drm_global_reference *ref)
{ {
int ret; int ret;
struct drm_global_item *item = &glob[ref->global_type]; struct drm_global_item *item = &glob[ref->global_type];
void *object;
mutex_lock(&item->mutex); mutex_lock(&item->mutex);
if (item->refcount == 0) { if (item->refcount == 0) {
...@@ -85,7 +84,6 @@ int drm_global_item_ref(struct drm_global_reference *ref) ...@@ -85,7 +84,6 @@ int drm_global_item_ref(struct drm_global_reference *ref)
} }
++item->refcount; ++item->refcount;
ref->object = item->object; ref->object = item->object;
object = item->object;
mutex_unlock(&item->mutex); mutex_unlock(&item->mutex);
return 0; return 0;
out_err: out_err:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -2,6 +2,7 @@ config DRM_EXYNOS ...@@ -2,6 +2,7 @@ config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series" tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment