Commit 682b7c1c 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 the main drm merge window pull request, changes all over the
  place, mostly normal levels of churn.

  Highlights:

  Core drm:
     More cleanups, fix race on connector/encoder naming, docs updates,
     object locking rework in prep for atomic modeset

  i915:
     mipi DSI support, valleyview power fixes, cursor size fixes,
     execlist refactoring, vblank improvements, userptr support, OOM
     handling improvements

  radeon:
     GPUVM tuning and large page size support, gart fixes, deep color
     HDMI support, HDMI audio cleanups

  nouveau:
     - displayport rework should fix lots of issues
     - initial gk20a support
     - gk110b support
     - gk208 fixes

  exynos:
     probe order fixes, HDMI changes, IPP consolidation

  msm:
     debugfs updates, misc fixes

  ast:
     ast2400 support, sync with UMS driver

  tegra:
     cleanups, hdmi + hw cursor for Tegra 124.

  panel:
     fixes existing panels add some new ones.

  ipuv3:
     moved from staging to drivers/gpu"

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (761 commits)
  drm/nouveau/disp/dp: fix tmds passthrough on dp connector
  drm/nouveau/dp: probe dpcd to determine connectedness
  drm/nv50-: trigger update after all connectors disabled
  drm/nv50-: prepare for attaching a SOR to multiple heads
  drm/gf119-/disp: fix debug output on update failure
  drm/nouveau/disp/dp: make use of postcursor when its available
  drm/g94-/disp/dp: take max pullup value across all lanes
  drm/nouveau/bios/dp: parse lane postcursor data
  drm/nouveau/dp: fix support for dpms
  drm/nouveau: register a drm_dp_aux channel for each dp connector
  drm/g94-/disp: add method to power-off dp lanes
  drm/nouveau/disp/dp: maintain link in response to hpd signal
  drm/g94-/disp: bash and wait for something after changing lane power regs
  drm/nouveau/disp/dp: split link config/power into two steps
  drm/nv50/disp: train PIOR-attached DP from second supervisor
  drm/nouveau/disp/dp: make use of existing output data for link training
  drm/gf119/disp: start removing direct vbios parsing from supervisor
  drm/nv50/disp: start removing direct vbios parsing from supervisor
  drm/nouveau/disp/dp: maintain receiver caps in response to hpd signal
  drm/nouveau/disp/dp: create subclass for dp outputs
  ...
parents 16b90578 bc1dfff0
This diff is collapsed.
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux XGA" #define TIMING_NAME "Linux XGA"
#define ESTABLISHED_TIMINGS_BITS 0x08 /* Bit 3 -> 1024x768 @60 Hz */ #define ESTABLISHED_TIMING2_BITS 0x08 /* Bit 3 -> 1024x768 @60 Hz */
#define HSYNC_POL 0 #define HSYNC_POL 0
#define VSYNC_POL 0 #define VSYNC_POL 0
#define CRC 0x55 #define CRC 0x55
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux SXGA" #define TIMING_NAME "Linux SXGA"
#define ESTABLISHED_TIMINGS_BITS 0x00 /* none */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0xa0 #define CRC 0xa0
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux UXGA" #define TIMING_NAME "Linux UXGA"
#define ESTABLISHED_TIMINGS_BITS 0x00 /* none */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x9d #define CRC 0x9d
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define DPI 96 #define DPI 96
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux WSXGA" #define TIMING_NAME "Linux WSXGA"
#define ESTABLISHED_TIMINGS_BITS 0x00 /* none */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x26 #define CRC 0x26
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define DPI 96 #define DPI 96
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux FHD" #define TIMING_NAME "Linux FHD"
#define ESTABLISHED_TIMINGS_BITS 0x00 /* none */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x05 #define CRC 0x05
......
/*
800x600.S: EDID data set for standard 800x600 60 Hz monitor
Copyright (C) 2011 Carsten Emde <C.Emde@osadl.org>
Copyright (C) 2014 Linaro Limited
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
/* EDID */
#define VERSION 1
#define REVISION 3
/* Display */
#define CLOCK 40000 /* kHz */
#define XPIX 800
#define YPIX 600
#define XY_RATIO XY_RATIO_4_3
#define XBLANK 256
#define YBLANK 28
#define XOFFSET 40
#define XPULSE 128
#define YOFFSET (63+1)
#define YPULSE (63+4)
#define DPI 72
#define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux SVGA"
#define ESTABLISHED_TIMING1_BITS 0x01 /* Bit 0: 800x600 @ 60Hz */
#define HSYNC_POL 1
#define VSYNC_POL 1
#define CRC 0xc2
#include "edid.S"
...@@ -18,7 +18,7 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an ...@@ -18,7 +18,7 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an
individually prepared or corrected EDID data set in the /lib/firmware individually prepared or corrected EDID data set in the /lib/firmware
directory from where it is loaded via the firmware interface. The code directory from where it is loaded via the firmware interface. The code
(see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for (see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for
commonly used screen resolutions (1024x768, 1280x1024, 1600x1200, commonly used screen resolutions (800x600, 1024x768, 1280x1024, 1600x1200,
1680x1050, 1920x1080) as binary blobs, but the kernel source tree does 1680x1050, 1920x1080) as binary blobs, but the kernel source tree does
not contain code to create these data. In order to elucidate the origin not contain code to create these data. In order to elucidate the origin
of the built-in binary EDID blobs and to facilitate the creation of of the built-in binary EDID blobs and to facilitate the creation of
......
...@@ -33,6 +33,17 @@ ...@@ -33,6 +33,17 @@
#define XY_RATIO_5_4 0b10 #define XY_RATIO_5_4 0b10
#define XY_RATIO_16_9 0b11 #define XY_RATIO_16_9 0b11
/* Provide defaults for the timing bits */
#ifndef ESTABLISHED_TIMING1_BITS
#define ESTABLISHED_TIMING1_BITS 0x00
#endif
#ifndef ESTABLISHED_TIMING2_BITS
#define ESTABLISHED_TIMING2_BITS 0x00
#endif
#ifndef ESTABLISHED_TIMING3_BITS
#define ESTABLISHED_TIMING3_BITS 0x00
#endif
#define mfgname2id(v1,v2,v3) \ #define mfgname2id(v1,v2,v3) \
((((v1-'@')&0x1f)<<10)+(((v2-'@')&0x1f)<<5)+((v3-'@')&0x1f)) ((((v1-'@')&0x1f)<<10)+(((v2-'@')&0x1f)<<5)+((v3-'@')&0x1f))
#define swap16(v1) ((v1>>8)+((v1&0xff)<<8)) #define swap16(v1) ((v1>>8)+((v1&0xff)<<8))
...@@ -139,7 +150,7 @@ white_x_y_msb: .byte 0x50,0x54 ...@@ -139,7 +150,7 @@ white_x_y_msb: .byte 0x50,0x54
Bit 2 640x480 @ 75 Hz Bit 2 640x480 @ 75 Hz
Bit 1 800x600 @ 56 Hz Bit 1 800x600 @ 56 Hz
Bit 0 800x600 @ 60 Hz */ Bit 0 800x600 @ 60 Hz */
estbl_timing1: .byte 0x00 estbl_timing1: .byte ESTABLISHED_TIMING1_BITS
/* Bit 7 800x600 @ 72 Hz /* Bit 7 800x600 @ 72 Hz
Bit 6 800x600 @ 75 Hz Bit 6 800x600 @ 75 Hz
...@@ -149,11 +160,11 @@ estbl_timing1: .byte 0x00 ...@@ -149,11 +160,11 @@ estbl_timing1: .byte 0x00
Bit 2 1024x768 @ 72 Hz Bit 2 1024x768 @ 72 Hz
Bit 1 1024x768 @ 75 Hz Bit 1 1024x768 @ 75 Hz
Bit 0 1280x1024 @ 75 Hz */ Bit 0 1280x1024 @ 75 Hz */
estbl_timing2: .byte ESTABLISHED_TIMINGS_BITS estbl_timing2: .byte ESTABLISHED_TIMING2_BITS
/* Bit 7 1152x870 @ 75 Hz (Apple Macintosh II) /* Bit 7 1152x870 @ 75 Hz (Apple Macintosh II)
Bits 6-0 Other manufacturer-specific display mod */ Bits 6-0 Other manufacturer-specific display mod */
estbl_timing3: .byte 0x00 estbl_timing3: .byte ESTABLISHED_TIMING3_BITS
/* Standard timing */ /* Standard timing */
/* X resolution, less 31, divided by 8 (256-2288 pixels) */ /* X resolution, less 31, divided by 8 (256-2288 pixels) */
......
...@@ -136,6 +136,7 @@ of the following host1x client modules: ...@@ -136,6 +136,7 @@ of the following host1x client modules:
- compatible: "nvidia,tegra<chip>-hdmi" - compatible: "nvidia,tegra<chip>-hdmi"
- reg: Physical base address and length of the controller's registers. - reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt outputs from the controller. - interrupts: The interrupt outputs from the controller.
- hdmi-supply: supply for the +5V HDMI connector pin
- vdd-supply: regulator for supply voltage - vdd-supply: regulator for supply voltage
- pll-supply: regulator for PLL - pll-supply: regulator for PLL
- clocks: Must contain an entry for each entry in clock-names. - clocks: Must contain an entry for each entry in clock-names.
...@@ -180,6 +181,7 @@ of the following host1x client modules: ...@@ -180,6 +181,7 @@ of the following host1x client modules:
See ../reset/reset.txt for details. See ../reset/reset.txt for details.
- reset-names: Must include the following entries: - reset-names: Must include the following entries:
- dsi - dsi
- avdd-dsi-supply: phandle of a supply that powers the DSI controller
- nvidia,mipi-calibrate: Should contain a phandle and a specifier specifying - nvidia,mipi-calibrate: Should contain a phandle and a specifier specifying
which pads are used by this DSI output and need to be calibrated. See also which pads are used by this DSI output and need to be calibrated. See also
../mipi/nvidia,tegra114-mipi.txt. ../mipi/nvidia,tegra114-mipi.txt.
......
AU Optronics Corporation 13.3" WXGA (1366x768) TFT LCD panel
Required properties:
- compatible: should be "auo,b133xtn01"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
Emerging Display Technology Corp. 5.7" VGA TFT LCD panel
Required properties:
- compatible: should be "edt,et057090dhu"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
Emerging Display Technology Corp. ET070080DH6 7.0" WVGA TFT LCD panel
Required properties:
- compatible: should be "edt,et070080dh6"
This panel is the same as ETM0700G0DH6 except for the touchscreen.
ET070080DH6 is the model with resistive touch.
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
Emerging Display Technology Corp. ETM0700G0DH6 7.0" WVGA TFT LCD panel
Required properties:
- compatible: should be "edt,etm0700g0dh6"
This panel is the same as ET070080DH6 except for the touchscreen.
ETM0700G0DH6 is the model with capacitive multitouch.
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
...@@ -62,6 +62,10 @@ Optional properties for dp-controller: ...@@ -62,6 +62,10 @@ Optional properties for dp-controller:
-hsync-active-high: -hsync-active-high:
HSYNC polarity configuration. HSYNC polarity configuration.
High if defined, Low if not defined High if defined, Low if not defined
-samsung,hpd-gpio:
Hotplug detect GPIO.
Indicates which GPIO should be used for hotplug
detection
Example: Example:
......
...@@ -5,6 +5,7 @@ Required properties: ...@@ -5,6 +5,7 @@ Required properties:
1) "samsung,exynos5-hdmi" <DEPRECATED> 1) "samsung,exynos5-hdmi" <DEPRECATED>
2) "samsung,exynos4210-hdmi" 2) "samsung,exynos4210-hdmi"
3) "samsung,exynos4212-hdmi" 3) "samsung,exynos4212-hdmi"
4) "samsung,exynos5420-hdmi"
- reg: physical base address of the hdmi and length of memory mapped - reg: physical base address of the hdmi and length of memory mapped
region. region.
- interrupts: interrupt number to the cpu. - interrupts: interrupt number to the cpu.
...@@ -27,6 +28,7 @@ Required properties: ...@@ -27,6 +28,7 @@ Required properties:
"hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
- ddc: phandle to the hdmi ddc node - ddc: phandle to the hdmi ddc node
- phy: phandle to the hdmi phy node - phy: phandle to the hdmi phy node
- samsung,syscon-phandle: phandle for system controller node for PMU.
Example: Example:
...@@ -37,4 +39,5 @@ Example: ...@@ -37,4 +39,5 @@ Example:
hpd-gpio = <&gpx3 7 1>; hpd-gpio = <&gpx3 7 1>;
ddc = <&hdmi_ddc_node>; ddc = <&hdmi_ddc_node>;
phy = <&hdmi_phy_node>; phy = <&hdmi_phy_node>;
samsung,syscon-phandle = <&pmu_system_controller>;
}; };
...@@ -2952,6 +2952,7 @@ L: dri-devel@lists.freedesktop.org ...@@ -2952,6 +2952,7 @@ L: dri-devel@lists.freedesktop.org
T: git git://people.freedesktop.org/~airlied/linux T: git git://people.freedesktop.org/~airlied/linux
S: Maintained S: Maintained
F: drivers/gpu/drm/ F: drivers/gpu/drm/
F: drivers/gpu/vga/
F: include/drm/ F: include/drm/
F: include/uapi/drm/ F: include/uapi/drm/
......
...@@ -419,7 +419,7 @@ static size_t __init gen6_stolen_size(int num, int slot, int func) ...@@ -419,7 +419,7 @@ 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 size_t gen8_stolen_size(int num, int slot, int func) static size_t __init gen8_stolen_size(int num, int slot, int func)
{ {
u16 gmch_ctrl; u16 gmch_ctrl;
...@@ -429,48 +429,73 @@ static size_t gen8_stolen_size(int num, int slot, int func) ...@@ -429,48 +429,73 @@ static size_t gen8_stolen_size(int num, int slot, int func)
return gmch_ctrl << 25; /* 32 MB units */ return gmch_ctrl << 25; /* 32 MB units */
} }
static size_t __init chv_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 >>= SNB_GMCH_GMS_SHIFT;
gmch_ctrl &= SNB_GMCH_GMS_MASK;
/*
* 0x0 to 0x10: 32MB increments starting at 0MB
* 0x11 to 0x16: 4MB increments starting at 8MB
* 0x17 to 0x1d: 4MB increments start at 36MB
*/
if (gmch_ctrl < 0x11)
return gmch_ctrl << 25;
else if (gmch_ctrl < 0x17)
return (gmch_ctrl - 0x11 + 2) << 22;
else
return (gmch_ctrl - 0x17 + 9) << 22;
}
struct intel_stolen_funcs { struct intel_stolen_funcs {
size_t (*size)(int num, int slot, int func); size_t (*size)(int num, int slot, int func);
u32 (*base)(int num, int slot, int func, size_t size); u32 (*base)(int num, int slot, int func, size_t size);
}; };
static const struct intel_stolen_funcs i830_stolen_funcs = { static const struct intel_stolen_funcs i830_stolen_funcs __initconst = {
.base = i830_stolen_base, .base = i830_stolen_base,
.size = i830_stolen_size, .size = i830_stolen_size,
}; };
static const struct intel_stolen_funcs i845_stolen_funcs = { static const struct intel_stolen_funcs i845_stolen_funcs __initconst = {
.base = i845_stolen_base, .base = i845_stolen_base,
.size = i830_stolen_size, .size = i830_stolen_size,
}; };
static const struct intel_stolen_funcs i85x_stolen_funcs = { static const struct intel_stolen_funcs i85x_stolen_funcs __initconst = {
.base = i85x_stolen_base, .base = i85x_stolen_base,
.size = gen3_stolen_size, .size = gen3_stolen_size,
}; };
static const struct intel_stolen_funcs i865_stolen_funcs = { static const struct intel_stolen_funcs i865_stolen_funcs __initconst = {
.base = i865_stolen_base, .base = i865_stolen_base,
.size = gen3_stolen_size, .size = gen3_stolen_size,
}; };
static const struct intel_stolen_funcs gen3_stolen_funcs = { static const struct intel_stolen_funcs gen3_stolen_funcs __initconst = {
.base = intel_stolen_base, .base = intel_stolen_base,
.size = gen3_stolen_size, .size = gen3_stolen_size,
}; };
static const struct intel_stolen_funcs gen6_stolen_funcs = { static const struct intel_stolen_funcs gen6_stolen_funcs __initconst = {
.base = intel_stolen_base, .base = intel_stolen_base,
.size = gen6_stolen_size, .size = gen6_stolen_size,
}; };
static const struct intel_stolen_funcs gen8_stolen_funcs = { static const struct intel_stolen_funcs gen8_stolen_funcs __initconst = {
.base = intel_stolen_base, .base = intel_stolen_base,
.size = gen8_stolen_size, .size = gen8_stolen_size,
}; };
static struct pci_device_id intel_stolen_ids[] __initdata = { static const struct intel_stolen_funcs chv_stolen_funcs __initconst = {
.base = intel_stolen_base,
.size = chv_stolen_size,
};
static const struct pci_device_id intel_stolen_ids[] __initconst = {
INTEL_I830_IDS(&i830_stolen_funcs), INTEL_I830_IDS(&i830_stolen_funcs),
INTEL_I845G_IDS(&i845_stolen_funcs), INTEL_I845G_IDS(&i845_stolen_funcs),
INTEL_I85X_IDS(&i85x_stolen_funcs), INTEL_I85X_IDS(&i85x_stolen_funcs),
...@@ -496,7 +521,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = { ...@@ -496,7 +521,8 @@ static struct pci_device_id intel_stolen_ids[] __initdata = {
INTEL_HSW_D_IDS(&gen6_stolen_funcs), INTEL_HSW_D_IDS(&gen6_stolen_funcs),
INTEL_HSW_M_IDS(&gen6_stolen_funcs), INTEL_HSW_M_IDS(&gen6_stolen_funcs),
INTEL_BDW_M_IDS(&gen8_stolen_funcs), INTEL_BDW_M_IDS(&gen8_stolen_funcs),
INTEL_BDW_D_IDS(&gen8_stolen_funcs) INTEL_BDW_D_IDS(&gen8_stolen_funcs),
INTEL_CHV_IDS(&chv_stolen_funcs),
}; };
static void __init intel_graphics_stolen(int num, int slot, int func) static void __init intel_graphics_stolen(int num, int slot, int func)
......
obj-y += drm/ vga/ obj-y += drm/ vga/
obj-$(CONFIG_TEGRA_HOST1X) += host1x/ obj-$(CONFIG_TEGRA_HOST1X) += host1x/
obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
...@@ -83,6 +83,8 @@ config DRM_KMS_CMA_HELPER ...@@ -83,6 +83,8 @@ config DRM_KMS_CMA_HELPER
source "drivers/gpu/drm/i2c/Kconfig" source "drivers/gpu/drm/i2c/Kconfig"
source "drivers/gpu/drm/bridge/Kconfig"
config DRM_TDFX config DRM_TDFX
tristate "3dfx Banshee/Voodoo3+" tristate "3dfx Banshee/Voodoo3+"
depends on DRM && PCI depends on DRM && PCI
...@@ -199,5 +201,3 @@ source "drivers/gpu/drm/msm/Kconfig" ...@@ -199,5 +201,3 @@ source "drivers/gpu/drm/msm/Kconfig"
source "drivers/gpu/drm/tegra/Kconfig" source "drivers/gpu/drm/tegra/Kconfig"
source "drivers/gpu/drm/panel/Kconfig" source "drivers/gpu/drm/panel/Kconfig"
source "drivers/gpu/drm/bridge/Kconfig"
...@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ ...@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.o \ drm_trace_points.o drm_global.o drm_prime.o \
drm_rect.o drm_vma_manager.o drm_flip_work.o \ drm_rect.o drm_vma_manager.o drm_flip_work.o \
drm_plane_helper.o drm_modeset_lock.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
...@@ -23,7 +23,8 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o ...@@ -23,7 +23,8 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
drm-usb-y := drm_usb.o drm-usb-y := drm_usb.o
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_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_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
......
...@@ -173,7 +173,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -173,7 +173,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (ret) if (ret)
goto err_kms; goto err_kms;
ret = drm_irq_install(dev); ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
if (ret) if (ret)
goto err_kms; goto err_kms;
...@@ -402,7 +402,7 @@ static struct platform_driver armada_drm_platform_driver = { ...@@ -402,7 +402,7 @@ static struct platform_driver armada_drm_platform_driver = {
static int __init armada_drm_init(void) static int __init armada_drm_init(void)
{ {
armada_drm_driver.num_ioctls = DRM_ARRAY_SIZE(armada_ioctls); armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls);
return platform_driver_register(&armada_drm_platform_driver); return platform_driver_register(&armada_drm_platform_driver);
} }
module_init(armada_drm_init); module_init(armada_drm_init);
......
...@@ -181,10 +181,8 @@ void armada_fbdev_lastclose(struct drm_device *dev) ...@@ -181,10 +181,8 @@ void armada_fbdev_lastclose(struct drm_device *dev)
{ {
struct armada_private *priv = dev->dev_private; struct armada_private *priv = dev->dev_private;
drm_modeset_lock_all(dev);
if (priv->fbdev) if (priv->fbdev)
drm_fb_helper_restore_fbdev_mode(priv->fbdev); drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
drm_modeset_unlock_all(dev);
} }
void armada_fbdev_fini(struct drm_device *dev) void armada_fbdev_fini(struct drm_device *dev)
......
...@@ -433,7 +433,6 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, ...@@ -433,7 +433,6 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
if (dobj->obj.filp) { if (dobj->obj.filp) {
struct address_space *mapping; struct address_space *mapping;
gfp_t gfp;
int count; int count;
count = dobj->obj.size / PAGE_SIZE; count = dobj->obj.size / PAGE_SIZE;
...@@ -441,12 +440,11 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, ...@@ -441,12 +440,11 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
goto free_sgt; goto free_sgt;
mapping = file_inode(dobj->obj.filp)->i_mapping; mapping = file_inode(dobj->obj.filp)->i_mapping;
gfp = mapping_gfp_mask(mapping);
for_each_sg(sgt->sgl, sg, count, i) { for_each_sg(sgt->sgl, sg, count, i) {
struct page *page; struct page *page;
page = shmem_read_mapping_page_gfp(mapping, i, gfp); page = shmem_read_mapping_page(mapping, i);
if (IS_ERR(page)) { if (IS_ERR(page)) {
num = i; num = i;
goto release; goto release;
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
ccflags-y := -Iinclude/drm ccflags-y := -Iinclude/drm
ast-y := ast_drv.o ast_main.o ast_mode.o ast_fb.o ast_ttm.o ast_post.o ast-y := ast_drv.o ast_main.o ast_mode.o ast_fb.o ast_ttm.o ast_post.o ast_dp501.o
obj-$(CONFIG_DRM_AST) := ast.o obj-$(CONFIG_DRM_AST) := ast.o
\ No newline at end of file
#include <linux/firmware.h>
#include <drm/drmP.h>
#include "ast_drv.h"
MODULE_FIRMWARE("ast_dp501_fw.bin");
int ast_load_dp501_microcode(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
static char *fw_name = "ast_dp501_fw.bin";
int err;
err = request_firmware(&ast->dp501_fw, fw_name, dev->dev);
if (err)
return err;
return 0;
}
static void send_ack(struct ast_private *ast)
{
u8 sendack;
sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
sendack |= 0x80;
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
}
static void send_nack(struct ast_private *ast)
{
u8 sendack;
sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
sendack &= ~0x80;
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
}
static bool wait_ack(struct ast_private *ast)
{
u8 waitack;
u32 retry = 0;
do {
waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
waitack &= 0x80;
udelay(100);
} while ((!waitack) && (retry++ < 1000));
if (retry < 1000)
return true;
else
return false;
}
static bool wait_nack(struct ast_private *ast)
{
u8 waitack;
u32 retry = 0;
do {
waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
waitack &= 0x80;
udelay(100);
} while ((waitack) && (retry++ < 1000));
if (retry < 1000)
return true;
else
return false;
}
static void set_cmd_trigger(struct ast_private *ast)
{
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
}
static void clear_cmd_trigger(struct ast_private *ast)
{
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
}
#if 0
static bool wait_fw_ready(struct ast_private *ast)
{
u8 waitready;
u32 retry = 0;
do {
waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
waitready &= 0x40;
udelay(100);
} while ((!waitready) && (retry++ < 1000));
if (retry < 1000)
return true;
else
return false;
}
#endif
static bool ast_write_cmd(struct drm_device *dev, u8 data)
{
struct ast_private *ast = dev->dev_private;
int retry = 0;
if (wait_nack(ast)) {
send_nack(ast);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
send_ack(ast);
set_cmd_trigger(ast);
do {
if (wait_ack(ast)) {
clear_cmd_trigger(ast);
send_nack(ast);
return true;
}
} while (retry++ < 100);
}
clear_cmd_trigger(ast);
send_nack(ast);
return false;
}
static bool ast_write_data(struct drm_device *dev, u8 data)
{
struct ast_private *ast = dev->dev_private;
if (wait_nack(ast)) {
send_nack(ast);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
send_ack(ast);
if (wait_ack(ast)) {
send_nack(ast);
return true;
}
}
send_nack(ast);
return false;
}
#if 0
static bool ast_read_data(struct drm_device *dev, u8 *data)
{
struct ast_private *ast = dev->dev_private;
u8 tmp;
*data = 0;
if (wait_ack(ast) == false)
return false;
tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff);
*data = tmp;
if (wait_nack(ast) == false) {
send_nack(ast);
return false;
}
send_nack(ast);
return true;
}
static void clear_cmd(struct ast_private *ast)
{
send_nack(ast);
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
}
#endif
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode)
{
ast_write_cmd(dev, 0x40);
ast_write_data(dev, mode);
msleep(10);
}
static u32 get_fw_base(struct ast_private *ast)
{
return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff;
}
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
{
struct ast_private *ast = dev->dev_private;
u32 i, data;
u32 boot_address;
data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
if (data) {
boot_address = get_fw_base(ast);
for (i = 0; i < size; i += 4)
*(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i);
return true;
}
return false;
}
bool ast_launch_m68k(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u32 i, data, len = 0;
u32 boot_address;
u8 *fw_addr = NULL;
u8 jreg;
data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
if (!data) {
if (ast->dp501_fw_addr) {
fw_addr = ast->dp501_fw_addr;
len = 32*1024;
} else if (ast->dp501_fw) {
fw_addr = (u8 *)ast->dp501_fw->data;
len = ast->dp501_fw->size;
}
/* Get BootAddress */
ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
data = ast_mindwm(ast, 0x1e6e0004);
switch (data & 0x03) {
case 0:
boot_address = 0x44000000;
break;
default:
case 1:
boot_address = 0x48000000;
break;
case 2:
boot_address = 0x50000000;
break;
case 3:
boot_address = 0x60000000;
break;
}
boot_address -= 0x200000; /* -2MB */
/* copy image to buffer */
for (i = 0; i < len; i += 4) {
data = *(u32 *)(fw_addr + i);
ast_moutdwm(ast, boot_address + i, data);
}
/* Init SCU */
ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
/* Launch FW */
ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address);
ast_moutdwm(ast, 0x1e6e2100, 1);
/* Update Scratch */
data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff; /* D[11:9] = 100b: UEFI handling */
data |= 0x800;
ast_moutdwm(ast, 0x1e6e2040, data);
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
jreg |= 0x02;
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
}
return true;
}
u8 ast_get_dp501_max_clk(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u32 boot_address, offset, data;
u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
boot_address = get_fw_base(ast);
/* validate FW version */
offset = 0xf000;
data = ast_mindwm(ast, boot_address + offset);
if ((data & 0xf0) != 0x10) /* version: 1x */
return maxclk;
/* Read Link Capability */
offset = 0xf014;
*(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
if (linkcap[2] == 0) {
linkrate = linkcap[0];
linklanes = linkcap[1];
data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
if (data > 0xff)
data = 0xff;
maxclk = (u8)data;
}
return maxclk;
}
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
{
struct ast_private *ast = dev->dev_private;
u32 i, boot_address, offset, data;
boot_address = get_fw_base(ast);
/* validate FW version */
offset = 0xf000;
data = ast_mindwm(ast, boot_address + offset);
if ((data & 0xf0) != 0x10)
return false;
/* validate PnP Monitor */
offset = 0xf010;
data = ast_mindwm(ast, boot_address + offset);
if (!(data & 0x01))
return false;
/* Read EDID */
offset = 0xf020;
for (i = 0; i < 128; i += 4) {
data = ast_mindwm(ast, boot_address + offset + i);
*(u32 *)(ediddata + i) = data;
}
return true;
}
static bool ast_init_dvo(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u8 jreg;
u32 data;
ast_write32(ast, 0xf004, 0x1e6e0000);
ast_write32(ast, 0xf000, 0x1);
ast_write32(ast, 0x12000, 0x1688a8a8);
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
if (!(jreg & 0x80)) {
/* Init SCU DVO Settings */
data = ast_read32(ast, 0x12008);
/* delay phase */
data &= 0xfffff8ff;
data |= 0x00000500;
ast_write32(ast, 0x12008, data);
if (ast->chip == AST2300) {
data = ast_read32(ast, 0x12084);
/* multi-pins for DVO single-edge */
data |= 0xfffe0000;
ast_write32(ast, 0x12084, data);
data = ast_read32(ast, 0x12088);
/* multi-pins for DVO single-edge */
data |= 0x000fffff;
ast_write32(ast, 0x12088, data);
data = ast_read32(ast, 0x12090);
/* multi-pins for DVO single-edge */
data &= 0xffffffcf;
data |= 0x00000020;
ast_write32(ast, 0x12090, data);
} else { /* AST2400 */
data = ast_read32(ast, 0x12088);
/* multi-pins for DVO single-edge */
data |= 0x30000000;
ast_write32(ast, 0x12088, data);
data = ast_read32(ast, 0x1208c);
/* multi-pins for DVO single-edge */
data |= 0x000000cf;
ast_write32(ast, 0x1208c, data);
data = ast_read32(ast, 0x120a4);
/* multi-pins for DVO single-edge */
data |= 0xffff0000;
ast_write32(ast, 0x120a4, data);
data = ast_read32(ast, 0x120a8);
/* multi-pins for DVO single-edge */
data |= 0x0000000f;
ast_write32(ast, 0x120a8, data);
data = ast_read32(ast, 0x12094);
/* multi-pins for DVO single-edge */
data |= 0x00000002;
ast_write32(ast, 0x12094, data);
}
}
/* Force to DVO */
data = ast_read32(ast, 0x1202c);
data &= 0xfffbffff;
ast_write32(ast, 0x1202c, data);
/* Init VGA DVO Settings */
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
return true;
}
void ast_init_3rdtx(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u8 jreg;
u32 data;
if (ast->chip == AST2300 || ast->chip == AST2400) {
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
switch (jreg & 0x0e) {
case 0x04:
ast_init_dvo(dev);
break;
case 0x08:
ast_launch_m68k(dev);
break;
case 0x0c:
ast_init_dvo(dev);
break;
default:
if (ast->tx_chip_type == AST_TX_SIL164)
ast_init_dvo(dev);
else {
ast_write32(ast, 0x12000, 0x1688a8a8);
data = ast_read32(ast, 0x1202c);
data &= 0xfffcffff;
ast_write32(ast, 0, data);
}
}
}
}
...@@ -94,9 +94,7 @@ static int ast_drm_thaw(struct drm_device *dev) ...@@ -94,9 +94,7 @@ static int ast_drm_thaw(struct drm_device *dev)
ast_post_gpu(dev); ast_post_gpu(dev);
drm_mode_config_reset(dev); drm_mode_config_reset(dev);
drm_modeset_lock_all(dev);
drm_helper_resume_force_mode(dev); drm_helper_resume_force_mode(dev);
drm_modeset_unlock_all(dev);
console_lock(); console_lock();
ast_fbdev_set_suspend(dev, 0); ast_fbdev_set_suspend(dev, 0);
...@@ -198,7 +196,6 @@ static const struct file_operations ast_fops = { ...@@ -198,7 +196,6 @@ static const struct file_operations ast_fops = {
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM, .driver_features = DRIVER_MODESET | DRIVER_GEM,
.dev_priv_size = 0,
.load = ast_driver_load, .load = ast_driver_load,
.unload = ast_driver_unload, .unload = ast_driver_unload,
......
...@@ -61,9 +61,17 @@ enum ast_chip { ...@@ -61,9 +61,17 @@ enum ast_chip {
AST2200, AST2200,
AST2150, AST2150,
AST2300, AST2300,
AST2400,
AST1180, AST1180,
}; };
enum ast_tx_chip {
AST_TX_NONE,
AST_TX_SIL164,
AST_TX_ITE66121,
AST_TX_DP501,
};
#define AST_DRAM_512Mx16 0 #define AST_DRAM_512Mx16 0
#define AST_DRAM_1Gx16 1 #define AST_DRAM_1Gx16 1
#define AST_DRAM_512Mx32 2 #define AST_DRAM_512Mx32 2
...@@ -102,6 +110,12 @@ struct ast_private { ...@@ -102,6 +110,12 @@ struct ast_private {
* we have. */ * we have. */
struct ttm_bo_kmap_obj cache_kmap; struct ttm_bo_kmap_obj cache_kmap;
int next_cursor; int next_cursor;
bool support_wide_screen;
enum ast_tx_chip tx_chip_type;
u8 dp501_maxclk;
u8 *dp501_fw_addr;
const struct firmware *dp501_fw; /* dp501 fw */
}; };
int ast_driver_load(struct drm_device *dev, unsigned long flags); int ast_driver_load(struct drm_device *dev, unsigned long flags);
...@@ -368,4 +382,14 @@ int ast_mmap(struct file *filp, struct vm_area_struct *vma); ...@@ -368,4 +382,14 @@ int ast_mmap(struct file *filp, struct vm_area_struct *vma);
/* ast post */ /* ast post */
void ast_post_gpu(struct drm_device *dev); void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
/* ast dp501 */
int ast_load_dp501_microcode(struct drm_device *dev);
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
bool ast_launch_m68k(struct drm_device *dev);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
u8 ast_get_dp501_max_clk(struct drm_device *dev);
void ast_init_3rdtx(struct drm_device *dev);
#endif #endif
...@@ -66,12 +66,16 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, ...@@ -66,12 +66,16 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
static int ast_detect_chip(struct drm_device *dev) static int ast_detect_chip(struct drm_device *dev)
{ {
struct ast_private *ast = dev->dev_private; struct ast_private *ast = dev->dev_private;
uint32_t data, jreg;
if (dev->pdev->device == PCI_CHIP_AST1180) { if (dev->pdev->device == PCI_CHIP_AST1180) {
ast->chip = AST1100; ast->chip = AST1100;
DRM_INFO("AST 1180 detected\n"); DRM_INFO("AST 1180 detected\n");
} else { } else {
if (dev->pdev->revision >= 0x20) { if (dev->pdev->revision >= 0x30) {
ast->chip = AST2400;
DRM_INFO("AST 2400 detected\n");
} else if (dev->pdev->revision >= 0x20) {
ast->chip = AST2300; ast->chip = AST2300;
DRM_INFO("AST 2300 detected\n"); DRM_INFO("AST 2300 detected\n");
} else if (dev->pdev->revision >= 0x10) { } else if (dev->pdev->revision >= 0x10) {
...@@ -104,6 +108,59 @@ static int ast_detect_chip(struct drm_device *dev) ...@@ -104,6 +108,59 @@ static int ast_detect_chip(struct drm_device *dev)
DRM_INFO("AST 2000 detected\n"); DRM_INFO("AST 2000 detected\n");
} }
} }
switch (ast->chip) {
case AST1180:
ast->support_wide_screen = true;
break;
case AST2000:
ast->support_wide_screen = false;
break;
default:
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
if (!(jreg & 0x80))
ast->support_wide_screen = true;
else if (jreg & 0x01)
ast->support_wide_screen = true;
else {
ast->support_wide_screen = false;
ast_write32(ast, 0xf004, 0x1e6e0000);
ast_write32(ast, 0xf000, 0x1);
data = ast_read32(ast, 0x1207c);
data &= 0x300;
if (ast->chip == AST2300 && data == 0x0) /* ast1300 */
ast->support_wide_screen = true;
if (ast->chip == AST2400 && data == 0x100) /* ast1400 */
ast->support_wide_screen = true;
}
break;
}
ast->tx_chip_type = AST_TX_NONE;
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
if (jreg & 0x80)
ast->tx_chip_type = AST_TX_SIL164;
if ((ast->chip == AST2300) || (ast->chip == AST2400)) {
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
switch (jreg) {
case 0x04:
ast->tx_chip_type = AST_TX_SIL164;
break;
case 0x08:
ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);
if (ast->dp501_fw_addr) {
/* backup firmware */
if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
kfree(ast->dp501_fw_addr);
ast->dp501_fw_addr = NULL;
}
}
/* fallthrough */
case 0x0c:
ast->tx_chip_type = AST_TX_DP501;
}
}
return 0; return 0;
} }
...@@ -129,7 +186,7 @@ static int ast_get_dram_info(struct drm_device *dev) ...@@ -129,7 +186,7 @@ static int ast_get_dram_info(struct drm_device *dev)
else else
ast->dram_bus_width = 32; ast->dram_bus_width = 32;
if (ast->chip == AST2300) { if (ast->chip == AST2300 || ast->chip == AST2400) {
switch (data & 0x03) { switch (data & 0x03) {
case 0: case 0:
ast->dram_type = AST_DRAM_512Mx16; ast->dram_type = AST_DRAM_512Mx16;
...@@ -257,17 +314,32 @@ static u32 ast_get_vram_info(struct drm_device *dev) ...@@ -257,17 +314,32 @@ static u32 ast_get_vram_info(struct drm_device *dev)
{ {
struct ast_private *ast = dev->dev_private; struct ast_private *ast = dev->dev_private;
u8 jreg; u8 jreg;
u32 vram_size;
ast_open_key(ast); ast_open_key(ast);
vram_size = AST_VIDMEM_DEFAULT_SIZE;
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
switch (jreg & 3) { switch (jreg & 3) {
case 0: return AST_VIDMEM_SIZE_8M; case 0: vram_size = AST_VIDMEM_SIZE_8M; break;
case 1: return AST_VIDMEM_SIZE_16M; case 1: vram_size = AST_VIDMEM_SIZE_16M; break;
case 2: return AST_VIDMEM_SIZE_32M; case 2: vram_size = AST_VIDMEM_SIZE_32M; break;
case 3: return AST_VIDMEM_SIZE_64M; case 3: vram_size = AST_VIDMEM_SIZE_64M; break;
}
jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
switch (jreg & 0x03) {
case 1:
vram_size -= 0x100000;
break;
case 2:
vram_size -= 0x200000;
break;
case 3:
vram_size -= 0x400000;
break;
} }
return AST_VIDMEM_DEFAULT_SIZE;
return vram_size;
} }
int ast_driver_load(struct drm_device *dev, unsigned long flags) int ast_driver_load(struct drm_device *dev, unsigned long flags)
...@@ -316,6 +388,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -316,6 +388,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
if (ast->chip == AST2100 || if (ast->chip == AST2100 ||
ast->chip == AST2200 || ast->chip == AST2200 ||
ast->chip == AST2300 || ast->chip == AST2300 ||
ast->chip == AST2400 ||
ast->chip == AST1180) { ast->chip == AST1180) {
dev->mode_config.max_width = 1920; dev->mode_config.max_width = 1920;
dev->mode_config.max_height = 2048; dev->mode_config.max_height = 2048;
...@@ -343,6 +416,7 @@ int ast_driver_unload(struct drm_device *dev) ...@@ -343,6 +416,7 @@ int ast_driver_unload(struct drm_device *dev)
{ {
struct ast_private *ast = dev->dev_private; struct ast_private *ast = dev->dev_private;
kfree(ast->dp501_fw_addr);
ast_mode_fini(dev); ast_mode_fini(dev);
ast_fbdev_fini(dev); ast_fbdev_fini(dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
...@@ -411,16 +485,13 @@ static void ast_bo_unref(struct ast_bo **bo) ...@@ -411,16 +485,13 @@ static void ast_bo_unref(struct ast_bo **bo)
tbo = &((*bo)->bo); tbo = &((*bo)->bo);
ttm_bo_unref(&tbo); ttm_bo_unref(&tbo);
if (tbo == NULL) *bo = NULL;
*bo = NULL;
} }
void ast_gem_free_object(struct drm_gem_object *obj) void ast_gem_free_object(struct drm_gem_object *obj)
{ {
struct ast_bo *ast_bo = gem_to_ast_bo(obj); struct ast_bo *ast_bo = gem_to_ast_bo(obj);
if (!ast_bo)
return;
ast_bo_unref(&ast_bo); ast_bo_unref(&ast_bo);
} }
......
...@@ -115,11 +115,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo ...@@ -115,11 +115,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
else else
vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
break; break;
case 1360:
vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
break;
case 1440: case 1440:
vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
break; break;
case 1600: case 1600:
vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; if (crtc->mode.crtc_vdisplay == 900)
vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
else
vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
break; break;
case 1680: case 1680:
vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
...@@ -175,14 +181,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo ...@@ -175,14 +181,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel); if (vbios_mode->enh_table->flags & NewModeInfo) {
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
}
} }
return true; return true;
...@@ -389,7 +398,7 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode ...@@ -389,7 +398,7 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
/* Set Threshold */ /* Set Threshold */
if (ast->chip == AST2300) { if (ast->chip == AST2300 || ast->chip == AST2400) {
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
} else if (ast->chip == AST2100 || } else if (ast->chip == AST2100 ||
...@@ -451,9 +460,13 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -451,9 +460,13 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0); ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0);
if (ast->tx_chip_type == AST_TX_DP501)
ast_set_dp501_video_output(crtc->dev, 1);
ast_crtc_load_lut(crtc); ast_crtc_load_lut(crtc);
break; break;
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
if (ast->tx_chip_type == AST_TX_DP501)
ast_set_dp501_video_output(crtc->dev, 0);
ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
break; break;
} }
...@@ -729,10 +742,24 @@ static int ast_encoder_init(struct drm_device *dev) ...@@ -729,10 +742,24 @@ static int ast_encoder_init(struct drm_device *dev)
static int ast_get_modes(struct drm_connector *connector) static int ast_get_modes(struct drm_connector *connector)
{ {
struct ast_connector *ast_connector = to_ast_connector(connector); struct ast_connector *ast_connector = to_ast_connector(connector);
struct ast_private *ast = connector->dev->dev_private;
struct edid *edid; struct edid *edid;
int ret; int ret;
bool flags = false;
edid = drm_get_edid(connector, &ast_connector->i2c->adapter); if (ast->tx_chip_type == AST_TX_DP501) {
ast->dp501_maxclk = 0xff;
edid = kmalloc(128, GFP_KERNEL);
if (!edid)
return -ENOMEM;
flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
if (flags)
ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
else
kfree(edid);
}
if (!flags)
edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
if (edid) { if (edid) {
drm_mode_connector_update_edid_property(&ast_connector->base, edid); drm_mode_connector_update_edid_property(&ast_connector->base, edid);
ret = drm_add_edid_modes(connector, edid); ret = drm_add_edid_modes(connector, edid);
...@@ -746,7 +773,56 @@ static int ast_get_modes(struct drm_connector *connector) ...@@ -746,7 +773,56 @@ static int ast_get_modes(struct drm_connector *connector)
static int ast_mode_valid(struct drm_connector *connector, static int ast_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
return MODE_OK; struct ast_private *ast = connector->dev->dev_private;
int flags = MODE_NOMODE;
uint32_t jtemp;
if (ast->support_wide_screen) {
if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
return MODE_OK;
if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
return MODE_OK;
if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
return MODE_OK;
if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
return MODE_OK;
if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
return MODE_OK;
if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST1180)) {
if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
return MODE_OK;
if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
if (jtemp & 0x01)
return MODE_NOMODE;
else
return MODE_OK;
}
}
}
switch (mode->hdisplay) {
case 640:
if (mode->vdisplay == 480) flags = MODE_OK;
break;
case 800:
if (mode->vdisplay == 600) flags = MODE_OK;
break;
case 1024:
if (mode->vdisplay == 768) flags = MODE_OK;
break;
case 1280:
if (mode->vdisplay == 1024) flags = MODE_OK;
break;
case 1600:
if (mode->vdisplay == 1200) flags = MODE_OK;
break;
default:
return flags;
}
return flags;
} }
static void ast_connector_destroy(struct drm_connector *connector) static void ast_connector_destroy(struct drm_connector *connector)
......
This diff is collapsed.
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#define HBorder 0x00000020 #define HBorder 0x00000020
#define VBorder 0x00000010 #define VBorder 0x00000010
#define WideScreenMode 0x00000100 #define WideScreenMode 0x00000100
#define NewModeInfo 0x00000200
/* DCLK Index */ /* DCLK Index */
#define VCLK25_175 0x00 #define VCLK25_175 0x00
...@@ -67,6 +67,11 @@ ...@@ -67,6 +67,11 @@
#define VCLK106_5 0x12 #define VCLK106_5 0x12
#define VCLK146_25 0x13 #define VCLK146_25 0x13
#define VCLK148_5 0x14 #define VCLK148_5 0x14
#define VCLK71 0x15
#define VCLK88_75 0x16
#define VCLK119 0x17
#define VCLK85_5 0x18
#define VCLK97_75 0x19
static struct ast_vbios_dclk_info dclk_table[] = { static struct ast_vbios_dclk_info dclk_table[] = {
{0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */
...@@ -90,6 +95,10 @@ static struct ast_vbios_dclk_info dclk_table[] = { ...@@ -90,6 +95,10 @@ static struct ast_vbios_dclk_info dclk_table[] = {
{0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
{0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
{0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
{0x47, 0x6c, 0x80}, /* 15: VCLK71 */
{0x25, 0x65, 0x80}, /* 16: VCLK88.75 */
{0x77, 0x58, 0x80}, /* 17: VCLK119 */
{0x32, 0x67, 0x80}, /* 18: VCLK85_5 */
}; };
static struct ast_vbios_stdtable vbios_stdtable[] = { static struct ast_vbios_stdtable vbios_stdtable[] = {
...@@ -225,41 +234,63 @@ static struct ast_vbios_enhtable res_1600x1200[] = { ...@@ -225,41 +234,63 @@ static struct ast_vbios_enhtable res_1600x1200[] = {
(SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, (SyncPP | Charx8Dot), 0xFF, 1, 0x33 },
}; };
static struct ast_vbios_enhtable res_1920x1200[] = { /* 16:9 */
{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ static struct ast_vbios_enhtable res_1360x768[] = {
(SyncNP | Charx8Dot), 60, 1, 0x34 }, {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */
{2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
(SyncNP | Charx8Dot), 0xFF, 1, 0x34 }, {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* end */
(SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 },
};
static struct ast_vbios_enhtable res_1600x900[] = {
{1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A },
{1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* end */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x3A }
}; };
static struct ast_vbios_enhtable res_1920x1080[] = {
{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 },
{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 },
};
/* 16:10 */ /* 16:10 */
static struct ast_vbios_enhtable res_1280x800[] = { static struct ast_vbios_enhtable res_1280x800[] = {
{1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 35 },
{1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x35 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 },
{1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x35 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x35 },
}; };
static struct ast_vbios_enhtable res_1440x900[] = { static struct ast_vbios_enhtable res_1440x900[] = {
{1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
{1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x36 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
{1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x36 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x36 },
}; };
static struct ast_vbios_enhtable res_1680x1050[] = { static struct ast_vbios_enhtable res_1680x1050[] = {
{1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
{2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x37 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
{2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
(SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x37 }, (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x37 },
}; };
/* HDTV */ static struct ast_vbios_enhtable res_1920x1200[] = {
static struct ast_vbios_enhtable res_1920x1080[] = { {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 },
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x38 }, {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
{2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 },
(SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x38 },
}; };
#endif #endif
...@@ -434,17 +434,13 @@ static void bochs_bo_unref(struct bochs_bo **bo) ...@@ -434,17 +434,13 @@ static void bochs_bo_unref(struct bochs_bo **bo)
tbo = &((*bo)->bo); tbo = &((*bo)->bo);
ttm_bo_unref(&tbo); ttm_bo_unref(&tbo);
if (tbo == NULL) *bo = NULL;
*bo = NULL;
} }
void bochs_gem_free_object(struct drm_gem_object *obj) void bochs_gem_free_object(struct drm_gem_object *obj)
{ {
struct bochs_bo *bochs_bo = gem_to_bochs_bo(obj); struct bochs_bo *bochs_bo = gem_to_bochs_bo(obj);
if (!bochs_bo)
return;
bochs_bo_unref(&bochs_bo); bochs_bo_unref(&bochs_bo);
} }
......
...@@ -225,12 +225,6 @@ int ptn3460_get_modes(struct drm_connector *connector) ...@@ -225,12 +225,6 @@ int ptn3460_get_modes(struct drm_connector *connector)
return num_modes; return num_modes;
} }
static int ptn3460_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
{ {
struct ptn3460_bridge *ptn_bridge; struct ptn3460_bridge *ptn_bridge;
...@@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) ...@@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
.get_modes = ptn3460_get_modes, .get_modes = ptn3460_get_modes,
.mode_valid = ptn3460_mode_valid,
.best_encoder = ptn3460_best_encoder, .best_encoder = ptn3460_best_encoder,
}; };
......
...@@ -264,17 +264,13 @@ static void cirrus_bo_unref(struct cirrus_bo **bo) ...@@ -264,17 +264,13 @@ static void cirrus_bo_unref(struct cirrus_bo **bo)
tbo = &((*bo)->bo); tbo = &((*bo)->bo);
ttm_bo_unref(&tbo); ttm_bo_unref(&tbo);
if (tbo == NULL) *bo = NULL;
*bo = NULL;
} }
void cirrus_gem_free_object(struct drm_gem_object *obj) void cirrus_gem_free_object(struct drm_gem_object *obj)
{ {
struct cirrus_bo *cirrus_bo = gem_to_cirrus_bo(obj); struct cirrus_bo *cirrus_bo = gem_to_cirrus_bo(obj);
if (!cirrus_bo)
return;
cirrus_bo_unref(&cirrus_bo); cirrus_bo_unref(&cirrus_bo);
} }
......
...@@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) ...@@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector)
return count; return count;
} }
static int cirrus_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
/* Any mode we've added is valid */
return MODE_OK;
}
static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
*connector) *connector)
{ {
...@@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector) ...@@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector)
struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = { struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = {
.get_modes = cirrus_vga_get_modes, .get_modes = cirrus_vga_get_modes,
.mode_valid = cirrus_vga_mode_valid,
.best_encoder = cirrus_connector_best_encoder, .best_encoder = cirrus_connector_best_encoder,
}; };
......
...@@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, ...@@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
list->master = dev->primary->master; list->master = dev->primary->master;
*maplist = list; *maplist = list;
return 0; return 0;
} }
int drm_addmap(struct drm_device * dev, resource_size_t offset, int drm_addmap(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type, unsigned int size, enum drm_map_type type,
...@@ -656,13 +656,13 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) ...@@ -656,13 +656,13 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request)
DRM_DEBUG("zone invalid\n"); DRM_DEBUG("zone invalid\n");
return -EINVAL; return -EINVAL;
} }
spin_lock(&dev->count_lock); spin_lock(&dev->buf_lock);
if (dev->buf_use) { if (dev->buf_use) {
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
return -EBUSY; return -EBUSY;
} }
atomic_inc(&dev->buf_alloc); atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order]; entry = &dma->bufs[order];
...@@ -805,13 +805,13 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) ...@@ -805,13 +805,13 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order; total = PAGE_SIZE << page_order;
spin_lock(&dev->count_lock); spin_lock(&dev->buf_lock);
if (dev->buf_use) { if (dev->buf_use) {
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
return -EBUSY; return -EBUSY;
} }
atomic_inc(&dev->buf_alloc); atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order]; entry = &dma->bufs[order];
...@@ -1015,13 +1015,13 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request ...@@ -1015,13 +1015,13 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return -EINVAL; return -EINVAL;
spin_lock(&dev->count_lock); spin_lock(&dev->buf_lock);
if (dev->buf_use) { if (dev->buf_use) {
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
return -EBUSY; return -EBUSY;
} }
atomic_inc(&dev->buf_alloc); atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order]; entry = &dma->bufs[order];
...@@ -1175,7 +1175,7 @@ int drm_addbufs(struct drm_device *dev, void *data, ...@@ -1175,7 +1175,7 @@ int drm_addbufs(struct drm_device *dev, void *data,
* \param arg pointer to a drm_buf_info structure. * \param arg pointer to a drm_buf_info structure.
* \return zero on success or a negative number on failure. * \return zero on success or a negative number on failure.
* *
* Increments drm_device::buf_use while holding the drm_device::count_lock * Increments drm_device::buf_use while holding the drm_device::buf_lock
* lock, preventing of allocating more buffers after this call. Information * lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space. * about each requested buffer is then copied into user space.
*/ */
...@@ -1196,13 +1196,13 @@ int drm_infobufs(struct drm_device *dev, void *data, ...@@ -1196,13 +1196,13 @@ int drm_infobufs(struct drm_device *dev, void *data,
if (!dma) if (!dma)
return -EINVAL; return -EINVAL;
spin_lock(&dev->count_lock); spin_lock(&dev->buf_lock);
if (atomic_read(&dev->buf_alloc)) { if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
return -EBUSY; return -EBUSY;
} }
++dev->buf_use; /* Can't allocate more after this call */ ++dev->buf_use; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
if (dma->bufs[i].buf_count) if (dma->bufs[i].buf_count)
...@@ -1381,13 +1381,13 @@ int drm_mapbufs(struct drm_device *dev, void *data, ...@@ -1381,13 +1381,13 @@ int drm_mapbufs(struct drm_device *dev, void *data,
if (!dma) if (!dma)
return -EINVAL; return -EINVAL;
spin_lock(&dev->count_lock); spin_lock(&dev->buf_lock);
if (atomic_read(&dev->buf_alloc)) { if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
return -EBUSY; return -EBUSY;
} }
dev->buf_use++; /* Can't allocate more after this call */ dev->buf_use++; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock); spin_unlock(&dev->buf_lock);
if (request->count >= dma->buf_count) { if (request->count >= dma->buf_count) {
if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP)) if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP))
......
...@@ -131,14 +131,14 @@ drm_clflush_sg(struct sg_table *st) ...@@ -131,14 +131,14 @@ drm_clflush_sg(struct sg_table *st)
EXPORT_SYMBOL(drm_clflush_sg); EXPORT_SYMBOL(drm_clflush_sg);
void void
drm_clflush_virt_range(char *addr, unsigned long length) drm_clflush_virt_range(void *addr, unsigned long length)
{ {
#if defined(CONFIG_X86) #if defined(CONFIG_X86)
if (cpu_has_clflush) { if (cpu_has_clflush) {
char *end = addr + length; void *end = addr + length;
mb(); mb();
for (; addr < end; addr += boot_cpu_data.x86_clflush_size) for (; addr < end; addr += boot_cpu_data.x86_clflush_size)
clflush(addr); clflushopt(addr);
clflushopt(end - 1); clflushopt(end - 1);
mb(); mb();
return; return;
......
This diff is collapsed.
This diff is collapsed.
...@@ -206,13 +206,17 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) ...@@ -206,13 +206,17 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
* i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
* @adapter: i2c adapter to register * @adapter: i2c adapter to register
* *
* This registers an i2c adapater that uses dp aux channel as it's underlaying * This registers an i2c adapter that uses dp aux channel as it's underlaying
* transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
* and store it in the algo_data member of the @adapter argument. This will be * and store it in the algo_data member of the @adapter argument. This will be
* used by the i2c over dp aux algorithm to drive the hardware. * used by the i2c over dp aux algorithm to drive the hardware.
* *
* RETURNS: * RETURNS:
* 0 on success, -ERRNO on failure. * 0 on success, -ERRNO on failure.
*
* IMPORTANT:
* This interface is deprecated, please switch to the new dp aux helpers and
* drm_dp_aux_register().
*/ */
int int
i2c_dp_aux_add_bus(struct i2c_adapter *adapter) i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
...@@ -378,7 +382,10 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request, ...@@ -378,7 +382,10 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
* transactions. * transactions.
*/ */
for (retry = 0; retry < 7; retry++) { for (retry = 0; retry < 7; retry++) {
mutex_lock(&aux->hw_mutex);
err = aux->transfer(aux, &msg); err = aux->transfer(aux, &msg);
mutex_unlock(&aux->hw_mutex);
if (err < 0) { if (err < 0) {
if (err == -EBUSY) if (err == -EBUSY)
continue; continue;
...@@ -592,7 +599,9 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) ...@@ -592,7 +599,9 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
* before giving up the AUX transaction. * before giving up the AUX transaction.
*/ */
for (retry = 0; retry < 7; retry++) { for (retry = 0; retry < 7; retry++) {
mutex_lock(&aux->hw_mutex);
err = aux->transfer(aux, msg); err = aux->transfer(aux, msg);
mutex_unlock(&aux->hw_mutex);
if (err < 0) { if (err < 0) {
if (err == -EBUSY) if (err == -EBUSY)
continue; continue;
...@@ -725,13 +734,15 @@ static const struct i2c_algorithm drm_dp_i2c_algo = { ...@@ -725,13 +734,15 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
}; };
/** /**
* drm_dp_aux_register_i2c_bus() - register an I2C adapter for I2C-over-AUX * drm_dp_aux_register() - initialise and register aux channel
* @aux: DisplayPort AUX channel * @aux: DisplayPort AUX channel
* *
* Returns 0 on success or a negative error code on failure. * Returns 0 on success or a negative error code on failure.
*/ */
int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux) int drm_dp_aux_register(struct drm_dp_aux *aux)
{ {
mutex_init(&aux->hw_mutex);
aux->ddc.algo = &drm_dp_i2c_algo; aux->ddc.algo = &drm_dp_i2c_algo;
aux->ddc.algo_data = aux; aux->ddc.algo_data = aux;
aux->ddc.retries = 3; aux->ddc.retries = 3;
...@@ -746,14 +757,14 @@ int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux) ...@@ -746,14 +757,14 @@ int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux)
return i2c_add_adapter(&aux->ddc); return i2c_add_adapter(&aux->ddc);
} }
EXPORT_SYMBOL(drm_dp_aux_register_i2c_bus); EXPORT_SYMBOL(drm_dp_aux_register);
/** /**
* drm_dp_aux_unregister_i2c_bus() - unregister an I2C-over-AUX adapter * drm_dp_aux_unregister() - unregister an AUX adapter
* @aux: DisplayPort AUX channel * @aux: DisplayPort AUX channel
*/ */
void drm_dp_aux_unregister_i2c_bus(struct drm_dp_aux *aux) void drm_dp_aux_unregister(struct drm_dp_aux *aux)
{ {
i2c_del_adapter(&aux->ddc); i2c_del_adapter(&aux->ddc);
} }
EXPORT_SYMBOL(drm_dp_aux_unregister_i2c_bus); EXPORT_SYMBOL(drm_dp_aux_unregister);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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