|
@@ -44,8 +44,8 @@
|
|
#include <linux/ivtvfb.h>
|
|
#include <linux/ivtvfb.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
|
|
|
|
-#ifdef CONFIG_MTRR
|
|
|
|
-#include <asm/mtrr.h>
|
|
|
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
|
+#include <asm/pat.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#include "ivtv-driver.h"
|
|
#include "ivtv-driver.h"
|
|
@@ -155,12 +155,11 @@ struct osd_info {
|
|
/* Buffer size */
|
|
/* Buffer size */
|
|
u32 video_buffer_size;
|
|
u32 video_buffer_size;
|
|
|
|
|
|
-#ifdef CONFIG_MTRR
|
|
|
|
/* video_base rounded down as required by hardware MTRRs */
|
|
/* video_base rounded down as required by hardware MTRRs */
|
|
unsigned long fb_start_aligned_physaddr;
|
|
unsigned long fb_start_aligned_physaddr;
|
|
/* video_base rounded up as required by hardware MTRRs */
|
|
/* video_base rounded up as required by hardware MTRRs */
|
|
unsigned long fb_end_aligned_physaddr;
|
|
unsigned long fb_end_aligned_physaddr;
|
|
-#endif
|
|
|
|
|
|
+ int wc_cookie;
|
|
|
|
|
|
/* Store the buffer offset */
|
|
/* Store the buffer offset */
|
|
int set_osd_coords_x;
|
|
int set_osd_coords_x;
|
|
@@ -1099,6 +1098,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
|
|
static int ivtvfb_init_io(struct ivtv *itv)
|
|
static int ivtvfb_init_io(struct ivtv *itv)
|
|
{
|
|
{
|
|
struct osd_info *oi = itv->osd_info;
|
|
struct osd_info *oi = itv->osd_info;
|
|
|
|
+ /* Find the largest power of two that maps the whole buffer */
|
|
|
|
+ int size_shift = 31;
|
|
|
|
|
|
mutex_lock(&itv->serialize_lock);
|
|
mutex_lock(&itv->serialize_lock);
|
|
if (ivtv_init_on_first_open(itv)) {
|
|
if (ivtv_init_on_first_open(itv)) {
|
|
@@ -1132,29 +1133,16 @@ static int ivtvfb_init_io(struct ivtv *itv)
|
|
oi->video_pbase, oi->video_vbase,
|
|
oi->video_pbase, oi->video_vbase,
|
|
oi->video_buffer_size / 1024);
|
|
oi->video_buffer_size / 1024);
|
|
|
|
|
|
-#ifdef CONFIG_MTRR
|
|
|
|
- {
|
|
|
|
- /* Find the largest power of two that maps the whole buffer */
|
|
|
|
- int size_shift = 31;
|
|
|
|
-
|
|
|
|
- while (!(oi->video_buffer_size & (1 << size_shift))) {
|
|
|
|
- size_shift--;
|
|
|
|
- }
|
|
|
|
- size_shift++;
|
|
|
|
- oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
|
|
|
|
- oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
|
|
|
|
- oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
|
|
|
|
- oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
|
|
|
|
- if (mtrr_add(oi->fb_start_aligned_physaddr,
|
|
|
|
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
|
|
|
|
- MTRR_TYPE_WRCOMB, 1) < 0) {
|
|
|
|
- IVTVFB_INFO("disabled mttr\n");
|
|
|
|
- oi->fb_start_aligned_physaddr = 0;
|
|
|
|
- oi->fb_end_aligned_physaddr = 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
|
|
+ while (!(oi->video_buffer_size & (1 << size_shift)))
|
|
|
|
+ size_shift--;
|
|
|
|
+ size_shift++;
|
|
|
|
+ oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
|
|
|
|
+ oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
|
|
|
|
+ oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
|
|
|
|
+ oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
|
|
|
|
+ oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
|
|
|
|
+ oi->fb_end_aligned_physaddr -
|
|
|
|
+ oi->fb_start_aligned_physaddr);
|
|
/* Blank the entire osd. */
|
|
/* Blank the entire osd. */
|
|
memset_io(oi->video_vbase, 0, oi->video_buffer_size);
|
|
memset_io(oi->video_vbase, 0, oi->video_buffer_size);
|
|
|
|
|
|
@@ -1172,14 +1160,7 @@ static void ivtvfb_release_buffers (struct ivtv *itv)
|
|
|
|
|
|
/* Release pseudo palette */
|
|
/* Release pseudo palette */
|
|
kfree(oi->ivtvfb_info.pseudo_palette);
|
|
kfree(oi->ivtvfb_info.pseudo_palette);
|
|
-
|
|
|
|
-#ifdef CONFIG_MTRR
|
|
|
|
- if (oi->fb_end_aligned_physaddr) {
|
|
|
|
- mtrr_del(-1, oi->fb_start_aligned_physaddr,
|
|
|
|
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
|
|
+ arch_phys_wc_del(oi->wc_cookie);
|
|
kfree(oi);
|
|
kfree(oi);
|
|
itv->osd_info = NULL;
|
|
itv->osd_info = NULL;
|
|
}
|
|
}
|
|
@@ -1284,6 +1265,13 @@ static int __init ivtvfb_init(void)
|
|
int registered = 0;
|
|
int registered = 0;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
|
+ if (WARN(pat_enabled(),
|
|
|
|
+ "ivtvfb needs PAT disabled, boot with nopat kernel parameter\n")) {
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
|
|
if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
|
|
printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
|
|
printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
|
|
IVTV_MAX_CARDS - 1);
|
|
IVTV_MAX_CARDS - 1);
|