From: <ai...@ke...> - 2007-04-10 06:21:58
|
libdrm/xf86drmMode.c | 4 libdrm/xf86drmMode.h | 2 linux-core/drm_crtc.c | 7 + linux-core/intel_display.c | 186 ++++++++++++++++++++++----------------------- linux-core/intel_sdvo.c | 72 +++++++++-------- shared-core/drm.h | 3 6 files changed, 140 insertions(+), 134 deletions(-) New commits: diff-tree 23a66fd506e71fdfde906d1679fb07c0df8bec4c (from f1476e4e5cefd4aa8c487b4e651a26056110e2f0) Author: David Airlie <ai...@as...> Date: Tue Apr 10 16:26:07 2007 +1000 fixup true/false in intel_sdvo.c diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 0e870d1..4a954f9 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -298,7 +298,7 @@ static bool intel_sdvo_get_trained_input *input_1 = response.input0_trained; *input_2 = response.input1_trained; - return TRUE; + return true; } static bool intel_sdvo_get_active_outputs(struct drm_output *output, @@ -363,13 +363,13 @@ static bool intel_sdvo_get_input_pixel_c status = intel_sdvo_read_response(output, &clocks, sizeof(clocks)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; /* Convert the values from units of 10 kHz to kHz. */ *clock_min = clocks.min * 10; *clock_max = clocks.max * 10; - return TRUE; + return true; } static bool intel_sdvo_set_target_output(struct drm_output *output, @@ -393,15 +393,15 @@ static bool intel_sdvo_get_timing(struct status = intel_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, cmd + 1, NULL, 0); status = intel_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_get_input_timing(struct drm_output *output, @@ -426,14 +426,14 @@ static bool intel_sdvo_set_timing(struct intel_sdvo_write_cmd(output, cmd, &dtd->part1, sizeof(dtd->part1)); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_set_input_timing(struct drm_output *output, @@ -464,16 +464,16 @@ static bool intel_sdvo_get_preferred_inp status = intel_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, NULL, 0); status = intel_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } #endif @@ -502,9 +502,9 @@ static bool intel_sdvo_set_clock_rate_mu intel_sdvo_write_cmd(output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_mode_fixup(struct drm_output *output, @@ -515,7 +515,7 @@ static bool intel_sdvo_mode_fixup(struct * device will be told of the multiplier during mode_set. */ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); - return TRUE; + return true; } static void intel_sdvo_mode_set(struct drm_output *output, @@ -584,7 +584,7 @@ static void intel_sdvo_mode_set(struct d intel_sdvo_set_output_timing(output, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); /* We would like to use i830_sdvo_create_preferred_input_timing() to * provide the device with a timing it can support, if it supports that @@ -620,16 +620,20 @@ static void intel_sdvo_mode_set(struct d } /* Set the SDVO control regs. */ - sdvox = I915_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + if (0/*IS_I965GM(dev)*/) { + sdvox = SDVO_BORDER_ENABLE; + } else { + sdvox = I915_READ(sdvo_priv->output_device); + switch (sdvo_priv->output_device) { + case SDVOB: + sdvox &= SDVOB_PRESERVE_MASK; + break; + case SDVOC: + sdvox &= SDVOC_PRESERVE_MASK; + break; + } + sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + } if (intel_crtc->pipe == 1) sdvox |= SDVO_PIPE_B_SELECT; @@ -706,13 +710,13 @@ static void intel_sdvo_save(struct drm_o intel_sdvo_get_active_outputs(output, &sdvo_priv->save_active_outputs); if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_get_input_timing(output, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(output, FALSE, TRUE); + intel_sdvo_set_target_input(output, false, true); intel_sdvo_get_input_timing(output, &sdvo_priv->save_input_dtd_2); } @@ -754,12 +758,12 @@ static void intel_sdvo_restore(struct dr } if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(output, FALSE, TRUE); + intel_sdvo_set_target_input(output, false, true); intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_2); } @@ -805,9 +809,9 @@ static bool intel_sdvo_get_capabilities( intel_sdvo_write_cmd(output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); status = intel_sdvo_read_response(output, caps, sizeof(*caps)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } @@ -980,7 +984,7 @@ void intel_sdvo_init(drm_device_t *dev, } else { - unsigned char bytes[2]; + unsigned char bytes[2]; memcpy (bytes, &sdvo_priv->caps.output_flags, 2); DRM_DEBUG("%s: No active TMDS outputs (0x%02x%02x)\n", @@ -997,7 +1001,7 @@ void intel_sdvo_init(drm_device_t *dev, /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_get_input_pixel_clock_range(output, &sdvo_priv->pixel_clock_min, diff-tree f1476e4e5cefd4aa8c487b4e651a26056110e2f0 (from 1e39dc43230ba1827eedc29ab422464281ec3e1b) Author: David Airlie <ai...@as...> Date: Tue Apr 10 16:25:52 2007 +1000 re-tab and fixup the i915GM get core clock function to actually work diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 92b3940..75d7359 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -583,8 +583,9 @@ static int intel_get_core_clock_speed(dr else if (IS_I945GM(dev) || IS_845G(dev)) return 200000; else if (IS_I915GM(dev)) { -#if 0 - u16 gcfgc = pciReadWord(dev->PciTag, I915_GCFGC); + u16 gcfgc = 0; + + pci_read_config_word(dev->pdev, I915_GCFGC, &gcfgc); if (gcfgc & I915_LOW_FREQUENCY_ENABLE) return 133000; @@ -597,7 +598,6 @@ static int intel_get_core_clock_speed(dr return 190000; } } -#endif } else if (IS_I865G(dev)) return 266000; else if (IS_I855(dev)) { @@ -835,106 +835,102 @@ static void intel_crtc_mode_set(struct d if (intel_panel_fitter_pipe(dev) == pipe) I915_WRITE(PFIT_CONTROL, 0); + DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + drm_mode_debug_printmodeline(dev, mode); + #if 0 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); - if (!xf86ModesEqual(mode, adjusted_mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); - } - i830PrintPll("chosen", &clock); + if (!xf86ModesEqual(mode, adjusted_mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + xf86PrintModeline(pScrn->scrnIndex, mode); + } + i830PrintPll("chosen", &clock); #endif - if (dpll & DPLL_VCO_ENABLE) - { + if (dpll & DPLL_VCO_ENABLE) { + I915_WRITE(fp_reg, fp); + I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + I915_READ(dpll_reg); + udelay(150); + } + + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ + if (is_lvds) { + u32 lvds = I915_READ(LVDS); + + lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; + /* Set the B0-B3 data pairs corresponding to whether we're going to + * set the DPLLs for dual-channel mode or not. + */ + if (clock.p2 == 7) + lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; + else + lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); + + /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) + * appropriately here, but we need to look more thoroughly into how + * panels behave in the two modes. + */ + + I915_WRITE(LVDS, lvds); + I915_READ(LVDS); + } + I915_WRITE(fp_reg, fp); - I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + I915_WRITE(dpll_reg, dpll); I915_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ udelay(150); - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) - { - u32 lvds = I915_READ(LVDS); - - lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more thoroughly into how - * panels behave in the two modes. - */ - - I915_WRITE(LVDS, lvds); - I915_READ(LVDS); - } - - I915_WRITE(fp_reg, fp); - I915_WRITE(dpll_reg, dpll); - I915_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - if (IS_I965G(dev)) { - int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; - I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | - ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); - } else { - /* write it again -- the BIOS does, after all */ - I915_WRITE(dpll_reg, dpll); - } - I915_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - I915_WRITE(dspstride_reg, crtc->fb->pitch * (crtc->fb->bits_per_pixel / 8)); - /* pipesrc and dspsize control the size that is scaled from, which should - * always be the user's requested size. - */ - I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - I915_WRITE(dsppos_reg, 0); - I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - I915_WRITE(pipeconf_reg, pipeconf); - I915_READ(pipeconf_reg); - - intel_wait_for_vblank(dev); - - I915_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ - intel_pipe_set_base(crtc, x, y); - + + if (IS_I965G(dev)) { + int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; + I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | + ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); + } else { + /* write it again -- the BIOS does, after all */ + I915_WRITE(dpll_reg, dpll); + } + I915_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + I915_WRITE(dspstride_reg, crtc->fb->pitch * (crtc->fb->bits_per_pixel / 8)); + /* pipesrc and dspsize control the size that is scaled from, which should + * always be the user's requested size. + */ + I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + I915_WRITE(dsppos_reg, 0); + I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); + I915_WRITE(pipeconf_reg, pipeconf); + I915_READ(pipeconf_reg); + + intel_wait_for_vblank(dev); + + I915_WRITE(dspcntr_reg, dspcntr); + + /* Flush the plane changes */ + intel_pipe_set_base(crtc, x, y); + #ifdef XF86DRI // TODO // I830DRISetVBlankInterrupt (pScrn, TRUE); #endif - - intel_wait_for_vblank(dev); - - + + intel_wait_for_vblank(dev); } /** Loads the palette/gamma unit for the CRTC with the prepared values */ @@ -1002,7 +998,7 @@ void intel_crtc_init(drm_device_t *dev, if (crtc == NULL) return; - intel_crtc = kmalloc(sizeof(struct intel_crtc), GFP_KERNEL); + intel_crtc = kzalloc(sizeof(struct intel_crtc), GFP_KERNEL); if (intel_crtc == NULL) { kfree(crtc); return; diff-tree 1e39dc43230ba1827eedc29ab422464281ec3e1b (from 40bd6dcd86d554ca426deccd4fbada693c4be8a6) Author: David Airlie <ai...@as...> Date: Tue Apr 10 16:25:31 2007 +1000 export output name to userspace diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index df8ea8e..c0444e6 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -40,6 +40,7 @@ #include "xf86drmMode.h" #include "xf86drm.h" #include <drm.h> +#include <string.h> /* * Util functions @@ -385,7 +386,8 @@ drmModeOutputPtr drmModeGetOutput(int fd r->crtcs = out.crtcs; r->clones = out.clones; r->modes = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t)); - + strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN); + r->name[DRM_OUTPUT_NAME_LEN-1] = 0; return r; err_allocs: diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index fadfdc5..594eb48 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -120,7 +120,7 @@ typedef enum { typedef struct _drmModeOutput { unsigned int crtc; /**< Crtc currently connected to */ - + unsigned char name[DRM_OUTPUT_NAME_LEN]; drmModeConnection connection; uint32_t mmWidth, mmHeight; /**< HxW in millimeters */ drmModeSubPixel subpixel; diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 46b7f7a..cc082d9 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -838,16 +838,19 @@ int drm_mode_getoutput(struct inode *ino if (copy_from_user(&out_resp, argp, sizeof(out_resp))) return -EFAULT; - DRM_DEBUG("output id %d\n", out_resp.output); + DRM_DEBUG("output id %d:\n", out_resp.output); output= idr_find(&dev->mode_config.crtc_idr, out_resp.output); if (!output || (output->id != out_resp.output)) return -EINVAL; - DRM_DEBUG("about to count modes\n"); + DRM_DEBUG("about to count modes: %s\n", output->name); list_for_each_entry(mode, &output->modes, head) mode_count++; DRM_DEBUG("about to count modes %d %d %p\n", mode_count, out_resp.count_modes, output->crtc); + strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN); + out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0; + out_resp.mm_width = output->mm_width; out_resp.mm_height = output->mm_height; out_resp.subpixel = output->subpixel_order; diff --git a/shared-core/drm.h b/shared-core/drm.h index 8329609..f1afc04 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -891,7 +891,7 @@ typedef union drm_mm_init_arg{ /* * Drm mode setting */ - +#define DRM_OUTPUT_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 struct drm_mode_modeinfo { @@ -946,6 +946,7 @@ struct drm_mode_get_output { unsigned int output; /**< Id */ unsigned int crtc; /**< Id of crtc */ + unsigned char name[DRM_OUTPUT_NAME_LEN]; unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ |
From: <jb...@ke...> - 2007-04-11 14:09:01
|
linux-core/drm_bo.c | 10 ++++-- linux-core/drm_crtc.c | 40 +++++++++++++-------------- linux-core/drm_crtc.h | 5 ++- linux-core/intel_crt.c | 45 ++++++++++++++++++++++--------- linux-core/intel_display.c | 2 - linux-core/intel_drv.h | 1 linux-core/intel_lvds.c | 21 +++++++++++--- shared-core/i915_init.c | 65 ++++++++++++++++++++++++++++++++++++++------- 8 files changed, 135 insertions(+), 54 deletions(-) New commits: diff-tree dd00aa5851ca7c5590ae0b0825dd84c027cfd420 (from f35db6690625ccd01fb61dc766e6380a9c14c331) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 07:08:48 2007 -0700 export vblank routine for use by intel_display.c and intel_sdvo.c. diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index 0675e06..f47e623 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -73,5 +73,6 @@ extern void intel_output_prepare (struct extern void intel_output_commit (struct drm_output *output); extern struct drm_display_mode *intel_crtc_mode_get(drm_device_t *dev, struct drm_crtc *crtc); +extern void intel_wait_for_vblank(drm_device_t *dev); #endif /* __INTEL_DRV_H__ */ diff-tree f35db6690625ccd01fb61dc766e6380a9c14c331 (from 78598fdaa8b23a199880a63b79f17cfd7f14cb0f) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 07:08:29 2007 -0700 Fixup DDC probing. We only have one DDC bus so we have to use it only on demand, and unregister when we're done. diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c index e62aa8d..ca7ae7b 100644 --- a/linux-core/intel_crt.c +++ b/linux-core/intel_crt.c @@ -180,6 +180,7 @@ static bool intel_crt_detect_ddc(struct static enum drm_output_status intel_crt_detect(struct drm_output *output) { drm_device_t *dev = output->dev; + struct intel_output *intel_output = output->driver_private; if (IS_I945G(dev)| IS_I945GM(dev) || IS_I965G(dev)) { if (intel_crt_detect_hotplug(output)) @@ -188,21 +189,47 @@ static enum drm_output_status intel_crt_ return output_status_disconnected; } - if (intel_crt_detect_ddc(output)) + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return 0; + } + + if (intel_crt_detect_ddc(output)) { + intel_i2c_destroy(intel_output->ddc_bus); return output_status_connected; + } + intel_i2c_destroy(intel_output->ddc_bus); /* TODO use load detect */ return output_status_unknown; } static void intel_crt_destroy(struct drm_output *output) { + if (output->driver_private) + kfree(output->driver_private); +} + +static int intel_crt_get_modes(struct drm_output *output) +{ + struct drm_device *dev = output->dev; struct intel_output *intel_output = output->driver_private; + int ret; - intel_i2c_destroy(intel_output->ddc_bus); + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return 0; + } - if (output->driver_private) - kfree(output->driver_private); + ret = intel_ddc_get_modes(output); + intel_i2c_destroy(intel_output->ddc_bus); + return ret; } /* @@ -218,7 +245,7 @@ static const struct drm_output_funcs int .mode_set = intel_crt_mode_set, .commit = intel_output_commit, .detect = intel_crt_detect, - .get_modes = intel_ddc_get_modes, + .get_modes = intel_crt_get_modes, .cleanup = intel_crt_destroy, }; @@ -239,12 +266,4 @@ void intel_crt_init(drm_device_t *dev) output->driver_private = intel_output; output->interlace_allowed = 0; output->doublescan_allowed = 0; - - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return; - } } diff-tree 78598fdaa8b23a199880a63b79f17cfd7f14cb0f (from 7e48d47fb51cc0f1a38a99acfe591821a45d7081) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 07:07:54 2007 -0700 Various changes for in-kernel modesetting: - allow drm_buffer_object_create to be called w/o dev_mapping - fixup i915 init code to allocate memory, fb and set modes right - pass fb to drm_initial_config for setup - change some debug output to make it easier to spot - fixup lvds code to use DDC probing correctly diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 17d6fbc..2107a3a 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1530,7 +1530,7 @@ static int drm_bo_handle_wait(drm_file_t return ret; } -int drm_buffer_object_create(drm_file_t * priv, +int drm_buffer_object_create(drm_device_t *dev, unsigned long size, drm_bo_type_t type, uint32_t mask, @@ -1539,7 +1539,6 @@ int drm_buffer_object_create(drm_file_t unsigned long buffer_start, drm_buffer_object_t ** buf_obj) { - drm_device_t *dev = priv->head->dev; drm_buffer_manager_t *bm = &dev->bm; drm_buffer_object_t *bo; int ret = 0; @@ -1615,6 +1614,7 @@ int drm_buffer_object_create(drm_file_t drm_bo_usage_deref_unlocked(bo); return ret; } +EXPORT_SYMBOL(drm_buffer_object_create); static int drm_bo_add_user_object(drm_file_t * priv, drm_buffer_object_t * bo, int shareable) @@ -1670,7 +1670,8 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) switch (req->op) { case drm_bo_create: rep.ret = - drm_buffer_object_create(priv, req->size, + drm_buffer_object_create(priv->head->dev, + req->size, req->type, req->mask, req->hint, @@ -2301,6 +2302,9 @@ void drm_bo_unmap_virtual(drm_buffer_obj loff_t offset = ((loff_t) bo->map_list.hash.key) << PAGE_SHIFT; loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT; + if (!dev->dev_mapping) + return; + unmap_mapping_range(dev->dev_mapping, offset, holelen, 1); } diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1c1c300..b349527 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -57,6 +57,7 @@ struct drm_framebuffer *drm_framebuffer_ return fb; } +EXPORT_SYMBOL(drm_framebuffer_create); void drm_framebuffer_destroy(struct drm_framebuffer *fb) { @@ -493,30 +494,28 @@ out_err: return ret; } -bool drm_initial_config(drm_device_t *dev, bool can_grow) +/** + * drm_initial_config - setup a sane initial output configuration + * @dev: DRM device + * @fb: framebuffer backing for new setup + * @can_grow: this configuration is growable + * + * Scan the CRTCs and outputs and try to put together an initial setup. + * At the moment, this is a cloned configuration across all heads with + * @fb as the backing store. + */ +bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, + bool can_grow) { /* do a hardcoded initial configuration here */ struct drm_crtc *crtc, *vga_crtc = NULL, *dvi_crtc = NULL, *lvds_crtc = NULL; - struct drm_framebuffer *fb; struct drm_output *output, *use_output = NULL; -#if 0 - fb = drm_framebuffer_create(dev); - if (!fb) - return false; - - fb->pitch = 1024; - fb->width = 1024; - fb->height = 768; - fb->depth = 24; - fb->bits_per_pixel = 32; -#endif - /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - // crtc->fb = fb; + crtc->fb = fb; if (!vga_crtc) { vga_crtc = crtc; crtc->enabled = 1; @@ -527,8 +526,7 @@ bool drm_initial_config(drm_device_t *de crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; - } - else if (!dvi_crtc) { + } else if (!dvi_crtc) { dvi_crtc = crtc; crtc->enabled = 1; crtc->desired_x = 0; @@ -536,7 +534,7 @@ bool drm_initial_config(drm_device_t *de } } - drm_crtc_probe_output_modes(dev, 1024, 768); + drm_crtc_probe_output_modes(dev, 2048, 2048); /* hard bind the CRTCS */ @@ -551,20 +549,20 @@ bool drm_initial_config(drm_device_t *de } if (!strncmp(output->name, "VGA", 3)) { output->crtc = vga_crtc; - drm_mode_debug_printmodeline(dev, des_mode); + DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name); output->crtc->desired_mode = des_mode; output->initial_x = 0; output->initial_y = 0; use_output = output; } else if (!strncmp(output->name, "TMDS", 4)) { output->crtc = vga_crtc; - drm_mode_debug_printmodeline(dev, des_mode); + DRM_DEBUG("TMDS preferred mode: %s\n", des_mode->name); output->crtc->desired_mode = des_mode; output->initial_x = 0; output->initial_y = 0; } else if (!strncmp(output->name, "LVDS", 3)) { output->crtc = lvds_crtc; - drm_mode_debug_printmodeline(dev, des_mode); + DRM_DEBUG("LVDS preferred mode: %s\n", des_mode->name); output->crtc->desired_mode = des_mode; output->initial_x = 0; output->initial_y = 0; diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index d5d256d..54c508c 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -452,10 +452,13 @@ extern int drm_mode_vrefresh(struct drm_ extern void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags); extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); -extern bool drm_initial_config(struct drm_device *dev, bool cangrow); +extern bool drm_initial_config(struct drm_device *dev, + struct drm_framebuffer *fb, bool cangrow); extern void drm_framebuffer_set_object(struct drm_device *dev, unsigned long handle); extern bool drm_set_desired_modes(struct drm_device *dev); +extern int drmfb_probe(struct drm_device *dev, struct drm_framebuffer *fb); +extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); /* IOCTLs */ extern int drm_mode_getresources(struct inode *inode, struct file *filp, diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 04a6e08..bb6f7f2 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1128,11 +1128,9 @@ static void intel_setup_outputs(drm_devi intel_crt_init(dev); -#if 0 /* Set up integrated LVDS */ if (IS_MOBILE(dev) && !IS_I830(dev)) intel_lvds_init(dev); -#endif if (IS_I9XX(dev)) { intel_sdvo_init(dev, SDVOB); diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 90a2610..8ecb204 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,6 +164,7 @@ static bool intel_lvds_mode_fixup(struct struct intel_crtc *intel_crtc = output->crtc->driver_private; struct drm_output *tmp_output; +#if 0 spin_lock(&dev->mode_config.config_lock); list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) { if (tmp_output != output && tmp_output->crtc == output->crtc) { @@ -173,6 +174,7 @@ static bool intel_lvds_mode_fixup(struct } } spin_lock(&dev->mode_config.config_lock); +#endif if (intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -199,7 +201,7 @@ static bool intel_lvds_mode_fixup(struct dev_priv->panel_fixed_mode->vsync_end; adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; -// xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); } /* @@ -272,11 +274,11 @@ static int intel_lvds_get_modes(struct d "failed.\n"); return 0; } - intel_i2c_destroy(intel_output->ddc_bus); ret = intel_ddc_get_modes(output); if (ret) return ret; + intel_i2c_destroy(intel_output->ddc_bus); /* Didn't get an EDID */ if (!output->monitor_info) { @@ -359,19 +361,31 @@ void intel_lvds_init(struct drm_device * output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + /* * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ intel_ddc_get_modes(output); + intel_i2c_destroy(intel_output->ddc_bus); list_for_each_entry(scan, &output->probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) break; } - if (scan) + if (scan) { dev_priv->panel_fixed_mode = scan; + DRM_DEBUG("LVDS panel_fixed: %s\n", scan->name); + } +#if 0 /* * If we didn't get EDID, try checking if the panel is already turned * on. If so, assume that whatever is currently programmed is the @@ -395,7 +409,6 @@ void intel_lvds_init(struct drm_device * } /* No BIOS poking yet... */ -#if 0 /* Get the LVDS fixed mode out of the BIOS. We should support LVDS * with the BIOS being unavailable or broken, but lack the * configuration options for now. diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 5af86f8..d9fb485 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -4,10 +4,23 @@ #include "i915_drm.h" #include "i915_drv.h" +/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags + * + * The driver load routine has to do several things: + * - drive output discovery via intel_modeset_init() + * - initialize the memory manager + * - allocate initial config memory + * - setup the DRM framebuffer with the allocated memory + */ int i915_driver_load(drm_device_t *dev, unsigned long flags) { drm_i915_private_t *dev_priv; drm_i915_init_t init; + drm_buffer_object_t *entry; + struct drm_framebuffer *fb; int ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); @@ -45,7 +58,6 @@ int i915_driver_load(drm_device_t *dev, return ret; } -#if 0 ret = drm_setup(dev); if (ret) { DRM_ERROR("drm_setup failed\n"); @@ -60,17 +72,48 @@ int i915_driver_load(drm_device_t *dev, return DRM_ERR(EINVAL); } - /* FIXME: where does the sarea_priv really go? */ - // dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL); + /* FIXME: assume sarea_priv is right after SAREA */ + dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t); - /* FIXME: need real front buffer offset */ - /// dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024; -#endif + /* + * Initialize the memory manager for local and AGP space + */ drm_bo_driver_init(dev); - /* this probably doesn't belong here - TODO */ - //drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); + /* FIXME: initial stolen area 8M init */ +#define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */ + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base, + SCANOUT_SIZE); + + /* Allocate scanout buffer and command ring */ + /* FIXME: types and other args correct? */ + drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, PAGE_SIZE, 0, + &entry); + + DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n", + entry->buffer_start, entry->offset); intel_modeset_init(dev); - // drm_set_desired_modes(dev); + + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb\n"); + return -EINVAL; + } + + fb->width = 1024; + fb->height = 768; + fb->pitch = 1024; + fb->bits_per_pixel = 32; + fb->depth = 32; + fb->offset = entry->offset; + fb->bo = entry; + + drm_initial_config(dev, fb, false); + drmfb_probe(dev, fb); + drm_set_desired_modes(dev); + #if 0 /* FIXME: command ring needs AGP space, do we own it at this point? */ dev_priv->ring.Start = dev_priv->baseaddr; @@ -133,8 +176,10 @@ int i915_driver_load(drm_device_t *dev, int i915_driver_unload(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_framebuffer *fb; - intel_modeset_cleanup(dev); + /* FIXME: remove framebuffer */ + //intel_modeset_cleanup(dev); drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; |
From: <jb...@ke...> - 2007-04-11 18:48:36
|
linux-core/intel_display.c | 46 ++++++++------- linux-core/intel_lvds.c | 16 ++--- shared-core/i915_drv.h | 21 +++++++ shared-core/i915_init.c | 132 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 171 insertions(+), 44 deletions(-) New commits: diff-tree 8dd75bd601f5fbf9793afc7b869a278050aa17d5 (from 63d4d40463b04f1277470ccf5cc96dafd81e8687) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 11:47:58 2007 -0700 Add aperture size and preallocation probing (from intelfb), cleanup load code to be more general. diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index b1bf046..c22ab84 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -318,6 +318,27 @@ extern void intel_modeset_cleanup(drm_de extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); +/* + * The Bridge device's PCI config space has information about the + * fb aperture size and the amount of pre-reserved memory. + */ +#define INTEL_GMCH_CTRL 0x52 +#define INTEL_GMCH_ENABLED 0x4 +#define INTEL_GMCH_MEM_MASK 0x1 +#define INTEL_GMCH_MEM_64M 0x1 +#define INTEL_GMCH_MEM_128M 0 + +#define INTEL_855_GMCH_GMS_MASK (0x7 << 4) +#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4) + +#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 43c535d..fba633f 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2007 Intel Corporation + * Jesse Barnes <jes...@in...> + * + * Copyright © 2002, 2003 David Dawes <da...@xf...> + * 2004 Sylvain Meyer + * + * GPL/BSD dual license + */ #include "drmP.h" #include "drm.h" #include "drm_sarea.h" @@ -5,6 +14,96 @@ #include "i915_drv.h" /** + * i915_probe_agp - get AGP bootup configuration + * @pdev: PCI device + * @aperture_size: returns AGP aperture configured size + * @preallocated_size: returns size of BIOS preallocated AGP space + * + * Since Intel integrated graphics are UMA, the BIOS has to set aside + * some RAM for the framebuffer at early boot. This code figures out + * how much was set aside so we can use it for our own purposes. + */ +int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, + unsigned long *preallocated_size) +{ + struct pci_dev *bridge_dev; + u16 tmp = 0; + unsigned long overhead; + + bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); + if (!bridge_dev) { + DRM_ERROR("bridge device not found\n"); + return -1; + } + + /* Get the fb aperture size and "stolen" memory amount. */ + pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); + pci_dev_put(bridge_dev); + + *aperture_size = 1024 * 1024; + *preallocated_size = 1024 * 1024; + + switch (pdev->device) { + case PCI_DEVICE_ID_INTEL_82915G_IG: + case PCI_DEVICE_ID_INTEL_82915GM_IG: + case PCI_DEVICE_ID_INTEL_82945G_IG: + case PCI_DEVICE_ID_INTEL_82945GM_IG: + /* 915 and 945 chipsets support a 256MB aperture. + Aperture size is determined by inspected the + base address of the aperture. */ + if (pci_resource_start(pdev, 2) & 0x08000000) + *aperture_size *= 128; + else + *aperture_size *= 256; + break; + default: + if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) + *aperture_size *= 64; + else + *aperture_size *= 128; + break; + } + + /* + * Some of the preallocated space is taken by the GTT + * and popup. GTT is 1K per MB of aperture size, and popup is 4K. + */ + overhead = (*aperture_size / 1024) + 4096; + switch (tmp & INTEL_855_GMCH_GMS_MASK) { + case INTEL_855_GMCH_GMS_STOLEN_1M: + break; /* 1M already */ + case INTEL_855_GMCH_GMS_STOLEN_4M: + *preallocated_size *= 4; + break; + case INTEL_855_GMCH_GMS_STOLEN_8M: + *preallocated_size *= 8; + break; + case INTEL_855_GMCH_GMS_STOLEN_16M: + *preallocated_size *= 16; + break; + case INTEL_855_GMCH_GMS_STOLEN_32M: + *preallocated_size *= 32; + break; + case INTEL_915G_GMCH_GMS_STOLEN_48M: + *preallocated_size *= 48; + break; + case INTEL_915G_GMCH_GMS_STOLEN_64M: + *preallocated_size *= 64; + break; + case INTEL_855_GMCH_GMS_DISABLED: + DRM_ERROR("video memory is disabled\n"); + return -1; + default: + DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", + tmp & INTEL_855_GMCH_GMS_MASK); + return -1; + } + *preallocated_size -= overhead; + + return 0; +} + +/** * i915_driver_load - setup chip and create an initial config * @dev: DRM device * @flags: startup flags @@ -21,7 +120,8 @@ int i915_driver_load(drm_device_t *dev, drm_i915_init_t init; drm_buffer_object_t *entry; struct drm_framebuffer *fb; - int ret; + unsigned long agp_size, prealloc_size; + int hsize, vsize, bytes_per_pixel, size, ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -41,11 +141,13 @@ int i915_driver_load(drm_device_t *dev, if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); dev_priv->mmiolen = drm_get_resource_len(dev, 0); - dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = + drm_get_resource_start(dev, 2) & 0xff000000; } else if (drm_get_resource_start(dev, 1)) { dev_priv->mmiobase = drm_get_resource_start(dev, 1); dev_priv->mmiolen = drm_get_resource_len(dev, 1); - dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; + dev->mode_config.fb_base = dev_priv->baseaddr = + drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); return -ENODEV; @@ -79,14 +181,18 @@ int i915_driver_load(drm_device_t *dev, * Initialize the memory manager for local and AGP space */ drm_bo_driver_init(dev); - /* FIXME: initial stolen area 8M init */ -#define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */ - drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base, - SCANOUT_SIZE); + + i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, + prealloc_size); /* Allocate scanout buffer and command ring */ /* FIXME: types and other args correct? */ - drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc, + hsize = 1280; + vsize = 800; + bytes_per_pixel = 4; + size = hsize * vsize * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_dc, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, 0, PAGE_SIZE, 0, @@ -102,11 +208,11 @@ int i915_driver_load(drm_device_t *dev, return -EINVAL; } - fb->width = 1024; - fb->height = 768; - fb->pitch = 1024; - fb->bits_per_pixel = 32; - fb->depth = 32; + fb->width = hsize; + fb->height = vsize; + fb->pitch = hsize; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; fb->offset = entry->offset; fb->bo = entry; diff-tree 63d4d40463b04f1277470ccf5cc96dafd81e8687 (from 425da42e95606fec19cc87fad9329d48f93dfe6b) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 11:46:37 2007 -0700 Fix i2c unregistration, cleanup panel_fixed_mode assignment. diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index ec69327..e8670ad 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,7 +164,7 @@ static bool intel_lvds_mode_fixup(struct struct intel_crtc *intel_crtc = output->crtc->driver_private; struct drm_output *tmp_output; -#if 0 +#if 0 /* FIXME: Check for other outputs on this pipe */ spin_lock(&dev->mode_config.config_lock); list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) { if (tmp_output != output && tmp_output->crtc == output->crtc) { @@ -274,11 +274,11 @@ static int intel_lvds_get_modes(struct d "failed.\n"); return 0; } - ret = intel_ddc_get_modes(output); + intel_i2c_destroy(intel_output->ddc_bus); + if (ret) return ret; - intel_i2c_destroy(intel_output->ddc_bus); /* Didn't get an EDID */ if (!output->monitor_info) { @@ -377,13 +377,11 @@ void intel_lvds_init(struct drm_device * intel_ddc_get_modes(output); intel_i2c_destroy(intel_output->ddc_bus); list_for_each_entry(scan, &output->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + dev_priv->panel_fixed_mode = + drm_mode_duplicate(dev, scan); break; - } - - if (scan) { - dev_priv->panel_fixed_mode = scan; - DRM_DEBUG("LVDS panel_fixed: %s\n", scan->name); + } } #if 0 diff-tree 425da42e95606fec19cc87fad9329d48f93dfe6b (from c731b68091aa7284ee3a89c8a7ea3fdabac45a54) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 11:44:54 2007 -0700 Whitespace cleanups. diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index bb6f7f2..396f4cf 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -168,18 +168,18 @@ static const intel_limit_t intel_limits[ }, }; -static const intel_limit_t *intel_limit (struct drm_crtc *crtc) +static const intel_limit_t *intel_limit(struct drm_crtc *crtc) { drm_device_t *dev = crtc->dev; const intel_limit_t *limit; if (IS_I9XX(dev)) { - if (intel_pipe_has_type (crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; else limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; } else { - if (intel_pipe_has_type (crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; else limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; @@ -280,18 +280,20 @@ static bool intel_find_best_PLL(struct d { drm_device_t *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; - intel_clock_t clock; - const intel_limit_t *limit = intel_limit (crtc); + intel_clock_t clock; + const intel_limit_t *limit = intel_limit(crtc); int err = target; - if (IS_I9XX(dev)& intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - (I915_READ(LVDS) & LVDS_PORT_EN) != 0) - { - /* For LVDS, if the panel is on, just rely on its current settings for - * dual-channel. We haven't figured out how to reliably set up - * different single/dual channel state, if we even can. - */ - if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + (I915_READ(LVDS) & LVDS_PORT_EN) != 0) { + /* + * For LVDS, if the panel is on, just rely on its current + * settings for dual-channel. We haven't figured out how to + * reliably set up different single/dual channel state, if we + * even can. + */ + if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP) clock.p2 = limit->p2.p2_fast; else clock.p2 = limit->p2.p2_slow; @@ -304,17 +306,16 @@ static bool intel_find_best_PLL(struct d memset (best_clock, 0, sizeof (*best_clock)); - for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) - { - for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && clock.m2 <= limit->m2.max; clock.m2++) - { - for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) - { - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; clock.p1++) - { + for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { + for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && + clock.m2 <= limit->m2.max; clock.m2++) { + for (clock.n = limit->n.min; clock.n <= limit->n.max; + clock.n++) { + for (clock.p1 = limit->p1.min; + clock.p1 <= limit->p1.max; clock.p1++) { int this_err; - intel_clock (dev, refclk, &clock); + intel_clock(dev, refclk, &clock); if (!intel_PLL_is_valid(crtc, &clock)) continue; @@ -328,6 +329,7 @@ static bool intel_find_best_PLL(struct d } } } + return (err != target); } |
From: <ai...@ke...> - 2007-04-13 05:07:30
|
linux-core/drm_bo.c | 1 linux-core/drm_bufs.c | 3 - linux-core/drm_drv.c | 30 +++++----- linux-core/drm_stub.c | 1 linux-core/i915_drv.c | 1 linux-core/intel_lvds.c | 7 +- shared-core/drm.h | 3 - shared-core/i915_dma.c | 106 -------------------------------------- shared-core/i915_drv.h | 3 + shared-core/i915_init.c | 132 ++++++++++++++++++++++++++---------------------- 10 files changed, 99 insertions(+), 188 deletions(-) New commits: diff-tree cc471a361fc7058df4fb8d15d9c9a8b5cdd3dd77 (from 27598bacfd8e086832753a8b931f0fce18989f8d) Author: David Airlie <ai...@as...> Date: Fri Apr 13 14:33:52 2007 +1000 i915/drm: clean up a lot of the i915/drm startup/teardown sequences When the kernel driver is loaded it sets up a lot of stuff.. it tears down the same stuff on unload. This add a new map type called DRM_DRIVER which means the driver will clean the mapping up and fix up the map cleaner diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 8793ba0..1ba53c8 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -57,7 +57,7 @@ static drm_map_list_t *drm_find_matching drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); if (entry->map && map->type == entry->map->type && ((entry->map->offset == map->offset) || - (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { + ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) { return entry; } } @@ -417,6 +417,7 @@ int drm_rmmap_locked(drm_device_t *dev, break; case _DRM_SHM: vfree(map->handle); + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ break; case _DRM_AGP: case _DRM_SCATTER_GATHER: diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index b7a7ade..7bb8c65 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -147,7 +147,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { int drm_lastclose(drm_device_t * dev) { drm_magic_entry_t *pt, *next; - drm_map_list_t *r_list; + drm_map_list_t *r_list, *r_list_tmp; drm_vma_entry_t *vma, *vma_next; int i; @@ -238,10 +238,9 @@ int drm_lastclose(drm_device_t * dev) } if (dev->maplist) { - while (!list_empty(&dev->maplist->head)) { - struct list_head *list = dev->maplist->head.next; - r_list = list_entry(list, drm_map_list_t, head); - drm_rmmap_locked(dev, r_list->map); + list_for_each_entry_safe(r_list, r_list_tmp, &dev->maplist->head, head) { + if (!(r_list->map->flags & _DRM_DRIVER)) + drm_rmmap_locked(dev, r_list->map); } } @@ -265,8 +264,7 @@ int drm_lastclose(drm_device_t * dev) if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_dma_takedown(dev); - if (dev->lock.hw_lock) { - dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ + if (dev->lock.filp) { dev->lock.filp = NULL; wake_up_interruptible(&dev->lock.lock_queue); } @@ -377,14 +375,6 @@ static void drm_cleanup(drm_device_t * d drm_lastclose(dev); drm_fence_manager_takedown(dev); - if (dev->maplist) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - dev->maplist = NULL; - drm_ht_remove(&dev->map_hash); - drm_mm_takedown(&dev->offset_manager); - drm_ht_remove(&dev->object_hash); - } - if (!drm_fb_loaded) pci_disable_device(dev->pdev); @@ -399,7 +389,7 @@ static void drm_cleanup(drm_device_t * d DRM_DEBUG("mtrr_del=%d\n", retval); } - drm_bo_driver_finish(dev); + // drm_bo_driver_finish(dev); if (drm_core_has_AGP(dev) && dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); @@ -408,6 +398,14 @@ static void drm_cleanup(drm_device_t * d if (dev->driver->unload) dev->driver->unload(dev); + if (dev->maplist) { + drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + dev->maplist = NULL; + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); + drm_ht_remove(&dev->object_hash); + } + drm_put_head(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 13652eb..417e509 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -132,7 +132,6 @@ static int drm_fill_in_dev(drm_device_t } } - if (dev->driver->load) if ((retcode = dev->driver->load(dev, ent->driver_data))) goto error_out_unreg; diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index b9e624f..50ff977 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -80,7 +80,6 @@ static struct drm_driver driver = { DRIVER_IRQ_VBL2, .load = i915_driver_load, .unload = i915_driver_unload, - .firstopen = i915_driver_firstopen, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .device_is_agp = i915_driver_device_is_agp, diff --git a/shared-core/drm.h b/shared-core/drm.h index b5b0aa5..6c626f6 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -289,7 +289,8 @@ typedef enum drm_map_flags { _DRM_KERNEL = 0x08, /**< kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40 /**< Removable mapping */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Driver will take care of it */ } drm_map_flags_t; typedef struct drm_ctx_priv_map { diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index cf729c6..2b29dbe 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -88,16 +88,6 @@ int i915_dma_cleanup(drm_device_t * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - dev_priv->hw_status_page = NULL; - dev_priv->dma_status_page = 0; - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - - dev_priv->sarea_priv = NULL; return 0; } @@ -106,39 +96,6 @@ static int i915_initialize(drm_device_t drm_i915_private_t * dev_priv, drm_i915_init_t * init) { - DRM_GETSAREA(); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); - } - - dev_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->ring.map.offset = init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; dev_priv->cpp = init->cpp; dev_priv->sarea_priv->pf_current_page = 0; @@ -152,27 +109,6 @@ static int i915_initialize(drm_device_t */ dev_priv->allow_batchbuffer = 1; - /* Program Hardware Status Page */ - dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, - 0xffffffff); - - if (!dev_priv->status_page_dmah) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return DRM_ERR(ENOMEM); - } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I915_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - -//drm_set_desired_modes(dev); - return 0; } @@ -182,29 +118,6 @@ static int i915_dma_resume(drm_device_t DRM_DEBUG("%s\n", __FUNCTION__); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - return DRM_ERR(EINVAL); - } - - if (!dev_priv->mmio_map) { - DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); - } - - if (dev_priv->ring.map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } - - /* Program Hardware Status Page */ - if (!dev_priv->hw_status_page) { - DRM_ERROR("Can not find hardware status page\n"); - return DRM_ERR(EINVAL); - } - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); @@ -889,23 +802,4 @@ int i915_driver_device_is_agp(drm_device return 1; } -int i915_driver_firstopen(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - DRM_DEBUG("\n"); - - if (!dev_priv->mmio_map) { - ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); - if (ret != 0) { - DRM_ERROR("Cannot add mapping for MMIO registers\n"); - return ret; - } - } - - DRM_DEBUG("dev_priv->mmio map is %p\n", dev_priv->mmio_map); - - return 0; -} diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c22ab84..f434301 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -89,6 +89,7 @@ typedef struct _drm_i915_vbl_swap { } drm_i915_vbl_swap_t; typedef struct drm_i915_private { + drm_buffer_object_t *ring_buffer; drm_local_map_t *sarea; drm_local_map_t *mmio_map; @@ -922,4 +923,6 @@ extern int i915_wait_ring(drm_device_t * #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) +#define PRIMARY_RINGBUFFER_SIZE (128*1024) + #endif diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index f0ab457..be70262 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -151,7 +151,7 @@ int i915_driver_load(drm_device_t *dev, } ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map); + _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); if (ret != 0) { DRM_ERROR("Cannot add mapping for MMIO registers\n"); return ret; @@ -159,20 +159,13 @@ int i915_driver_load(drm_device_t *dev, /* prebuild the SAREA */ sareapage = max(SAREA_MAX, PAGE_SIZE); - ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, - &map); + ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, + &dev_priv->sarea); if (ret) { DRM_ERROR("SAREA setup failed\n"); return ret; } - DRM_GETSAREA(); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); - } init_waitqueue_head(&dev->lock.lock_queue); /* FIXME: assume sarea_priv is right after SAREA */ @@ -187,61 +180,34 @@ int i915_driver_load(drm_device_t *dev, drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, prealloc_size); - /* Allocate scanout buffer and command ring */ - /* FIXME: types and other args correct? */ - hsize = 1280; - vsize = 800; - bytes_per_pixel = 4; - size = hsize * vsize * bytes_per_pixel; - drm_buffer_object_create(dev, size, drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, - 0, PAGE_SIZE, 0, - &entry); - - intel_modeset_init(dev); - - fb = drm_framebuffer_create(dev); - if (!fb) { - DRM_ERROR("failed to allocate fb\n"); + size = PRIMARY_RINGBUFFER_SIZE; + ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_NO_MOVE, + DRM_BO_HINT_DONT_FENCE, 0x1, 0, + &dev_priv->ring_buffer); + if (ret < 0) { + DRM_ERROR("Unable to allocate ring buffer\n"); return -EINVAL; } - fb->width = hsize; - fb->height = vsize; - fb->pitch = hsize; - fb->bits_per_pixel = bytes_per_pixel * 8; - fb->depth = bytes_per_pixel * 8; - fb->offset = entry->offset; - fb->bo = entry; - - drm_initial_config(dev, fb, false); - drmfb_probe(dev, fb); -#if 0 - /* FIXME: command ring needs AGP space, do we own it at this point? */ - dev_priv->ring.Start = dev_priv->baseaddr; - dev_priv->ring.End = 128*1024; - dev_priv->ring.Size = 128*1024; + /* remap the buffer object properly */ + dev_priv->ring.Start = dev_priv->ring_buffer->offset + dev_priv->baseaddr; + dev_priv->ring.End = dev_priv->ring.Start + size; + dev_priv->ring.Size = size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - dev_priv->ring.map.offset = dev_priv->ring.Start; - dev_priv->ring.map.size = dev_priv->ring.Size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; + dev_priv->ring.virtual_start = ioremap((dev_priv->ring.Start), (dev_priv->ring_buffer->mem.num_pages * PAGE_SIZE)); - drm_core_ioremap(&dev_priv->ring.map, dev); - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return DRM_ERR(ENOMEM); - } + DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); + I915_WRITE(LP_RING + RING_HEAD, 0); + I915_WRITE(LP_RING + RING_TAIL, 0); + I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); + I915_WRITE(LP_RING + RING_LEN, ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | + (RING_NO_REPORT | RING_VALID)); - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - dev_priv->cpp = 4; dev_priv->sarea_priv->pf_current_page = 0; /* We are using separate values as placeholders for mechanisms for @@ -271,8 +237,40 @@ int i915_driver_load(drm_device_t *dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); + +#if 1 + /* Allocate scanout buffer and command ring */ + /* FIXME: types and other args correct? */ + hsize = 1280; + vsize = 800; + bytes_per_pixel = 4; + size = hsize * vsize * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, PAGE_SIZE, 0, + &entry); #endif + intel_modeset_init(dev); + +#if 1 + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb\n"); + return -EINVAL; + } + fb->width = hsize; + fb->height = vsize; + fb->pitch = hsize; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; + fb->offset = entry->offset; + fb->bo = entry; + + drm_initial_config(dev, fb, false); + drmfb_probe(dev, fb); +#endif return 0; } @@ -281,7 +279,26 @@ int i915_driver_unload(drm_device_t *dev drm_i915_private_t *dev_priv = dev->dev_private; struct drm_framebuffer *fb; + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + dev_priv->hw_status_page = NULL; + dev_priv->dma_status_page = 0; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } + + I915_WRITE(LP_RING + RING_LEN, 0); + + iounmap(dev_priv->ring.virtual_start); + + drm_bo_driver_finish(dev); + intel_modeset_cleanup(dev); + DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); + drm_rmmap(dev, dev_priv->mmio_map); + drm_rmmap(dev, dev_priv->sarea); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -296,7 +313,6 @@ void i915_driver_lastclose(drm_device_t i915_dma_cleanup(dev); - dev_priv->mmio_map = NULL; } void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) diff-tree 27598bacfd8e086832753a8b931f0fce18989f8d (from a890d596fc22a3dca9d390f96f0f739cf90de5e1) Author: David Airlie <ai...@as...> Date: Fri Apr 13 14:31:10 2007 +1000 export drm_bo_driver_finish symbol diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index a379c74..045d5fd 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2125,6 +2125,7 @@ int drm_bo_driver_finish(drm_device_t * mutex_unlock(&dev->bm.init_mutex); return ret; } +EXPORT_SYMBOL(drm_bo_driver_finish); int drm_bo_driver_init(drm_device_t * dev) { diff-tree a890d596fc22a3dca9d390f96f0f739cf90de5e1 (from 9f0f6509f5278b5d46a282acf40e7b69790892a6) Author: David Airlie <ai...@as...> Date: Fri Apr 13 14:30:44 2007 +1000 revert LVDS destroy - this oops on sysfs on sdvo init of i2c bus diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 4020ec6..db02541 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -476,8 +476,7 @@ out: return; failed: - DRM_DEBUG("No LVDS modes found, disabling.\n"); - intel_i2c_destroy(intel_output->ddc_bus); - kfree(output->driver_private); - drm_output_destroy(output); + DRM_DEBUG("No LVDS modes found, disabling.\n"); + // intel_lvds_destroy(output); + // drm_output_destroy(output); } |
From: <ai...@ke...> - 2007-04-17 08:19:21
|
linux-core/drmP.h | 2 ++ linux-core/drm_bo.c | 5 ++++- linux-core/drm_bo_move.c | 1 + linux-core/drm_crtc.c | 33 +++++++++++++++++++++++++-------- linux-core/drm_crtc.h | 1 + linux-core/drm_fb.c | 7 ++----- linux-core/drm_fops.c | 4 +++- linux-core/drm_objects.h | 5 +++++ linux-core/drm_stub.c | 13 +++++++------ shared-core/i915_dma.c | 12 ++++++++++++ shared-core/i915_drv.h | 1 - shared-core/i915_init.c | 35 ++++++++++++++++++++++------------- 12 files changed, 84 insertions(+), 35 deletions(-) New commits: diff-tree 1a5e647f63f083788a7fe43c2367d2e022c48588 (from 56ef1ab8acc0c68b66c4f781107b605f9dd79657) Author: Dave Airlie <ai...@li...> Date: Tue Apr 17 18:18:42 2007 +1000 I don't think this dec is necessary and my stuff all works without .. with it everything falls over diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 343cc1e..d6dce10 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1740,7 +1740,8 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) entry = drm_user_object_entry(uo, drm_buffer_object_t, base); - atomic_dec(&entry->usage); + /* I don't think this is needed - D.A. */ + // atomic_dec(&entry->usage); mutex_unlock(&dev->struct_mutex); mutex_lock(&entry->mutex); drm_bo_fill_rep_arg(entry, &rep); diff-tree 56ef1ab8acc0c68b66c4f781107b605f9dd79657 (from 79aa1d54746f33c33ffbf98fb96ccbf88c3cb390) Author: Dave Airlie <ai...@li...> Date: Tue Apr 17 18:18:25 2007 +1000 add some missing export symbols diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 045d5fd..343cc1e 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -494,6 +494,7 @@ void drm_bo_usage_deref_locked(drm_buffe drm_bo_destroy_locked(bo); } } +EXPORT_SYMBOL(drm_bo_usage_deref_locked); static void drm_bo_base_deref_locked(drm_file_t * priv, drm_user_object_t * uo) { @@ -1993,6 +1994,7 @@ int drm_bo_clean_mm(drm_device_t * dev, return ret; } +EXPORT_SYMBOL(drm_bo_clean_mm); /** *Evict all buffers of a particular mem_type, but leave memory manager diff-tree 79aa1d54746f33c33ffbf98fb96ccbf88c3cb390 (from cd5769c3b563048357535b24dc40783775adb227) Author: Dave Airlie <ai...@li...> Date: Tue Apr 17 18:16:38 2007 +1000 another large overhaul of interactions with userspace... We need to keep a list of user created fbs to nuke on master exit. We also need to use the bo properly. diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 0d0ec99..326565c 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -431,6 +431,8 @@ typedef struct drm_file { drm_open_hash_t refd_object_hash[_DRM_NO_REF_TYPES]; void *driver_priv; + + struct list_head fbs; } drm_file_t; /** Wait queue */ diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c index 415e4be..eaeef1b 100644 --- a/linux-core/drm_bo_move.c +++ b/linux-core/drm_bo_move.c @@ -151,6 +151,7 @@ void drm_mem_reg_iounmap(drm_device_t * iounmap(virtual); } } +EXPORT_SYMBOL(drm_mem_reg_iounmap); static int drm_copy_io_page(void *dst, void *src, unsigned long page) { diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index adea030..bf019df 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -64,6 +64,15 @@ void drm_framebuffer_destroy(struct drm_ { drm_device_t *dev = fb->dev; + /* remove from any CRTC */ + { + struct drm_crtc *crtc; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->fb == fb) + crtc->fb = NULL; + } + } + spin_lock(&dev->mode_config.config_lock); drm_mode_idr_put(dev, fb->id); list_del(&fb->head); @@ -1034,6 +1043,7 @@ int drm_mode_addfb(struct inode *inode, r.buffer_id = fb->id; + list_add(&fb->filp_head, &priv->fbs); /* bind the fb to the crtc for now */ { struct drm_crtc *crtc; @@ -1049,7 +1059,7 @@ int drm_mode_addfb(struct inode *inode, } int drm_mode_rmfb(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -1067,13 +1077,6 @@ int drm_mode_rmfb(struct inode *inode, s /* TODO check if we own the buffer */ /* TODO release all crtc connected to the framebuffer */ /* bind the fb to the crtc for now */ - { - struct drm_crtc *crtc; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb == fb) - crtc->fb = NULL; - } - } /* TODO unhock the destructor from the buffer object */ drm_framebuffer_destroy(fb); @@ -1111,3 +1114,17 @@ int drm_mode_getfb(struct inode *inode, return 0; } + +void drm_fb_release(struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + struct drm_framebuffer *fb, *tfb; + + list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { + list_del(&fb->filp_head); + drmfb_remove(dev, fb); + drm_framebuffer_destroy(fb); + + } +} diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index c02dced..584788e 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -184,6 +184,7 @@ struct drm_framebuffer { void *fbdev; u32 pseudo_palette[17]; void *virtual_base; + struct list_head filp_head; }; struct drm_crtc; struct drm_output; diff --git a/linux-core/drm_fb.c b/linux-core/drm_fb.c index df979cd..ef05341 100644 --- a/linux-core/drm_fb.c +++ b/linux-core/drm_fb.c @@ -84,6 +84,7 @@ static int drmfb_set_par(struct fb_info struct drm_device *dev = par->dev; drm_set_desired_modes(dev); + return 0; } static struct fb_ops drmfb_ops = { @@ -136,10 +137,6 @@ int drmfb_probe(struct drm_device *dev, info->flags = FBINFO_DEFAULT; - base = fb->bo->offset + dev->mode_config.fb_base; - size = (fb->bo->mem.num_pages * PAGE_SIZE); - - DRM_DEBUG("remapping %08X %d\n", base, size); ret = drm_mem_reg_ioremap(dev, &fb->bo->mem, &fb->virtual_base); if (ret) DRM_ERROR("error mapping fb: %d\n", ret); @@ -194,7 +191,7 @@ int drmfb_remove(struct drm_device *dev, struct fb_info *info = fb->fbdev; if (info) { - iounmap(fb->virtual_base); + drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base); unregister_framebuffer(info); framebuffer_release(info); } diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index d400a4d..e474897 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -86,7 +86,7 @@ static int drm_setup(drm_device_t * dev) INIT_LIST_HEAD(&dev->ctxlist->head); dev->vmalist = NULL; - dev->sigdata.lock = NULL; + // dev->sigdata.lock = NULL; init_waitqueue_head(&dev->lock.lock_queue); dev->queue_count = 0; dev->queue_reserved = 0; @@ -270,6 +270,7 @@ static int drm_open_helper(struct inode INIT_LIST_HEAD(&priv->user_objects); INIT_LIST_HEAD(&priv->refd_objects); + INIT_LIST_HEAD(&priv->fbs); for (i=0; i<_DRM_NO_REF_TYPES; ++i) { ret = drm_ht_create(&priv->refd_object_hash[i], DRM_FILE_HASH_ORDER); @@ -501,6 +502,7 @@ int drm_release(struct inode *inode, str mutex_unlock(&dev->ctxlist_mutex); mutex_lock(&dev->struct_mutex); + drm_fb_release(filp); drm_object_release(filp); if (priv->remove_auth_on_close == 1) { drm_file_t *temp = dev->file_first; diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index b3155af..401fd0e 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -467,4 +467,9 @@ extern int drm_bo_move_accel_cleanup(drm uint32_t fence_flags, drm_bo_mem_reg_t * new_mem); +extern int drm_mem_reg_ioremap(struct drm_device *dev, drm_bo_mem_reg_t * mem, + void **virtual); +extern void drm_mem_reg_iounmap(struct drm_device *dev, drm_bo_mem_reg_t * mem, + void *virtual); + #endif diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 417e509..01ffe67 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -79,27 +79,28 @@ static int drm_fill_in_dev(drm_device_t #endif dev->irq = pdev->irq; - if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) return -ENOMEM; - } + if (drm_mm_init(&dev->offset_manager, DRM_FILE_PAGE_OFFSET_START, DRM_FILE_PAGE_OFFSET_SIZE)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); drm_ht_remove(&dev->map_hash); return -ENOMEM; } if (drm_ht_create(&dev->object_hash, DRM_OBJECT_HASH_ORDER)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); drm_ht_remove(&dev->map_hash); drm_mm_takedown(&dev->offset_manager); return -ENOMEM; } dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); - if (dev->maplist == NULL) + if (dev->maplist == NULL) { + drm_ht_remove(&dev->object_hash); + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); return -ENOMEM; + } INIT_LIST_HEAD(&dev->maplist->head); /* the DRM has 6 counters */ diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 2b29dbe..25172c1 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -85,6 +85,8 @@ int i915_dma_cleanup(drm_device_t * dev) * may not have been called from userspace and after dev_private * is freed, it's too late. */ + I915_WRITE(LP_RING + RING_LEN, 0); + if (dev->irq) drm_irq_uninstall(dev); @@ -97,6 +99,16 @@ static int i915_initialize(drm_device_t drm_i915_init_t * init) { + /* reset ring pointers */ + I915_WRITE(LP_RING + RING_LEN, 0); + mb(); + + memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size); + + I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); + I915_WRITE(LP_RING + RING_LEN, ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | (RING_NO_REPORT | RING_VALID)); + + dev_priv->cpp = init->cpp; dev_priv->sarea_priv->pf_current_page = 0; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f434301..8c2b481 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -93,7 +93,6 @@ typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; - unsigned long baseaddr; unsigned long mmiobase; unsigned long mmiolen; diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 273a111..2ed7a82 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -138,12 +138,12 @@ int i915_driver_load(drm_device_t *dev, if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); dev_priv->mmiolen = drm_get_resource_len(dev, 0); - dev->mode_config.fb_base = dev_priv->baseaddr = + dev->mode_config.fb_base = drm_get_resource_start(dev, 2) & 0xff000000; } else if (drm_get_resource_start(dev, 1)) { dev_priv->mmiobase = drm_get_resource_start(dev, 1); dev_priv->mmiolen = drm_get_resource_len(dev, 1); - dev->mode_config.fb_base = dev_priv->baseaddr = + dev->mode_config.fb_base = drm_get_resource_start(dev, 0) & 0xff000000; } else { DRM_ERROR("Unable to find MMIO registers\n"); @@ -178,14 +178,18 @@ int i915_driver_load(drm_device_t *dev, i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); DRM_DEBUG("setting up %d bytes of PRIV0 space\n", prealloc_size); - drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, + drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, 0, prealloc_size >> PAGE_SHIFT); + I915_WRITE(LP_RING + RING_LEN, 0); + I915_WRITE(LP_RING + RING_HEAD, 0); + I915_WRITE(LP_RING + RING_TAIL, 0); + size = PRIMARY_RINGBUFFER_SIZE; ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_PRIV0 | - DRM_BO_FLAG_NO_MOVE, + DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, 0x1, 0, &dev_priv->ring_buffer); if (ret < 0) { @@ -194,23 +198,17 @@ int i915_driver_load(drm_device_t *dev, } /* remap the buffer object properly */ - dev_priv->ring.Start = dev_priv->ring_buffer->offset + dev_priv->baseaddr; + dev_priv->ring.Start = dev_priv->ring_buffer->offset; dev_priv->ring.End = dev_priv->ring.Start + size; dev_priv->ring.Size = size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, &dev_priv->ring.virtual_start); if (ret) DRM_ERROR("error mapping ring buffer: %d\n", ret); DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); - I915_WRITE(LP_RING + RING_HEAD, 0); - I915_WRITE(LP_RING + RING_TAIL, 0); - I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); - I915_WRITE(LP_RING + RING_LEN, ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | - (RING_NO_REPORT | RING_VALID)); dev_priv->sarea_priv->pf_current_page = 0; @@ -294,11 +292,22 @@ int i915_driver_unload(drm_device_t *dev I915_WRITE(LP_RING + RING_LEN, 0); - iounmap(dev_priv->ring.virtual_start); + intel_modeset_cleanup(dev); + + drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, + dev_priv->ring.virtual_start); + + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(dev_priv->ring_buffer); + mutex_unlock(&dev->struct_mutex); + + if (drm_bo_clean_mm(dev, DRM_BO_MEM_PRIV0)) { + DRM_ERROR("Memory manager type 3 not clean. " + "Delaying takedown\n"); + } drm_bo_driver_finish(dev); - intel_modeset_cleanup(dev); DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); drm_rmmap(dev, dev_priv->mmio_map); drm_rmmap(dev, dev_priv->sarea); |
From: <al...@ke...> - 2007-04-17 15:11:39
|
linux-core/intel_sdvo.c | 20 +++++++++++++++----- linux-core/intel_sdvo_regs.h | 6 +++++- shared-core/i915_init.c | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) New commits: diff-tree b729b919baed250313caf3f0bbd4044e084de8bf (from ecd9801c3cf08082b4aaa7e23f1f94a5e1d47a75) Author: Alan Hourihane <al...@fa...> Date: Tue Apr 17 16:11:00 2007 +0100 Fix a register read that was swapped SDVOB/SDVOC Check for the PENDING message when reading the attached displays. Ensures the command has completed before continuing. (probably need to check PENDING in other SDVO calls too) diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 1b45afd..6f592f8 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -29,6 +29,7 @@ */ #include <linux/i2c.h> +#include <linux/delay.h> #include "drmP.h" #include "drm.h" #include "drm_crtc.h" @@ -69,9 +70,9 @@ static void intel_sdvo_write_sdvox(struc int i; if (sdvo_priv->output_device == SDVOB) - cval = I915_READ(SDVOC); - else bval = I915_READ(SDVOB); + else + cval = I915_READ(SDVOC); /* * Write the registers twice for luck. Sometimes, @@ -869,12 +870,21 @@ static enum drm_output_status intel_sdvo { u8 response[2]; u8 status; + u8 retry = 50; intel_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); - status = intel_sdvo_read_response(output, &response, 2); - if (status != SDVO_CMD_STATUS_SUCCESS) - return output_status_unknown; + while (retry--) { + status = intel_sdvo_read_response(output, &response, 2); + + if (status == SDVO_CMD_STATUS_SUCCESS) + break; + + if (status != SDVO_CMD_STATUS_PENDING) + return output_status_unknown; + + mdelay(50); + } DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); if ((response[0] != 0) || (response[1] != 0)) diff-tree ecd9801c3cf08082b4aaa7e23f1f94a5e1d47a75 (from 32b5616cc681e404f671b4bc3b030ee24b753d4a) Author: Alan Hourihane <al...@fa...> Date: Tue Apr 17 16:09:40 2007 +0100 Fix SDVO outputs diff --git a/linux-core/intel_sdvo_regs.h b/linux-core/intel_sdvo_regs.h index c8ab950..a9d1671 100644 --- a/linux-core/intel_sdvo_regs.h +++ b/linux-core/intel_sdvo_regs.h @@ -37,7 +37,11 @@ #define SDVO_OUTPUT_SCART0 (1 << 5) #define SDVO_OUTPUT_LVDS0 (1 << 6) #define SDVO_OUTPUT_TMDS1 (1 << 8) -#define SDVO_OUTPUT_RGB1 (1 << 13) +#define SDVO_OUTPUT_RGB1 (1 << 9) +#define SDVO_OUTPUT_CVBS1 (1 << 10) +#define SDVO_OUTPUT_SVID1 (1 << 11) +#define SDVO_OUTPUT_YPRPB1 (1 << 12) +#define SDVO_OUTPUT_SCART1 (1 << 13) #define SDVO_OUTPUT_LVDS1 (1 << 14) #define SDVO_OUTPUT_LAST (14) diff-tree 32b5616cc681e404f671b4bc3b030ee24b753d4a (from 1a5e647f63f083788a7fe43c2367d2e022c48588) Author: Alan Hourihane <al...@fa...> Date: Tue Apr 17 16:08:26 2007 +0100 Correct PCI ID for i845 diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 2ed7a82..5872aeb 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -45,7 +45,7 @@ int i915_probe_agp(struct pci_dev *pdev, switch (pdev->device) { case PCI_DEVICE_ID_INTEL_82830_CGC: - case PCI_DEVICE_ID_INTEL_82845G_HB: + case PCI_DEVICE_ID_INTEL_82845G_IG: case PCI_DEVICE_ID_INTEL_82855GM_IG: case PCI_DEVICE_ID_INTEL_82865_IG: if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) |
From: <jb...@ke...> - 2007-05-18 16:43:05
|
linux-core/drm_crtc.c | 338 ++++++++++++++++++++++++++++--------------------- linux-core/drm_crtc.h | 1 linux-core/drm_fb.c | 9 - linux-core/drm_modes.c | 2 linux-core/edid.h | 138 -------------------- linux-core/intel_fb.c | 1 6 files changed, 202 insertions(+), 287 deletions(-) New commits: diff-tree a4929b921e44dcd3cae8e384b9b7eabc51db28ff (from parents) Merge: f89458722173b364b8c3c27788b6c61889da554c d42c1de3fb05405820b03ec9bb12f0b9a7eb0a7b Author: Jesse Barnes <jb...@ho...> Date: Fri May 18 09:42:51 2007 -0700 Merge branch 'modesetting-101' of git+ssh://git.freedesktop.org/git/mesa/drm into origin/modesetting-101 Conflicts: linux-core/drm_crtc.c - reconcile with locking changes diff --cc linux-core/drm_crtc.c index e5a4b32,1586eb1..245fe5b @@@ -857,15 -886,7 +856,10 @@@ */ bool drm_initial_config(drm_device_t *dev, bool can_grow) { - /* do a hardcoded initial configuration here */ - struct drm_display_mode *des_mode = NULL; struct drm_output *output; - struct drm_framebuffer *fb; - drm_buffer_object_t *fbo; - unsigned long size, bytes_per_pixel; + int ret = false; + + spin_lock(&dev->mode_config.config_lock); drm_crtc_probe_output_modes(dev, 2048, 2048); @@@ -918,9 -902,7 +875,8 @@@ } drm_disable_unused_functions(dev); - out: - return false; + spin_unlock(&dev->mode_config.config_lock); + return ret; } EXPORT_SYMBOL(drm_initial_config); diff-tree f89458722173b364b8c3c27788b6c61889da554c (from f3beabedc36b7bc2d45ca9c7f64d2c54e291e32b) Author: Jesse Barnes <jb...@ho...> Date: Fri May 18 09:40:01 2007 -0700 Add locking. The main lock is dev->mode_config.config_lock. It should be held across any operations that modify mode lists, crtc config, output config, etc. It should be taken at high level entry points (currently just initial config and user IOCTL). Seems to work ok on my system, but needs more testing (with lockdep) and review from some fresh eyes. diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index ab8b468..e5a4b32 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -39,8 +39,7 @@ * @ptr: object pointer, used to generate unique ID * * LOCKING: - * Process context (either init or calling process). Must take DRM mode_config - * lock around IDR allocation. + * Caller must hold DRM mode_config lock. * * Create a unique identifier based on @ptr in @dev's identifier space. Used * for tracking modes, CRTCs and outputs. @@ -59,15 +58,12 @@ again: return 0; } - spin_lock(&dev->mode_config.config_lock); - ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id); if (ret == -EAGAIN) { spin_unlock(&dev->mode_config.config_lock); goto again; } - spin_unlock(&dev->mode_config.config_lock); return new_id; } @@ -116,8 +112,7 @@ struct drm_crtc *drm_crtc_from_fb(struct * @dev: DRM device * * LOCKING: - * Process context (either init or calling process). Must take DRM mode_config - * lock around mode_config manipulation. + * Caller must hold mode config lock. * * Creates a new framebuffer objects and adds it to @dev's DRM mode_config. * @@ -128,27 +123,21 @@ struct drm_framebuffer *drm_framebuffer_ { struct drm_framebuffer *fb; - spin_lock(&dev->mode_config.config_lock); /* Limit to single framebuffer for now */ if (dev->mode_config.num_fb > 1) { spin_unlock(&dev->mode_config.config_lock); DRM_ERROR("Attempt to add multiple framebuffers failed\n"); return NULL; } - spin_unlock(&dev->mode_config.config_lock); fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL); - if (!fb) { - + if (!fb) return NULL; - } fb->id = drm_idr_get(dev, fb); fb->dev = dev; - spin_lock(&dev->mode_config.config_lock); dev->mode_config.num_fb++; list_add(&fb->head, &dev->mode_config.fb_list); - spin_unlock(&dev->mode_config.config_lock); return fb; } @@ -159,8 +148,7 @@ EXPORT_SYMBOL(drm_framebuffer_create); * @fb: framebuffer to remove * * LOCKING: - * Process context (either init or calling process). Must take DRM mode_config - * lock around mode_config manipulation. + * Caller must hold mode config lock. * * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes * it, setting it to NULL. @@ -171,7 +159,6 @@ void drm_framebuffer_destroy(struct drm_ struct drm_crtc *crtc; /* remove from any CRTC */ - spin_lock(&dev->mode_config.config_lock); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (crtc->fb == fb) crtc->fb = NULL; @@ -180,7 +167,6 @@ void drm_framebuffer_destroy(struct drm_ drm_idr_put(dev, fb->id); list_del(&fb->head); dev->mode_config.num_fb--; - spin_unlock(&dev->mode_config.config_lock); kfree(fb); } @@ -191,8 +177,7 @@ void drm_framebuffer_destroy(struct drm_ * @funcs: callbacks for the new CRTC * * LOCKING: - * Process context (either init or calling process). Must take DRM mode_config - * lock around mode_config manipulation. + * Caller must hold mode config lock. * * Creates a new CRTC object and adds it to @dev's mode_config structure. * @@ -213,10 +198,8 @@ struct drm_crtc *drm_crtc_create(drm_dev crtc->id = drm_idr_get(dev, crtc); - spin_lock(&dev->mode_config.config_lock); list_add_tail(&crtc->head, &dev->mode_config.crtc_list); dev->mode_config.num_crtc++; - spin_unlock(&dev->mode_config.config_lock); return crtc; } @@ -227,8 +210,7 @@ EXPORT_SYMBOL(drm_crtc_create); * @crtc: CRTC to remove * * LOCKING: - * Process context (either init or calling process). Must take DRM mode_config - * lock around mode_config traversal. + * Caller must hold mode config lock. * * Cleanup @crtc. Calls @crtc's cleanup function, then removes @crtc from * its associated DRM device's mode_config. Frees it afterwards. @@ -240,11 +222,9 @@ void drm_crtc_destroy(struct drm_crtc *c if (crtc->funcs->cleanup) (*crtc->funcs->cleanup)(crtc); - spin_lock(&dev->mode_config.config_lock); drm_idr_put(dev, crtc->id); list_del(&crtc->head); dev->mode_config.num_crtc--; - spin_unlock(&dev->mode_config.config_lock); kfree(crtc); } EXPORT_SYMBOL(drm_crtc_destroy); @@ -254,7 +234,7 @@ EXPORT_SYMBOL(drm_crtc_destroy); * @crtc: CRTC to check * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * Walk @crtc's DRM device's mode_config and see if it's in use. * @@ -289,7 +269,7 @@ static struct drm_display_mode std_mode[ * @maxY: max height for modes * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * Based on @dev's mode_config layout, scan all the outputs and try to detect * modes on them. Modes will first be added to the output's probed_modes @@ -379,7 +359,7 @@ void drm_crtc_probe_output_modes(struct * @y: height of mode * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * Try to set @mode on @crtc. Give @crtc and its associated outputs a chance * to fixup or reject the mode prior to trying to set it. @@ -497,7 +477,7 @@ EXPORT_SYMBOL(drm_crtc_set_mode); * @dev: DRM device * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * If an output or CRTC isn't part of @dev's mode_config, it can be disabled * by calling its dpms function, which should power it off. @@ -524,17 +504,14 @@ void drm_disable_unused_functions(struct * @mode: mode data * * LOCKING: - * Process context (either init or calling process). Must take @output's - * mode_lock around mode list manipulation. + * Caller must hold mode config lock. * * Add @mode to @output's mode list for later use. */ void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode) { - spin_lock(&output->modes_lock); list_add(&mode->head, &output->probed_modes); - spin_unlock(&output->modes_lock); } EXPORT_SYMBOL(drm_mode_probed_add); @@ -544,16 +521,13 @@ EXPORT_SYMBOL(drm_mode_probed_add); * @mode: mode to remove * * LOCKING: - * Process context (either init or calling process). Must take @output's - * mode_lock around mode list manipulation. + * Caller must hold mode config lock. * * Remove @mode from @output's mode list, then free it. */ void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode) { - spin_lock(&output->modes_lock); list_del(&mode->head); - spin_unlock(&output->modes_lock); kfree(mode); } EXPORT_SYMBOL(drm_mode_remove); @@ -565,8 +539,7 @@ EXPORT_SYMBOL(drm_mode_remove); * @name: user visible name of the output * * LOCKING: - * Process context (either init or calling process). Must take @dev's - * mode_config lock around mode list manipulation. + * Caller must hold @dev's mode_config lock. * * Creates a new drm_output structure and adds it to @dev's mode_config * structure. @@ -593,7 +566,6 @@ struct drm_output *drm_output_create(drm output->subpixel_order = SubPixelUnknown; INIT_LIST_HEAD(&output->probed_modes); INIT_LIST_HEAD(&output->modes); - spin_lock_init(&output->modes_lock); /* randr_output? */ /* output_set_monitor(output)? */ /* check for output_ignored(output)? */ @@ -614,9 +586,7 @@ EXPORT_SYMBOL(drm_output_create); * @output: output to remove * * LOCKING: - * Process context (either init or calling process). Must take @dev's - * mode_config lock around mode list manipulation. Caller must hold - * modes lock? (FIXME) + * Caller must hold @dev's mode_config lock. * * Call @output's cleanup function, then remove the output from the DRM * mode_config after freeing @output's modes. @@ -704,7 +674,7 @@ EXPORT_SYMBOL(drm_mode_create); * @mode: mode to remove * * LOCKING: - * None. + * Caller must hold mode config lock. * * Free @mode's unique identifier, then free it. */ @@ -786,7 +756,7 @@ out_err: * @dev: DRM device * * LOCKING: - * None. + * Caller must hold mode config lock. */ static void drm_pick_crtcs (drm_device_t *dev) { @@ -876,7 +846,7 @@ clone: * @can_grow: this configuration is growable * * LOCKING: - * Must take various locks. (FIXME) + * Called at init time, must take mode config lock. * * Scan the CRTCs and outputs and try to put together an initial setup. * At the moment, this is a cloned configuration across all heads with @@ -893,7 +863,9 @@ bool drm_initial_config(drm_device_t *de struct drm_framebuffer *fb; drm_buffer_object_t *fbo; unsigned long size, bytes_per_pixel; - int ret; + int ret = false; + + spin_lock(&dev->mode_config.config_lock); drm_crtc_probe_output_modes(dev, 2048, 2048); @@ -908,7 +880,8 @@ bool drm_initial_config(drm_device_t *de fb = drm_framebuffer_create(dev); if (!fb) { DRM_ERROR("failed to allocate fb.\n"); - return true; + ret = true; + goto out; } output->crtc->fb = fb; des_mode = output->crtc->desired_mode; @@ -945,7 +918,9 @@ bool drm_initial_config(drm_device_t *de } drm_disable_unused_functions(dev); - return false; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } EXPORT_SYMBOL(drm_initial_config); @@ -954,7 +929,7 @@ EXPORT_SYMBOL(drm_initial_config); * @dev: DRM device * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * Free up all the outputs and CRTCs associated with this DRM device, then * free up the framebuffers and associated buffer objects. @@ -1001,7 +976,7 @@ EXPORT_SYMBOL(drm_mode_config_cleanup); * @fb: new framebuffer * * LOCKING: - * Caller? (FIXME) + * Caller must hold mode config lock. * * Setup a new configuration, provided by the user in @crtc_info, and enable * it. @@ -1144,7 +1119,7 @@ void drm_crtc_convert_umode(struct drm_d * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Construct a set of configuration description structures and return * them to the user, including CRTC, output and framebuffer configuration. @@ -1167,7 +1142,7 @@ int drm_mode_getresources(struct inode * struct drm_crtc *crtc; struct drm_mode_modeinfo u_mode; struct drm_display_mode *mode; - int retcode = 0; + int ret = 0; int mode_count= 0; int output_count = 0; int crtc_count = 0; @@ -1176,6 +1151,8 @@ int drm_mode_getresources(struct inode * memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); + spin_lock(&dev->mode_config.config_lock); + list_for_each(lh, &dev->mode_config.fb_list) fb_count++; @@ -1191,8 +1168,10 @@ int drm_mode_getresources(struct inode * list_for_each(lh, &dev->mode_config.usermode_list) mode_count++; - if (copy_from_user(&card_res, argp, sizeof(card_res))) - return -EFAULT; + if (copy_from_user(&card_res, argp, sizeof(card_res))) { + ret = -EFAULT; + goto out_unlock; + } if (card_res.count_modes == 0) { DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height); @@ -1212,7 +1191,7 @@ int drm_mode_getresources(struct inode * copied = 0; list_for_each_entry(fb, &dev->mode_config.fb_list, head) { if (put_user(fb->id, &card_res.fb_id[copied++])) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1225,7 +1204,7 @@ int drm_mode_getresources(struct inode * list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){ DRM_DEBUG("CRTC ID is %d\n", crtc->id); if (put_user(crtc->id, &card_res.crtc_id[copied++])) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1240,7 +1219,7 @@ int drm_mode_getresources(struct inode * head) { DRM_DEBUG("OUTPUT ID is %d\n", output->id); if (put_user(output->id, &card_res.output_id[copied++])) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1255,7 +1234,7 @@ int drm_mode_getresources(struct inode * list_for_each_entry(mode, &output->modes, head) { drm_crtc_convert_to_umode(&u_mode, mode); if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1264,7 +1243,7 @@ int drm_mode_getresources(struct inode * list_for_each_entry(mode, &dev->mode_config.usermode_list, head) { drm_crtc_convert_to_umode(&u_mode, mode); if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1277,9 +1256,11 @@ done: card_res.count_modes); if (copy_to_user(argp, &card_res, sizeof(card_res))) - return -EFAULT; + ret = -EFAULT; - return retcode; +out_unlock: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1309,14 +1290,18 @@ int drm_mode_getcrtc(struct inode *inode struct drm_crtc *crtc; struct drm_output *output; int ocount; - int retcode = 0; + int ret = 0; if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id); - if (!crtc || (crtc->id != crtc_resp.crtc_id)) - return -EINVAL; + if (!crtc || (crtc->id != crtc_resp.crtc_id)) { + ret = -EINVAL; + goto out; + } + crtc_resp.x = crtc->x; crtc_resp.y = crtc->y; crtc_resp.fb_id = 1; @@ -1335,9 +1320,11 @@ int drm_mode_getcrtc(struct inode *inode } if (copy_to_user(argp, &crtc_resp, sizeof(crtc_resp))) - return -EFAULT; + ret = -EFAULT; - return retcode; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1367,7 +1354,7 @@ int drm_mode_getoutput(struct inode *ino struct drm_output *output; struct drm_display_mode *mode; int mode_count = 0; - int retcode = 0; + int ret = 0; int copied = 0; int i; @@ -1375,9 +1362,13 @@ int drm_mode_getoutput(struct inode *ino return -EFAULT; DRM_DEBUG("output id %d:\n", out_resp.output); + + spin_lock(&dev->mode_config.config_lock); output= idr_find(&dev->mode_config.crtc_idr, out_resp.output); - if (!output || (output->id != out_resp.output)) - return -EINVAL; + if (!output || (output->id != out_resp.output)) { + ret = -EINVAL; + goto out_unlock; + } list_for_each_entry(mode, &output->modes, head) mode_count++; @@ -1402,14 +1393,14 @@ int drm_mode_getoutput(struct inode *ino copied = 0; list_for_each_entry(mode, &output->modes, head) { if (put_user(mode->mode_id, &out_resp.modes[copied++])) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { if (output->user_mode_ids[i] != 0) if (put_user(output->user_mode_ids[i], &out_resp.modes[copied++])) { - retcode = -EFAULT; + ret = -EFAULT; goto done; } } @@ -1419,9 +1410,11 @@ int drm_mode_getoutput(struct inode *ino done: if (copy_to_user(argp, &out_resp, sizeof(out_resp))) - return -EFAULT; + ret = -EFAULT; - return retcode; +out_unlock: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1452,26 +1445,28 @@ int drm_mode_setcrtc(struct inode *inode struct drm_output **output_set = NULL, *output; struct drm_display_mode *mode; struct drm_framebuffer *fb = NULL; - int retcode = 0; + int ret = 0; int i; if (copy_from_user(&crtc_req, argp, sizeof(crtc_req))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id); if (!crtc || (crtc->id != crtc_req.crtc_id)) { DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id); - return -EINVAL; + ret = -EINVAL; + goto out; } if (crtc_req.mode) { - /* if we have a mode we need a framebuffer */ if (crtc_req.fb_id) { fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id); if (!fb || (fb->id != crtc_req.fb_id)) { DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id); - return -EINVAL; + ret = -EINVAL; + goto out; } } mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode); @@ -1489,43 +1484,55 @@ int drm_mode_setcrtc(struct inode *inode } DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode); - return -EINVAL; + ret = -EINVAL; + goto out; } } else mode = NULL; if (crtc_req.count_outputs == 0 && mode) { DRM_DEBUG("Count outputs is 0 but mode set\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } if (crtc_req.count_outputs > 0 && !mode && !fb) { DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs); - return -EINVAL; + ret = -EINVAL; + goto out; } if (crtc_req.count_outputs > 0) { u32 out_id; - output_set = kmalloc(crtc_req.count_outputs * sizeof(struct drm_output *), GFP_KERNEL); - if (!output_set) - return -ENOMEM; + output_set = kmalloc(crtc_req.count_outputs * + sizeof(struct drm_output *), GFP_KERNEL); + if (!output_set) { + ret = -ENOMEM; + goto out; + } for (i = 0; i < crtc_req.count_outputs; i++) { - if (get_user(out_id, &crtc_req.set_outputs[i])) - return -EFAULT; + if (get_user(out_id, &crtc_req.set_outputs[i])) { + ret = -EFAULT; + goto out; + } output = idr_find(&dev->mode_config.crtc_idr, out_id); if (!output || (out_id != output->id)) { DRM_DEBUG("Output id %d unknown\n", out_id); - return -EINVAL; + ret = -EINVAL; + goto out; } output_set[i] = output; } } - retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb); - return retcode; + ret = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb); + +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1536,7 +1543,7 @@ int drm_mode_setcrtc(struct inode *inode * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Add a new FB to the specified CRTC, given a user request. * @@ -1555,7 +1562,8 @@ int drm_mode_addfb(struct inode *inode, struct drm_mode_config *config = &dev->mode_config; struct drm_framebuffer *fb; struct drm_buffer_object *bo; - int ret; + struct drm_crtc *crtc; + int ret = 0; if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; @@ -1569,17 +1577,22 @@ int drm_mode_addfb(struct inode *inode, return -EINVAL; } + spin_lock(&dev->mode_config.config_lock); /* TODO check limits are okay */ ret = drm_get_buffer_object(dev, &bo, r.handle); - if (ret || !bo) - return -EINVAL; + if (ret || !bo) { + ret = -EINVAL; + goto out; + } /* TODO check buffer is sufficently large */ /* TODO setup destructor callback */ fb = drm_framebuffer_create(dev); - if(!fb) - return -EINVAL;; + if (!fb) { + ret = -EINVAL; + goto out; + } fb->width = r.width; fb->height = r.height; @@ -1593,20 +1606,20 @@ int drm_mode_addfb(struct inode *inode, list_add(&fb->filp_head, &priv->fbs); - if (copy_to_user(argp, &r, sizeof(r))) - return -EFAULT; + if (copy_to_user(argp, &r, sizeof(r))) { + ret = -EFAULT; + goto out; + } - /* bind the fb to the crtc for now */ - { - struct drm_crtc *crtc; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - crtc->fb = fb; - - dev->driver->fb_probe(dev, crtc); - } + /* FIXME: bind the fb to the right crtc */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + crtc->fb = fb; + dev->driver->fb_probe(dev, crtc); } - return 0; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1617,7 +1630,7 @@ int drm_mode_addfb(struct inode *inode, * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Remove the FB specified by the user. * @@ -1633,12 +1646,15 @@ int drm_mode_rmfb(struct inode *inode, s drm_device_t *dev = priv->head->dev; struct drm_framebuffer *fb = 0; uint32_t id = arg; + int ret = 0; + spin_lock(&dev->mode_config.config_lock); fb = idr_find(&dev->mode_config.crtc_idr, id); /* TODO check that we realy get a framebuffer back. */ if (!fb || (id != fb->id)) { DRM_ERROR("mode invalid framebuffer id\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb)); @@ -1650,7 +1666,9 @@ int drm_mode_rmfb(struct inode *inode, s drm_framebuffer_destroy(fb); - return 0; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1678,14 +1696,17 @@ int drm_mode_getfb(struct inode *inode, struct drm_mode_fb_cmd __user *argp = (void __user *)arg; struct drm_mode_fb_cmd r; struct drm_framebuffer *fb; + int ret = 0; if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id); if (!fb || (r.buffer_id != fb->id)) { DRM_ERROR("invalid framebuffer id\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } r.height = fb->height; @@ -1696,9 +1717,11 @@ int drm_mode_getfb(struct inode *inode, r.pitch = fb->pitch; if (copy_to_user(argp, &r, sizeof(r))) - return -EFAULT; + ret = -EFAULT; - return 0; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1706,7 +1729,7 @@ int drm_mode_getfb(struct inode *inode, * @filp: file * from the ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Destroy all the FBs associated with @filp. * @@ -1721,11 +1744,13 @@ void drm_fb_release(struct file *filp) drm_device_t *dev = priv->head->dev; struct drm_framebuffer *fb, *tfb; + spin_lock(&dev->mode_config.config_lock); list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { list_del(&fb->filp_head); dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb)); drm_framebuffer_destroy(fb); } + spin_unlock(&dev->mode_config.config_lock); } /** @@ -1751,28 +1776,32 @@ int drm_mode_addmode(struct inode *inode struct drm_mode_modeinfo __user *argp = (void __user *)arg; struct drm_mode_modeinfo new_mode; struct drm_display_mode *user_mode; + int ret = 0; if (copy_from_user(&new_mode, argp, sizeof(new_mode))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); user_mode = drm_mode_create(dev); - if (!user_mode) - return -ENOMEM; + if (!user_mode) { + ret = -ENOMEM; + goto out; + } drm_crtc_convert_umode(user_mode, &new_mode); user_mode->type |= DRM_MODE_TYPE_USERDEF; user_mode->output_count = 0; - spin_lock(&dev->mode_config.config_lock); list_add(&user_mode->head, &dev->mode_config.usermode_list); - spin_unlock(&dev->mode_config.config_lock); new_mode.id = user_mode->mode_id; if (copy_to_user(argp, &new_mode, sizeof(new_mode))) - return -EFAULT; + ret = -EFAULT; - return 0; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } /** @@ -1796,29 +1825,37 @@ int drm_mode_rmmode(struct inode *inode, drm_device_t *dev = priv->head->dev; uint32_t id = arg; struct drm_display_mode *mode, *t; - int retcode = -EINVAL; + int ret = -EINVAL; + spin_lock(&dev->mode_config.config_lock); mode = idr_find(&dev->mode_config.crtc_idr, id); - if (!mode || (id != mode->mode_id)) - return -EINVAL; + if (!mode || (id != mode->mode_id)) { + ret = -EINVAL; + goto out; + } - if (!(mode->type & DRM_MODE_TYPE_USERDEF)) - return -EINVAL; + if (!(mode->type & DRM_MODE_TYPE_USERDEF)) { + ret = -EINVAL; + goto out; + } - if (mode->output_count) - return -EINVAL; + if (mode->output_count) { + ret = -EINVAL; + goto out; + } - spin_lock(&dev->mode_config.config_lock); list_for_each_entry(t, &dev->mode_config.usermode_list, head) { if (t == mode) { list_del(&mode->head); drm_mode_destroy(dev, mode); - retcode = 0; + ret = 0; break; } } + +out: spin_unlock(&dev->mode_config.config_lock); - return retcode; + return ret; } /** @@ -1843,18 +1880,24 @@ int drm_mode_attachmode(struct inode *in struct drm_mode_mode_cmd mode_cmd; struct drm_output *output; struct drm_display_mode *mode; - int i; + int i, ret = 0; if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); + mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id); - if (!mode || (mode->mode_id != mode_cmd.mode_id)) - return -EINVAL; + if (!mode || (mode->mode_id != mode_cmd.mode_id)) { + ret = -EINVAL; + goto out; + } output = idr_find(&dev->mode_config.crtc_idr, mode_cmd.output_id); - if (!output || (output->id != mode_cmd.output_id)) - return -EINVAL; + if (!output || (output->id != mode_cmd.output_id)) { + ret = -EINVAL; + goto out; + } for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { if (output->user_mode_ids[i] == 0) { @@ -1865,9 +1908,11 @@ int drm_mode_attachmode(struct inode *in } if (i == DRM_OUTPUT_MAX_UMODES) - return -ENOSPC; + ret = -ENOSPC; - return 0; +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } @@ -1892,18 +1937,24 @@ int drm_mode_detachmode(struct inode *in struct drm_mode_mode_cmd mode_cmd; struct drm_output *output; struct drm_display_mode *mode; - int i, found = 0; + int i, found = 0, ret = 0; if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd))) return -EFAULT; + spin_lock(&dev->mode_config.config_lock); + mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id); - if (!mode || (mode->mode_id != mode_cmd.mode_id)) - return -EINVAL; + if (!mode || (mode->mode_id != mode_cmd.mode_id)) { + ret = -EINVAL; + goto out; + } output = idr_find(&dev->mode_config.crtc_idr, mode_cmd.output_id); - if (!output || (output->id != mode_cmd.output_id)) - return -EINVAL; + if (!output || (output->id != mode_cmd.output_id)) { + ret = -EINVAL; + goto out; + } for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { @@ -1915,7 +1966,9 @@ int drm_mode_detachmode(struct inode *in } if (!found) - return -EINVAL; - - return 0; + ret = -EINVAL; + +out: + spin_unlock(&dev->mode_config.config_lock); + return ret; } diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index fa143e6..7ca8311 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -417,7 +417,6 @@ struct drm_output { unsigned long possible_clones; bool interlace_allowed; bool doublescan_allowed; - spinlock_t modes_lock; /* protects modes and probed_modes lists */ struct list_head modes; /* list of modes on this output */ /* diff --git a/linux-core/drm_fb.c b/linux-core/drm_fb.c index 5f2b1ce..7a105d5 100644 --- a/linux-core/drm_fb.c +++ b/linux-core/drm_fb.c @@ -299,9 +299,8 @@ int drmfb_probe(struct drm_device *dev, int ret; info = framebuffer_alloc(sizeof(struct drmfb_par), device); - if (!info){ - return -EINVAL; - } + if (!info) + return -ENOMEM; fb->fbdev = info; @@ -408,8 +407,10 @@ int drmfb_probe(struct drm_device *dev, break; } - if (register_framebuffer(info) < 0) + if (register_framebuffer(info) < 0) { + unregister_framebuffer(info); return -EINVAL; + } printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c index 97f7607..41b5fad 100644 --- a/linux-core/drm_modes.c +++ b/linux-core/drm_modes.c @@ -141,7 +141,7 @@ EXPORT_SYMBOL(drm_mode_height); * * Return @mode's vrefresh rate or calculate it if necessary. * - * FIXME: why is this needed? + * FIXME: why is this needed? shouldn't vrefresh be set already? * * RETURNS: * Vertical refresh rate of @mode x 1000. For precision reasons. diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 7126c16..2ce6646 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -203,6 +203,7 @@ static int intelfb_check_var(struct fb_v } /* this will let fbcon do the mode init */ +/* FIXME: take mode config lock? */ static int intelfb_set_par(struct fb_info *info) { struct intelfb_par *par = info->par; diff-tree f3beabedc36b7bc2d45ca9c7f64d2c54e291e32b (from b7bf317f42915dc4f5fde4a696e37985cea45104) Author: Jesse Barnes <jb...@ho...> Date: Thu May 17 13:48:46 2007 -0700 Remove unused edid.h header from X.Org. diff --git a/linux-core/edid.h b/linux-core/edid.h deleted file mode 100644 index bd89fb3..0000000 --- a/linux-core/edid.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * drivers/video/edid.h - EDID/DDC Header - * - * Based on: - * 1. XFree86 4.3.0, edid.h - * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> - * - * 2. John Fremlin <vi...@us...> and - * Ani Joshi <aj...@un...> - * - * DDC is a Trademark of VESA (Video Electronics Standard Association). - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. -*/ - -#ifndef __EDID_H__ -#define __EDID_H__ - -#define EDID_LENGTH 0x80 -#define EDID_HEADER 0x00 -#define EDID_HEADER_END 0x07 - -#define ID_MANUFACTURER_NAME 0x08 -#define ID_MANUFACTURER_NAME_END 0x09 -#define ID_MODEL 0x0a - -#define ID_SERIAL_NUMBER 0x0c - -#define MANUFACTURE_WEEK 0x10 -#define MANUFACTURE_YEAR 0x11 - -#define EDID_STRUCT_VERSION 0x12 -#define EDID_STRUCT_REVISION 0x13 - -#define EDID_STRUCT_DISPLAY 0x14 - -#define DPMS_FLAGS 0x18 -#define ESTABLISHED_TIMING_1 0x23 -#define ESTABLISHED_TIMING_2 0x24 -#define MANUFACTURERS_TIMINGS 0x25 - -/* standard timings supported */ -#define STD_TIMING 8 -#define STD_TIMING_DESCRIPTION_SIZE 2 -#define STD_TIMING_DESCRIPTIONS_START 0x26 - -#define DETAILED_TIMING_DESCRIPTIONS_START 0x36 -#define DETAILED_TIMING_DESCRIPTION_SIZE 18 -#define NO_DETAILED_TIMING_DESCRIPTIONS 4 - -#define DETAILED_TIMING_DESCRIPTION_1 0x36 -#define DETAILED_TIMING_DESCRIPTION_2 0x48 -#define DETAILED_TIMING_DESCRIPTION_3 0x5a -#define DETAILED_TIMING_DESCRIPTION_4 0x6c - -#define DESCRIPTOR_DATA 5 - -#define UPPER_NIBBLE( x ) \ - (((128|64|32|16) & (x)) >> 4) - -#define LOWER_NIBBLE( x ) \ - ((1|2|4|8) & (x)) - -#define COMBINE_HI_8LO( hi, lo ) \ - ( (((unsigned)hi) << 8) | (unsigned)lo ) - -#define COMBINE_HI_4LO( hi, lo ) \ - ( (((unsigned)hi) << 4) | (unsigned)lo ) - -#define PIXEL_CLOCK_LO (unsigned)block[ 0 ] -#define PIXEL_CLOCK_HI (unsigned)block[ 1 ] -#define PIXEL_CLOCK (COMBINE_HI_8LO( PIXEL_CLOCK_HI,PIXEL_CLOCK_LO )*10000) -#define H_ACTIVE_LO (unsigned)block[ 2 ] -#define H_BLANKING_LO (unsigned)block[ 3 ] -#define H_ACTIVE_HI UPPER_NIBBLE( (unsigned)block[ 4 ] ) -#define H_ACTIVE COMBINE_HI_8LO( H_ACTIVE_HI, H_ACTIVE_LO ) -#define H_BLANKING_HI LOWER_NIBBLE( (unsigned)block[ 4 ] ) -#define H_BLANKING COMBINE_HI_8LO( H_BLANKING_HI, H_BLANKING_LO ) - -#define V_ACTIVE_LO (unsigned)block[ 5 ] -#define V_BLANKING_LO (unsigned)block[ 6 ] -#define V_ACTIVE_HI UPPER_NIBBLE( (unsigned)block[ 7 ] ) -#define V_ACTIVE COMBINE_HI_8LO( V_ACTIVE_HI, V_ACTIVE_LO ) -#define V_BLANKING_HI LOWER_NIBBLE( (unsigned)block[ 7 ] ) -#define V_BLANKING COMBINE_HI_8LO( V_BLANKING_HI, V_BLANKING_LO ) - -#define H_SYNC_OFFSET_LO (unsigned)block[ 8 ] -#define H_SYNC_WIDTH_LO (unsigned)block[ 9 ] - -#define V_SYNC_OFFSET_LO UPPER_NIBBLE( (unsigned)block[ 10 ] ) -#define V_SYNC_WIDTH_LO LOWER_NIBBLE( (unsigned)block[ 10 ] ) - -#define V_SYNC_WIDTH_HI ((unsigned)block[ 11 ] & (1|2)) -#define V_SYNC_OFFSET_HI (((unsigned)block[ 11 ] & (4|8)) >> 2) - -#define H_SYNC_WIDTH_HI (((unsigned)block[ 11 ] & (16|32)) >> 4) -#define H_SYNC_OFFSET_HI (((unsigned)block[ 11 ] & (64|128)) >> 6) - -#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) -#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) - -#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) -#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) - -#define H_SIZE_LO (unsigned)block[ 12 ] -#define V_SIZE_LO (unsigned)block[ 13 ] - -#define H_SIZE_HI UPPER_NIBBLE( (unsigned)block[ 14 ] ) -#define V_SIZE_HI LOWER_NIBBLE( (unsigned)block[ 14 ] ) - -#define H_SIZE COMBINE_HI_8LO( H_SIZE_HI, H_SIZE_LO ) -#define V_SIZE COMBINE_HI_8LO( V_SIZE_HI, V_SIZE_LO ) - -#define H_BORDER (unsigned)block[ 15 ] -#define V_BORDER (unsigned)block[ 16 ] - -#define FLAGS (unsigned)block[ 17 ] - -#define INTERLACED (FLAGS&128) -#define SYNC_TYPE (FLAGS&3<<3) /* bits 4,3 */ -#define SYNC_SEPARATE (3<<3) -#define HSYNC_POSITIVE (FLAGS & 4) -#define VSYNC_POSITIVE (FLAGS & 2) - -#define V_MIN_RATE block[ 5 ] -#define V_MAX_RATE block[ 6 ] -#define H_MIN_RATE block[ 7 ] -#define H_MAX_RATE block[ 8 ] -#define MAX_PIXEL_CLOCK (((int)block[ 9 ]) * 10) -#define GTF_SUPPORT block[10] - -#define DPMS_ACTIVE_OFF (1 << 5) -#define DPMS_SUSPEND (1 << 6) -#define DPMS_STANDBY (1 << 7) - -#endif /* __EDID_H__ */ |
From: <jb...@ke...> - 2007-09-25 23:18:17
|
linux-core/drm_bo.c | 1 - linux-core/drm_drv.c | 2 +- shared-core/i915_init.c | 9 ++++----- 3 files changed, 5 insertions(+), 7 deletions(-) New commits: diff-tree 972ec4fa25059c84ed103c28efcb17f9f97a6d74 (from 053ff86566bcf050c7fd5b5dc7158bb35d39c38b) Author: Jesse Barnes <jes...@in...> Date: Tue Sep 25 16:18:01 2007 -0700 Hack out i915_mem_takedown We may want to make the old i915 memory manager obsolete eventually, and in the meantime the takedown causes problems on unload so remove it for now. diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 065afcd..918bbcb 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -291,12 +291,12 @@ int i915_driver_unload(struct drm_device DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage)); mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(&dev_priv->ring_buffer); - mutex_unlock(&dev->struct_mutex); if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { DRM_ERROR("Memory manager type 3 not clean. " "Delaying takedown\n"); } + mutex_unlock(&dev->struct_mutex); drm_bo_driver_finish(dev); @@ -315,15 +315,14 @@ void i915_driver_lastclose(struct drm_de struct drm_i915_private *dev_priv = dev->dev_private; i915_do_cleanup_pageflip(dev); - - i915_mem_takedown(&(dev_priv->agp_heap)); - + //i915_mem_takedown(&(dev_priv->agp_heap)); i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp) { struct drm_i915_private *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); + + //i915_mem_release(dev, filp, dev_priv->agp_heap); } diff-tree 053ff86566bcf050c7fd5b5dc7158bb35d39c38b (from 5433bbbfde10bed7fbafcd90c64c364546ca724f) Author: Jesse Barnes <jes...@in...> Date: Tue Sep 25 16:16:33 2007 -0700 Move map hash destruction to after driver unload hook is called The driver unload routine will want to remove register and SAREA maps, so don't destroy the map hash before we get there. diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 9004d53..5d2745e 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -391,7 +391,6 @@ static void drm_cleanup(struct drm_devic drm_lastclose(dev); drm_fence_manager_takedown(dev); - drm_ht_remove(&dev->map_hash); drm_mm_takedown(&dev->offset_manager); drm_ht_remove(&dev->object_hash); @@ -412,6 +411,7 @@ static void drm_cleanup(struct drm_devic if (dev->driver->unload) dev->driver->unload(dev); + drm_ht_remove(&dev->map_hash); if (drm_core_has_AGP(dev) && dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; diff-tree 5433bbbfde10bed7fbafcd90c64c364546ca724f (from cbcbe80c09bd95485ce8a9b0d86242fedcd7c182) Author: Jesse Barnes <jes...@in...> Date: Tue Sep 25 16:15:48 2007 -0700 Remove buffer object user list check in drm_bo_destroy_unlocked In the case of driver allocated buffers, there won't necessarily be a user list associated with the buffer, so don't bug out on an empty list. diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 89062f1..ea93ed1 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -417,7 +417,6 @@ static void drm_bo_destroy_locked(struct atomic_dec(&bm->count); - BUG_ON(!list_empty(&bo->base.list)); drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ); return; |
From: <th...@ke...> - 2007-10-26 08:36:43
|
libdrm/xf86drm.c | 4 ++-- libdrm/xf86mm.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) New commits: commit 343696583c77983ac7689b24cd49529864035cf7 Merge: 26c32a3... a4c87d3... Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Fri Oct 26 10:33:42 2007 +0200 Merge branch 'master' into modesetting-101 commit a4c87d3796cac374d25e01b26bdbb9028ce03107 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Fri Oct 26 10:31:14 2007 +0200 Minor libdrm fixes. diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 2f9d5c8..7001a0e 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2865,7 +2865,7 @@ int drmBOVersion(int fd, unsigned int *major, memset(&arg, 0, sizeof(arg)); ret = ioctl(fd, DRM_IOCTL_BO_VERSION, &arg); if (ret) - return ret; + return -errno; if (major) *major = arg.major; @@ -2874,7 +2874,7 @@ int drmBOVersion(int fd, unsigned int *major, if (patchlevel) *patchlevel = arg.patchlevel; - return (ret) ? -errno : 0; + return 0; } diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index 49ae2c0..d3df849 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -29,6 +29,7 @@ #ifndef _XF86MM_H_ #define _XF86MM_H_ #include <stddef.h> +#include <stdint.h> #include "drm.h" /* @@ -37,7 +38,7 @@ * be protected using an external mutex. * * Note: Don't protect the following functions, as it may lead to deadlocks: - * drmBOUnmap(), drmFenceBuffers(). + * drmBOUnmap(). * The kernel is synchronizing and refcounting buffer maps. * User space only needs to refcount object usage within the same application. */ @@ -156,9 +157,6 @@ extern int drmBOUnreference(int fd, drmBO *buf); extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, void **address); extern int drmBOUnmap(int fd, drmBO *buf); -extern int drmBOValidate(int fd, drmBO *buf, uint32_t fence_class, uint64_t flags, - uint64_t mask, unsigned hint); - extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle); extern int drmBOInfo(int fd, drmBO *buf); extern int drmBOBusy(int fd, drmBO *buf, int *busy); commit 1681189e11b5a00ae72a55de932146ea37f7afd9 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Fri Oct 26 10:25:57 2007 +0200 Buffer flags and masks are 64-bit. don't mask off the high dword. Signed-off-by: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 8d1e2f5..16203c7 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -54,9 +54,9 @@ static int drm_bo_setup_vm_locked(struct drm_buffer_object * bo); static void drm_bo_takedown_vm_locked(struct drm_buffer_object * bo); static void drm_bo_unmap_virtual(struct drm_buffer_object * bo); -static inline uint32_t drm_bo_type_flags(unsigned type) +static inline uint64_t drm_bo_type_flags(unsigned type) { - return (1 << (24 + type)); + return (1ULL << (24 + type)); } /* @@ -785,10 +785,10 @@ static int drm_bo_mem_force_space(struct drm_device * dev, static int drm_bo_mt_compatible(struct drm_mem_type_manager * man, uint32_t mem_type, - uint32_t mask, uint32_t * res_mask) + uint64_t mask, uint32_t * res_mask) { - uint32_t cur_flags = drm_bo_type_flags(mem_type); - uint32_t flag_diff; + uint64_t cur_flags = drm_bo_type_flags(mem_type); + uint64_t flag_diff; if (man->flags & _DRM_FLAG_MEMTYPE_CACHED) cur_flags |= DRM_BO_FLAG_CACHED; @@ -1271,7 +1271,7 @@ static void drm_buffer_user_object_unmap(struct drm_file *file_priv, * Note that new_mem_flags are NOT transferred to the bo->mem.mask. */ -int drm_bo_move_buffer(struct drm_buffer_object * bo, uint32_t new_mem_flags, +int drm_bo_move_buffer(struct drm_buffer_object * bo, uint64_t new_mem_flags, int no_wait, int move_unfenced) { struct drm_device *dev = bo->dev; diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c index 2a35d45..7c86c4a 100644 --- a/linux-core/drm_bo_move.c +++ b/linux-core/drm_bo_move.c @@ -53,8 +53,8 @@ int drm_bo_move_ttm(struct drm_buffer_object * bo, { struct drm_ttm *ttm = bo->ttm; struct drm_bo_mem_reg *old_mem = &bo->mem; - uint32_t save_flags = old_mem->flags; - uint32_t save_mask = old_mem->mask; + uint64_t save_flags = old_mem->flags; + uint64_t save_mask = old_mem->mask; int ret; if (old_mem->mem_type == DRM_BO_MEM_TT) { @@ -210,8 +210,8 @@ int drm_bo_move_memcpy(struct drm_buffer_object * bo, void *old_iomap; void *new_iomap; int ret; - uint32_t save_flags = old_mem->flags; - uint32_t save_mask = old_mem->mask; + uint64_t save_flags = old_mem->flags; + uint64_t save_mask = old_mem->mask; unsigned long i; unsigned long page; unsigned long add = 0; @@ -333,8 +333,8 @@ int drm_bo_move_accel_cleanup(struct drm_buffer_object * bo, struct drm_mem_type_manager *man = &dev->bm.man[new_mem->mem_type]; struct drm_bo_mem_reg *old_mem = &bo->mem; int ret; - uint32_t save_flags = old_mem->flags; - uint32_t save_mask = old_mem->mask; + uint64_t save_flags = old_mem->flags; + uint64_t save_mask = old_mem->mask; struct drm_buffer_object *old_obj; if (bo->fence) diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 702ece5..8b14ac6 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -511,7 +511,8 @@ extern int drm_bo_wait(struct drm_buffer_object * bo, int lazy, int ignore_signa int no_wait); extern int drm_bo_mem_space(struct drm_buffer_object * bo, struct drm_bo_mem_reg * mem, int no_wait); -extern int drm_bo_move_buffer(struct drm_buffer_object * bo, uint32_t new_mem_flags, +extern int drm_bo_move_buffer(struct drm_buffer_object * bo, + uint64_t new_mem_flags, int no_wait, int move_unfenced); extern int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type); extern int drm_bo_init_mm(struct drm_device * dev, unsigned type, |
From: <th...@ke...> - 2007-11-07 17:30:29
|
linux-core/drm_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit e9805de5c736f899dea5220ab8b521cc69c9eca6 Merge: c07dd80... c20370e... Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Wed Nov 7 18:10:46 2007 +0100 Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101 Conflicts: shared-core/i915_dma.c commit c20370e0969e41bbf735daf932e37ac5ec959213 Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Wed Nov 7 18:07:10 2007 +0100 Don't overwrite TTM page flags. diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index 8a44070..1a61ef6 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -264,7 +264,7 @@ int drm_ttm_set_user(struct drm_ttm *ttm, ttm->user_mm = mm; ttm->dummy_read_page = dummy_read_page; - ttm->page_flags = DRM_TTM_PAGE_USER | + ttm->page_flags |= DRM_TTM_PAGE_USER | ((write) ? DRM_TTM_PAGE_USER_WRITE : 0); commit 47497abc1e38081564db429329a3ba16198c1521 Author: Dave Airlie <ai...@cl...> Date: Wed Nov 7 23:10:24 2007 +1000 i915: oops disable TTM is backwards diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 541b4cc..5bc3c49 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1402,7 +1402,7 @@ int i915_driver_device_is_agp(struct drm_device * dev) int i915_driver_firstopen(struct drm_device *dev) { #ifdef I915_HAVE_BUFFER - if (!IS_I9XX(dev)) + if (IS_I9XX(dev)) drm_bo_driver_init(dev); #endif return 0; |
From: <ai...@ke...> - 2007-11-26 04:07:08
|
linux-core/drm_crtc.c | 162 +++++++++++++++++++++++++++++++++----------------- linux-core/drm_crtc.h | 25 +++++-- linux-core/drm_drv.c | 8 +- linux-core/intel_fb.c | 70 +++++++++------------ 4 files changed, 163 insertions(+), 102 deletions(-) New commits: commit f9ac54b0319b273de83a004d6cfdf46a3b9d6ced Author: Dave Airlie <ai...@re...> Date: Mon Nov 26 15:06:42 2007 +1100 fb: make fb interface use user mode attach/detach for adding modes diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index d5f3a0e..bc29270 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1722,6 +1722,70 @@ int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode) } EXPORT_SYMBOL(drm_mode_rmmode); +static int drm_mode_attachmode(struct drm_device *dev, + struct drm_output *output, + struct drm_display_mode *mode) +{ + int ret = 0; + int i; + + for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { + if (output->user_mode_ids[i] == 0) { + output->user_mode_ids[i] = mode->mode_id; + mode->output_count++; + break; + } + } + + if (i == DRM_OUTPUT_MAX_UMODES) + ret = -ENOSPC; + + return ret; +} + +int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + struct drm_output *output; + + list_for_each_entry(output, &dev->mode_config.output_list, head) { + if (output->crtc == crtc) + drm_mode_attachmode(dev, output, mode); + } +} +EXPORT_SYMBOL(drm_mode_attachmode_crtc); + +static int drm_mode_detachmode(struct drm_device *dev, + struct drm_output *output, + struct drm_display_mode *mode) +{ + int found = 0; + int ret = 0, i; + + for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { + if (output->user_mode_ids[i] == mode->mode_id) { + output->user_mode_ids[i] = 0; + mode->output_count--; + found = 1; + } + } + + if (!found) + ret = -EINVAL; + + return ret; +} + +int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) +{ + struct drm_output *output; + + list_for_each_entry(output, &dev->mode_config.output_list, head) { + drm_mode_detachmode(dev, output, mode); + } +} +EXPORT_SYMBOL(drm_mode_detachmode_crtc); + /** * drm_fb_addmode - adds a user defined mode * @inode: inode from the ioctl @@ -1822,7 +1886,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev, struct drm_mode_mode_cmd *mode_cmd = data; struct drm_output *output; struct drm_display_mode *mode; - int i, ret = 0; + int ret = 0; mutex_lock(&dev->mode_config.mutex); @@ -1838,17 +1902,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev, goto out; } - for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { - if (output->user_mode_ids[i] == 0) { - output->user_mode_ids[i] = mode->mode_id; - mode->output_count++; - break; - } - } - - if (i == DRM_OUTPUT_MAX_UMODES) - ret = -ENOSPC; - + ret = drm_mode_attachmode(dev, output, mode); out: mutex_unlock(&dev->mode_config.mutex); return ret; @@ -1873,7 +1927,7 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev, struct drm_mode_mode_cmd *mode_cmd = data; struct drm_output *output; struct drm_display_mode *mode; - int i, found = 0, ret = 0; + int ret = 0; mutex_lock(&dev->mode_config.mutex); @@ -1890,17 +1944,7 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev, } - for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) { - if (output->user_mode_ids[i] == mode->mode_id) { - output->user_mode_ids[i] = 0; - mode->output_count--; - found = 1; - } - } - - if (!found) - ret = -EINVAL; - + ret = drm_mode_detachmode(dev, output, mode); out: mutex_unlock(&dev->mode_config.mutex); return ret; diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index a9f6a13..fc97525 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -497,6 +497,12 @@ extern void drm_disable_unused_functions(struct drm_device *dev); extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode); extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode); +/* for us by fb module */ +extern int drm_mode_attachmode_crtc(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_display_mode *mode); +extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode); + extern struct drm_display_mode *drm_mode_create(struct drm_device *dev); extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); extern void drm_mode_list_concat(struct list_head *head, diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 3a4ffc7..5f43f29 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -223,7 +223,7 @@ static int intelfb_set_par(struct fb_info *info) struct intelfb_par *par = info->par; struct drm_framebuffer *fb = par->crtc->fb; struct drm_device *dev = par->dev; - struct drm_display_mode *drm_mode; + struct drm_display_mode *drm_mode, *search_mode; struct drm_output *output; struct fb_var_screeninfo *var = &info->var; int found = 0; @@ -248,34 +248,7 @@ static int intelfb_set_par(struct fb_info *info) info->screen_size = info->fix.smem_len; /* ??? */ - /* Should we walk the output's modelist or just create our own ??? - * For now, we create and destroy a mode based on the incoming - * parameters. But there's commented out code below which scans - * the output list too. - */ -#if 0 - list_for_each_entry(output, &dev->mode_config.output_list, head) { - if (output->crtc == par->crtc) - break; - } - - list_for_each_entry(drm_mode, &output->modes, head) { - if (drm_mode->hdisplay == var->xres && - drm_mode->vdisplay == var->yres && - (((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) && - (((PICOS2KHZ(var->pixclock))/1000) <= ((drm_mode->clock/1000)+1))) { - found = 1; - break; - } - } - - if (!found) { - DRM_ERROR("Couldn't find a mode for requested %dx%d-%d\n", - var->xres,var->yres,var_to_refresh(var)); - return -EINVAL; - } -#else - + /* create a drm mode */ drm_mode = drm_mode_create(dev); drm_mode->hdisplay = var->xres; drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin; @@ -289,14 +262,36 @@ static int intelfb_set_par(struct fb_info *info) drm_mode->vrefresh = drm_mode_vrefresh(drm_mode); drm_mode_set_name(drm_mode); drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V); -#endif - drm_mode_addmode(dev, drm_mode); - if (par->fb_mode) - drm_mode_rmmode(dev, par->fb_mode); + list_for_each_entry(output, &dev->mode_config.output_list, head) { + if (output->crtc == par->crtc) + break; + } + + drm_mode_debug_printmodeline(dev, drm_mode); + list_for_each_entry(search_mode, &output->modes, head) { + DRM_ERROR("mode %s : %s\n", drm_mode->name, search_mode->name); + drm_mode_debug_printmodeline(dev, search_mode); + if (drm_mode_equal(drm_mode, search_mode)) { + drm_mode_destroy(dev, drm_mode); + drm_mode = search_mode; + found = 1; + break; + } + } - par->fb_mode = drm_mode; - drm_mode_debug_printmodeline(dev, drm_mode); + if (!found) { + drm_mode_addmode(dev, drm_mode); + if (par->fb_mode) { + drm_mode_detachmode_crtc(dev, par->fb_mode); + drm_mode_rmmode(dev, par->fb_mode); + } + + par->fb_mode = drm_mode; + drm_mode_debug_printmodeline(dev, drm_mode); + /* attach mode */ + drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode); + } if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) return -EINVAL; commit 362f4283205a01b2a60a49838721e9fff9ae1a4c Author: Dave Airlie <ai...@re...> Date: Mon Nov 26 14:28:48 2007 +1100 add _ioctl to the end of two more ioctls diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 8730255..d5f3a0e 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1816,8 +1816,8 @@ out: * RETURNS: * Zero on success, errno on failure. */ -int drm_mode_attachmode(struct drm_device *dev, - void *data, struct drm_file *file_priv) +int drm_mode_attachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) { struct drm_mode_mode_cmd *mode_cmd = data; struct drm_output *output; @@ -1867,8 +1867,8 @@ out: * RETURNS: * Zero on success, errno on failure. */ -int drm_mode_detachmode(struct drm_device *dev, - void *data, struct drm_file *file_priv) +int drm_mode_detachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) { struct drm_mode_mode_cmd *mode_cmd = data; struct drm_output *output; diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index f555b6b..a9f6a13 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -543,10 +543,10 @@ extern int drm_mode_addmode_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_rmmode_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int drm_mode_attachmode(struct drm_device *dev, - void *data, struct drm_file *file_priv); -extern int drm_mode_detachmode(struct drm_device *dev, - void *data, struct drm_file *file_priv); +extern int drm_mode_attachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_detachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 5156d15..e606bc6 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -126,8 +126,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), commit 53b4e0cb789151164a0a43b55058319667847aaf Author: Dave Airlie <ai...@re...> Date: Mon Nov 26 14:05:49 2007 +1100 drm: make fb modes use usermode add/remove interface this stops usermode from getting a mode in the crtc it can't make sense off. diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index df93484..8730255 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -439,7 +439,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, if (output->crtc != crtc) continue; - DRM_INFO("%s: set mode %s\n", output->name, mode->name); + DRM_INFO("%s: set mode %s %x\n", output->name, mode->name, mode->mode_id); output->funcs->mode_set(output, mode, adjusted_mode); } @@ -858,7 +858,7 @@ clone: output->crtc->desired_mode = des_mode; output->initial_x = 0; output->initial_y = 0; - DRM_DEBUG("Desired mode for CRTC %d is %s\n",c,des_mode->name); + DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name); break; } } @@ -1694,8 +1694,36 @@ void drm_fb_release(struct file *filp) mutex_unlock(&dev->mode_config.mutex); } +/* + * + */ +void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode) +{ + user_mode->type |= DRM_MODE_TYPE_USERDEF; + + user_mode->output_count = 0; + list_add(&user_mode->head, &dev->mode_config.usermode_list); +} +EXPORT_SYMBOL(drm_mode_addmode); + +int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode) +{ + struct drm_display_mode *t; + int ret = -EINVAL; + list_for_each_entry(t, &dev->mode_config.usermode_list, head) { + if (t == mode) { + list_del(&mode->head); + drm_mode_destroy(dev, mode); + ret = 0; + break; + } + } + return ret; +} +EXPORT_SYMBOL(drm_mode_rmmode); + /** - * drm_fb_newmode - adds a user defined mode + * drm_fb_addmode - adds a user defined mode * @inode: inode from the ioctl * @filp: file * from the ioctl * @cmd: cmd from ioctl @@ -1709,8 +1737,8 @@ void drm_fb_release(struct file *filp) * writes new mode id into arg. * Zero on success, errno on failure. */ -int drm_mode_addmode(struct drm_device *dev, - void *data, struct drm_file *file_priv) +int drm_mode_addmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) { struct drm_mode_modeinfo *new_mode = data; struct drm_display_mode *user_mode; @@ -1724,12 +1752,8 @@ int drm_mode_addmode(struct drm_device *dev, } drm_crtc_convert_umode(user_mode, new_mode); - user_mode->type |= DRM_MODE_TYPE_USERDEF; - - user_mode->output_count = 0; - - list_add(&user_mode->head, &dev->mode_config.usermode_list); + drm_mode_addmode(dev, user_mode); new_mode->id = user_mode->mode_id; out: @@ -1751,38 +1775,28 @@ out: * RETURNS: * Zero on success, errno on failure. */ -int drm_mode_rmmode(struct drm_device *dev, - void *data, struct drm_file *file_priv) +int drm_mode_rmmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) { uint32_t *id = data; - struct drm_display_mode *mode, *t; + struct drm_display_mode *mode; int ret = -EINVAL; mutex_lock(&dev->mode_config.mutex); mode = idr_find(&dev->mode_config.crtc_idr, *id); if (!mode || (*id != mode->mode_id)) { - ret = -EINVAL; goto out; } if (!(mode->type & DRM_MODE_TYPE_USERDEF)) { - ret = -EINVAL; goto out; } if (mode->output_count) { - ret = -EINVAL; goto out; } - list_for_each_entry(t, &dev->mode_config.usermode_list, head) { - if (t == mode) { - list_del(&mode->head); - drm_mode_destroy(dev, mode); - ret = 0; - break; - } - } + ret = drm_mode_rmmode(dev, mode); out: mutex_unlock(&dev->mode_config.mutex); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 0645dd6..f555b6b 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -494,6 +494,9 @@ extern void drm_mode_set_name(struct drm_display_mode *mode); extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2); extern void drm_disable_unused_functions(struct drm_device *dev); +extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode); +extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode); + extern struct drm_display_mode *drm_mode_create(struct drm_device *dev); extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); extern void drm_mode_list_concat(struct list_head *head, @@ -536,10 +539,10 @@ extern int drm_mode_rmfb(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_getfb(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int drm_mode_addmode(struct drm_device *dev, - void *data, struct drm_file *file_priv); -extern int drm_mode_rmmode(struct drm_device *dev, - void *data, struct drm_file *file_priv); +extern int drm_mode_addmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_rmmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); extern int drm_mode_attachmode(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_detachmode(struct drm_device *dev, diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 8cd7afb..5156d15 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -124,8 +124,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY), diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 564a913..3a4ffc7 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -47,6 +47,7 @@ struct intelfb_par { struct drm_device *dev; struct drm_crtc *crtc; + struct drm_display_mode *fb_mode; }; static int @@ -107,7 +108,6 @@ static int intelfb_check_var(struct fb_var_screeninfo *var, struct intelfb_par *par = info->par; struct drm_device *dev = par->dev; struct drm_framebuffer *fb = par->crtc->fb; - struct drm_display_mode *drm_mode; struct drm_output *output; int depth, found = 0; @@ -275,6 +275,7 @@ static int intelfb_set_par(struct fb_info *info) return -EINVAL; } #else + drm_mode = drm_mode_create(dev); drm_mode->hdisplay = var->xres; drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin; @@ -290,18 +291,16 @@ static int intelfb_set_par(struct fb_info *info) drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V); #endif + drm_mode_addmode(dev, drm_mode); + if (par->fb_mode) + drm_mode_rmmode(dev, par->fb_mode); + + par->fb_mode = drm_mode; drm_mode_debug_printmodeline(dev, drm_mode); if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) return -EINVAL; - /* Have to destroy our created mode if we're not searching the mode - * list for it. - */ -#if 1 - drm_mode_destroy(dev, drm_mode); -#endif - return 0; } |
From: <ai...@ke...> - 2008-01-04 06:50:16
|
linux-core/drmP.h | 33 +++++++++------- linux-core/drm_agpsupport.c | 2 linux-core/drm_bo.c | 14 +++--- linux-core/drm_bo_lock.c | 4 - linux-core/drm_crtc.c | 8 +-- linux-core/drm_drv.c | 33 ++++++++-------- linux-core/drm_fence.c | 4 - linux-core/drm_fops.c | 23 +++++------ linux-core/drm_object.c | 16 +++---- linux-core/drm_proc.c | 4 - linux-core/drm_stub.c | 83 +++++++++++++++++++++++------------------ linux-core/drm_sysfs.c | 53 +++++++++++++++----------- linux-core/drm_vm.c | 20 ++++----- linux-core/i810_dma.c | 4 - linux-core/intel_display.c | 12 ++--- shared-core/Makefile.am | 1 shared-core/i915_dma.c | 6 +- shared-core/radeon_ms.h | 15 ++++++- shared-core/radeon_ms_dac.c | 4 - shared-core/radeon_ms_drm.h | 8 --- shared-core/radeon_ms_family.c | 10 ++-- shared-core/radeon_ms_i2c.c | 15 +------ shared-core/radeon_ms_output.c | 4 - 23 files changed, 200 insertions(+), 176 deletions(-) New commits: commit d3da253adbf471c9af9c68b2ff67cbf516856352 Author: Dave Airlie <ai...@re...> Date: Fri Jan 4 17:49:40 2008 +1100 drm: add initial support for a drm control device node diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 962ad4e..5bc4887 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -699,6 +699,7 @@ struct drm_minor { int minor; /**< Minor device number */ int type; /**< Control or render */ dev_t device; /**< Device number for mknod */ + struct device kdev; /**< Linux device */ struct drm_device *dev; /* for render nodes */ struct proc_dir_entry *dev_root; /**< proc directory entry */ @@ -711,7 +712,6 @@ struct drm_minor { * may contain multiple heads. */ struct drm_device { - struct device dev; /**< Linux device */ char *unique; /**< Unique identifier: e.g., busid */ int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ @@ -1158,7 +1158,7 @@ extern void drm_agp_chipset_flush(struct drm_device *dev); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); -extern int drm_put_head(struct drm_minor *minor); +extern int drm_put_minor(struct drm_minor *minor); extern unsigned int drm_debug; /* 1 to enable debug output */ extern unsigned int drm_minors_limit; extern struct drm_minor **drm_minors; @@ -1198,8 +1198,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah); struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(void); -extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_minor *minor); -extern void drm_sysfs_device_remove(struct drm_device *dev); +extern int drm_sysfs_device_add(struct drm_minor *minor); +extern void drm_sysfs_device_remove(struct drm_minor *minor); /* * Basic memory manager support (drm_mm.c) diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 29fa18d..58beec6 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -423,7 +423,8 @@ static void drm_cleanup(struct drm_device * dev) drm_mm_takedown(&dev->offset_manager); drm_ht_remove(&dev->object_hash); - drm_put_head(&dev->primary); + drm_put_minor(&dev->primary); + drm_put_minor(&dev->control); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); } diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 433869e..cee00c5 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -160,7 +160,7 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) +static int drm_get_minor(struct drm_device *dev, struct drm_minor *minor, int type) { struct drm_minor **minors = drm_minors; int ret; @@ -172,19 +172,23 @@ static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) if (!*minors) { *minor = (struct drm_minor) { + .type = type, .dev = dev, .device = MKDEV(DRM_MAJOR, index), .minor = index, }; - if ((ret = - drm_proc_init(dev, index, drm_proc_root, - &minor->dev_root))) { - printk(KERN_ERR - "DRM: Failed to initialize /proc/dri.\n"); - goto err_g1; - } - ret = drm_sysfs_device_add(dev, minor); + if (type == DRM_MINOR_RENDER) { + ret = drm_proc_init(dev, index, drm_proc_root, + &minor->dev_root); + if (ret) { + DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); + goto err_g1; + } + } else + minor->dev_root = NULL; + + ret = drm_sysfs_device_add(minor); if (ret) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); @@ -199,7 +203,8 @@ static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) DRM_ERROR("out of minors\n"); return -ENOMEM; err_g2: - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + if (minor->type == DRM_MINOR_RENDER) + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); err_g1: *minor = (struct drm_minor) { .dev = NULL}; @@ -245,22 +250,28 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, printk(KERN_ERR "DRM: fill_in_dev failed\n"); goto err_g3; } - if ((ret = drm_get_head(dev, &dev->primary))) + + if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) goto err_g3; + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_RENDER))) + goto err_g4; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary.minor); return 0; - err_g3: +err_g4: + drm_put_minor(&dev->control); +err_g3: if (!drm_fb_loaded) pci_disable_device(pdev); - err_g2: +err_g2: if (!drm_fb_loaded) pci_release_regions(pdev); - err_g1: +err_g1: if (!drm_fb_loaded) pci_set_drvdata(pdev, NULL); @@ -315,8 +326,9 @@ int drm_put_minor(struct drm_minor *minor) DRM_DEBUG("release secondary minor %d\n", index); - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); - drm_sysfs_device_remove(minor->dev); + if (minor->type == DRM_MINOR_RENDER) + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + drm_sysfs_device_remove(minor); *minor = (struct drm_minor) {.type = DRM_MINOR_UNASSIGNED, .dev = NULL}; diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index 1f2d763..a56e995 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -19,7 +19,7 @@ #include "drm_core.h" #include "drmP.h" -#define to_drm_device(d) container_of(d, struct drm_device, dev) +#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) /** * drm_sysfs_suspend - DRM class suspend hook @@ -31,7 +31,8 @@ */ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) { - struct drm_device *drm_dev = to_drm_device(dev); + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; printk(KERN_ERR "%s\n", __FUNCTION__); @@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) */ static int drm_sysfs_resume(struct device *dev) { - struct drm_device *drm_dev = to_drm_device(dev); + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; if (drm_dev->driver->resume) return drm_dev->driver->resume(drm_dev); @@ -122,10 +124,11 @@ void drm_sysfs_destroy(void) static ssize_t show_dri(struct device *device, struct device_attribute *attr, char *buf) { - struct drm_device *dev = to_drm_device(device); - if (dev->driver->dri_library_name) - return dev->driver->dri_library_name(dev, buf); - return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); + struct drm_minor *drm_minor = to_drm_minor(device); + struct drm_device *drm_dev = drm_minor->dev; + if (drm_dev->driver->dri_library_name) + return drm_dev->driver->dri_library_name(drm_dev, buf); + return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); } static struct device_attribute device_attrs[] = { @@ -154,25 +157,31 @@ static void drm_sysfs_device_release(struct device *dev) * as the parent for the Linux device, and make sure it has a file containing * the driver we're using (for userspace compatibility). */ -int drm_sysfs_device_add(struct drm_device *dev, struct drm_minor *minor) +int drm_sysfs_device_add(struct drm_minor *minor) { int err; int i, j; - - dev->dev.parent = &dev->pdev->dev; - dev->dev.class = drm_class; - dev->dev.release = drm_sysfs_device_release; - dev->dev.devt = minor->device; - snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", minor->minor); - - err = device_register(&dev->dev); + char *minor_str; + + minor->kdev.parent = &minor->dev->pdev->dev; + minor->kdev.class = drm_class; + minor->kdev.release = drm_sysfs_device_release; + minor->kdev.devt = minor->device; + if (minor->type == DRM_MINOR_CONTROL) + minor_str = "controlD%d"; + else + minor_str = "card%d"; + + snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->minor); + + err = device_register(&minor->kdev); if (err) { DRM_ERROR("device add failed: %d\n", err); goto err_out; } for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(&dev->dev, &device_attrs[i]); + err = device_create_file(&minor->kdev, &device_attrs[i]); if (err) goto err_out_files; } @@ -182,8 +191,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_minor *minor) err_out_files: if (i > 0) for (j = 0; j < i; j++) - device_remove_file(&dev->dev, &device_attrs[i]); - device_unregister(&dev->dev); + device_remove_file(&minor->kdev, &device_attrs[i]); + device_unregister(&minor->kdev); err_out: return err; @@ -196,11 +205,11 @@ err_out: * This call unregisters and cleans up a class device that was created with a * call to drm_sysfs_device_add() */ -void drm_sysfs_device_remove(struct drm_device *dev) +void drm_sysfs_device_remove(struct drm_minor *minor) { int i; for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(&dev->dev, &device_attrs[i]); - device_unregister(&dev->dev); + device_remove_file(&minor->kdev, &device_attrs[i]); + device_unregister(&minor->kdev); } commit df9cfeff37d40722df4e8a785478ac41246ca51f Author: Dave Airlie <ai...@re...> Date: Fri Jan 4 17:48:42 2008 +1100 crtc: fixup allocation size diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index dc8b146..b49fa69 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1952,7 +1952,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, { struct drm_property *property = NULL; - property = kzalloc(sizeof(struct drm_output), GFP_KERNEL); + property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); if (!property) return NULL; commit 10937cf20b6814e4cf68114fab4619fad94eafcb Author: Dave Airlie <ai...@re...> Date: Fri Jan 4 16:12:24 2008 +1100 drm: move drm_head to drm_minor and fix up users diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 5e674b2..962ad4e 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -412,13 +412,12 @@ enum drm_ref_type { struct drm_file { int authenticated; int master; - int minor; pid_t pid; uid_t uid; drm_magic_t magic; unsigned long ioctl_count; struct list_head lhead; - struct drm_head *head; + struct drm_minor *minor; int remove_auth_on_close; unsigned long lock_count; @@ -690,16 +689,19 @@ struct drm_driver { struct pci_driver pci_driver; }; +#define DRM_MINOR_UNASSIGNED 0 +#define DRM_MINOR_CONTROL 1 +#define DRM_MINOR_RENDER 2 /** - * DRM head structure. This structure represent a video head on a card - * that may contain multiple heads. Embed one per head of these in the - * private drm_device structure. + * DRM minor structure. This structure represents a drm minor number. */ -struct drm_head { +struct drm_minor { int minor; /**< Minor device number */ + int type; /**< Control or render */ + dev_t device; /**< Device number for mknod */ struct drm_device *dev; + /* for render nodes */ struct proc_dir_entry *dev_root; /**< proc directory entry */ - dev_t device; /**< Device number for mknod */ struct class_device *dev_class; }; @@ -830,7 +832,10 @@ struct drm_device { struct drm_driver *driver; drm_local_map_t *agp_buffer_map; unsigned int agp_buffer_token; - struct drm_head primary; /**< primary screen head */ + + /* minor number for control node */ + struct drm_minor control; + struct drm_minor primary; /**< primary screen head */ struct drm_fence_manager fm; struct drm_buffer_manager bm; @@ -1153,10 +1158,10 @@ extern void drm_agp_chipset_flush(struct drm_device *dev); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); -extern int drm_put_head(struct drm_head * head); +extern int drm_put_head(struct drm_minor *minor); extern unsigned int drm_debug; /* 1 to enable debug output */ -extern unsigned int drm_cards_limit; -extern struct drm_head **drm_heads; +extern unsigned int drm_minors_limit; +extern struct drm_minor **drm_minors; extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; @@ -1193,7 +1198,7 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah); struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(void); -extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); +extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_minor *minor); extern void drm_sysfs_device_remove(struct drm_device *dev); /* diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index e8bfaea..0b321af 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -130,7 +130,7 @@ EXPORT_SYMBOL(drm_agp_acquire); int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - return drm_agp_acquire((struct drm_device *) file_priv->head->dev); + return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); } /** diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index e4ec24e..55f5d08 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1164,7 +1164,7 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep) { struct drm_buffer_object *bo; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int ret = 0; int no_wait = hint & DRM_BO_HINT_DONT_BLOCK; @@ -1236,7 +1236,7 @@ out: static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; struct drm_ref_object *ro; int ret = 0; @@ -1543,7 +1543,7 @@ int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep, struct drm_buffer_object **bo_rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; int ret; int no_wait = hint & DRM_BO_HINT_DONT_BLOCK; @@ -1581,7 +1581,7 @@ EXPORT_SYMBOL(drm_bo_handle_validate); static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; mutex_lock(&dev->struct_mutex); @@ -1604,7 +1604,7 @@ static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle, uint32_t hint, struct drm_bo_info_rep *rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; int no_wait = hint & DRM_BO_HINT_DONT_BLOCK; int ret; @@ -1717,7 +1717,7 @@ EXPORT_SYMBOL(drm_buffer_object_create); static int drm_bo_add_user_object(struct drm_file *file_priv, struct drm_buffer_object *bo, int shareable) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -1757,7 +1757,7 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil if (bo_type == drm_bo_type_user) req->mask &= ~DRM_BO_FLAG_SHAREABLE; - ret = drm_buffer_object_create(file_priv->head->dev, + ret = drm_buffer_object_create(file_priv->minor->dev, req->size, bo_type, req->mask, req->hint, req->page_alignment, req->buffer_start, &entry); diff --git a/linux-core/drm_bo_lock.c b/linux-core/drm_bo_lock.c index f967fb7..2795384 100644 --- a/linux-core/drm_bo_lock.c +++ b/linux-core/drm_bo_lock.c @@ -141,7 +141,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv) * while holding it. */ - dev = file_priv->head->dev; + dev = file_priv->minor->dev; mutex_lock(&dev->struct_mutex); ret = drm_add_user_object(file_priv, &lock->base, 0); lock->base.remove = &drm_bo_write_lock_remove; @@ -156,7 +156,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv) int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_ref_object *ro; mutex_lock(&dev->struct_mutex); diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index bb89cb1..dc8b146 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -356,7 +356,7 @@ void drm_crtc_probe_single_output_modes(struct drm_output *output, int maxX, int } - drm_mode_prune_invalid(dev, &output->modes, true); + drm_mode_prune_invalid(dev, &output->modes, TRUE); if (list_empty(&output->modes)) { struct drm_display_mode *stdmode; @@ -510,7 +510,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, /* XXX free adjustedmode */ drm_mode_destroy(dev, adjusted_mode); - ret = true; + ret = TRUE; /* TODO */ // if (scrn->pScreen) // drm_crtc_set_screen_sub_pixel_order(dev); @@ -1781,7 +1781,7 @@ out: void drm_fb_release(struct file *filp) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_framebuffer *fb, *tfb; mutex_lock(&dev->mode_config.mutex); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index ab02c65..29fa18d 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -432,19 +432,19 @@ void drm_exit(struct drm_driver *driver) { int i; struct drm_device *dev = NULL; - struct drm_head *head; + struct drm_minor *minor; DRM_DEBUG("\n"); if (drm_fb_loaded) { - for (i = 0; i < drm_cards_limit; i++) { - head = drm_heads[i]; - if (!head) + for (i = 0; i < drm_minors_limit; i++) { + minor = drm_minors[i]; + if (!minor) continue; - if (!head->dev) + if (!minor->dev) continue; - if (head->dev->driver != driver) + if (minor->dev->driver != driver) continue; - dev = head->dev; + dev = minor->dev; if (dev) { /* release the pci driver */ if (dev->pdev) @@ -495,10 +495,10 @@ static int __init drm_core_init(void) drm_init_memctl(avail_memctl_mem/2, avail_memctl_mem*3/4, si.mem_unit); ret = -ENOMEM; - drm_cards_limit = - (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); - drm_heads = drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); - if (!drm_heads) + drm_minors_limit = + (drm_minors_limit < DRM_MAX_MINOR + 1 ? drm_minors_limit : DRM_MAX_MINOR + 1); + drm_minors = drm_calloc(drm_minors_limit, sizeof(*drm_minors), DRM_MEM_STUB); + if (!drm_minors) goto err_p1; if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) @@ -528,7 +528,7 @@ err_p3: drm_sysfs_destroy(); err_p2: unregister_chrdev(DRM_MAJOR, "drm"); - drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); + drm_free(drm_minors, sizeof(*drm_minors) * drm_minors_limit, DRM_MEM_STUB); err_p1: return ret; } @@ -540,7 +540,7 @@ static void __exit drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); - drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); + drm_free(drm_minors, sizeof(*drm_minors) * drm_minors_limit, DRM_MEM_STUB); } module_init(drm_core_init); @@ -600,7 +600,7 @@ EXPORT_SYMBOL(drm_ioctl); long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_ioctl_desc *ioctl; drm_ioctl_t *func; unsigned int nr = DRM_IOCTL_NR(cmd); @@ -612,7 +612,7 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++file_priv->ioctl_count; DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - current->pid, cmd, nr, (long)old_encode_dev(file_priv->head->device), + current->pid, cmd, nr, (long)old_encode_dev(file_priv->minor->device), file_priv->authenticated); if ((nr >= DRM_CORE_IOCTL_COUNT) && diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index 288b4db..b2c4e9c 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -516,7 +516,7 @@ static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class, int drm_fence_add_user_object(struct drm_file *priv, struct drm_fence_object *fence, int shareable) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -612,7 +612,7 @@ void drm_fence_manager_takedown(struct drm_device *dev) struct drm_fence_object *drm_lookup_fence_object(struct drm_file *priv, uint32_t handle) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_fence_object *fence; diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 7efcb23..28aaeb1 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -131,13 +131,13 @@ int drm_open(struct inode *inode, struct file *filp) int minor = iminor(inode); int retcode = 0; - if (!((minor >= 0) && (minor < drm_cards_limit))) + if (!((minor >= 0) && (minor < drm_minors_limit))) return -ENODEV; - if (!drm_heads[minor]) + if (!drm_minors[minor]) return -ENODEV; - if (!(dev = drm_heads[minor]->dev)) + if (!(dev = drm_minors[minor]->dev)) return -ENODEV; retcode = drm_open_helper(inode, filp, dev); @@ -182,13 +182,13 @@ int drm_stub_open(struct inode *inode, struct file *filp) DRM_DEBUG("\n"); - if (!((minor >= 0) && (minor < drm_cards_limit))) + if (!((minor >= 0) && (minor < drm_minors_limit))) return -ENODEV; - if (!drm_heads[minor]) + if (!drm_minors[minor]) return -ENODEV; - if (!(dev = drm_heads[minor]->dev)) + if (!(dev = drm_minors[minor]->dev)) return -ENODEV; old_fops = filp->f_op; @@ -254,8 +254,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->filp = filp; priv->uid = current->euid; priv->pid = current->pid; - priv->minor = minor; - priv->head = drm_heads[minor]; + priv->minor = drm_minors[minor]; priv->ioctl_count = 0; /* for compatibility root is always authenticated */ priv->authenticated = capable(CAP_SYS_ADMIN); @@ -321,11 +320,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, int drm_fasync(int fd, struct file *filp, int on) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int retcode; DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, - (long)old_encode_dev(priv->head->device)); + (long)old_encode_dev(priv->minor->device)); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; @@ -375,7 +374,7 @@ static void drm_object_release(struct file *filp) int drm_release(struct inode *inode, struct file *filp) { struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int retcode = 0; lock_kernel(); @@ -390,7 +389,7 @@ int drm_release(struct inode *inode, struct file *filp) */ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - current->pid, (long)old_encode_dev(file_priv->head->device), + current->pid, (long)old_encode_dev(file_priv->minor->device), dev->open_count); if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c index 5ade617..16ccdbc 100644 --- a/linux-core/drm_object.c +++ b/linux-core/drm_object.c @@ -33,7 +33,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item, int shareable) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; DRM_ASSERT_LOCKED(&dev->struct_mutex); @@ -58,7 +58,7 @@ EXPORT_SYMBOL(drm_add_user_object); struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_hash_item *hash; int ret; struct drm_user_object *item; @@ -85,7 +85,7 @@ EXPORT_SYMBOL(drm_lookup_user_object); static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; if (atomic_dec_and_test(&item->refcount)) { @@ -121,7 +121,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced struct drm_ref_object *item; struct drm_open_hash *ht = &priv->refd_object_hash[ref_action]; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); if (!referenced_object->shareable && priv != referenced_object->owner) { DRM_ERROR("Not allowed to reference this object\n"); return -EINVAL; @@ -178,7 +178,7 @@ struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv, struct drm_hash_item *hash; int ret; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); ret = drm_ht_find_item(&priv->refd_object_hash[ref_action], (unsigned long)referenced_object, &hash); if (ret) @@ -212,7 +212,7 @@ void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item) struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; enum drm_ref_type unref_action; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); unref_action = item->unref_action; if (atomic_dec_and_test(&item->refcount)) { ret = drm_ht_remove_item(ht, &item->hash); @@ -239,7 +239,7 @@ EXPORT_SYMBOL(drm_remove_ref_object); int drm_user_object_ref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type, struct drm_user_object **object) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_hash_item *hash; int ret; @@ -269,7 +269,7 @@ out_err: int drm_user_object_unref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_ref_object *ro; int ret; diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 3012c5b..8f26726 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -90,7 +90,7 @@ static struct drm_proc_list { * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -int drm_proc_init(struct drm_device * dev, int minor, +int drm_proc_init(struct drm_device *dev, int minor, struct proc_dir_entry *root, struct proc_dir_entry **dev_root) { struct proc_dir_entry *ent; @@ -535,7 +535,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, list_for_each_entry(priv, &dev->filelist, lhead) { DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", priv->authenticated ? 'y' : 'n', - priv->minor, + priv->minor->minor, priv->pid, priv->uid, priv->magic, priv->ioctl_count); } diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index cc759d5..433869e 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -37,20 +37,20 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_cards_limit = 16; /* Enough for one machine */ +unsigned int drm_minors_limit = 16; /* Enough for one machine */ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); +MODULE_PARM_DESC(minors_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); -module_param_named(cards_limit, drm_cards_limit, int, 0444); +module_param_named(minors_limit, drm_minors_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); -struct drm_head **drm_heads; +struct drm_minor **drm_minors; struct class *drm_class; struct proc_dir_entry *drm_proc_root; @@ -160,48 +160,48 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(struct drm_device * dev, struct drm_head * head) +static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) { - struct drm_head **heads = drm_heads; + struct drm_minor **minors = drm_minors; int ret; - int minor; + int index; DRM_DEBUG("\n"); - for (minor = 0; minor < drm_cards_limit; minor++, heads++) { - if (!*heads) { + for (index = 0; index < drm_minors_limit; index++, minors++) { + if (!*minors) { - *head = (struct drm_head) { + *minor = (struct drm_minor) { .dev = dev, - .device = MKDEV(DRM_MAJOR, minor), - .minor = minor, + .device = MKDEV(DRM_MAJOR, index), + .minor = index, }; if ((ret = - drm_proc_init(dev, minor, drm_proc_root, - &head->dev_root))) { + drm_proc_init(dev, index, drm_proc_root, + &minor->dev_root))) { printk(KERN_ERR "DRM: Failed to initialize /proc/dri.\n"); goto err_g1; } - ret = drm_sysfs_device_add(dev, head); + ret = drm_sysfs_device_add(dev, minor); if (ret) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); goto err_g2; } - *heads = head; + *minors = minor; - DRM_DEBUG("new minor assigned %d\n", minor); + DRM_DEBUG("new minor assigned %d\n", index); return 0; } } DRM_ERROR("out of minors\n"); return -ENOMEM; err_g2: - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); err_g1: - *head = (struct drm_head) { + *minor = (struct drm_minor) { .dev = NULL}; return ret; } @@ -309,17 +309,18 @@ int drm_put_dev(struct drm_device * dev) * last minor released. * */ -int drm_put_head(struct drm_head * head) +int drm_put_minor(struct drm_minor *minor) { - int minor = head->minor; + int index = minor->minor; - DRM_DEBUG("release secondary minor %d\n", minor); + DRM_DEBUG("release secondary minor %d\n", index); - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(head->dev); + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + drm_sysfs_device_remove(minor->dev); - *head = (struct drm_head) {.dev = NULL}; + *minor = (struct drm_minor) {.type = DRM_MINOR_UNASSIGNED, + .dev = NULL}; - drm_heads[minor] = NULL; + drm_minors[index] = NULL; return 0; } diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index 3aaac11..1f2d763 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -154,7 +154,7 @@ static void drm_sysfs_device_release(struct device *dev) * as the parent for the Linux device, and make sure it has a file containing * the driver we're using (for userspace compatibility). */ -int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) +int drm_sysfs_device_add(struct drm_device *dev, struct drm_minor *minor) { int err; int i, j; @@ -162,8 +162,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) dev->dev.parent = &dev->pdev->dev; dev->dev.class = drm_class; dev->dev.release = drm_sysfs_device_release; - dev->dev.devt = head->device; - snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); + dev->dev.devt = minor->device; + snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", minor->minor); err = device_register(&dev->dev); if (err) { diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index f2681cc..f439fa2 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -86,7 +86,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, unsigned long address) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_map *map = NULL; struct drm_map_list *r_list; struct drm_hash_item *hash; @@ -204,7 +204,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, static void drm_vm_shm_close(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; struct drm_map *map; struct drm_map_list *r_list; @@ -286,7 +286,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, unsigned long address) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_device_dma *dma = dev->dma; unsigned long offset; unsigned long page_nr; @@ -323,7 +323,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, { struct drm_map *map = (struct drm_map *) vma->vm_private_data; struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_sg_mem *entry = dev->sg; unsigned long offset; unsigned long map_offset; @@ -419,7 +419,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { static void drm_vm_open_locked(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *vma_entry; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -437,7 +437,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma) static void drm_vm_open(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; mutex_lock(&dev->struct_mutex); drm_vm_open_locked(vma); @@ -455,7 +455,7 @@ static void drm_vm_open(struct vm_area_struct *vma) static void drm_vm_close(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -491,7 +491,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) struct drm_device_dma *dma; unsigned long length = vma->vm_end - vma->vm_start; - dev = priv->head->dev; + dev = priv->minor->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", vma->vm_start, vma->vm_end, vma->vm_pgoff); @@ -556,7 +556,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_map *map = NULL; unsigned long offset = 0; struct drm_hash_item *hash; @@ -677,7 +677,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) int drm_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index c085fbc..64c7c0d 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -113,7 +113,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) drm_i810_buf_priv_t *buf_priv; lock_kernel(); - dev = priv->head->dev; + dev = priv->minor->dev; dev_priv = dev->dev_private; buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; @@ -141,7 +141,7 @@ static const struct file_operations i810_buffer_fops = { static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; drm_i810_buf_priv_t *buf_priv = buf->dev_private; drm_i810_private_t *dev_priv = dev->dev_private; const struct file_operations *old_fops; diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 8a6ce44..a81cfe6 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -461,7 +461,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) intel_crtc_load_lut(crtc); /* Give the overlay scaler a chance to enable if it's on this pipe */ - //intel_crtc_dpms_video(crtc, true); TODO + //intel_crtc_dpms_video(crtc, TRUE); TODO break; case DPMSModeOff: /* Give the overlay scaler a chance to disable if it's on this pipe */ @@ -699,19 +699,19 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, switch (intel_output->type) { case INTEL_OUTPUT_LVDS: - is_lvds = true; + is_lvds = TRUE; break; case INTEL_OUTPUT_SDVO: - is_sdvo = true; + is_sdvo = TRUE; break; case INTEL_OUTPUT_DVO: - is_dvo = true; + is_dvo = TRUE; break; case INTEL_OUTPUT_TVOUT: - is_tv = true; + is_tv = TRUE; break; case INTEL_OUTPUT_ANALOG: - is_crt = true; + is_crt = TRUE; break; } } diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index 42e08e7..7193e52 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -32,7 +32,6 @@ klibdrminclude_HEADERS = \ nouveau_drm.h \ r128_drm.h \ radeon_drm.h \ - radeon_ms_drm.h \ savage_drm.h \ sis_drm.h \ via_drm.h \ diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 23e8b49..4c1a07a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -780,7 +780,7 @@ int i915_process_relocs(struct drm_file *file_priv, struct drm_i915_validate_buffer *buffers, uint32_t num_buffers) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *reloc_list_object; uint32_t cur_handle = *reloc_buf_handle; uint32_t *reloc_page; @@ -866,7 +866,7 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, struct drm_i915_validate_buffer *buffers, uint32_t buf_count) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct i915_relocatee_info relocatee; int ret = 0; int b; @@ -926,7 +926,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned long next = 0; int ret = 0; unsigned buf_count = 0; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; uint32_t buf_reloc_handle, buf_handle; diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index d86c40b..ee795f3 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -87,6 +87,17 @@ enum radeon_monitor_type { MT_STV = 5 }; +enum radeon_connector_type { + CONNECTOR_NONE, + CONNECTOR_PROPRIETARY, + CONNECTOR_VGA, + CONNECTOR_DVI_I, + CONNECTOR_DVI_D, + CONNECTOR_CTV, + CONNECTOR_STV, + CONNECTOR_UNSUPPORTED +}; + enum radeon_output_type { OUTPUT_NONE, OUTPUT_DAC1, @@ -120,6 +131,7 @@ struct radeon_ms_connector { int crtc; uint32_t i2c_reg; char outputs[RADEON_MAX_OUTPUTS]; + char name[32]; }; struct radeon_ms_output { @@ -447,7 +459,8 @@ int radeon_ms_wait_for_idle(struct drm_device *dev); /* radeon_ms_i2c.c */ void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c); struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, - const uint32_t reg, int type); + const uint32_t reg, + const char *name); /* radeon_ms_irq.c */ void radeon_ms_irq_emit(struct drm_device *dev); diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c index 2483eab..297623a 100644 --- a/shared-core/radeon_ms_dac.c +++ b/shared-core/radeon_ms_dac.c @@ -369,8 +369,8 @@ int radeon_ms_dac2_mode_set(struct radeon_ms_output *output, case CHIP_R420: case CHIP_R430: case CHIP_R480: - if (connector->type != ConnectorComposite && - connector->type != ConnectorSVIDEO) { + if (connector->type != CONNECTOR_CTV && + connector->type != CONNECTOR_STV) { state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL; } } diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h index 7186030..842d533 100644 --- a/shared-core/radeon_ms_drm.h +++ b/shared-core/radeon_ms_drm.h @@ -57,12 +57,4 @@ struct drm_radeon_execbuffer { struct drm_fence_arg fence_arg; }; -#define RADEON_MS_MAX_SAREA_CLIPRECTS 16 - -struct drm_radeon_ms_sarea { - /* the cliprects */ - struct drm_clip_rect boxes[RADEON_MS_MAX_SAREA_CLIPRECTS]; - unsigned int nbox; -}; - #endif diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index fcfec79..779595d 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -58,17 +58,19 @@ static struct radeon_ms_output radeon_ms_dac2 = { }; static struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 - } + }, + "VGA" }; static struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 - } + }, + "DVI-I" }; static struct radeon_ms_properties properties[] = { diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c index f873070..1801c49 100644 --- a/shared-core/radeon_ms_i2c.c +++ b/shared-core/radeon_ms_i2c.c @@ -219,7 +219,8 @@ static void set_data(void *i2c_priv, int data) * */ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, - const uint32_t reg, int type) + const uint32_t reg, + const char *name) { struct radeon_ms_i2c *i2c; int ret; @@ -232,17 +233,7 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, i2c->drm_dev = dev; i2c->reg = reg; - switch (type) { - case ConnectorVGA: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-VGA"); - break; - case ConnectorDVII: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-DVII"); - break; - default: - snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-UNKNOWN"); - break; - } + snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-%s", name); i2c->adapter.owner = THIS_MODULE; /* fixme need to take a look at what its needed for */ i2c->adapter.id = I2C_HW_B_RADEON; diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index a1ed29c..35e5c37 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -249,14 +249,14 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) dev_priv->properties->connectors[i], sizeof(struct radeon_ms_connector)); connector->i2c = radeon_ms_i2c_create(dev, - connector->i2c_reg, connector->type); + connector->i2c_reg, connector->name); if (connector->i2c == NULL) { radeon_ms_connectors_destroy(dev); return -ENOMEM; } output = drm_output_create(dev, &radeon_ms_output_funcs, - connector->type); + connector->name); if (output == NULL) { radeon_ms_connectors_destroy(dev); return -EINVAL; |
From: <gl...@ke...> - 2008-01-15 15:02:32
|
linux-core/Makefile.kernel | 3 linux-core/radeon_ms_combios.c | 1 linux-core/radeon_ms_combios.h | 1 linux-core/radeon_ms_properties.c | 1 linux-core/radeon_ms_properties.h | 1 linux-core/radeon_ms_rom.c | 1 linux-core/radeon_ms_rom.h | 1 shared-core/radeon_ms.h | 44 +-- shared-core/radeon_ms_combios.c | 411 +++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_combios.h | 385 ++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_crtc.c | 45 ++-- shared-core/radeon_ms_dac.c | 2 shared-core/radeon_ms_drm.c | 28 ++ shared-core/radeon_ms_family.c | 100 --------- shared-core/radeon_ms_i2c.c | 63 +++++ shared-core/radeon_ms_output.c | 54 +++- shared-core/radeon_ms_properties.c | 123 +++++++++++ shared-core/radeon_ms_properties.h | 50 ++++ shared-core/radeon_ms_reg.h | 26 ++ shared-core/radeon_ms_rom.c | 91 ++++++++ shared-core/radeon_ms_rom.h | 51 ++++ 21 files changed, 1321 insertions(+), 161 deletions(-) New commits: commit 6ba979ea467ef6ff76c32ee63ee9a6d4073ec672 Author: Jerome Glisse <gl...@fr...> Date: Tue Jan 15 16:01:39 2008 +0100 radeon_ms: use radeon connector type insted of drm diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c index ecd4bd0..65609af 100644 --- a/shared-core/radeon_ms_combios.c +++ b/shared-core/radeon_ms_combios.c @@ -144,13 +144,13 @@ static int radeon_ms_combios_connector_add(struct drm_device *dev, connector->i2c_reg = i2c_reg; switch (connector->type) { - case ConnectorVGA: + case CONNECTOR_VGA: sprintf(connector->name, "VGA"); break; - case ConnectorDVII: + case CONNECTOR_DVI_I: sprintf(connector->name, "DVI-I"); break; - case ConnectorDVID: + case CONNECTOR_DVI_D: sprintf(connector->name, "DVI-D"); break; default: @@ -279,7 +279,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) switch (connector_type) { case BIOS_CONNECTOR_TYPE__CRT: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorVGA, + CONNECTOR_VGA, i2c_reg); if (ret) { return ret; @@ -288,7 +288,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) break; case BIOS_CONNECTOR_TYPE__DVI_I: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorDVII, + CONNECTOR_DVI_I, i2c_reg); if (ret) { return ret; @@ -297,7 +297,7 @@ int radeon_ms_connectors_from_combios(struct drm_device *dev) break; case BIOS_CONNECTOR_TYPE__DVI_D: ret = radeon_ms_combios_connector_add(dev, c, - ConnectorDVID, + CONNECTOR_DVI_D, i2c_reg); if (ret) { return ret; diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c index 297623a..e631294 100644 --- a/shared-core/radeon_ms_dac.c +++ b/shared-core/radeon_ms_dac.c @@ -370,7 +370,7 @@ int radeon_ms_dac2_mode_set(struct radeon_ms_output *output, case CHIP_R430: case CHIP_R480: if (connector->type != CONNECTOR_CTV && - connector->type != CONNECTOR_STV) { + connector->type != CONNECTOR_STV) { state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL; } } diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c index 2bd45dc..baf2a7f 100644 --- a/shared-core/radeon_ms_properties.c +++ b/shared-core/radeon_ms_properties.c @@ -58,7 +58,7 @@ struct radeon_ms_output radeon_ms_dac2 = { }; struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 }, @@ -66,7 +66,7 @@ struct radeon_ms_connector radeon_ms_vga = { }; struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 }, commit 20a8e2d30e99a3248e6f02f792a29d20ec9f2ce5 Author: Jerome Glisse <gl...@fr...> Date: Tue Jan 15 14:30:40 2008 +0100 radeon_ms: cope with lastest drm modesetting change diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c index 04a3369..ecd4bd0 100644 --- a/shared-core/radeon_ms_combios.c +++ b/shared-core/radeon_ms_combios.c @@ -143,10 +143,25 @@ static int radeon_ms_combios_connector_add(struct drm_device *dev, connector->type = connector_type; connector->i2c_reg = i2c_reg; + switch (connector->type) { + case ConnectorVGA: + sprintf(connector->name, "VGA"); + break; + case ConnectorDVII: + sprintf(connector->name, "DVI-I"); + break; + case ConnectorDVID: + sprintf(connector->name, "DVI-D"); + break; + default: + sprintf(connector->name, "UNKNOWN-CONNECTOR"); + break; + } + if (i2c_reg) { connector->i2c = radeon_ms_i2c_create(dev, connector->i2c_reg, - connector->type); + connector->name); if (connector->i2c == NULL) { radeon_ms_connectors_destroy(dev); return -ENOMEM; diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 1880632..bc17437 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -255,8 +255,8 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) return -ENOMEM; } output = drm_output_create(dev, - &radeon_ms_output_funcs, - connector->name); + &radeon_ms_output_funcs, + connector->type); if (output == NULL) { radeon_ms_connectors_destroy(dev); return -EINVAL; diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c index 393f496..2bd45dc 100644 --- a/shared-core/radeon_ms_properties.c +++ b/shared-core/radeon_ms_properties.c @@ -61,14 +61,16 @@ struct radeon_ms_connector radeon_ms_vga = { NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, { 0, -1, -1, -1, -1, -1, -1, -1 - } + }, + "VGA" }; struct radeon_ms_connector radeon_ms_dvi_i_2 = { NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, { 1, -1, -1, -1, -1, -1, -1, -1 - } + }, + "DVI-I" }; struct radeon_ms_properties properties[] = { commit f1f934c8c97d6664fb5e1920a41154c09cc7f293 Author: Jerome Glisse <gl...@fr...> Date: Tue Jan 15 14:05:25 2008 +0100 radeon_ms: add rom parsing & adapt code Add rom (only combios for now) parsing and use informations retrieve instead of hardcoded table. Shuffle code around a bit. diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 7ef504a..b4fdcf6 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -39,7 +39,8 @@ radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \ radeon_ms_bus.o radeon_ms_fence.o \ radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \ radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \ - radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o + radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o \ + radeon_ms_properties.o radeon_ms_rom.o radeon_ms_combios.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o savage-objs := savage_drv.o savage_bci.o savage_state.o diff --git a/linux-core/radeon_ms_combios.c b/linux-core/radeon_ms_combios.c new file mode 120000 index 0000000..d7b9995 --- /dev/null +++ b/linux-core/radeon_ms_combios.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_combios.c \ No newline at end of file diff --git a/linux-core/radeon_ms_combios.h b/linux-core/radeon_ms_combios.h new file mode 120000 index 0000000..5b19c70 --- /dev/null +++ b/linux-core/radeon_ms_combios.h @@ -0,0 +1 @@ +../shared-core/radeon_ms_combios.h \ No newline at end of file diff --git a/linux-core/radeon_ms_properties.c b/linux-core/radeon_ms_properties.c new file mode 120000 index 0000000..e2e0dc0 --- /dev/null +++ b/linux-core/radeon_ms_properties.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_properties.c \ No newline at end of file diff --git a/linux-core/radeon_ms_properties.h b/linux-core/radeon_ms_properties.h new file mode 120000 index 0000000..59783e8 --- /dev/null +++ b/linux-core/radeon_ms_properties.h @@ -0,0 +1 @@ +../shared-core/radeon_ms_properties.h \ No newline at end of file diff --git a/linux-core/radeon_ms_rom.c b/linux-core/radeon_ms_rom.c new file mode 120000 index 0000000..80f5f60 --- /dev/null +++ b/linux-core/radeon_ms_rom.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_rom.c \ No newline at end of file diff --git a/linux-core/radeon_ms_rom.h b/linux-core/radeon_ms_rom.h new file mode 120000 index 0000000..f20e42b --- /dev/null +++ b/linux-core/radeon_ms_rom.h @@ -0,0 +1 @@ +../shared-core/radeon_ms_rom.h \ No newline at end of file diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index ee795f3..a784882 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -33,6 +33,8 @@ #include "radeon_ms_drv.h" #include "radeon_ms_reg.h" #include "radeon_ms_drm.h" +#include "radeon_ms_rom.h" +#include "radeon_ms_properties.h" #define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\ "Keith Whitwell, others." @@ -43,10 +45,6 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -#define RADEON_PAGE_SIZE 4096 -#define RADEON_MAX_CONNECTORS 8 -#define RADEON_MAX_OUTPUTS 8 - enum radeon_bus_type { RADEON_PCI = 0x10000, RADEON_AGP = 0x20000, @@ -154,20 +152,6 @@ struct radeon_ms_output { struct radeon_state *state); }; -struct radeon_ms_properties { - uint16_t subvendor; - uint16_t subdevice; - int16_t pll_reference_freq; - int32_t pll_min_pll_freq; - int32_t pll_max_pll_freq; - char pll_use_bios; - char pll_dummy_reads; - char pll_delay; - char pll_r300_errata; - struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; - struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; -}; - struct radeon_state { /* memory */ uint32_t config_aper_0_base; @@ -310,7 +294,6 @@ struct drm_radeon_private { /* card family */ uint32_t usec_timeout; uint32_t family; - struct radeon_ms_properties *properties; struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; /* drm map (MMIO, FB) */ @@ -342,6 +325,9 @@ struct drm_radeon_private { uint8_t cp_ready; uint8_t bus_ready; uint8_t write_back; + /* abstract asic specific structures */ + struct radeon_ms_rom rom; + struct radeon_ms_properties properties; }; @@ -369,6 +355,11 @@ int radeon_ms_pcie_init(struct drm_device *dev); void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state); void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state); +/* radeon_ms_combios.c */ +int radeon_ms_combios_get_properties(struct drm_device *dev); +int radeon_ms_connectors_from_combios(struct drm_device *dev); +int radeon_ms_outputs_from_combios(struct drm_device *dev); + /* radeon_ms_compat.c */ long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -475,12 +466,21 @@ void radeon_ms_irq_uninstall(struct drm_device * dev); /* radeon_ms_output.c */ void radeon_ms_connectors_destroy(struct drm_device *dev); int radeon_ms_connectors_from_properties(struct drm_device *dev); +int radeon_ms_connectors_from_rom(struct drm_device *dev); void radeon_ms_outputs_destroy(struct drm_device *dev); int radeon_ms_outputs_from_properties(struct drm_device *dev); +int radeon_ms_outputs_from_rom(struct drm_device *dev); void radeon_ms_outputs_restore(struct drm_device *dev, struct radeon_state *state); void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state); +/* radeon_ms_properties.c */ +int radeon_ms_properties_init(struct drm_device *dev); + +/* radeon_ms_rom.c */ +int radeon_ms_rom_get_properties(struct drm_device *dev); +int radeon_ms_rom_init(struct drm_device *dev); + /* radeon_ms_state.c */ void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state); void radeon_ms_state_restore(struct drm_device *dev, @@ -545,7 +545,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv) /* This workaround is necessary on rv200 and RS200 or PLL * reads may return garbage (among others...) */ - if (dev_priv->properties->pll_dummy_reads) { + if (dev_priv->properties.pll_dummy_reads) { tmp = MMIO_R(CLOCK_CNTL_DATA); tmp = MMIO_R(CRTC_GEN_CNTL); } @@ -554,7 +554,7 @@ static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv) * CLOCK_CNTL_INDEX register access. If not, register reads afterward * may not be correct. */ - if (dev_priv->properties->pll_r300_errata) { + if (dev_priv->properties.pll_r300_errata) { tmp = save = MMIO_R(CLOCK_CNTL_INDEX); tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK; tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN; @@ -569,7 +569,7 @@ static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv) /* This workarounds is necessary on RV100, RS100 and RS200 chips * or the chip could hang on a subsequent access */ - if (dev_priv->properties->pll_delay) { + if (dev_priv->properties.pll_delay) { /* we can't deal with posted writes here ... */ udelay(5000); } diff --git a/shared-core/radeon_ms_combios.c b/shared-core/radeon_ms_combios.c new file mode 100644 index 0000000..04a3369 --- /dev/null +++ b/shared-core/radeon_ms_combios.c @@ -0,0 +1,396 @@ +/* + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + */ +/* + * Authors: + * Jérôme Glisse <gl...@fr...> + */ +#include "radeon_ms.h" + +extern struct radeon_ms_output radeon_ms_dac1; +extern struct radeon_ms_output radeon_ms_dac2; +extern const struct drm_output_funcs radeon_ms_output_funcs; + +static struct combios_connector_chip_info * +radeon_ms_combios_get_connector_chip_info(struct drm_device *dev, int chip_num) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_ms_rom *rom = &dev_priv->rom; + struct combios_header *header; + struct combios_connector_table *connector_table; + struct combios_connector_chip_info *connector_chip_info; + uint32_t offset; + int numof_chips, i; + + if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) { + return NULL; + } + header = rom->rom.combios_header; + offset = header->usPointerToExtendedInitTable2; + if ((offset + sizeof(struct combios_connector_table)) > rom->rom_size) { + DRM_INFO("[radeon_ms] wrong COMBIOS connector offset\n"); + return NULL; + } + if (!offset) { + return NULL; + } + connector_table = (struct combios_connector_table *) + &rom->rom_image[offset]; + numof_chips = (connector_table->ucConnectorHeader & + BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK) >> + BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT; + DRM_INFO("[radeon_ms] COMBIOS number of chip: %d (table rev: %d)\n", + numof_chips, + (connector_table->ucConnectorHeader & + BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK) >> + BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT); + for (i = 0; i < numof_chips; i++) { + int chip; + + connector_chip_info = &connector_table->sChipConnectorInfo[i]; + chip = (connector_chip_info->ucChipHeader & + BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK) >> + BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT; + DRM_INFO("[radeon_ms] COMBIOS chip: %d (asked for: %d)\n", + chip, chip_num); + if (chip == chip_num) { + return connector_chip_info; + } + } + return NULL; +} + +static int radeon_combios_get_connector_infos(struct drm_device *dev, + int connector_info, + int *connector_type, + int *ddc_line, + int *tmds_type, + int *dac_type) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + + *connector_type = (connector_info & BIOS_CONNECTOR_INFO__TYPE__MASK) >> + BIOS_CONNECTOR_INFO__TYPE__SHIFT; + *ddc_line = (connector_info & BIOS_CONNECTOR_INFO__DDC_LINE__MASK) >> + BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT; + *tmds_type = (connector_info & BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK) >> + BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT; + *dac_type = (connector_info & BIOS_CONNECTOR_INFO__DAC_TYPE__MASK) >> + BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT; + + /* most XPRESS chips seem to specify DDC_CRT2 for their + * VGA DDC port, however DDC never seems to work on that + * port. Some have reported success on DDC_MONID, so + * lets see what happens with that. + */ + if (dev_priv->family == CHIP_RS400 && + *connector_type == BIOS_CONNECTOR_TYPE__CRT && + *ddc_line == BIOS_DDC_LINE__CRT2) { + *ddc_line = BIOS_DDC_LINE__MONID01; + } + /* XPRESS desktop chips seem to have a proprietary + * connector listed for DVI-D, try and do the right + * thing here. + */ + if (dev_priv->family == CHIP_RS400 && + *connector_type == BIOS_CONNECTOR_TYPE__PROPRIETARY) { + DRM_INFO("[radeon_ms] COMBIOS Proprietary connector " + "found, assuming DVI-D\n"); + *dac_type = 2; + *tmds_type = BIOS_TMDS_TYPE__EXTERNAL; + *connector_type = BIOS_CONNECTOR_TYPE__DVI_D; + } + return 0; +} + +static int radeon_ms_combios_connector_add(struct drm_device *dev, + int connector_number, + int connector_type, + uint32_t i2c_reg) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_ms_connector *connector = NULL; + struct drm_output *output = NULL; + + connector = drm_alloc(sizeof(struct radeon_ms_connector), + DRM_MEM_DRIVER); + if (connector == NULL) { + radeon_ms_connectors_destroy(dev); + return -ENOMEM; + } + memset(connector, 0, sizeof(struct radeon_ms_connector)); + connector->monitor_type = MT_NONE; + connector->type = connector_type; + connector->i2c_reg = i2c_reg; + + if (i2c_reg) { + connector->i2c = radeon_ms_i2c_create(dev, + connector->i2c_reg, + connector->type); + if (connector->i2c == NULL) { + radeon_ms_connectors_destroy(dev); + return -ENOMEM; + } + } else { + connector->i2c = NULL; + } + + output = drm_output_create(dev, &radeon_ms_output_funcs, + connector->type); + if (output == NULL) { + radeon_ms_connectors_destroy(dev); + return -EINVAL; + } + connector->output = output; + output->driver_private = connector; + output->possible_crtcs = 0x3; + dev_priv->connectors[connector_number] = connector; + return 0; +} + +int radeon_ms_combios_get_properties(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_ms_rom *rom = &dev_priv->rom; + struct combios_pll_block *pll_block; + struct combios_header *header; + uint32_t offset; + + if (rom->type != ROM_COMBIOS || rom->rom_image == NULL) { + return 0; + } + header = rom->rom.combios_header; + offset = header->usPointerToPllInfoBlock; + if ((offset + sizeof(struct combios_pll_block)) > rom->rom_size) { + DRM_INFO("[radeon_ms] wrong COMBIOS pll block offset\n"); + return 0; + } + if (!offset) { + return 0; + } + pll_block = (struct combios_pll_block *)&rom->rom_image[offset]; + dev_priv->properties.pll_reference_freq = pll_block->usDotClockRefFreq; + dev_priv->properties.pll_reference_div = pll_block->usDotClockRefDiv; + dev_priv->properties.pll_min_pll_freq = pll_block->ulDotClockMinFreq; + dev_priv->properties.pll_max_pll_freq = pll_block->ulDotClockMaxFreq; + dev_priv->properties.pll_reference_freq *= 10; + dev_priv->properties.pll_min_pll_freq *= 10; + dev_priv->properties.pll_max_pll_freq *= 10; + DRM_INFO("[radeon_ms] COMBIOS pll reference frequency : %d\n", + dev_priv->properties.pll_reference_freq); + DRM_INFO("[radeon_ms] COMBIOS pll reference divider : %d\n", + dev_priv->properties.pll_reference_div); + DRM_INFO("[radeon_ms] COMBIOS pll minimum frequency : %d\n", + dev_priv->properties.pll_min_pll_freq); + DRM_INFO("[radeon_ms] COMBIOS pll maximum frequency : %d\n", + dev_priv->properties.pll_max_pll_freq); + return 1; +} + +int radeon_ms_connectors_from_combios(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct combios_connector_chip_info *connector_chip_info; + int connector_type, ddc_line, tmds_type, dac_type; + int dac1, dac2, tmdsint, tmdsext; + int numof_connector, i, c = 0, added, j; + uint32_t i2c_reg; + int ret; + + dac1 = dac2 = tmdsint = tmdsext = -1; + connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1); + if (connector_chip_info == NULL) { + return -1; + } + numof_connector = (connector_chip_info->ucChipHeader & + BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >> + BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT; + DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n", + numof_connector); + for (i = 0; i < numof_connector; i++) { + int connector_info = connector_chip_info->sConnectorInfo[i]; + + ret = radeon_combios_get_connector_infos(dev, + connector_info, + &connector_type, + &ddc_line, + &tmds_type, + &dac_type); + + switch (ddc_line) { + case BIOS_DDC_LINE__MONID01: + i2c_reg = GPIO_MONID; + break; + case BIOS_DDC_LINE__DVI: + i2c_reg = GPIO_DVI_DDC; + break; + case BIOS_DDC_LINE__VGA: + i2c_reg = GPIO_DDC1; + break; + case BIOS_DDC_LINE__CRT2: + i2c_reg = GPIO_CRT2_DDC; + break; + case BIOS_DDC_LINE__GPIOPAD: + i2c_reg = VIPPAD_EN; + break; + case BIOS_DDC_LINE__ZV_LCDPAD: + i2c_reg = VIPPAD1_EN; + break; + default: + i2c_reg = 0; + break; + } + added = 0; + switch (connector_type) { + case BIOS_CONNECTOR_TYPE__CRT: + ret = radeon_ms_combios_connector_add(dev, c, + ConnectorVGA, + i2c_reg); + if (ret) { + return ret; + } + added = 1; + break; + case BIOS_CONNECTOR_TYPE__DVI_I: + ret = radeon_ms_combios_connector_add(dev, c, + ConnectorDVII, + i2c_reg); + if (ret) { + return ret; + } + added = 1; + break; + case BIOS_CONNECTOR_TYPE__DVI_D: + ret = radeon_ms_combios_connector_add(dev, c, + ConnectorDVID, + i2c_reg); + if (ret) { + return ret; + } + added = 1; + break; + default: + break; + } + if (added) { + j = 0; + /* find to which output this connector is associated + * by following same algo as in: + * radeon_ms_outputs_from_combios*/ + switch (dac_type) { + case BIOS_DAC_TYPE__CRT: + if (dac1 == -1) { + dac1 = c; + } + dev_priv->connectors[c]->outputs[j++] = dac1; + break; + case BIOS_DAC_TYPE__NON_CRT: + if (dac2 == -1) { + dac2 = c; + } + dev_priv->connectors[c]->outputs[j++] = dac2; + break; + } +#if 0 + switch (tmds_type) { + case BIOS_TMDS_TYPE__INTERNAL: + if (tmdsint == -1) { + tmdsint = c; + } + dev_priv->connectors[c]->outputs[j++] = tmdsint; + break; + case BIOS_TMDS_TYPE__EXTERNAL: + if (tmdsext == -1) { + tmdsext = c; + } + dev_priv->connectors[c]->outputs[j++] = tmdsext; + break; + } +#endif + c++; + } + } + return c; +} + +int radeon_ms_outputs_from_combios(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct combios_connector_chip_info *connector_chip_info; + int connector_type, ddc_line, tmds_type, dac_type; + int numof_connector, i, dac1_present, dac2_present, c = 0; + int ret; + + dac1_present = dac2_present = 0; + connector_chip_info = radeon_ms_combios_get_connector_chip_info(dev, 1); + if (connector_chip_info == NULL) { + return -1; + } + numof_connector = (connector_chip_info->ucChipHeader & + BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK) >> + BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT; + DRM_INFO("[radeon_ms] COMBIOS number of connector: %d\n", + numof_connector); + for (i = 0; i < numof_connector; i++) { + int connector_info = connector_chip_info->sConnectorInfo[i]; + + ret = radeon_combios_get_connector_infos(dev, + connector_info, + &connector_type, + &ddc_line, + &tmds_type, + &dac_type); + + if (!dac1_present && dac_type == BIOS_DAC_TYPE__CRT) { + dev_priv->outputs[c] = + drm_alloc(sizeof(struct radeon_ms_output), + DRM_MEM_DRIVER); + if (dev_priv->outputs[c] == NULL) { + radeon_ms_outputs_destroy(dev); + return -ENOMEM; + } + memcpy(dev_priv->outputs[c], &radeon_ms_dac1, + sizeof(struct radeon_ms_output)); + dev_priv->outputs[c]->dev = dev; + dev_priv->outputs[c]->initialize(dev_priv->outputs[c]); + dac1_present = 1; + c++; + } + if (!dac2_present && dac_type == BIOS_DAC_TYPE__NON_CRT) { + dev_priv->outputs[c] = + drm_alloc(sizeof(struct radeon_ms_output), + DRM_MEM_DRIVER); + if (dev_priv->outputs[c] == NULL) { + radeon_ms_outputs_destroy(dev); + return -ENOMEM; + } + memcpy(dev_priv->outputs[c], &radeon_ms_dac2, + sizeof(struct radeon_ms_output)); + dev_priv->outputs[c]->dev = dev; + dev_priv->outputs[c]->initialize(dev_priv->outputs[c]); + dac1_present = 1; + c++; + } + } + return c; +} diff --git a/shared-core/radeon_ms_combios.h b/shared-core/radeon_ms_combios.h new file mode 100644 index 0000000..fbceadf --- /dev/null +++ b/shared-core/radeon_ms_combios.h @@ -0,0 +1,385 @@ +/* + * Copyright 2006-2007 Advanced Micro Devices, Inc. + * Copyright 2007 Jérôme Glisse + * + * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + */ +/* + * Authors: + * Jérôme Glisse <gl...@fr...> + */ +#ifndef __RADEON_MS_COMBIOS_H__ +#define __RADEON_MS_COMBIOS_H__ + +#pragma pack(1) + +#define ROM_HEADER 0x48 + +struct combios_header +{ + uint8_t ucTypeDefinition; + uint8_t ucExtFunctionCode; + uint8_t ucOemID1; + uint8_t ucOemID2; + uint8_t ucBiosMajorRev; + uint8_t ucBiosMinorRev; + uint16_t usStructureSize; + uint16_t usPointerToSmi; + uint16_t usPointerToPmid; + uint16_t usPointerToInitTable; + uint16_t usPointerToCrcChecksumBlock; + uint16_t usPointerToConfigFilename; + uint16_t usPointerToLogonMessage; + uint16_t usPointerToMiscInfo; + uint16_t usPciBusDevInitCode; + uint16_t usBiosRuntimeSegmentAddress; + uint16_t usIoBaseAddress; + uint16_t usSubsystemVendorID; + uint16_t usSubsystemID; + uint16_t usPostVendorID; + uint16_t usInt10Offset; + uint16_t usInt10Segment; + uint16_t usMonitorInfo; + uint16_t usPointerToConfigBlock; + uint16_t usPointerToDacDelayInfo; + uint16_t usPointerToCapDataStruct; + uint16_t usPointerToInternalCrtTables; + uint16_t usPointerToPllInfoBlock; + uint16_t usPointerToTVInfoTable; + uint16_t usPointerToDFPInfoTable; + uint16_t usPointerToHWConfigTable; + uint16_t usPointerToMMConfigTable; + uint32_t ulTVStdPatchTableSignature; + uint16_t usPointerToTVStdPatchTable; + uint16_t usPointerToPanelInfoTable; + uint16_t usPointerToAsicInfoTable; + uint16_t usPointerToAuroraInfoTable; + uint16_t usPointerToPllInitTable; + uint16_t usPointerToMemoryConfigTable; + uint16_t usPointerToSaveMaskTable; + uint16_t usPointerHardCodedEdid; + uint16_t usPointerToExtendedInitTable1; + uint16_t usPointerToExtendedInitTable2; + uint16_t usPointerToDynamicClkTable; + uint16_t usPointerToReservedMemoryTable; + uint16_t usPointerToBridgetInitTable; + uint16_t usPointerToExtTMDSInitTable; + uint16_t usPointerToMemClkInfoTable; + uint16_t usPointerToExtDACTable; + uint16_t usPointerToMiscInfoTable; +}; + +struct combios_pll_block +{ + /* Usually 6 */ + uint8_t ucPLLBiosVersion; + /* Size in bytes */ + uint8_t ucStructureSize; + /* Dot clock entry used for accelerated modes */ + uint8_t ucDotClockEntry; + /* Dot clock entry used for extended VGA modes */ + uint8_t ucDotClockEntryVga; + /* Offset into internal clock table used for by VGA parameter table */ + uint16_t usPointerToInternalClock; + /* Offset into actual programmed frequency table at POST */ + uint16_t usPointerToFreqTable; + /* XCLK setting, (memory clock in 10 KHz units) */ + uint16_t usXclkSetting; + /* MCLK setting, (engine clock in 10 KHz units) */ + uint16_t usMclkSetting; + /* Number of PLL information block to follow, currently value is 3 */ + uint8_t ucPllInfoBlockNumber; + /* Size of each PLL information block */ + uint8_t ucPllInfoBlockSize; + /* Reference frequency of the dot clock */ + uint16_t usDotClockRefFreq; + /* Reference Divider of the dot clock */ + uint16_t usDotClockRefDiv; + /* Min Frequency supported before post divider for the dot clock */ + uint32_t ulDotClockMinFreq; + /* Max Frequency can be supported for the dot clock */ + uint32_t ulDotClockMaxFreq; + /* Reference frequency of the MCLK, engine clock */ + uint16_t usMclkRefFreq; + /* Reference Divider of the MCLK, engine clock */ + uint16_t usMclkRefDiv; + /* Min Frequency supported before post divider for MCLK, engine clock */ + uint32_t ulMclkMinFreq; + /* Max Frequency can be supported for the MCLK, engine clock */ + uint32_t ulMclkMaxFreq; + /* Reference frequency of the XCLK, memory clock */ + uint16_t usXclkRefFreq; + /* Reference Divider of the XCLK, memory clock */ + uint16_t usXclkRefDiv; + /* Min Frequency supported before post divider for XCLK, memory clock */ + uint32_t ulXclkMinFreq; + /* Max Frequency can be supported for the XCLK, memory clock */ + uint32_t ulXclkMaxFreq; + + /*this is the PLL Information Table Extended structure version 10 */ + uint8_t ucNumberOfExtendedPllBlocks; + uint8_t ucSizePLLDefinition; + uint16_t ulCrystalFrequencyPixelClock_pll; + uint32_t ulMinInputPixelClockPLLFrequency; + uint32_t ulMaxInputPixelClockPLLFrequency; + uint32_t ulMinOutputPixelClockPLLFrequency; + uint32_t ulMaxOutputPixelClockPLLFrequency; + + /*version 11 */ + uint16_t ulCrystalFrequencyEngineClock_pll; + uint32_t ulMinInputFrequencyEngineClock_pll; + uint32_t ulMaxInputFrequencyEngineClock_pll; + uint32_t ulMinOutputFrequencyEngineClock_pll; + uint32_t ulMaxOutputFrequencyEngineClock_pll; + uint16_t ulCrystalFrequencyMemoryClock_pll; + uint32_t ulMinInputFrequencyMemoryClock_pll; + uint32_t ulMaxInputFrequencyMemoryClock_pll; + uint32_t ulMinOutputFrequencyMemoryClock_pll; + uint32_t ulMaxOutputFrequencyMemoryClock_pll; + uint32_t ulMaximumDACOutputFrequency; +}; + +#define MAX_NO_OF_LCD_RES_TIMING 25 + +struct panel_information_table +{ + uint8_t ucPanelIdentification; + uint8_t ucPanelIDString[24]; + uint16_t usHorizontalSize; + uint16_t usVerticalSize; + uint16_t usFlatPanelType; + uint8_t ucRedBitsPerPrimary; + uint8_t ucGreenBitsPerPrimary; + uint8_t ucBlueBitsPerPrimary; + uint8_t ucReservedBitsPerPrimary; + uint8_t ucPanelCaps; + uint8_t ucPowerSequenceDelayStepsInMS; + uint8_t ucSupportedRefreshRateExtended; + uint16_t usExtendedPanelInfoTable; + uint16_t usPtrToHalfFrameBufferInformationTable; + uint16_t usVccOntoBlOn; + uint16_t usOffDelay; + uint16_t usRefDiv; + uint8_t ucPostDiv; + uint16_t usFeedBackDiv; + uint8_t ucSpreadSpectrumType; + uint16_t usSpreadSpectrumPercentage; + uint8_t ucBackLightLevel; + uint8_t ucBiasLevel; + uint8_t ucPowerSequenceDelay; + uint32_t ulPanelData; + uint8_t ucPanelRefreshRateData; + uint16_t usSupportedRefreshRate; + uint16_t usModeTableOffset[MAX_NO_OF_LCD_RES_TIMING]; +}; + +struct extended_panel_info_table +{ + uint8_t ucExtendedPanelInfoTableVer; + uint8_t ucSSDelay; + uint8_t ucSSStepSizeIndex; +}; + +struct lcd_mode_table_center +{ + uint16_t usHorizontalRes; + uint16_t usVerticalRes; + uint8_t ucModeType; + uint16_t usOffset2ExpParamTable; + uint16_t usOffset2TvParamTable; + uint16_t usPixelClock; + uint16_t usPixelClockAdjustment; + uint16_t usFpPos; + uint8_t ucReserved; + uint8_t ucMiscBits; + uint16_t usCrtcHTotal; + uint16_t usCrtcHDisp; + uint16_t usCrtcHSyncStrt; + uint8_t ucCrtcHSyncWid; + uint16_t usCrtcVTotal; + uint16_t usCrtcVDisp; + uint16_t usCrtcVSyncStrt; + uint8_t ucOvrWidTop; +}; + +struct lcd_mode_table_exp +{ + uint16_t usPixelClock; + uint16_t usPixelClockAdjustment; + uint16_t usFpPos; + uint8_t ucReserved; + uint8_t ucMiscBits; + uint16_t usCrtcHTotal; + uint16_t usCrtcHDisp; + uint16_t usCrtcHSyncStrt; + uint8_t ucCrtcHSyncWid; + uint16_t usCrtcVTotal; + uint16_t usCrtcVDisp; + uint16_t usCrtcVSyncStrt; + uint8_t ucOvrWidTop; + uint16_t usHorizontalBlendRatio; + uint32_t ulVgaVertStretching; + uint16_t usCopVertStretching; + uint16_t usVgaExtVertStretching; +}; + +struct tmds_pll_cntl_block +{ + uint16_t usClockUpperRange; + uint32_t ulPllSetting; +}; + +#define MAX_PLL_CNTL_ENTRIES 8 + +struct combios_dfp_info_table +{ + uint8_t ucDFPInfoTableRev; + uint8_t ucDFPInfoTableSize; + uint16_t usOffsetDetailedTimingTable; + uint8_t ucReserved; + uint8_t ucNumberOfClockRanges; + uint16_t usMaxPixelClock; + uint32_t ulInitValueTmdsPllCntl; + uint32_t ulFinalValueTmdsPllCntl; + struct tmds_pll_cntl_block sTmdsPllCntlBlock[MAX_PLL_CNTL_ENTRIES]; +}; + +struct combios_exttmds_table_header +{ + uint8_t ucTableRev; + uint16_t usTableSize; + uint8_t ucNoBlocks; +}; + +struct combios_exttmds_block_header +{ + uint16_t usMaxFreq; + uint8_t ucI2CSlaveAddr; + uint8_t ucI2CLine; + uint8_t ucConnectorId; + uint8_t ucFlags; +}; + +/* Connector table - applicable from Piglet and later ASICs + byte 0 (embedded revision) + [7:4] = number of chips (valid number 1 - 15) + [3:0] = revision number of table (valid number 1 - 15) + + byte 1 (Chip info) + [7:4] = chip number, max. 15 (valid number 1 - 15) + [3:0] = number of connectors for that chip, (valid number 1 - 15) + (number of connectors = number of 'Connector info' entries + for that chip) + + byte 2,3 (Connector info) + [15:12] - connector type + = 0 - no connector + = 1 - proprietary + = 2 - CRT + = 3 - DVI-I + = 4 - DVI-D + = 5-15 - reserved for future expansion + [11:8] - DDC line pair used for that connector + = 0 - no DDC + = 1 - MONID 0/1 + = 2 - DVI_DDC + = 3 - VGA_DDC + = 4 - CRT2_DDC + = 5-15 - reserved for future expansion + [5] - bit indicating presence of multiplexer for TV,CRT2 + [7:6] - reserved for future expansion + [4] - TMDS type + = 0 - internal TMDS + = 1 - external TMDS + [3:1] - reserved for future expansion + [0] - DAC associated with that connector + = 0 - CRT DAC + = 1 - non-CRT DAC (e.g. TV DAC, external DAC ..) + + byte 4,5,6... - byte 4,5 can be another "Connector info" word + describing another connector + - or byte 5 is a "Chip info" byte for anther chip, + then start with byte 5,6 to describe connectors + for that chip + - or byte 5 = 0 if all connectors for all chips on + board have been described, no more connector left + to describe. +*/ +#define BIOS_CONNECTOR_INFO__TYPE__MASK 0xF000 +#define BIOS_CONNECTOR_INFO__TYPE__SHIFT 0x0000000C +#define BIOS_CONNECTOR_TYPE__NONE 0x00000000 +#define BIOS_CONNECTOR_TYPE__PROPRIETARY 0x00000001 +#define BIOS_CONNECTOR_TYPE__CRT 0x00000002 +#define BIOS_CONNECTOR_TYPE__DVI_I 0x00000003 +#define BIOS_CONNECTOR_TYPE__DVI_D 0x00000004 + +#define BIOS_CONNECTOR_INFO__DDC_LINE__MASK 0x0F00 +#define BIOS_CONNECTOR_INFO__DDC_LINE__SHIFT 0x00000008 +#define BIOS_DDC_LINE__NONE 0x00000000 +#define BIOS_DDC_LINE__MONID01 0x00000001 +#define BIOS_DDC_LINE__DVI 0x00000002 +#define BIOS_DDC_LINE__VGA 0x00000003 +#define BIOS_DDC_LINE__CRT2 0x00000004 +#define BIOS_DDC_LINE__GPIOPAD 0x00000005 +#define BIOS_DDC_LINE__ZV_LCDPAD 0x00000006 + +#define BIOS_CONNECTOR_INFO__TMDS_TYPE__MASK 0x0010 +#define BIOS_CONNECTOR_INFO__TMDS_TYPE__SHIFT 0x00000004 +#define BIOS_TMDS_TYPE__INTERNAL 0x00000000 +#define BIOS_TMDS_TYPE__EXTERNAL 0x00000001 + +#define BIOS_CONNECTOR_INFO__DAC_TYPE__MASK 0x0001 +#define BIOS_CONNECTOR_INFO__DAC_TYPE__SHIFT 0x00000000 +#define BIOS_DAC_TYPE__CRT 0x00000000 +#define BIOS_DAC_TYPE__NON_CRT 0x00000001 + +#define BIOS_CONNECTOR_INFO__MUX_MASK 0x00000020 +#define BIOS_CONNECTOR_INFO__MUX_SHIFT 0x00000005 + +#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__MASK 0xF0 +#define BIOS_CHIPINFO_HEADER__CHIP_NUMBER__SHIFT 0x00000004 + +#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__MASK 0x0F +#define BIOS_CHIPINFO_HEADER__NUMBER_OF_CONNECTORS__SHIFT 0x00000000 + +#define BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS 0x00000010 + +struct combios_connector_chip_info +{ + uint8_t ucChipHeader; + uint16_t sConnectorInfo[BIOS_CHIPINFO__MAX_NUMBER_OF_CONNECTORS]; +}; + +#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__MASK 0xF0 +#define BIOS_CONNECTOR_HEADER__NUMBER_OF_CHIPS__SHIFT 0x00000004 + +#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__MASK 0x0F +#define BIOS_CONNECTOR_HEADER__TABLE_REVISION__SHIFT 0x00000000 + +struct combios_connector_table +{ + uint8_t ucConnectorHeader; + struct combios_connector_chip_info sChipConnectorInfo[0x10]; +}; + +#pragma pack() + +int combios_parse(unsigned char *rom, struct combios_header *header); + +#endif diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index fe89e5e..0da5a5a 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -380,23 +380,26 @@ static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc) } /* compute PLL registers values for requested video mode */ -static int radeon_pll1_constraint(int clock, int rdiv, +static int radeon_pll1_constraint(struct drm_device *dev, + int clock, int rdiv, int fdiv, int pdiv, int rfrq, int pfrq) { - int dfrq; - - if (rdiv < 2 || fdiv < 4) { - return 0; - } - dfrq = rfrq / rdiv; - if (dfrq < 2000 || dfrq > 3300) { - return 0; - } - if (pfrq < 125000 || pfrq > 250000) { - return 0; - } - return 1; + struct drm_radeon_private *dev_priv = dev->dev_private; + int dfrq; + + if (rdiv < 2 || fdiv < 4) { + return 0; + } + dfrq = rfrq / rdiv; + if (dfrq < 2000 || dfrq > 3300) { + return 0; + } + if (pfrq < dev_priv->properties.pll_min_pll_freq || + pfrq > dev_priv->properties.pll_max_pll_freq) { + return 0; + } + return 1; } static void radeon_pll1_compute(struct drm_crtc *crtc, @@ -424,7 +427,7 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, struct drm_radeon_private *dev_priv = crtc->dev->dev_private; struct radeon_state *state = &dev_priv->driver_state; int clock = mode->clock; - int rfrq = dev_priv->properties->pll_reference_freq; + int rfrq = dev_priv->properties.pll_reference_freq; int pdiv = 1; int pdiv_id = 0; int rdiv_best = 2; @@ -441,11 +444,11 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, int diff_cpfrq = 350000; /* clamp frequency into pll [min; max] frequency range */ - if (clock > dev_priv->properties->pll_max_pll_freq) { - clock = dev_priv->properties->pll_max_pll_freq; + if (clock > dev_priv->properties.pll_max_pll_freq) { + clock = dev_priv->properties.pll_max_pll_freq; } - if ((clock * 12) < dev_priv->properties->pll_min_pll_freq) { - clock = dev_priv->properties->pll_min_pll_freq / 12; + if ((clock * 12) < dev_priv->properties.pll_min_pll_freq) { + clock = dev_priv->properties.pll_min_pll_freq / 12; } /* maximize pll_ref_div while staying in boundary and minimizing @@ -457,8 +460,8 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, tfrq = clock * post_div->divider; for (fdiv = 1023; fdiv >= 4; fdiv--) { rdiv = (fdiv * rfrq) / tfrq; - if (radeon_pll1_constraint(clock, rdiv, fdiv, - pdiv, rfrq, tfrq)) { + if (radeon_pll1_constraint(crtc->dev, clock, rdiv, + fdiv, pdiv, rfrq, tfrq)) { pfrq = (fdiv * rfrq) / rdiv; diff_cpfrq = pfrq - tfrq; if ((diff_cpfrq >= 0 && diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 8d0481e..91ca4a3 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -203,15 +203,35 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) radeon_ms_driver_unload(dev); return ret; } - ret = radeon_ms_outputs_from_properties(dev); - if (ret != 0) { + ret = radeon_ms_outputs_from_rom(dev); + if (ret < 0) { radeon_ms_driver_unload(dev); return ret; + } else if (!ret) { + ret = radeon_ms_outputs_from_properties(dev); + if (ret < 0) { + radeon_ms_driver_unload(dev); + return ret; + } else if (ret == 0) { + DRM_INFO("[radeon_ms] no outputs !\n"); + } + } else { + DRM_INFO("[radeon_ms] added %d outputs from rom.\n", ret); } - ret = radeon_ms_connectors_from_properties(dev); - if (ret != 0) { + ret = radeon_ms_connectors_from_rom(dev); + if (ret < 0) { radeon_ms_driver_unload(dev); return ret; + } else if (!ret) { + ret = radeon_ms_connectors_from_properties(dev); + if (ret < 0) { + radeon_ms_driver_unload(dev); + return ret; + } else if (!ret) { + DRM_INFO("[radeon_ms] no connectors !\n"); + } + } else { + DRM_INFO("[radeon_ms] added %d connectors from rom.\n", ret); } radeon_ms_outputs_save(dev, &dev_priv->load_state); drm_initial_config(dev, false); diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index 779595d..b70dca2 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -29,87 +29,6 @@ #include "drm.h" #include "radeon_ms.h" -static struct radeon_ms_output radeon_ms_dac1 = { - OUTPUT_DAC1, - NULL, - NULL, - radeon_ms_dac1_initialize, - radeon_ms_dac1_detect, - radeon_ms_dac1_dpms, - radeon_ms_dac1_get_modes, - radeon_ms_dac1_mode_fixup, - radeon_ms_dac1_mode_set, - radeon_ms_dac1_restore, - radeon_ms_dac1_save -}; - -static struct radeon_ms_output radeon_ms_dac2 = { - OUTPUT_DAC2, - NULL, - NULL, - radeon_ms_dac2_initialize, - radeon_ms_dac2_detect, - radeon_ms_dac2_dpms, - radeon_ms_dac2_get_modes, - radeon_ms_dac2_mode_fixup, - radeon_ms_dac2_mode_set, - radeon_ms_dac2_restore, - radeon_ms_dac2_save -}; - -static struct radeon_ms_connector radeon_ms_vga = { - NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1, - { - 0, -1, -1, -1, -1, -1, -1, -1 - }, - "VGA" -}; - -static struct radeon_ms_connector radeon_ms_dvi_i_2 = { - NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2, - { - 1, -1, -1, -1, -1, -1, -1, -1 - }, - "DVI-I" -}; - -static struct radeon_ms_properties properties[] = { - /* default only one VGA connector */ - { - 0, 0, 27000, 25000, 200000, 1, 1, 1, 1, - { - &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL, - NULL - }, - { - &radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL, - NULL - } - }, - { - 0x1043, 0x176, 27000, 25000, 200000, 1, 1, 1, 1, - { - &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, - NULL, NULL, NULL - }, - { - &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, - NULL, NULL, NULL - } - }, - { - 0x1002, 0x4150, 27000, 25000, 200000, 1, 1, 1, 1, - { - &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, - NULL, NULL, NULL - }, - { - &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL, - NULL, NULL, NULL - } - }, -}; - extern const uint32_t radeon_cp_microcode[]; extern const uint32_t r200_cp_microcode[]; extern const uint32_t r300_cp_microcode[]; @@ -159,7 +78,7 @@ static void r300_flush_cache(struct drm_device *dev) int radeon_ms_family_init(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; - int i; + int ret; dev_priv->microcode = radeon_cp_microcode; dev_priv->irq_emit = radeon_ms_irq_emit; @@ -213,17 +132,10 @@ int radeon_ms_family_init(struct drm_device *dev) DRM_ERROR("Unknown radeon bus type, aborting\n"); return -EINVAL; } - dev_priv->properties = NULL; - for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) { - if (dev->pdev->subsystem_vendor == properties[i].subvendor && - dev->pdev->subsystem_device == properties[i].subdevice) { - DRM_INFO("[radeon_ms] found properties for 0x%04X:0x%04X\n", - properties[i].subvendor, properties[i].subdevice); - dev_priv->properties = &properties[i]; - } - } - if (dev_priv->properties == NULL) { - dev_priv->properties = &properties[0]; + ret = radeon_ms_rom_init(dev); + if (ret) { + return ret; } - return 0; + ret = radeon_ms_properties_init(dev); + return ret; } diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c index 1801c49..f4468c1 100644 --- a/shared-core/radeon_ms_i2c.c +++ b/shared-core/radeon_ms_i2c.c @@ -66,6 +66,22 @@ static int get_clock(void *data) v = 0; } break; + case GPIO_MONID: + v = MMIO_R(GPIO_MONID); + if ((GPIO_MONID__GPIO_MONID_1_INPUT & v)) { + v = 1; + } else { + v = 0; + } + break; + case GPIO_CRT2_DDC: + v = MMIO_R(GPIO_CRT2_DDC); + if ((GPIO_CRT2_DDC__CRT2_DDC_CLK_INPUT & v)) { + v = 1; + } else { + v = 0; + } + break; default: v = 0; break; @@ -112,6 +128,22 @@ static int get_data(void *data) v = 0; } break; + case GPIO_MONID: + v = MMIO_R(GPIO_MONID); + if ((GPIO_MONID__GPIO_MONID_0_INPUT & v)) { + v = 1; + } else { + v = 0; + } + break; + case GPIO_CRT2_DDC: + v = MMIO_R(GPIO_CRT2_DDC); + if ((GPIO_CRT2_DDC__CRT2_DDC_DATA_INPUT & v)) { + v = 1; + } else { + v = 0; + } + break; default: v = 0; break; @@ -157,6 +189,18 @@ static void set_clock(void *i2c_priv, int clock) v |= GPIO_DDC2__DDC2_CLK_OUT_EN; } break; + case GPIO_MONID: + v &= ~GPIO_MONID__GPIO_MONID_1_OUT_EN; + if (!clock) { + v |= GPIO_MONID__GPIO_MONID_1_OUT_EN; + } + break; + case GPIO_CRT2_DDC: + v &= ~GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN; + if (!clock) { + v |= GPIO_CRT2_DDC__CRT2_DDC_CLK_OUT_EN; + } + break; default: return; } @@ -201,6 +245,18 @@ static void set_data(void *i2c_priv, int data) v |= GPIO_DDC2__DDC2_DATA_OUT_EN; } break; + case GPIO_MONID: + v &= ~GPIO_MONID__GPIO_MONID_0_OUT_EN; + if (!data) { + v |= GPIO_MONID__GPIO_MONID_0_OUT_EN; + } + break; + case GPIO_CRT2_DDC: + v &= ~GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN; + if (!data) { + v |= GPIO_CRT2_DDC__CRT2_DDC_DATA_OUT_EN; + } + break; default: return; } @@ -251,11 +307,12 @@ struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev, ret = i2c_bit_add_bus(&i2c->adapter); if(ret) { - DRM_INFO("[radeon_ms] failed to register I2C '%s' bus\n", - i2c->adapter.name); + DRM_INFO("[radeon_ms] failed to register I2C '%s' bus (0x%X)\n", + i2c->adapter.name, reg); goto out_free; } - DRM_INFO("[radeon_ms] registered I2C '%s' bus\n", i2c->adapter.name); + DRM_INFO("[radeon_ms] registered I2C '%s' bus (0x%X)\n", + i2c->adapter.name, reg); return i2c; out_free: diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 35e5c37..1880632 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -189,7 +189,7 @@ static void radeon_ms_output_cleanup(struct drm_output *output) output->driver_private = NULL; } -static const struct drm_output_funcs radeon_ms_output_funcs = { +const struct drm_output_funcs radeon_ms_output_funcs = { .dpms = radeon_ms_output_dpms, .save = NULL, .restore = NULL, @@ -233,11 +233,11 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_ms_connector *connector = NULL; struct drm_output *output = NULL; - int i = 0; + int i = 0, c = 0; radeon_ms_connectors_destroy(dev); for (i = 0; i < RADEON_MAX_CONNECTORS; i++) { - if (dev_priv->properties->connectors[i]) { + if (dev_priv->properties.connectors[i]) { connector = drm_alloc(sizeof(struct radeon_ms_connector), DRM_MEM_DRIVER); @@ -245,11 +245,11 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) radeon_ms_connectors_destroy(dev); return -ENOMEM; } - memcpy(connector, - dev_priv->properties->connectors[i], - sizeof(struct radeon_ms_connector)); - connector->i2c = radeon_ms_i2c_create(dev, - connector->i2c_reg, connector->name); + memcpy(connector, dev_priv->properties.connectors[i], + sizeof(struct radeon_ms_connector)); + connector->i2c = + radeon_ms_i2c_create(dev, connector->i2c_reg, + connector->name); if (connector->i2c == NULL) { radeon_ms_connectors_destroy(dev); return -ENOMEM; @@ -264,9 +264,20 @@ int radeon_ms_connectors_from_properties(struct drm_device *dev) connector->output = output; output->driver_private = connector; output->possible_crtcs = 0x3; - dev_priv->connectors[i] = connector; + dev_priv->connectors[c++] = connector; } } + return c; +} + +int radeon_ms_connectors_from_rom(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + + switch (dev_priv->rom.type) { + case ROM_COMBIOS: + return radeon_ms_connectors_from_combios(dev); + } return 0; } @@ -289,24 +300,37 @@ int radeon_ms_outputs_from_properties(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; int i = 0; + int c = 0; radeon_ms_outputs_destroy(dev); for (i = 0; i < RADEON_MAX_OUTPUTS; i++) { - if (dev_priv->properties->outputs[i]) { + if (dev_priv->properties.outputs[i]) { dev_priv->outputs[i] = drm_alloc(sizeof(struct radeon_ms_output), - DRM_MEM_DRIVER); + DRM_MEM_DRIVER); if (dev_priv->outputs[i] == NULL) { radeon_ms_outputs_destroy(dev); return -ENOMEM; } memcpy(dev_priv->outputs[i], - dev_priv->properties->outputs[i], - sizeof(struct radeon_ms_output)); + dev_priv->properties.outputs[i], + sizeof(struct radeon_ms_output)); dev_priv->outputs[i]->dev = dev; dev_priv->outputs[i]->initialize(dev_priv->outputs[i]); + c++; } } + return c; +} + +int radeon_ms_outputs_from_rom(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + + switch (dev_priv->rom.type) { + case ROM_COMBIOS: + return radeon_ms_outputs_from_combios(dev); + } return 0; } diff --git a/shared-core/radeon_ms_properties.c b/shared-core/radeon_ms_properties.c new file mode 100644 index 0000000..393f496 --- /dev/null +++ b/shared-core/radeon_ms_properties.c @@ -0,0 +1,121 @@ +/* + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + */ +/* + * Authors: + * Jerome Glisse <gl...@fr...> + */ +#include "drmP.h" +#include "drm.h" +#include "radeon_ms.h" + +struct radeon_ms_output radeon_ms_dac1 = { + OUTPUT_DAC1, + NULL, + NULL, + radeon_ms_dac1_initialize, + radeon_ms_dac1_detect, + radeon_ms_dac1_dpms, + radeon_ms_dac1_get_modes, + radeon_ms_dac1_mode_fixup, + radeon_ms_dac1_mode_set, + radeon_ms_dac1_restore, + radeon_ms_dac1_save +}; + +struct radeon_ms_output radeon_ms_dac2 = { + OUTPUT_DAC2, + NULL, + NULL, + radeon_ms_dac2_initialize, + radeon_ms_dac2_detect, + radeon_ms_dac2_dpms, + radeon_ms_dac2_get_modes, + radeon_ms_dac2_mode_fixup, + radeon_ms_dac2_mode_set, + radeon_ms_dac2_restore, + radeon_ms_dac2_save +}; + +struct radeon_ms_connector radeon_ms_vga = { + NULL, NULL, NULL, ConnectorVGA, MT_NONE, 0, GPIO_DDC1, + { + 0, -1, -1, -1, -1, -1, -1, -1 + } +}; + +struct radeon_ms_connector radeon_ms_dvi_i_2 = { + NULL, NULL, NULL, ConnectorDVII, MT_NONE, 0, GPIO_DDC2, + { + 1, -1, -1, -1, -1, -1, -1, -1 + } +}; + +struct radeon_ms_properties properties[] = { + /* default only one VGA connector */ + { + 0, 0, 27000, 12, 25000, 200000, 1, 1, 1, 1, + { + &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL, + NULL + }, + { + &radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL, + NULL + } + } +}; + +int radeon_ms_properties_init(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + int i, ret; + + for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) { + if (dev->pdev->subsystem_vendor == properties[i].subvendor && + dev->pdev->subsystem_device == properties[i].subdevice) { + DRM_INFO("[radeon_ms] found properties for " + "0x%04X:0x%04X\n", properties[i].subvendor, + properties[i].subdevice); + memcpy(&dev_priv->properties, &properties[i], + sizeof(struct radeon_ms_properties)); + } + } + if (dev_priv->properties.subvendor == 0) { + ret = radeon_ms_rom_get_properties(dev); + if (ret < 0) { + return ret; + } + if (!ret) { + memcpy(&dev_priv->properties, &properties[0], + sizeof(struct radeon_ms_properties)); + } else { + dev_priv->properties.pll_dummy_reads = 1; + dev_priv->properties.pll_delay = 1; + dev_priv->properties.pll_r300_errata = 1; + } + dev_priv->properties.subvendor = dev->pdev->subsystem_vendor; + dev_priv->properties.subdevice = dev->pdev->subsystem_device; + } + return 0; +} diff --git a/shared-core/radeon_ms_properties.h b/shared-core/radeon_ms_properties.h new file mode 100644 index 0000000..a02a84d --- /dev/null +++ b/shared-core/radeon_ms_properties.h @@ -0,0 +1,50 @@ +/* + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + */ +/* + * Authors: + * Jerome Glisse <gl...@fr...> + */ +#ifndef __RADEON_MS_PROPERTIES_H__ +#define __RADEON_MS_PROPERTIES_H__ + +#define RADEON_PAGE_SIZE 4096 +#define RADEON_MAX_CONNECTORS 8 +#define RADEON_MAX_OUTPUTS 8 + +struct radeon_ms_properties { + uint16_t subvendor; + uint16_t subdevice; + int16_t pll_reference_freq; + int16_t pll_reference_div; + int32_t pll_min_pll_freq; + int32_t pll_max_pll_freq; + char pll_use_bios; + char pll_dummy_reads; + char pll_delay; + char pll_r300_errata; + struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; + struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; +}; + +#endif diff --git a/shared-core/radeon_ms_reg.h b/shared-core/radeon_ms_reg.h index d450280..56963c6 100644 --- a/shared-core/radeon_ms_reg.h +++ b/shared-core/radeon_ms_reg.h @@ -827,6 +827,32 @@ #define GPIO_DDC2__SW_CAN_USE_DVI_I2C 0x00100000 #define GPIO_DDC2__SW_DONE_USING_DVI_I2C 0x00200000 #define GPIO_DDC2__HW_USING_DVI_I2C 0x00400000 +#define GPIO_DVI_DDC 0x00000064 +#d... [truncated message content] |
From: <ai...@ke...> - 2008-02-15 06:28:36
|
linux-core/drmP.h | 5 ++--- linux-core/drm_bufs.c | 1 + linux-core/drm_crtc.c | 8 +++++++- linux-core/drm_fops.c | 25 ++++++++++++++++--------- linux-core/drm_proc.c | 2 -- linux-core/drm_stub.c | 22 ++++++++++------------ linux-core/drm_sysfs.c | 2 ++ 7 files changed, 38 insertions(+), 27 deletions(-) New commits: commit 222092a1a810b67b014ad6881f0c028ec6563329 Author: Dave Airlie <ai...@re...> Date: Fri Feb 15 16:15:04 2008 +1000 various fixes from trying to get userspace started diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 3e1767c..031f8ba 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -318,6 +318,7 @@ static int drm_addmap_core(struct drm_device *dev, unsigned int offset, list->user_token = list->hash.key << PAGE_SHIFT; mutex_unlock(&dev->struct_mutex); + list->master = dev->primary->master; *maplist = list; return 0; } diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 55390a8..3a0dd9c 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1094,7 +1094,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, crtc->fb = fb; crtc->enabled = (new_mode != NULL); if (new_mode != NULL) { - DRM_DEBUG("attempting to set mode from userspace\n"); + DRM_DEBUG("attempting to set mode from userspace %p\n", crtc->fb); drm_mode_debug_printmodeline(dev, new_mode); if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x, crtc_info->y)) { @@ -1577,7 +1577,13 @@ int drm_mode_setcrtc(struct drm_device *dev, ret = -EINVAL; goto out; } + DRM_DEBUG("found fb %p for id %d\n", fb, crtc_req->fb_id); + } else { + DRM_DEBUG("Unknown FB ID %d\n", crtc_req->fb_id); + ret = -EINVAL; + goto out; } + mode = drm_mode_create(dev); drm_crtc_convert_umode(mode, &crtc_req->mode); diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 6ac09fb..5a74f42 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -268,9 +268,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp, goto out_free; } - mutex_lock(&dev->struct_mutex); /* if there is no current master make this fd it */ + mutex_lock(&dev->struct_mutex); if (!priv->minor->master) { priv->minor->master = drm_get_master(priv->minor); if (!priv->minor->master) { @@ -281,17 +281,22 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->is_master = 1; priv->master = priv->minor->master; + mutex_unlock(&dev->struct_mutex); if (dev->driver->master_create) { ret = dev->driver->master_create(dev, priv->master); if (ret) { drm_put_master(priv->minor->master); priv->minor->master = priv->master = NULL; + mutex_unlock(&dev->struct_mutex); goto out_free; } } - } - else + } else { priv->master = priv->minor->master; + mutex_unlock(&dev->struct_mutex); + } + + mutex_lock(&dev->struct_mutex); list_add(&priv->lhead, &dev->filelist); mutex_unlock(&dev->struct_mutex); @@ -477,6 +482,14 @@ int drm_release(struct inode *inode, struct file *filp) mutex_unlock(&dev->ctxlist_mutex); drm_fb_release(filp); + + file_priv->master = NULL; + + if (file_priv->is_master) { + drm_put_master(file_priv->minor->master); + file_priv->minor->master = NULL; + } + mutex_lock(&dev->struct_mutex); drm_object_release(filp); if (file_priv->remove_auth_on_close == 1) { @@ -487,12 +500,6 @@ int drm_release(struct inode *inode, struct file *filp) } list_del(&file_priv->lhead); - if (file_priv->is_master) { - drm_put_master(file_priv->minor->master); - file_priv->minor->master = NULL; - } - - file_priv->master = NULL; mutex_unlock(&dev->struct_mutex); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 801dab0..334c8f0 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -152,6 +152,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, INIT_LIST_HEAD(&dev->ctxlist); INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); + INIT_LIST_HEAD(&dev->filelist); spin_lock_init(&dev->count_lock); spin_lock_init(&dev->drw_lock); commit 75b01cf996f2efdd72c5280238460443d5d1fbc7 Author: Dave Airlie <ai...@re...> Date: Fri Feb 15 10:04:28 2008 +1000 switch naming to new proposed scheme diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 697dc9a..ab17ba0 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -762,8 +762,8 @@ struct drm_driver { #define DRM_MINOR_UNASSIGNED 0 #define DRM_MINOR_CONTROL 1 -#define DRM_MINOR_RENDER 2 -#define DRM_MINOR_GPGPU 3 /* this node is restricted to operations that don't require a master */ +#define DRM_MINOR_LEGACY 2 +#define DRM_MINOR_RENDER 3 /** * DRM minor structure. This structure represents a drm minor number. */ diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 2ccf6d9..e10501f 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -210,7 +210,6 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { struct drm_minor *minor = (struct drm_minor *) data; - struct drm_master *master = minor->master; struct drm_device *dev = minor->dev; int len = 0; struct drm_map *map; @@ -269,7 +268,6 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { struct drm_minor *minor = (struct drm_minor *) data; - struct drm_master *master = minor->master; struct drm_device *dev = minor->dev; int ret; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index d399258..801dab0 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -56,14 +56,14 @@ static int drm_minor_get_id(struct drm_device *dev, int type) { int new_id; int ret; - int base = 0, limit = 127; + int base = 0, limit = 63; if (type == DRM_MINOR_CONTROL) { + base += 64; + limit = base + 127; + } else if (type == DRM_MINOR_RENDER) { base += 128; - limit = base + 64; - } else if (type == DRM_MINOR_GPGPU) { - base += 192; - limit = base + 64; + limit = base + 255; } again: @@ -270,7 +270,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t idr_replace(&drm_minors_idr, new_minor, minor_id); - if (type == DRM_MINOR_RENDER) { + if (type == DRM_MINOR_LEGACY) { ret = drm_proc_init(new_minor, minor_id, drm_proc_root); if (ret) { DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); @@ -292,7 +292,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t err_g2: - if (new_minor->type == DRM_MINOR_RENDER) + if (new_minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(new_minor, drm_proc_root); err_mem: kfree(new_minor); @@ -345,7 +345,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) goto err_g3; - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_RENDER))) + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) goto err_g4; if (dev->driver->load) @@ -416,7 +416,7 @@ int drm_put_minor(struct drm_minor **minor_p) struct drm_minor *minor = *minor_p; DRM_DEBUG("release secondary minor %d\n", minor->index); - if (minor->type == DRM_MINOR_RENDER) + if (minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(minor, drm_proc_root); drm_sysfs_device_remove(minor); diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index cd03da8..f03e5d4 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -171,6 +171,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) minor->kdev.devt = minor->device; if (minor->type == DRM_MINOR_CONTROL) minor_str = "controlD%d"; + else if (minor->type == DRM_MINOR_RENDER) + minor_str = "renderD%d"; else minor_str = "card%d"; commit f2f8ace3e1342d83096bf392922130d39cd86ec2 Author: Dave Airlie <ai...@re...> Date: Fri Feb 15 09:57:30 2008 +1000 remove drm_minors_limit diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 81417f1..697dc9a 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1248,7 +1248,6 @@ extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, extern int drm_put_dev(struct drm_device *dev); extern int drm_put_minor(struct drm_minor **minor); extern unsigned int drm_debug; /* 1 to enable debug output */ -extern unsigned int drm_minors_limit; extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index ebb8fb9..d399258 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -37,17 +37,14 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_minors_limit = 16; /* Enough for one machine */ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(minors_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); -module_param_named(minors_limit, drm_minors_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); struct idr drm_minors_idr; |
From: <ai...@ke...> - 2008-02-22 04:04:24
|
libdrm/xf86drm.c | 15 +++++++++++++++ libdrm/xf86mm.h | 1 + linux-core/drm_bo.c | 37 +++++++++++++++++++++++++++++++++++++ linux-core/drm_crtc.c | 5 +++-- linux-core/drm_crtc.h | 2 +- linux-core/drm_drv.c | 2 ++ linux-core/drm_objects.h | 2 ++ shared-core/drm.h | 7 +++++++ 8 files changed, 68 insertions(+), 3 deletions(-) New commits: commit fad1db2d73f8dd95f17db10c7ea381c7774e3c29 Author: Dave Airlie <ai...@re...> Date: Thu Feb 21 15:58:56 2008 +1000 modesetting: fix memory leak and misallocation diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index ebd15c5..bf37730 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1092,7 +1092,8 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_output *output; int count = 0, ro; - save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL); + /* this is meant to be num_output not num_crtc */ + save_crtcs = kzalloc(dev->mode_config.num_output * sizeof(struct drm_crtc *), GFP_KERNEL); if (!save_crtcs) return -ENOMEM; @@ -1663,10 +1664,10 @@ int drm_mode_setcrtc(struct drm_device *dev, } } - /* What happens to output_set, leak? */ ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb); out: + kfree(output_set); mutex_unlock(&dev->mode_config.mutex); return ret; } commit cdad850ebc3570e5ff5a0996f36832c965aa8a1d Author: Dave Airlie <ai...@re...> Date: Wed Feb 20 13:27:10 2008 +1000 add ioctl to get back memory managed area sized - used for kernel inited areas diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 39a849c..13e9955 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2883,6 +2883,21 @@ int drmMMUnlock(int fd, unsigned memType, int unlockBM) return drmIoctlTimeout(fd, DRM_IOCTL_MM_UNLOCK, &arg); } +int drmMMInfo(int fd, unsigned memType, uint64_t *size) +{ + struct drm_mm_info_arg arg; + + memset(&arg, 0, sizeof(arg)); + + arg.mem_type = memType; + + if (ioctl(fd, DRM_IOCTL_MM_INFO, &arg)) + return -errno; + + *size = arg.p_size; + return 0; +} + int drmBOVersion(int fd, unsigned int *major, unsigned int *minor, unsigned int *patchlevel) diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index c80288a..bb57340 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -172,6 +172,7 @@ extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize, extern int drmMMTakedown(int fd, unsigned memType); extern int drmMMLock(int fd, unsigned memType, int lockBM, int ignoreNoEvict); extern int drmMMUnlock(int fd, unsigned memType, int unlockBM); +extern int drmMMInfo(int fd, unsigned memType, uint64_t *size); extern int drmBOSetStatus(int fd, drmBO *buf, uint64_t flags, uint64_t mask, unsigned int hint, diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 54b8baf..ebba2fa 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2289,6 +2289,7 @@ int drm_bo_init_mm(struct drm_device *dev, unsigned type, man->has_type = 1; man->use_type = 1; man->kern_init_type = kern_init; + man->size = p_size; INIT_LIST_HEAD(&man->lru); INIT_LIST_HEAD(&man->pinned); @@ -2562,6 +2563,42 @@ int drm_mm_unlock_ioctl(struct drm_device *dev, return 0; } +int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_mm_info_arg *arg = data; + struct drm_buffer_manager *bm = &dev->bm; + struct drm_bo_driver *driver = dev->driver->bo_driver; + struct drm_mem_type_manager *man; + int ret = 0; + int mem_type = arg->mem_type; + + if (!driver) { + DRM_ERROR("Buffer objects are not supported by this driver\n"); + return -EINVAL; + } + + if (mem_type >= DRM_BO_MEM_TYPES) { + DRM_ERROR("Illegal memory type %d\n", arg->mem_type); + return -EINVAL; + } + + mutex_lock(&dev->struct_mutex); + if (!bm->initialized) { + DRM_ERROR("DRM memory manager was not initialized\n"); + ret = -EINVAL; + goto out; + } + + + man = &bm->man[arg->mem_type]; + + arg->p_size = man->size; + +out: + mutex_unlock(&dev->struct_mutex); + + return ret; +} /* * buffer object vm functions. */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 4f5b364..4932ea5 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -164,6 +164,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0), + + DRM_IOCTL_DEF(DRM_IOCTL_MM_INFO, drm_mm_info_ioctl, 0), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 71da4b2..cce5817 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -525,6 +525,7 @@ struct drm_mem_type_manager { unsigned long io_offset; unsigned long io_size; void *io_addr; + uint64_t size; /* size of managed area for reporting to userspace */ }; struct drm_bo_lock { @@ -651,6 +652,7 @@ extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_driver_finish(struct drm_device *dev); extern int drm_bo_driver_init(struct drm_device *dev); diff --git a/shared-core/drm.h b/shared-core/drm.h index 0d7cfd2..cbe83fd 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -950,6 +950,12 @@ struct drm_mm_init_arg { uint64_t p_size; }; +struct drm_mm_info_arg { + unsigned int mem_type; + uint64_t p_size; +}; + + /* * Drm mode setting */ @@ -1209,6 +1215,7 @@ struct drm_mode_hotplug { #define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg) #define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg) #define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) +#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) #define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) commit 0d1cb1e8408d497fec66d9f31603f93800049c75 Author: Dave Airlie <ai...@re...> Date: Wed Feb 20 13:26:40 2008 +1000 hopefully shit works now without this... diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 3097057..d733d8c 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -479,7 +479,7 @@ struct drm_output { struct drm_display_info *monitor_info; /* if any */ const struct drm_output_funcs *funcs; void *driver_private; - uint32_t make_shit_work; + struct list_head user_modes; struct drm_property_blob *edid_blob_ptr; u32 property_ids[DRM_OUTPUT_MAX_PROPERTY]; |
From: <ai...@ke...> - 2008-03-05 17:09:13
|
linux-core/drmP.h | 5 +++-- linux-core/drm_bo.c | 3 ++- linux-core/drm_objects.h | 2 +- linux-core/drm_stub.c | 4 ++++ shared-core/i915_dma.c | 7 +++++++ 5 files changed, 17 insertions(+), 4 deletions(-) New commits: commit e00dea812ddb9b483de9f58f7a7aa7105427512d Merge: f78cdac... 1257459... Author: Dave Airlie <ai...@li...> Date: Thu Mar 6 05:26:23 2008 +1000 Merge branch 'master' of ../../drm into modesetting-101 Conflicts: linux-core/drmP.h linux-core/drm_drv.c linux-core/drm_proc.c linux-core/drm_stub.c linux-core/drm_sysfs.c diff --cc linux-core/drmP.h index 1a0a565,1fea807..4797485 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@@ -761,9 -721,8 +761,10 @@@ struct drm_driver }; #define DRM_MINOR_UNASSIGNED 0 - #define DRM_MINOR_CONTROL 1 - #define DRM_MINOR_LEGACY 2 + #define DRM_MINOR_LEGACY 1 ++#define DRM_MINOR_CONTROL 2 +#define DRM_MINOR_RENDER 3 + /** * DRM minor structure. This structure represents a drm minor number. */ diff --cc linux-core/drm_stub.c index 6856075,6584f51..ba13e5e --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@@ -344,17 -285,13 +344,21 @@@ int drm_get_dev(struct pci_dev *pdev, c } /* only add the control node on a modesetting platform */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) + goto err_g3; + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - goto err_g3; + goto err_g4; + + if (dev->driver->load) + if ((ret = dev->driver->load(dev, ent->driver_data))) + goto err_g5; + if (dev->driver->load) + if ((ret = dev->driver->load(dev, ent->driver_data))) + goto err_g4; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary->index); commit 12574590cdf7871755d1939463ca6898251fd0d1 Author: Dave Airlie <ai...@li...> Date: Thu Mar 6 05:21:50 2008 +1000 drm: reorganise minor number handling using code from modesetting branch Rip out the whole head thing and replace it with an idr and drm_minor structure. diff --git a/linux-core/drmP.h b/linux-core/drmP.h index f196e11..1fea807 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -408,13 +408,12 @@ enum drm_ref_type { struct drm_file { int authenticated; int master; - int minor; pid_t pid; uid_t uid; drm_magic_t magic; unsigned long ioctl_count; struct list_head lhead; - struct drm_head *head; + struct drm_minor *minor; int remove_auth_on_close; unsigned long lock_count; @@ -721,16 +720,19 @@ struct drm_driver { struct pci_driver pci_driver; }; +#define DRM_MINOR_UNASSIGNED 0 +#define DRM_MINOR_LEGACY 1 + /** - * DRM head structure. This structure represent a video head on a card - * that may contain multiple heads. Embed one per head of these in the - * private drm_device structure. + * DRM minor structure. This structure represents a drm minor number. */ -struct drm_head { - int minor; /**< Minor device number */ +struct drm_minor { + int index; /**< Minor device number */ + int type; /**< Control or render */ + dev_t device; /**< Device number for mknod */ + struct device kdev; /**< Linux device */ struct drm_device *dev; struct proc_dir_entry *dev_root; /**< proc directory entry */ - dev_t device; /**< Device number for mknod */ struct class_device *dev_class; }; @@ -740,7 +742,6 @@ struct drm_head { * may contain multiple heads. */ struct drm_device { - struct device dev; /**< Linux device */ char *unique; /**< Unique identifier: e.g., busid */ int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ @@ -870,7 +871,7 @@ struct drm_device { struct drm_driver *driver; drm_local_map_t *agp_buffer_map; unsigned int agp_buffer_token; - struct drm_head primary; /**< primary screen head */ + struct drm_minor *primary; /**< render type primary screen head */ struct drm_fence_manager fm; struct drm_buffer_manager bm; @@ -1187,23 +1188,20 @@ extern void drm_agp_chipset_flush(struct drm_device *dev); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); -extern int drm_put_head(struct drm_head * head); +extern int drm_put_minor(struct drm_minor **minor); extern unsigned int drm_debug; /* 1 to enable debug output */ -extern unsigned int drm_cards_limit; -extern struct drm_head **drm_heads; + extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; +extern struct idr drm_minors_idr; + extern drm_local_map_t *drm_getsarea(struct drm_device *dev); /* Proc support (drm_proc.h) */ -extern int drm_proc_init(struct drm_device *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int drm_proc_cleanup(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); +int drm_proc_init(struct drm_minor *minor, int minor_id, + struct proc_dir_entry *root); +int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); /* Scatter Gather Support (drm_scatter.h) */ extern void drm_sg_cleanup(struct drm_sg_mem * entry); @@ -1226,8 +1224,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah); struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(void); -extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); -extern void drm_sysfs_device_remove(struct drm_device *dev); +extern int drm_sysfs_device_add(struct drm_minor *minor); +extern void drm_sysfs_device_remove(struct drm_minor *minor); /* * Basic memory manager support (drm_mm.c) diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index f58d551..0aa94a7 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -130,7 +130,7 @@ EXPORT_SYMBOL(drm_agp_acquire); int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - return drm_agp_acquire((struct drm_device *) file_priv->head->dev); + return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); } /** diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 17180d8..95802fe 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1190,7 +1190,7 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep) { struct drm_buffer_object *bo; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int ret = 0; int no_wait = hint & DRM_BO_HINT_DONT_BLOCK; @@ -1262,7 +1262,7 @@ out: static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; struct drm_ref_object *ro; int ret = 0; @@ -1654,7 +1654,7 @@ int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep, struct drm_buffer_object **bo_rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; int ret; @@ -1690,7 +1690,7 @@ EXPORT_SYMBOL(drm_bo_handle_validate); static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle, struct drm_bo_info_rep *rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; mutex_lock(&dev->struct_mutex); @@ -1713,7 +1713,7 @@ static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle, uint32_t hint, struct drm_bo_info_rep *rep) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_buffer_object *bo; int no_wait = hint & DRM_BO_HINT_DONT_BLOCK; int ret; @@ -1833,7 +1833,7 @@ EXPORT_SYMBOL(drm_buffer_object_create); static int drm_bo_add_user_object(struct drm_file *file_priv, struct drm_buffer_object *bo, int shareable) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -1881,7 +1881,7 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil if (bo_type == drm_bo_type_user) req->flags &= ~DRM_BO_FLAG_SHAREABLE; - ret = drm_buffer_object_create(file_priv->head->dev, + ret = drm_buffer_object_create(file_priv->minor->dev, req->size, bo_type, req->flags, req->hint, req->page_alignment, req->buffer_start, &entry); diff --git a/linux-core/drm_bo_lock.c b/linux-core/drm_bo_lock.c index f967fb7..2795384 100644 --- a/linux-core/drm_bo_lock.c +++ b/linux-core/drm_bo_lock.c @@ -141,7 +141,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv) * while holding it. */ - dev = file_priv->head->dev; + dev = file_priv->minor->dev; mutex_lock(&dev->struct_mutex); ret = drm_add_user_object(file_priv, &lock->base, 0); lock->base.remove = &drm_bo_write_lock_remove; @@ -156,7 +156,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv) int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_ref_object *ro; mutex_lock(&dev->struct_mutex); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 3c2794d..1daa865 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -416,35 +416,35 @@ static void drm_cleanup(struct drm_device * dev) drm_mm_takedown(&dev->offset_manager); drm_ht_remove(&dev->object_hash); - drm_put_head(&dev->primary); + drm_put_minor(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); } -void drm_exit(struct drm_driver *driver) +int drm_minors_cleanup(int id, void *ptr, void *data) { - int i; - struct drm_device *dev = NULL; - struct drm_head *head; + struct drm_minor *minor = ptr; + struct drm_device *dev; + struct drm_driver *driver = data; + + dev = minor->dev; + if (minor->dev->driver != driver) + return 0; + + if (minor->type != DRM_MINOR_LEGACY) + return 0; + if (dev) + pci_dev_put(dev->pdev); + drm_cleanup(dev); + return 1; +} + +void drm_exit(struct drm_driver *driver) +{ DRM_DEBUG("\n"); if (drm_fb_loaded) { - for (i = 0; i < drm_cards_limit; i++) { - head = drm_heads[i]; - if (!head) - continue; - if (!head->dev) - continue; - if (head->dev->driver != driver) - continue; - dev = head->dev; - if (dev) { - /* release the pci driver */ - if (dev->pdev) - pci_dev_put(dev->pdev); - drm_cleanup(dev); - } - } + idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); } else pci_unregister_driver(&driver->pci_driver); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) @@ -467,6 +467,7 @@ static int __init drm_core_init(void) unsigned long avail_memctl_mem; unsigned long max_memctl_mem; + idr_init(&drm_minors_idr); si_meminfo(&si); /* @@ -488,11 +489,6 @@ static int __init drm_core_init(void) drm_init_memctl(avail_memctl_mem/2, avail_memctl_mem*3/4, si.mem_unit); ret = -ENOMEM; - drm_cards_limit = - (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); - drm_heads = drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); - if (!drm_heads) - goto err_p1; if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) goto err_p1; @@ -521,7 +517,8 @@ err_p3: drm_sysfs_destroy(); err_p2: unregister_chrdev(DRM_MAJOR, "drm"); - drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); + + idr_destroy(&drm_minors_idr); err_p1: return ret; } @@ -533,7 +530,7 @@ static void __exit drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); - drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); + idr_destroy(&drm_minors_idr); } module_init(drm_core_init); @@ -593,7 +590,7 @@ EXPORT_SYMBOL(drm_ioctl); long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct drm_ioctl_desc *ioctl; drm_ioctl_t *func; unsigned int nr = DRM_IOCTL_NR(cmd); @@ -605,7 +602,7 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++file_priv->ioctl_count; DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - current->pid, cmd, nr, (long)old_encode_dev(file_priv->head->device), + current->pid, cmd, nr, (long)old_encode_dev(file_priv->minor->device), file_priv->authenticated); if ((nr >= DRM_CORE_IOCTL_COUNT) && diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index 247bc0a..9d80327 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -494,7 +494,7 @@ static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class, int drm_fence_add_user_object(struct drm_file *priv, struct drm_fence_object *fence, int shareable) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -590,7 +590,7 @@ void drm_fence_manager_takedown(struct drm_device *dev) struct drm_fence_object *drm_lookup_fence_object(struct drm_file *priv, uint32_t handle) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_fence_object *fence; diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 0e1c486..7fe274a 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -128,16 +128,15 @@ static int drm_setup(struct drm_device * dev) int drm_open(struct inode *inode, struct file *filp) { struct drm_device *dev = NULL; - int minor = iminor(inode); + int minor_id = iminor(inode); + struct drm_minor *minor; int retcode = 0; - if (!((minor >= 0) && (minor < drm_cards_limit))) + minor = idr_find(&drm_minors_idr, minor_id); + if (!minor) return -ENODEV; - if (!drm_heads[minor]) - return -ENODEV; - - if (!(dev = drm_heads[minor]->dev)) + if (!(dev = minor->dev)) return -ENODEV; retcode = drm_open_helper(inode, filp, dev); @@ -176,19 +175,18 @@ EXPORT_SYMBOL(drm_open); int drm_stub_open(struct inode *inode, struct file *filp) { struct drm_device *dev = NULL; - int minor = iminor(inode); + struct drm_minor *minor; + int minor_id = iminor(inode); int err = -ENODEV; const struct file_operations *old_fops; DRM_DEBUG("\n"); - if (!((minor >= 0) && (minor < drm_cards_limit))) + minor = idr_find(&drm_minors_idr, minor_id); + if (!minor) return -ENODEV; - - if (!drm_heads[minor]) - return -ENODEV; - - if (!(dev = drm_heads[minor]->dev)) + + if (!(dev = minor->dev)) return -ENODEV; old_fops = filp->f_op; @@ -233,7 +231,7 @@ static int drm_cpu_valid(void) static int drm_open_helper(struct inode *inode, struct file *filp, struct drm_device * dev) { - int minor = iminor(inode); + int minor_id = iminor(inode); struct drm_file *priv; int ret; int i, j; @@ -243,7 +241,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, if (!drm_cpu_valid()) return -EINVAL; - DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); + DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor_id); priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); if (!priv) @@ -254,8 +252,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->filp = filp; priv->uid = current->euid; priv->pid = current->pid; - priv->minor = minor; - priv->head = drm_heads[minor]; + priv->minor = idr_find(&drm_minors_idr, minor_id); priv->ioctl_count = 0; /* for compatibility root is always authenticated */ priv->authenticated = capable(CAP_SYS_ADMIN); @@ -320,11 +317,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, int drm_fasync(int fd, struct file *filp, int on) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int retcode; DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, - (long)old_encode_dev(priv->head->device)); + (long)old_encode_dev(priv->minor->device)); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; @@ -374,7 +371,7 @@ static void drm_object_release(struct file *filp) int drm_release(struct inode *inode, struct file *filp) { struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int retcode = 0; lock_kernel(); @@ -389,7 +386,7 @@ int drm_release(struct inode *inode, struct file *filp) */ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - current->pid, (long)old_encode_dev(file_priv->head->device), + current->pid, (long)old_encode_dev(file_priv->minor->device), dev->open_count); if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c index 7d2e3a2..2994b71 100644 --- a/linux-core/drm_object.c +++ b/linux-core/drm_object.c @@ -33,7 +33,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item, int shareable) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; DRM_ASSERT_LOCKED(&dev->struct_mutex); @@ -58,7 +58,7 @@ EXPORT_SYMBOL(drm_add_user_object); struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_hash_item *hash; int ret; struct drm_user_object *item; @@ -85,7 +85,7 @@ EXPORT_SYMBOL(drm_lookup_user_object); static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; if (atomic_dec_and_test(&item->refcount)) { @@ -121,7 +121,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced struct drm_ref_object *item; struct drm_open_hash *ht = &priv->refd_object_hash[ref_action]; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); if (!referenced_object->shareable && priv != referenced_object->owner) { DRM_ERROR("Not allowed to reference this object\n"); return -EINVAL; @@ -178,7 +178,7 @@ struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv, struct drm_hash_item *hash; int ret; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); ret = drm_ht_find_item(&priv->refd_object_hash[ref_action], (unsigned long)referenced_object, &hash); if (ret) @@ -212,7 +212,7 @@ void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item) struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; enum drm_ref_type unref_action; - DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); + DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex); unref_action = item->unref_action; if (atomic_dec_and_test(&item->refcount)) { ret = drm_ht_remove_item(ht, &item->hash); @@ -239,7 +239,7 @@ EXPORT_SYMBOL(drm_remove_ref_object); int drm_user_object_ref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type, struct drm_user_object **object) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_hash_item *hash; int ret; @@ -269,7 +269,7 @@ out_err: int drm_user_object_unref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type) { - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_user_object *uo; struct drm_ref_object *ro; int ret; diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 3012c5b..67afee8 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -90,34 +90,35 @@ static struct drm_proc_list { * "/proc/dri/%minor%/", and each entry in proc_list as * "/proc/dri/%minor%/%name%". */ -int drm_proc_init(struct drm_device * dev, int minor, - struct proc_dir_entry *root, struct proc_dir_entry **dev_root) +int drm_proc_init(struct drm_minor *minor, int minor_id, + struct proc_dir_entry *root) { struct proc_dir_entry *ent; int i, j; char name[64]; - sprintf(name, "%d", minor); - *dev_root = proc_mkdir(name, root); - if (!*dev_root) { + sprintf(name, "%d", minor_id); + minor->dev_root = proc_mkdir(name, root); + if (!minor->dev_root) { DRM_ERROR("Cannot create /proc/dri/%s\n", name); return -1; } for (i = 0; i < DRM_PROC_ENTRIES; i++) { ent = create_proc_entry(drm_proc_list[i].name, - S_IFREG | S_IRUGO, *dev_root); + S_IFREG | S_IRUGO, minor->dev_root); if (!ent) { DRM_ERROR("Cannot create /proc/dri/%s/%s\n", name, drm_proc_list[i].name); for (j = 0; j < i; j++) remove_proc_entry(drm_proc_list[i].name, - *dev_root); + minor->dev_root); remove_proc_entry(name, root); + minor->dev_root = NULL; return -1; } ent->read_proc = drm_proc_list[i].f; - ent->data = dev; + ent->data = minor; } return 0; } @@ -132,18 +133,17 @@ int drm_proc_init(struct drm_device * dev, int minor, * * Remove all proc entries created by proc_init(). */ -int drm_proc_cleanup(int minor, struct proc_dir_entry *root, - struct proc_dir_entry *dev_root) +int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) { int i; char name[64]; - if (!root || !dev_root) + if (!root || !minor->dev_root) return 0; for (i = 0; i < DRM_PROC_ENTRIES; i++) - remove_proc_entry(drm_proc_list[i].name, dev_root); - sprintf(name, "%d", minor); + remove_proc_entry(drm_proc_list[i].name, minor->dev_root); + sprintf(name, "%d", minor->index); remove_proc_entry(name, root); return 0; @@ -165,7 +165,8 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root, static int drm_name_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; if (offset > DRM_PROC_LIMIT) { @@ -207,7 +208,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, static int drm__vm_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; struct drm_map *map; struct drm_map_list *r_list; @@ -264,7 +266,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, static int drm_vm_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -287,7 +290,8 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, static int drm__queues_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; int i; struct drm_queue *q; @@ -337,7 +341,8 @@ static int drm__queues_info(char *buf, char **start, off_t offset, static int drm_queues_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -360,7 +365,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, static int drm__bufs_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; struct drm_device_dma *dma = dev->dma; int i; @@ -409,7 +415,8 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, static int drm_bufs_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -432,7 +439,8 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, static int drm__objects_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; struct drm_buffer_manager *bm = &dev->bm; struct drm_fence_manager *fm = &dev->fm; @@ -496,7 +504,8 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request, static int drm_objects_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -519,7 +528,8 @@ static int drm_objects_info(char *buf, char **start, off_t offset, int request, static int drm__clients_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; struct drm_file *priv; @@ -535,7 +545,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, list_for_each_entry(priv, &dev->filelist, lhead) { DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", priv->authenticated ? 'y' : 'n', - priv->minor, + priv->minor->index, priv->pid, priv->uid, priv->magic, priv->ioctl_count); } @@ -552,7 +562,8 @@ static int drm__clients_info(char *buf, char **start, off_t offset, static int drm_clients_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); @@ -566,7 +577,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset, static int drm__vma_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int len = 0; struct drm_vma_entry *pt; struct vm_area_struct *vma; @@ -625,7 +637,8 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, static int drm_vma_info(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - struct drm_device *dev = (struct drm_device *) data; + struct drm_minor *minor = (struct drm_minor *) data; + struct drm_device *dev = minor->dev; int ret; mutex_lock(&dev->struct_mutex); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 00a2452..6584f51 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -37,23 +37,49 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_cards_limit = 16; /* Enough for one machine */ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); -module_param_named(cards_limit, drm_cards_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); -struct drm_head **drm_heads; +struct idr drm_minors_idr; + struct class *drm_class; struct proc_dir_entry *drm_proc_root; +static int drm_minor_get_id(struct drm_device *dev, int type) +{ + int new_id; + int ret; + int base = 0, limit = 63; + +again: + if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { + DRM_ERROR("Out of memory expanding drawable idr\n"); + return -ENOMEM; + } + mutex_lock(&dev->struct_mutex); + ret = idr_get_new_above(&drm_minors_idr, NULL, + base, &new_id); + mutex_unlock(&dev->struct_mutex); + if (ret == -EAGAIN) { + goto again; + } else if (ret) { + return ret; + } + + if (new_id >= limit) { + idr_remove(&drm_minors_idr, new_id); + return -EINVAL; + } + return new_id; +} + static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) @@ -161,49 +187,60 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(struct drm_device * dev, struct drm_head * head) +static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) { - struct drm_head **heads = drm_heads; + struct drm_minor *new_minor; int ret; - int minor; + int minor_id; DRM_DEBUG("\n"); - for (minor = 0; minor < drm_cards_limit; minor++, heads++) { - if (!*heads) { - - *head = (struct drm_head) { - .dev = dev, - .device = MKDEV(DRM_MAJOR, minor), - .minor = minor, - }; - if ((ret = - drm_proc_init(dev, minor, drm_proc_root, - &head->dev_root))) { - printk(KERN_ERR - "DRM: Failed to initialize /proc/dri.\n"); - goto err_g1; - } - - ret = drm_sysfs_device_add(dev, head); - if (ret) { - printk(KERN_ERR - "DRM: Error sysfs_device_add.\n"); - goto err_g2; - } - *heads = head; - - DRM_DEBUG("new minor assigned %d\n", minor); - return 0; + minor_id = drm_minor_get_id(dev, type); + if (minor_id < 0) + return minor_id; + + new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); + if (!new_minor) { + ret = -ENOMEM; + goto err_idr; + } + + new_minor->type = type; + new_minor->device = MKDEV(DRM_MAJOR, minor_id); + new_minor->dev = dev; + new_minor->index = minor_id; + + idr_replace(&drm_minors_idr, new_minor, minor_id); + + if (type == DRM_MINOR_LEGACY) { + ret = drm_proc_init(new_minor, minor_id, drm_proc_root); + if (ret) { + DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); + goto err_mem; } + } else + new_minor->dev_root = NULL; + + ret = drm_sysfs_device_add(new_minor); + if (ret) { + printk(KERN_ERR + "DRM: Error sysfs_device_add.\n"); + goto err_g2; } - DRM_ERROR("out of minors\n"); - return -ENOMEM; + *minor = new_minor; + + DRM_DEBUG("new minor assigned %d\n", minor_id); + return 0; + + err_g2: - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); -err_g1: - *head = (struct drm_head) { - .dev = NULL}; + if (new_minor->type == DRM_MINOR_LEGACY) + drm_proc_cleanup(new_minor, drm_proc_root); +err_mem: + kfree(new_minor); +err_idr: + idr_remove(&drm_minors_idr, minor_id); + *minor = NULL; return ret; } @@ -246,22 +283,29 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, printk(KERN_ERR "DRM: fill_in_dev failed\n"); goto err_g3; } - if ((ret = drm_get_head(dev, &dev->primary))) + + /* only add the control node on a modesetting platform */ + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) goto err_g3; + if (dev->driver->load) + if ((ret = dev->driver->load(dev, ent->driver_data))) + goto err_g4; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary.minor); + driver->date, dev->primary->index); return 0; - - err_g3: +err_g4: + drm_put_minor(&dev->primary); +err_g3: if (!drm_fb_loaded) pci_disable_device(pdev); - err_g2: +err_g2: if (!drm_fb_loaded) pci_release_regions(pdev); - err_g1: +err_g1: if (!drm_fb_loaded) pci_set_drvdata(pdev, NULL); @@ -310,17 +354,18 @@ int drm_put_dev(struct drm_device * dev) * last minor released. * */ -int drm_put_head(struct drm_head * head) +int drm_put_minor(struct drm_minor **minor_p) { - int minor = head->minor; - - DRM_DEBUG("release secondary minor %d\n", minor); + struct drm_minor *minor = *minor_p; + DRM_DEBUG("release secondary minor %d\n", minor->index); - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(head->dev); + if (minor->type == DRM_MINOR_LEGACY) + drm_proc_cleanup(minor, drm_proc_root); + drm_sysfs_device_remove(minor); - *head = (struct drm_head) {.dev = NULL}; + idr_remove(&drm_minors_idr, minor->index); - drm_heads[minor] = NULL; + kfree(minor); + *minor_p = NULL; return 0; } diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index c02e204..3275942 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -19,7 +19,7 @@ #include "drm_core.h" #include "drmP.h" -#define to_drm_device(d) container_of(d, struct drm_device, dev) +#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) /** * drm_sysfs_suspend - DRM class suspend hook @@ -31,7 +31,8 @@ */ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) { - struct drm_device *drm_dev = to_drm_device(dev); + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; printk(KERN_ERR "%s\n", __FUNCTION__); @@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) */ static int drm_sysfs_resume(struct device *dev) { - struct drm_device *drm_dev = to_drm_device(dev); + struct drm_minor *drm_minor = to_drm_minor(dev); + struct drm_device *drm_dev = drm_minor->dev; if (drm_dev->driver->resume) return drm_dev->driver->resume(drm_dev); @@ -122,10 +124,11 @@ void drm_sysfs_destroy(void) static ssize_t show_dri(struct device *device, struct device_attribute *attr, char *buf) { - struct drm_device *dev = to_drm_device(device); - if (dev->driver->dri_library_name) - return dev->driver->dri_library_name(dev, buf); - return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); + struct drm_minor *drm_minor = to_drm_minor(device); + struct drm_device *drm_dev = drm_minor->dev; + if (drm_dev->driver->dri_library_name) + return drm_dev->driver->dri_library_name(drm_dev, buf); + return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); } static struct device_attribute device_attrs[] = { @@ -154,25 +157,28 @@ static void drm_sysfs_device_release(struct device *dev) * as the parent for the Linux device, and make sure it has a file containing * the driver we're using (for userspace compatibility). */ -int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) +int drm_sysfs_device_add(struct drm_minor *minor) { int err; int i, j; + char *minor_str; - dev->dev.parent = &dev->pdev->dev; - dev->dev.class = drm_class; - dev->dev.release = drm_sysfs_device_release; - dev->dev.devt = head->device; - snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); + minor->kdev.parent = &minor->dev->pdev->dev; + minor->kdev.class = drm_class; + minor->kdev.release = drm_sysfs_device_release; + minor->kdev.devt = minor->device; + minor_str = "card%d"; + + snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index); - err = device_register(&dev->dev); + err = device_register(&minor->kdev); if (err) { DRM_ERROR("device add failed: %d\n", err); goto err_out; } for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(&dev->dev, &device_attrs[i]); + err = device_create_file(&minor->kdev, &device_attrs[i]); if (err) goto err_out_files; } @@ -182,8 +188,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) err_out_files: if (i > 0) for (j = 0; j < i; j++) - device_remove_file(&dev->dev, &device_attrs[i]); - device_unregister(&dev->dev); + device_remove_file(&minor->kdev, &device_attrs[i]); + device_unregister(&minor->kdev); err_out: return err; @@ -196,11 +202,11 @@ err_out: * This call unregisters and cleans up a class device that was created with a * call to drm_sysfs_device_add() */ -void drm_sysfs_device_remove(struct drm_device *dev) +void drm_sysfs_device_remove(struct drm_minor *minor) { int i; for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(&dev->dev, &device_attrs[i]); - device_unregister(&dev->dev); + device_remove_file(&minor->kdev, &device_attrs[i]); + device_unregister(&minor->kdev); } diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index c481a53..15e1c0f 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -86,7 +86,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, unsigned long address) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_map *map = NULL; struct drm_map_list *r_list; struct drm_hash_item *hash; @@ -204,7 +204,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, static void drm_vm_shm_close(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; struct drm_map *map; struct drm_map_list *r_list; @@ -286,7 +286,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, unsigned long address) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_device_dma *dma = dev->dma; unsigned long offset; unsigned long page_nr; @@ -323,7 +323,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, { struct drm_map *map = (struct drm_map *) vma->vm_private_data; struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_sg_mem *entry = dev->sg; unsigned long offset; unsigned long map_offset; @@ -419,7 +419,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { static void drm_vm_open_locked(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *vma_entry; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -437,7 +437,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma) static void drm_vm_open(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; mutex_lock(&dev->struct_mutex); drm_vm_open_locked(vma); @@ -455,7 +455,7 @@ static void drm_vm_open(struct vm_area_struct *vma) static void drm_vm_close(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -491,7 +491,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) struct drm_device_dma *dma; unsigned long length = vma->vm_end - vma->vm_start; - dev = priv->head->dev; + dev = priv->minor->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", vma->vm_start, vma->vm_end, vma->vm_pgoff); @@ -556,7 +556,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; struct drm_map *map = NULL; unsigned long offset = 0; struct drm_hash_item *hash; @@ -677,7 +677,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) int drm_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->head->dev; + struct drm_device *dev = priv->minor->dev; int ret; mutex_lock(&dev->struct_mutex); diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 3c9ca3b..f2bf5d9 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -113,7 +113,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) drm_i810_buf_priv_t *buf_priv; lock_kernel(); - dev = priv->head->dev; + dev = priv->minor->dev; dev_priv = dev->dev_private; buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; @@ -141,7 +141,7 @@ static const struct file_operations i810_buffer_fops = { static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; drm_i810_buf_priv_t *buf_priv = buf->dev_private; drm_i810_private_t *dev_priv = dev->dev_private; const struct file_operations *old_fops; diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9e474bc..7d247f9 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -988,7 +988,7 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, struct drm_i915_validate_buffer *buffers, uint32_t buf_count) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; struct i915_relocatee_info relocatee; int ret = 0; int b; @@ -1195,7 +1195,7 @@ void i915_fence_or_sync(struct drm_file *file_priv, struct drm_fence_arg *fence_arg, struct drm_fence_object **fence_p) { - struct drm_device *dev = file_priv->head->dev; + struct drm_device *dev = file_priv->minor->dev; int ret; struct drm_fence_object *fence; commit 638353103d009d44bd5bdbe97cc7cef1bf011cdf Author: Xiang, Haihao <hai...@in...> Date: Wed Mar 5 15:08:46 2008 +0800 i915: Evict if relocatee buffer is CACHED_MAPPED before writting relocations, otherwise the GPU probably sees some inconsistent data. Fix fd.o bug#14656 diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 3b180d1..17180d8 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1066,7 +1066,7 @@ static int drm_bo_busy(struct drm_buffer_object *bo) return 0; } -static int drm_bo_evict_cached(struct drm_buffer_object *bo) +int drm_bo_evict_cached(struct drm_buffer_object *bo) { int ret = 0; @@ -1076,6 +1076,7 @@ static int drm_bo_evict_cached(struct drm_buffer_object *bo) return ret; } +EXPORT_SYMBOL(drm_bo_evict_cached); /* * Wait until a buffer is unmapped. */ diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 69a5c27..fd32f0f 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -697,7 +697,7 @@ extern int drm_bo_do_validate(struct drm_buffer_object *bo, uint64_t flags, uint64_t mask, uint32_t hint, uint32_t fence_class, struct drm_bo_info_rep *rep); - +extern int drm_bo_evict_cached(struct drm_buffer_object *bo); /* * Buffer object memory move- and map helpers. * drm_bo_move.c diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f9e02c7..9e474bc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -806,6 +806,7 @@ struct i915_relocatee_info { struct drm_bo_kmap_obj kmap; int is_iomem; int idle; + int evicted; }; struct drm_i915_validate_buffer { @@ -878,6 +879,12 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, relocatee->data_page = drm_bmo_virtual(&relocatee->kmap, &relocatee->is_iomem); relocatee->page_offset = (relocatee->offset & PAGE_MASK); + + if (!relocatee->evicted && + relocatee->buf->mem.flags & DRM_BO_FLAG_CACHED_MAPPED) { + drm_bo_evict_cached(relocatee->buf); + relocatee->evicted = 1; + } } val = buffers[buf_index].buffer->offset; |
From: <ai...@ke...> - 2008-03-05 17:59:17
|
shared-core/drm.h | 172 ------------------------------------------------------ 1 file changed, 3 insertions(+), 169 deletions(-) New commits: commit 44a2209790e3f9651b72a884cc8539144b619d1c Merge: e00dea8... d5c0101... Author: Dave Airlie <ai...@li...> Date: Thu Mar 6 05:39:07 2008 +1000 Merge branch 'master' of ../../drm into modesetting-101 Conflicts: shared-core/drm.h diff --cc shared-core/drm.h index 303a84b,5981dcb..753af6b --- a/shared-core/drm.h +++ b/shared-core/drm.h @@@ -1221,23 -1052,6 +1052,26 @@@ struct drm_mm_info_arg #define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg) #define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) #define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) ++<<<<<<< HEAD:shared-core/drm.h + +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA3, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xA4, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int) +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd) + +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xA7, struct drm_mode_output_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_blob) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd) + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAB, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xAC, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug) ++======= ++>>>>>>> d5c0101252e9f48ef1b59f48c05fea7007df97f0:shared-core/drm.h /*@}*/ commit d5c0101252e9f48ef1b59f48c05fea7007df97f0 Author: Dave Airlie <ai...@re...> Date: Mon Feb 18 10:39:21 2008 +1000 ttm: make sure userspace can't destroy kernel create memory managers this adds something to say the kernel initialised the memory region not the userspace. and blocks userspace from deallocating kernel areas diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index b67946e..3e8ffa0 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2180,7 +2180,7 @@ restart: return 0; } -int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type) +int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean) { struct drm_buffer_manager *bm = &dev->bm; struct drm_mem_type_manager *man = &bm->man[mem_type]; @@ -2196,6 +2196,13 @@ int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type) "memory manager type %u\n", mem_type); return ret; } + + if ((man->kern_init_type) && (kern_clean == 0)) { + DRM_ERROR("Trying to take down kernel initialized " + "memory manager type %u\n", mem_type); + return -EPERM; + } + man->use_type = 0; man->has_type = 0; @@ -2247,9 +2254,9 @@ static int drm_bo_lock_mm(struct drm_device *dev, unsigned mem_type) return ret; } -int drm_bo_init_mm(struct drm_device *dev, - unsigned type, - unsigned long p_offset, unsigned long p_size) +int drm_bo_init_mm(struct drm_device *dev, unsigned type, + unsigned long p_offset, unsigned long p_size, + int kern_init) { struct drm_buffer_manager *bm = &dev->bm; int ret = -EINVAL; @@ -2283,6 +2290,7 @@ int drm_bo_init_mm(struct drm_device *dev, } man->has_type = 1; man->use_type = 1; + man->kern_init_type = kern_init; man->size = p_size; INIT_LIST_HEAD(&man->lru); @@ -2316,7 +2324,7 @@ int drm_bo_driver_finish(struct drm_device *dev) man = &bm->man[i]; if (man->has_type) { man->use_type = 0; - if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i)) { + if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i, 1)) { ret = -EBUSY; DRM_ERROR("DRM memory manager type %d " "is not clean.\n", i); @@ -2386,7 +2394,7 @@ int drm_bo_driver_init(struct drm_device *dev) * Initialize the system memory buffer type. * Other types need to be driver / IOCTL initialized. */ - ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0); + ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0, 1); if (ret) goto out_unlock; @@ -2446,7 +2454,7 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_ goto out; } ret = drm_bo_init_mm(dev, arg->mem_type, - arg->p_offset, arg->p_size); + arg->p_offset, arg->p_size, 0); out: mutex_unlock(&dev->struct_mutex); @@ -2485,9 +2493,11 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f goto out; } ret = 0; - if (drm_bo_clean_mm(dev, arg->mem_type)) { - DRM_ERROR("Memory manager type %d not clean. " - "Delaying takedown\n", arg->mem_type); + if ((ret = drm_bo_clean_mm(dev, arg->mem_type, 0))) { + if (ret == -EINVAL) + DRM_ERROR("Memory manager type %d not clean. " + "Delaying takedown\n", arg->mem_type); + ret = 0; } out: mutex_unlock(&dev->struct_mutex); diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index ae0725c..69e3f67 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -516,6 +516,7 @@ struct drm_buffer_object { struct drm_mem_type_manager { int has_type; int use_type; + int kern_init_type; struct drm_mm manager; struct list_head lru; struct list_head pinned; @@ -684,9 +685,10 @@ extern int drm_bo_mem_space(struct drm_buffer_object *bo, extern int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags, int no_wait, int move_unfenced); -extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type); +extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean); extern int drm_bo_init_mm(struct drm_device *dev, unsigned type, - unsigned long p_offset, unsigned long p_size); + unsigned long p_offset, unsigned long p_size, + int kern_init); extern int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle, uint64_t flags, uint64_t mask, uint32_t hint, uint32_t fence_class, int use_old_fence_class, diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 3d376ae..80b2990 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -376,7 +376,7 @@ nouveau_mem_init_ttm(struct drm_device *dev) bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT; if (bar1_size < vram_size) { if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, - bar1_size, vram_size - bar1_size))) { + bar1_size, vram_size - bar1_size, 1))) { DRM_ERROR("Failed PRIV0 mm init: %d\n", ret); return ret; } @@ -387,7 +387,7 @@ nouveau_mem_init_ttm(struct drm_device *dev) #ifdef HACK_OLD_MM vram_size /= 4; #endif - if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size))) { + if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) { DRM_ERROR("Failed VRAM mm init: %d\n", ret); return ret; } @@ -407,7 +407,7 @@ nouveau_mem_init_ttm(struct drm_device *dev) if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, dev_priv->gart_info.aper_size >> - PAGE_SHIFT))) { + PAGE_SHIFT, 1))) { DRM_ERROR("Failed TT mm init: %d\n", ret); return ret; } commit 180c9188f4cb7163f1e3e7d5098eaabf29a98540 Author: Dave Airlie <ai...@re...> Date: Wed Feb 20 13:27:10 2008 +1000 drm/ttm: add ioctl to get back memory managed area sized taken from modesetting branch but could be useful outside it. diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index fb8f1c6..3317ba5 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2871,6 +2871,21 @@ int drmMMUnlock(int fd, unsigned memType, int unlockBM) return drmIoctlTimeout(fd, DRM_IOCTL_MM_UNLOCK, &arg); } +int drmMMInfo(int fd, unsigned memType, uint64_t *size) +{ + struct drm_mm_info_arg arg; + + memset(&arg, 0, sizeof(arg)); + + arg.mem_type = memType; + + if (ioctl(fd, DRM_IOCTL_MM_INFO, &arg)) + return -errno; + + *size = arg.p_size; + return 0; +} + int drmBOVersion(int fd, unsigned int *major, unsigned int *minor, unsigned int *patchlevel) diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h index c80288a..bb57340 100644 --- a/libdrm/xf86mm.h +++ b/libdrm/xf86mm.h @@ -172,6 +172,7 @@ extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize, extern int drmMMTakedown(int fd, unsigned memType); extern int drmMMLock(int fd, unsigned memType, int lockBM, int ignoreNoEvict); extern int drmMMUnlock(int fd, unsigned memType, int unlockBM); +extern int drmMMInfo(int fd, unsigned memType, uint64_t *size); extern int drmBOSetStatus(int fd, drmBO *buf, uint64_t flags, uint64_t mask, unsigned int hint, diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 95802fe..b67946e 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -2283,6 +2283,7 @@ int drm_bo_init_mm(struct drm_device *dev, } man->has_type = 1; man->use_type = 1; + man->size = p_size; INIT_LIST_HEAD(&man->lru); INIT_LIST_HEAD(&man->pinned); @@ -2553,6 +2554,42 @@ int drm_mm_unlock_ioctl(struct drm_device *dev, return 0; } +int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_mm_info_arg *arg = data; + struct drm_buffer_manager *bm = &dev->bm; + struct drm_bo_driver *driver = dev->driver->bo_driver; + struct drm_mem_type_manager *man; + int ret = 0; + int mem_type = arg->mem_type; + + if (!driver) { + DRM_ERROR("Buffer objects are not supported by this driver\n"); + return -EINVAL; + } + + if (mem_type >= DRM_BO_MEM_TYPES) { + DRM_ERROR("Illegal memory type %d\n", arg->mem_type); + return -EINVAL; + } + + mutex_lock(&dev->struct_mutex); + if (!bm->initialized) { + DRM_ERROR("DRM memory manager was not initialized\n"); + ret = -EINVAL; + goto out; + } + + + man = &bm->man[arg->mem_type]; + + arg->p_size = man->size; + +out: + mutex_unlock(&dev->struct_mutex); + + return ret; +} /* * buffer object vm functions. */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 1daa865..b8b8333 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -148,6 +148,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0), + + DRM_IOCTL_DEF(DRM_IOCTL_MM_INFO, drm_mm_info_ioctl, 0), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index fd32f0f..ae0725c 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -525,6 +525,7 @@ struct drm_mem_type_manager { unsigned long io_offset; unsigned long io_size; void *io_addr; + uint64_t size; /* size of managed area for reporting to userspace */ }; struct drm_bo_lock { @@ -651,6 +652,7 @@ extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_bo_driver_finish(struct drm_device *dev); extern int drm_bo_driver_init(struct drm_device *dev); diff --git a/shared-core/drm.h b/shared-core/drm.h index 663696c..5981dcb 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -955,6 +955,11 @@ struct drm_mm_init_arg { uint64_t p_size; }; +struct drm_mm_info_arg { + unsigned int mem_type; + uint64_t p_size; +}; + /** * \name Ioctls Definitions */ @@ -1046,6 +1051,7 @@ struct drm_mm_init_arg { #define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg) #define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg) #define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) +#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) /*@}*/ |
From: <ai...@ke...> - 2008-03-05 17:59:17
|
libdrm/xf86drmMode.c | 16 ++++------------ linux-core/drm_compat.c | 2 +- linux-core/drm_drv.c | 15 ++++++++++++--- linux-core/i915_drv.c | 5 +++-- shared-core/i915_init.c | 9 +++++++++ 5 files changed, 29 insertions(+), 18 deletions(-) New commits: commit f78cdac8e512642db1aaf09bf9178e23ede25586 Author: Dave Airlie <airlied@panoply-rh.(none)> Date: Wed Mar 5 15:28:59 2008 +1000 fixup previous merge diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index b7b8e39..9b98266 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -806,5 +806,5 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, } EXPORT_SYMBOL(kmap_atomic_prot_pfn); - +#endif commit 4dbf447f4305e3c2aa8914b5ccfc07d9bf8ef28e Author: Dave Airlie <airlied@panoply-rh.(none)> Date: Wed Mar 5 15:28:38 2008 +1000 drm: fixup compat with old x.org drivers diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index dd76421..434789d 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -187,7 +187,9 @@ int drm_lastclose(struct drm_device * dev) DRM_DEBUG("\n"); -/* return 0; */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + drm_bo_driver_finish(dev); + /* * We can't do much about this function failing. */ @@ -425,13 +427,20 @@ int drm_minors_cleanup(int id, void *ptr, void *data) struct drm_minor *minor = ptr; struct drm_device *dev; struct drm_driver *driver = data; - if (id < 127 || id > 192) - return 0; dev = minor->dev; if (minor->dev->driver != driver) return 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (minor->type != DRM_MINOR_CONTROL) + return 0; + } else { + if (minor->type != DRM_MINOR_LEGACY) + return 0; + } + + if (dev) pci_dev_put(dev->pdev); drm_cleanup(dev); diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index b844dfe..0e65c0c 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -48,8 +48,8 @@ extern struct drm_fence_driver i915_fence_driver; #ifdef I915_HAVE_BUFFER -static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; -static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL}; +static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; +static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL}; static struct drm_bo_driver i915_bo_driver = { .mem_type_prio = i915_mem_prios, @@ -566,6 +566,7 @@ static struct drm_driver driver = { DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, .load = i915_driver_load, .unload = i915_driver_unload, + .firstopen = i915_driver_firstopen, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .suspend = i915_suspend, diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index a2e08bc..1f22d17 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -401,3 +401,12 @@ void i915_driver_lastclose(struct drm_device * dev) i915_dma_cleanup(dev); } + +int i915_driver_firstopen(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + drm_bo_driver_init(dev); + return 0; +} commit 4aa7efe398911bd58fb348703444a92114e45114 Author: Dave Airlie <airlied@panoply-rh.(none)> Date: Wed Mar 5 10:41:54 2008 +1000 libdrm: fix warnings in mode code diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 30b434d..07b14db 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -37,6 +37,7 @@ */ #include <stdint.h> #include <sys/ioctl.h> +#include <stdio.h> #include "xf86drmMode.h" #include "xf86drm.h" @@ -125,7 +126,6 @@ void drmModeFreeOutput(drmModeOutputPtr ptr) drmModeResPtr drmModeGetResources(int fd) { struct drm_mode_card_res res; - int i; drmModeResPtr r = 0; memset(&res, 0, sizeof(struct drm_mode_card_res)); @@ -196,7 +196,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, f.depth = depth; f.handle = bo_handle; - if (ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)) + if ((ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f))) return ret; *buf_id = f.buffer_id; @@ -243,7 +243,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) { struct drm_mode_crtc crtc; drmModeCrtcPtr r; - int i = 0; crtc.count_outputs = 0; crtc.outputs = 0; @@ -276,10 +275,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) r->possibles = crtc.possibles; return r; - -err_allocs: - - return 0; } @@ -433,8 +428,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) { struct drm_mode_get_property prop; drmModePropertyPtr r; - struct drm_mode_property_blob *blob_tmp; - int i; + prop.prop_id = property_id; prop.count_enum_blobs = 0; prop.count_values = 0; @@ -549,7 +543,7 @@ int drmModeOutputSetProperty(int fd, uint32_t output_id, uint32_t property_id, osp.prop_id = property_id; osp.value = value; - if (ret = ioctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)) + if ((ret = ioctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp))) return ret; return 0; @@ -565,8 +559,6 @@ int drmCheckModesettingSupported(const char *busid) { #ifdef __linux__ char pci_dev_dir[1024]; - char *bus_id_path; - char *bus_type; int domain, bus, dev, func; DIR *sysdir; struct dirent *dent; |
From: <jb...@ke...> - 2008-04-08 20:12:02
|
linux-core/drmP.h | 4 linux-core/drm_crtc.c | 46 ++++++++++ linux-core/drm_crtc.h | 6 + linux-core/drm_sysfs.c | 197 ++++++++++++++++++++++++++++++++++++++++++--- linux-core/intel_display.c | 5 - linux-core/intel_drv.h | 1 shared-core/i915_init.c | 1 7 files changed, 250 insertions(+), 10 deletions(-) New commits: commit e3c7a0fcb0122400e5b5035125ad4fa88599f28a Merge: a2edd07... 779e826... Author: Jesse Barnes <jb...@ni...> Date: Tue Apr 8 12:48:41 2008 -0700 Merge branch 'modesetting-101' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-101 commit a2edd07f20df67e741026097c5d46f12296d7c9d Author: Jesse Barnes <jb...@ni...> Date: Tue Apr 8 12:44:52 2008 -0700 Add devname in modeset case If the driver is 'modeset' enabled, it'll register it's interrupt handler at load time. Set the devname in this case so that /proc/interrupts makes sense. diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index a76acb4..ce6f165 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -265,6 +265,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM"); drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT"); + dev->devname = DRIVER_NAME; drm_irq_install(dev); } commit 5a3ce06f3a3dfa9412b9660c1e1f35d24c815dbb Author: Jesse Barnes <jb...@ni...> Date: Tue Apr 8 12:42:23 2008 -0700 Improved DRM sysfs support This patch ties outputs, output properties and hotplug events into the DRM core. Each output has a corresponding directory under the primary DRM device (usually card0) containing dpms, edid, modes, and connection status files. New hotplug change events occur when outputs are added or hotplug events are detected. diff --git a/linux-core/drmP.h b/linux-core/drmP.h index f96e6be..24f8c3d 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1311,7 +1311,11 @@ struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(void); extern int drm_sysfs_device_add(struct drm_minor *minor); +extern void drm_sysfs_hotplug_event(struct drm_device *dev); extern void drm_sysfs_device_remove(struct drm_minor *minor); +extern char *drm_get_output_status_name(enum drm_output_status status); +extern int drm_sysfs_output_add(struct drm_output *output); +extern void drm_sysfs_output_remove(struct drm_output *output); /* * Basic memory manager support (drm_mm.c) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 0cd0ebd..19155e1 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -47,6 +47,18 @@ static struct drm_prop_enum_list drm_dpms_enum_list[] = { DPMSModeSuspend, "Suspend" }, { DPMSModeOff, "Off" } }; + +char *drm_get_dpms_name(int val) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++) + if (drm_dpms_enum_list[i].type == val) + return drm_dpms_enum_list[i].name; + + return "unknown"; +} + static struct drm_prop_enum_list drm_conn_enum_list[] = { { ConnectorUnknown, "Unknown" }, { ConnectorVGA, "VGA" }, @@ -79,6 +91,16 @@ char *drm_get_output_name(struct drm_output *output) return buf; } +char *drm_get_output_status_name(enum drm_output_status status) +{ + if (status == output_status_connected) + return "connected"; + else if (status == output_status_disconnected) + return "disconnected"; + else + return "unknown"; +} + /** * drm_idr_get - allocate a new identifier * @dev: DRM device @@ -629,6 +651,8 @@ struct drm_output *drm_output_create(struct drm_device *dev, /* output_set_monitor(output)? */ /* check for output_ignored(output)? */ + drm_sysfs_output_add(output); + mutex_lock(&dev->mode_config.mutex); list_add_tail(&output->head, &dev->mode_config.output_list); dev->mode_config.num_output++; @@ -659,6 +683,8 @@ void drm_output_destroy(struct drm_output *output) struct drm_device *dev = output->dev; struct drm_display_mode *mode, *t; + drm_sysfs_output_remove(output); + if (*output->funcs->cleanup) (*output->funcs->cleanup)(output); @@ -1226,6 +1252,8 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output, DRM_ERROR("failed to set mode after hotplug\n"); } + drm_sysfs_hotplug_event(dev); + drm_disable_unused_functions(dev); return 0; @@ -2223,6 +2251,24 @@ int drm_output_property_set_value(struct drm_output *output, } EXPORT_SYMBOL(drm_output_property_set_value); +int drm_output_property_get_value(struct drm_output *output, + struct drm_property *property, uint64_t *val) +{ + int i; + + for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) { + if (output->property_ids[i] == property->id) { + *val = output->property_values[i]; + break; + } + } + + if (i == DRM_OUTPUT_MAX_PROPERTY) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL(drm_output_property_get_value); + int drm_mode_getproperty_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index bbeab60..ac0d2d5 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -451,6 +451,8 @@ struct drm_output_funcs { */ struct drm_output { struct drm_device *dev; + struct device kdev; + struct device_attribute *attr; struct list_head head; struct drm_crtc *crtc; int id; /* idr assigned */ @@ -563,6 +565,7 @@ struct drm_output *drm_output_create(struct drm_device *dev, int type); extern char *drm_get_output_name(struct drm_output *output); +extern char *drm_get_dpms_name(int val); extern void drm_output_destroy(struct drm_output *output); extern void drm_fb_release(struct file *filp); @@ -606,6 +609,9 @@ extern int drm_mode_output_update_edid_property(struct drm_output *output, extern int drm_output_property_set_value(struct drm_output *output, struct drm_property *property, uint64_t value); +extern int drm_output_property_get_value(struct drm_output *output, + struct drm_property *property, + uint64_t *value); extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); extern bool drm_initial_config(struct drm_device *dev, bool cangrow); extern void drm_framebuffer_set_object(struct drm_device *dev, diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index 3372a71..3e682c9 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -133,10 +133,6 @@ static ssize_t show_dri(struct device *device, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); } -static struct device_attribute device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - /** * drm_sysfs_device_release - do nothing * @dev: Linux device @@ -150,6 +146,189 @@ static void drm_sysfs_device_release(struct device *dev) return; } +/* + * Output properties + */ +static ssize_t status_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_output *output = container_of(device, struct drm_output, kdev); + return snprintf(buf, PAGE_SIZE, "%s", + drm_get_output_status_name(output->funcs->detect(output))); +} + +static ssize_t dpms_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_output *output = container_of(device, struct drm_output, kdev); + struct drm_device *dev = output->dev; + uint64_t dpms_status; + int ret; + + ret = drm_output_property_get_value(output, + dev->mode_config.dpms_property, + &dpms_status); + if (ret) + return 0; + + return snprintf(buf, PAGE_SIZE, "%s", drm_get_dpms_name((int)dpms_status)); +} + +static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct device *output_dev = container_of(kobj, struct device, kobj); + struct drm_output *output = container_of(output_dev, struct drm_output, + kdev); + unsigned char *edid; + size_t size; + + if (!output->edid_blob_ptr) + return 0; + + edid = output->edid_blob_ptr->data; + size = output->edid_blob_ptr->length; + if (!edid) + return 0; + + if (off >= size) + return 0; + + if (off + count > size) + count = size - off; + memcpy(buf, edid + off, count); + + return count; +} + +static ssize_t modes_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_output *output = container_of(device, struct drm_output, kdev); + struct drm_display_mode *mode; + int written = 0; + + list_for_each_entry(mode, &output->modes, head) { + written += snprintf(buf + written, PAGE_SIZE - written, "%s\n", + mode->name); + } + + return written; +} + +static struct device_attribute output_attrs[] = { + __ATTR_RO(status), + __ATTR_RO(dpms), + __ATTR_RO(modes), +}; + +static struct bin_attribute edid_attr = { + .attr.name = "edid", + .size = 128, + .read = edid_show, +}; + +/** + * drm_sysfs_output_add - add an output to sysfs + * @output: output to add + * + * Create an output device in sysfs, along with its associated output + * properties (so far, connection status, dpms, mode list & edid) and + * generate a hotplug event so userspace knows there's a new output + * available. + */ +int drm_sysfs_output_add(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + int ret = 0, i, j; + + if (device_is_registered(&output->kdev)) + return 0; + + output->kdev.parent = &dev->primary->kdev; + output->kdev.class = drm_class; + output->kdev.release = drm_sysfs_device_release; + + DRM_DEBUG("adding \"%s\" to sysfs", drm_get_output_name(output)); + + snprintf(output->kdev.bus_id, BUS_ID_SIZE, "card%d-%s", + dev->primary->index, drm_get_output_name(output)); + ret = device_register(&output->kdev); + + if (ret) { + DRM_ERROR("failed to register output device: %d\n", ret); + goto out; + } + + for (i = 0; i < ARRAY_SIZE(output_attrs); i++) { + ret = device_create_file(&output->kdev, &output_attrs[i]); + if (ret) + goto err_out_files; + } + + ret = sysfs_create_bin_file(&output->kdev.kobj, &edid_attr); + if (ret) + goto err_out_files; + + /* Let userspace know we have a new output */ + drm_sysfs_hotplug_event(dev); + + return 0; + +err_out_files: + if (i > 0) + for (j = 0; j < i; j++) + device_remove_file(&output->kdev, &output_attrs[i]); + device_unregister(&output->kdev); + +out: + return ret; +} + +/** + * drm_sysfs_output_remove - remove an output device from sysfs + * @output: output to remove + * + * Remove @output and its associated attributes from sysfs. Note that + * the device model core will take care of sending the "remove" uevent + * at this time, so we don't need to do it. + */ +void drm_sysfs_output_remove(struct drm_output *output) +{ + int i; + + DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_output_name(output)); + for (i = 0; i < i; i++) + device_remove_file(&output->kdev, &output_attrs[i]); + sysfs_remove_bin_file(&output->kdev.kobj, &edid_attr); + device_unregister(&output->kdev); +} + +/** + * drm_sysfs_hotplug_event - generate a DRM uevent + * @dev: DRM device + * + * Send a uevent for the DRM device specified by @dev. Currently we only + * set HOTPLUG=1 in the uevent environment, but this could be expanded to + * deal with other types of events. + */ +void drm_sysfs_hotplug_event(struct drm_device *dev) +{ + char *event_string = "HOTPLUG=1"; + char *envp[] = { event_string, NULL }; + + DRM_DEBUG("generating hotplug event\n"); + + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); +} + +static struct device_attribute dri_attrs[] = { + __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), +}; + /** * drm_sysfs_device_add - adds a class device to sysfs for a character driver * @dev: DRM device to be added @@ -184,8 +363,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) goto err_out; } - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(&minor->kdev, &device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(dri_attrs); i++) { + err = device_create_file(&minor->kdev, &dri_attrs[i]); if (err) goto err_out_files; } @@ -195,7 +374,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) err_out_files: if (i > 0) for (j = 0; j < i; j++) - device_remove_file(&minor->kdev, &device_attrs[i]); + device_remove_file(&minor->kdev, &dri_attrs[i]); device_unregister(&minor->kdev); err_out: @@ -213,7 +392,7 @@ void drm_sysfs_device_remove(struct drm_minor *minor) { int i; - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(&minor->kdev, &device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(dri_attrs); i++) + device_remove_file(&minor->kdev, &dri_attrs[i]); device_unregister(&minor->kdev); } diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index fa2b9be..0615c1c 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1292,7 +1292,10 @@ static void intel_setup_outputs(struct drm_device *dev) intel_sdvo_init(dev, SDVOB); intel_sdvo_init(dev, SDVOC); } - +#if 0 + if (IS_I9XX(dev) && !IS_I915G(dev)) + intel_tv_init(dev); +#endif list_for_each_entry(output, &dev->mode_config.output_list, head) { struct intel_output *intel_output = output->driver_private; int crtc_mask = 0, clone_mask = 0; diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index a36fd3f..62e21a5 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -68,6 +68,7 @@ extern bool intel_ddc_probe(struct drm_output *output); extern void intel_crt_init(struct drm_device *dev); extern void intel_sdvo_init(struct drm_device *dev, int output_device); +extern void intel_tv_init(struct drm_device *dev); extern void intel_lvds_init(struct drm_device *dev); extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
From: <jb...@ke...> - 2008-04-11 03:54:33
|
linux-core/drm_crtc.c | 45 +++++-- linux-core/drm_crtc.h | 13 -- linux-core/intel_display.c | 21 --- linux-core/intel_sdvo.c | 25 ---- linux-core/intel_tv.c | 266 ++++++++++++++++----------------------------- 5 files changed, 129 insertions(+), 241 deletions(-) New commits: commit 3b32ee36ae58f733f281a2fa569ea8a8a926bb6d Author: Jesse Barnes <jb...@ni...> Date: Thu Apr 10 20:31:31 2008 -0700 Fixup Intel TV property code Use the new TV property creation routine and fixup the set_property code to actually do a mode set call when properties change. diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 84825eb..89bdda1 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -37,14 +37,6 @@ #include "i915_drm.h" #include "i915_drv.h" -enum tv_type { - TV_TYPE_NONE, - TV_TYPE_UNKNOWN, - TV_TYPE_COMPOSITE, - TV_TYPE_SVIDEO, - TV_TYPE_COMPONENT -}; - enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM @@ -1145,14 +1137,14 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, switch (tv_priv->type) { default: - case TV_TYPE_UNKNOWN: - case TV_TYPE_COMPOSITE: + case ConnectorUnknown: + case ConnectorComposite: tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; video_levels = tv_mode->composite_levels; color_conversion = tv_mode->composite_color; burst_ena = tv_mode->burst_ena; break; - case TV_TYPE_COMPONENT: + case ConnectorComponent: tv_ctl |= TV_ENC_OUTPUT_COMPONENT; video_levels = &component_levels; if (tv_mode->burst_ena) @@ -1161,7 +1153,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, color_conversion = &hdtv_csc_yprpb; burst_ena = FALSE; break; - case TV_TYPE_SVIDEO: + case ConnectorSVIDEO: tv_ctl |= TV_ENC_OUTPUT_SVIDEO; video_levels = tv_mode->svideo_levels; color_conversion = tv_mode->svideo_color; @@ -1218,8 +1210,11 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, if (tv_mode->pal_burst) tv_ctl |= TV_PAL_BURST; scctl1 = 0; - if (tv_mode->dda1_inc) + /* dda1 implies valid video levels */ + if (tv_mode->dda1_inc) { scctl1 |= TV_SC_DDA1_EN; + scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + } if (tv_mode->dda2_inc) scctl1 |= TV_SC_DDA2_EN; @@ -1228,7 +1223,6 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, scctl1 |= TV_SC_DDA3_EN; scctl1 |= tv_mode->sc_reset; - scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | @@ -1255,22 +1249,26 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, I915_WRITE(TV_SC_CTL_2, scctl2); I915_WRITE(TV_SC_CTL_3, scctl3); - I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | - color_conversion->gy); - I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) | - color_conversion->ay); - I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | - color_conversion->gu); - I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | - color_conversion->au); - I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | - color_conversion->gv); - I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | - color_conversion->av); + if (color_conversion) { + I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | + color_conversion->gy); + I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) | + color_conversion->ay); + I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | + color_conversion->gu); + I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | + color_conversion->au); + I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | + color_conversion->gv); + I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | + color_conversion->av); + } I915_WRITE(TV_CLR_KNOBS, 0x00606000); - I915_WRITE(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | - (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); + if (video_levels) + I915_WRITE(TV_CLR_LEVEL, + ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | + (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); { int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; @@ -1364,7 +1362,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) struct intel_output *intel_output = output->driver_private; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; - int type = TV_TYPE_UNKNOWN; + int type = ConnectorUnknown; tv_dac = I915_READ(TV_DAC); /* @@ -1402,24 +1400,21 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) */ if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { DRM_DEBUG("Detected Composite TV connection\n"); - type = TV_TYPE_COMPOSITE; + type = ConnectorComposite; } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { DRM_DEBUG("Detected S-Video TV connection\n"); - type = TV_TYPE_SVIDEO; + type = ConnectorSVIDEO; } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { DRM_DEBUG("Detected Component TV connection\n"); - type = TV_TYPE_COMPONENT; + type = ConnectorComponent; } else { DRM_DEBUG("No TV connection detected\n"); - type = TV_TYPE_NONE; + type = -1; } return type; } -static int -intel_tv_format_configure_property (struct drm_output *output); - /** * Detect the TV connection. * @@ -1446,18 +1441,18 @@ intel_tv_detect(struct drm_output *output) } if (type != tv_priv->type) { + struct drm_property *connector_property = + output->dev->mode_config.connector_type_property; + tv_priv->type = type; - intel_tv_format_configure_property(output); + drm_output_property_set_value(output, connector_property, + type); } - switch (type) { - case TV_TYPE_NONE: + if (type < 0) return output_status_disconnected; - case TV_TYPE_UNKNOWN: - return output_status_unknown; - default: - return output_status_connected; - } + + return output_status_connected; } static struct input_res { @@ -1539,134 +1534,40 @@ intel_tv_destroy (struct drm_output *output) } static bool -intel_tv_format_set_property(struct drm_output *output, - struct drm_property *prop, uint64_t val) -{ -#if 0 - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = - intel_tv_mode_lookup(tv_priv->tv_format); - int err; - - if (!tv_mode) - tv_mode = &tv_modes[0]; - err = RRChangeOutputProperty (output->randr_output, tv_format_atom, - XA_ATOM, 32, PropModeReplace, 1, - &tv_format_name_atoms[tv_mode - tv_modes], - FALSE, TRUE); - return err == Success; -#endif - return 0; -} - - -/** - * Configure the TV_FORMAT property to list only supported formats - * - * Unless the connector is component, list only the formats supported by - * svideo and composite - */ - -static int -intel_tv_format_configure_property(struct drm_output *output) -{ -#if 0 - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - Atom current_atoms[NUM_TV_MODES]; - int num_atoms = 0; - int i; - - if (!output->randr_output) - return Success; - - for (i = 0; i < NUM_TV_MODES; i++) - if (!tv_modes[i].component_only || - tv_priv->type == TV_TYPE_COMPONENT) - current_atoms[num_atoms++] = tv_format_name_atoms[i]; - - return RRConfigureOutputProperty(output->randr_output, tv_format_atom, - TRUE, FALSE, FALSE, - num_atoms, (INT32 *) current_atoms); -#endif - return 0; -} - -static void -intel_tv_create_resources(struct drm_output *output) -{ - struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - int i, err; - -#if 0 - /* Set up the tv_format property, which takes effect on mode set - * and accepts strings that match exactly - */ - tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1, - TRUE); - - for (i = 0; i < NUM_TV_MODES; i++) - tv_format_name_atoms[i] = MakeAtom (tv_modes[i].name, - strlen (tv_modes[i].name), - TRUE); - - err = intel_tv_format_configure_property (output); - - if (err != 0) { - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - - /* Set the current value of the tv_format property */ - if (!intel_tv_format_set_property (output)) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - - for (i = 0; i < 4; i++) - { - INT32 range[2]; - margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]), - TRUE); - - range[0] = 0; - range[1] = 100; - err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i], - TRUE, TRUE, FALSE, 2, range); - - if (err != 0) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - - err = RRChangeOutputProperty(output->randr_output, margin_atoms[i], - XA_INTEGER, 32, PropModeReplace, - 1, &tv_priv->margin[i], - FALSE, TRUE); - if (err != 0) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } -#endif -} - -static bool intel_tv_set_property(struct drm_output *output, struct drm_property *property, uint64_t val) { struct drm_device *dev = output->dev; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; int ret = 0; - - if (property == dev->mode_config.tv_left_margin_property || - property == dev->mode_config.tv_right_margin_property || - property == dev->mode_config.tv_top_margin_property || - property == dev->mode_config.tv_bottom_margin_property) { - ret = drm_output_property_set_value(output, property, val); + + ret = drm_output_property_set_value(output, property, val); + if (ret < 0) + goto out; + + if (property == dev->mode_config.tv_left_margin_property) + tv_priv->margin[TV_MARGIN_LEFT] = val; + else if (property == dev->mode_config.tv_right_margin_property) + tv_priv->margin[TV_MARGIN_RIGHT] = val; + else if (property == dev->mode_config.tv_top_margin_property) + tv_priv->margin[TV_MARGIN_TOP] = val; + else if (property == dev->mode_config.tv_bottom_margin_property) + tv_priv->margin[TV_MARGIN_BOTTOM] = val; + else if (property == dev->mode_config.tv_mode_property) { + if (val >= NUM_TV_MODES) { + ret = -EINVAL; + goto out; + } + tv_priv->tv_format = tv_modes[val].name; + intel_tv_mode_set(output, NULL, NULL); } else { - /* TV mode handling here */ + ret = -EINVAL; + goto out; } + intel_tv_mode_set(output, NULL, NULL); +out: return ret; } @@ -1693,6 +1594,8 @@ intel_tv_init(struct drm_device *dev) struct intel_output *intel_output; struct intel_tv_priv *tv_priv; u32 tv_dac_on, tv_dac_off, save_tv_dac; + char **tv_format_names; + int i, initial_mode = 0; /* FIXME: better TV detection and/or quirks */ #if 0 @@ -1743,22 +1646,47 @@ intel_tv_init(struct drm_device *dev) output->possible_crtcs = ((1 << 0) | (1 << 1)); output->possible_clones = (1 << INTEL_OUTPUT_TVOUT); intel_output->dev_priv = tv_priv; - tv_priv->type = TV_TYPE_UNKNOWN; + tv_priv->type = ConnectorUnknown; - tv_priv->tv_format = NULL; - /* BIOS margin values */ tv_priv->margin[TV_MARGIN_LEFT] = 54; tv_priv->margin[TV_MARGIN_TOP] = 36; tv_priv->margin[TV_MARGIN_RIGHT] = 46; tv_priv->margin[TV_MARGIN_BOTTOM] = 37; - if (!tv_priv->tv_format) - tv_priv->tv_format = kstrdup(tv_modes[0].name, GFP_KERNEL); + tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + drm_output_attach_property(output, + dev->mode_config.connector_type_property, + ConnectorUnknown); + + /* Create TV properties then attach current values */ + tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES, + DRM_MEM_DRIVER); + if (!tv_format_names) + goto out; + for (i = 0; i < NUM_TV_MODES; i++) + tv_format_names[i] = tv_modes[i].name; + drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + + drm_output_attach_property(output, dev->mode_config.tv_mode_property, + initial_mode); + drm_output_attach_property(output, + dev->mode_config.tv_left_margin_property, + tv_priv->margin[TV_MARGIN_LEFT]); + drm_output_attach_property(output, + dev->mode_config.tv_top_margin_property, + tv_priv->margin[TV_MARGIN_TOP]); + drm_output_attach_property(output, + dev->mode_config.tv_right_margin_property, + tv_priv->margin[TV_MARGIN_RIGHT]); + drm_output_attach_property(output, + dev->mode_config.tv_bottom_margin_property, + tv_priv->margin[TV_MARGIN_BOTTOM]); +out: drm_sysfs_output_add(output); } commit 83c3acb7da1043a63d260d5443f7149b2c664b08 Author: Jesse Barnes <jb...@ni...> Date: Thu Apr 10 20:30:12 2008 -0700 Split TV property creation into its own routine It needs to take arguments from the caller about supported TV formats, so declare it in drm_crtc.h and export it. diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index b33edce..1e5195d 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -767,9 +767,25 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev) dev->mode_config.connector_num_property->values[0] = 0; dev->mode_config.connector_num_property->values[1] = 20; - /* - * TV specific properties - */ + return 0; +} + +/** + * drm_create_tv_properties - create TV specific output properties + * @dev: DRM device + * @num_modes: number of different TV formats (modes) supported + * @modes: array of pointers to strings containing name of each format + * + * Called by a driver's TV initialization routine, this function creates + * the TV specific output properties for a given device. Caller is + * responsible for allocating a list of format names and passing them to + * this routine. + */ +bool drm_create_tv_properties(struct drm_device *dev, int num_modes, + char *modes[]) +{ + int i; + dev->mode_config.tv_left_margin_property = drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE, @@ -778,28 +794,33 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev) dev->mode_config.tv_left_margin_property->values[1] = 100; dev->mode_config.tv_right_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE | - DRM_MODE_PROP_IMMUTABLE, + drm_property_create(dev, DRM_MODE_PROP_RANGE, "right margin", 2); dev->mode_config.tv_right_margin_property->values[0] = 0; dev->mode_config.tv_right_margin_property->values[1] = 100; dev->mode_config.tv_top_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE | - DRM_MODE_PROP_IMMUTABLE, + drm_property_create(dev, DRM_MODE_PROP_RANGE, "top margin", 2); dev->mode_config.tv_top_margin_property->values[0] = 0; dev->mode_config.tv_top_margin_property->values[1] = 100; dev->mode_config.tv_bottom_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE | - DRM_MODE_PROP_IMMUTABLE, + drm_property_create(dev, DRM_MODE_PROP_RANGE, "bottom margin", 2); dev->mode_config.tv_bottom_margin_property->values[0] = 0; dev->mode_config.tv_bottom_margin_property->values[1] = 100; + dev->mode_config.tv_mode_property = + drm_property_create(dev, DRM_MODE_PROP_ENUM, + "mode", num_modes); + for (i = 0; i < num_modes; i++) + drm_property_add_enum(dev->mode_config.tv_mode_property, i, + i, modes[i]); + return 0; } +EXPORT_SYMBOL(drm_create_tv_properties); /** * drm_mode_config_init - initialize DRM mode_configuration structure diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 74316aa..20b1ea0 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -611,6 +611,8 @@ extern struct drm_property *drm_property_create(struct drm_device *dev, int flag extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); +extern bool drm_create_tv_properties(struct drm_device *dev, int num_formats, + char *formats[]); /* IOCTLs */ extern int drm_mode_getresources(struct drm_device *dev, commit bee546ad696e3157b878dfa90e563786b5b5c7ac Author: Jesse Barnes <jb...@ni...> Date: Thu Apr 10 19:02:53 2008 -0700 Remove structure fields & code Cleanup some random cruft left over from the initial port. diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index f437782..b33edce 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -440,7 +440,6 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_device *dev = crtc->dev; struct drm_display_mode *adjusted_mode, saved_mode; int saved_x, saved_y; - bool didLock = false; struct drm_output *output; bool ret = true; @@ -451,8 +450,6 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, if (!crtc->enabled) return true; - didLock = crtc->funcs->lock(crtc); - saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; @@ -544,9 +541,6 @@ done: crtc->x = saved_x; crtc->y = saved_y; } - - if (didLock) - crtc->funcs->unlock (crtc); return ret; } diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index ec5b20b..74316aa 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -308,13 +308,10 @@ struct drm_crtc_funcs { */ void (*dpms)(struct drm_crtc *crtc, int mode); - /* JJJ: Are these needed? */ /* Save CRTC state */ void (*save)(struct drm_crtc *crtc); /* suspend? */ /* Restore CRTC state */ void (*restore)(struct drm_crtc *crtc); /* resume? */ - bool (*lock)(struct drm_crtc *crtc); - void (*unlock)(struct drm_crtc *crtc); void (*prepare)(struct drm_crtc *crtc); void (*commit)(struct drm_crtc *crtc); @@ -367,10 +364,6 @@ struct drm_crtc { bool enabled; - /* JJJ: are these needed? */ - bool cursor_in_range; - bool cursor_shown; - struct drm_display_mode mode; int x, y; @@ -418,7 +411,6 @@ struct drm_output_funcs { struct drm_display_mode *adjusted_mode); enum drm_output_status (*detect)(struct drm_output *output); int (*get_modes)(struct drm_output *output); - /* JJJ: type checking for properties via property value type */ bool (*set_property)(struct drm_output *output, struct drm_property *property, uint64_t val); void (*cleanup)(struct drm_output *output); @@ -519,7 +511,6 @@ struct drm_mode_config { int num_output; struct list_head output_list; - /* int compat_output? */ int num_crtc; struct list_head crtc_list; @@ -527,8 +518,6 @@ struct drm_mode_config { int min_width, min_height; int max_width, max_height; - /* DamagePtr rotationDamage? */ - /* DGA stuff? */ struct drm_mode_config_funcs *funcs; unsigned long fb_base; diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 5ca33f7..6aa6125 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -571,25 +571,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) intel_crtc->dpms_mode = mode; } -static bool intel_crtc_lock(struct drm_crtc *crtc) -{ - /* Sync the engine before mode switch */ -// i830WaitSync(crtc->scrn); - -#if 0 // TODO def XF86DRI - return I830DRILock(crtc->scrn); -#else - return FALSE; -#endif -} - -static void intel_crtc_unlock (struct drm_crtc *crtc) -{ -#if 0 // TODO def XF86DRI - I830DRIUnlock (crtc->scrn); -#endif -} - static void intel_crtc_prepare (struct drm_crtc *crtc) { crtc->funcs->dpms(crtc, DPMSModeOff); @@ -1334,8 +1315,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, static const struct drm_crtc_funcs intel_crtc_funcs = { .dpms = intel_crtc_dpms, - .lock = intel_crtc_lock, - .unlock = intel_crtc_unlock, .mode_fixup = intel_crtc_mode_fixup, .mode_set = intel_crtc_mode_set, .mode_set_base = intel_pipe_set_base, diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index c9e65af..ba6fe9a 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -126,14 +126,6 @@ static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr, return false; } - -static bool intel_sdvo_read_byte_quiet(struct drm_output *output, int addr, - u8 *ch) -{ - return true; - -} - static bool intel_sdvo_write_byte(struct drm_output *output, int addr, u8 ch) { @@ -863,23 +855,6 @@ static bool intel_sdvo_get_capabilities(struct drm_output *output, struct intel_ return true; } - -static void intel_sdvo_dump_cmd(struct drm_output *output, int opcode) -{ - - -} - -static void intel_sdvo_dump_device(struct drm_output *output) -{ - -} - -void intel_sdvo_dump(void) -{ - -} - struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB) { struct drm_output *output = 0; |
From: <jb...@ke...> - 2008-04-23 01:35:40
|
linux-core/drm_sysfs.c | 2 +- linux-core/intel_dvo.c | 1 + shared-core/i915_irq.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) New commits: commit b57e1f7efd6e27efbf960ab11323981e016ea86e Author: Hong Liu <hon...@in...> Date: Fri Apr 18 16:52:04 2008 +0800 add sysfs entry for DVO output forget to add it in the previous DVO porting patch. Signed-off-by: Hong Liu <hon...@in...> diff --git a/linux-core/intel_dvo.c b/linux-core/intel_dvo.c index 423b751..6f31910 100644 --- a/linux-core/intel_dvo.c +++ b/linux-core/intel_dvo.c @@ -477,6 +477,7 @@ void intel_dvo_init(struct drm_device *dev) dvo->panel_wants_dither = true; } + drm_sysfs_output_add(output); drm_output_attach_property(output, dev->mode_config.connector_type_property, connector); commit 8a390e058fcea70b0c3a912543816bdf4c3e7c4c Author: Hong Liu <hon...@in...> Date: Fri Apr 18 16:49:23 2008 +0800 clear interrupt status before install irq On my 865G machine, it seems the CPU will receive interrupt before irq_postinstall is called. This will cause kernel oops because vblank is not inited at that time. Clear interrupt status before install seems fixing this problem. Signed-off-by: Hong Liu <hon...@in...> diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 8f136c8..422e81e 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -1217,14 +1217,25 @@ int i915_vblank_swap(struct drm_device *dev, void *data, void i915_driver_irq_preinstall(struct drm_device * dev) { struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; + u32 tmp; + + tmp = I915_READ(I915REG_PIPEASTAT); + I915_WRITE(I915REG_PIPEASTAT, tmp); + tmp = I915_READ(I915REG_PIPEBSTAT); + I915_WRITE(I915REG_PIPEBSTAT, tmp); + I915_WRITE16(I915REG_HWSTAM, 0xeffe); if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { I915_WRITE(I915REG_INT_MASK_R, 0x0); I915_WRITE(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ(I915REG_INT_IDENTITY_R); + I915_WRITE(I915REG_INT_IDENTITY_R, tmp); } else { I915_WRITE16(I915REG_INT_MASK_R, 0x0); I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); + tmp = I915_READ16(I915REG_INT_IDENTITY_R); + I915_WRITE16(I915REG_INT_IDENTITY_R, tmp); } } commit c250104c8f81026b4191ec8b2a709ff7ab5baedb Author: Hong Liu <hon...@in...> Date: Fri Apr 18 16:26:41 2008 +0800 fix removing output_attrs fix a typo in removing output sysfs. Signed-off-by: Hong Liu <hon...@in...> diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index ef73cc8..8691d15 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -302,7 +302,7 @@ void drm_sysfs_output_remove(struct drm_output *output) int i; DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_output_name(output)); - for (i = 0; i < i; i++) + for (i = 0; i < ARRAY_SIZE(output_attrs); i++) device_remove_file(&output->kdev, &output_attrs[i]); sysfs_remove_bin_file(&output->kdev.kobj, &edid_attr); device_unregister(&output->kdev); |
From: <wal...@ke...> - 2008-05-08 18:11:43
|
linux-core/drmP.h | 2 linux-core/drm_crtc.c | 96 +++++--- linux-core/drm_crtc.h | 7 linux-core/intel_drv.h | 2 linux-core/intel_fb.c | 506 +++++++++++++++++++++++----------------------- linux-core/radeon_ms_fb.c | 2 shared-core/radeon_ms.h | 2 7 files changed, 328 insertions(+), 289 deletions(-) New commits: commit 7bcbc443f4f5161ab1e1a11cb6694e6d6269377c Author: Jakob Bornecrantz <ja...@tu...> Date: Thu May 8 20:10:18 2008 +0200 i915: Changed intel_fb to use the new drm_crtc_set_config interface diff --git a/linux-core/drmP.h b/linux-core/drmP.h index f5e794e..52d2782 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -743,7 +743,7 @@ struct drm_driver { struct drm_set_version *sv); /* FB routines, if present */ - int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc); + int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); int (*fb_remove)(struct drm_device *dev, struct drm_crtc *crtc); int (*fb_resize)(struct drm_device *dev, struct drm_crtc *crtc); diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index bdcf5f9..2bc1c4e 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -540,8 +540,8 @@ done: crtc->mode = saved_mode; crtc->x = saved_x; crtc->y = saved_y; - } - + } + return ret; } EXPORT_SYMBOL(drm_crtc_set_mode); @@ -1036,16 +1036,6 @@ bool drm_initial_config(struct drm_device *dev, bool can_grow) drm_pick_crtcs(dev); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - - /* can't setup the crtc if there's no assigned mode */ - if (!crtc->desired_mode) - continue; - - /* Now setup the fbdev for attached crtcs */ - dev->driver->fb_probe(dev, crtc); - } - /* This is a little screwy, as we've already walked the outputs * above, but it's a little bit of magic too. There's the potential * for things not to get setup above if an existing device gets @@ -1058,6 +1048,8 @@ bool drm_initial_config(struct drm_device *dev, bool can_grow) if (!output->crtc || !output->crtc->desired_mode) continue; + dev->driver->fb_probe(dev, output->crtc, output); + /* and needs an attached fb */ if (output->crtc->fb) drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0); @@ -1140,12 +1132,15 @@ int drm_crtc_set_config(struct drm_mode_set *set) struct drm_output *output; int count = 0, ro; + DRM_DEBUG("\n"); + if (!set) return -EINVAL; if (!set->crtc) return -EINVAL; + DRM_DEBUG("crtc: %p fb: %p outputs: %p num_outputs: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->outputs, set->num_outputs, set->x, set->y); dev = set->crtc->dev; /* save previous config */ @@ -1223,6 +1218,7 @@ int drm_crtc_set_config(struct drm_mode_set *set) kfree(save_crtcs); return 0; } +EXPORT_SYMBOL(drm_crtc_set_config); /** * drm_hotplug_stage_two @@ -1267,7 +1263,7 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output, /* We should really check if there is a fb using this crtc */ if (!has_config) - dev->driver->fb_probe(dev, output->crtc); + dev->driver->fb_probe(dev, output->crtc, output); else { dev->driver->fb_resize(dev, output->crtc); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index abe8f3f..1d36dcd 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -605,6 +605,7 @@ extern struct drm_framebuffer *drm_framebuffer_create(struct drm_device *dev); extern void drm_framebuffer_destroy(struct drm_framebuffer *fb); extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc); extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); +extern int drm_crtc_set_config(struct drm_mode_set *set); extern bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int x, int y); extern bool drm_crtc_in_use(struct drm_crtc *crtc); diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index e0e6b79..6b89c00 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -90,7 +90,7 @@ extern struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB); extern int intel_sdvo_supports_hotplug(struct drm_output *output); extern void intel_sdvo_set_hotplug(struct drm_output *output, int enable); -extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc); +extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); extern int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc); extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc); diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 73ad35c..50c24a7 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -46,10 +46,14 @@ struct intelfb_par { struct drm_device *dev; +/* struct drm_crtc *crtc; struct drm_display_mode *fb_mode; struct drm_framebuffer *fb; +*/ + struct drm_display_mode *our_mode; struct drm_mode_set set; + struct drm_output *hack; }; /* static int @@ -68,8 +72,8 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, struct fb_info *info) { struct intelfb_par *par = info->par; - struct drm_framebuffer *fb = par->fb; - struct drm_crtc *crtc = par->crtc; + struct drm_framebuffer *fb = par->set.fb; + struct drm_crtc *crtc = par->set.crtc; if (regno > 255) return 1; @@ -109,7 +113,7 @@ static int intelfb_check_var(struct fb_var_screeninfo *var, { struct intelfb_par *par = info->par; /*struct drm_device *dev = par->dev;*/ - struct drm_framebuffer *fb = par->fb; + struct drm_framebuffer *fb = par->set.fb; /*struct drm_output *output;*/ int depth/*, found = 0*/; @@ -223,13 +227,12 @@ static int intelfb_check_var(struct fb_var_screeninfo *var, static int intelfb_set_par(struct fb_info *info) { struct intelfb_par *par = info->par; - struct drm_framebuffer *fb = par->fb; + struct drm_framebuffer *fb = par->set.fb; struct drm_device *dev = par->dev; struct drm_display_mode *drm_mode, *search_mode; struct drm_output *output = NULL; struct fb_var_screeninfo *var = &info->var; int found = 0; - int changed = 0; DRM_DEBUG("\n"); @@ -274,7 +277,7 @@ static int intelfb_set_par(struct fb_info *info) found = 0; list_for_each_entry(output, &dev->mode_config.output_list, head) { - if (output->crtc == par->crtc){ + if (output->crtc == par->set.crtc){ found = 1; break; } @@ -300,17 +303,24 @@ static int intelfb_set_par(struct fb_info *info) * create a new attachment for the incoming user specified mode */ if (!found) { - if (par->fb_mode) { + if (par->our_mode) { /* this also destroys the mode */ - drm_mode_detachmode_crtc(dev, par->fb_mode); + drm_mode_detachmode_crtc(dev, par->our_mode); } - par->fb_mode = drm_mode; + par->set.mode = drm_mode; + par->our_mode = drm_mode; drm_mode_debug_printmodeline(dev, drm_mode); /* attach mode */ - drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode); + drm_mode_attachmode_crtc(dev, par->set.crtc, par->set.mode); + } else { + par->set.mode = drm_mode; + if (par->our_mode) + drm_mode_detachmode_crtc(dev, par->our_mode); + par->our_mode = NULL; } +#if 0 /* re-attach fb */ if (!par->crtc->fb) { par->crtc->fb = par->fb; @@ -330,6 +340,9 @@ static int intelfb_set_par(struct fb_info *info) return -EINVAL; return 0; +#else + return drm_crtc_set_config(&par->set); +#endif } #if 0 @@ -481,27 +494,20 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { struct intelfb_par *par = info->par; - struct drm_crtc *crtc = par->crtc; - int changed = 0; + int ret; DRM_DEBUG("\n"); - /* TODO add check size and pos*/ - if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset) - changed = 1; - - /* re-attach fb */ - if (!crtc->fb) { - crtc->fb = par->fb; - changed = 1; - } + par->set.x = var->xoffset; + par->set.y = var->yoffset; - if (changed) - drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset); + ret = drm_crtc_set_config(&par->set); - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; + if (!ret) { + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + } - return 0; + return ret; } static struct fb_ops intelfb_ops = { @@ -560,7 +566,7 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc) } EXPORT_SYMBOL(intelfb_resize); -int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) +int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output) { struct fb_info *info; struct intelfb_par *par; @@ -575,6 +581,9 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) return -EINVAL; } + if (!output) + return -EINVAL; + fb = drm_framebuffer_create(dev); if (!fb) { framebuffer_release(info); @@ -616,8 +625,11 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) par = info->par; par->dev = dev; - par->crtc = crtc; - par->fb = fb; + par->set.crtc = crtc; + par->set.fb = fb; + par->hack = output; + par->set.outputs = &par->hack; + par->set.num_outputs = 1; info->fbops = &intelfb_ops; diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c index dbbddaf..ae4f2da 100644 --- a/linux-core/radeon_ms_fb.c +++ b/linux-core/radeon_ms_fb.c @@ -270,7 +270,7 @@ static struct fb_ops radeonfb_ops = { .fb_imageblit = cfb_imageblit, }; -int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc) +int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output) { struct drm_radeon_private *dev_priv = dev->dev_private; struct fb_info *info; diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index dd34683..1fdcd0a 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -435,7 +435,7 @@ int r3xx_fence_types(struct drm_buffer_object *bo, uint32_t * class, uint32_t * type); /* radeon_ms_fb.c */ -int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc); +int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc); /* radeon_ms_gpu.c */ commit 9d9104ad5fcd2d284a0a87385e9eb1a77adc869e Author: Jakob Bornecrantz <ja...@tu...> Date: Thu May 8 15:25:37 2008 +0200 i915: Fixed indent in intel_fb.c diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 7df1525..73ad35c 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -47,24 +47,25 @@ struct intelfb_par { struct drm_device *dev; struct drm_crtc *crtc; - struct drm_display_mode *fb_mode; + struct drm_display_mode *fb_mode; struct drm_framebuffer *fb; + struct drm_mode_set set; }; /* static int var_to_refresh(const struct fb_var_screeninfo *var) { int xtot = var->xres + var->left_margin + var->right_margin + - var->hsync_len; + var->hsync_len; int ytot = var->yres + var->upper_margin + var->lower_margin + - var->vsync_len; + var->vsync_len; return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; }*/ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) + unsigned blue, unsigned transp, + struct fb_info *info) { struct intelfb_par *par = info->par; struct drm_framebuffer *fb = par->fb; @@ -82,9 +83,9 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, if (regno < 16) { switch (fb->depth) { case 15: - fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | + fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | ((green & 0xf800) >> 6) | - ((blue & 0xf800) >> 11); + ((blue & 0xf800) >> 11); break; case 16: fb->pseudo_palette[regno] = (red & 0xf800) | @@ -94,7 +95,7 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, case 24: case 32: fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | - (green & 0xff00) | + (green & 0xff00) | ((blue & 0xff00) >> 8); break; } @@ -104,114 +105,114 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, } static int intelfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) + struct fb_info *info) { - struct intelfb_par *par = info->par; - /*struct drm_device *dev = par->dev;*/ + struct intelfb_par *par = info->par; + /*struct drm_device *dev = par->dev;*/ struct drm_framebuffer *fb = par->fb; - /*struct drm_output *output;*/ - int depth/*, found = 0*/; - - if (!var->pixclock) - return -EINVAL; - - /* Need to resize the fb object !!! */ - if (var->xres > fb->width || var->yres > fb->height) { - DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height); - DRM_ERROR("Need resizing code.\n"); - return -EINVAL; - } - - switch (var->bits_per_pixel) { - case 16: - depth = (var->green.length == 6) ? 16 : 15; - break; - case 32: - depth = (var->transp.length > 0) ? 32 : 24; - break; - default: - depth = var->bits_per_pixel; - break; - } - - switch (depth) { - case 8: - var->red.offset = 0; - var->green.offset = 0; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 15: - var->red.offset = 10; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 5; - var->blue.length = 5; - var->transp.length = 1; - var->transp.offset = 15; - break; - case 16: - var->red.offset = 11; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 6; - var->blue.length = 5; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 24: - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 32: - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 8; - var->transp.offset = 24; - break; - default: - return -EINVAL; - } + /*struct drm_output *output;*/ + int depth/*, found = 0*/; + + if (!var->pixclock) + return -EINVAL; + + /* Need to resize the fb object !!! */ + if (var->xres > fb->width || var->yres > fb->height) { + DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height); + DRM_ERROR("Need resizing code.\n"); + return -EINVAL; + } + + switch (var->bits_per_pixel) { + case 16: + depth = (var->green.length == 6) ? 16 : 15; + break; + case 32: + depth = (var->transp.length > 0) ? 32 : 24; + break; + default: + depth = var->bits_per_pixel; + break; + } + + switch (depth) { + case 8: + var->red.offset = 0; + var->green.offset = 0; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 15: + var->red.offset = 10; + var->green.offset = 5; + var->blue.offset = 0; + var->red.length = 5; + var->green.length = 5; + var->blue.length = 5; + var->transp.length = 1; + var->transp.offset = 15; + break; + case 16: + var->red.offset = 11; + var->green.offset = 5; + var->blue.offset = 0; + var->red.length = 5; + var->green.length = 6; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 24: + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 32: + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 8; + var->transp.offset = 24; + break; + default: + return -EINVAL; + } #if 0 - /* Here we walk the output mode list and look for modes. If we haven't - * got it, then bail. Not very nice, so this is disabled. - * In the set_par code, we create our mode based on the incoming - * parameters. Nicer, but may not be desired by some. - */ - list_for_each_entry(output, &dev->mode_config.output_list, head) { - if (output->crtc == par->crtc) - break; - } - - list_for_each_entry(drm_mode, &output->modes, head) { - if (drm_mode->hdisplay == var->xres && - drm_mode->vdisplay == var->yres && - (((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) && - (((PICOS2KHZ(var->pixclock))/1000) <= ((drm_mode->clock/1000)+1))) { + /* Here we walk the output mode list and look for modes. If we haven't + * got it, then bail. Not very nice, so this is disabled. + * In the set_par code, we create our mode based on the incoming + * parameters. Nicer, but may not be desired by some. + */ + list_for_each_entry(output, &dev->mode_config.output_list, head) { + if (output->crtc == par->crtc) + break; + } + + list_for_each_entry(drm_mode, &output->modes, head) { + if (drm_mode->hdisplay == var->xres && + drm_mode->vdisplay == var->yres && + (((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) && + (((PICOS2KHZ(var->pixclock))/1000) <= ((drm_mode->clock/1000)+1))) { found = 1; break; } } - if (!found) - return -EINVAL; + if (!found) + return -EINVAL; #endif return 0; @@ -224,68 +225,68 @@ static int intelfb_set_par(struct fb_info *info) struct intelfb_par *par = info->par; struct drm_framebuffer *fb = par->fb; struct drm_device *dev = par->dev; - struct drm_display_mode *drm_mode, *search_mode; - struct drm_output *output = NULL; - struct fb_var_screeninfo *var = &info->var; + struct drm_display_mode *drm_mode, *search_mode; + struct drm_output *output = NULL; + struct fb_var_screeninfo *var = &info->var; int found = 0; int changed = 0; DRM_DEBUG("\n"); - switch (var->bits_per_pixel) { - case 16: - fb->depth = (var->green.length == 6) ? 16 : 15; - break; - case 32: - fb->depth = (var->transp.length > 0) ? 32 : 24; - break; - default: - fb->depth = var->bits_per_pixel; - break; - } + switch (var->bits_per_pixel) { + case 16: + fb->depth = (var->green.length == 6) ? 16 : 15; + break; + case 32: + fb->depth = (var->transp.length > 0) ? 32 : 24; + break; + default: + fb->depth = var->bits_per_pixel; + break; + } - fb->bits_per_pixel = var->bits_per_pixel; + fb->bits_per_pixel = var->bits_per_pixel; - info->fix.line_length = fb->pitch; - info->fix.smem_len = info->fix.line_length * fb->height; - info->fix.visual = (fb->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + info->fix.line_length = fb->pitch; + info->fix.smem_len = info->fix.line_length * fb->height; + info->fix.visual = (fb->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; - info->screen_size = info->fix.smem_len; /* ??? */ + info->screen_size = info->fix.smem_len; /* ??? */ /* create a drm mode */ - drm_mode = drm_mode_create(dev); - drm_mode->hdisplay = var->xres; - drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin; - drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len; - drm_mode->htotal = drm_mode->hsync_end + var->left_margin; - drm_mode->vdisplay = var->yres; - drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin; - drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len; - drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin; - drm_mode->clock = PICOS2KHZ(var->pixclock); - drm_mode->vrefresh = drm_mode_vrefresh(drm_mode); + drm_mode = drm_mode_create(dev); + drm_mode->hdisplay = var->xres; + drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin; + drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len; + drm_mode->htotal = drm_mode->hsync_end + var->left_margin; + drm_mode->vdisplay = var->yres; + drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin; + drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len; + drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin; + drm_mode->clock = PICOS2KHZ(var->pixclock); + drm_mode->vrefresh = drm_mode_vrefresh(drm_mode); drm_mode->flags = 0; drm_mode->flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; drm_mode->flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; - drm_mode_set_name(drm_mode); + drm_mode_set_name(drm_mode); drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V); found = 0; - list_for_each_entry(output, &dev->mode_config.output_list, head) { - if (output->crtc == par->crtc){ + list_for_each_entry(output, &dev->mode_config.output_list, head) { + if (output->crtc == par->crtc){ found = 1; - break; + break; } - } + } /* no output bound, bail */ if (!found) return -EINVAL; found = 0; - drm_mode_debug_printmodeline(dev, drm_mode); - list_for_each_entry(search_mode, &output->modes, head) { + drm_mode_debug_printmodeline(dev, drm_mode); + list_for_each_entry(search_mode, &output->modes, head) { drm_mode_debug_printmodeline(dev, search_mode); if (drm_mode_equal(drm_mode, search_mode)) { drm_mode_destroy(dev, drm_mode); @@ -296,8 +297,8 @@ static int intelfb_set_par(struct fb_info *info) } /* If we didn't find a matching mode that exists on our output, - * create a new attachment for the incoming user specified mode - */ + * create a new attachment for the incoming user specified mode + */ if (!found) { if (par->fb_mode) { /* this also destroys the mode */ @@ -318,7 +319,7 @@ static int intelfb_set_par(struct fb_info *info) if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset) changed = 1; - + drm_mode_debug_printmodeline(dev, drm_mode); drm_mode_debug_printmodeline(dev, &par->crtc->mode); if (!drm_mode_equal(drm_mode, &par->crtc->mode)) @@ -333,9 +334,9 @@ static int intelfb_set_par(struct fb_info *info) #if 0 static void intelfb_copyarea(struct fb_info *info, - const struct fb_copyarea *region) + const struct fb_copyarea *region) { - struct intelfb_par *par = info->par; + struct intelfb_par *par = info->par; struct drm_device *dev = par->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 src_x1, src_y1, dst_x1, dst_y1, dst_x2, dst_y2, offset; @@ -380,7 +381,7 @@ static void intelfb_copyarea(struct fb_info *info, void intelfb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct intelfb_par *par = info->par; + struct intelfb_par *par = info->par; struct drm_device *dev = par->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 cmd, rop_pitch_depth, tmp; @@ -397,9 +398,9 @@ void intelfb_imageblit(struct fb_info *info, const struct fb_image *image) nbytes *= image->height; /* - * Check if the glyph data exceeds the immediate mode limit. - * It would take a large font (1K pixels) to hit this limit. - */ + * Check if the glyph data exceeds the immediate mode limit. + * It would take a large font (1K pixels) to hit this limit. + */ if (nbytes > 128 || image->depth != 1) return cfb_imageblit(info, image); @@ -407,13 +408,13 @@ void intelfb_imageblit(struct fb_info *info, const struct fb_image *image) ndwords = ROUND_UP_TO(nbytes, 4) / 4; /* - * Ring has to be padded to a quad word. But because the command starts - with 7 bytes, pad only if there is an even number of ndwords - */ + * Ring has to be padded to a quad word. But because the command starts + with 7 bytes, pad only if there is an even number of ndwords + */ pad = !(ndwords % 2); DRM_DEBUG("imageblit %dx%dx%d to (%d,%d)\n", image->width, - image->height, image->depth, image->dx, image->dy); + image->height, image->depth, image->dx, image->dy); DRM_DEBUG("nbytes: %d, ndwords: %d, pad: %d\n", nbytes, ndwords, pad); tmp = (XY_MONO_SRC_COPY_IMM_BLT & 0xff) + ndwords; @@ -477,7 +478,7 @@ void intelfb_imageblit(struct fb_info *info, const struct fb_image *image) } #endif static int intelfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) + struct fb_info *info) { struct intelfb_par *par = info->par; struct drm_crtc *crtc = par->crtc; @@ -505,11 +506,11 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var, static struct fb_ops intelfb_ops = { .owner = THIS_MODULE, - // .fb_open = intelfb_open, - // .fb_read = intelfb_read, - // .fb_write = intelfb_write, - // .fb_release = intelfb_release, - // .fb_ioctl = intelfb_ioctl, + //.fb_open = intelfb_open, + //.fb_read = intelfb_read, + //.fb_write = intelfb_write, + //.fb_release = intelfb_release, + //.fb_ioctl = intelfb_ioctl, .fb_check_var = intelfb_check_var, .fb_set_par = intelfb_set_par, .fb_setcolreg = intelfb_setcolreg, @@ -590,14 +591,14 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8); fb->depth = 24; ret = drm_buffer_object_create(dev, fb->pitch * fb->height, - drm_bo_type_kernel, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, 0, 0, - &fbo); + drm_bo_type_kernel, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0, 0, + &fbo); if (ret || !fbo) { printk(KERN_ERR "failed to allocate framebuffer\n"); drm_framebuffer_destroy(fb); @@ -607,7 +608,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) fb->bo = fbo; printk("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width, - fb->height, fbo->offset, fbo); + fb->height, fbo->offset, fbo); fb->fbdev = info; @@ -645,9 +646,9 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) info->flags = FBINFO_DEFAULT; ret = drm_bo_kmap(fb->bo, 0, fb->bo->num_pages, &fb->kmap); - if (ret) - DRM_ERROR("error mapping fb: %d\n", ret); - + if (ret) + DRM_ERROR("error mapping fb: %d\n", ret); + info->screen_base = fb->kmap.virtual; info->screen_size = info->fix.smem_len; /* FIXME */ info->pseudo_palette = fb->pseudo_palette; @@ -660,13 +661,13 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) info->var.height = -1; info->var.width = -1; - info->var.xres = mode->hdisplay; - info->var.right_margin = mode->hsync_start - mode->hdisplay; - info->var.hsync_len = mode->hsync_end - mode->hsync_start; - info->var.left_margin = mode->htotal - mode->hsync_end; - info->var.yres = mode->vdisplay; - info->var.lower_margin = mode->vsync_start - mode->vdisplay; - info->var.vsync_len = mode->vsync_end - mode->vsync_start; + info->var.xres = mode->hdisplay; + info->var.right_margin = mode->hsync_start - mode->hdisplay; + info->var.hsync_len = mode->hsync_end - mode->hsync_start; + info->var.left_margin = mode->htotal - mode->hsync_end; + info->var.yres = mode->vdisplay; + info->var.lower_margin = mode->vsync_start - mode->vdisplay; + info->var.vsync_len = mode->vsync_end - mode->vsync_start; info->var.upper_margin = mode->vtotal - mode->vsync_end; info->var.pixclock = KHZ2PICOS(mode->clock); @@ -693,48 +694,51 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) DRM_DEBUG(" pitch is %d\n", fb->pitch); switch(fb->depth) { case 8: - info->var.red.offset = 0; - info->var.green.offset = 0; - info->var.blue.offset = 0; - info->var.red.length = 8; /* 8bit DAC */ - info->var.green.length = 8; - info->var.blue.length = 8; - info->var.transp.offset = 0; - info->var.transp.length = 0; - break; + info->var.red.offset = 0; + info->var.green.offset = 0; + info->var.blue.offset = 0; + info->var.red.length = 8; /* 8bit DAC */ + info->var.green.length = 8; + info->var.blue.length = 8; + info->var.transp.offset = 0; + info->var.transp.length = 0; + break; case 15: - info->var.red.offset = 10; - info->var.green.offset = 5; - info->var.blue.offset = 0; - info->var.red.length = info->var.green.length = - info->var.blue.length = 5; - info->var.transp.offset = 15; - info->var.transp.length = 1; - break; + info->var.red.offset = 10; + info->var.green.offset = 5; + info->var.blue.offset = 0; + info->var.red.length = 5; + info->var.green.length = 5; + info->var.blue.length = 5; + info->var.transp.offset = 15; + info->var.transp.length = 1; + break; case 16: - info->var.red.offset = 11; - info->var.green.offset = 5; - info->var.blue.offset = 0; - info->var.red.length = 5; - info->var.green.length = 6; - info->var.blue.length = 5; - info->var.transp.offset = 0; + info->var.red.offset = 11; + info->var.green.offset = 5; + info->var.blue.offset = 0; + info->var.red.length = 5; + info->var.green.length = 6; + info->var.blue.length = 5; + info->var.transp.offset = 0; break; case 24: - info->var.red.offset = 16; - info->var.green.offset = 8; - info->var.blue.offset = 0; - info->var.red.length = info->var.green.length = - info->var.blue.length = 8; - info->var.transp.offset = 0; - info->var.transp.length = 0; - break; + info->var.red.offset = 16; + info->var.green.offset = 8; + info->var.blue.offset = 0; + info->var.red.length = 8; + info->var.green.length = 8; + info->var.blue.length = 8; + info->var.transp.offset = 0; + info->var.transp.length = 0; + break; case 32: info->var.red.offset = 16; info->var.green.offset = 8; info->var.blue.offset = 0; - info->var.red.length = info->var.green.length = - info->var.blue.length = 8; + info->var.red.length = 8; + info->var.green.length = 8; + info->var.blue.length = 8; info->var.transp.offset = 24; info->var.transp.length = 8; break; @@ -746,7 +750,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc) return -EINVAL; printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, - info->fix.id); + info->fix.id); return 0; } EXPORT_SYMBOL(intelfb_probe); commit ba36d54ad4a3ea52b338d55ca19a864283e7c9ce Author: Jakob Bornecrantz <ja...@tu...> Date: Thu May 8 15:00:18 2008 +0200 drm: Made set_config use drm_mode_set as a argument diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 2d1c806..bdcf5f9 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1130,16 +1130,27 @@ EXPORT_SYMBOL(drm_mode_config_cleanup); * RETURNS: * Zero. (FIXME) */ -int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set, struct drm_framebuffer *fb) +int drm_crtc_set_config(struct drm_mode_set *set) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev; struct drm_crtc **save_crtcs, *new_crtc; - bool save_enabled = crtc->enabled; + bool save_enabled; bool changed = false; bool flip_or_move = false; struct drm_output *output; int count = 0, ro; + if (!set) + return -EINVAL; + + if (!set->crtc) + return -EINVAL; + + dev = set->crtc->dev; + + /* save previous config */ + save_enabled = set->crtc->enabled; + /* this is meant to be num_output not num_crtc */ save_crtcs = kzalloc(dev->mode_config.num_output * sizeof(struct drm_crtc *), GFP_KERNEL); if (!save_crtcs) @@ -1147,30 +1158,30 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, /* We should be able to check here if the fb has the same properties * and then just flip_or_move it */ - if (crtc->fb != fb) + if (set->crtc->fb != set->fb) flip_or_move = true; - if (crtc_info->x != crtc->x || crtc_info->y != crtc->y) + if (set->x != set->crtc->x || set->y != set->crtc->y) flip_or_move = true; - if (new_mode && !drm_mode_equal(new_mode, &crtc->mode)) { + if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { DRM_DEBUG("modes are different\n"); - drm_mode_debug_printmodeline(dev, &crtc->mode); - drm_mode_debug_printmodeline(dev, new_mode); + drm_mode_debug_printmodeline(dev, &set->crtc->mode); + drm_mode_debug_printmodeline(dev, set->mode); changed = true; } list_for_each_entry(output, &dev->mode_config.output_list, head) { save_crtcs[count++] = output->crtc; - if (output->crtc == crtc) + if (output->crtc == set->crtc) new_crtc = NULL; else new_crtc = output->crtc; - for (ro = 0; ro < crtc_info->count_outputs; ro++) { - if (output_set[ro] == output) - new_crtc = crtc; + for (ro = 0; ro < set->num_outputs; ro++) { + if (set->outputs[ro] == output) + new_crtc = set->crtc; } if (new_crtc != output->crtc) { changed = true; @@ -1179,33 +1190,34 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, } /* mode_set_base is not a required function */ - if (flip_or_move && !crtc->funcs->mode_set_base) + if (flip_or_move && !set->crtc->funcs->mode_set_base) changed = true; if (changed) { - crtc->fb = fb; - crtc->enabled = (new_mode != NULL); - if (new_mode != NULL) { + set->crtc->fb = set->fb; + set->crtc->enabled = (set->mode != NULL); + if (set->mode != NULL) { DRM_DEBUG("attempting to set mode from userspace\n"); - drm_mode_debug_printmodeline(dev, new_mode); - if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x, - crtc_info->y)) { - crtc->enabled = save_enabled; + drm_mode_debug_printmodeline(dev, set->mode); + if (!drm_crtc_set_mode(set->crtc, set->mode, set->x, + set->y)) { + set->crtc->enabled = save_enabled; count = 0; list_for_each_entry(output, &dev->mode_config.output_list, head) output->crtc = save_crtcs[count++]; kfree(save_crtcs); return -EINVAL; } - crtc->desired_x = crtc_info->x; - crtc->desired_y = crtc_info->y; - crtc->desired_mode = new_mode; + /* TODO are these needed? */ + set->crtc->desired_x = set->x; + set->crtc->desired_y = set->y; + set->crtc->desired_mode = set->mode; } drm_disable_unused_functions(dev); } else if (flip_or_move) { - if (crtc->fb != fb) - crtc->fb = fb; - crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y); + if (set->crtc->fb != set->fb) + set->crtc->fb = set->fb; + set->crtc->funcs->mode_set_base(set->crtc, set->x, set->y); } kfree(save_crtcs); @@ -1648,6 +1660,7 @@ int drm_mode_setcrtc(struct drm_device *dev, struct drm_output **output_set = NULL, *output; struct drm_framebuffer *fb = NULL; struct drm_display_mode *mode = NULL; + struct drm_mode_set set; uint32_t __user *set_outputs_ptr; int ret = 0; int i; @@ -1724,7 +1737,14 @@ int drm_mode_setcrtc(struct drm_device *dev, } } - ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb); + set.crtc = crtc; + set.x = crtc_req->x; + set.y = crtc_req->y; + set.mode = mode; + set.outputs = output_set; + set.num_outputs = crtc_req->count_outputs; + set.fb =fb; + ret = drm_crtc_set_config(&set); out: kfree(output_set); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 64e7e51..abe8f3f 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -475,11 +475,17 @@ struct drm_output { * * Represents a single crtc the outputs that it drives with what mode * and from which framebuffer it scans out from. + * + * This is used to set modes. */ struct drm_mode_set { struct drm_framebuffer *fb; struct drm_crtc *crtc; + struct drm_display_mode *mode; + + uint32_t x; + uint32_t y; struct drm_output **outputs; size_t num_outputs; |
From: <ai...@ke...> - 2008-05-12 06:34:54
|
linux-core/drm_bufs.c | 2 +- linux-core/drm_drv.c | 46 +++++++++++++++++++++++----------------------- linux-core/drm_fops.c | 1 + linux-core/drm_proc.c | 3 +++ shared-core/i915_dma.c | 4 ++-- 5 files changed, 30 insertions(+), 26 deletions(-) New commits: commit 3f66a0005c1273b0fc935b9bd62a6fabaf99c2be Author: Dave Airlie <ai...@re...> Date: Mon May 12 16:29:13 2008 +1000 drm: remove root only from a lot of drm ioctls to get stuff running as non-root diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index f6ff75a..e905257 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -345,7 +345,7 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data, struct drm_map_list *maplist; int err; - if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP)) + if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM)) return -EPERM; err = drm_addmap_core(dev, map->offset, map->size, map->type, diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 82a9c19..d96b14b 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -59,18 +59,18 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), - DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), - DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), - DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -103,7 +103,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER), #if __OS_HAS_AGP DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -124,20 +124,20 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY | DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0), @@ -651,7 +651,7 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (cmd & IOC_IN) { if (copy_from_user(kdata, (void __user *)arg, _IOC_SIZE(cmd)) != 0) { - retcode = -EACCES; + retcode = -EFAULT; goto err_i1; } } @@ -671,13 +671,13 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if ((retcode == 0) && (cmd & IOC_OUT)) { if (copy_to_user((void __user *)arg, kdata, _IOC_SIZE(cmd)) != 0) - retcode = -EACCES; + retcode = -EFAULT; } err_i1: atomic_dec(&dev->ioctl_count); if (retcode) - DRM_DEBUG("ret = %d\n", retcode); + DRM_ERROR("ret = %x %d\n", nr, retcode); return retcode; } EXPORT_SYMBOL(drm_unlocked_ioctl); diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f3a963b..fc9e0e4 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1026,14 +1026,14 @@ static int i915_set_status_page(struct drm_device *dev, void *data, } struct drm_ioctl_desc i915_ioctls[] = { - DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER), DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), commit 1eedeed09192738334570e13acab381441f3d817 Author: Dave Airlie <ai...@re...> Date: Mon May 12 16:28:58 2008 +1000 drm: masters are always authenticated diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index a9f39ac..03881ee 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -281,6 +281,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->is_master = 1; priv->master = priv->minor->master; + priv->authenticated = 1; mutex_unlock(&dev->struct_mutex); if (dev->driver->master_create) { ret = dev->driver->master_create(dev, priv->master); commit 8f7fc880e8bbe9e59521df707f2ddd3e80e06e6f Author: Dave Airlie <ai...@re...> Date: Mon May 12 16:28:40 2008 +1000 drm: fix oops on reading proc file with no master diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index b6748b9..7f18520 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -175,6 +175,9 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request, return 0; } + if (!master) + return 0; + *start = &buf[offset]; *eof = 0; |
From: <ai...@ke...> - 2008-06-04 03:25:33
|
linux-core/drm_crtc.c | 1 - linux-core/drm_sysfs.c | 3 +++ linux-core/intel_display.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) New commits: commit 9f31bd09c1e748f72a30f6a0861cd72d93258992 Author: Dave Airlie <ai...@re...> Date: Wed Jun 4 13:16:49 2008 +1000 drm/sysfs: don't try an unregister if not registered diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index 01a3c04..c148256 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -301,6 +301,9 @@ void drm_sysfs_connector_remove(struct drm_connector *connector) { int i; + if (!device_is_registered(&connector->kdev)) + return; + DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_connector_name(connector)); for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) device_remove_file(&connector->kdev, &connector_attrs[i]); commit 8e4c61e52651c47f3d9fbbe5e80455baff0de2bb Author: Dave Airlie <ai...@re...> Date: Wed Jun 4 13:09:20 2008 +1000 intel: use kzalloc diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 3f5afac..6493af1 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1491,7 +1491,7 @@ struct drm_framebuffer *intel_user_framebuffer_create(struct drm_device *dev, { struct intel_framebuffer *intel_fb; - intel_fb = kmalloc(sizeof(*intel_fb), GFP_KERNEL); + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) return NULL; commit 8690ad8ae0778f2ccd8b428e1c6a8614ebc51707 Author: Dave Airlie <ai...@re...> Date: Wed Jun 4 13:09:05 2008 +1000 drm/modesetting: bo not used anymore diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 73ad317..d2060fd 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1257,7 +1257,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, struct drm_mode_cursor *req = data; struct drm_mode_object *obj; struct drm_crtc *crtc; - struct drm_buffer_object *bo = NULL; /* must be set */ int ret = 0; DRM_DEBUG("\n"); |
From: <mad...@ke...> - 2008-06-25 13:16:55
|
linux-core/nv50_crtc.c | 10 ++-- linux-core/nv50_crtc.h | 1 linux-core/nv50_cursor.c | 18 ++++++++ linux-core/nv50_cursor.h | 1 shared-core/nouveau_drm.h | 4 + shared-core/nouveau_drv.h | 2 shared-core/nouveau_mem.c | 87 ++++++++++++++++++++++++++++++----------- shared-core/nouveau_notifier.c | 2 shared-core/nouveau_object.c | 2 shared-core/nv50_fifo.c | 4 + 10 files changed, 100 insertions(+), 31 deletions(-) New commits: commit 09b67dda0bc040860aedce4a2d28bce1c80e56d6 Author: Maarten Maathuis <mad...@gm...> Date: Wed Jun 25 15:16:38 2008 +0200 NV50: Some cleanup and fixes. diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c index 0bcf305..af2f03d 100644 --- a/linux-core/nv50_crtc.c +++ b/linux-core/nv50_crtc.c @@ -192,10 +192,9 @@ static int nv50_crtc_blank(struct nv50_crtc *crtc, bool blanked) } else { OUT_MODE(NV50_CRTC0_FB_OFFSET + offset, crtc->fb->block->start >> 8); OUT_MODE(0x864 + offset, 0); - if (crtc->cursor->block) - OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + offset, crtc->cursor->block->start >> 8); - else - OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + offset, 0); + + crtc->cursor->set_offset(crtc); + if (dev_priv->chipset != 0x50) OUT_MODE(NV84_CRTC0_BLANK_UNK2 + offset, NV84_CRTC0_BLANK_UNK2_UNBLANK); @@ -212,6 +211,9 @@ static int nv50_crtc_blank(struct nv50_crtc *crtc, bool blanked) OUT_MODE(NV50_CRTC0_BLANK_CTRL + offset, NV50_CRTC0_BLANK_CTRL_UNBLANK); } + /* sometimes you need to know if a screen is already blanked. */ + crtc->blanked = blanked; + return 0; } diff --git a/linux-core/nv50_crtc.h b/linux-core/nv50_crtc.h index 0eadc3d..b63c5a2 100644 --- a/linux-core/nv50_crtc.h +++ b/linux-core/nv50_crtc.h @@ -39,6 +39,7 @@ struct nv50_crtc { struct drm_device *dev; int index; bool active; + bool blanked; struct nouveau_hw_mode *mode; struct nouveau_hw_mode *native_mode; diff --git a/linux-core/nv50_cursor.c b/linux-core/nv50_cursor.c index 47ae11b..091c94f 100644 --- a/linux-core/nv50_cursor.c +++ b/linux-core/nv50_cursor.c @@ -103,6 +103,21 @@ static int nv50_cursor_set_pos(struct nv50_crtc *crtc, int x, int y) return 0; } +static int nv50_cursor_set_offset(struct nv50_crtc *crtc) +{ + struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; + + NV50_DEBUG("\n"); + + if (crtc->cursor->block) { + OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x400, crtc->cursor->block->start >> 8); + } else { + OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x400, 0); + } + + return 0; +} + static int nv50_cursor_set_bo(struct nv50_crtc *crtc, drm_handle_t handle) { struct mem_block *block = NULL; @@ -121,7 +136,7 @@ static int nv50_cursor_set_bo(struct nv50_crtc *crtc, drm_handle_t handle) /* set the cursor offset cursor */ if (first_time) { - OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x400, crtc->cursor->block->start >> 8); + crtc->cursor->set_offset(crtc); if (crtc->cursor->visible) crtc->cursor->show(crtc); } @@ -148,6 +163,7 @@ int nv50_cursor_create(struct nv50_crtc *crtc) crtc->cursor->show = nv50_cursor_show; crtc->cursor->hide = nv50_cursor_hide; crtc->cursor->set_pos = nv50_cursor_set_pos; + crtc->cursor->set_offset = nv50_cursor_set_offset; crtc->cursor->set_bo = nv50_cursor_set_bo; crtc->cursor->enable = nv50_cursor_enable; crtc->cursor->disable = nv50_cursor_disable; diff --git a/linux-core/nv50_cursor.h b/linux-core/nv50_cursor.h index a2e4632..4fd0d39 100644 --- a/linux-core/nv50_cursor.h +++ b/linux-core/nv50_cursor.h @@ -40,6 +40,7 @@ struct nv50_cursor { int (*show) (struct nv50_crtc *crtc); int (*hide) (struct nv50_crtc *crtc); int (*set_pos) (struct nv50_crtc *crtc, int x, int y); + int (*set_offset) (struct nv50_crtc *crtc); int (*set_bo) (struct nv50_crtc *crtc, drm_handle_t handle); int (*enable) (struct nv50_crtc *crtc); int (*disable) (struct nv50_crtc *crtc); diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 51ac48d..4acd6bd 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -34,6 +34,8 @@ #include "drm.h" #include "drm_sarea.h" #include "nouveau_drv.h" +#include "nv50_kms_wrapper.h" + static struct mem_block * split_block(struct mem_block *p, uint64_t start, uint64_t size, @@ -730,6 +732,33 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags); + /* Check if the deallocations cause problems for our modesetting system. */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (dev_priv->card_type >= NV_50) { + struct nv50_crtc *crtc = NULL; + struct nv50_display *display = nv50_get_display(dev); + + list_for_each_entry(crtc, &display->crtcs, head) { + if (crtc->fb->block == block) { + crtc->fb->block = NULL; + + /* this will force a lut change next time a fb is loaded */ + crtc->lut->depth = 0; + + if (!crtc->blanked) + crtc->blank(crtc, TRUE); + } + + if (crtc->cursor->block == block) { + crtc->cursor->block = NULL; + + if (crtc->cursor->visible) + crtc->cursor->hide(crtc); + } + } + } + } + if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); commit be7276281694145e7c947b91a1c8e6e347de666c Author: Ben Skeggs <sk...@gm...> Date: Wed Jun 25 16:45:41 2008 +1000 nv50: when destroying a channel make sure it's not still current on PFIFO We won't get a PFIFO context switch when the same channel ID is recreated if the hw still thinks the channel is already active, which causes fun issues. Should allow X to be stopped and started without tearing down the entire card state in lastclose(). diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c index edf4edb..d681066 100644 --- a/shared-core/nv50_fifo.c +++ b/shared-core/nv50_fifo.c @@ -289,6 +289,7 @@ void nv50_fifo_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; DRM_DEBUG("ch%d\n", chan->id); @@ -298,6 +299,9 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) if (chan->id == 0) nv50_fifo_channel_disable(dev, 127, 0); + if ((NV_READ(NV03_PFIFO_CACHE1_PUSH1) & 0xffff) == chan->id) + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 127); + nouveau_gpuobj_ref_del(dev, &chan->ramfc); } commit 5a0164d1e1799b68b3131efd7b9fcaf20c578257 Author: Ben Skeggs <sk...@ni...> Date: Mon Jun 23 01:00:42 2008 +1000 nouveau: allocate drm-use vram buffers from end of vram. This avoids seeing garbage from engine setup etc before X gets around to pointing the CRTCs at a new scanout buffer. Not actually a noticable problem before G80 as PRAMIN is forced to the end of VRAM by the hardware already. diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index cf76205..bbb51bc 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -88,9 +88,11 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ #define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ #define NOUVEAU_MEM_NOVM 0x00000800 /* internal */ +#define NOUVEAU_MEM_USER 0x00001000 /* internal */ #define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ NOUVEAU_MEM_NOTIFIER | \ - NOUVEAU_MEM_NOVM) + NOUVEAU_MEM_NOVM | \ + NOUVEAU_MEM_USER) struct drm_nouveau_mem_alloc { int flags; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 20aa6b8..33e2a5b 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -375,7 +375,7 @@ extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, uint64_t size); extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, uint64_t size, int align2, - struct drm_file *); + struct drm_file *, int tail); extern void nouveau_mem_takedown(struct mem_block **heap); extern void nouveau_mem_free_block(struct mem_block *); extern struct mem_block* find_block_by_handle(struct mem_block *heap, drm_handle_t handle); diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 810eaf9..51ac48d 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -35,8 +35,9 @@ #include "drm_sarea.h" #include "nouveau_drv.h" -static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, - struct drm_file *file_priv) +static struct mem_block * +split_block(struct mem_block *p, uint64_t start, uint64_t size, + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -77,10 +78,9 @@ out: return p; } -struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, - uint64_t size, - int align2, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, + int align2, struct drm_file *file_priv, int tail) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -88,10 +88,22 @@ struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, if (!heap) return NULL; - list_for_each(p, heap) { - uint64_t start = (p->start + mask) & ~mask; - if (p->file_priv == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); + if (tail) { + list_for_each_prev(p, heap) { + uint64_t start = ((p->start + p->size) - size) & ~mask; + + if (p->file_priv == 0 && start >= p->start && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } + } else { + list_for_each(p, heap) { + uint64_t start = (p->start + mask) & ~mask; + + if (p->file_priv == 0 && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } } return NULL; @@ -574,13 +586,13 @@ int nouveau_mem_init(struct drm_device *dev) return 0; } -struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, - uint64_t size, int flags, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, + int flags, struct drm_file *file_priv) { - struct mem_block *block; - int type; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct mem_block *block; + int type, tail = !(flags & NOUVEAU_MEM_USER); /* * Make things easier on ourselves: all allocations are page-aligned. @@ -611,14 +623,14 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, #define NOUVEAU_MEM_ALLOC_AGP {\ type=NOUVEAU_MEM_AGP;\ block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ - alignment, file_priv); \ + alignment, file_priv, tail); \ if (block) goto alloc_ok;\ } #define NOUVEAU_MEM_ALLOC_PCI {\ type = NOUVEAU_MEM_PCI;\ block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ - alignment, file_priv); \ + alignment, file_priv, tail); \ if ( block ) goto alloc_ok;\ } @@ -627,11 +639,11 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, if (!(flags&NOUVEAU_MEM_MAPPED)) {\ block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ size, alignment, \ - file_priv); \ + file_priv, tail); \ if (block) goto alloc_ok;\ }\ block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ - alignment, file_priv);\ + alignment, file_priv, tail);\ if (block) goto alloc_ok;\ } @@ -749,7 +761,9 @@ out_free: * Ioctls */ -int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) +int +nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; @@ -759,8 +773,8 @@ int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file if (alloc->flags & NOUVEAU_MEM_INTERNAL) return -EINVAL; - block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, - alloc->flags, file_priv); + block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size, + alloc->flags | NOUVEAU_MEM_USER, file_priv); if (!block) return -ENOMEM; alloc->map_handle=block->map_handle; diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c index 82c8ab7..edece4d 100644 --- a/shared-core/nouveau_notifier.c +++ b/shared-core/nouveau_notifier.c @@ -94,7 +94,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, } mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0, - (struct drm_file *)-2); + (struct drm_file *)-2, 0); if (!mem) { DRM_ERROR("Channel %d notifier block full\n", chan->id); return -ENOMEM; diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 09f9027..5664bfc 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -248,7 +248,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, /* Allocate a chunk of the PRAMIN aperture */ gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, drm_order(align), - (struct drm_file *)-2); + (struct drm_file *)-2, 0); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); return -ENOMEM; |