aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/gma500
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-06-23 20:20:51 +0000
committerNicholas Bellinger <nab@linux-iscsi.org>2011-06-23 20:20:51 +0000
commit74d83b7eedab14e4b963a2220ff76f98fa6d4cb8 (patch)
treeff4b10ebd9cf1a057c4b1a703732858a539faff7 /drivers/staging/gma500
parent[SCSI] target: Convert TASK_ATTR to scsi_tcq.h definitions (diff)
parentLinux 3.0-rc4 (diff)
downloadlinux-dev-74d83b7eedab14e4b963a2220ff76f98fa6d4cb8.tar.xz
linux-dev-74d83b7eedab14e4b963a2220ff76f98fa6d4cb8.zip
Merge tag 'v3.0-rc4' of /pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'drivers/staging/gma500')
-rw-r--r--drivers/staging/gma500/Makefile15
-rw-r--r--drivers/staging/gma500/mrst.h217
-rw-r--r--drivers/staging/gma500/mrst_crtc.c619
-rw-r--r--drivers/staging/gma500/mrst_lvds.c371
-rw-r--r--drivers/staging/gma500/psb_2d.c9
-rw-r--r--drivers/staging/gma500/psb_bl.c118
-rw-r--r--drivers/staging/gma500/psb_buffer.c450
-rw-r--r--drivers/staging/gma500/psb_drm.h122
-rw-r--r--drivers/staging/gma500/psb_drv.c780
-rw-r--r--drivers/staging/gma500/psb_drv.h462
-rw-r--r--drivers/staging/gma500/psb_fb.c375
-rw-r--r--drivers/staging/gma500/psb_fb.h16
-rw-r--r--drivers/staging/gma500/psb_fence.c122
-rw-r--r--drivers/staging/gma500/psb_gem.c320
-rw-r--r--drivers/staging/gma500/psb_gtt.c1263
-rw-r--r--drivers/staging/gma500/psb_gtt.h84
-rw-r--r--drivers/staging/gma500/psb_intel_bios.c13
-rw-r--r--drivers/staging/gma500/psb_intel_display.c147
-rw-r--r--drivers/staging/gma500/psb_intel_drv.h13
-rw-r--r--drivers/staging/gma500/psb_intel_lvds.c50
-rw-r--r--drivers/staging/gma500/psb_intel_sdvo.c4
-rw-r--r--drivers/staging/gma500/psb_irq.c178
-rw-r--r--drivers/staging/gma500/psb_lid.c (renamed from drivers/staging/gma500/psb_reset.c)0
-rw-r--r--drivers/staging/gma500/psb_mmu.c61
-rw-r--r--drivers/staging/gma500/psb_powermgmt.c755
-rw-r--r--drivers/staging/gma500/psb_powermgmt.h55
-rw-r--r--drivers/staging/gma500/psb_pvr_glue.c73
-rw-r--r--drivers/staging/gma500/psb_pvr_glue.h25
-rw-r--r--drivers/staging/gma500/psb_sgx.c238
-rw-r--r--drivers/staging/gma500/psb_sgx.h32
-rw-r--r--drivers/staging/gma500/psb_ttm_fence.c605
-rw-r--r--drivers/staging/gma500/psb_ttm_fence_api.h272
-rw-r--r--drivers/staging/gma500/psb_ttm_fence_driver.h302
-rw-r--r--drivers/staging/gma500/psb_ttm_fence_user.c237
-rw-r--r--drivers/staging/gma500/psb_ttm_fence_user.h140
-rw-r--r--drivers/staging/gma500/psb_ttm_glue.c349
-rw-r--r--drivers/staging/gma500/psb_ttm_placement_user.c628
-rw-r--r--drivers/staging/gma500/psb_ttm_placement_user.h252
-rw-r--r--drivers/staging/gma500/psb_ttm_userobj_api.h85
39 files changed, 2996 insertions, 6861 deletions
diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index a52ba48be518..db73ec6d8128 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -5,6 +5,7 @@ ccflags-y += -Iinclude/drm
psb_gfx-y += psb_bl.o \
psb_drv.o \
+ psb_gem.o \
psb_fb.o \
psb_2d.o \
psb_gtt.o \
@@ -15,17 +16,11 @@ psb_gfx-y += psb_bl.o \
psb_intel_lvds.o \
psb_intel_modes.o \
psb_intel_sdvo.o \
- psb_reset.o \
- psb_sgx.o \
- psb_pvr_glue.o \
- psb_buffer.o \
- psb_fence.o \
+ psb_lid.o \
psb_mmu.o \
- psb_ttm_glue.o \
- psb_ttm_fence.o \
- psb_ttm_fence_user.o \
- psb_ttm_placement_user.o \
psb_powermgmt.o \
- psb_irq.o
+ psb_irq.o \
+ mrst_crtc.o \
+ mrst_lvds.o
obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h
new file mode 100644
index 000000000000..5e4aaeb3711b
--- /dev/null
+++ b/drivers/staging/gma500/mrst.h
@@ -0,0 +1,217 @@
+/**************************************************************************
+ * Copyright (c) 2007-2011, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+/* MID device specific descriptors */
+
+struct mrst_vbt {
+ s8 signature[4]; /*4 bytes,"$GCT" */
+ u8 revision;
+ u8 size;
+ u8 checksum;
+ void *mrst_gct;
+} __attribute__ ((packed));
+
+struct mrst_timing_info {
+ u16 pixel_clock;
+ u8 hactive_lo;
+ u8 hblank_lo;
+ u8 hblank_hi:4;
+ u8 hactive_hi:4;
+ u8 vactive_lo;
+ u8 vblank_lo;
+ u8 vblank_hi:4;
+ u8 vactive_hi:4;
+ u8 hsync_offset_lo;
+ u8 hsync_pulse_width_lo;
+ u8 vsync_pulse_width_lo:4;
+ u8 vsync_offset_lo:4;
+ u8 vsync_pulse_width_hi:2;
+ u8 vsync_offset_hi:2;
+ u8 hsync_pulse_width_hi:2;
+ u8 hsync_offset_hi:2;
+ u8 width_mm_lo;
+ u8 height_mm_lo;
+ u8 height_mm_hi:4;
+ u8 width_mm_hi:4;
+ u8 hborder;
+ u8 vborder;
+ u8 unknown0:1;
+ u8 hsync_positive:1;
+ u8 vsync_positive:1;
+ u8 separate_sync:2;
+ u8 stereo:1;
+ u8 unknown6:1;
+ u8 interlaced:1;
+} __attribute__((packed));
+
+struct gct_r10_timing_info {
+ u16 pixel_clock;
+ u32 hactive_lo:8;
+ u32 hactive_hi:4;
+ u32 hblank_lo:8;
+ u32 hblank_hi:4;
+ u32 hsync_offset_lo:8;
+ u16 hsync_offset_hi:2;
+ u16 hsync_pulse_width_lo:8;
+ u16 hsync_pulse_width_hi:2;
+ u16 hsync_positive:1;
+ u16 rsvd_1:3;
+ u8 vactive_lo:8;
+ u16 vactive_hi:4;
+ u16 vblank_lo:8;
+ u16 vblank_hi:4;
+ u16 vsync_offset_lo:4;
+ u16 vsync_offset_hi:2;
+ u16 vsync_pulse_width_lo:4;
+ u16 vsync_pulse_width_hi:2;
+ u16 vsync_positive:1;
+ u16 rsvd_2:3;
+} __attribute__((packed));
+
+struct mrst_panel_descriptor_v1 {
+ u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
+ /* 0x61190 if MIPI */
+ u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
+ u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+ u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
+ /* Register 0x61210 */
+ struct mrst_timing_info DTD;/*18 bytes, Standard definition */
+ u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
+ /* Bit 0, Frequency, 15 bits,0 - 32767Hz */
+ /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
+ u16 Panel_MIPI_Display_Descriptor;
+ /*16 bits, Defined as follows: */
+ /* if MIPI, 0x0000 if LVDS */
+ /* Bit 0, Type, 2 bits, */
+ /* 0: Type-1, */
+ /* 1: Type-2, */
+ /* 2: Type-3, */
+ /* 3: Type-4 */
+ /* Bit 2, Pixel Format, 4 bits */
+ /* Bit0: 16bpp (not supported in LNC), */
+ /* Bit1: 18bpp loosely packed, */
+ /* Bit2: 18bpp packed, */
+ /* Bit3: 24bpp */
+ /* Bit 6, Reserved, 2 bits, 00b */
+ /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
+ /* Bit 14, Reserved, 2 bits, 00b */
+} __attribute__ ((packed));
+
+struct mrst_panel_descriptor_v2 {
+ u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
+ /* 0x61190 if MIPI */
+ u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
+ u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+ u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
+ /* Register 0x61210 */
+ struct mrst_timing_info DTD;/*18 bytes, Standard definition */
+ u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
+ /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
+ u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */
+ /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
+ u16 Panel_MIPI_Display_Descriptor;
+ /*16 bits, Defined as follows: */
+ /* if MIPI, 0x0000 if LVDS */
+ /* Bit 0, Type, 2 bits, */
+ /* 0: Type-1, */
+ /* 1: Type-2, */
+ /* 2: Type-3, */
+ /* 3: Type-4 */
+ /* Bit 2, Pixel Format, 4 bits */
+ /* Bit0: 16bpp (not supported in LNC), */
+ /* Bit1: 18bpp loosely packed, */
+ /* Bit2: 18bpp packed, */
+ /* Bit3: 24bpp */
+ /* Bit 6, Reserved, 2 bits, 00b */
+ /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
+ /* Bit 14, Reserved, 2 bits, 00b */
+} __attribute__ ((packed));
+
+union mrst_panel_rx {
+ struct{
+ u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
+ /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
+ u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
+ /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
+ u16 SupportedVideoTransferMode:2; /*0: Non-burst only */
+ /* 1: Burst and non-burst */
+ /* 2/3: Reserved */
+ u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
+ u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
+ u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
+ u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
+ u16 Rsvd:5;/*5 bits,00000b */
+ } panelrx;
+ u16 panel_receiver;
+} __attribute__ ((packed));
+
+struct mrst_gct_v1 {
+ union{ /*8 bits,Defined as follows: */
+ struct {
+ u8 PanelType:4; /*4 bits, Bit field for panels*/
+ /* 0 - 3: 0 = LVDS, 1 = MIPI*/
+ /*2 bits,Specifies which of the*/
+ u8 BootPanelIndex:2;
+ /* 4 panels to use by default*/
+ u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
+ /* the 4 MIPI DSI receivers to use*/
+ } PD;
+ u8 PanelDescriptor;
+ };
+ struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
+ union mrst_panel_rx panelrx[4]; /* panel receivers*/
+} __attribute__ ((packed));
+
+struct mrst_gct_v2 {
+ union{ /*8 bits,Defined as follows: */
+ struct {
+ u8 PanelType:4; /*4 bits, Bit field for panels*/
+ /* 0 - 3: 0 = LVDS, 1 = MIPI*/
+ /*2 bits,Specifies which of the*/
+ u8 BootPanelIndex:2;
+ /* 4 panels to use by default*/
+ u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
+ /* the 4 MIPI DSI receivers to use*/
+ } PD;
+ u8 PanelDescriptor;
+ };
+ struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
+ union mrst_panel_rx panelrx[4]; /* panel receivers*/
+} __attribute__ ((packed));
+
+struct mrst_gct_data {
+ u8 bpi; /* boot panel index, number of panel used during boot */
+ u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
+ struct mrst_timing_info DTD; /* timing info for the selected panel */
+ u32 Panel_Port_Control;
+ u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/
+ u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+ u32 PP_Cycle_Delay;
+ u16 Panel_Backlight_Inverter_Descriptor;
+ u16 Panel_MIPI_Display_Descriptor;
+} __attribute__ ((packed));
+
+#define MODE_SETTING_IN_CRTC 0x1
+#define MODE_SETTING_IN_ENCODER 0x2
+#define MODE_SETTING_ON_GOING 0x3
+#define MODE_SETTING_IN_DSR 0x4
+#define MODE_SETTING_ENCODER_DONE 0x8
+#define GCT_R10_HEADER_SIZE 16
+#define GCT_R10_DISPLAY_DESC_SIZE 28
+
diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
new file mode 100644
index 000000000000..e4a0c033b5b2
--- /dev/null
+++ b/drivers/staging/gma500/mrst_crtc.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+
+#include <drm/drmP.h>
+#include "psb_fb.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_display.h"
+#include "psb_powermgmt.h"
+
+struct psb_intel_range_t {
+ int min, max;
+};
+
+struct mrst_limit_t {
+ struct psb_intel_range_t dot, m, p1;
+};
+
+struct mrst_clock_t {
+ /* derived values */
+ int dot;
+ int m;
+ int p1;
+};
+
+#define MRST_LIMIT_LVDS_100L 0
+#define MRST_LIMIT_LVDS_83 1
+#define MRST_LIMIT_LVDS_100 2
+
+#define MRST_DOT_MIN 19750
+#define MRST_DOT_MAX 120000
+#define MRST_M_MIN_100L 20
+#define MRST_M_MIN_100 10
+#define MRST_M_MIN_83 12
+#define MRST_M_MAX_100L 34
+#define MRST_M_MAX_100 17
+#define MRST_M_MAX_83 20
+#define MRST_P1_MIN 2
+#define MRST_P1_MAX_0 7
+#define MRST_P1_MAX_1 8
+
+static const struct mrst_limit_t mrst_limits[] = {
+ { /* MRST_LIMIT_LVDS_100L */
+ .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+ .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
+ .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
+ },
+ { /* MRST_LIMIT_LVDS_83L */
+ .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+ .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
+ .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
+ },
+ { /* MRST_LIMIT_LVDS_100 */
+ .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+ .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
+ .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
+ },
+};
+
+#define MRST_M_MIN 10
+static const u32 mrst_m_converts[] = {
+ 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
+ 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
+ 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
+};
+
+static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
+{
+ const struct mrst_limit_t *limit = NULL;
+ struct drm_device *dev = crtc->dev;
+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+
+ if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
+ || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
+ switch (dev_priv->core_freq) {
+ case 100:
+ limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
+ break;
+ case 166:
+ limit = &mrst_limits[MRST_LIMIT_LVDS_83];
+ break;
+ case 200:
+ limit = &mrst_limits[MRST_LIMIT_LVDS_100];
+ break;
+ }
+ } else {
+ limit = NULL;
+ PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n");
+ }
+
+ return limit;
+}
+
+/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
+static void mrst_clock(int refclk, struct mrst_clock_t *clock)
+{
+ clock->dot = (refclk * clock->m) / (14 * clock->p1);
+}
+
+void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
+{
+ PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n",
+ prefix, clock->dot, clock->m, clock->p1);
+}
+
+/**
+ * Returns a set of divisors for the desired target clock with the given refclk,
+ * or FALSE. Divisor values are the actual divisors for
+ */
+static bool
+mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
+ struct mrst_clock_t *best_clock)
+{
+ struct mrst_clock_t clock;
+ const struct mrst_limit_t *limit = mrst_limit(crtc);
+ int err = target;
+
+ memset(best_clock, 0, sizeof(*best_clock));
+
+ for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
+ for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
+ clock.p1++) {
+ int this_err;
+
+ mrst_clock(refclk, &clock);
+
+ this_err = abs(clock.dot - target);
+ if (this_err < err) {
+ *best_clock = clock;
+ err = this_err;
+ }
+ }
+ }
+ DRM_DEBUG("mrstFindBestPLL err = %d.\n", err);
+
+ return err != target;
+}
+
+/**
+ * Sets the power management mode of the pipe and plane.
+ *
+ * This code should probably grow support for turning the cursor off and back
+ * on appropriately at the same time as we're turning the pipe off/on.
+ */
+static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+ struct drm_device *dev = crtc->dev;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+ int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE;
+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+ u32 temp;
+ bool enabled;
+
+ PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe);
+
+ if (!gma_power_begin(dev, true))
+ return;
+
+ /* XXX: When our outputs are all unaware of DPMS modes other than off
+ * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+ */
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ /* Enable the DPLL */
+ temp = REG_READ(dpll_reg);
+ if ((temp & DPLL_VCO_ENABLE) == 0) {
+ REG_WRITE(dpll_reg, temp);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+ }
+ /* Enable the pipe */
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) == 0)
+ REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
+ /* Enable the plane */
+ temp = REG_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+ REG_WRITE(dspcntr_reg,
+ temp | DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ }
+
+ psb_intel_crtc_load_lut(crtc);
+
+ /* Give the overlay scaler a chance to enable
+ if it's on this pipe */
+ /* psb_intel_crtc_dpms_video(crtc, true); TODO */
+ break;
+ case DRM_MODE_DPMS_OFF:
+ /* Give the overlay scaler a chance to disable
+ * if it's on this pipe */
+ /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
+
+ /* Disable the VGA plane that we never use */
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+ /* Disable display plane */
+ temp = REG_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+ REG_WRITE(dspcntr_reg,
+ temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ REG_READ(dspbase_reg);
+ }
+
+ /* Next, disable display pipes */
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+ REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+ REG_READ(pipeconf_reg);
+ }
+ /* Wait for for the pipe disable to take effect. */
+ psb_intel_wait_for_vblank(dev);
+
+ temp = REG_READ(dpll_reg);
+ if ((temp & DPLL_VCO_ENABLE) != 0) {
+ REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+ REG_READ(dpll_reg);
+ }
+
+ /* Wait for the clocks to turn off. */
+ udelay(150);
+ break;
+ }
+
+ enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
+
+ /*Set FIFO Watermarks*/
+ REG_WRITE(DSPARB, 0x3FFF);
+ REG_WRITE(DSPFW1, 0x3F88080A);
+ REG_WRITE(DSPFW2, 0x0b060808);
+ REG_WRITE(DSPFW3, 0x0);
+ REG_WRITE(DSPFW4, 0x08030404);
+ REG_WRITE(DSPFW5, 0x04040404);
+ REG_WRITE(DSPFW6, 0x78);
+ REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
+ /* Must write Bit 14 of the Chicken Bit Register */
+
+ gma_power_end(dev);
+}
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int mrst_panel_fitter_pipe(struct drm_device *dev)
+{
+ u32 pfit_control;
+
+ pfit_control = REG_READ(PFIT_CONTROL);
+
+ /* See if the panel fitter is in use */
+ if ((pfit_control & PFIT_ENABLE) == 0)
+ return -1;
+ return (pfit_control >> 29) & 3;
+}
+
+static int mrst_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct drm_device *dev = crtc->dev;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+ int pipe = psb_intel_crtc->pipe;
+ int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
+ int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+ int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
+ int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
+ int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
+ int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
+ int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
+ int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
+ int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+ int refclk = 0;
+ struct mrst_clock_t clock;
+ u32 dpll = 0, fp = 0, dspcntr, pipeconf;
+ bool ok, is_sdvo = false;
+ bool is_crt = false, is_lvds = false, is_tv = false;
+ bool is_mipi = false;
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct psb_intel_output *psb_intel_output = NULL;
+ uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
+ struct drm_encoder *encoder;
+
+ PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
+
+ if (!gma_power_begin(dev, true))
+ return 0;
+
+ memcpy(&psb_intel_crtc->saved_mode,
+ mode,
+ sizeof(struct drm_display_mode));
+ memcpy(&psb_intel_crtc->saved_adjusted_mode,
+ adjusted_mode,
+ sizeof(struct drm_display_mode));
+
+ list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+
+ if (encoder->crtc != crtc)
+ continue;
+
+ psb_intel_output = enc_to_psb_intel_output(encoder);
+ switch (psb_intel_output->type) {
+ case INTEL_OUTPUT_LVDS:
+ is_lvds = true;
+ break;
+ case INTEL_OUTPUT_SDVO:
+ is_sdvo = true;
+ break;
+ case INTEL_OUTPUT_TVOUT:
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_ANALOG:
+ is_crt = true;
+ break;
+ case INTEL_OUTPUT_MIPI:
+ is_mipi = true;
+ break;
+ }
+ }
+
+ /* Disable the VGA plane that we never use */
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+ /* Disable the panel fitter if it was on our pipe */
+ if (mrst_panel_fitter_pipe(dev) == pipe)
+ REG_WRITE(PFIT_CONTROL, 0);
+
+ REG_WRITE(pipesrc_reg,
+ ((mode->crtc_hdisplay - 1) << 16) |
+ (mode->crtc_vdisplay - 1));
+
+ if (psb_intel_output)
+ drm_connector_property_get_value(&psb_intel_output->base,
+ dev->mode_config.scaling_mode_property, &scalingType);
+
+ if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
+ /* Moorestown doesn't have register support for centering so
+ * we need to mess with the h/vblank and h/vsync start and
+ * ends to get centering */
+ int offsetX = 0, offsetY = 0;
+
+ offsetX = (adjusted_mode->crtc_hdisplay -
+ mode->crtc_hdisplay) / 2;
+ offsetY = (adjusted_mode->crtc_vdisplay -
+ mode->crtc_vdisplay) / 2;
+
+ REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(hblank_reg,
+ (adjusted_mode->crtc_hblank_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
+ REG_WRITE(hsync_reg,
+ (adjusted_mode->crtc_hsync_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
+ REG_WRITE(vblank_reg,
+ (adjusted_mode->crtc_vblank_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
+ REG_WRITE(vsync_reg,
+ (adjusted_mode->crtc_vsync_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
+ } else {
+ REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
+ ((adjusted_mode->crtc_hblank_end - 1) << 16));
+ REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
+ ((adjusted_mode->crtc_hsync_end - 1) << 16));
+ REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
+ ((adjusted_mode->crtc_vblank_end - 1) << 16));
+ REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
+ ((adjusted_mode->crtc_vsync_end - 1) << 16));
+ }
+
+ /* Flush the plane changes */
+ {
+ struct drm_crtc_helper_funcs *crtc_funcs =
+ crtc->helper_private;
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+ }
+
+ /* setup pipeconf */
+ pipeconf = REG_READ(pipeconf_reg);
+
+ /* Set up the display plane register */
+ dspcntr = REG_READ(dspcntr_reg);
+ dspcntr |= DISPPLANE_GAMMA_ENABLE;
+
+ if (pipe == 0)
+ dspcntr |= DISPPLANE_SEL_PIPE_A;
+ else
+ dspcntr |= DISPPLANE_SEL_PIPE_B;
+
+ dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE;
+ dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE;
+
+ if (is_mipi)
+ goto mrst_crtc_mode_set_exit;
+
+ refclk = dev_priv->core_freq * 1000;
+
+ dpll = 0; /*BIT16 = 0 for 100MHz reference */
+
+ ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
+
+ if (!ok) {
+ PSB_DEBUG_ENTRY(
+ "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
+ } else {
+ PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d,"
+ "m = %x, p1 = %x.\n", clock.dot, clock.m,
+ clock.p1);
+ }
+
+ fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8;
+
+ dpll |= DPLL_VGA_MODE_DIS;
+
+
+ dpll |= DPLL_VCO_ENABLE;
+
+ if (is_lvds)
+ dpll |= DPLLA_MODE_LVDS;
+ else
+ dpll |= DPLLB_MODE_DAC_SERIAL;
+
+ if (is_sdvo) {
+ int sdvo_pixel_multiply =
+ adjusted_mode->clock / mode->clock;
+
+ dpll |= DPLL_DVO_HIGH_SPEED;
+ dpll |=
+ (sdvo_pixel_multiply -
+ 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
+ }
+
+
+ /* compute bitmask from p1 value */
+ dpll |= (1 << (clock.p1 - 2)) << 17;
+
+ dpll |= DPLL_VCO_ENABLE;
+
+ mrstPrintPll("chosen", &clock);
+
+ if (dpll & DPLL_VCO_ENABLE) {
+ REG_WRITE(fp_reg, fp);
+ REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+ REG_READ(dpll_reg);
+ /* Check the DPLLA lock bit PIPEACONF[29] */
+ udelay(150);
+ }
+
+ REG_WRITE(fp_reg, fp);
+ REG_WRITE(dpll_reg, dpll);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+
+ /* write it again -- the BIOS does, after all */
+ REG_WRITE(dpll_reg, dpll);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to stabilize. */
+ udelay(150);
+
+ REG_WRITE(pipeconf_reg, pipeconf);
+ REG_READ(pipeconf_reg);
+ psb_intel_wait_for_vblank(dev);
+
+ REG_WRITE(dspcntr_reg, dspcntr);
+ psb_intel_wait_for_vblank(dev);
+
+mrst_crtc_mode_set_exit:
+ gma_power_end(dev);
+ return 0;
+}
+
+static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+int mrst_pipe_set_base(struct drm_crtc *crtc,
+ int x, int y, struct drm_framebuffer *old_fb)
+{
+ struct drm_device *dev = crtc->dev;
+ /* struct drm_i915_master_private *master_priv; */
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
+ int pipe = psb_intel_crtc->pipe;
+ unsigned long start, offset;
+ /* FIXME: check if we need this surely MRST is pipe 0 only */
+ int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
+ int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+ int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+ int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+ u32 dspcntr;
+ int ret = 0;
+
+ PSB_DEBUG_ENTRY("\n");
+
+ /* no fb bound */
+ if (!crtc->fb) {
+ DRM_DEBUG("No FB bound\n");
+ return 0;
+ }
+
+ if (!gma_power_begin(dev, true))
+ return 0;
+
+ start = psbfb->gtt->offset;
+ offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
+ REG_WRITE(dspstride, crtc->fb->pitch);
+
+ dspcntr = REG_READ(dspcntr_reg);
+ dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+
+ switch (crtc->fb->bits_per_pixel) {
+ case 8:
+ dspcntr |= DISPPLANE_8BPP;
+ break;
+ case 16:
+ if (crtc->fb->depth == 15)
+ dspcntr |= DISPPLANE_15_16BPP;
+ else
+ dspcntr |= DISPPLANE_16BPP;
+ break;
+ case 24:
+ case 32:
+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+ break;
+ default:
+ DRM_ERROR("Unknown color depth\n");
+ ret = -EINVAL;
+ goto pipe_set_base_exit;
+ }
+ REG_WRITE(dspcntr_reg, dspcntr);
+
+ DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
+ if (0 /* FIXMEAC - check what PSB needs */) {
+ REG_WRITE(dspbase, offset);
+ REG_READ(dspbase);
+ REG_WRITE(dspsurf, start);
+ REG_READ(dspsurf);
+ } else {
+ REG_WRITE(dspbase, start + offset);
+ REG_READ(dspbase);
+ }
+
+pipe_set_base_exit:
+ gma_power_end(dev);
+ return ret;
+}
+
+static void mrst_crtc_prepare(struct drm_crtc *crtc)
+{
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void mrst_crtc_commit(struct drm_crtc *crtc)
+{
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+const struct drm_crtc_helper_funcs mrst_helper_funcs = {
+ .dpms = mrst_crtc_dpms,
+ .mode_fixup = mrst_crtc_mode_fixup,
+ .mode_set = mrst_crtc_mode_set,
+ .mode_set_base = mrst_pipe_set_base,
+ .prepare = mrst_crtc_prepare,
+ .commit = mrst_crtc_commit,
+};
+
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
new file mode 100644
index 000000000000..4a08b74f5ff9
--- /dev/null
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright © 2006-2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ * Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/i2c.h>
+#include <drm/drmP.h>
+#include <asm/mrst.h>
+
+#include "psb_intel_bios.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+#include <linux/pm_runtime.h>
+
+/* The max/min PWM frequency in BPCR[31:17] - */
+/* The smallest number is 1 (not 0) that can fit in the
+ * 15-bit field of the and then*/
+/* shifts to the left by one bit to get the actual 16-bit
+ * value that the 15-bits correspond to.*/
+#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
+#define BRIGHTNESS_MAX_LEVEL 100
+
+/**
+ * Sets the power state for the panel.
+ */
+static void mrst_lvds_set_power(struct drm_device *dev,
+ struct psb_intel_output *output, bool on)
+{
+ u32 pp_status;
+ DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+ PSB_DEBUG_ENTRY("\n");
+
+ if (!gma_power_begin(dev, true))
+ return;
+
+ if (on) {
+ REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
+ POWER_TARGET_ON);
+ do {
+ pp_status = REG_READ(PP_STATUS);
+ } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
+ dev_priv->is_lvds_on = true;
+ } else {
+ REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
+ ~POWER_TARGET_ON);
+ do {
+ pp_status = REG_READ(PP_STATUS);
+ } while (pp_status & PP_ON);
+ dev_priv->is_lvds_on = false;
+ pm_request_idle(&dev->pdev->dev);
+ }
+
+ gma_power_end(dev);
+}
+
+static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+ PSB_DEBUG_ENTRY("\n");
+
+ if (mode == DRM_MODE_DPMS_ON)
+ mrst_lvds_set_power(dev, output, true);
+ else
+ mrst_lvds_set_power(dev, output, false);
+
+ /* XXX: We never power down the LVDS pairs. */
+}
+
+static void mrst_lvds_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct psb_intel_mode_device *mode_dev =
+ enc_to_psb_intel_output(encoder)->mode_dev;
+ struct drm_device *dev = encoder->dev;
+ u32 lvds_port;
+ uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
+
+ PSB_DEBUG_ENTRY("\n");
+
+ if (!gma_power_begin(dev, true))
+ return;
+
+ /*
+ * The LVDS pin pair will already have been turned on in the
+ * psb_intel_crtc_mode_set since it has a large impact on the DPLL
+ * settings.
+ */
+ lvds_port = (REG_READ(LVDS) &
+ (~LVDS_PIPEB_SELECT)) |
+ LVDS_PORT_EN |
+ LVDS_BORDER_EN;
+
+ if (mode_dev->panel_wants_dither)
+ lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
+
+ REG_WRITE(LVDS, lvds_port);
+
+ drm_connector_property_get_value(
+ &enc_to_psb_intel_output(encoder)->base,
+ dev->mode_config.scaling_mode_property,
+ &v);
+
+ if (v == DRM_MODE_SCALE_NO_SCALE)
+ REG_WRITE(PFIT_CONTROL, 0);
+ else if (v == DRM_MODE_SCALE_ASPECT) {
+ if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
+ (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
+ if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
+ (mode->hdisplay * adjusted_mode->crtc_vdisplay))
+ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+ else if ((adjusted_mode->crtc_hdisplay *
+ mode->vdisplay) > (mode->hdisplay *
+ adjusted_mode->crtc_vdisplay))
+ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
+ PFIT_SCALING_MODE_PILLARBOX);
+ else
+ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
+ PFIT_SCALING_MODE_LETTERBOX);
+ } else
+ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+ } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
+ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+
+ gma_power_end(dev);
+}
+
+
+static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
+ .dpms = mrst_lvds_dpms,
+ .mode_fixup = psb_intel_lvds_mode_fixup,
+ .prepare = psb_intel_lvds_prepare,
+ .mode_set = mrst_lvds_mode_set,
+ .commit = psb_intel_lvds_commit,
+};
+
+static struct drm_display_mode lvds_configuration_modes[] = {
+ /* hard coded fixed mode for TPO LTPS LPJ040K001A */
+ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
+ 846, 1056, 0, 480, 489, 491, 525, 0, 0) },
+ /* hard coded fixed mode for LVDS 800x480 */
+ { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
+ 802, 1024, 0, 480, 481, 482, 525, 0, 0) },
+ /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
+ 1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
+ /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
+ 1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
+ /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
+ { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
+ 1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
+ /* hard coded fixed mode for LVDS 1024x768 */
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+ 1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
+ /* hard coded fixed mode for LVDS 1366x768 */
+ { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
+ 1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
+};
+
+/* Returns the panel fixed mode from configuration. */
+
+static struct drm_display_mode *
+mrst_lvds_get_configuration_mode(struct drm_device *dev)
+{
+ struct drm_display_mode *mode = NULL;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+
+ if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode)
+ return NULL;
+
+ mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+ mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+ mode->hsync_start = mode->hdisplay + \
+ ((ti->hsync_offset_hi << 8) | \
+ ti->hsync_offset_lo);
+ mode->hsync_end = mode->hsync_start + \
+ ((ti->hsync_pulse_width_hi << 8) | \
+ ti->hsync_pulse_width_lo);
+ mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+ ti->hblank_lo);
+ mode->vsync_start = \
+ mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
+ ti->vsync_offset_lo);
+ mode->vsync_end = \
+ mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
+ ti->vsync_pulse_width_lo);
+ mode->vtotal = mode->vdisplay + \
+ ((ti->vblank_hi << 8) | ti->vblank_lo);
+ mode->clock = ti->pixel_clock * 10;
+#if 0
+ printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
+ printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
+ printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
+ printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
+ printk(KERN_INFO "htotal is %d\n", mode->htotal);
+ printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
+ printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
+ printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
+ printk(KERN_INFO "clock is %d\n", mode->clock);
+#endif
+ } else
+ mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
+
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ return mode;
+}
+
+/**
+ * mrst_lvds_init - setup LVDS connectors on this device
+ * @dev: drm device
+ *
+ * Create the connector, register the LVDS DDC bus, and try to figure out what
+ * modes we can display on the LVDS panel (if present).
+ */
+void mrst_lvds_init(struct drm_device *dev,
+ struct psb_intel_mode_device *mode_dev)
+{
+ struct psb_intel_output *psb_intel_output;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+ struct drm_psb_private *dev_priv =
+ (struct drm_psb_private *) dev->dev_private;
+ struct edid *edid;
+ int ret = 0;
+ struct i2c_adapter *i2c_adap;
+ struct drm_display_mode *scan; /* *modes, *bios_mode; */
+
+ PSB_DEBUG_ENTRY("\n");
+
+ psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
+ if (!psb_intel_output)
+ return;
+
+ psb_intel_output->mode_dev = mode_dev;
+ connector = &psb_intel_output->base;
+ encoder = &psb_intel_output->enc;
+ dev_priv->is_lvds_on = true;
+ drm_connector_init(dev, &psb_intel_output->base,
+ &psb_intel_lvds_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+
+ drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
+ DRM_MODE_ENCODER_LVDS);
+
+ drm_mode_connector_attach_encoder(&psb_intel_output->base,
+ &psb_intel_output->enc);
+ psb_intel_output->type = INTEL_OUTPUT_LVDS;
+
+ drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
+ drm_connector_helper_add(connector,
+ &psb_intel_lvds_connector_helper_funcs);
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
+
+ drm_connector_attach_property(connector,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_FULLSCREEN);
+ drm_connector_attach_property(connector,
+ dev_priv->backlight_property,
+ BRIGHTNESS_MAX_LEVEL);
+
+ mode_dev->panel_wants_dither = false;
+ if (dev_priv->vbt_data.size != 0x00)
+ mode_dev->panel_wants_dither = (dev_priv->gct_data.
+ Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
+
+ /*
+ * LVDS discovery:
+ * 1) check for EDID on DDC
+ * 2) check for VBT data
+ * 3) check to see if LVDS is already on
+ * if none of the above, no panel
+ * 4) make sure lid is open
+ * if closed, act like it's not there for now
+ */
+
+ /* This ifdef can go once the cpu ident stuff is cleaned up in arch */
+#if defined(CONFIG_X86_MRST)
+ if (mrst_identify_cpu())
+ i2c_adap = i2c_get_adapter(2);
+ else /* Oaktrail uses I2C 1 */
+#endif
+ i2c_adap = i2c_get_adapter(1);
+
+ if (i2c_adap == NULL)
+ printk(KERN_ALERT "No ddc adapter available!\n");
+ /*
+ * Attempt to get the fixed panel mode from DDC. Assume that the
+ * preferred mode is the right one.
+ */
+ if (i2c_adap) {
+ edid = drm_get_edid(connector, i2c_adap);
+ if (edid) {
+ drm_mode_connector_update_edid_property(connector,
+ edid);
+ ret = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+ }
+
+ list_for_each_entry(scan, &connector->probed_modes, head) {
+ if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+ mode_dev->panel_fixed_mode =
+ drm_mode_duplicate(dev, scan);
+ goto out; /* FIXME: check for quirks */
+ }
+ }
+ }
+
+ /*
+ * If we didn't get EDID, try geting panel timing
+ * from configuration data
+ */
+ mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
+
+ if (mode_dev->panel_fixed_mode) {
+ mode_dev->panel_fixed_mode->type |=
+ DRM_MODE_TYPE_PREFERRED;
+ goto out; /* FIXME: check for quirks */
+ }
+
+ /* If we still don't have a mode after all that, give up. */
+ if (!mode_dev->panel_fixed_mode) {
+ DRM_DEBUG
+ ("Found no modes on the lvds, ignoring the LVDS\n");
+ goto failed_find;
+ }
+
+out:
+ drm_sysfs_connector_add(connector);
+ return;
+
+failed_find:
+ DRM_DEBUG("No LVDS modes found, disabling.\n");
+ if (psb_intel_output->ddc_bus)
+ psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
+
+/* failed_ddc: */
+
+ drm_encoder_cleanup(encoder);
+ drm_connector_cleanup(connector);
+ kfree(connector);
+}
+
diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index e4cae5d77d01..0bd834c982d3 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -40,7 +40,6 @@
#include "psb_reg.h"
#include "psb_drv.h"
#include "psb_fb.h"
-#include "psb_sgx.h"
void psb_spank(struct drm_psb_private *dev_priv)
{
@@ -85,7 +84,7 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
/* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize
it with console use */
-static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
+int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
unsigned size)
{
int ret = 0;
@@ -161,7 +160,7 @@ static void psbfb_fillrect_accel(struct fb_info *info,
if (!fb)
return;
- offset = psbfb->offset;
+ offset = psbfb->gtt->offset;
stride = fb->pitch;
switch (fb->depth) {
@@ -304,7 +303,7 @@ static void psbfb_copyarea_accel(struct fb_info *info,
if (!fb)
return;
- offset = psbfb->offset;
+ offset = psbfb->gtt->offset;
stride = fb->pitch;
switch (fb->depth) {
@@ -344,7 +343,7 @@ void psbfb_copyarea(struct fb_info *info,
if (unlikely(info->state != FBINFO_STATE_RUNNING))
return;
- if (1 || (info->flags & FBINFO_HWACCEL_DISABLED))
+ if (info->flags & FBINFO_HWACCEL_DISABLED)
return cfb_copyarea(info, region);
/* psb_check_power_state(dev, PSB_DEVICE_SGX); */
diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 70c17b352f9f..5dffc71c5125 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c
@@ -33,7 +33,6 @@
#define BLC_PWM_FREQ_CALC_CONSTANT 32
#define MHz 1000000
#define BRIGHTNESS_MIN_LEVEL 1
-#define BRIGHTNESS_MAX_LEVEL 100
#define BRIGHTNESS_MASK 0xFF
#define BLC_POLARITY_NORMAL 0
#define BLC_POLARITY_INVERSE 1
@@ -59,15 +58,57 @@ int psb_set_brightness(struct backlight_device *bd)
DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
- /* Perform value bounds checking */
- if (level < BRIGHTNESS_MIN_LEVEL)
- level = BRIGHTNESS_MIN_LEVEL;
+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
psb_intel_lvds_set_brightness(dev, level);
psb_brightness = level;
return 0;
}
+int mrst_set_brightness(struct backlight_device *bd)
+{
+ struct drm_device *dev = bl_get_data(psb_backlight_device);
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int level = bd->props.brightness;
+ u32 blc_pwm_ctl;
+ u32 max_pwm_blc;
+
+ DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
+
+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
+
+ if (gma_power_begin(dev, 0)) {
+ /* Calculate and set the brightness value */
+ max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
+ blc_pwm_ctl = level * max_pwm_blc / 100;
+
+ /* Adjust the backlight level with the percent in
+ * dev_priv->blc_adj1;
+ */
+ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
+ blc_pwm_ctl = blc_pwm_ctl / 100;
+
+ /* Adjust the backlight level with the percent in
+ * dev_priv->blc_adj2;
+ */
+ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
+ blc_pwm_ctl = blc_pwm_ctl / 100;
+
+ if (blc_pol == BLC_POLARITY_INVERSE)
+ blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl;
+ /* force PWM bit on */
+ REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+ REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
+ gma_power_end(dev);
+ }
+ psb_brightness = level;
+ return 0;
+}
+
int psb_get_brightness(struct backlight_device *bd)
{
DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness);
@@ -85,24 +126,33 @@ static const struct backlight_ops psb_ops = {
static int device_backlight_init(struct drm_device *dev)
{
+ struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long core_clock;
/* u32 bl_max_freq; */
/* unsigned long value; */
u16 bl_max_freq;
uint32_t value;
uint32_t blc_pwm_precision_factor;
- struct drm_psb_private *dev_priv = dev->dev_private;
- /* get bl_max_freq and pol from dev_priv*/
- if (!dev_priv->lvds_bl) {
- DRM_ERROR("Has no valid LVDS backlight info\n");
- return 1;
+ if (IS_MRST(dev)) {
+ dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+ dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
+ bl_max_freq = 256;
+ /* this needs to be set elsewhere */
+ blc_pol = BLC_POLARITY_NORMAL;
+ blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
+ } else {
+ /* get bl_max_freq and pol from dev_priv*/
+ if (!dev_priv->lvds_bl) {
+ DRM_ERROR("Has no valid LVDS backlight info\n");
+ return 1;
+ }
+ bl_max_freq = dev_priv->lvds_bl->freq;
+ blc_pol = dev_priv->lvds_bl->pol;
+ blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
+ blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
+ blc_type = dev_priv->lvds_bl->type;
}
- bl_max_freq = dev_priv->lvds_bl->freq;
- blc_pol = dev_priv->lvds_bl->pol;
- blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
- blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
- blc_type = dev_priv->lvds_bl->type;
core_clock = dev_priv->core_freq;
@@ -111,20 +161,27 @@ static int device_backlight_init(struct drm_device *dev)
value /= bl_max_freq;
value /= blc_pwm_precision_factor;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
- /* Check: may be MFLD only */
- if (
- value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
- value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
- return 2;
- else {
- value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
- REG_WRITE(BLC_PWM_CTL,
- (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
- (value));
+ if (gma_power_begin(dev, false)) {
+ if (IS_MRST(dev)) {
+ if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
+ return 2;
+ else {
+ REG_WRITE(BLC_PWM_CTL2,
+ (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+ REG_WRITE(BLC_PWM_CTL, value | (value << 16));
+ }
+ } else {
+ if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
+ value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
+ return 2;
+ else {
+ value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
+ REG_WRITE(BLC_PWM_CTL,
+ (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
+ (value));
+ }
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
return 0;
}
@@ -136,7 +193,8 @@ int psb_backlight_init(struct drm_device *dev)
struct backlight_properties props;
memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = BRIGHTNESS_MAX_LEVEL;
+ props.max_brightness = 100;
+ props.type = BACKLIGHT_PLATFORM;
psb_backlight_device = backlight_device_register("psb-bl", NULL,
(void *)dev, &psb_ops, &props);
@@ -147,8 +205,8 @@ int psb_backlight_init(struct drm_device *dev)
if (ret < 0)
return ret;
- psb_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL;
- psb_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL;
+ psb_backlight_device->props.brightness = 100;
+ psb_backlight_device->props.max_brightness = 100;
backlight_update_status(psb_backlight_device);
#endif
return 0;
diff --git a/drivers/staging/gma500/psb_buffer.c b/drivers/staging/gma500/psb_buffer.c
deleted file mode 100644
index 3077f6a7b7dc..000000000000
--- a/drivers/staging/gma500/psb_buffer.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
- */
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_execbuf_util.h"
-#include "psb_ttm_fence_api.h"
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-#define DRM_MEM_TTM 26
-
-struct drm_psb_ttm_backend {
- struct ttm_backend base;
- struct page **pages;
- unsigned int desired_tile_stride;
- unsigned int hw_tile_stride;
- int mem_type;
- unsigned long offset;
- unsigned long num_pages;
-};
-
-/*
- * MSVDX/TOPAZ GPU virtual space looks like this
- * (We currently use only one MMU context).
- * PSB_MEM_MMU_START: from 0x00000000~0xe000000, for generic buffers
- * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing
- * TTM_PL_RAR: from TTM_PL_CI+CI size, for RAR/video buffer sharing
- * TTM_PL_TT: from TTM_PL_RAR+RAR size, for buffers need to mapping into GTT
- */
-static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
- struct ttm_mem_type_manager *man)
-{
-
- struct drm_psb_private *dev_priv =
- container_of(bdev, struct drm_psb_private, bdev);
- struct psb_gtt *pg = dev_priv->pg;
-
- switch (type) {
- case TTM_PL_SYSTEM:
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
- man->available_caching = TTM_PL_FLAG_CACHED |
- TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
- man->default_caching = TTM_PL_FLAG_CACHED;
- break;
- case DRM_PSB_MEM_MMU:
- man->func = &ttm_bo_manager_func;
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
- TTM_MEMTYPE_FLAG_CMA;
- man->gpu_offset = PSB_MEM_MMU_START;
- man->available_caching = TTM_PL_FLAG_CACHED |
- TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
- man->default_caching = TTM_PL_FLAG_WC;
- break;
- case TTM_PL_CI:
- man->func = &ttm_bo_manager_func;
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
- TTM_MEMTYPE_FLAG_FIXED;
- man->gpu_offset = pg->mmu_gatt_start + (pg->ci_start);
- man->available_caching = TTM_PL_FLAG_UNCACHED;
- man->default_caching = TTM_PL_FLAG_UNCACHED;
- break;
- case TTM_PL_RAR: /* Unmappable RAR memory */
- man->func = &ttm_bo_manager_func;
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
- TTM_MEMTYPE_FLAG_FIXED;
- man->available_caching = TTM_PL_FLAG_UNCACHED;
- man->default_caching = TTM_PL_FLAG_UNCACHED;
- man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start);
- break;
- case TTM_PL_TT: /* Mappable GATT memory */
- man->func = &ttm_bo_manager_func;
-#ifdef PSB_WORKING_HOST_MMU_ACCESS
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-#else
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
- TTM_MEMTYPE_FLAG_CMA;
-#endif
- man->available_caching = TTM_PL_FLAG_CACHED |
- TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
- man->default_caching = TTM_PL_FLAG_WC;
- man->gpu_offset = pg->mmu_gatt_start +
- (pg->rar_start + dev_priv->rar_region_size);
- break;
- default:
- DRM_ERROR("Unsupported memory type %u\n", (unsigned) type);
- return -EINVAL;
- }
- return 0;
-}
-
-
-static void psb_evict_mask(struct ttm_buffer_object *bo,
- struct ttm_placement *placement)
-{
- static uint32_t cur_placement;
-
- cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEM;
- cur_placement |= TTM_PL_FLAG_SYSTEM;
-
- placement->fpfn = 0;
- placement->lpfn = 0;
- placement->num_placement = 1;
- placement->placement = &cur_placement;
- placement->num_busy_placement = 0;
- placement->busy_placement = NULL;
-
- /* all buffers evicted to system memory */
- /* return cur_placement | TTM_PL_FLAG_SYSTEM; */
-}
-
-static int psb_invalidate_caches(struct ttm_bo_device *bdev,
- uint32_t placement)
-{
- return 0;
-}
-
-static int psb_move_blit(struct ttm_buffer_object *bo,
- bool evict, bool no_wait,
- struct ttm_mem_reg *new_mem)
-{
- BUG();
- return 0;
-}
-
-/*
- * Flip destination ttm into GATT,
- * then blit and subsequently move out again.
- */
-
-static int psb_move_flip(struct ttm_buffer_object *bo,
- bool evict, bool interruptible, bool no_wait,
- struct ttm_mem_reg *new_mem)
-{
- /*struct ttm_bo_device *bdev = bo->bdev;*/
- struct ttm_mem_reg tmp_mem;
- int ret;
- struct ttm_placement placement;
- uint32_t flags = TTM_PL_FLAG_TT;
-
- tmp_mem = *new_mem;
- tmp_mem.mm_node = NULL;
-
- placement.fpfn = 0;
- placement.lpfn = 0;
- placement.num_placement = 1;
- placement.placement = &flags;
- placement.num_busy_placement = 0; /* FIXME */
- placement.busy_placement = NULL;
-
- ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible,
- false, no_wait);
- if (ret)
- return ret;
- ret = ttm_tt_bind(bo->ttm, &tmp_mem);
- if (ret)
- goto out_cleanup;
- ret = psb_move_blit(bo, true, no_wait, &tmp_mem);
- if (ret)
- goto out_cleanup;
-
- ret = ttm_bo_move_ttm(bo, evict, false, no_wait, new_mem);
-out_cleanup:
- if (tmp_mem.mm_node) {
- drm_mm_put_block(tmp_mem.mm_node);
- tmp_mem.mm_node = NULL;
- }
- return ret;
-}
-
-static int psb_move(struct ttm_buffer_object *bo,
- bool evict, bool interruptible, bool no_wait_reserve,
- bool no_wait, struct ttm_mem_reg *new_mem)
-{
- struct ttm_mem_reg *old_mem = &bo->mem;
-
- if ((old_mem->mem_type == TTM_PL_RAR) ||
- (new_mem->mem_type == TTM_PL_RAR)) {
- if (old_mem->mm_node) {
- spin_lock(&bo->glob->lru_lock);
- drm_mm_put_block(old_mem->mm_node);
- spin_unlock(&bo->glob->lru_lock);
- }
- old_mem->mm_node = NULL;
- *old_mem = *new_mem;
- } else if (old_mem->mem_type == TTM_PL_SYSTEM) {
- return ttm_bo_move_memcpy(bo, evict, false, no_wait, new_mem);
- } else if (new_mem->mem_type == TTM_PL_SYSTEM) {
- int ret = psb_move_flip(bo, evict, interruptible,
- no_wait, new_mem);
- if (unlikely(ret != 0)) {
- if (ret == -ERESTART)
- return ret;
- else
- return ttm_bo_move_memcpy(bo, evict, false,
- no_wait, new_mem);
- }
- } else {
- if (psb_move_blit(bo, evict, no_wait, new_mem))
- return ttm_bo_move_memcpy(bo, evict, false, no_wait,
- new_mem);
- }
- return 0;
-}
-
-static int drm_psb_tbe_populate(struct ttm_backend *backend,
- unsigned long num_pages,
- struct page **pages,
- struct page *dummy_read_page,
- dma_addr_t *dma_addrs)
-{
- struct drm_psb_ttm_backend *psb_be =
- container_of(backend, struct drm_psb_ttm_backend, base);
-
- psb_be->pages = pages;
- return 0;
-}
-
-static int drm_psb_tbe_unbind(struct ttm_backend *backend)
-{
- struct ttm_bo_device *bdev = backend->bdev;
- struct drm_psb_private *dev_priv =
- container_of(bdev, struct drm_psb_private, bdev);
- struct drm_psb_ttm_backend *psb_be =
- container_of(backend, struct drm_psb_ttm_backend, base);
- struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
- /* struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type]; */
-
- if (psb_be->mem_type == TTM_PL_TT) {
- uint32_t gatt_p_offset =
- (psb_be->offset - dev_priv->pg->mmu_gatt_start)
- >> PAGE_SHIFT;
-
- (void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset,
- psb_be->num_pages,
- psb_be->desired_tile_stride,
- psb_be->hw_tile_stride, 0);
- }
-
- psb_mmu_remove_pages(pd, psb_be->offset,
- psb_be->num_pages,
- psb_be->desired_tile_stride,
- psb_be->hw_tile_stride);
-
- return 0;
-}
-
-static int drm_psb_tbe_bind(struct ttm_backend *backend,
- struct ttm_mem_reg *bo_mem)
-{
- struct ttm_bo_device *bdev = backend->bdev;
- struct drm_psb_private *dev_priv =
- container_of(bdev, struct drm_psb_private, bdev);
- struct drm_psb_ttm_backend *psb_be =
- container_of(backend, struct drm_psb_ttm_backend, base);
- struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
- struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type];
- struct drm_mm_node *mm_node = bo_mem->mm_node;
- int type;
- int ret = 0;
-
- psb_be->mem_type = bo_mem->mem_type;
- psb_be->num_pages = bo_mem->num_pages;
- psb_be->desired_tile_stride = 0;
- psb_be->hw_tile_stride = 0;
- psb_be->offset = (mm_node->start << PAGE_SHIFT) +
- man->gpu_offset;
-
- type =
- (bo_mem->
- placement & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0;
-
- if (psb_be->mem_type == TTM_PL_TT) {
- uint32_t gatt_p_offset =
- (psb_be->offset - dev_priv->pg->mmu_gatt_start)
- >> PAGE_SHIFT;
-
- ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages,
- gatt_p_offset,
- psb_be->num_pages,
- psb_be->desired_tile_stride,
- psb_be->hw_tile_stride, type);
- }
-
- ret = psb_mmu_insert_pages(pd, psb_be->pages,
- psb_be->offset, psb_be->num_pages,
- psb_be->desired_tile_stride,
- psb_be->hw_tile_stride, type);
- if (ret)
- goto out_err;
-
- return 0;
-out_err:
- drm_psb_tbe_unbind(backend);
- return ret;
-
-}
-
-static void drm_psb_tbe_clear(struct ttm_backend *backend)
-{
- struct drm_psb_ttm_backend *psb_be =
- container_of(backend, struct drm_psb_ttm_backend, base);
-
- psb_be->pages = NULL;
- return;
-}
-
-static void drm_psb_tbe_destroy(struct ttm_backend *backend)
-{
- struct drm_psb_ttm_backend *psb_be =
- container_of(backend, struct drm_psb_ttm_backend, base);
-
- if (backend)
- kfree(psb_be);
-}
-
-static struct ttm_backend_func psb_ttm_backend = {
- .populate = drm_psb_tbe_populate,
- .clear = drm_psb_tbe_clear,
- .bind = drm_psb_tbe_bind,
- .unbind = drm_psb_tbe_unbind,
- .destroy = drm_psb_tbe_destroy,
-};
-
-static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev)
-{
- struct drm_psb_ttm_backend *psb_be;
-
- psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL);
- if (!psb_be)
- return NULL;
- psb_be->pages = NULL;
- psb_be->base.func = &psb_ttm_backend;
- psb_be->base.bdev = bdev;
- return &psb_be->base;
-}
-
-static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
- struct ttm_mem_reg *mem)
-{
- struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
- struct drm_psb_private *dev_priv =
- container_of(bdev, struct drm_psb_private, bdev);
- struct psb_gtt *pg = dev_priv->pg;
- struct drm_mm_node *mm_node = mem->mm_node;
-
- mem->bus.addr = NULL;
- mem->bus.offset = 0;
- mem->bus.size = mem->num_pages << PAGE_SHIFT;
- mem->bus.base = 0;
- mem->bus.is_iomem = false;
- if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
- return -EINVAL;
- switch (mem->mem_type) {
- case TTM_PL_SYSTEM:
- /* system memory */
- return 0;
- case TTM_PL_TT:
- mem->bus.offset = mm_node->start << PAGE_SHIFT;
- mem->bus.base = pg->gatt_start;
- mem->bus.is_iomem = false;
- /* Don't know whether it is IO_MEM, this flag
- used in vm_fault handle */
- break;
- case DRM_PSB_MEM_MMU:
- mem->bus.offset = mm_node->start << PAGE_SHIFT;
- mem->bus.base = 0x00000000;
- break;
- case TTM_PL_CI:
- mem->bus.offset = mm_node->start << PAGE_SHIFT;
- mem->bus.base = dev_priv->ci_region_start;;
- mem->bus.is_iomem = true;
- break;
- case TTM_PL_RAR:
- mem->bus.offset = mm_node->start << PAGE_SHIFT;
- mem->bus.base = dev_priv->rar_region_start;;
- mem->bus.is_iomem = true;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static void psb_ttm_io_mem_free(struct ttm_bo_device *bdev,
- struct ttm_mem_reg *mem)
-{
-}
-
-/*
- * Use this memory type priority if no eviction is needed.
- */
-/*
-static uint32_t psb_mem_prios[] = {
- TTM_PL_CI,
- TTM_PL_RAR,
- TTM_PL_TT,
- DRM_PSB_MEM_MMU,
- TTM_PL_SYSTEM
-};
-*/
-/*
- * Use this memory type priority if need to evict.
- */
-/*
-static uint32_t psb_busy_prios[] = {
- TTM_PL_TT,
- TTM_PL_CI,
- TTM_PL_RAR,
- DRM_PSB_MEM_MMU,
- TTM_PL_SYSTEM
-};
-*/
-struct ttm_bo_driver psb_ttm_bo_driver = {
-/*
- .mem_type_prio = psb_mem_prios,
- .mem_busy_prio = psb_busy_prios,
- .num_mem_type_prio = ARRAY_SIZE(psb_mem_prios),
- .num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios),
-*/
- .create_ttm_backend_entry = &drm_psb_tbe_init,
- .invalidate_caches = &psb_invalidate_caches,
- .init_mem_type = &psb_init_mem_type,
- .evict_flags = &psb_evict_mask,
- .move = &psb_move,
- .verify_access = &psb_verify_access,
- .sync_obj_signaled = &ttm_fence_sync_obj_signaled,
- .sync_obj_wait = &ttm_fence_sync_obj_wait,
- .sync_obj_flush = &ttm_fence_sync_obj_flush,
- .sync_obj_unref = &ttm_fence_sync_obj_unref,
- .sync_obj_ref = &ttm_fence_sync_obj_ref,
- .io_mem_reserve = &psb_ttm_io_mem_reserve,
- .io_mem_free = &psb_ttm_io_mem_free
-};
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index a339406052ef..49ffdd5b90e2 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -28,9 +28,6 @@
#include "drm_mode.h"
#endif
-#include "psb_ttm_fence_user.h"
-#include "psb_ttm_placement_user.h"
-
#define DRM_PSB_SAREA_MAJOR 0
#define DRM_PSB_SAREA_MINOR 2
#define PSB_FIXED_SHIFT 16
@@ -41,15 +38,6 @@
* Public memory types.
*/
-#define DRM_PSB_MEM_MMU TTM_PL_PRIV1
-#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1
-
-#define TTM_PL_CI TTM_PL_PRIV0
-#define TTM_PL_FLAG_CI TTM_PL_FLAG_PRIV0
-
-#define TTM_PL_RAR TTM_PL_PRIV2
-#define TTM_PL_FLAG_RAR TTM_PL_FLAG_PRIV2
-
typedef s32 psb_fixed;
typedef u32 psb_ufixed;
@@ -112,111 +100,12 @@ struct drm_psb_sarea {
u32 num_active_scanouts;
};
-#define PSB_RELOC_MAGIC 0x67676767
-#define PSB_RELOC_SHIFT_MASK 0x0000FFFF
-#define PSB_RELOC_SHIFT_SHIFT 0
-#define PSB_RELOC_ALSHIFT_MASK 0xFFFF0000
-#define PSB_RELOC_ALSHIFT_SHIFT 16
-
-#define PSB_RELOC_OP_OFFSET 0 /* Offset of the indicated
- * buffer
- */
-
-struct drm_psb_reloc {
- u32 reloc_op;
- u32 where; /* offset in destination buffer */
- u32 buffer; /* Buffer reloc applies to */
- u32 mask; /* Destination format: */
- u32 shift; /* Destination format: */
- u32 pre_add; /* Destination format: */
- u32 background; /* Destination add */
- u32 dst_buffer; /* Destination buffer. Index into buffer_list */
- u32 arg0; /* Reloc-op dependent */
- u32 arg1;
-};
-
-
#define PSB_GPU_ACCESS_READ (1ULL << 32)
#define PSB_GPU_ACCESS_WRITE (1ULL << 33)
#define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
#define PSB_BO_FLAG_COMMAND (1ULL << 52)
-#define PSB_ENGINE_2D 0
-#define PSB_ENGINE_VIDEO 1
-#define LNC_ENGINE_ENCODE 5
-
-/*
- * For this fence class we have a couple of
- * fence types.
- */
-
-#define _PSB_FENCE_EXE_SHIFT 0
-#define _PSB_FENCE_FEEDBACK_SHIFT 4
-
-#define _PSB_FENCE_TYPE_EXE (1 << _PSB_FENCE_EXE_SHIFT)
-#define _PSB_FENCE_TYPE_FEEDBACK (1 << _PSB_FENCE_FEEDBACK_SHIFT)
-
-#define PSB_NUM_ENGINES 6
-
-
-#define PSB_FEEDBACK_OP_VISTEST (1 << 0)
-
-struct drm_psb_extension_rep {
- s32 exists;
- u32 driver_ioctl_offset;
- u32 sarea_offset;
- u32 major;
- u32 minor;
- u32 pl;
-};
-
-#define DRM_PSB_EXT_NAME_LEN 128
-
-union drm_psb_extension_arg {
- char extension[DRM_PSB_EXT_NAME_LEN];
- struct drm_psb_extension_rep rep;
-};
-
-struct psb_validate_req {
- u64 set_flags;
- u64 clear_flags;
- u64 next;
- u64 presumed_gpu_offset;
- u32 buffer_handle;
- u32 presumed_flags;
- u32 group;
- u32 pad64;
-};
-
-struct psb_validate_rep {
- u64 gpu_offset;
- u32 placement;
- u32 fence_type_mask;
-};
-
-#define PSB_USE_PRESUMED (1 << 0)
-
-struct psb_validate_arg {
- int handled;
- int ret;
- union {
- struct psb_validate_req req;
- struct psb_validate_rep rep;
- } d;
-};
-
-
-#define DRM_PSB_FENCE_NO_USER (1 << 0)
-
-struct psb_ttm_fence_rep {
- u32 handle;
- u32 fence_class;
- u32 fence_type;
- u32 signaled_types;
- u32 error;
-};
-
/*
* Feedback components:
*/
@@ -330,17 +219,6 @@ struct drm_psb_register_rw_arg {
u32 subpicture_disable_mask;
};
-struct psb_gtt_mapping_arg {
- void *hKernelMemInfo;
- u32 offset_pages;
-};
-
-struct drm_psb_getpageaddrs_arg {
- u32 handle;
- unsigned long *page_addrs;
- unsigned long gtt_offset;
-};
-
/* Controlling the kernel modesetting buffers */
#define DRM_PSB_KMS_OFF 0x00
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index d01d45e7a14d..aa87b1b6a44a 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -38,30 +38,29 @@
int drm_psb_debug;
static int drm_psb_trap_pagefaults;
-int drm_psb_disable_vsync = 1;
int drm_psb_no_fb;
-int gfxrtdelay = 2 * 1000;
static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
MODULE_PARM_DESC(debug, "Enable debug output");
MODULE_PARM_DESC(no_fb, "Disable FBdev");
MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
-MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts");
-MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb");
-MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB");
-MODULE_PARM_DESC(ospm, "switch for ospm support");
-MODULE_PARM_DESC(rtpm, "Specifies Runtime PM delay for GFX");
-MODULE_PARM_DESC(hdmi_edid, "EDID info for HDMI monitor");
module_param_named(debug, drm_psb_debug, int, 0600);
module_param_named(no_fb, drm_psb_no_fb, int, 0600);
module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
-module_param_named(rtpm, gfxrtdelay, int, 0600);
static struct pci_device_id pciidlist[] = {
{ 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 },
{ 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 },
+ { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
{ 0, 0, 0}
};
MODULE_DEVICE_TABLE(pci, pciidlist);
@@ -74,10 +73,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
#define DRM_IOCTL_PSB_KMS_ON \
DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_LEAVE \
- DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_ENTER \
- DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE)
#define DRM_IOCTL_PSB_SIZES \
DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
struct drm_psb_sizes_arg)
@@ -97,18 +92,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
#define DRM_IOCTL_PSB_REGISTER_RW \
DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_GTT_MAP \
- DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \
- struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_GTT_UNMAP \
- DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \
- struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_GETPAGEADDRS \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\
- struct drm_psb_getpageaddrs_arg)
-#define DRM_IOCTL_PSB_UPDATE_GUARD \
- DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \
- uint32_t)
#define DRM_IOCTL_PSB_DPST \
DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
uint32_t)
@@ -122,74 +105,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
struct drm_psb_get_pipe_from_crtc_id_arg)
-/*
- * TTM execbuf extension.
- */
-
-#define DRM_PSB_CMDBUF 0x23
-#define DRM_PSB_SCENE_UNREF 0x24
-#define DRM_IOCTL_PSB_KMS_OFF DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_KMS_ON DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-/*
- * TTM placement user extension.
- */
-
-#define DRM_PSB_PLACEMENT_OFFSET (DRM_PSB_SCENE_UNREF + 1)
-
-#define DRM_PSB_TTM_PL_CREATE (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_UNREF (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_SYNCCPU (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_WAITIDLE (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_CREATE_UB (TTM_PL_CREATE_UB + DRM_PSB_PLACEMENT_OFFSET)
-
-/*
- * TTM fence extension.
- */
-
-#define DRM_PSB_FENCE_OFFSET (DRM_PSB_TTM_PL_CREATE_UB + 1)
-#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET)
-#define DRM_PSB_TTM_FENCE_FINISH (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET)
-#define DRM_PSB_TTM_FENCE_UNREF (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET)
-
-#define DRM_PSB_FLIP (DRM_PSB_TTM_FENCE_UNREF + 1) /*20*/
-
-#define DRM_IOCTL_PSB_TTM_PL_CREATE \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
- union ttm_pl_create_arg)
-#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\
- union ttm_pl_reference_arg)
-#define DRM_IOCTL_PSB_TTM_PL_UNREF \
- DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\
- struct ttm_pl_reference_req)
-#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU \
- DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\
- struct ttm_pl_synccpu_arg)
-#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE \
- DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\
- struct ttm_pl_waitidle_arg)
-#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\
- union ttm_pl_setstatus_arg)
-#define DRM_IOCTL_PSB_TTM_PL_CREATE_UB \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE_UB,\
- union ttm_pl_create_ub_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED, \
- union ttm_fence_signaled_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \
- DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH, \
- union ttm_fence_finish_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \
- DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF, \
- struct ttm_fence_unref_arg)
-
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
static int psb_sizes_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
@@ -218,11 +133,6 @@ static struct drm_ioctl_desc psb_ioctls[] = {
PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
psbfb_kms_on_ioctl,
DRM_ROOT_ONLY),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl,
- DRM_ROOT_ONLY),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER,
- psb_vt_enter_ioctl,
- DRM_ROOT_ONLY),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
@@ -232,92 +142,226 @@ static struct drm_ioctl_desc psb_ioctls[] = {
DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP,
- psb_gtt_map_meminfo_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP,
- psb_gtt_unmap_meminfo_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS,
- psb_getpageaddrs_ioctl,
- DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
psb_intel_get_pipe_from_crtc_id, 0),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE_UB, psb_pl_ub_create_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED,
- psb_fence_signaled_ioctl, DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl,
- DRM_AUTH),
};
-static void psb_set_uopt(struct drm_psb_uopt *uopt)
+static void psb_lastclose(struct drm_device *dev)
{
return;
}
-static void psb_lastclose(struct drm_device *dev)
+static void psb_do_takedown(struct drm_device *dev)
{
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) dev->dev_private;
+ /* FIXME: do we need to clean up the gtt here ? */
+}
- return;
+void mrst_get_fuse_settings(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ uint32_t fuse_value = 0;
+ uint32_t fuse_value_tmp = 0;
- if (!dev->dev_private)
- return;
+#define FB_REG06 0xD0810600
+#define FB_MIPI_DISABLE (1 << 11)
+#define FB_REG09 0xD0810900
+#define FB_REG09 0xD0810900
+#define FB_SKU_MASK 0x7000
+#define FB_SKU_SHIFT 12
+#define FB_SKU_100 0
+#define FB_SKU_100L 1
+#define FB_SKU_83 2
+ pci_write_config_dword(pci_root, 0xD0, FB_REG06);
+ pci_read_config_dword(pci_root, 0xD4, &fuse_value);
+
+ dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
+
+ DRM_INFO("internal display is %s\n",
+ dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
+
+ /*prevent Runtime suspend at start*/
+ if (dev_priv->iLVDS_enable) {
+ dev_priv->is_lvds_on = true;
+ dev_priv->is_mipi_on = false;
+ }
+ else {
+ dev_priv->is_mipi_on = true;
+ dev_priv->is_lvds_on = false;
+ }
+
+ dev_priv->video_device_fuse = fuse_value;
+
+ pci_write_config_dword(pci_root, 0xD0, FB_REG09);
+ pci_read_config_dword(pci_root, 0xD4, &fuse_value);
+
+ DRM_INFO("SKU values is 0x%x. \n", fuse_value);
+ fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
- mutex_lock(&dev_priv->cmdbuf_mutex);
- if (dev_priv->context.buffers) {
- vfree(dev_priv->context.buffers);
- dev_priv->context.buffers = NULL;
+ dev_priv->fuse_reg_value = fuse_value;
+
+ switch (fuse_value_tmp) {
+ case FB_SKU_100:
+ dev_priv->core_freq = 200;
+ break;
+ case FB_SKU_100L:
+ dev_priv->core_freq = 100;
+ break;
+ case FB_SKU_83:
+ dev_priv->core_freq = 166;
+ break;
+ default:
+ DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp);
+ dev_priv->core_freq = 0;
}
- mutex_unlock(&dev_priv->cmdbuf_mutex);
+ DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq);
+ pci_dev_put(pci_root);
}
-static void psb_do_takedown(struct drm_device *dev)
+void mid_get_pci_revID (struct drm_psb_private *dev_priv)
{
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->bdev;
+ uint32_t platform_rev_id = 0;
+ struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+ /*get the revison ID, B0:D2:F0;0x08 */
+ pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
+ dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
+ pci_dev_put(pci_gfx_root);
+ PSB_DEBUG_ENTRY("platform_rev_id is %x\n", dev_priv->platform_rev_id);
+}
- if (dev_priv->have_mem_mmu) {
- ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU);
- dev_priv->have_mem_mmu = 0;
- }
+void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
+{
+ struct mrst_vbt *vbt = &dev_priv->vbt_data;
+ u32 platform_config_address;
+ u16 new_size;
+ u8 *vbt_virtual;
+ u8 bpi;
+ u8 number_desc = 0;
+ struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
+ struct gct_r10_timing_info ti;
+ void *pGCT;
+ struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
- if (dev_priv->have_tt) {
- ttm_bo_clean_mm(bdev, TTM_PL_TT);
- dev_priv->have_tt = 0;
- }
+ /*get the address of the platform config vbt, B0:D2:F0;0xFC */
+ pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address);
+ pci_dev_put(pci_gfx_root);
+ DRM_INFO("drm platform config address is %x\n",
+ platform_config_address);
- if (dev_priv->have_camera) {
- ttm_bo_clean_mm(bdev, TTM_PL_CI);
- dev_priv->have_camera = 0;
- }
- if (dev_priv->have_rar) {
- ttm_bo_clean_mm(bdev, TTM_PL_RAR);
- dev_priv->have_rar = 0;
+ /* check for platform config address == 0. */
+ /* this means fw doesn't support vbt */
+
+ if (platform_config_address == 0) {
+ vbt->size = 0;
+ return;
}
+ /* get the virtual address of the vbt */
+ vbt_virtual = ioremap(platform_config_address, sizeof(*vbt));
+
+ memcpy(vbt, vbt_virtual, sizeof(*vbt));
+ iounmap(vbt_virtual); /* Free virtual address space */
+
+ printk(KERN_ALERT "GCT revision is %x\n", vbt->revision);
+
+ switch (vbt->revision) {
+ case 0:
+ vbt->mrst_gct = NULL;
+ vbt->mrst_gct = \
+ ioremap(platform_config_address + sizeof(*vbt) - 4,
+ vbt->size - sizeof(*vbt) + 4);
+ pGCT = vbt->mrst_gct;
+ bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
+ dev_priv->gct_data.bpi = bpi;
+ dev_priv->gct_data.pt =
+ ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
+ memcpy(&dev_priv->gct_data.DTD,
+ &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
+ sizeof(struct mrst_timing_info));
+ dev_priv->gct_data.Panel_Port_Control =
+ ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+ ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+ break;
+ case 1:
+ vbt->mrst_gct = NULL;
+ vbt->mrst_gct = \
+ ioremap(platform_config_address + sizeof(*vbt) - 4,
+ vbt->size - sizeof(*vbt) + 4);
+ pGCT = vbt->mrst_gct;
+ bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
+ dev_priv->gct_data.bpi = bpi;
+ dev_priv->gct_data.pt =
+ ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
+ memcpy(&dev_priv->gct_data.DTD,
+ &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
+ sizeof(struct mrst_timing_info));
+ dev_priv->gct_data.Panel_Port_Control =
+ ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+ ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+ break;
+ case 0x10:
+ /*header definition changed from rev 01 (v2) to rev 10h. */
+ /*so, some values have changed location*/
+ new_size = vbt->checksum; /*checksum contains lo size byte*/
+ /*LSB of mrst_gct contains hi size byte*/
+ new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
+
+ vbt->checksum = vbt->size; /*size contains the checksum*/
+ if (new_size > 0xff)
+ vbt->size = 0xff; /*restrict size to 255*/
+ else
+ vbt->size = new_size;
+
+ /* number of descriptors defined in the GCT */
+ number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
+ bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
+ vbt->mrst_gct = NULL;
+ vbt->mrst_gct = \
+ ioremap(platform_config_address + GCT_R10_HEADER_SIZE,
+ GCT_R10_DISPLAY_DESC_SIZE * number_desc);
+ pGCT = vbt->mrst_gct;
+ pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
+ dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
+
+ /*copy the GCT display timings into a temp structure*/
+ memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
+
+ /*now copy the temp struct into the dev_priv->gct_data*/
+ dp_ti->pixel_clock = ti.pixel_clock;
+ dp_ti->hactive_hi = ti.hactive_hi;
+ dp_ti->hactive_lo = ti.hactive_lo;
+ dp_ti->hblank_hi = ti.hblank_hi;
+ dp_ti->hblank_lo = ti.hblank_lo;
+ dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
+ dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
+ dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
+ dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
+ dp_ti->vactive_hi = ti.vactive_hi;
+ dp_ti->vactive_lo = ti.vactive_lo;
+ dp_ti->vblank_hi = ti.vblank_hi;
+ dp_ti->vblank_lo = ti.vblank_lo;
+ dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
+ dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
+ dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
+ dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
+
+ /*mov the MIPI_Display_Descriptor data from GCT to dev priv*/
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+ *((u8 *)pGCT + 0x0d);
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
+ (*((u8 *)pGCT + 0x0e)) << 8;
+ break;
+ default:
+ printk(KERN_ERR "Unknown revision of GCT!\n");
+ vbt->size = 0;
+ }
}
static void psb_get_core_freq(struct drm_device *dev)
@@ -358,36 +402,10 @@ static void psb_get_core_freq(struct drm_device *dev)
}
}
-#define FB_REG06 0xD0810600
-#define FB_TOPAZ_DISABLE BIT0
-#define FB_MIPI_DISABLE BIT11
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK (BIT12|BIT13|BIT14)
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
-
-bool mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
- uint32_t platform_rev_id = 0;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
- /*get the revison ID, B0:D2:F0;0x08 */
- pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
- dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
- pci_dev_put(pci_gfx_root);
- PSB_DEBUG_ENTRY("platform_rev_id is %x\n",
- dev_priv->platform_rev_id);
-
- return true;
-}
-
static int psb_do_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->bdev;
struct psb_gtt *pg = dev_priv->pg;
uint32_t stolen_gtt;
@@ -396,16 +414,6 @@ static int psb_do_init(struct drm_device *dev)
int ret = -ENOMEM;
-
- /*
- * Initialize sequence numbers for the different command
- * submission mechanisms.
- */
-
- dev_priv->sequence[PSB_ENGINE_2D] = 0;
- dev_priv->sequence[PSB_ENGINE_VIDEO] = 0;
- dev_priv->sequence[LNC_ENGINE_ENCODE] = 0;
-
if (pg->mmu_gatt_start & 0x0FFFFFFF) {
DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
ret = -EINVAL;
@@ -445,6 +453,7 @@ static int psb_do_init(struct drm_device *dev)
pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
tt_pages -= tt_start >> PAGE_SHIFT;
+ /* FIXME: can we kill ta_mem_size ? */
dev_priv->sizes.ta_mem_size = 0;
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
@@ -453,30 +462,10 @@ static int psb_do_init(struct drm_device *dev)
PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
PSB_CR_BIF_CTRL);
psb_spank(dev_priv);
-
- PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-
- /* TT region managed by TTM. */
- if (!ttm_bo_init_mm(bdev, TTM_PL_TT,
- pg->gatt_pages -
- (pg->ci_start >> PAGE_SHIFT) -
- ((dev_priv->ci_region_size + dev_priv->rar_region_size)
- >> PAGE_SHIFT))) {
-
- dev_priv->have_tt = 1;
- dev_priv->sizes.tt_size =
- (tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2;
- }
- if (!ttm_bo_init_mm(bdev,
- DRM_PSB_MEM_MMU,
- PSB_MEM_TT_START >> PAGE_SHIFT)) {
- dev_priv->have_mem_mmu = 1;
- dev_priv->sizes.mmu_size =
- PSB_MEM_TT_START / (1024*1024);
- }
+ /* mmu_gatt ?? */
+ PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
- PSB_DEBUG_INIT("Init MSVDX\n");
return 0;
out_err:
psb_do_takedown(dev);
@@ -510,39 +499,19 @@ static int psb_driver_unload(struct drm_device *dev)
down_read(&pg->sem);
psb_mmu_remove_pfn_sequence(
- psb_mmu_get_default_pd
- (dev_priv->mmu),
- pg->mmu_gatt_start,
- pg->vram_stolen_size >> PAGE_SHIFT);
- if (pg->ci_stolen_size != 0)
- psb_mmu_remove_pfn_sequence(
- psb_mmu_get_default_pd
- (dev_priv->mmu),
- pg->ci_start,
- pg->ci_stolen_size >> PAGE_SHIFT);
- if (pg->rar_stolen_size != 0)
- psb_mmu_remove_pfn_sequence(
- psb_mmu_get_default_pd
- (dev_priv->mmu),
- pg->rar_start,
- pg->rar_stolen_size >> PAGE_SHIFT);
+ psb_mmu_get_default_pd
+ (dev_priv->mmu),
+ pg->mmu_gatt_start,
+ dev_priv->vram_stolen_size >> PAGE_SHIFT);
up_read(&pg->sem);
psb_mmu_driver_takedown(dev_priv->mmu);
dev_priv->mmu = NULL;
}
- psb_gtt_takedown(dev_priv->pg, 1);
+ psb_gtt_takedown(dev);
if (dev_priv->scratch_page) {
__free_page(dev_priv->scratch_page);
dev_priv->scratch_page = NULL;
}
- if (dev_priv->has_bo_device) {
- ttm_bo_device_release(&dev_priv->bdev);
- dev_priv->has_bo_device = 0;
- }
- if (dev_priv->has_fence_device) {
- ttm_fence_device_release(&dev_priv->fdev);
- dev_priv->has_fence_device = 0;
- }
if (dev_priv->vdc_reg) {
iounmap(dev_priv->vdc_reg);
dev_priv->vdc_reg = NULL;
@@ -552,12 +521,6 @@ static int psb_driver_unload(struct drm_device *dev)
dev_priv->sgx_reg = NULL;
}
- if (dev_priv->tdev)
- ttm_object_device_release(&dev_priv->tdev);
-
- if (dev_priv->has_global)
- psb_ttm_global_release(dev_priv);
-
kfree(dev_priv);
dev->dev_private = NULL;
@@ -565,7 +528,7 @@ static int psb_driver_unload(struct drm_device *dev)
psb_intel_destroy_bios(dev);
}
- ospm_power_uninit();
+ gma_power_uninit(dev);
return 0;
}
@@ -574,49 +537,27 @@ static int psb_driver_unload(struct drm_device *dev)
static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
{
struct drm_psb_private *dev_priv;
- struct ttm_bo_device *bdev;
unsigned long resource_start;
struct psb_gtt *pg;
unsigned long irqflags;
int ret = -ENOMEM;
uint32_t tt_pages;
+ struct drm_connector *connector;
+ struct psb_intel_output *psb_intel_output;
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
if (dev_priv == NULL)
return -ENOMEM;
- INIT_LIST_HEAD(&dev_priv->video_ctx);
-
- dev_priv->num_pipe = 2;
+ if (IS_MRST(dev))
+ dev_priv->num_pipe = 1;
+ else
+ dev_priv->num_pipe = 2;
dev_priv->dev = dev;
- bdev = &dev_priv->bdev;
-
- ret = psb_ttm_global_init(dev_priv);
- if (unlikely(ret != 0))
- goto out_err;
- dev_priv->has_global = 1;
-
- dev_priv->tdev = ttm_object_device_init
- (dev_priv->mem_global_ref.object, PSB_OBJECT_HASH_ORDER);
- if (unlikely(dev_priv->tdev == NULL))
- goto out_err;
-
- mutex_init(&dev_priv->temp_mem);
- mutex_init(&dev_priv->cmdbuf_mutex);
- mutex_init(&dev_priv->reset_mutex);
- INIT_LIST_HEAD(&dev_priv->context.validate_list);
- INIT_LIST_HEAD(&dev_priv->context.kern_validate_list);
-
-/* mutex_init(&dev_priv->dsr_mutex); */
-
- spin_lock_init(&dev_priv->reloc_lock);
-
- DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue);
dev->dev_private = (void *) dev_priv;
dev_priv->chipset = chipset;
- psb_set_uopt(&dev_priv->uopt);
PSB_DEBUG_INIT("Mapping MMIO\n");
resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
@@ -626,34 +567,28 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (!dev_priv->vdc_reg)
goto out_err;
- dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET,
+ if (IS_MRST(dev))
+ dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET,
+ PSB_SGX_SIZE);
+ else
+ dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET,
PSB_SGX_SIZE);
if (!dev_priv->sgx_reg)
goto out_err;
- psb_get_core_freq(dev);
- psb_intel_opregion_init(dev);
- psb_intel_init_bios(dev);
-
- PSB_DEBUG_INIT("Init TTM fence and BO driver\n");
+ if (IS_MRST(dev)) {
+ mrst_get_fuse_settings(dev);
+ mrst_get_vbt_data(dev_priv);
+ mid_get_pci_revID(dev_priv);
+ } else {
+ psb_get_core_freq(dev);
+ psb_intel_opregion_init(dev);
+ psb_intel_init_bios(dev);
+ }
/* Init OSPM support */
- ospm_power_init(dev);
-
- ret = psb_ttm_fence_device_init(&dev_priv->fdev);
- if (unlikely(ret != 0))
- goto out_err;
-
- dev_priv->has_fence_device = 1;
- ret = ttm_bo_device_init(bdev,
- dev_priv->bo_global_ref.ref.object,
- &psb_ttm_bo_driver,
- DRM_PSB_FILE_PAGE_OFFSET, false);
- if (unlikely(ret != 0))
- goto out_err;
- dev_priv->has_bo_device = 1;
- ttm_lock_init(&dev_priv->ttm_lock);
+ gma_power_init(dev);
ret = -ENOMEM;
@@ -663,15 +598,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
set_pages_uc(dev_priv->scratch_page, 1);
- dev_priv->pg = psb_gtt_alloc(dev);
- if (!dev_priv->pg)
- goto out_err;
-
- ret = psb_gtt_init(dev_priv->pg, 0);
- if (ret)
- goto out_err;
-
- ret = psb_gtt_mm_init(dev_priv->pg);
+ ret = psb_gtt_init(dev, 0);
if (ret)
goto out_err;
@@ -686,40 +613,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
- /* CI/RAR use the lower half of TT. */
- pg->ci_start = (tt_pages / 2) << PAGE_SHIFT;
- pg->rar_start = pg->ci_start + pg->ci_stolen_size;
-
-
- /*
- * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area.
- */
- if (dev_priv->pg->ci_stolen_size != 0) {
- down_read(&pg->sem);
- ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd
- (dev_priv->mmu),
- dev_priv->ci_region_start >> PAGE_SHIFT,
- pg->mmu_gatt_start + pg->ci_start,
- pg->ci_stolen_size >> PAGE_SHIFT, 0);
- up_read(&pg->sem);
- if (ret)
- goto out_err;
- }
-
- /*
- * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area.
- */
- if (dev_priv->pg->rar_stolen_size != 0) {
- down_read(&pg->sem);
- ret = psb_mmu_insert_pfn_sequence(
- psb_mmu_get_default_pd(dev_priv->mmu),
- dev_priv->rar_region_start >> PAGE_SHIFT,
- pg->mmu_gatt_start + pg->rar_start,
- pg->rar_stolen_size >> PAGE_SHIFT, 0);
- up_read(&pg->sem);
- if (ret)
- goto out_err;
- }
dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
if (!dev_priv->pf_pd)
@@ -728,14 +621,13 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
- spin_lock_init(&dev_priv->sequence_lock);
-
- PSB_DEBUG_INIT("Begin to init MSVDX/Topaz\n");
-
ret = psb_do_init(dev);
if (ret)
return ret;
+ PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
+ PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
+
/* igd_opregion_init(&dev_priv->opregion_dev); */
acpi_video_register();
if (dev_priv->lid_state)
@@ -773,7 +665,18 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
drm_kms_helper_poll_init(dev);
}
- ret = psb_backlight_init(dev);
+ /* Only add backlight support if we have LVDS output */
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ head) {
+ psb_intel_output = to_psb_intel_output(connector);
+
+ switch (psb_intel_output->type) {
+ case INTEL_OUTPUT_LVDS:
+ ret = psb_backlight_init(dev);
+ break;
+ }
+ }
+
if (ret)
return ret;
#if 0
@@ -783,11 +686,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
#endif
/*Intel drm driver load is done, continue doing pvr load*/
DRM_DEBUG("Pvr driver load\n");
-
-/* if (PVRCore_Init() < 0)
- goto out_err; */
-/* if (MRSTLFBInit(dev) < 0)
- goto out_err;*/
return 0;
out_err:
psb_driver_unload(dev);
@@ -800,45 +698,6 @@ int psb_driver_device_is_agp(struct drm_device *dev)
}
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct ttm_bo_device *bdev = &dev_priv->bdev;
- struct ttm_mem_type_manager *man;
- int ret;
-
- ret = ttm_vt_lock(&dev_priv->ttm_lock, 1,
- psb_fpriv(file_priv)->tfile);
- if (unlikely(ret != 0))
- return ret;
-
- ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT);
- if (unlikely(ret != 0))
- goto out_unlock;
-
- man = &bdev->man[TTM_PL_TT];
-
-#if 0 /* What to do with this ? */
- if (unlikely(!drm_mm_clean(&man->manager)))
- DRM_INFO("Warning: GATT was not clean after VT switch.\n");
-#endif
-
- ttm_bo_swapout_all(&dev_priv->bdev);
-
- return 0;
-out_unlock:
- (void) ttm_vt_unlock(&dev_priv->ttm_lock);
- return ret;
-}
-
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- return ttm_vt_unlock(&dev_priv->ttm_lock);
-}
-
static int psb_sizes_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -945,13 +804,12 @@ static int psb_dpst_ioctl(struct drm_device *dev, void *data,
uint32_t y;
uint32_t reg;
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON))
- return 0;
+ if (!gma_power_begin(dev, 0))
+ return -EIO;
reg = PSB_RVDC32(PIPEASRC);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
/* horizontal is the left 16 bits */
x = reg >> 16;
@@ -1028,13 +886,12 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
drm_fb = obj_to_fb(obj);
psb_fb = to_psb_fb(drm_fb);
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
- REG_WRITE(DSPASURF, psb_fb->offset);
+ if (gma_power_begin(dev, 0)) {
+ REG_WRITE(DSPASURF, psb_fb->gtt->offset);
REG_READ(DSPASURF);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
- dev_priv->saveDSPASURF = psb_fb->offset;
+ dev_priv->saveDSPASURF = psb_fb->gtt->offset;
}
return 0;
@@ -1107,8 +964,8 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
struct drm_psb_private *dev_priv = psb_priv(dev);
struct drm_psb_stolen_memory_arg *arg = data;
- arg->base = dev_priv->pg->stolen_base;
- arg->size = dev_priv->pg->vram_stolen_size;
+ arg->base = dev_priv->stolen_base;
+ arg->size = dev_priv->vram_stolen_size;
return 0;
}
@@ -1118,11 +975,10 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
{
struct drm_psb_private *dev_priv = psb_priv(dev);
struct drm_psb_register_rw_arg *arg = data;
- UHBUsage usage =
- arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON;
+ bool usage = arg->b_force_hw_on ? true : false;
if (arg->display_write_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
PSB_WVDC32(arg->display.pfit_controls,
PFIT_CONTROL);
@@ -1147,7 +1003,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
PSB_WVDC32(arg->display.vtotal_b,
VTOTAL_B);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
dev_priv->savePFIT_CONTROL =
@@ -1172,7 +1028,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
}
if (arg->display_read_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
if (arg->display_read_mask &
REGRWBITS_PFIT_CONTROLS)
arg->display.pfit_controls =
@@ -1193,7 +1049,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
if (arg->display_read_mask &
REGRWBITS_PFIT_CONTROLS)
@@ -1219,7 +1075,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
}
if (arg->overlay_write_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
@@ -1270,7 +1126,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
}
}
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
@@ -1296,7 +1152,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
}
if (arg->overlay_read_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
@@ -1317,7 +1173,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
@@ -1343,7 +1199,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
}
if (arg->sprite_enable_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
PSB_WVDC32(0x1F3E, DSPARB);
PSB_WVDC32(arg->sprite.dspa_control
| PSB_RVDC32(DSPACNTR), DSPACNTR);
@@ -1358,22 +1214,22 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
PSB_RVDC32(DSPCSURF);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
if (arg->sprite_disable_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
PSB_WVDC32(0x3F3E, DSPARB);
PSB_WVDC32(0x0, DSPCCNTR);
PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
PSB_RVDC32(DSPCSURF);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
if (arg->subpicture_enable_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
uint32_t temp;
if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
temp = PSB_RVDC32(DSPACNTR);
@@ -1417,12 +1273,12 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
PSB_WVDC32(temp, DSPCSURF);
PSB_RVDC32(DSPCSURF);
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
if (arg->subpicture_disable_mask != 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+ if (gma_power_begin(dev, usage)) {
uint32_t temp;
if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
temp = PSB_RVDC32(DSPACNTR);
@@ -1463,42 +1319,20 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
PSB_WVDC32(temp, DSPCSURF);
PSB_RVDC32(DSPCSURF);
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
return 0;
}
-/* always available as we are SIGIO'd */
-static unsigned int psb_poll(struct file *filp,
- struct poll_table_struct *wait)
-{
- return POLLIN | POLLRDNORM;
-}
-
-/* Not sure what we will need yet - in the PVR driver this disappears into
- a tangle of abstracted handlers and per process crap */
-
-struct psb_priv {
- int dummy;
-};
-
static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
{
- struct psb_priv *psb = kzalloc(sizeof(struct psb_priv), GFP_KERNEL);
- if (psb == NULL)
- return -ENOMEM;
- priv->driver_priv = psb;
- DRM_DEBUG("\n");
- /*return PVRSRVOpen(dev, priv);*/
return 0;
}
static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
{
- kfree(priv->driver_priv);
- priv->driver_priv = NULL;
}
static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
@@ -1517,30 +1351,9 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
pm_runtime_allow(&dev->pdev->dev);
dev_priv->rpm_enabled = 1;
}
- /*
- * The driver private ioctls and TTM ioctls should be
- * thread-safe.
- */
-
- if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
- && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
- struct drm_ioctl_desc *ioctl =
- &psb_ioctls[nr - DRM_COMMAND_BASE];
-
- if (unlikely(ioctl->cmd != cmd)) {
- DRM_ERROR(
- "Invalid drm cmnd %d ioctl->cmd %x, cmd %x\n",
- nr - DRM_COMMAND_BASE, ioctl->cmd, cmd);
- return -EINVAL;
- }
-
- return drm_ioctl(filp, cmd, arg);
- }
- /*
- * Not all old drm ioctls are thread-safe.
- */
-
return drm_ioctl(filp, cmd, arg);
+
+ /* FIXME: do we need to wrap the other side of this */
}
@@ -1557,16 +1370,21 @@ static void psb_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}
-
static const struct dev_pm_ops psb_pm_ops = {
.runtime_suspend = psb_runtime_suspend,
.runtime_resume = psb_runtime_resume,
.runtime_idle = psb_runtime_idle,
};
+static struct vm_operations_struct psb_gem_vm_ops = {
+ .fault = psb_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+};
+
static struct drm_driver driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
- DRIVER_IRQ_VBL | DRIVER_MODESET,
+ DRIVER_IRQ_VBL | DRIVER_MODESET| DRIVER_GEM ,
.load = psb_driver_load,
.unload = psb_driver_unload,
@@ -1580,27 +1398,29 @@ static struct drm_driver driver = {
.enable_vblank = psb_enable_vblank,
.disable_vblank = psb_disable_vblank,
.get_vblank_counter = psb_get_vblank_counter,
- .firstopen = NULL,
.lastclose = psb_lastclose,
.open = psb_driver_open,
- .postclose = psb_driver_close,
-#if 0 /* ACFIXME */
- .get_map_ofs = drm_core_get_map_ofs,
- .get_reg_ofs = drm_core_get_reg_ofs,
- .proc_init = psb_proc_init,
- .proc_cleanup = psb_proc_cleanup,
-#endif
.preclose = psb_driver_preclose,
+ .postclose = psb_driver_close,
+ .reclaim_buffers = drm_core_reclaim_buffers,
+
+ .gem_init_object = psb_gem_init_object,
+ .gem_free_object = psb_gem_free_object,
+ .gem_vm_ops = &psb_gem_vm_ops,
+ .dumb_create = psb_gem_dumb_create,
+ .dumb_map_offset = psb_gem_dumb_map_gtt,
+ .dumb_destroy = psb_gem_dumb_destroy,
+
.fops = {
.owner = THIS_MODULE,
- .open = psb_open,
- .release = psb_release,
+ .open = drm_open,
+ .release = drm_release,
.unlocked_ioctl = psb_unlocked_ioctl,
- .mmap = psb_mmap,
- .poll = psb_poll,
+ .mmap = drm_gem_mmap,
+ .poll = drm_poll,
.fasync = drm_fasync,
.read = drm_read,
- },
+ },
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = PSB_DRM_DRIVER_DATE,
@@ -1612,8 +1432,8 @@ static struct drm_driver driver = {
static struct pci_driver psb_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
- .resume = ospm_power_resume,
- .suspend = ospm_power_suspend,
+ .resume = gma_power_resume,
+ .suspend = gma_power_suspend,
.probe = psb_probe,
.remove = psb_remove,
#ifdef CONFIG_PM
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 29a36056d664..e19a45478757 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -21,6 +21,7 @@
#define _PSB_DRV_H_
#include <linux/version.h>
+#include <linux/kref.h>
#include <drm/drmP.h>
#include "drm_global.h"
@@ -29,22 +30,19 @@
#include "psb_intel_drv.h"
#include "psb_gtt.h"
#include "psb_powermgmt.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_driver.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_lock.h"
+#include "mrst.h"
/*Append new drm mode definition here, align with libdrm definition*/
#define DRM_MODE_SCALE_NO_SCALE 2
-extern struct ttm_bo_driver psb_ttm_bo_driver;
-
enum {
CHIP_PSB_8108 = 0,
CHIP_PSB_8109 = 1,
+ CHIP_MRST_4100 = 2,
};
+#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
+
/*
*Hardware bugfixes
*/
@@ -52,10 +50,6 @@ enum {
#define DRIVER_NAME "pvrsrvkm"
#define DRIVER_DESC "drm driver for the Intel GMA500"
#define DRIVER_AUTHOR "Intel Corporation"
-#define OSPM_PROC_ENTRY "ospm"
-#define RTPM_PROC_ENTRY "rtpm"
-#define BLC_PROC_ENTRY "mrst_blc"
-#define DISPLAY_PROC_ENTRY "display_status"
#define PSB_DRM_DRIVER_DATE "2009-03-10"
#define PSB_DRM_DRIVER_MAJOR 8
@@ -92,26 +86,10 @@ enum {
#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
#define PSB_NUM_VALIDATE_BUFFERS 2048
-#define PSB_MEM_MMU_START 0x00000000
-#define PSB_MEM_TT_START 0xE0000000
-
-#define PSB_GL3_CACHE_CTL 0x2100
-#define PSB_GL3_CACHE_STAT 0x2108
-
/*
*Flags for external memory type field.
*/
-#define MRST_MSVDX_OFFSET 0x90000 /*MSVDX Base offset */
-#define PSB_MSVDX_OFFSET 0x50000 /*MSVDX Base offset */
-/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */
-#define PSB_MSVDX_SIZE 0x10000
-
-#define LNC_TOPAZ_OFFSET 0xA0000
-#define PNW_TOPAZ_OFFSET 0xC0000
-#define PNW_GL3_OFFSET 0xB0000
-#define LNC_TOPAZ_SIZE 0x10000
-#define PNW_TOPAZ_SIZE 0x30000 /* PNW VXE285 has two cores */
#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */
#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */
#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */
@@ -223,20 +201,6 @@ enum {
#define MDFLD_PNW_B0 0x04
#define MDFLD_PNW_C0 0x08
-#define MDFLD_DSR_2D_3D_0 BIT0
-#define MDFLD_DSR_2D_3D_2 BIT1
-#define MDFLD_DSR_CURSOR_0 BIT2
-#define MDFLD_DSR_CURSOR_2 BIT3
-#define MDFLD_DSR_OVERLAY_0 BIT4
-#define MDFLD_DSR_OVERLAY_2 BIT5
-#define MDFLD_DSR_MIPI_CONTROL BIT6
-#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
-
-#define MDFLD_DSR_RR 45
-#define MDFLD_DPU_ENABLE BIT31
-#define MDFLD_DSR_FULLSCREEN BIT30
-#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR)
-
#define PSB_PWR_STATE_ON 1
#define PSB_PWR_STATE_OFF 2
@@ -250,9 +214,6 @@ enum {
#define PSB_PCIx_MSI_ADDR_LOC 0x94
#define PSB_PCIx_MSI_DATA_LOC 0x98
-#define MDFLD_PLANE_MAX_WIDTH 2048
-#define MDFLD_PLANE_MAX_HEIGHT 2048
-
struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
@@ -266,142 +227,55 @@ struct psb_intel_opregion {
int enabled;
};
-/*
- *User options.
- */
-
-struct drm_psb_uopt {
- int pad; /*keep it here in case we use it in future*/
-};
-
-/**
- *struct psb_context
- *
- *@buffers: array of pre-allocated validate buffers.
- *@used_buffers: number of buffers in @buffers array currently in use.
- *@validate_buffer: buffers validated from user-space.
- *@kern_validate_buffers : buffers validated from kernel-space.
- *@fence_flags : Fence flags to be used for fence creation.
- *
- *This structure is used during execbuf validation.
- */
-
-struct psb_context {
- struct psb_validate_buffer *buffers;
- uint32_t used_buffers;
- struct list_head validate_list;
- struct list_head kern_validate_list;
- uint32_t fence_types;
- uint32_t val_seq;
-};
-
-struct psb_validate_buffer;
-
-/* Currently defined profiles */
-enum VAProfile {
- VAProfileMPEG2Simple = 0,
- VAProfileMPEG2Main = 1,
- VAProfileMPEG4Simple = 2,
- VAProfileMPEG4AdvancedSimple = 3,
- VAProfileMPEG4Main = 4,
- VAProfileH264Baseline = 5,
- VAProfileH264Main = 6,
- VAProfileH264High = 7,
- VAProfileVC1Simple = 8,
- VAProfileVC1Main = 9,
- VAProfileVC1Advanced = 10,
- VAProfileH263Baseline = 11,
- VAProfileJPEGBaseline = 12,
- VAProfileH264ConstrainedBaseline = 13
-};
-
-/* Currently defined entrypoints */
-enum VAEntrypoint {
- VAEntrypointVLD = 1,
- VAEntrypointIZZ = 2,
- VAEntrypointIDCT = 3,
- VAEntrypointMoComp = 4,
- VAEntrypointDeblocking = 5,
- VAEntrypointEncSlice = 6, /* slice level encode */
- VAEntrypointEncPicture = 7 /* pictuer encode, JPEG, etc */
-};
-
-
-struct psb_video_ctx {
- struct list_head head;
- struct file *filp; /* DRM device file pointer */
- int ctx_type; /* profile<<8|entrypoint */
- /* todo: more context specific data for multi-context support */
-};
-
-#define MODE_SETTING_IN_CRTC 0x1
-#define MODE_SETTING_IN_ENCODER 0x2
-#define MODE_SETTING_ON_GOING 0x3
-#define MODE_SETTING_IN_DSR 0x4
-#define MODE_SETTING_ENCODER_DONE 0x8
-#define GCT_R10_HEADER_SIZE 16
-#define GCT_R10_DISPLAY_DESC_SIZE 28
struct drm_psb_private {
- /*
- * DSI info.
- */
- void * dbi_dsr_info;
- void * dsi_configs[2];
-
- /*
- *TTM Glue.
- */
-
- struct drm_global_reference mem_global_ref;
- struct ttm_bo_global_ref bo_global_ref;
- int has_global;
-
struct drm_device *dev;
- struct ttm_object_device *tdev;
- struct ttm_fence_device fdev;
- struct ttm_bo_device bdev;
- struct ttm_lock ttm_lock;
- struct vm_operations_struct *ttm_vm_ops;
- int has_fence_device;
- int has_bo_device;
unsigned long chipset;
- struct drm_psb_uopt uopt;
-
struct psb_gtt *pg;
- /*GTT Memory manager*/
+ /* GTT Memory manager */
struct psb_gtt_mm *gtt_mm;
-
struct page *scratch_page;
- uint32_t sequence[PSB_NUM_ENGINES];
- uint32_t last_sequence[PSB_NUM_ENGINES];
- uint32_t last_submitted_seq[PSB_NUM_ENGINES];
+ u32 *gtt_map;
+ uint32_t stolen_base;
+ void *vram_addr;
+ unsigned long vram_stolen_size;
+ int gtt_initialized;
+ u16 gmch_ctrl; /* Saved GTT setup */
+ u32 pge_ctl;
+
+ struct mutex gtt_mutex;
+ struct resource *gtt_mem; /* Our PCI resource */
struct psb_mmu_driver *mmu;
struct psb_mmu_pd *pf_pd;
+ /*
+ * Register base
+ */
+
uint8_t *sgx_reg;
uint8_t *vdc_reg;
uint32_t gatt_free_offset;
- /* IMG video context */
- struct list_head video_ctx;
-
-
-
/*
- *Fencing / irq.
+ * Fencing / irq.
*/
uint32_t vdc_irq_mask;
uint32_t pipestat[PSB_NUM_PIPE];
- bool vblanksEnabledForFlips;
spinlock_t irqmask_lock;
- spinlock_t sequence_lock;
+
+ /*
+ * Power
+ */
+
+ bool suspended;
+ bool display_power;
+ int display_count;
/*
*Modesetting
@@ -413,40 +287,9 @@ struct drm_psb_private {
uint32_t num_pipe;
/*
- * CI share buffer
- */
- unsigned int ci_region_start;
- unsigned int ci_region_size;
-
- /*
- * RAR share buffer;
- */
- unsigned int rar_region_start;
- unsigned int rar_region_size;
-
- /*
*Memory managers
*/
- int have_camera;
- int have_rar;
- int have_tt;
- int have_mem_mmu;
- struct mutex temp_mem;
-
- /*
- *Relocation buffer mapping.
- */
-
- spinlock_t reloc_lock;
- unsigned int rel_mapped_pages;
- wait_queue_head_t rel_mapped_queue;
-
- /*
- *SAREA
- */
- struct drm_psb_sarea *sarea_priv;
-
/*
*OSPM info
*/
@@ -458,7 +301,8 @@ struct drm_psb_private {
struct drm_psb_sizes_arg sizes;
- uint32_t fuse_reg_value;
+ u32 fuse_reg_value;
+ u32 video_device_fuse;
/* pci revision id for B0:D2:F0 */
uint8_t platform_rev_id;
@@ -483,6 +327,7 @@ struct drm_psb_private {
unsigned int lvds_use_ssc:1;
int lvds_ssc_freq;
bool is_lvds_on;
+ bool is_mipi_on;
unsigned int core_freq;
uint32_t iLVDS_enable;
@@ -490,6 +335,20 @@ struct drm_psb_private {
/*runtime PM state*/
int rpm_enabled;
+ /* Moorestown specific */
+ struct mrst_vbt vbt_data;
+ struct mrst_gct_data gct_data;
+
+ /* Moorestown pipe config register value cache */
+ uint32_t pipeconf;
+ uint32_t pipeconf1;
+ uint32_t pipeconf2;
+
+ /* Moorestown plane control register value cache */
+ uint32_t dspcntr;
+ uint32_t dspcntr1;
+ uint32_t dspcntr2;
+
/*
*Register state
*/
@@ -595,98 +454,11 @@ struct drm_psb_private {
uint32_t saveOVC_OGAMC4;
uint32_t saveOVC_OGAMC5;
- /*
- * extra MDFLD Register state
- */
- uint32_t saveHDMIPHYMISCCTL;
- uint32_t saveHDMIB_CONTROL;
- uint32_t saveDSPCCNTR;
- uint32_t savePIPECCONF;
- uint32_t savePIPECSRC;
- uint32_t saveHTOTAL_C;
- uint32_t saveHBLANK_C;
- uint32_t saveHSYNC_C;
- uint32_t saveVTOTAL_C;
- uint32_t saveVBLANK_C;
- uint32_t saveVSYNC_C;
- uint32_t saveDSPCSTRIDE;
- uint32_t saveDSPCSIZE;
- uint32_t saveDSPCPOS;
- uint32_t saveDSPCSURF;
- uint32_t saveDSPCLINOFF;
- uint32_t saveDSPCTILEOFF;
- uint32_t saveDSPCCURSOR_CTRL;
- uint32_t saveDSPCCURSOR_BASE;
- uint32_t saveDSPCCURSOR_POS;
- uint32_t save_palette_c[256];
- uint32_t saveOV_OVADD_C;
- uint32_t saveOV_OGAMC0_C;
- uint32_t saveOV_OGAMC1_C;
- uint32_t saveOV_OGAMC2_C;
- uint32_t saveOV_OGAMC3_C;
- uint32_t saveOV_OGAMC4_C;
- uint32_t saveOV_OGAMC5_C;
-
- /* DSI reg save */
- uint32_t saveDEVICE_READY_REG;
- uint32_t saveINTR_EN_REG;
- uint32_t saveDSI_FUNC_PRG_REG;
- uint32_t saveHS_TX_TIMEOUT_REG;
- uint32_t saveLP_RX_TIMEOUT_REG;
- uint32_t saveTURN_AROUND_TIMEOUT_REG;
- uint32_t saveDEVICE_RESET_REG;
- uint32_t saveDPI_RESOLUTION_REG;
- uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
- uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
- uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
- uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
- uint32_t saveVERT_SYNC_PAD_COUNT_REG;
- uint32_t saveVERT_BACK_PORCH_COUNT_REG;
- uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
- uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
- uint32_t saveINIT_COUNT_REG;
- uint32_t saveMAX_RET_PAK_REG;
- uint32_t saveVIDEO_FMT_REG;
- uint32_t saveEOT_DISABLE_REG;
- uint32_t saveLP_BYTECLK_REG;
- uint32_t saveHS_LS_DBI_ENABLE_REG;
- uint32_t saveTXCLKESC_REG;
- uint32_t saveDPHY_PARAM_REG;
- uint32_t saveMIPI_CONTROL_REG;
- uint32_t saveMIPI;
- uint32_t saveMIPI_C;
- void (*init_drvIC)(struct drm_device *dev);
- void (*dsi_prePowerState)(struct drm_device *dev);
- void (*dsi_postPowerState)(struct drm_device *dev);
-
- /* DPST Register Save */
- uint32_t saveHISTOGRAM_INT_CONTROL_REG;
- uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
- uint32_t savePWM_CONTROL_LOGIC;
-
/* MSI reg save */
-
uint32_t msi_addr;
uint32_t msi_data;
/*
- *Scheduling.
- */
-
- struct mutex reset_mutex;
- struct mutex cmdbuf_mutex;
- /*uint32_t ta_mem_pages;
- struct psb_ta_mem *ta_mem;
- int force_ta_mem_load;*/
- atomic_t val_seq;
-
- /*
- *TODO: change this to be per drm-context.
- */
-
- struct psb_context context;
-
- /*
* LID-Switch
*/
spinlock_t lid_lock;
@@ -699,8 +471,6 @@ struct drm_psb_private {
*Watchdog
*/
- int timer_available;
-
uint32_t apm_reg;
uint16_t apm_base;
@@ -716,73 +486,17 @@ struct drm_psb_private {
};
-struct psb_file_data { /* TODO: Audit this, remove the indirection and set
- it up properly in open/postclose ACFIXME */
- void *priv;
-};
-
-struct psb_fpriv {
- struct ttm_object_file *tfile;
-};
-
struct psb_mmu_driver;
extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
extern int drm_pick_crtcs(struct drm_device *dev);
-static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
-{
- struct psb_file_data *pvr_file_priv
- = (struct psb_file_data *)file_priv->driver_priv;
- return (struct psb_fpriv *) pvr_file_priv->priv;
-}
-
static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
{
return (struct drm_psb_private *) dev->dev_private;
}
/*
- *TTM glue. psb_ttm_glue.c
- */
-
-extern int psb_open(struct inode *inode, struct file *filp);
-extern int psb_release(struct inode *inode, struct file *filp);
-extern int psb_mmap(struct file *filp, struct vm_area_struct *vma);
-
-extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_verify_access(struct ttm_buffer_object *bo,
- struct file *filp);
-extern ssize_t psb_ttm_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos);
-extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos);
-extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_extension_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_ttm_global_init(struct drm_psb_private *dev_priv);
-extern void psb_ttm_global_release(struct drm_psb_private *dev_priv);
-extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-/*
*MMU stuff.
*/
@@ -825,31 +539,6 @@ extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
uint32_t desired_tile_stride,
uint32_t hw_tile_stride);
/*
- *psb_sgx.c
- */
-
-
-
-extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_reg_submit(struct drm_psb_private *dev_priv,
- uint32_t *regs, unsigned int cmds);
-
-
-extern void psb_fence_or_sync(struct drm_file *file_priv,
- uint32_t engine,
- uint32_t fence_types,
- uint32_t fence_flags,
- struct list_head *list,
- struct psb_ttm_fence_rep *fence_arg,
- struct ttm_fence_object **fence_p);
-extern int psb_validate_kernel_buffer(struct psb_context *context,
- struct ttm_buffer_object *bo,
- uint32_t fence_class,
- uint64_t set_flags,
- uint64_t clr_flags);
-
-/*
*psb_irq.c
*/
@@ -859,8 +548,6 @@ extern int psb_irq_disable_dpst(struct drm_device *dev);
extern void psb_irq_preinstall(struct drm_device *dev);
extern int psb_irq_postinstall(struct drm_device *dev);
extern void psb_irq_uninstall(struct drm_device *dev);
-extern void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
-extern int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
extern void psb_irq_turn_on_dpst(struct drm_device *dev);
extern void psb_irq_turn_off_dpst(struct drm_device *dev);
@@ -878,29 +565,6 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
/*
- *psb_fence.c
- */
-
-extern void psb_fence_handler(struct drm_device *dev, uint32_t class);
-
-extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t flags, uint32_t *sequence,
- unsigned long *timeout_jiffies);
-extern void psb_fence_error(struct drm_device *dev,
- uint32_t class,
- uint32_t sequence, uint32_t type, int error);
-extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev);
-
-/* MSVDX/Topaz stuff */
-extern int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp);
-
-extern int lnc_video_frameskip(struct drm_device *dev,
- uint64_t user_pointer);
-extern int lnc_video_getparam(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
-/*
* psb_opregion.c
*/
extern int psb_intel_opregion_init(struct drm_device *dev);
@@ -930,6 +594,9 @@ extern int psbfb_sync(struct fb_info *info);
extern void psb_spank(struct drm_psb_private *dev_priv);
+extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
+ unsigned size);
+
/*
*psb_reset.c
*/
@@ -950,8 +617,36 @@ int psb_set_brightness(struct backlight_device *bd);
int psb_get_brightness(struct backlight_device *bd);
struct backlight_device * psb_get_backlight_device(void);
+/* mrst_crtc.c */
+extern const struct drm_crtc_helper_funcs mrst_helper_funcs;
+
+/* mrst_lvds.c */
+extern void mrst_lvds_init(struct drm_device *dev,
+ struct psb_intel_mode_device *mode_dev);
+
+/* psb_intel_lvds.c */
+extern void psb_intel_lvds_prepare(struct drm_encoder *encoder);
+extern void psb_intel_lvds_commit(struct drm_encoder *encoder);
+extern const struct drm_connector_helper_funcs
+ psb_intel_lvds_connector_helper_funcs;
+extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
+
+/* psb_gem.c */
+extern int psb_gem_init_object(struct drm_gem_object *obj);
+extern void psb_gem_free_object(struct drm_gem_object *obj);
+extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
+ struct drm_file *file);
+extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+ uint32_t handle);
+extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
+ uint32_t handle, uint64_t *offset);
+extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+
+
/*
- *Debug print bits setting
+ * Debug print bits setting
*/
#define PSB_D_GENERAL (1 << 0)
#define PSB_D_INIT (1 << 1)
@@ -975,7 +670,6 @@ struct backlight_device * psb_get_backlight_device(void);
extern int drm_psb_debug;
extern int drm_psb_no_fb;
-extern int drm_psb_disable_vsync;
extern int drm_idle_check_interval;
#define PSB_DEBUG_GENERAL(_fmt, _arg...) \
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index f67f53b12937..084c36bbfe86 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -36,10 +36,7 @@
#include "psb_drv.h"
#include "psb_intel_reg.h"
#include "psb_intel_drv.h"
-#include "psb_ttm_userobj_api.h"
#include "psb_fb.h"
-#include "psb_sgx.h"
-#include "psb_pvr_glue.h"
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -193,8 +190,7 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct psb_framebuffer *psbfb = vma->vm_private_data;
struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt *pg = dev_priv->pg;
- unsigned long phys_addr = (unsigned long)pg->stolen_base;;
+ unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@ -243,7 +239,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt *pg = dev_priv->pg;
if (vma->vm_pgoff != 0)
return -EINVAL;
@@ -256,22 +251,48 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
fb_screen_base = (char *)info->screen_base;
DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
- vma->vm_pgoff, fb_screen_base, pg->vram_addr);
+ vma->vm_pgoff, fb_screen_base,
+ dev_priv->vram_addr);
- /*if using stolen memory, */
- if (fb_screen_base == pg->vram_addr) {
+ /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
+ if (1 || fb_screen_base == dev_priv->vram_addr) {
vma->vm_ops = &psbfb_vm_ops;
vma->vm_private_data = (void *)psbfb;
vma->vm_flags |= VM_RESERVED | VM_IO |
VM_MIXEDMAP | VM_DONTEXPAND;
} else {
- /*using IMG meminfo, can I use pvrmmap to map it?*/
-
+ /* GTT memory backed by kernel/user pages, needs a different
+ approach ? - GEM ? */
}
return 0;
}
+static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+ struct psb_fbdev *fbdev = info->par;
+ struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct drm_device *dev = psbfb->base.dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 __user *p = (u32 __user *)arg;
+ u32 l;
+ u32 buf[32];
+ switch (cmd) {
+ case 0x12345678:
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+ if (get_user(l, p))
+ return -EFAULT;
+ if (l > 32)
+ return -EMSGSIZE;
+ if (copy_from_user(buf, p + 1, l * sizeof(u32)))
+ return -EFAULT;
+ psbfb_2d_submit(dev_priv, buf, l);
+ return 0;
+ default:
+ return -ENOTTY;
+ }
+}
static struct fb_ops psbfb_ops = {
.owner = THIS_MODULE,
@@ -284,11 +305,12 @@ static struct fb_ops psbfb_ops = {
.fb_imageblit = psbfb_imageblit,
.fb_mmap = psbfb_mmap,
.fb_sync = psbfb_sync,
+ .fb_ioctl = psbfb_ioctl,
};
static struct drm_framebuffer *psb_framebuffer_create
(struct drm_device *dev, struct drm_mode_fb_cmd *r,
- void *mm_private)
+ struct gtt_range *gt)
{
struct psb_framebuffer *fb;
int ret;
@@ -304,7 +326,7 @@ static struct drm_framebuffer *psb_framebuffer_create
drm_helper_mode_fill_fb_struct(&fb->base, r);
- fb->bo = mm_private;
+ fb->gtt = gt;
return &fb->base;
@@ -313,136 +335,58 @@ err:
return NULL;
}
-static struct drm_framebuffer *psb_user_framebuffer_create
- (struct drm_device *dev, struct drm_file *filp,
- struct drm_mode_fb_cmd *r)
-{
- struct ttm_buffer_object *bo = NULL;
- uint64_t size;
-
- bo = ttm_buffer_object_lookup(psb_fpriv(filp)->tfile, r->handle);
- if (!bo)
- return NULL;
-
- /* JB: TODO not drop, make smarter */
- size = ((uint64_t) bo->num_pages) << PAGE_SHIFT;
- if (size < r->width * r->height * 4)
- return NULL;
-
- /* JB: TODO not drop, refcount buffer */
- return psb_framebuffer_create(dev, r, bo);
-
-#if 0
- struct psb_framebuffer *psbfb;
- struct drm_framebuffer *fb;
- struct fb_info *info;
- void *psKernelMemInfo = NULL;
- void * hKernelMemInfo = (void *)r->handle;
- struct drm_psb_private *dev_priv
- = (struct drm_psb_private *)dev->dev_private;
- struct psb_fbdev *fbdev = dev_priv->fbdev;
- struct psb_gtt *pg = dev_priv->pg;
- int ret;
- uint32_t offset;
- uint64_t size;
-
- ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
- if (ret) {
- DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
- (u32)hKernelMemInfo);
- return NULL;
- }
-
- DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
- (u32)hKernelMemInfo);
-
- /* JB: TODO not drop, make smarter */
- size = psKernelMemInfo->ui32AllocSize;
- if (size < r->height * r->pitch)
+/**
+ * psbfb_alloc - allocate frame buffer memory
+ * @dev: the DRM device
+ * @aligned_size: space needed
+ *
+ * Allocate the frame buffer. In the usual case we get a GTT range that
+ * is stolen memory backed and life is simple. If there isn't sufficient
+ * stolen memory or the system has no stolen memory we allocate a range
+ * and back it with a GEM object.
+ *
+ * In this case the GEM object has no handle.
+ */
+static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
+{
+ struct gtt_range *backing;
+ /* Begin by trying to use stolen memory backing */
+ backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
+ if (backing)
+ return backing;
+ /* Next try using GEM host memory */
+ backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
+ if (backing == NULL)
return NULL;
- /* JB: TODO not drop, refcount buffer */
- /* return psb_framebuffer_create(dev, r, bo); */
-
- fb = psb_framebuffer_create(dev, r, (void *)psKernelMemInfo);
- if (!fb) {
- DRM_ERROR("failed to allocate fb.\n");
+ /* Now back it with an object */
+ if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
+ psb_gtt_free_range(dev, backing);
return NULL;
}
-
- psbfb = to_psb_fb(fb);
- psbfb->size = size;
- psbfb->hKernelMemInfo = hKernelMemInfo;
-
- DRM_DEBUG("Mapping to gtt..., KernelMemInfo %p\n", psKernelMemInfo);
-
- /*if not VRAM, map it into tt aperture*/
- if (psKernelMemInfo->pvLinAddrKM != pg->vram_addr) {
- ret = psb_gtt_map_meminfo(dev, hKernelMemInfo, &offset);
- if (ret) {
- DRM_ERROR("map meminfo for 0x%x failed\n",
- (u32)hKernelMemInfo);
- return NULL;
- }
- psbfb->offset = (offset << PAGE_SHIFT);
- } else {
- psbfb->offset = 0;
- }
- info = framebuffer_alloc(0, &dev->pdev->dev);
- if (!info)
- return NULL;
-
- strcpy(info->fix.id, "psbfb");
-
- info->flags = FBINFO_DEFAULT;
- info->fix.accel = FB_ACCEL_I830; /*FIXMEAC*/
- info->fbops = &psbfb_ops;
-
- info->fix.smem_start = dev->mode_config.fb_base;
- info->fix.smem_len = size;
-
- info->screen_base = psKernelMemInfo->pvLinAddrKM;
- info->screen_size = size;
-
- drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
- drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
- fb->width, fb->height);
-
- info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
- info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
-
- info->pixmap.size = 64 * 1024;
- info->pixmap.buf_align = 8;
- info->pixmap.access_align = 32;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
- info->pixmap.scan_align = 1;
-
- psbfb->fbdev = info;
- fbdev->pfb = psbfb;
-
- fbdev->psb_fb_helper.fb = fb;
- fbdev->psb_fb_helper.fbdev = info;
- MRSTLFBHandleChangeFB(dev, psbfb);
-
- return fb;
-#endif
+ return backing;
}
-
+
+/**
+ * psbfb_create - create a framebuffer
+ * @fbdev: the framebuffer device
+ * @sizes: specification of the layout
+ *
+ * Create a framebuffer to the specifications provided
+ */
static int psbfb_create(struct psb_fbdev *fbdev,
struct drm_fb_helper_surface_size *sizes)
{
struct drm_device *dev = fbdev->psb_fb_helper.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt *pg = dev_priv->pg;
struct fb_info *info;
struct drm_framebuffer *fb;
struct psb_framebuffer *psbfb;
struct drm_mode_fb_cmd mode_cmd;
struct device *device = &dev->pdev->dev;
-
- struct ttm_buffer_object *fbo = NULL;
int size, aligned_size;
int ret;
+ struct gtt_range *backing;
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
@@ -455,15 +399,19 @@ static int psbfb_create(struct psb_fbdev *fbdev,
size = mode_cmd.pitch * mode_cmd.height;
aligned_size = ALIGN(size, PAGE_SIZE);
+ /* Allocate the framebuffer in the GTT with stolen page backing */
+ backing = psbfb_alloc(dev, aligned_size);
+ if (backing == NULL)
+ return -ENOMEM;
+
mutex_lock(&dev->struct_mutex);
- fb = psb_framebuffer_create(dev, &mode_cmd, fbo);
+ fb = psb_framebuffer_create(dev, &mode_cmd, backing);
if (!fb) {
DRM_ERROR("failed to allocate fb.\n");
ret = -ENOMEM;
goto out_err1;
}
psbfb = to_psb_fb(fb);
- psbfb->size = size;
info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
if (!info) {
@@ -485,10 +433,24 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->fbops = &psbfb_ops;
info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;
- info->screen_base = (char *)pg->vram_addr;
+
+ /* Accessed via stolen memory directly, This only works for stolem
+ memory however. Need to address this once we start using gtt
+ pages we allocate */
+ info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
info->screen_size = size;
memset(info->screen_base, 0, size);
+ if (dev_priv->pg->stolen_size) {
+ info->apertures = alloc_apertures(1);
+ if (!info->apertures) {
+ ret = -ENOMEM;
+ goto out_err0;
+ }
+ info->apertures->ranges[0].base = dev->mode_config.fb_base;
+ info->apertures->ranges[0].size = dev_priv->pg->stolen_size;
+ }
+
drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
sizes->fb_width, sizes->fb_height);
@@ -515,9 +477,51 @@ out_err0:
fb->funcs->destroy(fb);
out_err1:
mutex_unlock(&dev->struct_mutex);
+ psb_gtt_free_range(dev, backing);
return ret;
}
+/**
+ * psb_user_framebuffer_create - create framebuffer
+ * @dev: our DRM device
+ * @filp: client file
+ * @cmd: mode request
+ *
+ * Create a new framebuffer backed by a userspace GEM object
+ */
+static struct drm_framebuffer *psb_user_framebuffer_create
+ (struct drm_device *dev, struct drm_file *filp,
+ struct drm_mode_fb_cmd *cmd)
+{
+ struct gtt_range *r;
+ struct drm_gem_object *obj;
+ struct psb_framebuffer *psbfb;
+
+ /* Find the GEM object and thus the gtt range object that is
+ to back this space */
+ obj = drm_gem_object_lookup(dev, filp, cmd->handle);
+ if (obj == NULL)
+ return ERR_PTR(-ENOENT);
+
+ /* Allocate a framebuffer */
+ psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL);
+ if (psbfb == NULL) {
+ drm_gem_object_unreference_unlocked(obj);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Let the core code do all the work */
+ r = container_of(obj, struct gtt_range, gem);
+ if (psb_framebuffer_create(dev, cmd, r) == NULL) {
+ drm_gem_object_unreference_unlocked(obj);
+ kfree(psbfb);
+ return ERR_PTR(-EINVAL);
+ }
+ /* Return the drm_framebuffer contained within the psb fbdev which
+ has been initialized by the framebuffer creation */
+ return &psbfb->base;
+}
+
static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno)
{
@@ -561,15 +565,20 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
if (fbdev->psb_fb_helper.fbdev) {
info = fbdev->psb_fb_helper.fbdev;
+ /* FIXME: this is a bit more inside knowledge than I'd like
+ but I don't see how to make a fake GEM object of the
+ stolen space nicely */
+ if (psbfb->gtt->stolen)
+ psb_gtt_free_range(dev, psbfb->gtt);
+ else
+ drm_gem_object_unreference(&psbfb->gtt->gem);
unregister_framebuffer(info);
iounmap(info->screen_base);
framebuffer_release(info);
}
drm_fb_helper_fini(&fbdev->psb_fb_helper);
-
drm_framebuffer_cleanup(&psbfb->base);
-
return 0;
}
@@ -610,7 +619,6 @@ void psb_fbdev_fini(struct drm_device *dev)
dev_priv->fbdev = NULL;
}
-
static void psbfb_output_poll_changed(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
@@ -627,7 +635,6 @@ int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
return 0;
info = psbfb->fbdev;
- psbfb->pvrBO = NULL;
if (info)
framebuffer_release(info);
@@ -635,28 +642,48 @@ int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
}
/*EXPORT_SYMBOL(psbfb_remove); */
+/**
+ * psb_user_framebuffer_create_handle - add hamdle to a framebuffer
+ * @fb: framebuffer
+ * @file_priv: our DRM file
+ * @handle: returned handle
+ *
+ * Our framebuffer object is a GTT range which also contains a GEM
+ * object. We need to turn it into a handle for userspace. GEM will do
+ * the work for us
+ */
static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle)
{
- /* JB: TODO currently we can't go from a bo to a handle with ttm */
- (void) file_priv;
- *handle = 0;
- return 0;
+ struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ struct gtt_range *r = psbfb->gtt;
+ if (r->stolen)
+ return -EOPNOTSUPP;
+ return drm_gem_handle_create(file_priv, &r->gem, handle);
}
+/**
+ * psb_user_framebuffer_destroy - destruct user created fb
+ * @fb: framebuffer
+ *
+ * User framebuffers are backed by GEM objects so all we have to do is
+ * clean up a bit and drop the reference, GEM will handle the fallout
+ */
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ struct gtt_range *r = psbfb->gtt;
- /*ummap gtt pages*/
- psb_gtt_unmap_meminfo(dev, psbfb->hKernelMemInfo);
if (psbfb->fbdev)
psbfb_remove(dev, fb);
- /* JB: TODO not drop, refcount buffer */
+ /* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
+ /* We are no longer using the resource in GEM */
+ drm_gem_object_unreference_unlocked(&r->gem);
+
kfree(fb);
}
@@ -698,8 +725,15 @@ static void psb_setup_outputs(struct drm_device *dev)
psb_create_backlight_property(dev);
- psb_intel_lvds_init(dev, &dev_priv->mode_dev);
- /* psb_intel_sdvo_init(dev, SDVOB); */
+ if (IS_MRST(dev)) {
+ if (dev_priv->iLVDS_enable)
+ mrst_lvds_init(dev, &dev_priv->mode_dev);
+ else
+ DRM_ERROR("DSI is not supported\n");
+ } else {
+ psb_intel_lvds_init(dev, &dev_priv->mode_dev);
+ psb_intel_sdvo_init(dev, SDVOB);
+ }
list_for_each_entry(connector, &dev->mode_config.connector_list,
head) {
@@ -716,7 +750,10 @@ static void psb_setup_outputs(struct drm_device *dev)
break;
case INTEL_OUTPUT_LVDS:
PSB_DEBUG_ENTRY("LVDS.\n");
- crtc_mask = (1 << 1);
+ if (IS_MRST(dev))
+ crtc_mask = (1 << 0);
+ else
+ crtc_mask = (1 << 1);
clone_mask = (1 << INTEL_OUTPUT_LVDS);
break;
case INTEL_OUTPUT_MIPI:
@@ -743,52 +780,6 @@ static void psb_setup_outputs(struct drm_device *dev)
}
}
-static void *psb_bo_from_handle(struct drm_device *dev,
- struct drm_file *file_priv,
- unsigned int handle)
-{
- void *psKernelMemInfo = NULL;
- void * hKernelMemInfo = (void *)handle;
- int ret;
-
- ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
- if (ret) {
- DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
- (u32)hKernelMemInfo);
- return NULL;
- }
-
- return (void *)psKernelMemInfo;
-}
-
-static size_t psb_bo_size(struct drm_device *dev, void *bof)
-{
-#if 0
- void *psKernelMemInfo = (void *)bof;
- return (size_t)psKernelMemInfo->ui32AllocSize;
-#else
- return 0;
-#endif
-}
-
-static size_t psb_bo_offset(struct drm_device *dev, void *bof)
-{
- struct psb_framebuffer *psbfb
- = (struct psb_framebuffer *)bof;
-
- return (size_t)psbfb->offset;
-}
-
-static int psb_bo_pin_for_scanout(struct drm_device *dev, void *bo)
-{
- return 0;
-}
-
-static int psb_bo_unpin_for_scanout(struct drm_device *dev, void *bo)
-{
- return 0;
-}
-
void psb_modeset_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv =
@@ -797,12 +788,6 @@ void psb_modeset_init(struct drm_device *dev)
int i;
PSB_DEBUG_ENTRY("\n");
- /* Init mm functions */
- mode_dev->bo_from_handle = psb_bo_from_handle;
- mode_dev->bo_size = psb_bo_size;
- mode_dev->bo_offset = psb_bo_offset;
- mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout;
- mode_dev->bo_unpin_for_scanout = psb_bo_unpin_for_scanout;
drm_mode_config_init(dev);
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index b4fab9262db5..c8ec0d6febb1 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -28,32 +28,22 @@
#include "psb_drv.h"
-/*IMG Headers*/
-/*#include "servicesint.h"*/
-
struct psb_framebuffer {
struct drm_framebuffer base;
struct address_space *addr_space;
- struct ttm_buffer_object *bo;
- struct fb_info * fbdev;
- /* struct ttm_bo_kmap_obj kmap; */
- void *pvrBO; /* FIXME: sort this out */
- void * hKernelMemInfo;
- uint32_t size;
- uint32_t offset;
+ struct fb_info *fbdev;
+ struct gtt_range *gtt;
};
struct psb_fbdev {
struct drm_fb_helper psb_fb_helper;
- struct psb_framebuffer * pfb;
+ struct psb_framebuffer *pfb;
};
#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
-
extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
-
#endif
diff --git a/drivers/staging/gma500/psb_fence.c b/drivers/staging/gma500/psb_fence.c
deleted file mode 100644
index a70aa64f2cad..000000000000
--- a/drivers/staging/gma500/psb_fence.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-
-static void psb_fence_poll(struct ttm_fence_device *fdev,
- uint32_t fence_class, uint32_t waiting_types)
-{
- struct drm_psb_private *dev_priv =
- container_of(fdev, struct drm_psb_private, fdev);
-
-
- if (unlikely(!dev_priv))
- return;
-
- if (waiting_types == 0)
- return;
-
- /* DRM_ERROR("Polling fence sequence, got 0x%08x\n", sequence); */
- ttm_fence_handler(fdev, fence_class, 0 /* Sequence */,
- _PSB_FENCE_TYPE_EXE, 0);
-}
-
-void psb_fence_error(struct drm_device *dev,
- uint32_t fence_class,
- uint32_t sequence, uint32_t type, int error)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct ttm_fence_device *fdev = &dev_priv->fdev;
- unsigned long irq_flags;
- struct ttm_fence_class_manager *fc =
- &fdev->fence_class[fence_class];
-
- BUG_ON(fence_class >= PSB_NUM_ENGINES);
- write_lock_irqsave(&fc->lock, irq_flags);
- ttm_fence_handler(fdev, fence_class, sequence, type, error);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t flags, uint32_t *sequence,
- unsigned long *timeout_jiffies)
-{
- struct drm_psb_private *dev_priv =
- container_of(fdev, struct drm_psb_private, fdev);
-
- if (!dev_priv)
- return -EINVAL;
-
- if (fence_class >= PSB_NUM_ENGINES)
- return -EINVAL;
-
- DRM_ERROR("Unexpected fence class\n");
- return -EINVAL;
-}
-
-static void psb_fence_lockup(struct ttm_fence_object *fence,
- uint32_t fence_types)
-{
- DRM_ERROR("Unsupported fence class\n");
-}
-
-void psb_fence_handler(struct drm_device *dev, uint32_t fence_class)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct ttm_fence_device *fdev = &dev_priv->fdev;
- struct ttm_fence_class_manager *fc =
- &fdev->fence_class[fence_class];
- unsigned long irq_flags;
-
- write_lock_irqsave(&fc->lock, irq_flags);
- psb_fence_poll(fdev, fence_class, fc->waiting_types);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-
-static struct ttm_fence_driver psb_ttm_fence_driver = {
- .has_irq = NULL,
- .emit = psb_fence_emit_sequence,
- .flush = NULL,
- .poll = psb_fence_poll,
- .needed_flush = NULL,
- .wait = NULL,
- .signaled = NULL,
- .lockup = psb_fence_lockup,
-};
-
-int psb_ttm_fence_device_init(struct ttm_fence_device *fdev)
-{
- struct drm_psb_private *dev_priv =
- container_of(fdev, struct drm_psb_private, fdev);
- struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30),
- .flush_diff = (1 << 29),
- .sequence_mask = 0xFFFFFFFF
- };
-
- return ttm_fence_device_init(PSB_NUM_ENGINES,
- dev_priv->mem_global_ref.object,
- fdev, &fci, 1,
- &psb_ttm_fence_driver);
-}
diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
new file mode 100644
index 000000000000..76ff7bacd35b
--- /dev/null
+++ b/drivers/staging/gma500/psb_gem.c
@@ -0,0 +1,320 @@
+/*
+ * psb GEM interface
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Authors: Alan Cox
+ *
+ * TODO:
+ * - we don't actually put GEM objects into the GART yet
+ * - we need to work out if the MMU is relevant as well (eg for
+ * accelerated operations on a GEM object)
+ * - cache coherency
+ *
+ * ie this is just an initial framework to get us going.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+
+int psb_gem_init_object(struct drm_gem_object *obj)
+{
+ return -EINVAL;
+}
+
+void psb_gem_free_object(struct drm_gem_object *obj)
+{
+ struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
+ psb_gtt_free_range(obj->dev, gtt);
+ if (obj->map_list.map) {
+ /* Do things GEM should do for us */
+ struct drm_gem_mm *mm = obj->dev->mm_private;
+ struct drm_map_list *list = &obj->map_list;
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+ drm_mm_put_block(list->file_offset_node);
+ kfree(list->map);
+ list->map = NULL;
+ }
+ drm_gem_object_release(obj);
+}
+
+int psb_gem_get_aperture(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ return -EINVAL;
+}
+
+/**
+ * psb_gem_create_mmap_offset - invent an mmap offset
+ * @obj: our object
+ *
+ * This is basically doing by hand a pile of ugly crap which should
+ * be done automatically by the GEM library code but isn't
+ */
+static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+ struct drm_local_map *map;
+ int ret;
+
+ list = &obj->map_list;
+ list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
+ if (list->map == NULL)
+ return -ENOMEM;
+ map = list->map;
+ map->type = _DRM_GEM;
+ map->size = obj->size;
+ map->handle =obj;
+
+ list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
+ obj->size / PAGE_SIZE, 0, 0);
+ if (!list->file_offset_node) {
+ DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
+ ret = -ENOSPC;
+ goto free_it;
+ }
+ list->file_offset_node = drm_mm_get_block(list->file_offset_node,
+ obj->size / PAGE_SIZE, 0);
+ if (!list->file_offset_node) {
+ ret = -ENOMEM;
+ goto free_it;
+ }
+ list->hash.key = list->file_offset_node->start;
+ ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
+ if (ret) {
+ DRM_ERROR("failed to add to map hash\n");
+ goto free_mm;
+ }
+ return 0;
+
+free_mm:
+ drm_mm_put_block(list->file_offset_node);
+free_it:
+ kfree(list->map);
+ list->map = NULL;
+ return ret;
+}
+
+/**
+ * psb_gem_dumb_map_gtt - buffer mapping for dumb interface
+ * @file: our drm client file
+ * @dev: drm device
+ * @handle: GEM handle to the object (from dumb_create)
+ *
+ * Do the necessary setup to allow the mapping of the frame buffer
+ * into user memory. We don't have to do much here at the moment.
+ */
+int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
+ uint32_t handle, uint64_t *offset)
+{
+ int ret = 0;
+ struct drm_gem_object *obj;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ mutex_lock(&dev->struct_mutex);
+
+ /* GEM does all our handle to object mapping */
+ obj = drm_gem_object_lookup(dev, file, handle);
+ if (obj == NULL) {
+ ret = -ENOENT;
+ goto unlock;
+ }
+ /* What validation is needed here ? */
+
+ /* Make it mmapable */
+ if (!obj->map_list.map) {
+ ret = psb_gem_create_mmap_offset(obj);
+ if (ret)
+ goto out;
+ }
+ /* GEM should really work out the hash offsets for us */
+ *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
+out:
+ drm_gem_object_unreference(obj);
+unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+/**
+ * psb_gem_create - create a mappable object
+ * @file: the DRM file of the client
+ * @dev: our device
+ * @size: the size requested
+ * @handlep: returned handle (opaque number)
+ *
+ * Create a GEM object, fill in the boilerplate and attach a handle to
+ * it so that userspace can speak about it. This does the core work
+ * for the various methods that do/will create GEM objects for things
+ */
+static int psb_gem_create(struct drm_file *file,
+ struct drm_device *dev, uint64_t size, uint32_t *handlep)
+{
+ struct gtt_range *r;
+ int ret;
+ u32 handle;
+
+ size = roundup(size, PAGE_SIZE);
+
+ /* Allocate our object - for now a direct gtt range which is not
+ stolen memory backed */
+ r = psb_gtt_alloc_range(dev, size, "gem", 0);
+ if (r == NULL)
+ return -ENOSPC;
+ /* Initialize the extra goodies GEM needs to do all the hard work */
+ if (drm_gem_object_init(dev, &r->gem, size) != 0) {
+ psb_gtt_free_range(dev, r);
+ /* GEM doesn't give an error code and we don't have an
+ EGEMSUCKS so make something up for now - FIXME */
+ return -ENOMEM;
+ }
+ /* Give the object a handle so we can carry it more easily */
+ ret = drm_gem_handle_create(file, &r->gem, &handle);
+ if (ret) {
+ drm_gem_object_release(&r->gem);
+ psb_gtt_free_range(dev, r);
+ return ret;
+ }
+ /* We have the initial and handle reference but need only one now */
+ drm_gem_object_unreference(&r->gem);
+ *handlep = handle;
+ return 0;
+}
+
+/**
+ * psb_gem_dumb_create - create a dumb buffer
+ * @drm_file: our client file
+ * @dev: our device
+ * @args: the requested arguments copied from userspace
+ *
+ * Allocate a buffer suitable for use for a frame buffer of the
+ * form described by user space. Give userspace a handle by which
+ * to reference it.
+ */
+int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+ struct drm_mode_create_dumb *args)
+{
+ args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
+ args->size = args->pitch * args->height;
+ return psb_gem_create(file, dev, args->size, &args->handle);
+}
+
+/**
+ * psb_gem_dumb_destroy - destroy a dumb buffer
+ * @file: client file
+ * @dev: our DRM device
+ * @handle: the object handle
+ *
+ * Destroy a handle that was created via psb_gem_dumb_create, at least
+ * we hope it was created that way. i915 seems to assume the caller
+ * does the checking but that might be worth review ! FIXME
+ */
+int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+ uint32_t handle)
+{
+ /* No special work needed, drop the reference and see what falls out */
+ return drm_gem_handle_delete(file, handle);
+}
+
+/**
+ * psb_gem_fault - pagefault handler for GEM objects
+ * @vma: the VMA of the GEM object
+ * @vmf: fault detail
+ *
+ * Invoked when a fault occurs on an mmap of a GEM managed area. GEM
+ * does most of the work for us including the actual map/unmap calls
+ * but we need to do the actual page work.
+ *
+ * This code eventually needs to handle faulting objects in and out
+ * of the GART and repacking it when we run out of space. We can put
+ * that off for now and for our simple uses
+ *
+ * The VMA was set up by GEM. In doing so it also ensured that the
+ * vma->vm_private_data points to the GEM object that is backing this
+ * mapping.
+ *
+ * To avoid aliasing and cache funnies we want to map the object
+ * through the GART. For the moment this is slightly hackish. It would
+ * be nicer if GEM provided mmap opened/closed hooks for us giving
+ * the object so that we could track things nicely. That needs changes
+ * to the core GEM code so must be tackled post staging
+ *
+ * FIXME
+ */
+int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct drm_gem_object *obj;
+ struct gtt_range *r;
+ int ret;
+ unsigned long pfn;
+ pgoff_t page_offset;
+ struct drm_device *dev;
+
+ obj = vma->vm_private_data; /* GEM object */
+ dev = obj->dev;
+
+ r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */
+
+ /* Make sure we don't parallel update on a fault, nor move or remove
+ something from beneath our feet */
+ mutex_lock(&dev->struct_mutex);
+
+ /* For now the mmap pins the object and it stays pinned. As things
+ stand that will do us no harm */
+ if (r->mmapping == 0) {
+ ret = psb_gtt_pin(r);
+ if (ret < 0) {
+ DRM_ERROR("gma500: pin failed: %d\n", ret);
+ goto fail;
+ }
+ r->mmapping = 1;
+ }
+
+ /* FIXME: Locking. We may also need to repack the GART sometimes */
+
+ /* Page relative to the VMA start */
+ page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
+ >> PAGE_SHIFT;
+
+ /* Bus address of the page is gart + object offset + page offset */
+ /* Assumes gtt allocations are page aligned */
+ pfn = (r->resource.start >> PAGE_SHIFT) + page_offset;
+
+ pr_debug("Object GTT base at %p\n", (void *)(r->resource.start));
+ pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address,
+ pfn, pfn << PAGE_SHIFT);
+
+ ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
+
+fail:
+ mutex_unlock(&dev->struct_mutex);
+ switch (ret) {
+ case 0:
+ case -ERESTARTSYS:
+ case -EINTR:
+ return VM_FAULT_NOPAGE;
+ case -ENOMEM:
+ return VM_FAULT_OOM;
+ default:
+ return VM_FAULT_SIGBUS;
+ }
+}
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 53c1e1ed3bd2..74c5a6569d08 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -16,12 +16,24 @@
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ * Alan Cox <alan@linux.intel.com>
*/
#include <drm/drmP.h>
#include "psb_drv.h"
-#include "psb_pvr_glue.h"
+
+/*
+ * GTT resource allocator - manage page mappings in GTT space
+ */
+
+/**
+ * psb_gtt_mask_pte - generate GART pte entry
+ * @pfn: page number to encode
+ * @type: type of memory in the GART
+ *
+ * Set the GART entry for the appropriate memory type.
+ */
static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
{
uint32_t mask = PSB_PTE_VALID;
@@ -36,6 +48,327 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
return (pfn << PAGE_SHIFT) | mask;
}
+/**
+ * psb_gtt_entry - find the GART entries for a gtt_range
+ * @dev: our DRM device
+ * @r: our GTT range
+ *
+ * Given a gtt_range object return the GART offset of the page table
+ * entries for this gtt_range
+ */
+u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ unsigned long offset;
+
+ offset = r->resource.start - dev_priv->gtt_mem->start;
+
+ return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
+}
+
+/**
+ * psb_gtt_insert - put an object into the GART
+ * @dev: our DRM device
+ * @r: our GTT range
+ *
+ * Take our preallocated GTT range and insert the GEM object into
+ * the GART.
+ *
+ * FIXME: gtt lock ?
+ */
+static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 *gtt_slot, pte;
+ int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
+ struct page **pages;
+ int i;
+
+ if (r->pages == NULL) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ WARN_ON(r->stolen); /* refcount these maybe ? */
+
+ gtt_slot = psb_gtt_entry(dev, r);
+ pages = r->pages;
+
+ /* Make sure we have no alias present */
+ wbinvd();
+
+ /* Write our page entries into the GART itself */
+ for (i = 0; i < numpages; i++) {
+ pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
+ iowrite32(pte, gtt_slot++);
+ }
+ /* Make sure all the entries are set before we return */
+ ioread32(gtt_slot - 1);
+
+ return 0;
+}
+
+/**
+ * psb_gtt_remove - remove an object from the GART
+ * @dev: our DRM device
+ * @r: our GTT range
+ *
+ * Remove a preallocated GTT range from the GART. Overwrite all the
+ * page table entries with the dummy page
+ */
+
+static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 *gtt_slot, pte;
+ int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
+ int i;
+
+ WARN_ON(r->stolen);
+
+ gtt_slot = psb_gtt_entry(dev, r);
+ pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
+
+ for (i = 0; i < numpages; i++)
+ iowrite32(pte, gtt_slot++);
+ ioread32(gtt_slot - 1);
+}
+
+/**
+ * psb_gtt_attach_pages - attach and pin GEM pages
+ * @gt: the gtt range
+ *
+ * Pin and build an in kernel list of the pages that back our GEM object.
+ * While we hold this the pages cannot be swapped out
+ *
+ * FIXME: Do we need to cache flush when we update the GTT
+ */
+static int psb_gtt_attach_pages(struct gtt_range *gt)
+{
+ struct inode *inode;
+ struct address_space *mapping;
+ int i;
+ struct page *p;
+ int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
+
+ WARN_ON(gt->pages);
+
+ /* This is the shared memory object that backs the GEM resource */
+ inode = gt->gem.filp->f_path.dentry->d_inode;
+ mapping = inode->i_mapping;
+
+ gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
+ if (gt->pages == NULL)
+ return -ENOMEM;
+ for (i = 0; i < pages; i++) {
+ /* FIXME: review flags later */
+ p = read_cache_page_gfp(mapping, i,
+ __GFP_COLD | GFP_KERNEL);
+ if (IS_ERR(p))
+ goto err;
+ gt->pages[i] = p;
+ }
+ return 0;
+
+err:
+ while (i--)
+ page_cache_release(gt->pages[i]);
+ kfree(gt->pages);
+ gt->pages = NULL;
+ return PTR_ERR(p);
+}
+
+/**
+ * psb_gtt_detach_pages - attach and pin GEM pages
+ * @gt: the gtt range
+ *
+ * Undo the effect of psb_gtt_attach_pages. At this point the pages
+ * must have been removed from the GART as they could now be paged out
+ * and move bus address.
+ *
+ * FIXME: Do we need to cache flush when we update the GTT
+ */
+static void psb_gtt_detach_pages(struct gtt_range *gt)
+{
+ int i;
+ int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
+
+ for (i = 0; i < pages; i++) {
+ /* FIXME: do we need to force dirty */
+ set_page_dirty(gt->pages[i]);
+ /* Undo the reference we took when populating the table */
+ page_cache_release(gt->pages[i]);
+ }
+ kfree(gt->pages);
+ gt->pages = NULL;
+}
+
+/**
+ * psb_gtt_pin - pin pages into the GTT
+ * @gt: range to pin
+ *
+ * Pin a set of pages into the GTT. The pins are refcounted so that
+ * multiple pins need multiple unpins to undo.
+ *
+ * Non GEM backed objects treat this as a no-op as they are always GTT
+ * backed objects.
+ */
+int psb_gtt_pin(struct gtt_range *gt)
+{
+ int ret;
+ struct drm_device *dev = gt->gem.dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->gtt_mutex);
+
+ if (gt->in_gart == 0 && gt->stolen == 0) {
+ ret = psb_gtt_attach_pages(gt);
+ if (ret < 0)
+ goto out;
+ ret = psb_gtt_insert(dev, gt);
+ if (ret < 0) {
+ psb_gtt_detach_pages(gt);
+ goto out;
+ }
+ }
+ gt->in_gart++;
+out:
+ mutex_unlock(&dev_priv->gtt_mutex);
+ return ret;
+}
+
+/**
+ * psb_gtt_unpin - Drop a GTT pin requirement
+ * @gt: range to pin
+ *
+ * Undoes the effect of psb_gtt_pin. On the last drop the GEM object
+ * will be removed from the GTT which will also drop the page references
+ * and allow the VM to clean up or page stuff.
+ *
+ * Non GEM backed objects treat this as a no-op as they are always GTT
+ * backed objects.
+ */
+void psb_gtt_unpin(struct gtt_range *gt)
+{
+ struct drm_device *dev = gt->gem.dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->gtt_mutex);
+
+ WARN_ON(!gt->in_gart);
+
+ gt->in_gart--;
+ if (gt->in_gart == 0 && gt->stolen == 0) {
+ psb_gtt_remove(dev, gt);
+ psb_gtt_detach_pages(gt);
+ }
+ mutex_unlock(&dev_priv->gtt_mutex);
+}
+
+/*
+ * GTT resource allocator - allocate and manage GTT address space
+ */
+
+/**
+ * psb_gtt_alloc_range - allocate GTT address space
+ * @dev: Our DRM device
+ * @len: length (bytes) of address space required
+ * @name: resource name
+ * @backed: resource should be backed by stolen pages
+ *
+ * Ask the kernel core to find us a suitable range of addresses
+ * to use for a GTT mapping.
+ *
+ * Returns a gtt_range structure describing the object, or NULL on
+ * error. On successful return the resource is both allocated and marked
+ * as in use.
+ */
+struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
+ const char *name, int backed)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct gtt_range *gt;
+ struct resource *r = dev_priv->gtt_mem;
+ int ret;
+ unsigned long start, end;
+
+ if (backed) {
+ /* The start of the GTT is the stolen pages */
+ start = r->start;
+ end = r->start + dev_priv->pg->stolen_size - 1;
+ } else {
+ /* The rest we will use for GEM backed objects */
+ start = r->start + dev_priv->pg->stolen_size;
+ end = r->end;
+ }
+
+ gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
+ if (gt == NULL)
+ return NULL;
+ gt->resource.name = name;
+ gt->stolen = backed;
+ gt->in_gart = backed;
+ /* Ensure this is set for non GEM objects */
+ gt->gem.dev = dev;
+ kref_init(&gt->kref);
+
+ ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
+ len, start, end, PAGE_SIZE, NULL, NULL);
+ if (ret == 0) {
+ gt->offset = gt->resource.start - r->start;
+ return gt;
+ }
+ kfree(gt);
+ return NULL;
+}
+
+/**
+ * psb_gtt_destroy - final free up of a gtt
+ * @kref: the kref of the gtt
+ *
+ * Called from the kernel kref put when the final reference to our
+ * GTT object is dropped. At that point we can free up the resources.
+ *
+ * For now we handle mmap clean up here to work around limits in GEM
+ */
+static void psb_gtt_destroy(struct kref *kref)
+{
+ struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
+
+ /* Undo the mmap pin if we are destroying the object */
+ if (gt->mmapping) {
+ psb_gtt_unpin(gt);
+ gt->mmapping = 0;
+ }
+ WARN_ON(gt->in_gart && !gt->stolen);
+ release_resource(&gt->resource);
+ kfree(gt);
+}
+
+/**
+ * psb_gtt_kref_put - drop reference to a GTT object
+ * @gt: the GT being dropped
+ *
+ * Drop a reference to a psb gtt
+ */
+void psb_gtt_kref_put(struct gtt_range *gt)
+{
+ kref_put(&gt->kref, psb_gtt_destroy);
+}
+
+/**
+ * psb_gtt_free_range - release GTT address space
+ * @dev: our DRM device
+ * @gt: a mapping created with psb_gtt_alloc_range
+ *
+ * Release a resource that was allocated with psb_gtt_alloc_range
+ */
+void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
+{
+ psb_gtt_kref_put(gt);
+}
+
+
struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
{
struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
@@ -49,98 +382,89 @@ struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
return tmp;
}
-void psb_gtt_takedown(struct psb_gtt *pg, int free)
+void psb_gtt_takedown(struct drm_device *dev)
{
- struct drm_psb_private *dev_priv = pg->dev->dev_private;
-
- if (!pg)
- return;
+ struct drm_psb_private *dev_priv = dev->dev_private;
- if (pg->gtt_map) {
- iounmap(pg->gtt_map);
- pg->gtt_map = NULL;
+ /* FIXME: iounmap dev_priv->vram_addr etc */
+ if (dev_priv->gtt_map) {
+ iounmap(dev_priv->gtt_map);
+ dev_priv->gtt_map = NULL;
}
- if (pg->initialized) {
- pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
- pg->gmch_ctrl);
- PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
+ if (dev_priv->gtt_initialized) {
+ pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
+ dev_priv->gmch_ctrl);
+ PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void) PSB_RVDC32(PSB_PGETBL_CTL);
}
- if (free)
- kfree(pg);
+ kfree(dev_priv->pg);
+ dev_priv->pg = NULL;
}
-int psb_gtt_init(struct psb_gtt *pg, int resume)
+int psb_gtt_init(struct drm_device *dev, int resume)
{
- struct drm_device *dev = pg->dev;
struct drm_psb_private *dev_priv = dev->dev_private;
unsigned gtt_pages;
- unsigned long stolen_size, vram_stolen_size, ci_stolen_size;
- unsigned long rar_stolen_size;
+ unsigned long stolen_size, vram_stolen_size;
unsigned i, num_pages;
unsigned pfn_base;
- uint32_t ci_pages, vram_pages;
+ uint32_t vram_pages;
uint32_t tt_pages;
uint32_t *ttm_gtt_map;
uint32_t dvmt_mode = 0;
+ struct psb_gtt *pg;
int ret = 0;
uint32_t pte;
- pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
+ mutex_init(&dev_priv->gtt_mutex);
+
+ dev_priv->pg = pg = psb_gtt_alloc(dev);
+ if (pg == NULL)
+ return -ENOMEM;
+
+ pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
- pg->gmch_ctrl | _PSB_GMCH_ENABLED);
+ dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
- pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
- PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+ dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
+ PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
(void) PSB_RVDC32(PSB_PGETBL_CTL);
- pg->initialized = 1;
+ /* The root resource we allocate address space from */
+ dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
- pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK;
+ dev_priv->gtt_initialized = 1;
+
+ pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
/* fix me: video mmu has hw bug to access 0x0D0000000,
* then make gatt start at 0x0e000,0000 */
- pg->mmu_gatt_start = PSB_MEM_TT_START;
+ pg->mmu_gatt_start = 0xE0000000;
pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
gtt_pages =
pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
>> PAGE_SHIFT;
- pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
- vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
+ pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
+ vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
- /* CI is not included in the stolen size since the TOPAZ MMU bug */
- ci_stolen_size = dev_priv->ci_region_size;
- /* Don't add CI & RAR share buffer space
- * managed by TTM to stolen_size */
stolen_size = vram_stolen_size;
- rar_stolen_size = dev_priv->rar_region_size;
-
printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
pg->gatt_start, pg->gatt_pages/256);
printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
- printk(KERN_INFO "Stole memory information\n");
- printk(KERN_INFO " base in RAM: 0x%x\n", pg->stolen_base);
- printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
+ printk(KERN_INFO "Stolen memory information\n");
+ printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base);
+ printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
vram_stolen_size/1024);
- dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7;
+ dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n",
(dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
- if (ci_stolen_size > 0)
- printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n",
- dev_priv->ci_region_start,
- ci_stolen_size / 1024 / 1024);
- if (rar_stolen_size > 0)
- printk(KERN_INFO "RAR Stole memory: RAM base = 0x%08x, size = %lu M\n",
- dev_priv->rar_region_start,
- rar_stolen_size / 1024 / 1024);
-
if (resume && (gtt_pages != pg->gtt_pages) &&
(stolen_size != pg->stolen_size)) {
DRM_ERROR("GTT resume error.\n");
@@ -150,42 +474,40 @@ int psb_gtt_init(struct psb_gtt *pg, int resume)
pg->gtt_pages = gtt_pages;
pg->stolen_size = stolen_size;
- pg->vram_stolen_size = vram_stolen_size;
- pg->ci_stolen_size = ci_stolen_size;
- pg->rar_stolen_size = rar_stolen_size;
- pg->gtt_map =
+ dev_priv->vram_stolen_size = vram_stolen_size;
+ dev_priv->gtt_map =
ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
- if (!pg->gtt_map) {
+ if (!dev_priv->gtt_map) {
DRM_ERROR("Failure to map gtt.\n");
ret = -ENOMEM;
goto out_err;
}
- pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size);
- if (!pg->vram_addr) {
+ dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
+ if (!dev_priv->vram_addr) {
DRM_ERROR("Failure to map stolen base.\n");
ret = -ENOMEM;
goto out_err;
}
- DRM_DEBUG("%s: vram kernel virtual address %p\n", pg->vram_addr);
+ DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr);
tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
- ttm_gtt_map = pg->gtt_map + tt_pages / 2;
+ ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2;
/*
* insert vram stolen pages.
*/
- pfn_base = pg->stolen_base >> PAGE_SHIFT;
+ pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
num_pages, pfn_base, 0);
for (i = 0; i < num_pages; ++i) {
pte = psb_gtt_mask_pte(pfn_base + i, 0);
- iowrite32(pte, pg->gtt_map + i);
+ iowrite32(pte, dev_priv->gtt_map + i);
}
/*
@@ -194,36 +516,9 @@ int psb_gtt_init(struct psb_gtt *pg, int resume)
pfn_base = page_to_pfn(dev_priv->scratch_page);
pte = psb_gtt_mask_pte(pfn_base, 0);
for (; i < tt_pages / 2 - 1; ++i)
- iowrite32(pte, pg->gtt_map + i);
-
- /*
- * insert CI stolen pages
- */
-
- pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT;
- ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT;
- printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n",
- num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4);
- for (i = 0; i < num_pages; ++i) {
- pte = psb_gtt_mask_pte(pfn_base + i, 0);
- iowrite32(pte, ttm_gtt_map + i);
- }
+ iowrite32(pte, dev_priv->gtt_map + i);
/*
- * insert RAR stolen pages
- */
- if (rar_stolen_size != 0) {
- pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT;
- num_pages = rar_stolen_size >> PAGE_SHIFT;
- printk(KERN_INFO"Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n",
- num_pages, pfn_base,
- (ttm_gtt_map - pg->gtt_map + i) * 4);
- for (; i < num_pages + ci_pages; ++i) {
- pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0);
- iowrite32(pte, ttm_gtt_map + i);
- }
- }
- /*
* Init rest of gtt managed by TTM.
*/
@@ -234,801 +529,11 @@ int psb_gtt_init(struct psb_gtt *pg, int resume)
for (; i < pg->gatt_pages - tt_pages / 2; ++i)
iowrite32(pte, ttm_gtt_map + i);
- (void) ioread32(pg->gtt_map + i - 1);
+ (void) ioread32(dev_priv->gtt_map + i - 1);
return 0;
out_err:
- psb_gtt_takedown(pg, 0);
- return ret;
-}
-
-int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
- unsigned offset_pages, unsigned num_pages,
- unsigned desired_tile_stride,
- unsigned hw_tile_stride, int type)
-{
- unsigned rows = 1;
- unsigned add;
- unsigned row_add;
- unsigned i;
- unsigned j;
- uint32_t *cur_page = NULL;
- uint32_t pte;
-
- if (hw_tile_stride)
- rows = num_pages / desired_tile_stride;
- else
- desired_tile_stride = num_pages;
-
- add = desired_tile_stride;
- row_add = hw_tile_stride;
-
- down_read(&pg->sem);
- for (i = 0; i < rows; ++i) {
- cur_page = pg->gtt_map + offset_pages;
- for (j = 0; j < desired_tile_stride; ++j) {
- pte =
- psb_gtt_mask_pte(page_to_pfn(*pages++), type);
- iowrite32(pte, cur_page++);
- }
- offset_pages += add;
- }
- (void) ioread32(cur_page - 1);
- up_read(&pg->sem);
-
- return 0;
-}
-
-int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, dma_addr_t *pPhysFrames,
- unsigned offset_pages, unsigned num_pages, int type)
-{
- unsigned j;
- uint32_t *cur_page = NULL;
- uint32_t pte;
- u32 ba;
-
- down_read(&pg->sem);
- cur_page = pg->gtt_map + offset_pages;
- for (j = 0; j < num_pages; ++j) {
- ba = *pPhysFrames++;
- pte = psb_gtt_mask_pte(ba >> PAGE_SHIFT, type);
- iowrite32(pte, cur_page++);
- }
- (void) ioread32(cur_page - 1);
- up_read(&pg->sem);
- return 0;
-}
-
-int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
- unsigned num_pages, unsigned desired_tile_stride,
- unsigned hw_tile_stride, int rc_prot)
-{
- struct drm_psb_private *dev_priv = pg->dev->dev_private;
- unsigned rows = 1;
- unsigned add;
- unsigned row_add;
- unsigned i;
- unsigned j;
- uint32_t *cur_page = NULL;
- unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
- uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
-
- if (hw_tile_stride)
- rows = num_pages / desired_tile_stride;
- else
- desired_tile_stride = num_pages;
-
- add = desired_tile_stride;
- row_add = hw_tile_stride;
-
- if (rc_prot)
- down_read(&pg->sem);
- for (i = 0; i < rows; ++i) {
- cur_page = pg->gtt_map + offset_pages;
- for (j = 0; j < desired_tile_stride; ++j)
- iowrite32(pte, cur_page++);
-
- offset_pages += add;
- }
- (void) ioread32(cur_page - 1);
- if (rc_prot)
- up_read(&pg->sem);
-
- return 0;
-}
-
-int psb_gtt_mm_init(struct psb_gtt *pg)
-{
- struct psb_gtt_mm *gtt_mm;
- struct drm_psb_private *dev_priv = pg->dev->dev_private;
- struct drm_open_hash *ht;
- struct drm_mm *mm;
- int ret;
- uint32_t tt_start;
- uint32_t tt_size;
-
- if (!pg || !pg->initialized) {
- DRM_DEBUG("Invalid gtt struct\n");
- return -EINVAL;
- }
-
- gtt_mm = kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL);
- if (!gtt_mm)
- return -ENOMEM;
-
- spin_lock_init(&gtt_mm->lock);
-
- ht = &gtt_mm->hash;
- ret = drm_ht_create(ht, 20);
- if (ret) {
- DRM_DEBUG("Create hash table failed(%d)\n", ret);
- goto err_free;
- }
-
- tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages;
- tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
- (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
- mm = &gtt_mm->base;
-
- /*will use tt_start ~ 128M for IMG TT buffers*/
- ret = drm_mm_init(mm, tt_start, ((tt_size / 2) - tt_start));
- if (ret) {
- DRM_DEBUG("drm_mm_int error(%d)\n", ret);
- goto err_mm_init;
- }
-
- gtt_mm->count = 0;
-
- dev_priv->gtt_mm = gtt_mm;
-
- DRM_INFO("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n",
- (unsigned long)tt_start,
- (unsigned long)((tt_size / 2) - tt_start));
- return 0;
-err_mm_init:
- drm_ht_remove(ht);
-
-err_free:
- kfree(gtt_mm);
+ psb_gtt_takedown(dev);
return ret;
}
-
-/**
- * Delete all hash entries;
- */
-void psb_gtt_mm_takedown(void)
-{
- return;
-}
-
-static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm,
- u32 tgid,
- struct psb_gtt_hash_entry **hentry)
-{
- struct drm_hash_item *entry;
- struct psb_gtt_hash_entry *psb_entry;
- int ret;
-
- ret = drm_ht_find_item(&mm->hash, tgid, &entry);
- if (ret) {
- DRM_DEBUG("Cannot find entry pid=%ld\n", tgid);
- return ret;
- }
-
- psb_entry = container_of(entry, struct psb_gtt_hash_entry, item);
- if (!psb_entry) {
- DRM_DEBUG("Invalid entry");
- return -EINVAL;
- }
-
- *hentry = psb_entry;
- return 0;
-}
-
-
-static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm,
- u32 tgid,
- struct psb_gtt_hash_entry *hentry)
-{
- struct drm_hash_item *item;
- int ret;
-
- if (!hentry) {
- DRM_DEBUG("Invalid parameters\n");
- return -EINVAL;
- }
-
- item = &hentry->item;
- item->key = tgid;
-
- /**
- * NOTE: drm_ht_insert_item will perform such a check
- ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp);
- if (!ret) {
- DRM_DEBUG("Entry already exists for pid %ld\n", tgid);
- return -EAGAIN;
- }
- */
-
- /*Insert the given entry*/
- ret = drm_ht_insert_item(&mm->hash, item);
- if (ret) {
- DRM_DEBUG("Insert failure\n");
- return ret;
- }
-
- mm->count++;
-
- return 0;
-}
-
-static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm,
- u32 tgid,
- struct psb_gtt_hash_entry **entry)
-{
- struct psb_gtt_hash_entry *hentry;
- int ret;
-
- /*if the hentry for this tgid exists, just get it and return*/
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
- if (!ret) {
- DRM_DEBUG("Entry for tgid %ld exist, hentry %p\n",
- tgid, hentry);
- *entry = hentry;
- spin_unlock(&mm->lock);
- return 0;
- }
- spin_unlock(&mm->lock);
-
- DRM_DEBUG("Entry for tgid %ld doesn't exist, will create it\n", tgid);
-
- hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL);
- if (!hentry) {
- DRM_DEBUG("Kmalloc failled\n");
- return -ENOMEM;
- }
-
- ret = drm_ht_create(&hentry->ht, 20);
- if (ret) {
- DRM_DEBUG("Create hash table failed\n");
- return ret;
- }
-
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry);
- spin_unlock(&mm->lock);
-
- if (!ret)
- *entry = hentry;
-
- return ret;
-}
-
-static struct psb_gtt_hash_entry *
-psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
-{
- struct psb_gtt_hash_entry *tmp;
- int ret;
-
- ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp);
- if (ret) {
- DRM_DEBUG("Cannot find entry pid %ld\n", tgid);
- return NULL;
- }
-
- /*remove it from ht*/
- drm_ht_remove_item(&mm->hash, &tmp->item);
-
- mm->count--;
-
- return tmp;
-}
-
-static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
-{
- struct psb_gtt_hash_entry *entry;
-
- entry = psb_gtt_mm_remove_ht_locked(mm, tgid);
-
- if (!entry) {
- DRM_DEBUG("Invalid entry");
- return -EINVAL;
- }
-
- /*delete ht*/
- drm_ht_remove(&entry->ht);
-
- /*free this entry*/
- kfree(entry);
- return 0;
-}
-
-static int
-psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht,
- u32 key,
- struct psb_gtt_mem_mapping **hentry)
-{
- struct drm_hash_item *entry;
- struct psb_gtt_mem_mapping *mapping;
- int ret;
-
- ret = drm_ht_find_item(ht, key, &entry);
- if (ret) {
- DRM_DEBUG("Cannot find key %ld\n", key);
- return ret;
- }
-
- mapping = container_of(entry, struct psb_gtt_mem_mapping, item);
- if (!mapping) {
- DRM_DEBUG("Invalid entry\n");
- return -EINVAL;
- }
-
- *hentry = mapping;
- return 0;
-}
-
-static int
-psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht,
- u32 key,
- struct psb_gtt_mem_mapping *hentry)
-{
- struct drm_hash_item *item;
- struct psb_gtt_hash_entry *entry;
- int ret;
-
- if (!hentry) {
- DRM_DEBUG("hentry is NULL\n");
- return -EINVAL;
- }
-
- item = &hentry->item;
- item->key = key;
-
- ret = drm_ht_insert_item(ht, item);
- if (ret) {
- DRM_DEBUG("insert_item failed\n");
- return ret;
- }
-
- entry = container_of(ht, struct psb_gtt_hash_entry, ht);
- if (entry)
- entry->count++;
-
- return 0;
-}
-
-static int
-psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm,
- struct drm_open_hash *ht,
- u32 key,
- struct drm_mm_node *node,
- struct psb_gtt_mem_mapping **entry)
-{
- struct psb_gtt_mem_mapping *mapping;
- int ret;
-
- if (!node || !ht) {
- DRM_DEBUG("parameter error\n");
- return -EINVAL;
- }
-
- /*try to get this mem_map */
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping);
- if (!ret) {
- DRM_DEBUG("mapping entry for key %ld exists, entry %p\n",
- key, mapping);
- *entry = mapping;
- spin_unlock(&mm->lock);
- return 0;
- }
- spin_unlock(&mm->lock);
-
- DRM_DEBUG("Mapping entry for key %ld doesn't exist, will create it\n",
- key);
-
- mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL);
- if (!mapping) {
- DRM_DEBUG("kmalloc failed\n");
- return -ENOMEM;
- }
-
- mapping->node = node;
-
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping);
- spin_unlock(&mm->lock);
-
- if (!ret)
- *entry = mapping;
-
- return ret;
-}
-
-static struct psb_gtt_mem_mapping *
-psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key)
-{
- struct psb_gtt_mem_mapping *tmp;
- struct psb_gtt_hash_entry *entry;
- int ret;
-
- ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp);
- if (ret) {
- DRM_DEBUG("Cannot find key %ld\n", key);
- return NULL;
- }
-
- drm_ht_remove_item(ht, &tmp->item);
-
- entry = container_of(ht, struct psb_gtt_hash_entry, ht);
- if (entry)
- entry->count--;
-
- return tmp;
-}
-
-static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht,
- u32 key,
- struct drm_mm_node **node)
-{
- struct psb_gtt_mem_mapping *entry;
-
- entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key);
- if (!entry) {
- DRM_DEBUG("entry is NULL\n");
- return -EINVAL;
- }
-
- *node = entry->node;
-
- kfree(entry);
- return 0;
-}
-
-static int psb_gtt_add_node(struct psb_gtt_mm *mm,
- u32 tgid,
- u32 key,
- struct drm_mm_node *node,
- struct psb_gtt_mem_mapping **entry)
-{
- struct psb_gtt_hash_entry *hentry;
- struct psb_gtt_mem_mapping *mapping;
- int ret;
-
- ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry);
- if (ret) {
- DRM_DEBUG("alloc_insert failed\n");
- return ret;
- }
-
- ret = psb_gtt_mm_alloc_insert_mem_mapping(mm,
- &hentry->ht,
- key,
- node,
- &mapping);
- if (ret) {
- DRM_DEBUG("mapping alloc_insert failed\n");
- return ret;
- }
-
- *entry = mapping;
-
- return 0;
-}
-
-static int psb_gtt_remove_node(struct psb_gtt_mm *mm,
- u32 tgid,
- u32 key,
- struct drm_mm_node **node)
-{
- struct psb_gtt_hash_entry *hentry;
- struct drm_mm_node *tmp;
- int ret;
-
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
- if (ret) {
- DRM_DEBUG("Cannot find entry for pid %ld\n", tgid);
- spin_unlock(&mm->lock);
- return ret;
- }
- spin_unlock(&mm->lock);
-
- /*remove mapping entry*/
- spin_lock(&mm->lock);
- ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht,
- key,
- &tmp);
- if (ret) {
- DRM_DEBUG("remove_free failed\n");
- spin_unlock(&mm->lock);
- return ret;
- }
-
- *node = tmp;
-
- /*check the count of mapping entry*/
- if (!hentry->count) {
- DRM_DEBUG("count of mapping entry is zero, tgid=%ld\n", tgid);
- psb_gtt_mm_remove_free_ht_locked(mm, tgid);
- }
-
- spin_unlock(&mm->lock);
-
- return 0;
-}
-
-static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm,
- uint32_t pages,
- uint32_t align,
- struct drm_mm_node **node)
-{
- struct drm_mm_node *tmp_node;
- int ret;
-
- do {
- ret = drm_mm_pre_get(&mm->base);
- if (unlikely(ret)) {
- DRM_DEBUG("drm_mm_pre_get error\n");
- return ret;
- }
-
- spin_lock(&mm->lock);
- tmp_node = drm_mm_search_free(&mm->base, pages, align, 1);
- if (unlikely(!tmp_node)) {
- DRM_DEBUG("No free node found\n");
- spin_unlock(&mm->lock);
- break;
- }
-
- tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align);
- spin_unlock(&mm->lock);
- } while (!tmp_node);
-
- if (!tmp_node) {
- DRM_DEBUG("Node allocation failed\n");
- return -ENOMEM;
- }
-
- *node = tmp_node;
- return 0;
-}
-
-static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node)
-{
- spin_lock(&mm->lock);
- drm_mm_put_block(node);
- spin_unlock(&mm->lock);
-}
-
-int psb_gtt_map_meminfo(struct drm_device *dev,
- void *hKernelMemInfo,
- uint32_t *offset)
-{
- return -EINVAL;
- /* FIXMEAC */
-#if 0
- struct drm_psb_private *dev_priv
- = (struct drm_psb_private *)dev->dev_private;
- void *psKernelMemInfo;
- struct psb_gtt_mm *mm = dev_priv->gtt_mm;
- struct psb_gtt *pg = dev_priv->pg;
- uint32_t size, pages, offset_pages;
- void *kmem;
- struct drm_mm_node *node;
- struct page **page_list;
- struct psb_gtt_mem_mapping *mapping = NULL;
- int ret;
-
- ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
- if (ret) {
- DRM_DEBUG("Cannot find kernelMemInfo handle %ld\n",
- hKernelMemInfo);
- return -EINVAL;
- }
-
- DRM_DEBUG("Got psKernelMemInfo %p for handle %lx\n",
- psKernelMemInfo, (u32)hKernelMemInfo);
- size = psKernelMemInfo->ui32AllocSize;
- kmem = psKernelMemInfo->pvLinAddrKM;
- pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- DRM_DEBUG("KerMemInfo size %ld, cpuVadr %lx, pages %ld, osMemHdl %lx\n",
- size, kmem, pages, psKernelMemInfo->sMemBlk.hOSMemHandle);
-
- if (!kmem)
- DRM_DEBUG("kmem is NULL");
-
- /*get pages*/
- ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle,
- &page_list);
- if (ret) {
- DRM_DEBUG("get pages error\n");
- return ret;
- }
-
- DRM_DEBUG("get %ld pages\n", pages);
-
- /*alloc memory in TT apeture*/
- ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node);
- if (ret) {
- DRM_DEBUG("alloc TT memory error\n");
- goto failed_pages_alloc;
- }
-
- /*update psb_gtt_mm*/
- ret = psb_gtt_add_node(mm,
- task_tgid_nr(current),
- (u32)hKernelMemInfo,
- node,
- &mapping);
- if (ret) {
- DRM_DEBUG("add_node failed");
- goto failed_add_node;
- }
-
- node = mapping->node;
- offset_pages = node->start;
-
- DRM_DEBUG("get free node for %ld pages, offset %ld pages",
- pages, offset_pages);
-
- /*update gtt*/
- psb_gtt_insert_pages(pg, page_list,
- (unsigned)offset_pages,
- (unsigned)pages,
- 0,
- 0,
- 0);
-
- *offset = offset_pages;
- return 0;
-
-failed_add_node:
- psb_gtt_mm_free_mem(mm, node);
-failed_pages_alloc:
- kfree(page_list);
- return ret;
-#endif
-}
-
-int psb_gtt_unmap_meminfo(struct drm_device *dev, void * hKernelMemInfo)
-{
- struct drm_psb_private *dev_priv
- = (struct drm_psb_private *)dev->dev_private;
- struct psb_gtt_mm *mm = dev_priv->gtt_mm;
- struct psb_gtt *pg = dev_priv->pg;
- uint32_t pages, offset_pages;
- struct drm_mm_node *node;
- int ret;
-
- ret = psb_gtt_remove_node(mm,
- task_tgid_nr(current),
- (u32)hKernelMemInfo,
- &node);
- if (ret) {
- DRM_DEBUG("remove node failed\n");
- return ret;
- }
-
- /*remove gtt entries*/
- offset_pages = node->start;
- pages = node->size;
-
- psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
-
-
- /*free tt node*/
-
- psb_gtt_mm_free_mem(mm, node);
- return 0;
-}
-
-int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct psb_gtt_mapping_arg *arg
- = (struct psb_gtt_mapping_arg *)data;
- uint32_t *offset_pages = &arg->offset_pages;
-
- DRM_DEBUG("\n");
-
- return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages);
-}
-
-int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
-
- struct psb_gtt_mapping_arg *arg
- = (struct psb_gtt_mapping_arg *)data;
-
- DRM_DEBUG("\n");
-
- return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo);
-}
-
-int psb_gtt_map_pvr_memory(struct drm_device *dev, unsigned int hHandle,
- unsigned int ui32TaskId, dma_addr_t *pPages,
- unsigned int ui32PagesNum, unsigned int *ui32Offset)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt_mm *mm = dev_priv->gtt_mm;
- struct psb_gtt *pg = dev_priv->pg;
- uint32_t size, pages, offset_pages;
- struct drm_mm_node *node = NULL;
- struct psb_gtt_mem_mapping *mapping = NULL;
- int ret;
-
- size = ui32PagesNum * PAGE_SIZE;
- pages = 0;
-
- /*alloc memory in TT apeture*/
- ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node);
- if (ret) {
- DRM_DEBUG("alloc TT memory error\n");
- goto failed_pages_alloc;
- }
-
- /*update psb_gtt_mm*/
- ret = psb_gtt_add_node(mm,
- (u32)ui32TaskId,
- (u32)hHandle,
- node,
- &mapping);
- if (ret) {
- DRM_DEBUG("add_node failed");
- goto failed_add_node;
- }
-
- node = mapping->node;
- offset_pages = node->start;
-
- DRM_DEBUG("get free node for %ld pages, offset %ld pages",
- pages, offset_pages);
-
- /*update gtt*/
- psb_gtt_insert_phys_addresses(pg, pPages, (unsigned)offset_pages,
- (unsigned)ui32PagesNum, 0);
-
- *ui32Offset = offset_pages;
- return 0;
-
-failed_add_node:
- psb_gtt_mm_free_mem(mm, node);
-failed_pages_alloc:
- return ret;
-}
-
-
-int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle,
- unsigned int ui32TaskId)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt_mm *mm = dev_priv->gtt_mm;
- struct psb_gtt *pg = dev_priv->pg;
- uint32_t pages, offset_pages;
- struct drm_mm_node *node;
- int ret;
-
- ret = psb_gtt_remove_node(mm, (u32)ui32TaskId, (u32)hHandle, &node);
- if (ret) {
- printk(KERN_ERR "remove node failed\n");
- return ret;
- }
-
- /*remove gtt entries*/
- offset_pages = node->start;
- pages = node->size;
-
- psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
-
- /*free tt node*/
- psb_gtt_mm_free_mem(mm, node);
- return 0;
-}
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 0272f83b461e..535ae00f2ab9 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -22,84 +22,40 @@
#include <drm/drmP.h>
-/*#include "img_types.h"*/
-
struct psb_gtt {
struct drm_device *dev;
- int initialized;
uint32_t gatt_start;
uint32_t mmu_gatt_start;
- uint32_t ci_start;
- uint32_t rar_start;
uint32_t gtt_start;
uint32_t gtt_phys_start;
unsigned gtt_pages;
unsigned gatt_pages;
- uint32_t stolen_base;
- void *vram_addr;
- uint32_t pge_ctl;
- u16 gmch_ctrl;
unsigned long stolen_size;
unsigned long vram_stolen_size;
- unsigned long ci_stolen_size;
- unsigned long rar_stolen_size;
- uint32_t *gtt_map;
struct rw_semaphore sem;
};
-struct psb_gtt_mm {
- struct drm_mm base;
- struct drm_open_hash hash;
- uint32_t count;
- spinlock_t lock;
-};
-
-struct psb_gtt_hash_entry {
- struct drm_open_hash ht;
- uint32_t count;
- struct drm_hash_item item;
-};
-
-struct psb_gtt_mem_mapping {
- struct drm_mm_node *node;
- struct drm_hash_item item;
-};
-
/*Exported functions*/
-extern int psb_gtt_init(struct psb_gtt *pg, int resume);
-extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
- unsigned offset_pages, unsigned num_pages,
- unsigned desired_tile_stride,
- unsigned hw_tile_stride, int type);
-extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
- unsigned num_pages,
- unsigned desired_tile_stride,
- unsigned hw_tile_stride,
- int rc_prot);
-
-extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
-extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
-extern int psb_gtt_map_meminfo(struct drm_device *dev,
- void * hKernelMemInfo,
- uint32_t *offset);
-extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
- void * hKernelMemInfo);
-extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psb_gtt_mm_init(struct psb_gtt *pg);
-extern void psb_gtt_mm_takedown(void);
-
-extern int psb_gtt_map_pvr_memory(struct drm_device *dev,
- unsigned int hHandle,
- unsigned int ui32TaskId,
- dma_addr_t *pPages,
- unsigned int ui32PagesNum,
- unsigned int *ui32Offset);
+extern int psb_gtt_init(struct drm_device *dev, int resume);
+extern void psb_gtt_takedown(struct drm_device *dev);
+
+/* Each gtt_range describes an allocation in the GTT area */
+struct gtt_range {
+ struct resource resource;
+ u32 offset;
+ struct kref kref;
+ struct drm_gem_object gem; /* GEM high level stuff */
+ int in_gart; /* Currently in the GART (ref ct) */
+ bool stolen; /* Backed from stolen RAM */
+ bool mmapping; /* Is mmappable */
+ struct page **pages; /* Backing pages if present */
+};
-extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev,
- unsigned int hHandle,
- unsigned int ui32TaskId);
+extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
+ const char *name, int backed);
+extern void psb_gtt_kref_put(struct gtt_range *gt);
+extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
+extern int psb_gtt_pin(struct gtt_range *gt);
+extern void psb_gtt_unpin(struct gtt_range *gt);
#endif
diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c
index 48ac8ba7f40b..417965da5e24 100644
--- a/drivers/staging/gma500/psb_intel_bios.c
+++ b/drivers/staging/gma500/psb_intel_bios.c
@@ -154,10 +154,15 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
fill_detail_timing_data(panel_fixed_mode, dvo_timing);
- dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
-
- DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
- drm_mode_debug_printmodeline(panel_fixed_mode);
+ if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
+ dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
+ DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+ drm_mode_debug_printmodeline(panel_fixed_mode);
+ } else {
+ DRM_DEBUG("Ignoring bogus LVDS VBT mode.\n");
+ dev_priv->lvds_vbt = 0;
+ kfree(panel_fixed_mode);
+ }
return;
}
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 80b37f4ca10a..4f47d09d65de 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -341,9 +341,8 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
/* struct drm_i915_master_private *master_priv; */
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
- struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
int pipe = psb_intel_crtc->pipe;
- unsigned long Start, Offset;
+ unsigned long start, offset;
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
@@ -359,12 +358,17 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
return 0;
}
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_FORCE_POWER_ON))
+ if (!gma_power_begin(dev, true))
return 0;
- Start = mode_dev->bo_offset(dev, psbfb);
- Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+ /* We are displaying this buffer, make sure it is actually loaded
+ into the GTT */
+ ret = psb_gtt_pin(psbfb->gtt);
+ if (ret < 0)
+ goto psb_intel_pipe_set_base_exit;
+ start = psbfb->gtt->offset;
+
+ offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
REG_WRITE(dspstride, crtc->fb->pitch);
@@ -388,25 +392,29 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
default:
DRM_ERROR("Unknown color depth\n");
ret = -EINVAL;
+ psb_gtt_unpin(psbfb->gtt);
goto psb_intel_pipe_set_base_exit;
}
REG_WRITE(dspcntr_reg, dspcntr);
- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+
+ DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
if (0 /* FIXMEAC - check what PSB needs */) {
- REG_WRITE(dspbase, Offset);
+ REG_WRITE(dspbase, offset);
REG_READ(dspbase);
- REG_WRITE(dspsurf, Start);
+ REG_WRITE(dspsurf, start);
REG_READ(dspsurf);
} else {
- REG_WRITE(dspbase, Start + Offset);
+ REG_WRITE(dspbase, start + offset);
REG_READ(dspbase);
}
-psb_intel_pipe_set_base_exit:
-
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ /* If there was a previous display we can now unpin it */
+ if (old_fb)
+ psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
+psb_intel_pipe_set_base_exit:
+ gma_power_end(dev);
return ret;
}
@@ -816,8 +824,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
return;
}
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
for (i = 0; i < 256; i++) {
REG_WRITE(palreg + 4 * i,
((psb_intel_crtc->lut_r[i] +
@@ -827,7 +834,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
(psb_intel_crtc->lut_b[i] +
psb_intel_crtc->lut_adj[i]));
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
for (i = 0; i < 256; i++) {
dev_priv->save_palette_a[i] =
@@ -1022,19 +1029,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
uint32_t width, uint32_t height)
{
struct drm_device *dev = crtc->dev;
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private;
- struct psb_gtt *pg = dev_priv->pg;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
int pipe = psb_intel_crtc->pipe;
uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
uint32_t temp;
size_t addr = 0;
- uint32_t page_offset;
- size_t size;
- void *bo;
+ struct gtt_range *gt;
+ struct drm_gem_object *obj;
int ret;
DRM_DEBUG("\n");
@@ -1043,22 +1045,21 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
if (!handle) {
DRM_DEBUG("cursor off\n");
/* turn off the cursor */
- temp = 0;
- temp |= CURSOR_MODE_DISABLE;
+ temp = CURSOR_MODE_DISABLE;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
REG_WRITE(control, temp);
REG_WRITE(base, 0);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
- /* unpin the old bo */
- if (psb_intel_crtc->cursor_bo) {
- mode_dev->bo_unpin_for_scanout(dev,
- psb_intel_crtc->
- cursor_bo);
- psb_intel_crtc->cursor_bo = NULL;
+ /* Unpin the old GEM object */
+ if (psb_intel_crtc->cursor_obj) {
+ gt = container_of(psb_intel_crtc->cursor_obj,
+ struct gtt_range, gem);
+ psb_gtt_unpin(gt);
+ drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+ psb_intel_crtc->cursor_obj = NULL;
}
return 0;
@@ -1070,32 +1071,26 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
return -EINVAL;
}
- bo = mode_dev->bo_from_handle(dev, file_priv, handle);
- if (!bo)
+ obj = drm_gem_object_lookup(dev, file_priv, handle);
+ if (!obj)
return -ENOENT;
- ret = mode_dev->bo_pin_for_scanout(dev, bo);
- if (ret)
- return ret;
- size = mode_dev->bo_size(dev, bo);
- if (size < width * height * 4) {
+ if (obj->size < width * height * 4) {
DRM_ERROR("buffer is to small\n");
return -ENOMEM;
}
- /*insert this bo into gtt*/
- DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
- __func__, handle);
+ gt = container_of(obj, struct gtt_range, gem);
- ret = psb_gtt_map_meminfo(dev, (void *)handle, &page_offset);
+ /* Pin the memory into the GTT */
+ ret = psb_gtt_pin(gt);
if (ret) {
- DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
+ DRM_ERROR("Can not pin down handle 0x%x\n", handle);
return ret;
}
- addr = page_offset << PAGE_SHIFT;
- addr += pg->stolen_base;
+ addr = gt->offset; /* Or resource.start ??? */
psb_intel_crtc->cursor_addr = addr;
@@ -1104,17 +1099,19 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
temp |= (pipe << 28);
temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
REG_WRITE(control, temp);
REG_WRITE(base, addr);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
/* unpin the old bo */
- if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
- mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
- psb_intel_crtc->cursor_bo = bo;
+ if (psb_intel_crtc->cursor_obj && psb_intel_crtc->cursor_obj != obj) {
+ gt = container_of(psb_intel_crtc->cursor_obj,
+ struct gtt_range, gem);
+ psb_gtt_unpin(gt);
+ drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+ psb_intel_crtc->cursor_obj = obj;
}
return 0;
@@ -1126,7 +1123,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
int pipe = psb_intel_crtc->pipe;
uint32_t temp = 0;
- uint32_t adder;
+ uint32_t addr;
if (x < 0) {
@@ -1141,13 +1138,12 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
- adder = psb_intel_crtc->cursor_addr;
+ addr = psb_intel_crtc->cursor_addr;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
- REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
+ gma_power_end(dev);
}
return 0;
}
@@ -1197,15 +1193,14 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev,
bool is_lvds;
struct drm_psb_private *dev_priv = dev->dev_private;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
else
fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
dpll = (pipe == 0) ?
dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
@@ -1277,13 +1272,12 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
int vsync;
struct drm_psb_private *dev_priv = dev->dev_private;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
htot = (pipe == 0) ?
dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
@@ -1318,7 +1312,16 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
{
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-
+ struct gtt_range *gt;
+
+ /* Unpin the old GEM object */
+ if (psb_intel_crtc->cursor_obj) {
+ gt = container_of(psb_intel_crtc->cursor_obj,
+ struct gtt_range, gem);
+ psb_gtt_unpin(gt);
+ drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+ psb_intel_crtc->cursor_obj = NULL;
+ }
kfree(psb_intel_crtc->crtc_state);
drm_crtc_cleanup(crtc);
kfree(psb_intel_crtc);
@@ -1333,10 +1336,6 @@ static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
.commit = psb_intel_crtc_commit,
};
-static const struct drm_crtc_helper_funcs mrst_helper_funcs;
-static const struct drm_crtc_helper_funcs mdfld_helper_funcs;
-const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
-
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
.save = psb_intel_crtc_save,
.restore = psb_intel_crtc_restore,
@@ -1397,7 +1396,11 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
psb_intel_crtc->mode_dev = mode_dev;
psb_intel_crtc->cursor_addr = 0;
- drm_crtc_helper_add(&psb_intel_crtc->base,
+ if (IS_MRST(dev))
+ drm_crtc_helper_add(&psb_intel_crtc->base,
+ &mrst_helper_funcs);
+ else
+ drm_crtc_helper_add(&psb_intel_crtc->base,
&psb_intel_helper_funcs);
/* Setup the array of drm_connector pointer array */
diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
index f6229c56de40..6006ddd993f2 100644
--- a/drivers/staging/gma500/psb_intel_drv.h
+++ b/drivers/staging/gma500/psb_intel_drv.h
@@ -76,13 +76,7 @@ struct psb_intel_mode_device {
/*
* Abstracted memory manager operations
*/
- void *(*bo_from_handle) (struct drm_device *dev,
- struct drm_file *file_priv,
- unsigned int handle);
- size_t(*bo_size) (struct drm_device *dev, void *bo);
size_t(*bo_offset) (struct drm_device *dev, void *bo);
- int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo);
- int (*bo_unpin_for_scanout) (struct drm_device *dev, void *bo);
/*
* Cursor
@@ -156,11 +150,8 @@ struct psb_intel_crtc {
/* a mode_set for fbdev users on this crtc */
struct drm_mode_set mode_set;
- /* current bo we scanout from */
- void *scanout_bo;
-
- /* current bo we cursor from */
- void *cursor_bo;
+ /* GEM object that holds our cursor */
+ struct drm_gem_object *cursor_obj;
struct drm_display_mode saved_mode;
struct drm_display_mode saved_adjusted_mode;
diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
index d3d210a1026a..b0a225b9f562 100644
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ b/drivers/staging/gma500/psb_intel_lvds.c
@@ -32,13 +32,6 @@
#include "psb_powermgmt.h"
#include <linux/pm_runtime.h>
-/* MRST defines start */
-uint8_t blc_freq;
-uint8_t blc_minbrightness;
-uint8_t blc_i2caddr;
-uint8_t blc_brightnesscmd;
-int lvds_backlight; /* restore backlight to this value */
-
u32 CoreClock;
u32 PWMControlRegFreq;
@@ -83,13 +76,12 @@ static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
struct drm_psb_private *dev_priv = dev->dev_private;
u32 retVal;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
retVal = ((REG_READ(BLC_PWM_CTL) &
BACKLIGHT_MODULATION_FREQ_MASK) >>
BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else
retVal = ((dev_priv->saveBLC_PWM_CTL &
BACKLIGHT_MODULATION_FREQ_MASK) >>
@@ -98,8 +90,11 @@ static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
return retVal;
}
-/**
+/*
* Set LVDS backlight level by I2C command
+ *
+ * FIXME: at some point we need to both track this for PM and also
+ * disable runtime pm on MRST if the brightness is nil (ie blanked)
*/
static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
unsigned int level)
@@ -132,7 +127,7 @@ static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n",
- blc_brightnesscmd,
+ dev_priv->lvds_bl->brightnesscmd,
blc_i2c_brightness);
return 0;
}
@@ -200,14 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
struct drm_psb_private *dev_priv = dev->dev_private;
u32 blc_pwm_ctl;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
blc_pwm_ctl =
REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
REG_WRITE(BLC_PWM_CTL,
(blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
~BACKLIGHT_DUTY_CYCLE_MASK;
@@ -224,8 +218,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
{
u32 pp_status;
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_FORCE_POWER_ON))
+ if (!gma_power_begin(dev, true))
return;
if (on) {
@@ -248,7 +241,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
} while (pp_status & PP_ON);
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
@@ -400,11 +393,15 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2;
- /* PSB doesn't appear to be GEN4 */
- if (psb_intel_crtc->pipe == 0) {
+ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
+ if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
printk(KERN_ERR "Can't support LVDS on pipe A\n");
return false;
}
+ if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
+ printk(KERN_ERR "Must use PIPE A\n");
+ return false;
+ }
/* Should never happen!! */
list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
head) {
@@ -445,7 +442,7 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
return true;
}
-static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
+void psb_intel_lvds_prepare(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
@@ -453,8 +450,7 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
PSB_DEBUG_ENTRY("\n");
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_FORCE_POWER_ON))
+ if (!gma_power_begin(dev, true))
return;
mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
@@ -463,10 +459,10 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
psb_intel_lvds_set_power(dev, output, false);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
-static void psb_intel_lvds_commit(struct drm_encoder *encoder)
+void psb_intel_lvds_commit(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
@@ -669,14 +665,14 @@ static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
.commit = psb_intel_lvds_commit,
};
-static const struct drm_connector_helper_funcs
+const struct drm_connector_helper_funcs
psb_intel_lvds_connector_helper_funcs = {
.get_modes = psb_intel_lvds_get_modes,
.mode_valid = psb_intel_lvds_mode_valid,
.best_encoder = psb_intel_best_encoder,
};
-static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
+const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = psb_intel_lvds_save,
.restore = psb_intel_lvds_restore,
diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c
index 1d2bb021c0a5..df1c006ecfaa 100644
--- a/drivers/staging/gma500/psb_intel_sdvo.c
+++ b/drivers/staging/gma500/psb_intel_sdvo.c
@@ -204,7 +204,7 @@ static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
int i;
- if (1) {
+ if (0) {
DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
for (i = 0; i < args_len; i++)
printk(KERN_INFO"%02X ", ((u8 *) args)[i]);
@@ -266,7 +266,7 @@ static u8 psb_intel_sdvo_read_response(
SDVO_I2C_CMD_STATUS,
&status);
- if (1) {
+ if (0) {
DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
for (i = 0; i < response_len; i++)
printk(KERN_INFO"%02X ", ((u8 *) response)[i]);
diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c
index 4597c8824721..9ea37e588874 100644
--- a/drivers/staging/gma500/psb_irq.c
+++ b/drivers/staging/gma500/psb_irq.c
@@ -88,13 +88,12 @@ psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
u32 reg = psb_pipestat(pipe);
dev_priv->pipestat[pipe] |= mask;
/* Enable the interrupt, clear any pending status */
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev_priv->dev, false)) {
u32 writeVal = PSB_RVDC32(reg);
writeVal |= (mask | (mask >> 16));
PSB_WVDC32(writeVal, reg);
(void) PSB_RVDC32(reg);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev_priv->dev);
}
}
}
@@ -105,39 +104,36 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
if ((dev_priv->pipestat[pipe] & mask) != 0) {
u32 reg = psb_pipestat(pipe);
dev_priv->pipestat[pipe] &= ~mask;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev_priv->dev, false)) {
u32 writeVal = PSB_RVDC32(reg);
writeVal &= ~mask;
PSB_WVDC32(writeVal, reg);
(void) PSB_RVDC32(reg);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev_priv->dev);
}
}
}
void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
{
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev_priv->dev, false)) {
u32 pipe_event = mid_pipe_event(pipe);
dev_priv->vdc_irq_mask |= pipe_event;
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev_priv->dev);
}
}
void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
{
if (dev_priv->pipestat[pipe] == 0) {
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev_priv->dev, false)) {
u32 pipe_event = mid_pipe_event(pipe);
dev_priv->vdc_irq_mask &= ~pipe_event;
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev_priv->dev);
}
}
}
@@ -242,7 +238,7 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);
- if (dsp_int && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
+ if (dsp_int && gma_power_is_on(dev)) {
psb_vdc_interrupt(dev, vdc_stat);
handled = 1;
}
@@ -271,54 +267,28 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
void psb_irq_preinstall(struct drm_device *dev)
{
- psb_irq_preinstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-/**
- * FIXME: should I remove display irq enable here??
- */
-void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands)
-{
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
unsigned long irqflags;
- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- if (hw_islands & OSPM_DISPLAY_ISLAND) {
- if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
- PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (dev->vblank_enabled[0])
- dev_priv->vdc_irq_mask |=
- _PSB_PIPEA_EVENT_FLAG;
- if (dev->vblank_enabled[1])
- dev_priv->vdc_irq_mask |=
- _MDFLD_PIPEB_EVENT_FLAG;
- if (dev->vblank_enabled[2])
- dev_priv->vdc_irq_mask |=
- _MDFLD_PIPEC_EVENT_FLAG;
- }
- }
-/* NO I DONT WANT ANY IRQS GRRR FIXMEAC */
- if (hw_islands & OSPM_GRAPHICS_ISLAND)
- dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG;
-/* */
+ if (gma_power_is_on(dev))
+ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
+ if (dev->vblank_enabled[0])
+ dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG;
+ if (dev->vblank_enabled[1])
+ dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
+ if (dev->vblank_enabled[2])
+ dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
+
/*This register is safe even if display island is off*/
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}
int psb_irq_postinstall(struct drm_device *dev)
{
- return psb_irq_postinstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands)
-{
-
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
unsigned long irqflags;
@@ -327,48 +297,31 @@ int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- /*This register is safe even if display island is off*/
+ /* This register is safe even if display island is off */
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (hw_islands & OSPM_DISPLAY_ISLAND) {
- if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
- PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
- if (dev->vblank_enabled[0])
- psb_enable_pipestat(dev_priv, 0,
- PIPE_VBLANK_INTERRUPT_ENABLE);
- else
- psb_disable_pipestat(dev_priv, 0,
- PIPE_VBLANK_INTERRUPT_ENABLE);
-
- if (dev->vblank_enabled[1])
- psb_enable_pipestat(dev_priv, 1,
- PIPE_VBLANK_INTERRUPT_ENABLE);
- else
- psb_disable_pipestat(dev_priv, 1,
- PIPE_VBLANK_INTERRUPT_ENABLE);
-
- if (dev->vblank_enabled[2])
- psb_enable_pipestat(dev_priv, 2,
- PIPE_VBLANK_INTERRUPT_ENABLE);
- else
- psb_disable_pipestat(dev_priv, 2,
- PIPE_VBLANK_INTERRUPT_ENABLE);
- }
- }
+ if (dev->vblank_enabled[0])
+ psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
+ else
+ psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
- spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+ if (dev->vblank_enabled[1])
+ psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
+ else
+ psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
+ if (dev->vblank_enabled[2])
+ psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
+ else
+ psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
+
+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
return 0;
}
void psb_irq_uninstall(struct drm_device *dev)
{
- psb_irq_uninstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands)
-{
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
unsigned long irqflags;
@@ -377,39 +330,29 @@ void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- if (hw_islands & OSPM_DISPLAY_ISLAND) {
- if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
- PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
+ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
- if (dev->vblank_enabled[0])
- psb_disable_pipestat(dev_priv, 0,
- PIPE_VBLANK_INTERRUPT_ENABLE);
+ if (dev->vblank_enabled[0])
+ psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank_enabled[1])
- psb_disable_pipestat(dev_priv, 1,
- PIPE_VBLANK_INTERRUPT_ENABLE);
+ if (dev->vblank_enabled[1])
+ psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
- if (dev->vblank_enabled[2])
- psb_disable_pipestat(dev_priv, 2,
- PIPE_VBLANK_INTERRUPT_ENABLE);
- }
- dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
- _PSB_IRQ_MSVDX_FLAG |
- _LNC_IRQ_TOPAZ_FLAG;
- }
- /*TODO: remove following code*/
- if (hw_islands & OSPM_GRAPHICS_ISLAND)
- dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
+ if (dev->vblank_enabled[2])
+ psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
+
+ dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
+ _PSB_IRQ_MSVDX_FLAG |
+ _LNC_IRQ_TOPAZ_FLAG;
- /*These two registers are safe even if display island is off*/
+ /* These two registers are safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
wmb();
- /*This register is safe even if display island is off*/
+ /* This register is safe even if display island is off */
PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
-
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}
@@ -420,8 +363,7 @@ void psb_irq_turn_on_dpst(struct drm_device *dev)
u32 hist_reg;
u32 pwm_reg;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
@@ -443,7 +385,7 @@ void psb_irq_turn_on_dpst(struct drm_device *dev)
PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
PWM_CONTROL_LOGIC);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
@@ -472,8 +414,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
u32 hist_reg;
u32 pwm_reg;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
@@ -484,7 +425,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
PWM_CONTROL_LOGIC);
pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
}
@@ -526,18 +467,16 @@ static int psb_vblank_do_wait(struct drm_device *dev,
*/
int psb_enable_vblank(struct drm_device *dev, int pipe)
{
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) dev->dev_private;
+ struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;
uint32_t reg_val = 0;
uint32_t pipeconf_reg = mid_pipeconf(pipe);
PSB_DEBUG_ENTRY("\n");
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
reg_val = REG_READ(pipeconf_reg);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
if (!(reg_val & PIPEACONF_ENABLE))
@@ -545,7 +484,6 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- drm_psb_disable_vsync = 0;
mid_enable_pipe_event(dev_priv, pipe);
psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
@@ -559,15 +497,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
*/
void psb_disable_vblank(struct drm_device *dev, int pipe)
{
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) dev->dev_private;
+ struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;
PSB_DEBUG_ENTRY("\n");
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- drm_psb_disable_vsync = 1;
mid_disable_pipe_event(dev_priv, pipe);
psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
@@ -603,7 +539,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
return 0;
}
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
+ if (!gma_power_begin(dev, false))
return 0;
reg_val = REG_READ(pipeconf_reg);
@@ -632,7 +568,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
psb_get_vblank_counter_exit:
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
return count;
}
diff --git a/drivers/staging/gma500/psb_reset.c b/drivers/staging/gma500/psb_lid.c
index 21fd202f2931..21fd202f2931 100644
--- a/drivers/staging/gma500/psb_reset.c
+++ b/drivers/staging/gma500/psb_lid.c
diff --git a/drivers/staging/gma500/psb_mmu.c b/drivers/staging/gma500/psb_mmu.c
index edd0d4923e0f..c904d73b1de3 100644
--- a/drivers/staging/gma500/psb_mmu.c
+++ b/drivers/staging/gma500/psb_mmu.c
@@ -444,67 +444,6 @@ static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
}
-#if 0
-static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd,
- uint32_t mmu_offset)
-{
- uint32_t *v;
- uint32_t pfn;
-
- v = kmap_atomic(pd->p, KM_USER0);
- if (!v) {
- printk(KERN_INFO "Could not kmap pde page.\n");
- return 0;
- }
- pfn = v[psb_mmu_pd_index(mmu_offset)];
- /* printk(KERN_INFO "pde is 0x%08x\n",pfn); */
- kunmap_atomic(v, KM_USER0);
- if (((pfn & 0x0F) != PSB_PTE_VALID)) {
- printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n",
- mmu_offset, pfn);
- }
- v = ioremap(pfn & 0xFFFFF000, 4096);
- if (!v) {
- printk(KERN_INFO "Could not kmap pte page.\n");
- return 0;
- }
- pfn = v[psb_mmu_pt_index(mmu_offset)];
- /* printk(KERN_INFO "pte is 0x%08x\n",pfn); */
- iounmap(v);
- if (((pfn & 0x0F) != PSB_PTE_VALID)) {
- printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n",
- mmu_offset, pfn);
- }
- return pfn >> PAGE_SHIFT;
-}
-
-static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd,
- uint32_t mmu_offset,
- uint32_t gtt_pages)
-{
- uint32_t start;
- uint32_t next;
-
- printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n",
- mmu_offset, gtt_pages);
- down_read(&pd->driver->sem);
- start = psb_mmu_check_pte_locked(pd, mmu_offset);
- mmu_offset += PAGE_SIZE;
- gtt_pages -= 1;
- while (gtt_pages--) {
- next = psb_mmu_check_pte_locked(pd, mmu_offset);
- if (next != start + 1) {
- printk(KERN_INFO
- "Ptes out of order: 0x%08x, 0x%08x.\n",
- start, next);
- }
- start = next;
- mmu_offset += PAGE_SIZE;
- }
- up_read(&pd->driver->sem);
-}
-
-#endif
void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
uint32_t mmu_offset, uint32_t gtt_start,
diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c
index 7deb1ba82545..1495415be6c7 100644
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ b/drivers/staging/gma500/psb_powermgmt.c
@@ -24,83 +24,73 @@
* Authors:
* Benjamin Defnet <benjamin.r.defnet@intel.com>
* Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
+ * Massively reworked
+ * Alan Cox <alan@linux.intel.com>
*/
#include "psb_powermgmt.h"
#include "psb_drv.h"
+#include "psb_reg.h"
#include "psb_intel_reg.h"
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
-#undef OSPM_GFX_DPK
-
-extern u32 gui32SGXDeviceID;
-extern u32 gui32MRSTDisplayDeviceID;
-extern u32 gui32MRSTMSVDXDeviceID;
-extern u32 gui32MRSTTOPAZDeviceID;
-
-struct drm_device *gpDrmDevice = NULL;
static struct mutex power_mutex;
-static bool gbSuspendInProgress = false;
-static bool gbResumeInProgress = false;
-static int g_hw_power_status_mask;
-static atomic_t g_display_access_count;
-static atomic_t g_graphics_access_count;
-static atomic_t g_videoenc_access_count;
-static atomic_t g_videodec_access_count;
-int allow_runtime_pm = 0;
-
-void ospm_power_island_up(int hw_islands);
-void ospm_power_island_down(int hw_islands);
-static bool gbSuspended = false;
-bool gbgfxsuspended = false;
-/*
- * ospm_power_init
+/**
+ * gma_power_init - initialise power manager
+ * @dev: our device
*
- * Description: Initialize this ospm power management module
+ * Set up for power management tracking of our hardware.
*/
-void ospm_power_init(struct drm_device *dev)
+void gma_power_init(struct drm_device *dev)
{
- struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
-
- gpDrmDevice = dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
dev_priv->ospm_base &= 0xffff;
+ dev_priv->display_power = true; /* We start active */
+ dev_priv->display_count = 0; /* Currently no users */
+ dev_priv->suspended = false; /* And not suspended */
mutex_init(&power_mutex);
- g_hw_power_status_mask = OSPM_ALL_ISLANDS;
- atomic_set(&g_display_access_count, 0);
- atomic_set(&g_graphics_access_count, 0);
- atomic_set(&g_videoenc_access_count, 0);
- atomic_set(&g_videodec_access_count, 0);
+
+ if (!IS_MRST(dev)) {
+ /* FIXME: wants further review */
+ u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
+ /* Disable 2D clock gating */
+ gating &= ~3;
+ gating |= 1;
+ PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
+ PSB_RSGX32(PSB_CR_CLKGATECTL);
+ }
}
-/*
- * ospm_power_uninit
+/**
+ * gma_power_uninit - end power manager
+ * @dev: device to end for
*
- * Description: Uninitialize this ospm power management module
+ * Undo the effects of gma_power_init
*/
-void ospm_power_uninit(void)
+void gma_power_uninit(struct drm_device *dev)
{
mutex_destroy(&power_mutex);
- pm_runtime_disable(&gpDrmDevice->pdev->dev);
- pm_runtime_set_suspended(&gpDrmDevice->pdev->dev);
+ pm_runtime_disable(&dev->pdev->dev);
+ pm_runtime_set_suspended(&dev->pdev->dev);
}
-/*
- * save_display_registers
+/**
+ * save_display_registers - save registers lost on suspend
+ * @dev: our DRM device
*
- * Description: We are going to suspend so save current display
- * register state.
+ * Save the state we need in order to be able to restore the interface
+ * upon resume from suspend
*/
static int save_display_registers(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_crtc * crtc;
- struct drm_connector * connector;
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
/* Display arbitration control + watermarks */
dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
@@ -112,37 +102,31 @@ static int save_display_registers(struct drm_device *dev)
dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
- /*save crtc and output state*/
+ /* Save crtc and output state */
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if(drm_helper_crtc_in_use(crtc)) {
+ if (drm_helper_crtc_in_use(crtc))
crtc->funcs->save(crtc);
- }
}
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
connector->funcs->save(connector);
- }
- mutex_unlock(&dev->mode_config.mutex);
-
- /* Interrupt state */
- /*
- * Handled in psb_irq.c
- */
+ mutex_unlock(&dev->mode_config.mutex);
return 0;
}
-/*
- * restore_display_registers
+/**
+ * restore_display_registers - restore lost register state
+ * @dev: our DRM device
*
- * Description: We are going to resume so restore display register state.
+ * Restore register state that was lost during suspend and resume.
*/
static int restore_display_registers(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_crtc * crtc;
- struct drm_connector * connector;
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
/* Display arbitration + watermarks */
PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
@@ -158,39 +142,57 @@ static int restore_display_registers(struct drm_device *dev)
PSB_WVDC32(0x80000000, VGACNTRL);
mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if(drm_helper_crtc_in_use(crtc))
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ if (drm_helper_crtc_in_use(crtc))
crtc->funcs->restore(crtc);
- }
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- connector->funcs->restore(connector);
- }
- mutex_unlock(&dev->mode_config.mutex);
- /*Interrupt state*/
- /*
- * Handled in psb_irq.c
- */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->funcs->restore(connector);
+ mutex_unlock(&dev->mode_config.mutex);
return 0;
}
-/*
- * powermgmt_suspend_display
+
+/**
+ * power_down - power down the display island
+ * @dev: our DRM device
*
- * Description: Suspend the display hardware saving state and disabling
- * as necessary.
+ * Power down the display interface of our device
*/
-void ospm_suspend_display(struct drm_device *dev)
+static void power_down(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- int pp_stat, ret=0;
+ u32 pwr_mask ;
+ u32 pwr_sts;
- printk(KERN_ALERT "%s \n", __func__);
+ if (IS_MRST(dev)) {
+ pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+ outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "%s \n", __func__);
-#endif
- if (!(g_hw_power_status_mask & OSPM_DISPLAY_ISLAND))
+ while (true) {
+ pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+ if ((pwr_sts & pwr_mask) == pwr_mask)
+ break;
+ else
+ udelay(10);
+ }
+ dev_priv->display_power = false;
+ }
+}
+
+
+/**
+ * gma_suspend_display - suspend the display logic
+ * @dev: our DRM device
+ *
+ * Suspend the display logic of the graphics interface
+ */
+static void gma_suspend_display(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int pp_stat;
+
+ if (dev_priv->suspended)
return;
save_display_registers(dev);
@@ -225,37 +227,58 @@ void ospm_suspend_display(struct drm_device *dev)
!= DPI_FIFO_EMPTY);
PSB_WVDC32(0, DEVICE_READY_REG);
/* turn off panel power */
- ret = 0;
}
- ospm_power_island_down(OSPM_DISPLAY_ISLAND);
+ power_down(dev);
}
/*
- * ospm_resume_display
+ * power_up
*
- * Description: Resume the display hardware restoring state and enabling
- * as necessary.
+ * Description: Restore power to the specified island(s) (powergating)
*/
-void ospm_resume_display(struct pci_dev *pdev)
+static void power_up(struct drm_device *dev)
{
- struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt *pg = dev_priv->pg;
+ u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+ u32 pwr_sts, pwr_cnt;
- printk(KERN_ALERT "%s \n", __func__);
+ if (IS_MRST(dev)) {
+ pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
+ pwr_cnt &= ~pwr_mask;
+ outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "%s \n", __func__);
-#endif
- if (g_hw_power_status_mask & OSPM_DISPLAY_ISLAND)
+ while (true) {
+ pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+ if ((pwr_sts & pwr_mask) == 0)
+ break;
+ else
+ udelay(10);
+ }
+ }
+ dev_priv->suspended = false;
+ dev_priv->display_power = true;
+}
+
+/**
+ * gma_resume_display - resume display side logic
+ *
+ * Resume the display hardware restoring state and enabling
+ * as necessary.
+ */
+static void gma_resume_display(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->suspended == false)
return;
/* turn on the display power island */
- ospm_power_island_up(OSPM_DISPLAY_ISLAND);
+ power_up(dev);
- PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+ PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
pci_write_config_word(pdev, PSB_GMCH_CTRL,
- pg->gmch_ctrl | _PSB_GMCH_ENABLED);
+ dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
/* Don't reinitialize the GTT as it is unnecessary. The gtt is
* stored in memory so it will automatically be restored. All
@@ -267,26 +290,21 @@ void ospm_resume_display(struct pci_dev *pdev)
restore_display_registers(dev);
}
-#if 1
-/*
- * ospm_suspend_pci
+/**
+ * gma_suspend_pci - suspend PCI side
+ * @pdev: PCI device
*
- * Description: Suspend the pci device saving state and disabling
- * as necessary.
+ * Perform the suspend processing on our PCI device state
*/
-static void ospm_suspend_pci(struct pci_dev *pdev)
+static void gma_suspend_pci(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_psb_private *dev_priv = dev->dev_private;
int bsm, vbt;
- if (gbSuspended)
+ if (dev_priv->suspended)
return;
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "ospm_suspend_pci\n");
-#endif
-
pci_save_state(pdev);
pci_read_config_dword(pdev, 0x5C, &bsm);
dev_priv->saveBSM = bsm;
@@ -298,29 +316,25 @@ static void ospm_suspend_pci(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
- gbSuspended = true;
- gbgfxsuspended = true;
+ dev_priv->suspended = true;
}
-/*
- * ospm_resume_pci
+/**
+ * gma_resume_pci - resume helper
+ * @dev: our PCI device
*
- * Description: Resume the pci device restoring state and enabling
- * as necessary.
+ * Perform the resume processing on our PCI device state - rewrite
+ * register state and re-enable the PCI device
*/
-static bool ospm_resume_pci(struct pci_dev *pdev)
+static bool gma_resume_pci(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_psb_private *dev_priv = dev->dev_private;
- int ret = 0;
+ int ret;
- if (!gbSuspended)
+ if (!dev_priv->suspended)
return true;
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "ospm_resume_pci\n");
-#endif
-
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
@@ -331,448 +345,131 @@ static bool ospm_resume_pci(struct pci_dev *pdev)
ret = pci_enable_device(pdev);
if (ret != 0)
- printk(KERN_ALERT "ospm_resume_pci: pci_enable_device failed: %d\n", ret);
+ dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
else
- gbSuspended = false;
-
- return !gbSuspended;
-}
-#endif
-/*
- * ospm_power_suspend
- *
- * Description: OSPM is telling our driver to suspend so save state
- * and power down all hardware.
- */
-int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- int ret = 0;
- int graphics_access_count;
- int videoenc_access_count;
- int videodec_access_count;
- int display_access_count;
- bool suspend_pci = true;
-
- if(gbSuspendInProgress || gbResumeInProgress)
- {
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "OSPM_GFX_DPK: %s system BUSY \n", __func__);
-#endif
- return -EBUSY;
- }
-
- mutex_lock(&power_mutex);
-
- if (!gbSuspended) {
- graphics_access_count = atomic_read(&g_graphics_access_count);
- videoenc_access_count = atomic_read(&g_videoenc_access_count);
- videodec_access_count = atomic_read(&g_videodec_access_count);
- display_access_count = atomic_read(&g_display_access_count);
-
- if (graphics_access_count ||
- videoenc_access_count ||
- videodec_access_count ||
- display_access_count)
- ret = -EBUSY;
-
- if (!ret) {
- gbSuspendInProgress = true;
-
- psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- ospm_suspend_display(gpDrmDevice);
- if (suspend_pci == true) {
- ospm_suspend_pci(pdev);
- }
- gbSuspendInProgress = false;
- } else {
- printk(KERN_ALERT "ospm_power_suspend: device busy: graphics %d videoenc %d videodec %d display %d\n", graphics_access_count, videoenc_access_count, videodec_access_count, display_access_count);
- }
- }
-
-
- mutex_unlock(&power_mutex);
- return ret;
+ dev_priv->suspended = false;
+ return !dev_priv->suspended;
}
-/*
- * ospm_power_island_up
+/**
+ * gma_power_suspend - bus callback for suspend
+ * @pdev: our PCI device
+ * @state: suspend type
*
- * Description: Restore power to the specified island(s) (powergating)
+ * Called back by the PCI layer during a suspend of the system. We
+ * perform the necessary shut down steps and save enough state that
+ * we can undo this when resume is called.
*/
-void ospm_power_island_up(int hw_islands)
+int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
{
- u32 pwr_cnt = 0;
- u32 pwr_sts = 0;
- u32 pwr_mask = 0;
-
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) gpDrmDevice->dev_private;
-
-
- if (hw_islands & OSPM_DISPLAY_ISLAND) {
- pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-
- pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
- pwr_cnt &= ~pwr_mask;
- outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct drm_psb_private *dev_priv = dev->dev_private;
- while (true) {
- pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
- if ((pwr_sts & pwr_mask) == 0)
- break;
- else
- udelay(10);
+ mutex_lock(&power_mutex);
+ if (!dev_priv->suspended) {
+ if (dev_priv->display_count) {
+ mutex_unlock(&power_mutex);
+ return -EBUSY;
}
+ psb_irq_uninstall(dev);
+ gma_suspend_display(dev);
+ gma_suspend_pci(pdev);
}
-
- g_hw_power_status_mask |= hw_islands;
-}
-
-/*
- * ospm_power_resume
- */
-int ospm_power_resume(struct pci_dev *pdev)
-{
- if(gbSuspendInProgress || gbResumeInProgress)
- {
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "OSPM_GFX_DPK: %s hw_island: Suspend || gbResumeInProgress!!!! \n", __func__);
-#endif
- return 0;
- }
-
- mutex_lock(&power_mutex);
-
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume \n");
-#endif
-
- gbResumeInProgress = true;
-
- ospm_resume_pci(pdev);
-
- ospm_resume_display(gpDrmDevice->pdev);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-
- gbResumeInProgress = false;
-
- mutex_unlock(&power_mutex);
-
+ mutex_unlock(&power_mutex);
return 0;
}
-/*
- * ospm_power_island_down
+/**
+ * gma_power_resume - resume power
+ * @pdev: PCI device
*
- * Description: Cut power to the specified island(s) (powergating)
+ * Resume the PCI side of the graphics and then the displays
*/
-void ospm_power_island_down(int islands)
+int gma_power_resume(struct pci_dev *pdev)
{
-#if 0
- u32 pwr_cnt = 0;
- u32 pwr_mask = 0;
- u32 pwr_sts = 0;
-
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) gpDrmDevice->dev_private;
-
- g_hw_power_status_mask &= ~islands;
-
- if (islands & OSPM_GRAPHICS_ISLAND) {
- pwr_cnt |= PSB_PWRGT_GFX_MASK;
- pwr_mask |= PSB_PWRGT_GFX_MASK;
- if (dev_priv->graphics_state == PSB_PWR_STATE_ON) {
- dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
- dev_priv->gfx_last_mode_change = jiffies;
- dev_priv->graphics_state = PSB_PWR_STATE_OFF;
- dev_priv->gfx_off_cnt++;
- }
- }
- if (islands & OSPM_VIDEO_ENC_ISLAND) {
- pwr_cnt |= PSB_PWRGT_VID_ENC_MASK;
- pwr_mask |= PSB_PWRGT_VID_ENC_MASK;
- }
- if (islands & OSPM_VIDEO_DEC_ISLAND) {
- pwr_cnt |= PSB_PWRGT_VID_DEC_MASK;
- pwr_mask |= PSB_PWRGT_VID_DEC_MASK;
- }
- if (pwr_cnt) {
- pwr_cnt |= inl(dev_priv->apm_base);
- outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
- while (true) {
- pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
-
- if ((pwr_sts & pwr_mask) == pwr_mask)
- break;
- else
- udelay(10);
- }
- }
-
- if (islands & OSPM_DISPLAY_ISLAND) {
- pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-
- outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC));
+ struct drm_device *dev = pci_get_drvdata(pdev);
- while (true) {
- pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
- if ((pwr_sts & pwr_mask) == pwr_mask)
- break;
- else
- udelay(10);
- }
- }
-#endif
+ mutex_lock(&power_mutex);
+ gma_resume_pci(pdev);
+ gma_resume_display(pdev);
+ psb_irq_preinstall(dev);
+ psb_irq_postinstall(dev);
+ mutex_unlock(&power_mutex);
+ return 0;
}
-/*
- * ospm_power_is_hw_on
+
+/**
+ * gma_power_is_on - returne true if power is on
+ * @dev: our DRM device
*
- * Description: do an instantaneous check for if the specified islands
- * are on. Only use this in cases where you know the g_state_change_mutex
- * is already held such as in irq install/uninstall. Otherwise, use
- * ospm_power_using_hw_begin().
+ * Returns true if the display island power is on at this moment
*/
-bool ospm_power_is_hw_on(int hw_islands)
+bool gma_power_is_on(struct drm_device *dev)
{
- return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true:false;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ return dev_priv->display_power;
}
-/*
- * ospm_power_using_hw_begin
+
+/**
+ * gma_power_begin - begin requiring power
+ * @dev: our DRM device
+ * @force_on: true to force power on
*
- * Description: Notify PowerMgmt module that you will be accessing the
- * specified island's hw so don't power it off. If force_on is true,
- * this will power on the specified island if it is off.
- * Otherwise, this will return false and the caller is expected to not
- * access the hw.
+ * Begin an action that requires the display power island is enabled.
+ * We refcount the islands.
*
- * NOTE *** If this is called from and interrupt handler or other atomic
- * context, then it will return false if we are in the middle of a
- * power state transition and the caller will be expected to handle that
- * even if force_on is set to true.
+ * FIXME: locking
*/
-bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage)
+bool gma_power_begin(struct drm_device *dev, bool force_on)
{
- return 1; /*FIXMEAC */
-#if 0
- bool ret = true;
- bool island_is_off = false;
- bool b_atomic = (in_interrupt() || in_atomic());
- bool locked = true;
- struct pci_dev *pdev = gpDrmDevice->pdev;
- u32 deviceID = 0;
- bool force_on = usage ? true: false;
- /*quick path, not 100% race safe, but should be enough comapre to current other code in this file */
- if (!force_on) {
- if (hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask))
- return false;
- else {
- locked = false;
-#ifdef CONFIG_PM_RUNTIME
- /* increment pm_runtime_refcount */
- pm_runtime_get(&pdev->dev);
-#endif
- goto increase_count;
- }
- }
-
-
- if (!b_atomic)
- mutex_lock(&power_mutex);
-
- island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask);
-
- if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off)
- ret = false;
-
- if (ret && island_is_off && !force_on)
- ret = false;
-
- if (ret && island_is_off && force_on) {
- gbResumeInProgress = true;
-
- ret = ospm_resume_pci(pdev);
-
- if (ret) {
- switch(hw_island)
- {
- case OSPM_DISPLAY_ISLAND:
- deviceID = gui32MRSTDisplayDeviceID;
- ospm_resume_display(pdev);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- break;
- case OSPM_GRAPHICS_ISLAND:
- deviceID = gui32SGXDeviceID;
- ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
- break;
-#if 1
- case OSPM_VIDEO_DEC_ISLAND:
- if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
- //printk(KERN_ALERT "%s power on display for video decode use\n", __func__);
- deviceID = gui32MRSTDisplayDeviceID;
- ospm_resume_display(pdev);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- }
- else{
- //printk(KERN_ALERT "%s display is already on for video decode use\n", __func__);
- }
-
- if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
- //printk(KERN_ALERT "%s power on video decode\n", __func__);
- deviceID = gui32MRSTMSVDXDeviceID;
- ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
- }
- else{
- //printk(KERN_ALERT "%s video decode is already on\n", __func__);
- }
-
- break;
- case OSPM_VIDEO_ENC_ISLAND:
- if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
- //printk(KERN_ALERT "%s power on display for video encode\n", __func__);
- deviceID = gui32MRSTDisplayDeviceID;
- ospm_resume_display(pdev);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
- }
- else{
- //printk(KERN_ALERT "%s display is already on for video encode use\n", __func__);
- }
-
- if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
- //printk(KERN_ALERT "%s power on video encode\n", __func__);
- deviceID = gui32MRSTTOPAZDeviceID;
- ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
- psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
- psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
- }
- else{
- //printk(KERN_ALERT "%s video decode is already on\n", __func__);
- }
-#endif
- break;
-
- default:
- printk(KERN_ALERT "%s unknown island !!!! \n", __func__);
- break;
- }
-
- }
-
- if (!ret)
- printk(KERN_ALERT "ospm_power_using_hw_begin: forcing on %d failed\n", hw_island);
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int ret;
- gbResumeInProgress = false;
+ /* Power already on ? */
+ if (dev_priv->display_power) {
+ dev_priv->display_count++;
+ pm_runtime_get(&dev->pdev->dev);
+ return true;
}
-increase_count:
- if (ret) {
- switch(hw_island)
- {
- case OSPM_GRAPHICS_ISLAND:
- atomic_inc(&g_graphics_access_count);
- break;
- case OSPM_VIDEO_ENC_ISLAND:
- atomic_inc(&g_videoenc_access_count);
- break;
- case OSPM_VIDEO_DEC_ISLAND:
- atomic_inc(&g_videodec_access_count);
- break;
- case OSPM_DISPLAY_ISLAND:
- atomic_inc(&g_display_access_count);
- break;
- }
+ if (force_on == false)
+ return false;
+
+ /* Ok power up needed */
+ ret = gma_resume_pci(dev->pdev);
+ if (ret == 0) {
+ psb_irq_preinstall(dev);
+ psb_irq_postinstall(dev);
+ pm_runtime_get(&dev->pdev->dev);
+ dev_priv->display_count++;
+ return true;
}
-
- if (!b_atomic && locked)
- mutex_unlock(&power_mutex);
-
- return ret;
-#endif
+ return false;
}
-/*
- * ospm_power_using_hw_end
+/**
+ * gma_power_end - end use of power
+ * @dev: Our DRM device
*
- * Description: Notify PowerMgmt module that you are done accessing the
- * specified island's hw so feel free to power it off. Note that this
- * function doesn't actually power off the islands.
+ * Indicate that one of our gma_power_begin() requested periods when
+ * the diplay island power is needed has completed.
*/
-void ospm_power_using_hw_end(int hw_island)
-{
-#if 0 /* FIXMEAC */
- switch(hw_island)
- {
- case OSPM_GRAPHICS_ISLAND:
- atomic_dec(&g_graphics_access_count);
- break;
- case OSPM_VIDEO_ENC_ISLAND:
- atomic_dec(&g_videoenc_access_count);
- break;
- case OSPM_VIDEO_DEC_ISLAND:
- atomic_dec(&g_videodec_access_count);
- break;
- case OSPM_DISPLAY_ISLAND:
- atomic_dec(&g_display_access_count);
- break;
- }
-
- //decrement runtime pm ref count
- pm_runtime_put(&gpDrmDevice->pdev->dev);
-
- WARN_ON(atomic_read(&g_graphics_access_count) < 0);
- WARN_ON(atomic_read(&g_videoenc_access_count) < 0);
- WARN_ON(atomic_read(&g_videodec_access_count) < 0);
- WARN_ON(atomic_read(&g_display_access_count) < 0);
-#endif
-}
-
-int ospm_runtime_pm_allow(struct drm_device * dev)
+void gma_power_end(struct drm_device *dev)
{
- return 0;
-}
-
-void ospm_runtime_pm_forbid(struct drm_device * dev)
-{
- struct drm_psb_private * dev_priv = dev->dev_private;
-
- DRM_INFO("%s\n", __FUNCTION__);
-
- pm_runtime_forbid(&dev->pdev->dev);
- dev_priv->rpm_enabled = 0;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ dev_priv->display_count--;
+ WARN_ON(dev_priv->display_count < 0);
+ pm_runtime_put(&dev->pdev->dev);
}
int psb_runtime_suspend(struct device *dev)
{
- pm_message_t state;
- int ret = 0;
- state.event = 0;
-
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "OSPM_GFX_DPK: %s \n", __func__);
-#endif
- if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
- || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)){
-#ifdef OSPM_GFX_DPK
- printk(KERN_ALERT "OSPM_GFX_DPK: GFX: %d VEC: %d VED: %d DC: %d DSR: %d \n", atomic_read(&g_graphics_access_count),
- atomic_read(&g_videoenc_access_count), atomic_read(&g_videodec_access_count), atomic_read(&g_display_access_count));
-#endif
- return -EBUSY;
- }
- else
- ret = ospm_power_suspend(gpDrmDevice->pdev, state);
-
- return ret;
+ static pm_message_t dummy;
+ return gma_power_suspend(to_pci_dev(dev), dummy);
}
int psb_runtime_resume(struct device *dev)
@@ -782,11 +479,11 @@ int psb_runtime_resume(struct device *dev)
int psb_runtime_idle(struct device *dev)
{
- /*printk (KERN_ALERT "lvds:%d,mipi:%d\n", dev_priv->is_lvds_on, dev_priv->is_mipi_on);*/
- if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
- || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count))
- return 1;
- else
+ struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
+ struct drm_psb_private *dev_priv = drmdev->dev_private;
+ if (dev_priv->display_count)
return 0;
+ else
+ return 1;
}
diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h
index bf6f27af03a8..e005229af798 100644
--- a/drivers/staging/gma500/psb_powermgmt.h
+++ b/drivers/staging/gma500/psb_powermgmt.h
@@ -24,7 +24,8 @@
* Authors:
* Benjamin Defnet <benjamin.r.defnet@intel.com>
* Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
+ * Massively reworked
+ * Alan Cox <alan@linux.intel.com>
*/
#ifndef _PSB_POWERMGMT_H_
#define _PSB_POWERMGMT_H_
@@ -32,65 +33,35 @@
#include <linux/pci.h>
#include <drm/drmP.h>
-#define OSPM_GRAPHICS_ISLAND 0x1
-#define OSPM_VIDEO_ENC_ISLAND 0x2
-#define OSPM_VIDEO_DEC_ISLAND 0x4
-#define OSPM_DISPLAY_ISLAND 0x8
-#define OSPM_GL3_CACHE_ISLAND 0x10
-#define OSPM_ALL_ISLANDS 0x1f
-
-/* IPC message and command defines used to enable/disable mipi panel voltages */
-#define IPC_MSG_PANEL_ON_OFF 0xE9
-#define IPC_CMD_PANEL_ON 1
-#define IPC_CMD_PANEL_OFF 0
-
-typedef enum _UHBUsage
-{
- OSPM_UHB_ONLY_IF_ON = 0,
- OSPM_UHB_FORCE_POWER_ON,
-} UHBUsage;
-
-/* Use these functions to power down video HW for D0i3 purpose */
-
-void ospm_power_init(struct drm_device *dev);
-void ospm_power_uninit(void);
-
+void gma_power_init(struct drm_device *dev);
+void gma_power_uninit(struct drm_device *dev);
/*
- * OSPM will call these functions
+ * The kernel bus power management will call these functions
*/
-int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state);
-int ospm_power_resume(struct pci_dev *pdev);
+int gma_power_suspend(struct pci_dev *pdev, pm_message_t state);
+int gma_power_resume(struct pci_dev *pdev);
/*
* These are the functions the driver should use to wrap all hw access
* (i.e. register reads and writes)
*/
-bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage);
-void ospm_power_using_hw_end(int hw_island);
+bool gma_power_begin(struct drm_device *dev, bool force);
+void gma_power_end(struct drm_device *dev);
/*
* Use this function to do an instantaneous check for if the hw is on.
- * Only use this in cases where you know the g_state_change_mutex
- * is already held such as in irq install/uninstall and you need to
- * prevent a deadlock situation. Otherwise use ospm_power_using_hw_begin().
+ * Only use this in cases where you know the mutex is already held such
+ * as in irq install/uninstall and you need to
+ * prevent a deadlock situation. Otherwise use gma_power_begin().
*/
-bool ospm_power_is_hw_on(int hw_islands);
+bool gma_power_is_on(struct drm_device *dev);
/*
- * Power up/down different hw component rails/islands
- */
-void ospm_power_island_down(int hw_islands);
-void ospm_power_island_up(int hw_islands);
-void ospm_suspend_graphics(void);
-/*
* GFX-Runtime PM callbacks
*/
int psb_runtime_suspend(struct device *dev);
int psb_runtime_resume(struct device *dev);
int psb_runtime_idle(struct device *dev);
-int ospm_runtime_pm_allow(struct drm_device * dev);
-void ospm_runtime_pm_forbid(struct drm_device * dev);
-
#endif /*_PSB_POWERMGMT_H_*/
diff --git a/drivers/staging/gma500/psb_pvr_glue.c b/drivers/staging/gma500/psb_pvr_glue.c
deleted file mode 100644
index da78946b57ad..000000000000
--- a/drivers/staging/gma500/psb_pvr_glue.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "psb_pvr_glue.h"
-
-/**
- * FIXME: should NOT use these file under env/linux directly
- */
-
-int psb_get_meminfo_by_handle(void *hKernelMemInfo,
- void **ppsKernelMemInfo)
-{
- return -EINVAL;
-#if 0
- void *psKernelMemInfo = IMG_NULL;
- PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
- PVRSRV_ERROR eError;
-
- psPerProc = PVRSRVPerProcessData(task_tgid_nr(current));
- eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
- (IMG_VOID *)&psKernelMemInfo,
- hKernelMemInfo,
- PVRSRV_HANDLE_TYPE_MEM_INFO);
- if (eError != PVRSRV_OK) {
- DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n",
- (u32)hKernelMemInfo);
- return -EINVAL;
- }
-
- *ppsKernelMemInfo = psKernelMemInfo;
-
- DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
- (u32)hKernelMemInfo);
- return 0;
-#endif
-}
-
-int psb_get_pages_by_mem_handle(void *hOSMemHandle, struct page ***pages)
-{
- return -EINVAL;
-#if 0
- LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
- struct page **page_list;
- if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) {
- DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n");
- return -EINVAL;
- }
-
- page_list = psLinuxMemArea->uData.sPageList.pvPageList;
- if (!page_list) {
- DRM_DEBUG("Page List is NULL\n");
- return -ENOMEM;
- }
-
- *pages = page_list;
- return 0;
-#endif
-}
diff --git a/drivers/staging/gma500/psb_pvr_glue.h b/drivers/staging/gma500/psb_pvr_glue.h
deleted file mode 100644
index dee8cb2cadc0..000000000000
--- a/drivers/staging/gma500/psb_pvr_glue.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "psb_drv.h"
-
-extern int psb_get_meminfo_by_handle(void * hKernelMemInfo,
- void **ppsKernelMemInfo);
-extern u32 psb_get_tgid(void);
-extern int psb_get_pages_by_mem_handle(void * hOSMemHandle,
- struct page ***pages);
diff --git a/drivers/staging/gma500/psb_sgx.c b/drivers/staging/gma500/psb_sgx.c
deleted file mode 100644
index 973134bc2345..000000000000
--- a/drivers/staging/gma500/psb_sgx.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_drm.h"
-#include "psb_reg.h"
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_execbuf_util.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_placement.h"
-#include "psb_sgx.h"
-#include "psb_intel_reg.h"
-#include "psb_powermgmt.h"
-
-
-static inline int psb_same_page(unsigned long offset,
- unsigned long offset2)
-{
- return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
-}
-
-static inline unsigned long psb_offset_end(unsigned long offset,
- unsigned long end)
-{
- offset = (offset + PAGE_SIZE) & PAGE_MASK;
- return (end < offset) ? end : offset;
-}
-
-struct psb_dstbuf_cache {
- unsigned int dst;
- struct ttm_buffer_object *dst_buf;
- unsigned long dst_offset;
- uint32_t *dst_page;
- unsigned int dst_page_offset;
- struct ttm_bo_kmap_obj dst_kmap;
- bool dst_is_iomem;
-};
-
-struct psb_validate_buffer {
- struct ttm_validate_buffer base;
- struct psb_validate_req req;
- int ret;
- struct psb_validate_arg __user *user_val_arg;
- uint32_t flags;
- uint32_t offset;
- int po_correct;
-};
-static int
-psb_placement_fence_type(struct ttm_buffer_object *bo,
- uint64_t set_val_flags,
- uint64_t clr_val_flags,
- uint32_t new_fence_class,
- uint32_t *new_fence_type)
-{
- int ret;
- uint32_t n_fence_type;
- /*
- uint32_t set_flags = set_val_flags & 0xFFFFFFFF;
- uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF;
- */
- struct ttm_fence_object *old_fence;
- uint32_t old_fence_type;
- struct ttm_placement placement;
-
- if (unlikely
- (!(set_val_flags &
- (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) {
- DRM_ERROR
- ("GPU access type (read / write) is not indicated.\n");
- return -EINVAL;
- }
-
- /* User space driver doesn't set any TTM placement flags in
- set_val_flags or clr_val_flags */
- placement.num_placement = 0;/* FIXME */
- placement.num_busy_placement = 0;
- placement.fpfn = 0;
- placement.lpfn = 0;
- ret = psb_ttm_bo_check_placement(bo, &placement);
- if (unlikely(ret != 0))
- return ret;
-
- switch (new_fence_class) {
- default:
- n_fence_type = _PSB_FENCE_TYPE_EXE;
- }
-
- *new_fence_type = n_fence_type;
- old_fence = (struct ttm_fence_object *) bo->sync_obj;
- old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg;
-
- if (old_fence && ((new_fence_class != old_fence->fence_class) ||
- ((n_fence_type ^ old_fence_type) &
- old_fence_type))) {
- ret = ttm_bo_wait(bo, 0, 1, 0);
- if (unlikely(ret != 0))
- return ret;
- }
- /*
- bo->proposed_flags = (bo->proposed_flags | set_flags)
- & ~clr_flags & TTM_PL_MASK_MEMTYPE;
- */
- return 0;
-}
-
-int psb_validate_kernel_buffer(struct psb_context *context,
- struct ttm_buffer_object *bo,
- uint32_t fence_class,
- uint64_t set_flags, uint64_t clr_flags)
-{
- struct psb_validate_buffer *item;
- uint32_t cur_fence_type;
- int ret;
-
- if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) {
- DRM_ERROR("Out of free validation buffer entries for "
- "kernel buffer validation.\n");
- return -ENOMEM;
- }
-
- item = &context->buffers[context->used_buffers];
- item->user_val_arg = NULL;
- item->base.reserved = 0;
-
- ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq);
- if (unlikely(ret != 0))
- return ret;
-
- ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class,
- &cur_fence_type);
- if (unlikely(ret != 0)) {
- ttm_bo_unreserve(bo);
- return ret;
- }
-
- item->base.bo = ttm_bo_reference(bo);
- item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type;
- item->base.reserved = 1;
-
- /* Internal locking ??? FIXMEAC */
- list_add_tail(&item->base.head, &context->kern_validate_list);
- context->used_buffers++;
- /*
- ret = ttm_bo_validate(bo, 1, 0, 0);
- if (unlikely(ret != 0))
- goto out_unlock;
- */
- item->offset = bo->offset;
- item->flags = bo->mem.placement;
- context->fence_types |= cur_fence_type;
-
- return ret;
-}
-
-void psb_fence_or_sync(struct drm_file *file_priv,
- uint32_t engine,
- uint32_t fence_types,
- uint32_t fence_flags,
- struct list_head *list,
- struct psb_ttm_fence_rep *fence_arg,
- struct ttm_fence_object **fence_p)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct ttm_fence_device *fdev = &dev_priv->fdev;
- int ret;
- struct ttm_fence_object *fence;
- struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
- uint32_t handle;
-
- ret = ttm_fence_user_create(fdev, tfile,
- engine, fence_types,
- TTM_FENCE_FLAG_EMIT, &fence, &handle);
- if (ret) {
-
- /*
- * Fence creation failed.
- * Fall back to synchronous operation and idle the engine.
- */
-
- if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
-
- /*
- * Communicate to user-space that
- * fence creation has failed and that
- * the engine is idle.
- */
-
- fence_arg->handle = ~0;
- fence_arg->error = ret;
- }
-
- ttm_eu_backoff_reservation(list);
- if (fence_p)
- *fence_p = NULL;
- return;
- }
-
- ttm_eu_fence_buffer_objects(list, fence);
- if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
- struct ttm_fence_info info = ttm_fence_get_info(fence);
- fence_arg->handle = handle;
- fence_arg->fence_class = ttm_fence_class(fence);
- fence_arg->fence_type = ttm_fence_types(fence);
- fence_arg->signaled_types = info.signaled_types;
- fence_arg->error = 0;
- } else {
- ret =
- ttm_ref_object_base_unref(tfile, handle,
- ttm_fence_type);
- BUG_ON(ret);
- }
-
- if (fence_p)
- *fence_p = fence;
- else if (fence)
- ttm_fence_object_unref(&fence);
-}
-
diff --git a/drivers/staging/gma500/psb_sgx.h b/drivers/staging/gma500/psb_sgx.h
deleted file mode 100644
index 9300e2da993a..000000000000
--- a/drivers/staging/gma500/psb_sgx.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2008, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- *
- **/
-#ifndef _PSB_SGX_H_
-#define _PSB_SGX_H_
-
-extern int psb_submit_video_cmdbuf(struct drm_device *dev,
- struct ttm_buffer_object *cmd_buffer,
- unsigned long cmd_offset,
- unsigned long cmd_size,
- struct ttm_fence_object *fence);
-
-extern int drm_idle_check_interval;
-
-#endif
diff --git a/drivers/staging/gma500/psb_ttm_fence.c b/drivers/staging/gma500/psb_ttm_fence.c
deleted file mode 100644
index d1c359018cba..000000000000
--- a/drivers/staging/gma500/psb_ttm_fence.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "psb_ttm_fence_api.h"
-#include "psb_ttm_fence_driver.h"
-#include <linux/wait.h>
-#include <linux/sched.h>
-
-#include <drm/drmP.h>
-
-/*
- * Simple implementation for now.
- */
-
-static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask)
-{
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-
- printk(KERN_ERR "GPU lockup dectected on engine %u "
- "fence type 0x%08x\n",
- (unsigned int)fence->fence_class, (unsigned int)mask);
- /*
- * Give engines some time to idle?
- */
-
- write_lock(&fc->lock);
- ttm_fence_handler(fence->fdev, fence->fence_class,
- fence->sequence, mask, -EBUSY);
- write_unlock(&fc->lock);
-}
-
-/*
- * Convenience function to be called by fence::wait methods that
- * need polling.
- */
-
-int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy,
- bool interruptible, uint32_t mask)
-{
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
- uint32_t count = 0;
- int ret;
- unsigned long end_jiffies = fence->timeout_jiffies;
-
- DECLARE_WAITQUEUE(entry, current);
- add_wait_queue(&fc->fence_queue, &entry);
-
- ret = 0;
-
- for (;;) {
- __set_current_state((interruptible) ?
- TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- if (ttm_fence_object_signaled(fence, mask))
- break;
- if (time_after_eq(jiffies, end_jiffies)) {
- if (driver->lockup)
- driver->lockup(fence, mask);
- else
- ttm_fence_lockup(fence, mask);
- continue;
- }
- if (lazy)
- schedule_timeout(1);
- else if ((++count & 0x0F) == 0) {
- __set_current_state(TASK_RUNNING);
- schedule();
- __set_current_state((interruptible) ?
- TASK_INTERRUPTIBLE :
- TASK_UNINTERRUPTIBLE);
- }
- if (interruptible && signal_pending(current)) {
- ret = -ERESTART;
- break;
- }
- }
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&fc->fence_queue, &entry);
- return ret;
-}
-
-/*
- * Typically called by the IRQ handler.
- */
-
-void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class,
- uint32_t sequence, uint32_t type, uint32_t error)
-{
- int wake = 0;
- uint32_t diff;
- uint32_t relevant_type;
- uint32_t new_type;
- struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
- const struct ttm_fence_driver *driver = ttm_fence_driver_from_dev(fdev);
- struct list_head *head;
- struct ttm_fence_object *fence, *next;
- bool found = false;
-
- if (list_empty(&fc->ring))
- return;
-
- list_for_each_entry(fence, &fc->ring, ring) {
- diff = (sequence - fence->sequence) & fc->sequence_mask;
- if (diff > fc->wrap_diff) {
- found = true;
- break;
- }
- }
-
- fc->waiting_types &= ~type;
- head = (found) ? &fence->ring : &fc->ring;
-
- list_for_each_entry_safe_reverse(fence, next, head, ring) {
- if (&fence->ring == &fc->ring)
- break;
-
- DRM_DEBUG("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n",
- (unsigned long)fence, fence->sequence,
- fence->fence_type);
-
- if (error) {
- fence->info.error = error;
- fence->info.signaled_types = fence->fence_type;
- list_del_init(&fence->ring);
- wake = 1;
- break;
- }
-
- relevant_type = type & fence->fence_type;
- new_type = (fence->info.signaled_types | relevant_type) ^
- fence->info.signaled_types;
-
- if (new_type) {
- fence->info.signaled_types |= new_type;
- DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
- (unsigned long)fence,
- fence->info.signaled_types);
-
- if (unlikely(driver->signaled))
- driver->signaled(fence);
-
- if (driver->needed_flush)
- fc->pending_flush |=
- driver->needed_flush(fence);
-
- if (new_type & fence->waiting_types)
- wake = 1;
- }
-
- fc->waiting_types |=
- fence->waiting_types & ~fence->info.signaled_types;
-
- if (!(fence->fence_type & ~fence->info.signaled_types)) {
- DRM_DEBUG("Fence completely signaled 0x%08lx\n",
- (unsigned long)fence);
- list_del_init(&fence->ring);
- }
- }
-
- /*
- * Reinstate lost waiting types.
- */
-
- if ((fc->waiting_types & type) != type) {
- head = head->prev;
- list_for_each_entry(fence, head, ring) {
- if (&fence->ring == &fc->ring)
- break;
- diff =
- (fc->highest_waiting_sequence -
- fence->sequence) & fc->sequence_mask;
- if (diff > fc->wrap_diff)
- break;
-
- fc->waiting_types |=
- fence->waiting_types & ~fence->info.signaled_types;
- }
- }
-
- if (wake)
- wake_up_all(&fc->fence_queue);
-}
-
-static void ttm_fence_unring(struct ttm_fence_object *fence)
-{
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- unsigned long irq_flags;
-
- write_lock_irqsave(&fc->lock, irq_flags);
- list_del_init(&fence->ring);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask)
-{
- unsigned long flags;
- bool signaled;
- const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-
- mask &= fence->fence_type;
- read_lock_irqsave(&fc->lock, flags);
- signaled = (mask & fence->info.signaled_types) == mask;
- read_unlock_irqrestore(&fc->lock, flags);
- if (!signaled && driver->poll) {
- write_lock_irqsave(&fc->lock, flags);
- driver->poll(fence->fdev, fence->fence_class, mask);
- signaled = (mask & fence->info.signaled_types) == mask;
- write_unlock_irqrestore(&fc->lock, flags);
- }
- return signaled;
-}
-
-int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type)
-{
- const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- unsigned long irq_flags;
- uint32_t saved_pending_flush;
- uint32_t diff;
- bool call_flush;
-
- if (type & ~fence->fence_type) {
- DRM_ERROR("Flush trying to extend fence type, "
- "0x%x, 0x%x\n", type, fence->fence_type);
- return -EINVAL;
- }
-
- write_lock_irqsave(&fc->lock, irq_flags);
- fence->waiting_types |= type;
- fc->waiting_types |= fence->waiting_types;
- diff = (fence->sequence - fc->highest_waiting_sequence) &
- fc->sequence_mask;
-
- if (diff < fc->wrap_diff)
- fc->highest_waiting_sequence = fence->sequence;
-
- /*
- * fence->waiting_types has changed. Determine whether
- * we need to initiate some kind of flush as a result of this.
- */
-
- saved_pending_flush = fc->pending_flush;
- if (driver->needed_flush)
- fc->pending_flush |= driver->needed_flush(fence);
-
- if (driver->poll)
- driver->poll(fence->fdev, fence->fence_class,
- fence->waiting_types);
-
- call_flush = (fc->pending_flush != 0);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-
- if (call_flush && driver->flush)
- driver->flush(fence->fdev, fence->fence_class);
-
- return 0;
-}
-
-/*
- * Make sure old fence objects are signaled before their fence sequences are
- * wrapped around and reused.
- */
-
-void ttm_fence_flush_old(struct ttm_fence_device *fdev,
- uint32_t fence_class, uint32_t sequence)
-{
- struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
- struct ttm_fence_object *fence;
- unsigned long irq_flags;
- const struct ttm_fence_driver *driver = fdev->driver;
- bool call_flush;
-
- uint32_t diff;
-
- write_lock_irqsave(&fc->lock, irq_flags);
-
- list_for_each_entry_reverse(fence, &fc->ring, ring) {
- diff = (sequence - fence->sequence) & fc->sequence_mask;
- if (diff <= fc->flush_diff)
- break;
-
- fence->waiting_types = fence->fence_type;
- fc->waiting_types |= fence->fence_type;
-
- if (driver->needed_flush)
- fc->pending_flush |= driver->needed_flush(fence);
- }
-
- if (driver->poll)
- driver->poll(fdev, fence_class, fc->waiting_types);
-
- call_flush = (fc->pending_flush != 0);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-
- if (call_flush && driver->flush)
- driver->flush(fdev, fence->fence_class);
-
- /*
- * FIXME: Shold we implement a wait here for really old fences?
- */
-
-}
-
-int ttm_fence_object_wait(struct ttm_fence_object *fence,
- bool lazy, bool interruptible, uint32_t mask)
-{
- const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- int ret = 0;
- unsigned long timeout;
- unsigned long cur_jiffies;
- unsigned long to_jiffies;
-
- if (mask & ~fence->fence_type) {
- DRM_ERROR("Wait trying to extend fence type"
- " 0x%08x 0x%08x\n", mask, fence->fence_type);
- BUG();
- return -EINVAL;
- }
-
- if (driver->wait)
- return driver->wait(fence, lazy, interruptible, mask);
-
- ttm_fence_object_flush(fence, mask);
-retry:
- if (!driver->has_irq ||
- driver->has_irq(fence->fdev, fence->fence_class, mask)) {
-
- cur_jiffies = jiffies;
- to_jiffies = fence->timeout_jiffies;
-
- timeout = (time_after(to_jiffies, cur_jiffies)) ?
- to_jiffies - cur_jiffies : 1;
-
- if (interruptible)
- ret = wait_event_interruptible_timeout
- (fc->fence_queue,
- ttm_fence_object_signaled(fence, mask), timeout);
- else
- ret = wait_event_timeout
- (fc->fence_queue,
- ttm_fence_object_signaled(fence, mask), timeout);
-
- if (unlikely(ret == -ERESTARTSYS))
- return -ERESTART;
-
- if (unlikely(ret == 0)) {
- if (driver->lockup)
- driver->lockup(fence, mask);
- else
- ttm_fence_lockup(fence, mask);
- goto retry;
- }
-
- return 0;
- }
-
- return ttm_fence_wait_polling(fence, lazy, interruptible, mask);
-}
-
-int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags,
- uint32_t fence_class, uint32_t type)
-{
- const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- unsigned long flags;
- uint32_t sequence;
- unsigned long timeout;
- int ret;
-
- ttm_fence_unring(fence);
- ret = driver->emit(fence->fdev,
- fence_class, fence_flags, &sequence, &timeout);
- if (ret)
- return ret;
-
- write_lock_irqsave(&fc->lock, flags);
- fence->fence_class = fence_class;
- fence->fence_type = type;
- fence->waiting_types = 0;
- fence->info.signaled_types = 0;
- fence->info.error = 0;
- fence->sequence = sequence;
- fence->timeout_jiffies = timeout;
- if (list_empty(&fc->ring))
- fc->highest_waiting_sequence = sequence - 1;
- list_add_tail(&fence->ring, &fc->ring);
- fc->latest_queued_sequence = sequence;
- write_unlock_irqrestore(&fc->lock, flags);
- return 0;
-}
-
-int ttm_fence_object_init(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t type,
- uint32_t create_flags,
- void (*destroy) (struct ttm_fence_object *),
- struct ttm_fence_object *fence)
-{
- int ret = 0;
-
- kref_init(&fence->kref);
- fence->fence_class = fence_class;
- fence->fence_type = type;
- fence->info.signaled_types = 0;
- fence->waiting_types = 0;
- fence->sequence = 0;
- fence->info.error = 0;
- fence->fdev = fdev;
- fence->destroy = destroy;
- INIT_LIST_HEAD(&fence->ring);
- atomic_inc(&fdev->count);
-
- if (create_flags & TTM_FENCE_FLAG_EMIT) {
- ret = ttm_fence_object_emit(fence, create_flags,
- fence->fence_class, type);
- }
-
- return ret;
-}
-
-int ttm_fence_object_create(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t type,
- uint32_t create_flags,
- struct ttm_fence_object **c_fence)
-{
- struct ttm_fence_object *fence;
- int ret;
-
- ret = ttm_mem_global_alloc(fdev->mem_glob,
- sizeof(*fence),
- false,
- false);
- if (unlikely(ret != 0)) {
- printk(KERN_ERR "Out of memory creating fence object\n");
- return ret;
- }
-
- fence = kmalloc(sizeof(*fence), GFP_KERNEL);
- if (!fence) {
- printk(KERN_ERR "Out of memory creating fence object\n");
- ttm_mem_global_free(fdev->mem_glob, sizeof(*fence));
- return -ENOMEM;
- }
-
- ret = ttm_fence_object_init(fdev, fence_class, type,
- create_flags, NULL, fence);
- if (ret) {
- ttm_fence_object_unref(&fence);
- return ret;
- }
- *c_fence = fence;
-
- return 0;
-}
-
-static void ttm_fence_object_destroy(struct kref *kref)
-{
- struct ttm_fence_object *fence =
- container_of(kref, struct ttm_fence_object, kref);
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- unsigned long irq_flags;
-
- write_lock_irqsave(&fc->lock, irq_flags);
- list_del_init(&fence->ring);
- write_unlock_irqrestore(&fc->lock, irq_flags);
-
- atomic_dec(&fence->fdev->count);
- if (fence->destroy)
- fence->destroy(fence);
- else {
- ttm_mem_global_free(fence->fdev->mem_glob,
- sizeof(*fence));
- kfree(fence);
- }
-}
-
-void ttm_fence_device_release(struct ttm_fence_device *fdev)
-{
- kfree(fdev->fence_class);
-}
-
-int
-ttm_fence_device_init(int num_classes,
- struct ttm_mem_global *mem_glob,
- struct ttm_fence_device *fdev,
- const struct ttm_fence_class_init *init,
- bool replicate_init,
- const struct ttm_fence_driver *driver)
-{
- struct ttm_fence_class_manager *fc;
- const struct ttm_fence_class_init *fci;
- int i;
-
- fdev->mem_glob = mem_glob;
- fdev->fence_class = kzalloc(num_classes *
- sizeof(*fdev->fence_class), GFP_KERNEL);
-
- if (unlikely(!fdev->fence_class))
- return -ENOMEM;
-
- fdev->num_classes = num_classes;
- atomic_set(&fdev->count, 0);
- fdev->driver = driver;
-
- for (i = 0; i < fdev->num_classes; ++i) {
- fc = &fdev->fence_class[i];
- fci = &init[(replicate_init) ? 0 : i];
-
- fc->wrap_diff = fci->wrap_diff;
- fc->flush_diff = fci->flush_diff;
- fc->sequence_mask = fci->sequence_mask;
-
- rwlock_init(&fc->lock);
- INIT_LIST_HEAD(&fc->ring);
- init_waitqueue_head(&fc->fence_queue);
- }
-
- return 0;
-}
-
-struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence)
-{
- struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
- struct ttm_fence_info tmp;
- unsigned long irq_flags;
-
- read_lock_irqsave(&fc->lock, irq_flags);
- tmp = fence->info;
- read_unlock_irqrestore(&fc->lock, irq_flags);
-
- return tmp;
-}
-
-void ttm_fence_object_unref(struct ttm_fence_object **p_fence)
-{
- struct ttm_fence_object *fence = *p_fence;
-
- *p_fence = NULL;
- (void)kref_put(&fence->kref, &ttm_fence_object_destroy);
-}
-
-/*
- * Placement / BO sync object glue.
- */
-
-bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg)
-{
- struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
- uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
- return ttm_fence_object_signaled(fence, fence_types);
-}
-
-int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
- bool lazy, bool interruptible)
-{
- struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
- uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
- return ttm_fence_object_wait(fence, lazy, interruptible, fence_types);
-}
-
-int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg)
-{
- struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
- uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
- return ttm_fence_object_flush(fence, fence_types);
-}
-
-void ttm_fence_sync_obj_unref(void **sync_obj)
-{
- ttm_fence_object_unref((struct ttm_fence_object **)sync_obj);
-}
-
-void *ttm_fence_sync_obj_ref(void *sync_obj)
-{
- return (void *)
- ttm_fence_object_ref((struct ttm_fence_object *)sync_obj);
-}
diff --git a/drivers/staging/gma500/psb_ttm_fence_api.h b/drivers/staging/gma500/psb_ttm_fence_api.h
deleted file mode 100644
index b14a42711d03..000000000000
--- a/drivers/staging/gma500/psb_ttm_fence_api.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-#ifndef _TTM_FENCE_API_H_
-#define _TTM_FENCE_API_H_
-
-#include <linux/list.h>
-#include <linux/kref.h>
-
-#define TTM_FENCE_FLAG_EMIT (1 << 0)
-#define TTM_FENCE_TYPE_EXE (1 << 0)
-
-struct ttm_fence_device;
-
-/**
- * struct ttm_fence_info
- *
- * @fence_class: The fence class.
- * @fence_type: Bitfield indicating types for this fence.
- * @signaled_types: Bitfield indicating which types are signaled.
- * @error: Last error reported from the device.
- *
- * Used as output from the ttm_fence_get_info
- */
-
-struct ttm_fence_info {
- uint32_t signaled_types;
- uint32_t error;
-};
-
-/**
- * struct ttm_fence_object
- *
- * @fdev: Pointer to the fence device struct.
- * @kref: Holds the reference count of this fence object.
- * @ring: List head used for the circular list of not-completely
- * signaled fences.
- * @info: Data for fast retrieval using the ttm_fence_get_info()
- * function.
- * @timeout_jiffies: Absolute jiffies value indicating when this fence
- * object times out and, if waited on, calls ttm_fence_lockup
- * to check for and resolve a GPU lockup.
- * @sequence: Fence sequence number.
- * @waiting_types: Types currently waited on.
- * @destroy: Called to free the fence object, when its refcount has
- * reached zero. If NULL, kfree is used.
- *
- * This struct is provided in the driver interface so that drivers can
- * derive from it and create their own fence implementation. All members
- * are private to the fence implementation and the fence driver callbacks.
- * Otherwise a driver may access the derived object using container_of().
- */
-
-struct ttm_fence_object {
- struct ttm_fence_device *fdev;
- struct kref kref;
- uint32_t fence_class;
- uint32_t fence_type;
-
- /*
- * The below fields are protected by the fence class
- * manager spinlock.
- */
-
- struct list_head ring;
- struct ttm_fence_info info;
- unsigned long timeout_jiffies;
- uint32_t sequence;
- uint32_t waiting_types;
- void (*destroy) (struct ttm_fence_object *);
-};
-
-/**
- * ttm_fence_object_init
- *
- * @fdev: Pointer to a struct ttm_fence_device.
- * @fence_class: Fence class for this fence.
- * @type: Fence type for this fence.
- * @create_flags: Flags indicating varios actions at init time. At this point
- * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
- * the command stream.
- * @destroy: Destroy function. If NULL, kfree() is used.
- * @fence: The struct ttm_fence_object to initialize.
- *
- * Initialize a pre-allocated fence object. This function, together with the
- * destroy function makes it possible to derive driver-specific fence objects.
- */
-
-extern int
-ttm_fence_object_init(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t type,
- uint32_t create_flags,
- void (*destroy) (struct ttm_fence_object *fence),
- struct ttm_fence_object *fence);
-
-/**
- * ttm_fence_object_create
- *
- * @fdev: Pointer to a struct ttm_fence_device.
- * @fence_class: Fence class for this fence.
- * @type: Fence type for this fence.
- * @create_flags: Flags indicating varios actions at init time. At this point
- * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
- * the command stream.
- * @c_fence: On successful termination, *(@c_fence) will point to the created
- * fence object.
- *
- * Create and initialize a struct ttm_fence_object. The destroy function will
- * be set to kfree().
- */
-
-extern int
-ttm_fence_object_create(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t type,
- uint32_t create_flags,
- struct ttm_fence_object **c_fence);
-
-/**
- * ttm_fence_object_wait
- *
- * @fence: The fence object to wait on.
- * @lazy: Allow sleeps to reduce the cpu-usage if polling.
- * @interruptible: Sleep interruptible when waiting.
- * @type_mask: Wait for the given type_mask to signal.
- *
- * Wait for a fence to signal the given type_mask. The function will
- * perform a fence_flush using type_mask. (See ttm_fence_object_flush).
- *
- * Returns
- * -ERESTART if interrupted by a signal.
- * May return driver-specific error codes if timed-out.
- */
-
-extern int
-ttm_fence_object_wait(struct ttm_fence_object *fence,
- bool lazy, bool interruptible, uint32_t type_mask);
-
-/**
- * ttm_fence_object_flush
- *
- * @fence: The fence object to flush.
- * @flush_mask: Fence types to flush.
- *
- * Make sure that the given fence eventually signals the
- * types indicated by @flush_mask. Note that this may or may not
- * map to a CPU or GPU flush.
- */
-
-extern int
-ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask);
-
-/**
- * ttm_fence_get_info
- *
- * @fence: The fence object.
- *
- * Copy the info block from the fence while holding relevant locks.
- */
-
-struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence);
-
-/**
- * ttm_fence_object_ref
- *
- * @fence: The fence object.
- *
- * Return a ref-counted pointer to the fence object indicated by @fence.
- */
-
-static inline struct ttm_fence_object *ttm_fence_object_ref(struct
- ttm_fence_object
- *fence)
-{
- kref_get(&fence->kref);
- return fence;
-}
-
-/**
- * ttm_fence_object_unref
- *
- * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object.
- *
- * Unreference the fence object pointed to by *(@p_fence), clearing
- * *(p_fence).
- */
-
-extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence);
-
-/**
- * ttm_fence_object_signaled
- *
- * @fence: Pointer to the struct ttm_fence_object.
- * @mask: Type mask to check whether signaled.
- *
- * This function checks (without waiting) whether the fence object
- * pointed to by @fence has signaled the types indicated by @mask,
- * and returns 1 if true, 0 if false. This function does NOT perform
- * an implicit fence flush.
- */
-
-extern bool
-ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask);
-
-/**
- * ttm_fence_class
- *
- * @fence: Pointer to the struct ttm_fence_object.
- *
- * Convenience function that returns the fence class of a
- * struct ttm_fence_object.
- */
-
-static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence)
-{
- return fence->fence_class;
-}
-
-/**
- * ttm_fence_types
- *
- * @fence: Pointer to the struct ttm_fence_object.
- *
- * Convenience function that returns the fence types of a
- * struct ttm_fence_object.
- */
-
-static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence)
-{
- return fence->fence_type;
-}
-
-/*
- * The functions below are wrappers to the above functions, with
- * similar names but with sync_obj omitted. These wrappers are intended
- * to be plugged directly into the buffer object driver's sync object
- * API, if the driver chooses to use ttm_fence_objects as buffer object
- * sync objects. In the prototypes below, a sync_obj is cast to a
- * struct ttm_fence_object, whereas a sync_arg is cast to an
- * uint32_t representing a fence_type argument.
- */
-
-extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg);
-extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
- bool lazy, bool interruptible);
-extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg);
-extern void ttm_fence_sync_obj_unref(void **sync_obj);
-extern void *ttm_fence_sync_obj_ref(void *sync_obj);
-
-#endif
diff --git a/drivers/staging/gma500/psb_ttm_fence_driver.h b/drivers/staging/gma500/psb_ttm_fence_driver.h
deleted file mode 100644
index c35c569fa3f0..000000000000
--- a/drivers/staging/gma500/psb_ttm_fence_driver.h
+++ /dev/null
@@ -1,302 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-#ifndef _TTM_FENCE_DRIVER_H_
-#define _TTM_FENCE_DRIVER_H_
-
-#include <linux/kref.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include "psb_ttm_fence_api.h"
-#include "ttm/ttm_memory.h"
-
-/** @file ttm_fence_driver.h
- *
- * Definitions needed for a driver implementing the
- * ttm_fence subsystem.
- */
-
-/**
- * struct ttm_fence_class_manager:
- *
- * @wrap_diff: Sequence difference to catch 32-bit wrapping.
- * if (seqa - seqb) > @wrap_diff, then seqa < seqb.
- * @flush_diff: Sequence difference to trigger fence flush.
- * if (cur_seq - seqa) > @flush_diff, then consider fence object with
- * seqa as old an needing a flush.
- * @sequence_mask: Mask of valid bits in a fence sequence.
- * @lock: Lock protecting this struct as well as fence objects
- * associated with this struct.
- * @ring: Circular sequence-ordered list of fence objects.
- * @pending_flush: Fence types currently needing a flush.
- * @waiting_types: Fence types that are currently waited for.
- * @fence_queue: Queue of waiters on fences belonging to this fence class.
- * @highest_waiting_sequence: Sequence number of the fence with highest
- * sequence number and that is waited for.
- * @latest_queued_sequence: Sequence number of the fence latest queued
- * on the ring.
- */
-
-struct ttm_fence_class_manager {
-
- /*
- * Unprotected constant members.
- */
-
- uint32_t wrap_diff;
- uint32_t flush_diff;
- uint32_t sequence_mask;
-
- /*
- * The rwlock protects this structure as well as
- * the data in all fence objects belonging to this
- * class. This should be OK as most fence objects are
- * only read from once they're created.
- */
-
- rwlock_t lock;
- struct list_head ring;
- uint32_t pending_flush;
- uint32_t waiting_types;
- wait_queue_head_t fence_queue;
- uint32_t highest_waiting_sequence;
- uint32_t latest_queued_sequence;
-};
-
-/**
- * struct ttm_fence_device
- *
- * @fence_class: Array of fence class managers.
- * @num_classes: Array dimension of @fence_class.
- * @count: Current number of fence objects for statistics.
- * @driver: Driver struct.
- *
- * Provided in the driver interface so that the driver can derive
- * from this struct for its driver_private, and accordingly
- * access the driver_private from the fence driver callbacks.
- *
- * All members except "count" are initialized at creation and
- * never touched after that. No protection needed.
- *
- * This struct is private to the fence implementation and to the fence
- * driver callbacks, and may otherwise be used by drivers only to
- * obtain the derived device_private object using container_of().
- */
-
-struct ttm_fence_device {
- struct ttm_mem_global *mem_glob;
- struct ttm_fence_class_manager *fence_class;
- uint32_t num_classes;
- atomic_t count;
- const struct ttm_fence_driver *driver;
-};
-
-/**
- * struct ttm_fence_class_init
- *
- * @wrap_diff: Fence sequence number wrap indicator. If
- * (sequence1 - sequence2) > @wrap_diff, then sequence1 is
- * considered to be older than sequence2.
- * @flush_diff: Fence sequence number flush indicator.
- * If a non-completely-signaled fence has a fence sequence number
- * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff,
- * the fence is considered too old and it will be flushed upon the
- * next call of ttm_fence_flush_old(), to make sure no fences with
- * stale sequence numbers remains unsignaled. @flush_diff should
- * be sufficiently less than @wrap_diff.
- * @sequence_mask: Mask with valid bits of the fence sequence
- * number set to 1.
- *
- * This struct is used as input to ttm_fence_device_init.
- */
-
-struct ttm_fence_class_init {
- uint32_t wrap_diff;
- uint32_t flush_diff;
- uint32_t sequence_mask;
-};
-
-/**
- * struct ttm_fence_driver
- *
- * @has_irq: Called by a potential waiter. Should return 1 if a
- * fence object with indicated parameters is expected to signal
- * automatically, and 0 if the fence implementation needs to
- * repeatedly call @poll to make it signal.
- * @emit: Make sure a fence with the given parameters is
- * present in the indicated command stream. Return its sequence number
- * in "breadcrumb".
- * @poll: Check and report sequences of the given "fence_class"
- * that have signaled "types"
- * @flush: Make sure that the types indicated by the bitfield
- * ttm_fence_class_manager::pending_flush will eventually
- * signal. These bits have been put together using the
- * result from the needed_flush function described below.
- * @needed_flush: Given the fence_class and fence_types indicated by
- * "fence", and the last received fence sequence of this
- * fence class, indicate what types need a fence flush to
- * signal. Return as a bitfield.
- * @wait: Set to non-NULL if the driver wants to override the fence
- * wait implementation. Return 0 on success, -EBUSY on failure,
- * and -ERESTART if interruptible and a signal is pending.
- * @signaled: Driver callback that is called whenever a
- * ttm_fence_object::signaled_types has changed status.
- * This function is called from atomic context,
- * with the ttm_fence_class_manager::lock held in write mode.
- * @lockup: Driver callback that is called whenever a wait has exceeded
- * the lifetime of a fence object.
- * If there is a GPU lockup,
- * this function should, if possible, reset the GPU,
- * call the ttm_fence_handler with an error status, and
- * return. If no lockup was detected, simply extend the
- * fence timeout_jiffies and return. The driver might
- * want to protect the lockup check with a mutex and cache a
- * non-locked-up status for a while to avoid an excessive
- * amount of lockup checks from every waiting thread.
- */
-
-struct ttm_fence_driver {
- bool (*has_irq) (struct ttm_fence_device *fdev,
- uint32_t fence_class, uint32_t flags);
- int (*emit) (struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t flags,
- uint32_t *breadcrumb, unsigned long *timeout_jiffies);
- void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class);
- void (*poll) (struct ttm_fence_device *fdev,
- uint32_t fence_class, uint32_t types);
- uint32_t(*needed_flush)
- (struct ttm_fence_object *fence);
- int (*wait) (struct ttm_fence_object *fence, bool lazy,
- bool interruptible, uint32_t mask);
- void (*signaled) (struct ttm_fence_object *fence);
- void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types);
-};
-
-/**
- * function ttm_fence_device_init
- *
- * @num_classes: Number of fence classes for this fence implementation.
- * @mem_global: Pointer to the global memory accounting info.
- * @fdev: Pointer to an uninitialised struct ttm_fence_device.
- * @init: Array of initialization info for each fence class.
- * @replicate_init: Use the first @init initialization info for all classes.
- * @driver: Driver callbacks.
- *
- * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if
- * out-of-memory. Otherwise returns 0.
- */
-extern int
-ttm_fence_device_init(int num_classes,
- struct ttm_mem_global *mem_glob,
- struct ttm_fence_device *fdev,
- const struct ttm_fence_class_init *init,
- bool replicate_init,
- const struct ttm_fence_driver *driver);
-
-/**
- * function ttm_fence_device_release
- *
- * @fdev: Pointer to the fence device.
- *
- * Release all resources held by a fence device. Note that before
- * this function is called, the caller must have made sure all fence
- * objects belonging to this fence device are completely signaled.
- */
-
-extern void ttm_fence_device_release(struct ttm_fence_device *fdev);
-
-/**
- * ttm_fence_handler - the fence handler.
- *
- * @fdev: Pointer to the fence device.
- * @fence_class: Fence class that signals.
- * @sequence: Signaled sequence.
- * @type: Types that signal.
- * @error: Error from the engine.
- *
- * This function signals all fences with a sequence previous to the
- * @sequence argument, and belonging to @fence_class. The signaled fence
- * types are provided in @type. If error is non-zero, the error member
- * of the fence with sequence = @sequence is set to @error. This value
- * may be reported back to user-space, indicating, for example an illegal
- * 3D command or illegal mpeg data.
- *
- * This function is typically called from the driver::poll method when the
- * command sequence preceding the fence marker has executed. It should be
- * called with the ttm_fence_class_manager::lock held in write mode and
- * may be called from interrupt context.
- */
-
-extern void
-ttm_fence_handler(struct ttm_fence_device *fdev,
- uint32_t fence_class,
- uint32_t sequence, uint32_t type, uint32_t error);
-
-/**
- * ttm_fence_driver_from_dev
- *
- * @fdev: The ttm fence device.
- *
- * Returns a pointer to the fence driver struct.
- */
-
-static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev(
- struct ttm_fence_device *fdev)
-{
- return fdev->driver;
-}
-
-/**
- * ttm_fence_driver
- *
- * @fence: Pointer to a ttm fence object.
- *
- * Returns a pointer to the fence driver struct.
- */
-
-static inline const struct ttm_fence_driver *ttm_fence_driver(struct
- ttm_fence_object
- *fence)
-{
- return ttm_fence_driver_from_dev(fence->fdev);
-}
-
-/**
- * ttm_fence_fc
- *
- * @fence: Pointer to a ttm fence object.
- *
- * Returns a pointer to the struct ttm_fence_class_manager for the
- * fence class of @fence.
- */
-
-static inline struct ttm_fence_class_manager *ttm_fence_fc(struct
- ttm_fence_object
- *fence)
-{
- return &fence->fdev->fence_class[fence->fence_class];
-}
-
-#endif
diff --git a/drivers/staging/gma500/psb_ttm_fence_user.c b/drivers/staging/gma500/psb_ttm_fence_user.c
deleted file mode 100644
index 36f974fc607d..000000000000
--- a/drivers/staging/gma500/psb_ttm_fence_user.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include <drm/drmP.h>
-#include "psb_ttm_fence_user.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_driver.h"
-#include "psb_ttm_userobj_api.h"
-
-/**
- * struct ttm_fence_user_object
- *
- * @base: The base object used for user-space visibility and refcounting.
- *
- * @fence: The fence object itself.
- *
- */
-
-struct ttm_fence_user_object {
- struct ttm_base_object base;
- struct ttm_fence_object fence;
-};
-
-static struct ttm_fence_user_object *ttm_fence_user_object_lookup(
- struct ttm_object_file *tfile,
- uint32_t handle)
-{
- struct ttm_base_object *base;
-
- base = ttm_base_object_lookup(tfile, handle);
- if (unlikely(base == NULL)) {
- printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
- (unsigned long)handle);
- return NULL;
- }
-
- if (unlikely(base->object_type != ttm_fence_type)) {
- ttm_base_object_unref(&base);
- printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
- (unsigned long)handle);
- return NULL;
- }
-
- return container_of(base, struct ttm_fence_user_object, base);
-}
-
-/*
- * The fence object destructor.
- */
-
-static void ttm_fence_user_destroy(struct ttm_fence_object *fence)
-{
- struct ttm_fence_user_object *ufence =
- container_of(fence, struct ttm_fence_user_object, fence);
-
- ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence));
- kfree(ufence);
-}
-
-/*
- * The base object destructor. We basically unly unreference the
- * attached fence object.
- */
-
-static void ttm_fence_user_release(struct ttm_base_object **p_base)
-{
- struct ttm_fence_user_object *ufence;
- struct ttm_base_object *base = *p_base;
- struct ttm_fence_object *fence;
-
- *p_base = NULL;
-
- if (unlikely(base == NULL))
- return;
-
- ufence = container_of(base, struct ttm_fence_user_object, base);
- fence = &ufence->fence;
- ttm_fence_object_unref(&fence);
-}
-
-int
-ttm_fence_user_create(struct ttm_fence_device *fdev,
- struct ttm_object_file *tfile,
- uint32_t fence_class,
- uint32_t fence_types,
- uint32_t create_flags,
- struct ttm_fence_object **fence,
- uint32_t *user_handle)
-{
- int ret;
- struct ttm_fence_object *tmp;
- struct ttm_fence_user_object *ufence;
-
- ret = ttm_mem_global_alloc(fdev->mem_glob,
- sizeof(*ufence),
- false,
- false);
- if (unlikely(ret != 0))
- return -ENOMEM;
-
- ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
- if (unlikely(ufence == NULL)) {
- ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
- return -ENOMEM;
- }
-
- ret = ttm_fence_object_init(fdev,
- fence_class,
- fence_types, create_flags,
- &ttm_fence_user_destroy, &ufence->fence);
-
- if (unlikely(ret != 0))
- goto out_err0;
-
- /*
- * One fence ref is held by the fence ptr we return.
- * The other one by the base object. Need to up the
- * fence refcount before we publish this object to
- * user-space.
- */
-
- tmp = ttm_fence_object_ref(&ufence->fence);
- ret = ttm_base_object_init(tfile, &ufence->base,
- false, ttm_fence_type,
- &ttm_fence_user_release, NULL);
-
- if (unlikely(ret != 0))
- goto out_err1;
-
- *fence = &ufence->fence;
- *user_handle = ufence->base.hash.key;
-
- return 0;
-out_err1:
- ttm_fence_object_unref(&tmp);
- tmp = &ufence->fence;
- ttm_fence_object_unref(&tmp);
- return ret;
-out_err0:
- ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
- kfree(ufence);
- return ret;
-}
-
-int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data)
-{
- int ret;
- union ttm_fence_signaled_arg *arg = data;
- struct ttm_fence_object *fence;
- struct ttm_fence_info info;
- struct ttm_fence_user_object *ufence;
- struct ttm_base_object *base;
- ret = 0;
-
- ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
- if (unlikely(ufence == NULL))
- return -EINVAL;
-
- fence = &ufence->fence;
-
- if (arg->req.flush) {
- ret = ttm_fence_object_flush(fence, arg->req.fence_type);
- if (unlikely(ret != 0))
- goto out;
- }
-
- info = ttm_fence_get_info(fence);
- arg->rep.signaled_types = info.signaled_types;
- arg->rep.fence_error = info.error;
-
-out:
- base = &ufence->base;
- ttm_base_object_unref(&base);
- return ret;
-}
-
-int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data)
-{
- int ret;
- union ttm_fence_finish_arg *arg = data;
- struct ttm_fence_user_object *ufence;
- struct ttm_base_object *base;
- struct ttm_fence_object *fence;
- ret = 0;
-
- ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
- if (unlikely(ufence == NULL))
- return -EINVAL;
-
- fence = &ufence->fence;
-
- ret = ttm_fence_object_wait(fence,
- arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY,
- true, arg->req.fence_type);
- if (likely(ret == 0)) {
- struct ttm_fence_info info = ttm_fence_get_info(fence);
-
- arg->rep.signaled_types = info.signaled_types;
- arg->rep.fence_error = info.error;
- }
-
- base = &ufence->base;
- ttm_base_object_unref(&base);
-
- return ret;
-}
-
-int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data)
-{
- struct ttm_fence_unref_arg *arg = data;
- int ret = 0;
-
- ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type);
- return ret;
-}
diff --git a/drivers/staging/gma500/psb_ttm_fence_user.h b/drivers/staging/gma500/psb_ttm_fence_user.h
deleted file mode 100644
index 762a05728632..000000000000
--- a/drivers/staging/gma500/psb_ttm_fence_user.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef TTM_FENCE_USER_H
-#define TTM_FENCE_USER_H
-
-#if !defined(__KERNEL__) && !defined(_KERNEL)
-#include <stdint.h>
-#endif
-
-#define TTM_FENCE_MAJOR 0
-#define TTM_FENCE_MINOR 1
-#define TTM_FENCE_PL 0
-#define TTM_FENCE_DATE "080819"
-
-/**
- * struct ttm_fence_signaled_req
- *
- * @handle: Handle to the fence object. Input.
- *
- * @fence_type: Fence types we want to flush. Input.
- *
- * @flush: Boolean. Flush the indicated fence_types. Input.
- *
- * Argument to the TTM_FENCE_SIGNALED ioctl.
- */
-
-struct ttm_fence_signaled_req {
- uint32_t handle;
- uint32_t fence_type;
- int32_t flush;
- uint32_t pad64;
-};
-
-/**
- * struct ttm_fence_rep
- *
- * @signaled_types: Fence type that has signaled.
- *
- * @fence_error: Command execution error.
- * Hardware errors that are consequences of the execution
- * of the command stream preceding the fence are reported
- * here.
- *
- * Output argument to the TTM_FENCE_SIGNALED and
- * TTM_FENCE_FINISH ioctls.
- */
-
-struct ttm_fence_rep {
- uint32_t signaled_types;
- uint32_t fence_error;
-};
-
-union ttm_fence_signaled_arg {
- struct ttm_fence_signaled_req req;
- struct ttm_fence_rep rep;
-};
-
-/*
- * Waiting mode flags for the TTM_FENCE_FINISH ioctl.
- *
- * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling
- * wait.
- *
- * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU,
- * but return -EBUSY if the buffer is busy.
- */
-
-#define TTM_FENCE_FINISH_MODE_LAZY (1 << 0)
-#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1)
-
-/**
- * struct ttm_fence_finish_req
- *
- * @handle: Handle to the fence object. Input.
- *
- * @fence_type: Fence types we want to finish.
- *
- * @mode: Wait mode.
- *
- * Input to the TTM_FENCE_FINISH ioctl.
- */
-
-struct ttm_fence_finish_req {
- uint32_t handle;
- uint32_t fence_type;
- uint32_t mode;
- uint32_t pad64;
-};
-
-union ttm_fence_finish_arg {
- struct ttm_fence_finish_req req;
- struct ttm_fence_rep rep;
-};
-
-/**
- * struct ttm_fence_unref_arg
- *
- * @handle: Handle to the fence object.
- *
- * Argument to the TTM_FENCE_UNREF ioctl.
- */
-
-struct ttm_fence_unref_arg {
- uint32_t handle;
- uint32_t pad64;
-};
-
-/*
- * Ioctl offsets from extenstion start.
- */
-
-#define TTM_FENCE_SIGNALED 0x01
-#define TTM_FENCE_FINISH 0x02
-#define TTM_FENCE_UNREF 0x03
-
-#endif
diff --git a/drivers/staging/gma500/psb_ttm_glue.c b/drivers/staging/gma500/psb_ttm_glue.c
deleted file mode 100644
index d1d965e69ecd..000000000000
--- a/drivers/staging/gma500/psb_ttm_glue.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2008, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_ttm_userobj_api.h"
-#include <linux/io.h>
-
-
-static struct vm_operations_struct psb_ttm_vm_ops;
-
-/**
- * NOTE: driver_private of drm_file is now a struct psb_file_data struct
- * pPriv in struct psb_file_data contains the original psb_fpriv;
- */
-int psb_open(struct inode *inode, struct file *filp)
-{
- struct drm_file *file_priv;
- struct drm_psb_private *dev_priv;
- struct psb_fpriv *psb_fp;
- struct psb_file_data *pvr_file_priv;
- int ret;
-
- DRM_DEBUG("\n");
-
- ret = drm_open(inode, filp);
- if (unlikely(ret))
- return ret;
-
- psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL);
-
- if (unlikely(psb_fp == NULL))
- goto out_err0;
-
- file_priv = (struct drm_file *) filp->private_data;
- dev_priv = psb_priv(file_priv->minor->dev);
-
- DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0);
-
- psb_fp->tfile = ttm_object_file_init(dev_priv->tdev,
- PSB_FILE_OBJECT_HASH_ORDER);
- if (unlikely(psb_fp->tfile == NULL))
- goto out_err1;
-
- pvr_file_priv = (struct psb_file_data *)file_priv->driver_priv;
- if (!pvr_file_priv) {
- DRM_ERROR("drm file private is NULL\n");
- goto out_err1;
- }
-
- pvr_file_priv->priv = psb_fp;
- if (unlikely(dev_priv->bdev.dev_mapping == NULL))
- dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping;
-
- return 0;
-
-out_err1:
- kfree(psb_fp);
-out_err0:
- (void) drm_release(inode, filp);
- return ret;
-}
-
-int psb_release(struct inode *inode, struct file *filp)
-{
- struct drm_file *file_priv;
- struct psb_fpriv *psb_fp;
- struct drm_psb_private *dev_priv;
- int ret;
- file_priv = (struct drm_file *) filp->private_data;
- psb_fp = psb_fpriv(file_priv);
- dev_priv = psb_priv(file_priv->minor->dev);
-
- ttm_object_file_release(&psb_fp->tfile);
- kfree(psb_fp);
-
- ret = drm_release(inode, filp);
-
- return ret;
-}
-
-int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
-
- return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile,
- &psb_priv(dev)->ttm_lock, data);
-
-}
-
-int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
-
-}
-
-int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- return ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data);
-
-}
-
-int psb_pl_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
-
- return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile,
- &dev_priv->bdev, &dev_priv->ttm_lock, data);
-
-}
-
-int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
-
- return ttm_pl_ub_create_ioctl(psb_fpriv(file_priv)->tfile,
- &dev_priv->bdev, &dev_priv->ttm_lock, data);
-
-}
-/**
- * psb_ttm_fault - Wrapper around the ttm fault method.
- *
- * @vma: The struct vm_area_struct as in the vm fault() method.
- * @vmf: The struct vm_fault as in the vm fault() method.
- *
- * Since ttm_fault() will reserve buffers while faulting,
- * we need to take the ttm read lock around it, as this driver
- * relies on the ttm_lock in write mode to exclude all threads from
- * reserving and thus validating buffers in aperture- and memory shortage
- * situations.
- */
-
-static int psb_ttm_fault(struct vm_area_struct *vma,
- struct vm_fault *vmf)
-{
- struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
- vma->vm_private_data;
- struct drm_psb_private *dev_priv =
- container_of(bo->bdev, struct drm_psb_private, bdev);
- int ret;
-
- ret = ttm_read_lock(&dev_priv->ttm_lock, true);
- if (unlikely(ret != 0))
- return VM_FAULT_NOPAGE;
-
- ret = dev_priv->ttm_vm_ops->fault(vma, vmf);
-
- ttm_read_unlock(&dev_priv->ttm_lock);
- return ret;
-}
-
-/**
- * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to
- * PVRMMap
- */
-int psb_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct drm_file *file_priv;
- struct drm_psb_private *dev_priv;
- int ret;
-
- if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET ||
- vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET)
-#if 0 /* FIXMEAC */
- return PVRMMap(filp, vma);
-#else
- return -EINVAL;
-#endif
-
- file_priv = (struct drm_file *) filp->private_data;
- dev_priv = psb_priv(file_priv->minor->dev);
-
- ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev);
- if (unlikely(ret != 0))
- return ret;
-
- if (unlikely(dev_priv->ttm_vm_ops == NULL)) {
- dev_priv->ttm_vm_ops = (struct vm_operations_struct *)
- vma->vm_ops;
- psb_ttm_vm_ops = *vma->vm_ops;
- psb_ttm_vm_ops.fault = &psb_ttm_fault;
- }
-
- vma->vm_ops = &psb_ttm_vm_ops;
-
- return 0;
-}
-/*
-ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos)
-{
- struct drm_file *file_priv = (struct drm_file *)filp->private_data;
- struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
-
- return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1);
-}
-
-ssize_t psb_ttm_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos)
-{
- struct drm_file *file_priv = (struct drm_file *)filp->private_data;
- struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
-
- return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1);
-}
-*/
-int psb_verify_access(struct ttm_buffer_object *bo,
- struct file *filp)
-{
- struct drm_file *file_priv = (struct drm_file *)filp->private_data;
-
- if (capable(CAP_SYS_ADMIN))
- return 0;
-
- if (unlikely(!file_priv->authenticated))
- return -EPERM;
-
- return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile);
-}
-
-static int psb_ttm_mem_global_init(struct drm_global_reference *ref)
-{
- return ttm_mem_global_init(ref->object);
-}
-
-static void psb_ttm_mem_global_release(struct drm_global_reference *ref)
-{
- ttm_mem_global_release(ref->object);
-}
-
-int psb_ttm_global_init(struct drm_psb_private *dev_priv)
-{
- struct drm_global_reference *global_ref;
- int ret;
-
- global_ref = &dev_priv->mem_global_ref;
- global_ref->global_type = DRM_GLOBAL_TTM_MEM;
- global_ref->size = sizeof(struct ttm_mem_global);
- global_ref->init = &psb_ttm_mem_global_init;
- global_ref->release = &psb_ttm_mem_global_release;
-
- ret = drm_global_item_ref(global_ref);
- if (unlikely(ret != 0)) {
- DRM_ERROR("Failed referencing a global TTM memory object.\n");
- return ret;
- }
-
- dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object;
- global_ref = &dev_priv->bo_global_ref.ref;
- global_ref->global_type = DRM_GLOBAL_TTM_BO;
- global_ref->size = sizeof(struct ttm_bo_global);
- global_ref->init = &ttm_bo_global_init;
- global_ref->release = &ttm_bo_global_release;
- ret = drm_global_item_ref(global_ref);
- if (ret != 0) {
- DRM_ERROR("Failed setting up TTM BO subsystem.\n");
- drm_global_item_unref(global_ref);
- return ret;
- }
- return 0;
-}
-
-void psb_ttm_global_release(struct drm_psb_private *dev_priv)
-{
- drm_global_item_unref(&dev_priv->mem_global_ref);
-}
-
-int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_getpageaddrs_arg *arg = data;
- struct ttm_buffer_object *bo;
- struct ttm_tt *ttm;
- struct page **tt_pages;
- unsigned long i, num_pages;
- unsigned long *p = arg->page_addrs;
- int ret = 0;
-
- bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile,
- arg->handle);
- if (unlikely(bo == NULL)) {
- printk(KERN_ERR
- "Could not find buffer object for getpageaddrs.\n");
- return -EINVAL;
- }
-
- arg->gtt_offset = bo->offset;
- ttm = bo->ttm;
- num_pages = ttm->num_pages;
- tt_pages = ttm->pages;
-
- for (i = 0; i < num_pages; i++)
- p[i] = (unsigned long)page_to_phys(tt_pages[i]);
-
- return ret;
-}
diff --git a/drivers/staging/gma500/psb_ttm_placement_user.c b/drivers/staging/gma500/psb_ttm_placement_user.c
deleted file mode 100644
index 272b397982ed..000000000000
--- a/drivers/staging/gma500/psb_ttm_placement_user.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "psb_ttm_placement_user.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_lock.h"
-#include <linux/slab.h>
-#include <linux/sched.h>
-
-struct ttm_bo_user_object {
- struct ttm_base_object base;
- struct ttm_buffer_object bo;
-};
-
-static size_t pl_bo_size;
-
-static uint32_t psb_busy_prios[] = {
- TTM_PL_TT,
- TTM_PL_PRIV0, /* CI */
- TTM_PL_PRIV2, /* RAR */
- TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */
- TTM_PL_SYSTEM
-};
-
-static const struct ttm_placement default_placement = {
- 0, 0, 0, NULL, 5, psb_busy_prios
-};
-
-static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages)
-{
- size_t page_array_size =
- (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK;
-
- if (unlikely(pl_bo_size == 0)) {
- pl_bo_size = bdev->glob->ttm_bo_extra_size +
- ttm_round_pot(sizeof(struct ttm_bo_user_object));
- }
-
- return bdev->glob->ttm_bo_size + 2 * page_array_size;
-}
-
-static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file
- *tfile, uint32_t handle)
-{
- struct ttm_base_object *base;
-
- base = ttm_base_object_lookup(tfile, handle);
- if (unlikely(base == NULL)) {
- printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
- (unsigned long)handle);
- return NULL;
- }
-
- if (unlikely(base->object_type != ttm_buffer_type)) {
- ttm_base_object_unref(&base);
- printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
- (unsigned long)handle);
- return NULL;
- }
-
- return container_of(base, struct ttm_bo_user_object, base);
-}
-
-struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
- *tfile, uint32_t handle)
-{
- struct ttm_bo_user_object *user_bo;
- struct ttm_base_object *base;
-
- user_bo = ttm_bo_user_lookup(tfile, handle);
- if (unlikely(user_bo == NULL))
- return NULL;
-
- (void)ttm_bo_reference(&user_bo->bo);
- base = &user_bo->base;
- ttm_base_object_unref(&base);
- return &user_bo->bo;
-}
-
-static void ttm_bo_user_destroy(struct ttm_buffer_object *bo)
-{
- struct ttm_bo_user_object *user_bo =
- container_of(bo, struct ttm_bo_user_object, bo);
-
- ttm_mem_global_free(bo->glob->mem_glob, bo->acc_size);
- kfree(user_bo);
-}
-
-static void ttm_bo_user_release(struct ttm_base_object **p_base)
-{
- struct ttm_bo_user_object *user_bo;
- struct ttm_base_object *base = *p_base;
- struct ttm_buffer_object *bo;
-
- *p_base = NULL;
-
- if (unlikely(base == NULL))
- return;
-
- user_bo = container_of(base, struct ttm_bo_user_object, base);
- bo = &user_bo->bo;
- ttm_bo_unref(&bo);
-}
-
-static void ttm_bo_user_ref_release(struct ttm_base_object *base,
- enum ttm_ref_type ref_type)
-{
- struct ttm_bo_user_object *user_bo =
- container_of(base, struct ttm_bo_user_object, base);
- struct ttm_buffer_object *bo = &user_bo->bo;
-
- switch (ref_type) {
- case TTM_REF_SYNCCPU_WRITE:
- ttm_bo_synccpu_write_release(bo);
- break;
- default:
- BUG();
- }
-}
-
-static void ttm_pl_fill_rep(struct ttm_buffer_object *bo,
- struct ttm_pl_rep *rep)
-{
- struct ttm_bo_user_object *user_bo =
- container_of(bo, struct ttm_bo_user_object, bo);
-
- rep->gpu_offset = bo->offset;
- rep->bo_size = bo->num_pages << PAGE_SHIFT;
- rep->map_handle = bo->addr_space_offset;
- rep->placement = bo->mem.placement;
- rep->handle = user_bo->base.hash.key;
- rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg;
-}
-
-/* FIXME Copy from upstream TTM */
-static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
- unsigned long num_pages)
-{
- size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
- PAGE_MASK;
-
- return glob->ttm_bo_size + 2 * page_array_size;
-}
-
-/* FIXME Copy from upstream TTM "ttm_bo_create", upstream TTM does not
- export this, so copy it here */
-static int ttm_bo_create_private(struct ttm_bo_device *bdev,
- unsigned long size,
- enum ttm_bo_type type,
- struct ttm_placement *placement,
- uint32_t page_alignment,
- unsigned long buffer_start,
- bool interruptible,
- struct file *persistant_swap_storage,
- struct ttm_buffer_object **p_bo)
-{
- struct ttm_buffer_object *bo;
- struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
- int ret;
-
- size_t acc_size =
- ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
- ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
- if (unlikely(ret != 0))
- return ret;
-
- bo = kzalloc(sizeof(*bo), GFP_KERNEL);
-
- if (unlikely(bo == NULL)) {
- ttm_mem_global_free(mem_glob, acc_size);
- return -ENOMEM;
- }
-
- ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
- buffer_start, interruptible,
- persistant_swap_storage, acc_size, NULL);
- if (likely(ret == 0))
- *p_bo = bo;
-
- return ret;
-}
-
-int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
- struct ttm_placement *placement)
-{
- int i;
-
- for (i = 0; i < placement->num_placement; i++) {
- if (!capable(CAP_SYS_ADMIN)) {
- if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
- printk(KERN_ERR TTM_PFX "Need to be root to "
- "modify NO_EVICT status.\n");
- return -EINVAL;
- }
- }
- }
- for (i = 0; i < placement->num_busy_placement; i++) {
- if (!capable(CAP_SYS_ADMIN)) {
- if (placement->busy_placement[i]
- & TTM_PL_FLAG_NO_EVICT) {
- printk(KERN_ERR TTM_PFX "Need to be root to modify NO_EVICT status.\n");
- return -EINVAL;
- }
- }
- }
- return 0;
-}
-
-int ttm_buffer_object_create(struct ttm_bo_device *bdev,
- unsigned long size,
- enum ttm_bo_type type,
- uint32_t flags,
- uint32_t page_alignment,
- unsigned long buffer_start,
- bool interruptible,
- struct file *persistant_swap_storage,
- struct ttm_buffer_object **p_bo)
-{
- struct ttm_placement placement = default_placement;
- int ret;
-
- if ((flags & TTM_PL_MASK_CACHING) == 0)
- flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-
- placement.num_placement = 1;
- placement.placement = &flags;
-
- ret = ttm_bo_create_private(bdev,
- size,
- type,
- &placement,
- page_alignment,
- buffer_start,
- interruptible,
- persistant_swap_storage,
- p_bo);
-
- return ret;
-}
-
-
-int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
- struct ttm_bo_device *bdev,
- struct ttm_lock *lock, void *data)
-{
- union ttm_pl_create_arg *arg = data;
- struct ttm_pl_create_req *req = &arg->req;
- struct ttm_pl_rep *rep = &arg->rep;
- struct ttm_buffer_object *bo;
- struct ttm_buffer_object *tmp;
- struct ttm_bo_user_object *user_bo;
- uint32_t flags;
- int ret = 0;
- struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
- struct ttm_placement placement = default_placement;
- size_t acc_size =
- ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
- ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
- if (unlikely(ret != 0))
- return ret;
-
- flags = req->placement;
- user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
- if (unlikely(user_bo == NULL)) {
- ttm_mem_global_free(mem_glob, acc_size);
- return -ENOMEM;
- }
-
- bo = &user_bo->bo;
- ret = ttm_read_lock(lock, true);
- if (unlikely(ret != 0)) {
- ttm_mem_global_free(mem_glob, acc_size);
- kfree(user_bo);
- return ret;
- }
-
- placement.num_placement = 1;
- placement.placement = &flags;
-
- if ((flags & TTM_PL_MASK_CACHING) == 0)
- flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-
- ret = ttm_bo_init(bdev, bo, req->size,
- ttm_bo_type_device, &placement,
- req->page_alignment, 0, true,
- NULL, acc_size, &ttm_bo_user_destroy);
- ttm_read_unlock(lock);
-
- /*
- * Note that the ttm_buffer_object_init function
- * would've called the destroy function on failure!!
- */
-
- if (unlikely(ret != 0))
- goto out;
-
- tmp = ttm_bo_reference(bo);
- ret = ttm_base_object_init(tfile, &user_bo->base,
- flags & TTM_PL_FLAG_SHARED,
- ttm_buffer_type,
- &ttm_bo_user_release,
- &ttm_bo_user_ref_release);
- if (unlikely(ret != 0))
- goto out_err;
-
- ttm_pl_fill_rep(bo, rep);
- ttm_bo_unref(&bo);
-out:
- return 0;
-out_err:
- ttm_bo_unref(&tmp);
- ttm_bo_unref(&bo);
- return ret;
-}
-
-int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
- struct ttm_bo_device *bdev,
- struct ttm_lock *lock, void *data)
-{
- union ttm_pl_create_ub_arg *arg = data;
- struct ttm_pl_create_ub_req *req = &arg->req;
- struct ttm_pl_rep *rep = &arg->rep;
- struct ttm_buffer_object *bo;
- struct ttm_buffer_object *tmp;
- struct ttm_bo_user_object *user_bo;
- uint32_t flags;
- int ret = 0;
- struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
- struct ttm_placement placement = default_placement;
- size_t acc_size =
- ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
- ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
- if (unlikely(ret != 0))
- return ret;
-
- flags = req->placement;
- user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
- if (unlikely(user_bo == NULL)) {
- ttm_mem_global_free(mem_glob, acc_size);
- return -ENOMEM;
- }
- ret = ttm_read_lock(lock, true);
- if (unlikely(ret != 0)) {
- ttm_mem_global_free(mem_glob, acc_size);
- kfree(user_bo);
- return ret;
- }
- bo = &user_bo->bo;
-
- placement.num_placement = 1;
- placement.placement = &flags;
-
- ret = ttm_bo_init(bdev,
- bo,
- req->size,
- ttm_bo_type_user,
- &placement,
- req->page_alignment,
- req->user_address,
- true,
- NULL,
- acc_size,
- &ttm_bo_user_destroy);
-
- /*
- * Note that the ttm_buffer_object_init function
- * would've called the destroy function on failure!!
- */
- ttm_read_unlock(lock);
- if (unlikely(ret != 0))
- goto out;
-
- tmp = ttm_bo_reference(bo);
- ret = ttm_base_object_init(tfile, &user_bo->base,
- flags & TTM_PL_FLAG_SHARED,
- ttm_buffer_type,
- &ttm_bo_user_release,
- &ttm_bo_user_ref_release);
- if (unlikely(ret != 0))
- goto out_err;
-
- ttm_pl_fill_rep(bo, rep);
- ttm_bo_unref(&bo);
-out:
- return 0;
-out_err:
- ttm_bo_unref(&tmp);
- ttm_bo_unref(&bo);
- return ret;
-}
-
-int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data)
-{
- union ttm_pl_reference_arg *arg = data;
- struct ttm_pl_rep *rep = &arg->rep;
- struct ttm_bo_user_object *user_bo;
- struct ttm_buffer_object *bo;
- struct ttm_base_object *base;
- int ret;
-
- user_bo = ttm_bo_user_lookup(tfile, arg->req.handle);
- if (unlikely(user_bo == NULL)) {
- printk(KERN_ERR "Could not reference buffer object.\n");
- return -EINVAL;
- }
-
- bo = &user_bo->bo;
- ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL);
- if (unlikely(ret != 0)) {
- printk(KERN_ERR
- "Could not add a reference to buffer object.\n");
- goto out;
- }
-
- ttm_pl_fill_rep(bo, rep);
-
-out:
- base = &user_bo->base;
- ttm_base_object_unref(&base);
- return ret;
-}
-
-int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data)
-{
- struct ttm_pl_reference_req *arg = data;
-
- return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE);
-}
-
-int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data)
-{
- struct ttm_pl_synccpu_arg *arg = data;
- struct ttm_bo_user_object *user_bo;
- struct ttm_buffer_object *bo;
- struct ttm_base_object *base;
- bool existed;
- int ret;
-
- switch (arg->op) {
- case TTM_PL_SYNCCPU_OP_GRAB:
- user_bo = ttm_bo_user_lookup(tfile, arg->handle);
- if (unlikely(user_bo == NULL)) {
- printk(KERN_ERR
- "Could not find buffer object for synccpu.\n");
- return -EINVAL;
- }
- bo = &user_bo->bo;
- base = &user_bo->base;
- ret = ttm_bo_synccpu_write_grab(bo,
- arg->access_mode &
- TTM_PL_SYNCCPU_MODE_NO_BLOCK);
- if (unlikely(ret != 0)) {
- ttm_base_object_unref(&base);
- goto out;
- }
- ret = ttm_ref_object_add(tfile, &user_bo->base,
- TTM_REF_SYNCCPU_WRITE, &existed);
- if (existed || ret != 0)
- ttm_bo_synccpu_write_release(bo);
- ttm_base_object_unref(&base);
- break;
- case TTM_PL_SYNCCPU_OP_RELEASE:
- ret = ttm_ref_object_base_unref(tfile, arg->handle,
- TTM_REF_SYNCCPU_WRITE);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-out:
- return ret;
-}
-
-int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
- struct ttm_lock *lock, void *data)
-{
- union ttm_pl_setstatus_arg *arg = data;
- struct ttm_pl_setstatus_req *req = &arg->req;
- struct ttm_pl_rep *rep = &arg->rep;
- struct ttm_buffer_object *bo;
- struct ttm_bo_device *bdev;
- struct ttm_placement placement = default_placement;
- uint32_t flags[2];
- int ret;
-
- bo = ttm_buffer_object_lookup(tfile, req->handle);
- if (unlikely(bo == NULL)) {
- printk(KERN_ERR
- "Could not find buffer object for setstatus.\n");
- return -EINVAL;
- }
-
- bdev = bo->bdev;
-
- ret = ttm_read_lock(lock, true);
- if (unlikely(ret != 0))
- goto out_err0;
-
- ret = ttm_bo_reserve(bo, true, false, false, 0);
- if (unlikely(ret != 0))
- goto out_err1;
-
- ret = ttm_bo_wait_cpu(bo, false);
- if (unlikely(ret != 0))
- goto out_err2;
-
- flags[0] = req->set_placement;
- flags[1] = req->clr_placement;
-
- placement.num_placement = 2;
- placement.placement = flags;
-
- /* Review internal locking ? FIXMEAC */
- ret = psb_ttm_bo_check_placement(bo, &placement);
- if (unlikely(ret != 0))
- goto out_err2;
-
- placement.num_placement = 1;
- flags[0] = (req->set_placement | bo->mem.placement)
- & ~req->clr_placement;
-
- ret = ttm_bo_validate(bo, &placement, true, false, false);
- if (unlikely(ret != 0))
- goto out_err2;
-
- ttm_pl_fill_rep(bo, rep);
-out_err2:
- ttm_bo_unreserve(bo);
-out_err1:
- ttm_read_unlock(lock);
-out_err0:
- ttm_bo_unref(&bo);
- return ret;
-}
-
-static int psb_ttm_bo_block_reservation(struct ttm_buffer_object *bo,
- bool interruptible, bool no_wait)
-{
- int ret;
-
- while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
- if (no_wait)
- return -EBUSY;
- else if (interruptible) {
- ret = wait_event_interruptible(bo->event_queue,
- atomic_read(&bo->reserved) == 0);
- if (unlikely(ret != 0))
- return -ERESTART;
- } else {
- wait_event(bo->event_queue,
- atomic_read(&bo->reserved) == 0);
- }
- }
- return 0;
-}
-
-static void psb_ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
-{
- atomic_set(&bo->reserved, 0);
- wake_up_all(&bo->event_queue);
-}
-
-int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data)
-{
- struct ttm_pl_waitidle_arg *arg = data;
- struct ttm_buffer_object *bo;
- int ret;
-
- bo = ttm_buffer_object_lookup(tfile, arg->handle);
- if (unlikely(bo == NULL)) {
- printk(KERN_ERR "Could not find buffer object for waitidle.\n");
- return -EINVAL;
- }
-
- ret =
- psb_ttm_bo_block_reservation(bo, true,
- arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
- if (unlikely(ret != 0))
- goto out;
- ret = ttm_bo_wait(bo,
- arg->mode & TTM_PL_WAITIDLE_MODE_LAZY,
- true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
- psb_ttm_bo_unblock_reservation(bo);
-out:
- ttm_bo_unref(&bo);
- return ret;
-}
-
-int ttm_pl_verify_access(struct ttm_buffer_object *bo,
- struct ttm_object_file *tfile)
-{
- struct ttm_bo_user_object *ubo;
-
- /*
- * Check bo subclass.
- */
-
- if (unlikely(bo->destroy != &ttm_bo_user_destroy))
- return -EPERM;
-
- ubo = container_of(bo, struct ttm_bo_user_object, bo);
- if (likely(ubo->base.shareable || ubo->base.tfile == tfile))
- return 0;
-
- return -EPERM;
-}
diff --git a/drivers/staging/gma500/psb_ttm_placement_user.h b/drivers/staging/gma500/psb_ttm_placement_user.h
deleted file mode 100644
index 8b7068b54441..000000000000
--- a/drivers/staging/gma500/psb_ttm_placement_user.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef _TTM_PLACEMENT_USER_H_
-#define _TTM_PLACEMENT_USER_H_
-
-#if !defined(__KERNEL__) && !defined(_KERNEL)
-#include <stdint.h>
-#else
-#include <linux/kernel.h>
-#endif
-
-#include "ttm/ttm_placement.h"
-
-#define TTM_PLACEMENT_MAJOR 0
-#define TTM_PLACEMENT_MINOR 1
-#define TTM_PLACEMENT_PL 0
-#define TTM_PLACEMENT_DATE "080819"
-
-/**
- * struct ttm_pl_create_req
- *
- * @size: The buffer object size.
- * @placement: Flags that indicate initial acceptable
- * placement.
- * @page_alignment: Required alignment in pages.
- *
- * Input to the TTM_BO_CREATE ioctl.
- */
-
-struct ttm_pl_create_req {
- uint64_t size;
- uint32_t placement;
- uint32_t page_alignment;
-};
-
-/**
- * struct ttm_pl_create_ub_req
- *
- * @size: The buffer object size.
- * @user_address: User-space address of the memory area that
- * should be used to back the buffer object cast to 64-bit.
- * @placement: Flags that indicate initial acceptable
- * placement.
- * @page_alignment: Required alignment in pages.
- *
- * Input to the TTM_BO_CREATE_UB ioctl.
- */
-
-struct ttm_pl_create_ub_req {
- uint64_t size;
- uint64_t user_address;
- uint32_t placement;
- uint32_t page_alignment;
-};
-
-/**
- * struct ttm_pl_rep
- *
- * @gpu_offset: The current offset into the memory region used.
- * This can be used directly by the GPU if there are no
- * additional GPU mapping procedures used by the driver.
- *
- * @bo_size: Actual buffer object size.
- *
- * @map_handle: Offset into the device address space.
- * Used for map, seek, read, write. This will never change
- * during the lifetime of an object.
- *
- * @placement: Flag indicating the placement status of
- * the buffer object using the TTM_PL flags above.
- *
- * @sync_object_arg: Used for user-space synchronization and
- * depends on the synchronization model used. If fences are
- * used, this is the buffer_object::fence_type_mask
- *
- * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and
- * TTM_PL_SETSTATUS ioctls.
- */
-
-struct ttm_pl_rep {
- uint64_t gpu_offset;
- uint64_t bo_size;
- uint64_t map_handle;
- uint32_t placement;
- uint32_t handle;
- uint32_t sync_object_arg;
- uint32_t pad64;
-};
-
-/**
- * struct ttm_pl_setstatus_req
- *
- * @set_placement: Placement flags to set.
- *
- * @clr_placement: Placement flags to clear.
- *
- * @handle: The object handle
- *
- * Input to the TTM_PL_SETSTATUS ioctl.
- */
-
-struct ttm_pl_setstatus_req {
- uint32_t set_placement;
- uint32_t clr_placement;
- uint32_t handle;
- uint32_t pad64;
-};
-
-/**
- * struct ttm_pl_reference_req
- *
- * @handle: The object to put a reference on.
- *
- * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls.
- */
-
-struct ttm_pl_reference_req {
- uint32_t handle;
- uint32_t pad64;
-};
-
-/*
- * ACCESS mode flags for SYNCCPU.
- *
- * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not
- * writing to the buffer.
- *
- * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not
- * accessing the buffer.
- *
- * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait
- * for GPU accesses to finish but return -EBUSY.
- *
- * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable
- * memory while synchronized for CPU.
- */
-
-#define TTM_PL_SYNCCPU_MODE_READ TTM_ACCESS_READ
-#define TTM_PL_SYNCCPU_MODE_WRITE TTM_ACCESS_WRITE
-#define TTM_PL_SYNCCPU_MODE_NO_BLOCK (1 << 2)
-#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3)
-
-/**
- * struct ttm_pl_synccpu_arg
- *
- * @handle: The object to synchronize.
- *
- * @access_mode: access mode indicated by the
- * TTM_SYNCCPU_MODE flags.
- *
- * @op: indicates whether to grab or release the
- * buffer for cpu usage.
- *
- * Input to the TTM_PL_SYNCCPU ioctl.
- */
-
-struct ttm_pl_synccpu_arg {
- uint32_t handle;
- uint32_t access_mode;
- enum {
- TTM_PL_SYNCCPU_OP_GRAB,
- TTM_PL_SYNCCPU_OP_RELEASE
- } op;
- uint32_t pad64;
-};
-
-/*
- * Waiting mode flags for the TTM_BO_WAITIDLE ioctl.
- *
- * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling
- * wait.
- *
- * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU,
- * but return -EBUSY if the buffer is busy.
- */
-
-#define TTM_PL_WAITIDLE_MODE_LAZY (1 << 0)
-#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1)
-
-/**
- * struct ttm_waitidle_arg
- *
- * @handle: The object to synchronize.
- *
- * @mode: wait mode indicated by the
- * TTM_SYNCCPU_MODE flags.
- *
- * Argument to the TTM_BO_WAITIDLE ioctl.
- */
-
-struct ttm_pl_waitidle_arg {
- uint32_t handle;
- uint32_t mode;
-};
-
-union ttm_pl_create_arg {
- struct ttm_pl_create_req req;
- struct ttm_pl_rep rep;
-};
-
-union ttm_pl_reference_arg {
- struct ttm_pl_reference_req req;
- struct ttm_pl_rep rep;
-};
-
-union ttm_pl_setstatus_arg {
- struct ttm_pl_setstatus_req req;
- struct ttm_pl_rep rep;
-};
-
-union ttm_pl_create_ub_arg {
- struct ttm_pl_create_ub_req req;
- struct ttm_pl_rep rep;
-};
-
-/*
- * Ioctl offsets.
- */
-
-#define TTM_PL_CREATE 0x00
-#define TTM_PL_REFERENCE 0x01
-#define TTM_PL_UNREF 0x02
-#define TTM_PL_SYNCCPU 0x03
-#define TTM_PL_WAITIDLE 0x04
-#define TTM_PL_SETSTATUS 0x05
-#define TTM_PL_CREATE_UB 0x06
-
-#endif
diff --git a/drivers/staging/gma500/psb_ttm_userobj_api.h b/drivers/staging/gma500/psb_ttm_userobj_api.h
deleted file mode 100644
index 6a8f7c4ddc78..000000000000
--- a/drivers/staging/gma500/psb_ttm_userobj_api.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef _TTM_USEROBJ_API_H_
-#define _TTM_USEROBJ_API_H_
-
-#include "psb_ttm_placement_user.h"
-#include "psb_ttm_fence_user.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_api.h"
-#include "ttm/ttm_bo_api.h"
-
-struct ttm_lock;
-
-/*
- * User ioctls.
- */
-
-extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
- struct ttm_bo_device *bdev,
- struct ttm_lock *lock, void *data);
-extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
- struct ttm_bo_device *bdev,
- struct ttm_lock *lock, void *data);
-extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
- struct ttm_lock *lock, void *data);
-extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data);
-
-extern int
-ttm_fence_user_create(struct ttm_fence_device *fdev,
- struct ttm_object_file *tfile,
- uint32_t fence_class,
- uint32_t fence_types,
- uint32_t create_flags,
- struct ttm_fence_object **fence, uint32_t * user_handle);
-
-extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
- *tfile,
- uint32_t handle);
-
-extern int
-ttm_pl_verify_access(struct ttm_buffer_object *bo,
- struct ttm_object_file *tfile);
-
-extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
- unsigned long size,
- enum ttm_bo_type type,
- uint32_t flags,
- uint32_t page_alignment,
- unsigned long buffer_start,
- bool interruptible,
- struct file *persistant_swap_storage,
- struct ttm_buffer_object **p_bo);
-
-extern int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
- struct ttm_placement *placement);
-#endif