linux-next conflict reported needed resolution.
Conflicts:
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/ttm/ttm_bo.c
goto out;
}
- if (crtc_req->count_connectors > 0 && !mode && !fb) {
+ if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
- DRM_DEBUG("Count connectors is %d but no mode or fb set\n",
+ DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
crtc_req->count_connectors);
ret = -EINVAL;
goto out;
if (set->crtc->fb != set->fb) {
/* If we have no fb then treat it as a full mode set */
if (set->crtc->fb == NULL) {
- DRM_DEBUG("crtc has no fb, full mode set\n");
+ DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
mode_changed = true;
+ } else if (set->fb == NULL) {
+ mode_changed = true;
} else if ((set->fb->bits_per_pixel !=
set->crtc->fb->bits_per_pixel) ||
set->fb->depth != set->crtc->fb->depth)
struct detailed_non_pixel *data = &timing->data.other_data;
struct drm_display_mode *newmode;
- /* EDID up to and including 1.2 may put monitor info here */
- if (edid->version == 1 && edid->revision < 3)
- continue;
-
- /* Detailed mode timing */
- if (timing->pixel_clock) {
+ /* X server check is version 1.1 or higher */
+ if (edid->version == 1 && edid->revision >= 1 &&
+ !timing->pixel_clock) {
+ /* Other timing or info */
+ switch (data->type) {
+ case EDID_DETAIL_MONITOR_SERIAL:
+ break;
+ case EDID_DETAIL_MONITOR_STRING:
+ break;
+ case EDID_DETAIL_MONITOR_RANGE:
+ /* Get monitor range data */
+ break;
+ case EDID_DETAIL_MONITOR_NAME:
+ break;
+ case EDID_DETAIL_MONITOR_CPDATA:
+ break;
+ case EDID_DETAIL_STD_MODES:
+ /* Five modes per detailed section */
+ for (j = 0; j < 5; i++) {
+ struct std_timing *std;
+ struct drm_display_mode *newmode;
+
+ std = &data->data.timings[j];
- newmode = drm_mode_std(dev, std);
++ newmode = drm_mode_std(dev, std,
++ timing_level);
+ if (newmode) {
+ drm_mode_probed_add(connector, newmode);
+ modes++;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
newmode = drm_mode_detailed(dev, edid, timing, quirks);
if (!newmode)
continue;
intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
status = intel_sdvo_read_response(intel_output, &response, 2);
- DRM_DEBUG_KMS("SDVO response %d %d\n", response[0], response[1]);
- DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8);
++ DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
if (status != SDVO_CMD_STATUS_SUCCESS)
return connector_status_unknown;
return 0x72;
}
- DRM_DEBUG_KMS(I915_SDVO,
- "%s: Unknown SDVO output type (0x%02x%02x)\n",
- SDVO_NAME(sdvo_priv),
- bytes[0], bytes[1]);
+ static bool
+ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+ {
+ struct drm_connector *connector = &intel_output->base;
+ struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ bool ret = true, registered = false;
+
+ sdvo_priv->is_tv = false;
+ intel_output->needs_tv_clock = false;
+ sdvo_priv->is_lvds = false;
+
+ if (device_is_registered(&connector->kdev)) {
+ drm_sysfs_connector_remove(connector);
+ registered = true;
+ }
+
+ if (flags &
+ (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+ if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+ else
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+
+ encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
+ connector->connector_type = DRM_MODE_CONNECTOR_DVID;
+
+ if (intel_sdvo_get_supp_encode(intel_output,
+ &sdvo_priv->encode) &&
+ intel_sdvo_get_digital_encoding_mode(intel_output) &&
+ sdvo_priv->is_hdmi) {
+ /* enable hdmi encoding mode if supported */
+ intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
+ intel_sdvo_set_colorimetry(intel_output,
+ SDVO_COLORIMETRY_RGB256);
+ connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+ }
+ } else if (flags & SDVO_OUTPUT_SVID0) {
+
+ sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
+ encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+ connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+ sdvo_priv->is_tv = true;
+ intel_output->needs_tv_clock = true;
+ } else if (flags & SDVO_OUTPUT_RGB0) {
+
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
+ encoder->encoder_type = DRM_MODE_ENCODER_DAC;
+ connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+ } else if (flags & SDVO_OUTPUT_RGB1) {
+
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
+ encoder->encoder_type = DRM_MODE_ENCODER_DAC;
+ connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+ } else if (flags & SDVO_OUTPUT_LVDS0) {
+
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
+ encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+ sdvo_priv->is_lvds = true;
+ } else if (flags & SDVO_OUTPUT_LVDS1) {
+
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
+ encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+ sdvo_priv->is_lvds = true;
+ } else {
+
+ unsigned char bytes[2];
+
+ sdvo_priv->controlled_output = 0;
+ memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
++ DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
++ SDVO_NAME(sdvo_priv),
++ bytes[0], bytes[1]);
+ ret = false;
+ }
+
+ if (ret && registered)
+ ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
+
+
+ return ret;
+
+ }
+
bool intel_sdvo_init(struct drm_device *dev, int output_device)
{
struct drm_connector *connector;
intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
/* In defaut case sdvo lvds is false */
- sdvo_priv->is_lvds = false;
intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
- if (sdvo_priv->caps.output_flags &
- (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
- if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
- sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
- else
- sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
-
- encoder_type = DRM_MODE_ENCODER_TMDS;
- connector_type = DRM_MODE_CONNECTOR_DVID;
-
- if (intel_sdvo_get_supp_encode(intel_output,
- &sdvo_priv->encode) &&
- intel_sdvo_get_digital_encoding_mode(intel_output) &&
- sdvo_priv->is_hdmi) {
- /* enable hdmi encoding mode if supported */
- intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
- intel_sdvo_set_colorimetry(intel_output,
- SDVO_COLORIMETRY_RGB256);
- connector_type = DRM_MODE_CONNECTOR_HDMIA;
- }
- }
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
- {
- sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
- encoder_type = DRM_MODE_ENCODER_TVDAC;
- connector_type = DRM_MODE_CONNECTOR_SVIDEO;
- sdvo_priv->is_tv = true;
- intel_output->needs_tv_clock = true;
- }
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
- {
- sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
- encoder_type = DRM_MODE_ENCODER_DAC;
- connector_type = DRM_MODE_CONNECTOR_VGA;
- }
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
- {
- sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
- encoder_type = DRM_MODE_ENCODER_DAC;
- connector_type = DRM_MODE_CONNECTOR_VGA;
- }
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
- {
- sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
- encoder_type = DRM_MODE_ENCODER_LVDS;
- connector_type = DRM_MODE_CONNECTOR_LVDS;
- sdvo_priv->is_lvds = true;
- }
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
- {
- sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
- encoder_type = DRM_MODE_ENCODER_LVDS;
- connector_type = DRM_MODE_CONNECTOR_LVDS;
- sdvo_priv->is_lvds = true;
- }
- else
- {
- unsigned char bytes[2];
-
- sdvo_priv->controlled_output = 0;
- memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
- DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
- SDVO_NAME(sdvo_priv),
- bytes[0], bytes[1]);
- encoder_type = DRM_MODE_ENCODER_NONE;
- connector_type = DRM_MODE_CONNECTOR_Unknown;
+ if (intel_sdvo_output_setup(intel_output,
+ sdvo_priv->caps.output_flags) != true) {
- DRM_DEBUG("SDVO output failed to setup on SDVO%c\n",
++ DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
+ output_device == SDVOB ? 'B' : 'C');
goto err_i2c;
}
}
/* No others user of address space so set it to 0 */
r = ttm_bo_device_init(&rdev->mman.bdev,
- rdev->mman.mem_global_ref.object,
+ rdev->mman.bo_global_ref.ref.object,
- &radeon_bo_driver, DRM_FILE_PAGE_OFFSET);
+ &radeon_bo_driver, DRM_FILE_PAGE_OFFSET,
+ rdev->need_dma32);
if (r) {
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
return r;
#define TTM_BO_HASH_ORDER 13
static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
- static void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo);
static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
+static void ttm_bo_global_kobj_release(struct kobject *kobj);
+
+static struct attribute ttm_bo_count = {
+ .name = "bo_count",
+ .mode = S_IRUGO
+};
+
+static ssize_t ttm_bo_global_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buffer)
+{
+ struct ttm_bo_global *glob =
+ container_of(kobj, struct ttm_bo_global, kobj);
+
+ return snprintf(buffer, PAGE_SIZE, "%lu\n",
+ (unsigned long) atomic_read(&glob->bo_count));
+}
+
+static struct attribute *ttm_bo_global_attrs[] = {
+ &ttm_bo_count,
+ NULL
+};
+
+static struct sysfs_ops ttm_bo_global_ops = {
+ .show = &ttm_bo_global_show
+};
+
+static struct kobj_type ttm_bo_glob_kobj_type = {
+ .release = &ttm_bo_global_kobj_release,
+ .sysfs_ops = &ttm_bo_global_ops,
+ .default_attrs = ttm_bo_global_attrs
+};
+
static inline uint32_t ttm_bo_type_flags(unsigned type)
{
int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
{
- struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ struct ttm_bo_global *glob = bdev->glob;
+ struct ttm_mem_type_manager *man;
int ret = -EINVAL;
if (mem_type >= TTM_NUM_MEM_TYPES) {
}
EXPORT_SYMBOL(ttm_bo_device_release);
-/*
- * This function is intended to be called on drm driver load.
- * If you decide to call it from firstopen, you must protect the call
- * from a potentially racing ttm_bo_driver_finish in lastclose.
- * (This may happen on X server restart).
- */
-
int ttm_bo_device_init(struct ttm_bo_device *bdev,
- struct ttm_mem_global *mem_glob,
- struct ttm_bo_driver *driver, uint64_t file_page_offset,
+ struct ttm_bo_global *glob,
+ struct ttm_bo_driver *driver,
- uint64_t file_page_offset)
++ uint64_t file_page_offset,
+ bool need_dma32)
{
int ret = -EINVAL;
INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
bdev->nice_mode = true;
INIT_LIST_HEAD(&bdev->ddestroy);
- INIT_LIST_HEAD(&bdev->swap_lru);
bdev->dev_mapping = NULL;
- ttm_mem_init_shrink(&bdev->shrink, ttm_bo_swapout);
- ret = ttm_mem_register_shrink(mem_glob, &bdev->shrink);
- if (unlikely(ret != 0)) {
- printk(KERN_ERR TTM_PFX
- "Could not register buffer object swapout.\n");
- goto out_err2;
- }
+ bdev->glob = glob;
+ bdev->need_dma32 = need_dma32;
- bdev->ttm_bo_extra_size =
- ttm_round_pot(sizeof(struct ttm_tt)) +
- ttm_round_pot(sizeof(struct ttm_backend));
-
- bdev->ttm_bo_size = bdev->ttm_bo_extra_size +
- ttm_round_pot(sizeof(struct ttm_buffer_object));
+ mutex_lock(&glob->device_list_mutex);
+ list_add_tail(&bdev->device_list, &glob->device_list);
+ mutex_unlock(&glob->device_list_mutex);
return 0;
-out_err2:
+out_no_addr_mm:
ttm_bo_clean_mm(bdev, 0);
-out_err1:
- __free_page(bdev->dummy_read_page);
-out_err0:
+out_no_sys:
return ret;
}
EXPORT_SYMBOL(ttm_bo_device_init);
int (*sync_obj_flush) (void *sync_obj, void *sync_arg);
void (*sync_obj_unref) (void **sync_obj);
void *(*sync_obj_ref) (void *sync_obj);
+
+ /* hook to notify driver about a driver move so it
+ * can do tiling things */
+ void (*move_notify)(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *new_mem);
+ /* notify the driver we are taking a fault on this BO
+ * and have reserved it */
+ void (*fault_reserve_notify)(struct ttm_buffer_object *bo);
};
-#define TTM_NUM_MEM_TYPES 8
+/**
+ * struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global.
+ */
+
+struct ttm_bo_global_ref {
+ struct ttm_global_reference ref;
+ struct ttm_mem_global *mem_glob;
+};
-#define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs
- idling before CPU mapping */
-#define TTM_BO_PRIV_FLAG_MAX 1
/**
- * struct ttm_bo_device - Buffer object driver device-specific data.
+ * struct ttm_bo_global - Buffer object driver global data.
*
* @mem_glob: Pointer to a struct ttm_mem_global object for accounting.
- * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver.
- * @count: Current number of buffer object.
- * @pages: Current number of pinned pages.
* @dummy_read_page: Pointer to a dummy page used for mapping requests
* of unpopulated pages.
- * @shrink: A shrink callback object used for buffre object swap.
+ * @shrink: A shrink callback object used for buffer object swap.
* @ttm_bo_extra_size: Extra size (sizeof(struct ttm_buffer_object) excluded)
* used by a buffer object. This is excluding page arrays and backing pages.
* @ttm_bo_size: This is @ttm_bo_extra_size + sizeof(struct ttm_buffer_object).
* !0: Failure.
*/
extern int ttm_bo_device_init(struct ttm_bo_device *bdev,
- struct ttm_mem_global *mem_glob,
+ struct ttm_bo_global *glob,
struct ttm_bo_driver *driver,
- uint64_t file_page_offset);
+ uint64_t file_page_offset, bool need_dma32);
+
+ /**
+ * ttm_bo_unmap_virtual
+ *
+ * @bo: tear down the virtual mappings for this BO
+ */
+ extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo);
/**
* ttm_bo_reserve:
#define _TTM_MODULE_H_
#include <linux/kernel.h>
+struct kobject;
- #define TTM_PFX "[TTM]"
+ #define TTM_PFX "[TTM] "
enum ttm_global_types {
TTM_GLOBAL_TTM_MEM = 0,