From 5edaad87000a143504a8f8e2864bb415a9287d94 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 18 Apr 2012 01:30:02 -0300 Subject: drivers: gpu: drm: gma500: mdfld_dsi_output.h: Remove not unneeded include of version.h The output of "make versioncheck" points a incorrect include of version.h in the drivers/gpu/drm/gma500/mdfld_dsi_output.h: drivers/gpu/drm/gma500/mdfld_dsi_output.h: 32 linux/version.h not needed. If we take a look in the file, we can agree to remove it. Cc: David Airlie Cc: Signed-off-by: Marcos Paulo de Souza Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/mdfld_dsi_output.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 21071cef92a4..36eb0744841c 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,7 +29,6 @@ #define __MDFLD_DSI_OUTPUT_H__ #include -#include #include #include #include -- cgit From 87438494152a9313ee56b8a0026ad5e6e87c5972 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Sat, 28 Apr 2012 23:20:42 +0200 Subject: cdv: Fix typos in initialization of mdfld_chip_ops Signed-off-by: Patrik Jakobsson Acked-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/mdfld_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/mdfld_device.c b/drivers/gpu/drm/gma500/mdfld_device.c index a0bd48cd92f4..717f4db28c3c 100644 --- a/drivers/gpu/drm/gma500/mdfld_device.c +++ b/drivers/gpu/drm/gma500/mdfld_device.c @@ -672,8 +672,8 @@ const struct psb_ops mdfld_chip_ops = { .accel_2d = 0, .pipes = 3, .crtcs = 3, - .lvds_mask = (1 << 1); - .hdmi_mask = (1 << 1); + .lvds_mask = (1 << 1), + .hdmi_mask = (1 << 1), .sgx_offset = MRST_SGX_OFFSET, .chip_setup = mid_chip_setup, -- cgit From 0c95e52365f141ff6bfdb172c97d1d2bb2a53f39 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 16:27:45 +0100 Subject: gma500: mdfld_dsi_dpi_mode_set() do not corrupt DSPSTRIDE The proper stride value set in mdfld__intel_pipe_set_base(). TODO: move tc35876x support to separate driver and get rid of all if (mdfld_get_panel_type(dev, pipe) == TC35876X) { ... } Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/mdfld_dsi_dpi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c index d52358b744a0..b34ff097b979 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c @@ -869,7 +869,6 @@ void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, mdfld_set_pipe_timing(dsi_config, pipe); REG_WRITE(DSPABASE, 0x00); - REG_WRITE(DSPASTRIDE, (mode->hdisplay * 4)); REG_WRITE(DSPASIZE, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); -- cgit From 62c5950783546057ca03fb03eee6e3db0ac714d3 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:05:15 +0100 Subject: gma500: don't register the ACPI video bus We are not yet ready for this and it makes a mess on some devices. Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/psb_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index d5a6eab8227e..45bd0c78035d 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -350,7 +350,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); /* igd_opregion_init(&dev_priv->opregion_dev); */ - acpi_video_register(); +/* acpi_video_register(); */ if (dev_priv->lid_state) psb_lid_timer_init(dev_priv); -- cgit From 5f503148efdda2648a735add359aa6dc6b1499c3 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:05:40 +0100 Subject: gma500: Sync up Oaktrail HDMI Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/oaktrail_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 4c5a1864adf4..d0b224408ba1 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -469,6 +469,7 @@ static int oaktrail_chip_setup(struct drm_device *dev) gma_intel_opregion_init(dev); psb_intel_init_bios(dev); } + oaktrail_hdmi_setup(dev); return 0; } -- cgit From bb84977941ad85a5c0b9ff4fd5331913e31107c4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:05:53 +0100 Subject: gma500: wide framebuffer memory If we set a small text framebuffer and have a bigger scanout then we want to send black not random bits for the overscan. Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/framebuffer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index c9fe4bdeb681..4fc0d08bd61b 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -408,6 +408,8 @@ static int psbfb_create(struct psb_fbdev *fbdev, return -ENOMEM; } + memset(dev_priv->vram_addr + backing->offset, 0, size); + mutex_lock(&dev->struct_mutex); info = framebuffer_alloc(0, device); -- cgit From 9aba9d3a2ca42572c9c196e8be6cab59b7c078b6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:06:05 +0100 Subject: gma500: implement backlight functionality for Cedartrail devices Basically a straight cut/paste from the reference driver code then cleaned up a spot. Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/cdv_device.c | 115 ++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 63 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 62f9b735459b..726bfb7375fc 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c @@ -57,8 +57,7 @@ static int cdv_output_init(struct drm_device *dev) cdv_intel_crt_init(dev, &dev_priv->mode_dev); cdv_intel_lvds_init(dev, &dev_priv->mode_dev); - /* These bits indicate HDMI not SDVO on CDV, but we don't yet support - the HDMI interface */ + /* These bits indicate HDMI not SDVO on CDV */ if (REG_READ(SDVOB) & SDVO_DETECTED) cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); if (REG_READ(SDVOC) & SDVO_DETECTED) @@ -69,76 +68,71 @@ static int cdv_output_init(struct drm_device *dev) #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE /* - * Poulsbo Backlight Interfaces + * Cedartrail Backlght Interfaces */ -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 - -#define PSB_BLC_PWM_PRECISION_FACTOR 10 -#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 - -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) - -static int cdv_brightness; static struct backlight_device *cdv_backlight_device; -static int cdv_get_brightness(struct backlight_device *bd) +static int cdv_backlight_combination_mode(struct drm_device *dev) { - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return cdv_brightness; + return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE; } - -static int cdv_backlight_setup(struct drm_device *dev) +static int cdv_get_brightness(struct backlight_device *bd) { - 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; - - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "Has no valid LVDS backlight info\n"); - return -ENOENT; - } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; + struct drm_device *dev = bl_get_data(bd); + u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - core_clock = dev_priv->core_freq; + if (cdv_backlight_combination_mode(dev)) { + u8 lbpc; - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; + val &= ~1; + pci_read_config_byte(dev->pdev, 0xF4, &lbpc); + val *= lbpc; + } + return val; +} - if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return -ERANGE; - else { - /* FIXME */ +static u32 cdv_get_max_backlight(struct drm_device *dev) +{ + u32 max = REG_READ(BLC_PWM_CTL); + + if (max == 0) { + DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n"); + /* i915 does this, I believe which means that we should not + * smash PWM control as firmware will take control of it. */ + return 1; } - return 0; + + max >>= 16; + if (cdv_backlight_combination_mode(dev)) + max *= 0xff; + return max; } static int cdv_set_brightness(struct backlight_device *bd) { + struct drm_device *dev = bl_get_data(bd); int level = bd->props.brightness; + u32 blc_pwm_ctl; /* Percentage 1-100% being valid */ if (level < 1) level = 1; - /*cdv_intel_lvds_set_brightness(dev, level); FIXME */ - cdv_brightness = level; + if (cdv_backlight_combination_mode(dev)) { + u32 max = cdv_get_max_backlight(dev); + u8 lbpc; + + lbpc = level * 0xfe / max + 1; + level /= lbpc; + + pci_write_config_byte(dev->pdev, 0xF4, lbpc); + } + + 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))); return 0; } @@ -150,7 +144,6 @@ static const struct backlight_ops cdv_ops = { static int cdv_backlight_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - int ret; struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); @@ -162,14 +155,9 @@ static int cdv_backlight_init(struct drm_device *dev) if (IS_ERR(cdv_backlight_device)) return PTR_ERR(cdv_backlight_device); - ret = cdv_backlight_setup(dev); - if (ret < 0) { - backlight_device_unregister(cdv_backlight_device); - cdv_backlight_device = NULL; - return ret; - } - cdv_backlight_device->props.brightness = 100; - cdv_backlight_device->props.max_brightness = 100; + cdv_backlight_device->props.brightness = + cdv_get_brightness(cdv_backlight_device); + cdv_backlight_device->props.max_brightness = cdv_get_max_brightness; backlight_update_status(cdv_backlight_device); dev_priv->backlight_device = cdv_backlight_device; return 0; @@ -244,11 +232,12 @@ static void cdv_init_pm(struct drm_device *dev) static void cdv_errata(struct drm_device *dev) { /* Disable bonus launch. - * CPU and GPU competes for memory and display misses updates and flickers. - * Worst with dual core, dual displays. + * CPU and GPU competes for memory and display misses updates and + * flickers. Worst with dual core, dual displays. * - * Fixes were done to Win 7 gfx driver to disable a feature called Bonus - * Launch to work around the issue, by degrading performance. + * Fixes were done to Win 7 gfx driver to disable a feature called + * Bonus Launch to work around the issue, by degrading + * performance. */ CDV_MSG_WRITE32(3, 0x30, 0x08027108); } -- cgit From d839ede47a56ff5f316c88391818488f8e5913af Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:06:18 +0100 Subject: gma500: opregion and ACPI Add the opregion support and bring us in line with the opregion functionality in the reference driver code. We can't share this with i915 currently because there are hardcoded assumptions about dev_priv etc in both versions. [airlied: include opregion.h fix] Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/Makefile | 2 +- drivers/gpu/drm/gma500/cdv_device.c | 4 +- drivers/gpu/drm/gma500/intel_opregion.c | 178 ---------------- drivers/gpu/drm/gma500/oaktrail_device.c | 2 +- drivers/gpu/drm/gma500/opregion.c | 350 +++++++++++++++++++++++++++++++ drivers/gpu/drm/gma500/opregion.h | 29 +++ drivers/gpu/drm/gma500/psb_device.c | 2 +- drivers/gpu/drm/gma500/psb_drv.c | 8 +- drivers/gpu/drm/gma500/psb_drv.h | 4 +- drivers/gpu/drm/gma500/psb_intel_reg.h | 1 + drivers/gpu/drm/gma500/psb_irq.c | 4 + 11 files changed, 396 insertions(+), 188 deletions(-) delete mode 100644 drivers/gpu/drm/gma500/intel_opregion.c create mode 100644 drivers/gpu/drm/gma500/opregion.c create mode 100644 drivers/gpu/drm/gma500/opregion.h (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile index 1583982917ce..efdad010b4e3 100644 --- a/drivers/gpu/drm/gma500/Makefile +++ b/drivers/gpu/drm/gma500/Makefile @@ -12,8 +12,8 @@ gma500_gfx-y += gem_glue.o \ intel_bios.o \ intel_i2c.o \ intel_gmbus.o \ - intel_opregion.o \ mmu.o \ + opregion.o \ power.o \ psb_drv.o \ psb_intel_display.o \ diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 726bfb7375fc..c10f02068d11 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c @@ -157,7 +157,7 @@ static int cdv_backlight_init(struct drm_device *dev) cdv_backlight_device->props.brightness = cdv_get_brightness(cdv_backlight_device); - cdv_backlight_device->props.max_brightness = cdv_get_max_brightness; + cdv_backlight_device->props.max_brightness = cdv_get_max_backlight(dev); backlight_update_status(cdv_backlight_device); dev_priv->backlight_device = cdv_backlight_device; return 0; @@ -490,7 +490,7 @@ static int cdv_chip_setup(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func); cdv_get_core_freq(dev); - gma_intel_opregion_init(dev); + psb_intel_opregion_init(dev); psb_intel_init_bios(dev); cdv_hotplug_enable(dev, false); return 0; diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c deleted file mode 100644 index 7041f40affff..000000000000 --- a/drivers/gpu/drm/gma500/intel_opregion.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * FIXME: resolve with the i915 version - */ - -#include "psb_drv.h" - -#define PCI_ASLE 0xe4 -#define PCI_ASLS 0xfc - -#define OPREGION_HEADER_OFFSET 0 -#define OPREGION_ACPI_OFFSET 0x100 -#define ACPI_CLID 0x01ac /* current lid state indicator */ -#define ACPI_CDCK 0x01b0 /* current docking state indicator */ -#define OPREGION_SWSCI_OFFSET 0x200 -#define OPREGION_ASLE_OFFSET 0x300 -#define OPREGION_VBT_OFFSET 0x400 - -#define OPREGION_SIGNATURE "IntelGraphicsMem" -#define MBOX_ACPI (1<<0) -#define MBOX_SWSCI (1<<1) -#define MBOX_ASLE (1<<2) - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __packed; - -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi { - u32 drdy; /* driver readiness */ - u32 csts; /* notification status */ - u32 cevt; /* current event */ - u8 rsvd1[20]; - u32 didl[8]; /* supported display devices ID list */ - u32 cpdl[8]; /* currently presented display list */ - u32 cadl[8]; /* currently active display list */ - u32 nadl[8]; /* next active devices list */ - u32 aslp; /* ASL sleep time-out */ - u32 tidx; /* toggle table index */ - u32 chpd; /* current hotplug enable indicator */ - u32 clid; /* current lid state*/ - u32 cdck; /* current docking state */ - u32 sxsw; /* Sx state resume */ - u32 evts; /* ASL supported events */ - u32 cnot; /* current OS notification */ - u32 nrdy; /* driver status */ - u8 rsvd2[60]; -} __attribute__((packed)); - -/* OpRegion mailbox #2: SWSCI */ -struct opregion_swsci { - u32 scic; /* SWSCI command|status|data */ - u32 parm; /* command parameters */ - u32 dslp; /* driver sleep time-out */ - u8 rsvd[244]; -} __attribute__((packed)); - -/* OpRegion mailbox #3: ASLE */ -struct opregion_asle { - u32 ardy; /* driver readiness */ - u32 aslc; /* ASLE interrupt command */ - u32 tche; /* technology enabled indicator */ - u32 alsi; /* current ALS illuminance reading */ - u32 bclp; /* backlight brightness to set */ - u32 pfit; /* panel fitting state */ - u32 cblv; /* current brightness level */ - u16 bclm[20]; /* backlight level duty cycle mapping table */ - u32 cpfm; /* current panel fitting mode */ - u32 epfm; /* enabled panel fitting modes */ - u8 plut[74]; /* panel LUT and identifier */ - u32 pfmb; /* PWM freq and min brightness */ - u8 rsvd[102]; -} __attribute__((packed)); - -/* ASLE irq request bits */ -#define ASLE_SET_ALS_ILLUM (1 << 0) -#define ASLE_SET_BACKLIGHT (1 << 1) -#define ASLE_SET_PFIT (1 << 2) -#define ASLE_SET_PWM_FREQ (1 << 3) -#define ASLE_REQ_MSK 0xf - -/* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAILED (1<<10) -#define ASLE_BACKLIGHT_FAILED (1<<12) -#define ASLE_PFIT_FAILED (1<<14) -#define ASLE_PWM_FREQ_FAILED (1<<16) - -/* ASLE backlight brightness to set */ -#define ASLE_BCLP_VALID (1<<31) -#define ASLE_BCLP_MSK (~(1<<31)) - -/* ASLE panel fitting request */ -#define ASLE_PFIT_VALID (1<<31) -#define ASLE_PFIT_CENTER (1<<0) -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define ASLE_PFIT_STRETCH_GFX (1<<2) - -/* PWM frequency and minimum brightness */ -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define ASLE_PFMB_PWM_VALID (1<<31) - -#define ASLE_CBLV_VALID (1<<31) - -#define ACPI_OTHER_OUTPUT (0<<8) -#define ACPI_VGA_OUTPUT (1<<8) -#define ACPI_TV_OUTPUT (2<<8) -#define ACPI_DIGITAL_OUTPUT (3<<8) -#define ACPI_LVDS_OUTPUT (4<<8) - -int gma_intel_opregion_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_opregion *opregion = &dev_priv->opregion; - u32 opregion_phy; - void *base; - u32 *lid_state; - - dev_priv->lid_state = NULL; - - pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); - if (opregion_phy == 0) - return -ENOTSUPP; - - base = ioremap(opregion_phy, 8*1024); - if (!base) - return -ENOMEM; - /* FIXME: should use _io ops - ditto on i915 */ - if (memcmp(base, OPREGION_SIGNATURE, 16)) { - DRM_ERROR("opregion signature mismatch\n"); - iounmap(base); - return -EINVAL; - } - - lid_state = base + 0x01ac; - - dev_priv->lid_state = lid_state; - dev_priv->lid_last_state = readl(lid_state); - opregion->header = base; - opregion->vbt = base + OPREGION_VBT_OFFSET; - return 0; -} - -int gma_intel_opregion_exit(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->opregion.header) - iounmap(dev_priv->opregion.header); - return 0; -} diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index d0b224408ba1..b152134a6ed4 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -466,7 +466,7 @@ static int oaktrail_chip_setup(struct drm_device *dev) return ret; if (vbt->size == 0) { /* Now pull the BIOS data */ - gma_intel_opregion_init(dev); + psb_intel_opregion_init(dev); psb_intel_init_bios(dev); } oaktrail_hdmi_setup(dev); diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c new file mode 100644 index 000000000000..483e0b28c7aa --- /dev/null +++ b/drivers/gpu/drm/gma500/opregion.c @@ -0,0 +1,350 @@ +/* + * Copyright 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#ifdef CONFIG_ACPI +#include +#include +#endif +#include "psb_drv.h" +#include "psb_intel_reg.h" + +#define PCI_ASLE 0xe4 +#define PCI_ASLS 0xfc + +#define OPREGION_HEADER_OFFSET 0 +#define OPREGION_ACPI_OFFSET 0x100 +#define ACPI_CLID 0x01ac /* current lid state indicator */ +#define ACPI_CDCK 0x01b0 /* current docking state indicator */ +#define OPREGION_SWSCI_OFFSET 0x200 +#define OPREGION_ASLE_OFFSET 0x300 +#define OPREGION_VBT_OFFSET 0x400 + +#define OPREGION_SIGNATURE "IntelGraphicsMem" +#define MBOX_ACPI (1<<0) +#define MBOX_SWSCI (1<<1) +#define MBOX_ASLE (1<<2) + +struct opregion_header { + u8 signature[16]; + u32 size; + u32 opregion_ver; + u8 bios_ver[32]; + u8 vbios_ver[16]; + u8 driver_ver[16]; + u32 mboxes; + u8 reserved[164]; +} __packed; + +/* OpRegion mailbox #1: public ACPI methods */ +struct opregion_acpi { + u32 drdy; /* driver readiness */ + u32 csts; /* notification status */ + u32 cevt; /* current event */ + u8 rsvd1[20]; + u32 didl[8]; /* supported display devices ID list */ + u32 cpdl[8]; /* currently presented display list */ + u32 cadl[8]; /* currently active display list */ + u32 nadl[8]; /* next active devices list */ + u32 aslp; /* ASL sleep time-out */ + u32 tidx; /* toggle table index */ + u32 chpd; /* current hotplug enable indicator */ + u32 clid; /* current lid state*/ + u32 cdck; /* current docking state */ + u32 sxsw; /* Sx state resume */ + u32 evts; /* ASL supported events */ + u32 cnot; /* current OS notification */ + u32 nrdy; /* driver status */ + u8 rsvd2[60]; +} __packed; + +/* OpRegion mailbox #2: SWSCI */ +struct opregion_swsci { + /*FIXME: add it later*/ +} __packed; + +/* OpRegion mailbox #3: ASLE */ +struct opregion_asle { + u32 ardy; /* driver readiness */ + u32 aslc; /* ASLE interrupt command */ + u32 tche; /* technology enabled indicator */ + u32 alsi; /* current ALS illuminance reading */ + u32 bclp; /* backlight brightness to set */ + u32 pfit; /* panel fitting state */ + u32 cblv; /* current brightness level */ + u16 bclm[20]; /* backlight level duty cycle mapping table */ + u32 cpfm; /* current panel fitting mode */ + u32 epfm; /* enabled panel fitting modes */ + u8 plut[74]; /* panel LUT and identifier */ + u32 pfmb; /* PWM freq and min brightness */ + u8 rsvd[102]; +} __packed; + +/* ASLE irq request bits */ +#define ASLE_SET_ALS_ILLUM (1 << 0) +#define ASLE_SET_BACKLIGHT (1 << 1) +#define ASLE_SET_PFIT (1 << 2) +#define ASLE_SET_PWM_FREQ (1 << 3) +#define ASLE_REQ_MSK 0xf + +/* response bits of ASLE irq request */ +#define ASLE_ALS_ILLUM_FAILED (1<<10) +#define ASLE_BACKLIGHT_FAILED (1<<12) +#define ASLE_PFIT_FAILED (1<<14) +#define ASLE_PWM_FREQ_FAILED (1<<16) + +/* ASLE backlight brightness to set */ +#define ASLE_BCLP_VALID (1<<31) +#define ASLE_BCLP_MSK (~(1<<31)) + +/* ASLE panel fitting request */ +#define ASLE_PFIT_VALID (1<<31) +#define ASLE_PFIT_CENTER (1<<0) +#define ASLE_PFIT_STRETCH_TEXT (1<<1) +#define ASLE_PFIT_STRETCH_GFX (1<<2) + +/* response bits of ASLE irq request */ +#define ASLE_ALS_ILLUM_FAILED (1<<10) +#define ASLE_BACKLIGHT_FAILED (1<<12) +#define ASLE_PFIT_FAILED (1<<14) +#define ASLE_PWM_FREQ_FAILED (1<<16) + +/* ASLE backlight brightness to set */ +#define ASLE_BCLP_VALID (1<<31) +#define ASLE_BCLP_MSK (~(1<<31)) + +/* ASLE panel fitting request */ +#define ASLE_PFIT_VALID (1<<31) +#define ASLE_PFIT_CENTER (1<<0) +#define ASLE_PFIT_STRETCH_TEXT (1<<1) +#define ASLE_PFIT_STRETCH_GFX (1<<2) + +/* PWM frequency and minimum brightness */ +#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) +#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) +#define ASLE_PFMB_PWM_MASK (0x7ffffe00) +#define ASLE_PFMB_PWM_VALID (1<<31) + +#define ASLE_CBLV_VALID (1<<31) + +static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct opregion_asle *asle = dev_priv->opregion.asle; + struct backlight_device *bd = dev_priv->backlight_device; + u32 max; + + DRM_DEBUG_DRIVER("asle set backlight %x\n", bclp); + + if (!(bclp & ASLE_BCLP_VALID)) + return ASLE_BACKLIGHT_FAILED; + + if (bd == NULL) + return ASLE_BACKLIGHT_FAILED; + + bclp &= ASLE_BCLP_MSK; + if (bclp > 255) + return ASLE_BACKLIGHT_FAILED; + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + max = bd->props.max_brightness; + bd->props.brightness = bclp * max / 255; + backlight_update_status(bd); +#endif + asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID; + + return 0; +} + +void psb_intel_opregion_asle_intr(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct opregion_asle *asle = dev_priv->opregion.asle; + u32 asle_stat = 0; + u32 asle_req; + + if (!asle) + return; + + asle_req = asle->aslc & ASLE_REQ_MSK; + if (!asle_req) { + DRM_DEBUG_DRIVER("non asle set request??\n"); + return; + } + + if (asle_req & ASLE_SET_BACKLIGHT) + asle_stat |= asle_set_backlight(dev, asle->bclp); + + asle->aslc = asle_stat; +} + +#define ASLE_ALS_EN (1<<0) +#define ASLE_BLC_EN (1<<1) +#define ASLE_PFIT_EN (1<<2) +#define ASLE_PFMB_EN (1<<3) + +void psb_intel_opregion_enable_asle(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct opregion_asle *asle = dev_priv->opregion.asle; + + if (asle) { + /* Don't do this on Medfield or other non PC like devices, they + use the bit for something different altogether */ + psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); + psb_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); + + asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN + | ASLE_PFMB_EN; + asle->ardy = 1; + } +} + +#define ACPI_EV_DISPLAY_SWITCH (1<<0) +#define ACPI_EV_LID (1<<1) +#define ACPI_EV_DOCK (1<<2) + +static struct psb_intel_opregion *system_opregion; + +static int psb_intel_opregion_video_event(struct notifier_block *nb, + unsigned long val, void *data) +{ + /* The only video events relevant to opregion are 0x80. These indicate + either a docking event, lid switch or display switch request. In + Linux, these are handled by the dock, button and video drivers. + We might want to fix the video driver to be opregion-aware in + future, but right now we just indicate to the firmware that the + request has been handled */ + + struct opregion_acpi *acpi; + + if (!system_opregion) + return NOTIFY_DONE; + + acpi = system_opregion->acpi; + acpi->csts = 0; + + return NOTIFY_OK; +} + +static struct notifier_block psb_intel_opregion_notifier = { + .notifier_call = psb_intel_opregion_video_event, +}; + +void psb_intel_opregion_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_opregion *opregion = &dev_priv->opregion; + + if (!opregion->header) + return; + + if (opregion->acpi) { + /* Notify BIOS we are ready to handle ACPI video ext notifs. + * Right now, all the events are handled by the ACPI video + * module. We don't actually need to do anything with them. */ + opregion->acpi->csts = 0; + opregion->acpi->drdy = 1; + + system_opregion = opregion; + register_acpi_notifier(&psb_intel_opregion_notifier); + } + + if (opregion->asle) + psb_intel_opregion_enable_asle(dev); +} + +void psb_intel_opregion_fini(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_opregion *opregion = &dev_priv->opregion; + + if (!opregion->header) + return; + + if (opregion->acpi) { + opregion->acpi->drdy = 0; + + system_opregion = NULL; + unregister_acpi_notifier(&psb_intel_opregion_notifier); + } + + /* just clear all opregion memory pointers now */ + iounmap(opregion->header); + opregion->header = NULL; + opregion->acpi = NULL; + opregion->swsci = NULL; + opregion->asle = NULL; + opregion->vbt = NULL; +} + +int psb_intel_opregion_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_opregion *opregion = &dev_priv->opregion; + u32 opregion_phy, mboxes; + void *base; + int err = 0; + + pci_read_config_dword(dev->pdev, PCI_ASLS, &opregion_phy); + if (opregion_phy == 0) { + DRM_DEBUG_DRIVER("ACPI Opregion not supported\n"); + return -ENOTSUPP; + } + DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy); +#ifdef CONFIG_ACPI + base = acpi_os_ioremap(opregion_phy, 8*1024); +#else + base = ioremap(opregion_phy, 8*1024); +#endif + if (!base) + return -ENOMEM; + + if (memcmp(base, OPREGION_SIGNATURE, 16)) { + DRM_DEBUG_DRIVER("opregion signature mismatch\n"); + err = -EINVAL; + goto err_out; + } + + opregion->header = base; + opregion->vbt = base + OPREGION_VBT_OFFSET; + + opregion->lid_state = base + ACPI_CLID; + + mboxes = opregion->header->mboxes; + if (mboxes & MBOX_ACPI) { + DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); + opregion->acpi = base + OPREGION_ACPI_OFFSET; + } + + if (mboxes & MBOX_ASLE) { + DRM_DEBUG_DRIVER("ASLE supported\n"); + opregion->asle = base + OPREGION_ASLE_OFFSET; + } + + return 0; + +err_out: + iounmap(base); + return err; +} + diff --git a/drivers/gpu/drm/gma500/opregion.h b/drivers/gpu/drm/gma500/opregion.h new file mode 100644 index 000000000000..a392ea8908b7 --- /dev/null +++ b/drivers/gpu/drm/gma500/opregion.h @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +extern void psb_intel_opregion_asle_intr(struct drm_device *dev); +extern void psb_intel_opregion_enable_asle(struct drm_device *dev); +extern void psb_intel_opregion_init(struct drm_device *dev); +extern void psb_intel_opregion_fini(struct drm_device *dev); +extern int psb_intel_opregion_setup(struct drm_device *dev); diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c index 34e6866a73b2..e95cddbceb60 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c @@ -293,7 +293,7 @@ static int psb_chip_setup(struct drm_device *dev) { psb_get_core_freq(dev); gma_intel_setup_gmbus(dev); - gma_intel_opregion_init(dev); + psb_intel_opregion_init(dev); psb_intel_init_bios(dev); return 0; } diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 45bd0c78035d..fc6045f926d6 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -215,12 +215,11 @@ static int psb_driver_unload(struct drm_device *dev) /* Kill vblank etc here */ gma_backlight_exit(dev); - psb_modeset_cleanup(dev); if (dev_priv) { + psb_intel_opregion_fini(dev); psb_lid_timer_takedown(dev_priv); - gma_intel_opregion_exit(dev); if (dev_priv->ops->chip_teardown) dev_priv->ops->chip_teardown(dev); @@ -310,6 +309,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (!dev_priv->sgx_reg) goto out_err; + psb_intel_opregion_setup(dev); + ret = dev_priv->ops->chip_setup(dev); if (ret) goto out_err; @@ -349,8 +350,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) 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(); */ + acpi_video_register(); if (dev_priv->lid_state) psb_lid_timer_init(dev_priv); diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index d3528a694206..377393686a12 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -30,6 +30,7 @@ #include "psb_intel_drv.h" #include "gtt.h" #include "power.h" +#include "opregion.h" #include "oaktrail.h" /* Append new drm mode definition here, align with libdrm definition */ @@ -120,6 +121,7 @@ enum { #define PSB_HWSTAM 0x2098 #define PSB_INSTPM 0x20C0 #define PSB_INT_IDENTITY_R 0x20A4 +#define _PSB_IRQ_ASLE (1<<0) #define _MDFLD_PIPEC_EVENT_FLAG (1<<2) #define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) #define _PSB_DPST_PIPEB_FLAG (1<<4) @@ -259,7 +261,7 @@ struct psb_intel_opregion { struct opregion_swsci *swsci; struct opregion_asle *asle; void *vbt; - int enabled; + u32 __iomem *lid_state; }; struct sdvo_device_mapping { diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h index 519a9cd9ffbc..8e8c8efb0a89 100644 --- a/drivers/gpu/drm/gma500/psb_intel_reg.h +++ b/drivers/gpu/drm/gma500/psb_intel_reg.h @@ -507,6 +507,7 @@ #define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17) #define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) #define PIPE_TE_ENABLE (1UL << 22) +#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL << 22) #define PIPE_DPST_EVENT_ENABLE (1UL << 23) #define PIPE_VSYNC_ENABL (1UL << 25) #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 2fcdffdc9063..4ffb2a062098 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -190,6 +190,9 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe) */ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { + if (vdc_stat & _PSB_IRQ_ASLE) + psb_intel_opregion_asle_intr(dev); + if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) mid_pipe_event_handler(dev, 0); @@ -283,6 +286,7 @@ void psb_irq_preinstall(struct drm_device *dev) /* Revisit this area - want per device masks ? */ if (dev_priv->ops->hotplug) dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; + dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE; /* This register is safe even if display island is off */ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); -- cgit From 25933ddeada7fe96a9900fe5f2ecf105fe4f367b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 May 2012 15:07:13 +0100 Subject: gma500: address the lid code We need this for Poulsbo Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/psb_drv.c | 2 +- drivers/gpu/drm/gma500/psb_drv.h | 1 - drivers/gpu/drm/gma500/psb_lid.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index fc6045f926d6..0e85978877e8 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -351,7 +351,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); acpi_video_register(); - if (dev_priv->lid_state) + if (dev_priv->opregion.lid_state) psb_lid_timer_init(dev_priv); ret = drm_vblank_init(dev, dev_priv->num_pipe); diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 377393686a12..5c5c3d0350e5 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -640,7 +640,6 @@ struct drm_psb_private { spinlock_t lid_lock; struct timer_list lid_timer; struct psb_intel_opregion opregion; - u32 *lid_state; u32 lid_last_state; /* diff --git a/drivers/gpu/drm/gma500/psb_lid.c b/drivers/gpu/drm/gma500/psb_lid.c index b867aabe6bf3..7ff8bb2bdc23 100644 --- a/drivers/gpu/drm/gma500/psb_lid.c +++ b/drivers/gpu/drm/gma500/psb_lid.c @@ -29,7 +29,7 @@ static void psb_lid_timer_func(unsigned long data) struct drm_device *dev = (struct drm_device *)dev_priv->dev; struct timer_list *lid_timer = &dev_priv->lid_timer; unsigned long irq_flags; - u32 *lid_state = dev_priv->lid_state; + u32 __iomem *lid_state = dev_priv->opregion.lid_state; u32 pp_status; if (readl(lid_state) == dev_priv->lid_last_state) -- cgit From f728bd1a9468846ccab46b5f9dd422ce5d2e68ff Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:07:27 +0100 Subject: gma500: psb_gtt_init(): drop unused variable Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/gtt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 54e5c9e1e6fa..7d6f73769129 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -413,7 +413,6 @@ int psb_gtt_init(struct drm_device *dev, int resume) unsigned long stolen_size, vram_stolen_size; unsigned i, num_pages; unsigned pfn_base; - uint32_t vram_pages; uint32_t dvmt_mode = 0; struct psb_gtt *pg; @@ -529,7 +528,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) */ pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; - vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; + 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 << PAGE_SHIFT, 0); for (i = 0; i < num_pages; ++i) { -- cgit From eab37607147b90e390aff357e67783e2b8008813 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:07:46 +0100 Subject: gma500: gtt: fix __iomem sparse warnings Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/gtt.c | 11 +++++++---- drivers/gpu/drm/gma500/psb_drv.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 7d6f73769129..4cd33df5f93c 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -61,7 +61,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) * Given a gtt_range object return the GTT offset of the page table * entries for this gtt_range */ -static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) +static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long offset; @@ -82,7 +82,8 @@ static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) */ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) { - u32 *gtt_slot, pte; + u32 __iomem *gtt_slot; + u32 pte; struct page **pages; int i; @@ -126,7 +127,8 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) 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; + u32 __iomem *gtt_slot; + u32 pte; int i; WARN_ON(r->stolen); @@ -152,7 +154,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) */ void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) { - u32 *gtt_slot, pte; + u32 __iomem *gtt_slot; + u32 pte; int i; if (roll >= r->npage) { diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 5c5c3d0350e5..9dc447632c90 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -507,7 +507,7 @@ struct drm_psb_private { /* GTT Memory manager */ struct psb_gtt_mm *gtt_mm; struct page *scratch_page; - u32 *gtt_map; + u32 __iomem *gtt_map; uint32_t stolen_base; void *vram_addr; unsigned long vram_stolen_size; -- cgit From 846a6038d6260153cb16377515e372ed10a2020f Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:08:08 +0100 Subject: gma500: sgx_reg and vdc_reg should be __iomem Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/psb_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 9dc447632c90..e59511d74934 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -525,8 +525,8 @@ struct drm_psb_private { * Register base */ - uint8_t *sgx_reg; - uint8_t *vdc_reg; + uint8_t __iomem *sgx_reg; + uint8_t __iomem *vdc_reg; uint32_t gatt_free_offset; /* -- cgit From 37214ca00e64749e1e65f159aa88f206acfd8e38 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:08:26 +0100 Subject: gma500: vram_addr should be __iomem Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/framebuffer.c | 3 +-- drivers/gpu/drm/gma500/psb_drv.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 4fc0d08bd61b..30400b68e4ba 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -455,8 +455,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->fix.ypanstep = 0; /* Accessed stolen memory directly */ - info->screen_base = (char *)dev_priv->vram_addr + - backing->offset; + info->screen_base = dev_priv->vram_addr + backing->offset; info->screen_size = size; if (dev_priv->gtt.stolen_size) { diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index e59511d74934..67a863bf803a 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -509,7 +509,7 @@ struct drm_psb_private { struct page *scratch_page; u32 __iomem *gtt_map; uint32_t stolen_base; - void *vram_addr; + u8 __iomem *vram_addr; unsigned long vram_stolen_size; int gtt_initialized; u16 gmch_ctrl; /* Saved GTT setup */ -- cgit From 232e6686abb011c8a1b4101245814c730efb1f0a Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:08:38 +0100 Subject: gma500: framebuffer: mark psb_fb_helper_funcs as static Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/framebuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 30400b68e4ba..f47f883ff9ef 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -572,7 +572,7 @@ static int psbfb_probe(struct drm_fb_helper *helper, return new_fb; } -struct drm_fb_helper_funcs psb_fb_helper_funcs = { +static struct drm_fb_helper_funcs psb_fb_helper_funcs = { .gamma_set = psbfb_gamma_set, .gamma_get = psbfb_gamma_get, .fb_probe = psbfb_probe, -- cgit From 9d12028884bd2a5cc1fa7dea5090a4e7f392fdf4 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:08:50 +0100 Subject: gma500: psb_irq_turn_off_dpst() fix bit operation Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/psb_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 4ffb2a062098..8652cdf3f03f 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -426,7 +426,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev) psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), + PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE, PWM_CONTROL_LOGIC); pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); -- cgit From d64363c7557959cf9ddbcd17541a19769720f286 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:09:03 +0100 Subject: gma500: lid_state should be __iomem This was mostly already fixed but this one change is needed to match Kirill's original submission Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/opregion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c index 483e0b28c7aa..05661bfeac75 100644 --- a/drivers/gpu/drm/gma500/opregion.c +++ b/drivers/gpu/drm/gma500/opregion.c @@ -302,7 +302,7 @@ int psb_intel_opregion_setup(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_opregion *opregion = &dev_priv->opregion; u32 opregion_phy, mboxes; - void *base; + void __iomem *base; int err = 0; pci_read_config_dword(dev->pdev, PCI_ASLS, &opregion_phy); -- cgit From 1f17fcd07bb906d34b73ca11fbed01dcc2c0cf2f Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:09:22 +0100 Subject: gma500: oaktrail_hdmi_i2c_handler(): base should be __iomem Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c index 5e84fbde749b..88627e3ba1e3 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c @@ -250,7 +250,7 @@ static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev) */ static void oaktrail_hdmi_i2c_gpio_fix(void) { - void *base; + void __iomem *base; unsigned int gpio_base = 0xff12c000; int gpio_len = 0x1000; u32 temp; -- cgit From 71ab1bee5388af0012eabea38e82f096bf381022 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:12:43 +0100 Subject: gma500: cdv_intel_lvds: mark cdv_intel_lvds_enc_funcs as static Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/cdv_intel_lvds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 44a8353d92bf..ff5b58eb878c 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -556,7 +556,7 @@ static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder) drm_encoder_cleanup(encoder); } -const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { +static const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { .destroy = cdv_intel_lvds_enc_destroy, }; -- cgit From 4ad35b2e32c4d7c3a489863e1a33a0774f6bf4b8 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 15:16:14 +0100 Subject: gma500: fix -Wmissing-include-dirs warnings cc1: warning: include/drm: No such file or directory [enabled by default] It's reproducible if you build with O=/some/obj/dir and W=1. Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile index efdad010b4e3..dd7d6b57996f 100644 --- a/drivers/gpu/drm/gma500/Makefile +++ b/drivers/gpu/drm/gma500/Makefile @@ -1,7 +1,7 @@ # # KMS driver for the GMA500 # -ccflags-y += -Iinclude/drm +ccflags-y += -I$(srctree)/include/drm gma500_gfx-y += gem_glue.o \ accel_2d.o \ -- cgit From 4086b1e2b19729eebf632073b9d4ab811726d8eb Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 3 May 2012 16:27:21 +0100 Subject: gma500: mid-bios: rewrite VBT/GCT handling in a cleaner way Signed-off-by: Kirill A. Shutemov Signed-off-by: Alan Cox Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/mid_bios.c | 295 +++++++++++++++++++------------ drivers/gpu/drm/gma500/oaktrail.h | 25 ++- drivers/gpu/drm/gma500/oaktrail_device.c | 8 +- drivers/gpu/drm/gma500/oaktrail_lvds.c | 4 +- drivers/gpu/drm/gma500/psb_drv.h | 2 +- 5 files changed, 203 insertions(+), 131 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c index 5eee9ad80da4..b2a790bd9899 100644 --- a/drivers/gpu/drm/gma500/mid_bios.c +++ b/drivers/gpu/drm/gma500/mid_bios.c @@ -118,139 +118,214 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv) dev_priv->platform_rev_id); } +struct vbt_header { + u32 signature; + u8 revision; +} __packed; + +/* The same for r0 and r1 */ +struct vbt_r0 { + struct vbt_header vbt_header; + u8 size; + u8 checksum; +} __packed; + +struct vbt_r10 { + struct vbt_header vbt_header; + u8 checksum; + u16 size; + u8 panel_count; + u8 primary_panel_idx; + u8 secondary_panel_idx; + u8 __reserved[5]; +} __packed; + +static int read_vbt_r0(u32 addr, struct vbt_r0 *vbt) +{ + void __iomem *vbt_virtual; + + vbt_virtual = ioremap(addr, sizeof(*vbt)); + if (vbt_virtual == NULL) + return -1; + + memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt)); + iounmap(vbt_virtual); + + return 0; +} + +static int read_vbt_r10(u32 addr, struct vbt_r10 *vbt) +{ + void __iomem *vbt_virtual; + + vbt_virtual = ioremap(addr, sizeof(*vbt)); + if (!vbt_virtual) + return -1; + + memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt)); + iounmap(vbt_virtual); + + return 0; +} + +static int mid_get_vbt_data_r0(struct drm_psb_private *dev_priv, u32 addr) +{ + struct vbt_r0 vbt; + void __iomem *gct_virtual; + struct gct_r0 gct; + u8 bpi; + + if (read_vbt_r0(addr, &vbt)) + return -1; + + gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt)); + if (!gct_virtual) + return -1; + memcpy_fromio(&gct, gct_virtual, sizeof(gct)); + iounmap(gct_virtual); + + bpi = gct.PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = gct.PD.PanelType; + dev_priv->gct_data.DTD = gct.panel[bpi].DTD; + dev_priv->gct_data.Panel_Port_Control = + gct.panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + gct.panel[bpi].Panel_MIPI_Display_Descriptor; + + return 0; +} + +static int mid_get_vbt_data_r1(struct drm_psb_private *dev_priv, u32 addr) +{ + struct vbt_r0 vbt; + void __iomem *gct_virtual; + struct gct_r1 gct; + u8 bpi; + + if (read_vbt_r0(addr, &vbt)) + return -1; + + gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt)); + if (!gct_virtual) + return -1; + memcpy_fromio(&gct, gct_virtual, sizeof(gct)); + iounmap(gct_virtual); + + bpi = gct.PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = gct.PD.PanelType; + dev_priv->gct_data.DTD = gct.panel[bpi].DTD; + dev_priv->gct_data.Panel_Port_Control = + gct.panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + gct.panel[bpi].Panel_MIPI_Display_Descriptor; + + return 0; +} + +static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) +{ + struct vbt_r10 vbt; + void __iomem *gct_virtual; + struct gct_r10 *gct; + struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD; + struct gct_r10_timing_info *ti; + int ret = -1; + + if (read_vbt_r10(addr, &vbt)) + return -1; + + gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL); + if (!gct) + return -1; + + gct_virtual = ioremap(addr + sizeof(vbt), + sizeof(*gct) * vbt.panel_count); + if (!gct_virtual) + goto out; + memcpy_fromio(gct, gct_virtual, sizeof(*gct)); + iounmap(gct_virtual); + + dev_priv->gct_data.bpi = vbt.primary_panel_idx; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + gct[vbt.primary_panel_idx].Panel_MIPI_Display_Descriptor; + + ti = &gct[vbt.primary_panel_idx].DTD; + 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; + + ret = 0; +out: + kfree(gct); + return ret; +} + static void mid_get_vbt_data(struct drm_psb_private *dev_priv) { struct drm_device *dev = dev_priv->dev; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; u32 addr; - u16 new_size; - u8 *vbt_virtual; - u8 bpi; - u8 number_desc = 0; - struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD; - struct gct_r10_timing_info ti; - void *pGCT; + u8 __iomem *vbt_virtual; + struct vbt_header vbt_header; struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + int ret = -1; - /* Get the address of the platform config vbt, B0:D2:F0;0xFC */ + /* Get the address of the platform config vbt */ pci_read_config_dword(pci_gfx_root, 0xFC, &addr); pci_dev_put(pci_gfx_root); dev_dbg(dev->dev, "drm platform config address is %x\n", addr); - /* check for platform config address == 0. */ - /* this means fw doesn't support vbt */ - - if (addr == 0) { - vbt->size = 0; - return; - } + if (!addr) + goto out; /* get the virtual address of the vbt */ - vbt_virtual = ioremap(addr, sizeof(*vbt)); - if (vbt_virtual == NULL) { - vbt->size = 0; - return; - } + vbt_virtual = ioremap(addr, sizeof(vbt_header)); + if (!vbt_virtual) + goto out; - memcpy(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); /* Free virtual address space */ + memcpy_fromio(&vbt_header, vbt_virtual, sizeof(vbt_header)); + iounmap(vbt_virtual); - /* No matching signature don't process the data */ - if (memcmp(vbt->signature, "$GCT", 4)) { - vbt->size = 0; - return; - } + if (memcmp(&vbt_header.signature, "$GCT", 4)) + goto out; + + dev_dbg(dev->dev, "GCT revision is %02x\n", vbt_header.revision); - dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision); - - switch (vbt->revision) { - case 0: - vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->oaktrail_gct; - bpi = ((struct oaktrail_gct_v1 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct oaktrail_gct_v1 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].DTD, - sizeof(struct oaktrail_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + switch (vbt_header.revision) { + case 0x00: + ret = mid_get_vbt_data_r0(dev_priv, addr); break; - case 1: - vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->oaktrail_gct; - bpi = ((struct oaktrail_gct_v2 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct oaktrail_gct_v2 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].DTD, - sizeof(struct oaktrail_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + case 0x01: + ret = mid_get_vbt_data_r1(dev_priv, addr); 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 oaktrail_gct contains hi size byte*/ - new_size |= ((0xff & (unsigned int)(long)vbt->oaktrail_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)(long)vbt->oaktrail_gct)) >> 8; - bpi = ((0xff0000 & (unsigned int)(long)vbt->oaktrail_gct)) >> 16; - vbt->oaktrail_gct = ioremap(addr + GCT_R10_HEADER_SIZE, - GCT_R10_DISPLAY_DESC_SIZE * number_desc); - pGCT = vbt->oaktrail_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; - - /* Move 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; + ret = mid_get_vbt_data_r10(dev_priv, addr); break; default: dev_err(dev->dev, "Unknown revision of GCT!\n"); - vbt->size = 0; } + +out: + if (ret) + dev_err(dev->dev, "Unable to read GCT!"); + else + dev_priv->has_gct = true; } int mid_chip_setup(struct drm_device *dev) diff --git a/drivers/gpu/drm/gma500/oaktrail.h b/drivers/gpu/drm/gma500/oaktrail.h index 2da1f368f14e..f2f9f38a5362 100644 --- a/drivers/gpu/drm/gma500/oaktrail.h +++ b/drivers/gpu/drm/gma500/oaktrail.h @@ -19,14 +19,6 @@ /* MID device specific descriptors */ -struct oaktrail_vbt { - s8 signature[4]; /*4 bytes,"$GCT" */ - u8 revision; - u8 size; - u8 checksum; - void *oaktrail_gct; -} __packed; - struct oaktrail_timing_info { u16 pixel_clock; u8 hactive_lo; @@ -161,7 +153,7 @@ union oaktrail_panel_rx { u16 panel_receiver; } __packed; -struct oaktrail_gct_v1 { +struct gct_r0 { union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ @@ -178,7 +170,7 @@ struct oaktrail_gct_v1 { union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ } __packed; -struct oaktrail_gct_v2 { +struct gct_r1 { union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ @@ -195,6 +187,16 @@ struct oaktrail_gct_v2 { union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ } __packed; +struct gct_r10 { + struct gct_r10_timing_info DTD; + u16 Panel_MIPI_Display_Descriptor; + u16 Panel_MIPI_Receiver_Descriptor; + u16 Panel_Backlight_Inverter_Descriptor; + u8 Panel_Initial_Brightness; + u32 MIPI_Ctlr_Init_ptr; + u32 MIPI_Panel_Init_ptr; +} __packed; + struct oaktrail_gct_data { u8 bpi; /* boot panel index, number of panel used during boot */ u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ @@ -213,9 +215,6 @@ struct oaktrail_gct_data { #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 - /* * Moorestown HDMI interfaces */ diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index b152134a6ed4..0bb74cc3ecf8 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -458,13 +458,12 @@ static int oaktrail_power_up(struct drm_device *dev) static int oaktrail_chip_setup(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; int ret; - + ret = mid_chip_setup(dev); if (ret < 0) return ret; - if (vbt->size == 0) { + if (!dev_priv->has_gct) { /* Now pull the BIOS data */ psb_intel_opregion_init(dev); psb_intel_init_bios(dev); @@ -476,10 +475,9 @@ static int oaktrail_chip_setup(struct drm_device *dev) static void oaktrail_teardown(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; oaktrail_hdmi_teardown(dev); - if (vbt->size == 0) + if (!dev_priv->has_gct) psb_intel_destroy_bios(dev); } diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 654f32b22b21..558c77fb55ec 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -257,7 +257,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, mode_dev->panel_fixed_mode = NULL; /* Use the firmware provided data on Moorestown */ - if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ + if (dev_priv->has_gct) { mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) return; @@ -371,7 +371,7 @@ void oaktrail_lvds_init(struct drm_device *dev, BRIGHTNESS_MAX_LEVEL); mode_dev->panel_wants_dither = false; - if (dev_priv->vbt_data.size != 0x00) + if (dev_priv->has_gct) mode_dev->panel_wants_dither = (dev_priv->gct_data. Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); if (dev_priv->lvds_dither) diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 67a863bf803a..270a27bc936a 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -612,7 +612,7 @@ struct drm_psb_private { int rpm_enabled; /* MID specific */ - struct oaktrail_vbt vbt_data; + bool has_gct; struct oaktrail_gct_data gct_data; /* Oaktrail HDMI state */ -- cgit