diff --git a/drivers/video/drm/drm_crtc.c b/drivers/video/drm/drm_crtc.c index 7e0811397f..0b95db34cc 100644 --- a/drivers/video/drm/drm_crtc.c +++ b/drivers/video/drm/drm_crtc.c @@ -2537,8 +2537,9 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) drm_for_each_crtc(tmp, crtc->dev) { if (tmp->primary->fb) drm_framebuffer_reference(tmp->primary->fb); -// if (tmp->old_fb) -// drm_framebuffer_unreference(tmp->old_fb); + if (tmp->primary->old_fb) + drm_framebuffer_unreference(tmp->primary->old_fb); + tmp->primary->old_fb = NULL; } return ret; diff --git a/drivers/video/drm/drm_probe_helper.c b/drivers/video/drm/drm_probe_helper.c index 5cc045dd9d..5bca9ff4a3 100644 --- a/drivers/video/drm/drm_probe_helper.c +++ b/drivers/video/drm/drm_probe_helper.c @@ -377,13 +377,9 @@ static void output_poll_execute(struct work_struct *work) mutex_unlock(&dev->mode_config.mutex); -out: ; +out:; -// if (changed) -// drm_kms_helper_hotplug_event(dev); -// if (repoll) -// schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); } /** diff --git a/drivers/video/drm/i915/Makefile b/drivers/video/drm/i915/Makefile index 936eb8b4df..91b830b0df 100644 --- a/drivers/video/drm/i915/Makefile +++ b/drivers/video/drm/i915/Makefile @@ -111,6 +111,7 @@ NAME_SRC= main.c \ intel_sprite.c \ intel_uncore.c \ kms_display.c \ + kos_cursor.c \ utils.c \ fwblob.asm \ ../hdmi.c \ diff --git a/drivers/video/drm/i915/i915_gem.c b/drivers/video/drm/i915/i915_gem.c index 3caeb63328..101c094837 100644 --- a/drivers/video/drm/i915/i915_gem.c +++ b/drivers/video/drm/i915/i915_gem.c @@ -2786,11 +2786,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait) struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_private *dev_priv = obj->base.dev->dev_private; int ret; - if(obj == get_fb_obj()) - { - WARN(1,"attempt to unbind fb object\n"); - return 0; - }; if (list_empty(&vma->vma_link)) return 0; @@ -3955,6 +3950,25 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, return obj; } +static bool discard_backing_storage(struct drm_i915_gem_object *obj) +{ + /* If we are the last user of the backing storage (be it shmemfs + * pages or stolen etc), we know that the pages are going to be + * immediately released. In this case, we can then skip copying + * back the contents from the GPU. + */ + + if (obj->madv != I915_MADV_WILLNEED) + return false; + + if (obj->base.filp == NULL) + return true; + +// printf("filp %p\n", obj->base.filp); + shmem_file_delete(obj->base.filp); + return true; +} + void i915_gem_free_object(struct drm_gem_object *gem_obj) { struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); @@ -3997,17 +4011,15 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) if (WARN_ON(obj->pages_pin_count)) obj->pages_pin_count = 0; + if (discard_backing_storage(obj)) + obj->madv = I915_MADV_DONTNEED; i915_gem_object_put_pages(obj); // i915_gem_object_free_mmap_offset(obj); BUG_ON(obj->pages); - - if(obj->base.filp != NULL) - { -// printf("filp %p\n", obj->base.filp); - shmem_file_delete(obj->base.filp); - } + if (obj->ops->release) + obj->ops->release(obj); drm_gem_object_release(&obj->base); i915_gem_info_remove_obj(dev_priv, obj->base.size); diff --git a/drivers/video/drm/i915/i915_gem_stolen.c b/drivers/video/drm/i915/i915_gem_stolen.c index 280663ce7c..d42224f328 100644 --- a/drivers/video/drm/i915/i915_gem_stolen.c +++ b/drivers/video/drm/i915/i915_gem_stolen.c @@ -415,16 +415,6 @@ int i915_gem_init_stolen(struct drm_device *dev) */ drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_usable_size); - { - u32 usable_size = dev_priv->gtt.stolen_usable_size >> 20; - if(i915.fbsize > usable_size) - { - i915.fbsize = usable_size; - DRM_DEBUG_KMS("Adjust framebuffer size to match reserved memory\n" - "new fbsize %dMB\n",i915.fbsize); - } - } - return 0; } diff --git a/drivers/video/drm/i915/i915_params.c b/drivers/video/drm/i915/i915_params.c index 945d2b67fb..a7c2df8029 100644 --- a/drivers/video/drm/i915/i915_params.c +++ b/drivers/video/drm/i915/i915_params.c @@ -40,7 +40,7 @@ struct i915_params i915 __read_mostly = { .preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT), .disable_power_well = -1, .enable_ips = 1, - .fastboot = 1, + .fastboot = 0, .prefault_disable = 0, .load_detect_test = 0, .reset = true, diff --git a/drivers/video/drm/i915/intel_display.c b/drivers/video/drm/i915/intel_display.c index 3936198444..8ed8f4d71d 100644 --- a/drivers/video/drm/i915/intel_display.c +++ b/drivers/video/drm/i915/intel_display.c @@ -3205,7 +3205,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; } -#if 0 static void intel_complete_page_flips(struct drm_device *dev) { struct drm_crtc *crtc; @@ -3302,7 +3301,7 @@ void intel_finish_reset(struct drm_device *dev) intel_display_resume(dev); - intel_hpd_init(dev_priv); +// intel_hpd_init(dev_priv); drm_modeset_unlock_all(dev); } @@ -3350,7 +3349,6 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) return pending; } -#endif static void intel_update_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *old_crtc_state) @@ -3931,6 +3929,28 @@ bool intel_has_pending_fb_unpin(struct drm_device *dev) return false; } +static void page_flip_completed(struct intel_crtc *intel_crtc) +{ + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); + struct intel_unpin_work *work = intel_crtc->unpin_work; + + /* ensure that the unpin work is consistent wrt ->pending. */ + smp_rmb(); + intel_crtc->unpin_work = NULL; + + if (work->event) + drm_send_vblank_event(intel_crtc->base.dev, + intel_crtc->pipe, + work->event); + + drm_crtc_vblank_put(&intel_crtc->base); + +// wake_up_all(&dev_priv->pending_flip_queue); +// queue_work(dev_priv->wq, &work->work); + +// trace_i915_flip_complete(intel_crtc->plane, +// work->pending_flip_obj); +} #if 0 void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { @@ -8057,15 +8077,13 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb->height = ((val >> 0) & 0xfff) + 1; val = I915_READ(DSPSTRIDE(pipe)); -// fb->pitches[0] = val & 0xffffffc0; - fb->pitches[0] = 2560*4; + fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_fb_align_height(dev, fb->height, fb->pixel_format, fb->modifier[0]); -// plane_config->size = fb->pitches[0] * aligned_height; - plane_config->size = i915.fbsize*1024*1024; + plane_config->size = fb->pitches[0] * aligned_height; DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", pipe_name(pipe), plane, fb->width, fb->height, @@ -9123,15 +9141,13 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, val = I915_READ(PLANE_STRIDE(pipe, 0)); stride_mult = intel_fb_stride_alignment(dev, fb->modifier[0], fb->pixel_format); -// fb->pitches[0] = (val & 0x3ff) * stride_mult; - fb->pitches[0] = 2560*4; + fb->pitches[0] = (val & 0x3ff) * stride_mult; aligned_height = intel_fb_align_height(dev, fb->height, fb->pixel_format, fb->modifier[0]); -// plane_config->size = fb->pitches[0] * aligned_height; - plane_config->size = i915.fbsize*1024*1024; + plane_config->size = fb->pitches[0] * aligned_height; DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", pipe_name(pipe), fb->width, fb->height, @@ -9222,15 +9238,13 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, fb->height = ((val >> 0) & 0xfff) + 1; val = I915_READ(DSPSTRIDE(pipe)); -// fb->pitches[0] = val & 0xffffffc0; - fb->pitches[0] = 2560*4; + fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_fb_align_height(dev, fb->height, fb->pixel_format, fb->modifier[0]); -// plane_config->size = fb->pitches[0] * aligned_height; - plane_config->size = i915.fbsize*1024*1024; + plane_config->size = fb->pitches[0] * aligned_height; DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", pipe_name(pipe), fb->width, fb->height, @@ -10748,7 +10762,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) kfree(intel_crtc); } -#if 0 static void intel_unpin_work_fn(struct work_struct *__work) { struct intel_unpin_work *work = @@ -10897,7 +10910,7 @@ static inline void intel_mark_page_flip_active(struct intel_unpin_work *work) /* and that it is marked active as soon as the irq could fire. */ smp_wmb(); } - +#if 0 static int intel_gen2_queue_flip(struct drm_device *dev, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -11378,7 +11391,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) intel_queue_rps_boost_for_request(dev, work->flip_queued_req); spin_unlock(&dev->event_lock); } - +#endif static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, @@ -11428,7 +11441,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->crtc = crtc; work->old_fb = old_fb; - INIT_WORK(&work->work, intel_unpin_work_fn); +// INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_crtc_vblank_get(crtc); if (ret) @@ -11610,7 +11623,6 @@ retry: } return ret; } -#endif /** @@ -14429,6 +14441,7 @@ static int intel_framebuffer_init(struct drm_device *dev, DRM_ERROR("framebuffer init failed %d\n", ret); return ret; } + kolibri_framebuffer_init(intel_fb); return 0; } @@ -14937,16 +14950,6 @@ void intel_modeset_init(struct drm_device *dev) * just get the first one. */ intel_find_initial_plane_obj(crtc, &plane_config); - if(!main_fb_obj) - { - struct drm_framebuffer *fb; - - fb = crtc->base.primary->fb; - main_fb_obj = intel_fb_obj(fb); - main_fb_obj->map_and_fenceable=true; - DRM_DEBUG_KMS("main_fb_obj %p gtt_offset 0x%08lx\n", main_fb_obj, i915_gem_obj_ggtt_offset(main_fb_obj)); - } - } } diff --git a/drivers/video/drm/i915/intel_drv.h b/drivers/video/drm/i915/intel_drv.h index 6d88a16ac9..3afe477625 100644 --- a/drivers/video/drm/i915/intel_drv.h +++ b/drivers/video/drm/i915/intel_drv.h @@ -118,6 +118,7 @@ enum intel_output_type { struct intel_framebuffer { struct drm_framebuffer base; struct drm_i915_gem_object *obj; + void *private; }; struct intel_fbdev { diff --git a/drivers/video/drm/i915/intel_fbdev.c b/drivers/video/drm/i915/intel_fbdev.c index b2646ccdfe..6481befb67 100644 --- a/drivers/video/drm/i915/intel_fbdev.c +++ b/drivers/video/drm/i915/intel_fbdev.c @@ -165,8 +165,14 @@ static int intelfb_alloc(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; size = PAGE_ALIGN(size); - obj = main_fb_obj; - obj->map_and_fenceable=true; + + /* If the FB is too big, just don't use it since fbdev is not very + * important and we should probably use that space with FBC or other + * features. */ + if (size * 2 < dev_priv->gtt.stolen_usable_size) + obj = i915_gem_object_create_stolen(dev, size); + if (obj == NULL) + obj = i915_gem_alloc_object(dev, size); if (!obj) { DRM_ERROR("failed to allocate framebuffer\n"); ret = -ENOMEM; @@ -214,7 +220,6 @@ static int intelfb_create(struct drm_fb_helper *helper, mutex_lock(&dev->struct_mutex); -#if 0 if (intel_fb && (sizes->fb_width > intel_fb->base.width || sizes->fb_height > intel_fb->base.height)) { @@ -225,8 +230,6 @@ static int intelfb_create(struct drm_fb_helper *helper, drm_framebuffer_unreference(&intel_fb->base); intel_fb = ifbdev->fb = NULL; } -#endif - if (!intel_fb || WARN_ON(!intel_fb->obj)) { DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); ret = intelfb_alloc(helper, sizes); @@ -253,9 +256,6 @@ static int intelfb_create(struct drm_fb_helper *helper, fb = &ifbdev->fb->base; - if(main_framebuffer == NULL) - main_framebuffer = fb; - ifbdev->helper.fb = fb; strcpy(info->fix.id, "inteldrmfb"); diff --git a/drivers/video/drm/i915/intel_panel.c b/drivers/video/drm/i915/intel_panel.c index 50c362c072..5c830d17c0 100644 --- a/drivers/video/drm/i915/intel_panel.c +++ b/drivers/video/drm/i915/intel_panel.c @@ -712,6 +712,10 @@ void intel_panel_set_backlight_acpi(struct intel_connector *connector, hw_level = clamp_user_to_hw(connector, user_level, user_max); panel->backlight.level = hw_level; + + if (panel->backlight.enabled) + intel_panel_actually_set_backlight(connector, hw_level); + mutex_unlock(&dev_priv->backlight_lock); } @@ -1105,6 +1109,10 @@ void intel_panel_enable_backlight(struct intel_connector *connector) WARN_ON(panel->backlight.max == 0); + if (panel->backlight.level <= panel->backlight.min) { + panel->backlight.level = panel->backlight.max; + } + panel->backlight.enable(connector); panel->backlight.enabled = true; diff --git a/drivers/video/drm/i915/kms_display.c b/drivers/video/drm/i915/kms_display.c index ab2fc1bf78..e7e2d36b98 100644 --- a/drivers/video/drm/i915/kms_display.c +++ b/drivers/video/drm/i915/kms_display.c @@ -11,13 +11,16 @@ #include -#include "bitmap.h" +//#include "bitmap.h" #include +void FASTCALL sysSetFramebuffer(void *fb)__asm__("SetFramebuffer"); +void kolibri_framebuffer_update(struct drm_i915_private *dev_priv, struct kos_framebuffer *kfb); +void init_system_cursors(struct drm_device *dev); + +addr_t dummy_fb_page; display_t *os_display; -struct drm_i915_gem_object *main_fb_obj; -struct drm_framebuffer *main_framebuffer; u32 cmd_buffer; u32 cmd_offset; @@ -25,17 +28,6 @@ u32 cmd_offset; void init_render(); int sna_init(); -static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); -static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); - -void __stdcall restore_cursor(int x, int y) -{}; - -void disable_mouse(void) -{}; - -struct mutex cursor_lock; - static char *manufacturer_name(unsigned char *x) { static char name[4]; @@ -59,19 +51,135 @@ static int count_connector_modes(struct drm_connector* connector) return count; }; +struct drm_framebuffer *get_framebuffer(struct drm_device *dev, struct drm_display_mode *mode, int tiling) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_fbdev *ifbdev = dev_priv->fbdev; + struct intel_framebuffer *intel_fb = ifbdev->fb; + struct drm_framebuffer *fb = &intel_fb->base; + struct drm_i915_gem_object *obj = NULL; + int stride, size; + +ENTER(); + + stride = mode->hdisplay *4; + + if(tiling) + { + int gen3size; + + if(IS_GEN3(dev)) + for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); + else + stride = ALIGN(stride, 512); + size = stride * ALIGN(mode->vdisplay, 8); + + if(IS_GEN3(dev)) + { + for (gen3size = 1024*1024; gen3size < size; gen3size <<= 1); + size = gen3size; + } + else + size = ALIGN(size, 4096); + } + else + { + stride = ALIGN(stride, 64); + size = stride * ALIGN(mode->vdisplay, 2); + } + + dbgprintf("size %x stride %x\n", size, stride); + + if(intel_fb == NULL || size > intel_fb->obj->base.size) + { + struct drm_mode_fb_cmd2 mode_cmd = {}; + int ret; + + DRM_DEBUG_KMS("remove old framebuffer\n"); + drm_framebuffer_remove(fb); + ifbdev->fb = NULL; + fb = NULL; + DRM_DEBUG_KMS("create new framebuffer\n"); + + mode_cmd.width = mode->hdisplay; + mode_cmd.height = mode->vdisplay; + + mode_cmd.pitches[0] = stride; + mode_cmd.pixel_format = DRM_FORMAT_XRGB8888; + + mutex_lock(&dev->struct_mutex); + + /* If the FB is too big, just don't use it since fbdev is not very + * important and we should probably use that space with FBC or other + * features. */ + if (size * 2 < dev_priv->gtt.stolen_usable_size) + obj = i915_gem_object_create_stolen(dev, size); + if (obj == NULL) + obj = i915_gem_alloc_object(dev, size); + if (!obj) { + DRM_ERROR("failed to allocate framebuffer\n"); + ret = -ENOMEM; + goto out; + } + + fb = __intel_framebuffer_create(dev, &mode_cmd, obj); + if (IS_ERR(fb)) { + ret = PTR_ERR(fb); + goto out_unref; + } + + /* Flush everything out, we'll be doing GTT only from now on */ + ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL, NULL); + if (ret) { + DRM_ERROR("failed to pin obj: %d\n", ret); + goto out_fb; + } + mutex_unlock(&dev->struct_mutex); + ifbdev->fb = to_intel_framebuffer(fb); + } + + obj = ifbdev->fb->obj; + + if(tiling) + { + obj->tiling_mode = I915_TILING_X; + fb->modifier[0] = I915_FORMAT_MOD_X_TILED; + obj->fence_dirty = true; + obj->stride = stride; + }; + + fb->width = mode->hdisplay; + fb->height = mode->vdisplay; + + fb->pitches[0] = + fb->pitches[1] = + fb->pitches[2] = + fb->pitches[3] = stride; + + fb->bits_per_pixel = 32; + fb->depth = 24; +LEAVE(); + return fb; + +out_fb: + drm_framebuffer_remove(fb); +out_unref: + drm_gem_object_unreference(&obj->base); +out: + mutex_unlock(&dev->struct_mutex); + return NULL; +} + static int set_mode(struct drm_device *dev, struct drm_connector *connector, struct drm_crtc *crtc, videomode_t *reqmode, bool strict) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_config *config = &dev->mode_config; struct drm_display_mode *mode = NULL, *tmpmode; struct drm_connector *tmpc; struct drm_framebuffer *fb = NULL; struct drm_mode_set set; - const char *con_name; - unsigned hdisplay, vdisplay; - int stride; + char con_edid[128]; int ret; drm_modeset_lock_all(dev); @@ -108,73 +216,42 @@ static int set_mode(struct drm_device *dev, struct drm_connector *connector, }; }; +out: + drm_modeset_unlock_all(dev); DRM_ERROR("%s failed\n", __FUNCTION__); - return -1; do_set: + drm_modeset_unlock_all(dev); - con_name = connector->name; + fb = get_framebuffer(dev, mode, 1); + if(fb == NULL) + { + DRM_ERROR("%s failed\n", __FUNCTION__); + return -1; + }; + drm_framebuffer_reference(fb); - char con_edid[128]; + drm_modeset_lock_all(dev); memcpy(con_edid, connector->edid_blob_ptr->data, 128); - DRM_DEBUG_KMS("Manufacturer: %s Model %x Serial Number %u\n", + + DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" + "monitor: %s model %x serial number %u\n", + mode->hdisplay, mode->vdisplay, + crtc->base.id, connector->name, manufacturer_name(con_edid + 0x08), (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); - DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s\n", - reqmode->width, reqmode->height, crtc->base.id, - con_name); - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - hdisplay = mode->hdisplay; - vdisplay = mode->vdisplay; - -// if (crtc->invert_dimensions) -// swap(hdisplay, vdisplay); - - fb = crtc->primary->fb; - if(fb == NULL) - fb = main_framebuffer; - - fb->width = reqmode->width; - fb->height = reqmode->height; - - main_fb_obj->tiling_mode = I915_TILING_X; - - if( main_fb_obj->tiling_mode == I915_TILING_X) - { - if(IS_GEN3(dev)) - for (stride = 512; stride < reqmode->width * 4; stride <<= 1); - else - stride = ALIGN(reqmode->width * 4, 512); - } - else - { - stride = ALIGN(reqmode->width * 4, 64); - } - - fb->pitches[0] = - fb->pitches[1] = - fb->pitches[2] = - fb->pitches[3] = stride; - - main_fb_obj->stride = stride; - - fb->bits_per_pixel = 32; - fb->depth = 24; - crtc->enabled = true; os_display->crtc = crtc; - i915_gem_object_put_fence(main_fb_obj); - - printf("fb:%p %dx%dx pitch %d format %x\n", + DRM_DEBUG_KMS("fb:%p %dx%dx pitch %d format %x\n", fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); set.crtc = crtc; @@ -189,19 +266,34 @@ do_set: if ( !ret ) { - os_display->width = fb->width; - os_display->height = fb->height; - os_display->vrefresh = drm_mode_vrefresh(mode); + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct kos_framebuffer *kfb = intel_fb->private; + kolibri_framebuffer_update(dev_priv, kfb); + DRM_DEBUG_KMS("kolibri framebuffer %p\n", kfb); - sysSetScreen(fb->width, fb->height, fb->pitches[0]); + os_display->width = mode->hdisplay; + os_display->height = mode->vdisplay; + os_display->vrefresh = drm_mode_vrefresh(mode); + sysSetFramebuffer(intel_fb->private); + sysSetScreen(mode->hdisplay, mode->vdisplay, fb->pitches[0]); + + os_display->connector = connector; + os_display->crtc = connector->encoder->crtc; + os_display->supported_modes = count_connector_modes(connector); + + crtc->cursor_x = os_display->width/2; + crtc->cursor_y = os_display->height/2; + + os_display->select_cursor(os_display->cursor); DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", - fb->width, fb->height, fb->pitches[0]); + mode->hdisplay, mode->vdisplay, fb->pitches[0]); } else DRM_ERROR("failed to set mode %d_%d on crtc %p\n", fb->width, fb->height, crtc); + drm_framebuffer_unreference(fb); drm_modeset_unlock_all(dev); return ret; @@ -215,10 +307,20 @@ static int set_mode_ex(struct drm_device *dev, struct drm_mode_config *config = &dev->mode_config; struct drm_framebuffer *fb = NULL; struct drm_mode_set set; + struct drm_crtc *crtc = NULL; + char con_edid[128]; int stride; int ret; + fb = get_framebuffer(dev, mode, 1); + if(fb == NULL) + { + DRM_ERROR("%s failed\n", __FUNCTION__); + return -1; + }; + drm_framebuffer_reference(fb); + drm_modeset_lock_all(dev); list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) @@ -229,57 +331,27 @@ static int set_mode_ex(struct drm_device *dev, f->dpms(tmpc, DRM_MODE_DPMS_OFF); }; - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - - fb = connector->encoder->crtc->primary->fb; - if(fb == NULL) - fb = main_framebuffer; - - fb->width = mode->hdisplay; - fb->height = mode->vdisplay;; - - main_fb_obj->tiling_mode = I915_TILING_X; - - if( main_fb_obj->tiling_mode == I915_TILING_X) - { - if(IS_GEN3(dev)) - for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); - else - stride = ALIGN(mode->hdisplay * 4, 512); - } - else - { - stride = ALIGN(mode->hdisplay * 4, 64); - } - - fb->pitches[0] = - fb->pitches[1] = - fb->pitches[2] = - fb->pitches[3] = stride; - - main_fb_obj->stride = stride; - - fb->bits_per_pixel = 32; - fb->depth = 24; - - connector->encoder->crtc->enabled = true; - - i915_gem_object_put_fence(main_fb_obj); + crtc = connector->encoder->crtc; memcpy(con_edid, connector->edid_blob_ptr->data, 128); DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" "monitor: %s model %x serial number %u\n", - fb->width, fb->height, + mode->hdisplay, mode->vdisplay, connector->encoder->crtc->base.id, connector->name, manufacturer_name(con_edid + 0x08), (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); + + crtc->enabled = true; + os_display->crtc = crtc; + DRM_DEBUG_KMS("use framebuffer %p %dx%d pitch %d format %x\n", fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); - set.crtc = connector->encoder->crtc; + set.crtc = crtc; set.x = 0; set.y = 0; set.mode = mode; @@ -290,13 +362,16 @@ static int set_mode_ex(struct drm_device *dev, ret = drm_mode_set_config_internal(&set); if ( !ret ) { - struct drm_crtc *crtc = os_display->crtc; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct kos_framebuffer *kfb = intel_fb->private; + kolibri_framebuffer_update(dev_priv, kfb); + DRM_DEBUG_KMS("kolibri framebuffer %p\n", kfb); - os_display->width = fb->width; - os_display->height = fb->height; + os_display->width = mode->hdisplay; + os_display->height = mode->vdisplay; os_display->vrefresh = drm_mode_vrefresh(mode); - - sysSetScreen(fb->width, fb->height, fb->pitches[0]); + sysSetFramebuffer(intel_fb->private); + sysSetScreen(mode->hdisplay, mode->vdisplay, fb->pitches[0]); os_display->connector = connector; os_display->crtc = connector->encoder->crtc; @@ -305,17 +380,17 @@ static int set_mode_ex(struct drm_device *dev, crtc->cursor_x = os_display->width/2; crtc->cursor_y = os_display->height/2; - select_cursor_kms(os_display->cursor); + os_display->select_cursor(os_display->cursor); DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", - fb->width, fb->height, fb->pitches[0]); + mode->hdisplay, mode->vdisplay, fb->pitches[0]); } else DRM_ERROR(" failed to set mode %d_%d on crtc %p\n", fb->width, fb->height, connector->encoder->crtc); + drm_framebuffer_unreference(fb); drm_modeset_unlock_all(dev); - return ret; } @@ -467,11 +542,15 @@ int init_display_kms(struct drm_device *dev, videomode_t *usermode) struct drm_connector_helper_funcs *connector_funcs; struct drm_connector *connector = NULL; struct drm_crtc *crtc = NULL; - struct drm_framebuffer *fb; + struct drm_plane *plane; - cursor_t *cursor; - u32 ifl; int ret; +ENTER(); + + drm_for_each_plane(plane, dev) + { + drm_plane_helper_disable(plane); + }; mutex_lock(&dev->mode_config.mutex); ret = choose_config(dev, &connector, &crtc); @@ -482,9 +561,9 @@ int init_display_kms(struct drm_device *dev, videomode_t *usermode) return -1; }; +/* mutex_lock(&dev->object_name_lock); idr_preload(GFP_KERNEL); - if (!main_fb_obj->base.name) { ret = idr_alloc(&dev->object_name_idr, &main_fb_obj->base, 1, 0, GFP_NOWAIT); @@ -492,9 +571,10 @@ int init_display_kms(struct drm_device *dev, videomode_t *usermode) main_fb_obj->base.handle_count++; DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->base.name ); } - idr_preload_end(); mutex_unlock(&dev->object_name_lock); +*/ + dummy_fb_page = AllocPage(); os_display = GetDisplay(); os_display->ddev = dev; @@ -503,32 +583,7 @@ int init_display_kms(struct drm_device *dev, videomode_t *usermode) os_display->supported_modes = count_connector_modes(connector); mutex_unlock(&dev->mode_config.mutex); - mutex_init(&cursor_lock); - mutex_lock(&dev->struct_mutex); - - ifl = safe_cli(); - { - list_for_each_entry(cursor, &os_display->cursors, list) - { - init_cursor(cursor); - }; - - os_display->restore_cursor(0,0); - os_display->init_cursor = init_cursor; - os_display->select_cursor = select_cursor_kms; - os_display->show_cursor = NULL; - os_display->move_cursor = move_cursor_kms; - os_display->restore_cursor = restore_cursor; - os_display->disable_mouse = disable_mouse; - - crtc->cursor_x = os_display->width/2; - crtc->cursor_y = os_display->height/2; - - select_cursor_kms(os_display->cursor); - }; - safe_sti(ifl); - - mutex_unlock(&dev->struct_mutex); + init_system_cursors(dev); ret = -1; @@ -557,9 +612,7 @@ int init_display_kms(struct drm_device *dev, videomode_t *usermode) set_mode(dev, os_display->connector, os_display->crtc, usermode, false); }; -#ifdef __HWA__ - err = init_bitmaps(); -#endif +LEAVE(); return ret; }; @@ -745,160 +798,138 @@ void i915_dpms(struct drm_device *dev, int mode) f->dpms(os_display->connector, mode); }; -void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) -{ - struct drm_i915_gem_object *obj = cursor->cobj; - list_del(&cursor->list); - - i915_gem_object_ggtt_unpin(cursor->cobj); - - mutex_lock(&main_device->struct_mutex); - drm_gem_object_unreference(&obj->base); - mutex_unlock(&main_device->struct_mutex); - - __DestroyObject(cursor); -}; - -int init_cursor(cursor_t *cursor) -{ - struct drm_i915_private *dev_priv = os_display->ddev->dev_private; - struct drm_i915_gem_object *obj; - uint32_t *bits; - uint32_t *src; - void *mapped; - - int i,j; - int ret; - - if (dev_priv->info.cursor_needs_physical) - { - bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8); - if (unlikely(bits == NULL)) - return ENOMEM; - cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); - } - else - { - obj = i915_gem_alloc_object(os_display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4); - if (unlikely(obj == NULL)) - return -ENOMEM; - - ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL); - if (ret) { - drm_gem_object_unreference(&obj->base); - return ret; - } - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - { - i915_gem_object_ggtt_unpin(obj); - drm_gem_object_unreference(&obj->base); - return ret; - } -/* You don't need to worry about fragmentation issues. - * GTT space is continuous. I guarantee it. */ - - mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), - KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW); - - if (unlikely(bits == NULL)) - { - i915_gem_object_ggtt_unpin(obj); - drm_gem_object_unreference(&obj->base); - return -ENOMEM; - }; - cursor->cobj = obj; - }; - - src = cursor->data; - - for(i = 0; i < 32; i++) - { - for(j = 0; j < 32; j++) - *bits++ = *src++; - for(j = 32; j < KMS_CURSOR_WIDTH; j++) - *bits++ = 0; - } - for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++) - *bits++ = 0; - - FreeKernelSpace(mapped); - - KernelFree(cursor->data); - - cursor->data = bits; - - cursor->header.destroy = destroy_cursor; - - return 0; -} - - -void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) -{ - struct drm_crtc *crtc = os_display->crtc; - struct drm_plane_state *cursor_state = crtc->cursor->state; - - x-= cursor->hot_x; - y-= cursor->hot_y; - - crtc->cursor_x = x; - crtc->cursor_y = y; - - cursor_state->crtc_x = x; - cursor_state->crtc_y = y; - - intel_crtc_update_cursor(crtc, 1); - -}; - -cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) -{ - struct drm_i915_private *dev_priv = os_display->ddev->dev_private; - struct drm_crtc *crtc = os_display->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - cursor_t *old; - - old = os_display->cursor; - - mutex_lock(&cursor_lock); - - os_display->cursor = cursor; - - if (!dev_priv->info.cursor_needs_physical) - intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); - else - intel_crtc->cursor_addr = (addr_t)cursor->cobj; - - intel_crtc->base.cursor->state->crtc_w = 64; - intel_crtc->base.cursor->state->crtc_h = 64; - intel_crtc->base.cursor->state->rotation = 0; - mutex_unlock(&cursor_lock); - - move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y); - return old; -}; int i915_fbinfo(struct drm_i915_fb_info *fb) { - struct drm_i915_private *dev_priv = os_display->ddev->dev_private; - struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); - struct drm_i915_gem_object *obj = get_fb_obj(); + u32 ifl; - fb->name = obj->base.name; - fb->width = os_display->width; - fb->height = os_display->height; - fb->pitch = obj->stride; - fb->tiling = obj->tiling_mode; - fb->crtc = crtc->base.base.id; - fb->pipe = crtc->pipe; + ifl = safe_cli(); + { + struct drm_i915_private *dev_priv = os_display->ddev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); + struct kos_framebuffer *kfb = os_display->current_lfb; + struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)kfb->private; + struct drm_i915_gem_object *obj = intel_fb->obj; + fb->name = obj->base.name; + fb->width = os_display->width; + fb->height = os_display->height; + fb->pitch = obj->stride; + fb->tiling = obj->tiling_mode; + fb->crtc = crtc->base.base.id; + fb->pipe = crtc->pipe; + } + safe_sti(ifl); return 0; } +int kolibri_framebuffer_init(struct intel_framebuffer *intel_fb) +{ + struct kos_framebuffer *kfb; + addr_t dummy_table; + addr_t *pt_addr = NULL; + int pde; +ENTER(); + kfb = kzalloc(sizeof(struct kos_framebuffer),0); + kfb->private = intel_fb; + + for(pde = 0; pde < 8; pde++) + { + dummy_table = AllocPage(); + kfb->pde[pde] = dummy_table|PG_UW; + + pt_addr = kmap((struct page*)dummy_table); + __builtin_memset(pt_addr,0,4096); + kunmap((struct page*)dummy_table); + }; + + intel_fb->private = kfb; +LEAVE(); + return 0; +#if 0 + struct sg_page_iter sg_iter; + num_pages = obj->base.size/4096; + printf("num_pages %d\n",num_pages); + + pte = 0; + pde = 0; + pt_addr = NULL; + + __sg_page_iter_start(&sg_iter, obj->pages->sgl, sg_nents(obj->pages->sgl), 0); + while (__sg_page_iter_next(&sg_iter)) + { + if (pt_addr == NULL) + { + addr_t pt = AllocPage(); + kfb->pde[pde] = pt|PG_UW; + pde++; + pt_addr = kmap_atomic((struct page*)pt); + } + pt_addr[pte] = sg_page_iter_dma_address(&sg_iter)|PG_UW|PG_WRITEC; + if( (pte & 15) == 0) + DRM_DEBUG_KMS("pte %x\n",pt_addr[pte]); + if (++pte == 1024) + { + kunmap_atomic(pt_addr); + pt_addr = NULL; + if (pde == 8) + break; + pte = 0; + } + } + + if(pt_addr) + { + for(;pte < 1024; pte++) + pt_addr[pte] = dummy_page|PG_UW; + kunmap_atomic(pt_addr); + } +#endif +}; + +void kolibri_framebuffer_update(struct drm_i915_private *dev_priv, struct kos_framebuffer *kfb) +{ + struct intel_framebuffer *intel_fb = kfb->private; + addr_t *pt_addr = NULL; + int pte = 0; + int pde = 0; + int num_pages; + addr_t pfn; +ENTER(); + num_pages = intel_fb->obj->base.size/4096; + pfn = dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(intel_fb->obj); + + while(num_pages) + { + if (pt_addr == NULL) + { + addr_t pt = kfb->pde[pde] & 0xFFFFF000; + pde++; + pt_addr = kmap_atomic((struct page*)pt); + } + pt_addr[pte] = pfn|PG_UW|PG_WRITEC; + pfn+= 4096; + num_pages--; + if (++pte == 1024) + { + kunmap_atomic(pt_addr); + pt_addr = NULL; + if (pde == 8) + break; + pte = 0; + } + } + + if(pt_addr) + { + for(;pte < 1024; pte++) + pt_addr[pte] = dummy_fb_page|PG_UW; + kunmap_atomic(pt_addr); + } +LEAVE(); +}; + typedef struct { int left; diff --git a/drivers/video/drm/i915/kos_cursor.c b/drivers/video/drm/i915/kos_cursor.c new file mode 100644 index 0000000000..5d0e3d97ea --- /dev/null +++ b/drivers/video/drm/i915/kos_cursor.c @@ -0,0 +1,177 @@ +#include +#include "i915_drv.h" +#include "intel_drv.h" +#include +#include + +static struct mutex cursor_lock; + +static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) +{ + struct drm_crtc *crtc = os_display->crtc; + struct drm_plane_state *cursor_state = crtc->cursor->state; + + x-= cursor->hot_x; + y-= cursor->hot_y; + + crtc->cursor_x = x; + crtc->cursor_y = y; + + cursor_state->crtc_x = x; + cursor_state->crtc_y = y; + + intel_crtc_update_cursor(crtc, 1); +}; + +static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) +{ + struct drm_i915_private *dev_priv = os_display->ddev->dev_private; + struct drm_crtc *crtc = os_display->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + cursor_t *old; + + old = os_display->cursor; + + mutex_lock(&cursor_lock); + + os_display->cursor = cursor; + + if (!dev_priv->info.cursor_needs_physical) + intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); + else + intel_crtc->cursor_addr = (addr_t)cursor->cobj; + + intel_crtc->base.cursor->state->crtc_w = 64; + intel_crtc->base.cursor->state->crtc_h = 64; + intel_crtc->base.cursor->state->rotation = 0; + mutex_unlock(&cursor_lock); + + move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y); + return old; +}; + +static void __stdcall restore_cursor(int x, int y){}; +static void disable_mouse(void){}; + +static void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) +{ + struct drm_i915_gem_object *obj = cursor->cobj; + list_del(&cursor->list); + + i915_gem_object_ggtt_unpin(cursor->cobj); + + mutex_lock(&main_device->struct_mutex); + drm_gem_object_unreference(&obj->base); + mutex_unlock(&main_device->struct_mutex); + + __DestroyObject(cursor); +}; + +static int init_cursor(cursor_t *cursor) +{ + display_t *display = GetDisplay(); + struct drm_i915_private *dev_priv = display->ddev->dev_private; + struct drm_i915_gem_object *obj; + uint32_t *bits; + uint32_t *src; + void *mapped; + + int i,j; + int ret; + + if (dev_priv->info.cursor_needs_physical) + { + bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8); + if (unlikely(bits == NULL)) + return ENOMEM; + cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); + } + else + { + obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4); + if (unlikely(obj == NULL)) + return -ENOMEM; + + ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL); + if (ret) { + drm_gem_object_unreference(&obj->base); + return ret; + } + + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) + { + i915_gem_object_ggtt_unpin(obj); + drm_gem_object_unreference(&obj->base); + return ret; + } +/* You don't need to worry about fragmentation issues. + * GTT space is continuous. I guarantee it. */ + + mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), + KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW); + + if (unlikely(bits == NULL)) + { + i915_gem_object_ggtt_unpin(obj); + drm_gem_object_unreference(&obj->base); + return -ENOMEM; + }; + cursor->cobj = obj; + }; + + src = cursor->data; + + for(i = 0; i < 32; i++) + { + for(j = 0; j < 32; j++) + *bits++ = *src++; + for(j = 32; j < KMS_CURSOR_WIDTH; j++) + *bits++ = 0; + } + for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++) + *bits++ = 0; + + FreeKernelSpace(mapped); + KernelFree(cursor->data); + cursor->data = bits; + cursor->header.destroy = destroy_cursor; + + return 0; +} + +void init_system_cursors(struct drm_device *dev) +{ + cursor_t *cursor; + display_t *display; + u32 ifl; + + display = GetDisplay(); + + mutex_init(&cursor_lock); + mutex_lock(&dev->struct_mutex); + + ifl = safe_cli(); + { + list_for_each_entry(cursor, &display->cursors, list) + { + init_cursor(cursor); + }; + + display->restore_cursor(0,0); + display->init_cursor = init_cursor; + display->select_cursor = select_cursor_kms; + display->show_cursor = NULL; + display->move_cursor = move_cursor_kms; + display->restore_cursor = restore_cursor; + display->disable_mouse = disable_mouse; + display->crtc->cursor_x = display->width/2; + display->crtc->cursor_y = display->height/2; + + select_cursor_kms(display->cursor); + }; + safe_sti(ifl); + + mutex_unlock(&dev->struct_mutex); +} diff --git a/drivers/video/drm/i915/main.c b/drivers/video/drm/i915/main.c index a2bfce0085..ca061c5a6a 100644 --- a/drivers/video/drm/i915/main.c +++ b/drivers/video/drm/i915/main.c @@ -14,7 +14,7 @@ #include "bitmap.h" #include "i915_kos32.h" -#define DRV_NAME "i915 v4.4.1" +#define DRV_NAME "i915 v4.4.2-dbg2" #define I915_DEV_CLOSE 0 #define I915_DEV_INIT 1 @@ -131,9 +131,7 @@ u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) if( GetService("DISPLAY") != 0 ) return 0; - printf("\n%s build %s %s\nusage: i915 [options]\n" - "-f\n" - "--fbsize <0-9> Set framebuffer size in megabytes (default: 16)\n", + printf("\n%s build %s %s\nusage: i915 [options]\n", DRV_NAME, __DATE__, __TIME__); printf("--rc6 <-1,0-7> Enable power-saving render C-state 6.\n" @@ -172,7 +170,6 @@ u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) { {"log", required_argument, 0, 'l'}, {"mode", required_argument, 0, 'm'}, - {"fbsize",required_argument, 0, 'f'}, {"video", required_argument, 0, 'v'}, {"rc6", required_argument, 0, OPTION_RC6}, {"fbc", required_argument, 0, OPTION_FBC}, @@ -181,7 +178,7 @@ u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) int option_index = 0; - c = getopt_long (argc, argv, "f:l:m:v:", + c = getopt_long (argc, argv, "l:m:v:", long_options, &option_index); if (c == -1) @@ -199,11 +196,6 @@ u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) printf("i915.fbc = %d\n",i915.enable_fbc); break; - case 'f': - i915.fbsize = my_atoi(&optarg); - printf("i915.fbsize =%d\n",i915.fbsize); - break; - case 'l': i915.log_file = optarg; break;