From: Ville Syrjälä Date: Thu, 14 Aug 2014 22:22:02 +0000 (+0300) Subject: drm/i915: Rewrite ns2501 driver a bit X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=bae06ca122a5f37bdd4d8faedae7881f53b145cd;p=linux-beck.git drm/i915: Rewrite ns2501 driver a bit Try to use the same programming sequence as used by the IEGD driver. Also shovel the magic register values into a big static const array. The register values are actually the based on what the BIOS programs on the Fujitsu-Siemens Lifebook S6010. IEGD seemed to have hardcoded register values (which also enabled the scaler for 1024x768 mode). However those didn't actually work so well on the S6010. Possibly the pipe timings that got used didn't match the ns2501 configuration. Signed-off-by: Ville Syrjälä Reviewed-by: Thomas Richter Signed-off-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index 85030d49be31..b2785716be2a 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c @@ -60,16 +60,291 @@ #define NS2501_REGC 0x0c +enum { + MODE_640x480, + MODE_800x600, + MODE_1024x768, +}; + +struct ns2501_reg { + uint8_t offset; + uint8_t value; +}; + +/* + * Magic values based on what the BIOS on + * Fujitsu-Siemens Lifebook S6010 programs (1024x768 panel). + */ +static const struct ns2501_reg regs_1024x768[][86] = { + [MODE_640x480] = { + [0] = { .offset = 0x0a, .value = 0x81, }, + [1] = { .offset = 0x18, .value = 0x07, }, + [2] = { .offset = 0x19, .value = 0x00, }, + [3] = { .offset = 0x1a, .value = 0x00, }, + [4] = { .offset = 0x1b, .value = 0x11, }, + [5] = { .offset = 0x1c, .value = 0x54, }, + [6] = { .offset = 0x1d, .value = 0x03, }, + [7] = { .offset = 0x1e, .value = 0x02, }, + [8] = { .offset = 0xf3, .value = 0x90, }, + [9] = { .offset = 0xf9, .value = 0x00, }, + [10] = { .offset = 0xc1, .value = 0x90, }, + [11] = { .offset = 0xc2, .value = 0x00, }, + [12] = { .offset = 0xc3, .value = 0x0f, }, + [13] = { .offset = 0xc4, .value = 0x03, }, + [14] = { .offset = 0xc5, .value = 0x16, }, + [15] = { .offset = 0xc6, .value = 0x00, }, + [16] = { .offset = 0xc7, .value = 0x02, }, + [17] = { .offset = 0xc8, .value = 0x02, }, + [18] = { .offset = 0xf4, .value = 0x00, }, + [19] = { .offset = 0x80, .value = 0xff, }, + [20] = { .offset = 0x81, .value = 0x07, }, + [21] = { .offset = 0x82, .value = 0x3d, }, + [22] = { .offset = 0x83, .value = 0x05, }, + [23] = { .offset = 0x94, .value = 0x00, }, + [24] = { .offset = 0x95, .value = 0x00, }, + [25] = { .offset = 0x96, .value = 0x05, }, + [26] = { .offset = 0x97, .value = 0x00, }, + [27] = { .offset = 0x9a, .value = 0x88, }, + [28] = { .offset = 0x9b, .value = 0x00, }, + [29] = { .offset = 0x98, .value = 0x00, }, + [30] = { .offset = 0x99, .value = 0x00, }, + [31] = { .offset = 0xf7, .value = 0x88, }, + [32] = { .offset = 0xf8, .value = 0x0a, }, + [33] = { .offset = 0x9c, .value = 0x24, }, + [34] = { .offset = 0x9d, .value = 0x00, }, + [35] = { .offset = 0x9e, .value = 0x25, }, + [36] = { .offset = 0x9f, .value = 0x03, }, + [37] = { .offset = 0xa0, .value = 0x28, }, + [38] = { .offset = 0xa1, .value = 0x01, }, + [39] = { .offset = 0xa2, .value = 0x28, }, + [40] = { .offset = 0xa3, .value = 0x05, }, + [41] = { .offset = 0xb6, .value = 0x09, }, + [42] = { .offset = 0xb8, .value = 0x00, }, + [43] = { .offset = 0xb9, .value = 0xa0, }, + [44] = { .offset = 0xba, .value = 0x00, }, + [45] = { .offset = 0xbb, .value = 0x20, }, + [46] = { .offset = 0x10, .value = 0x00, }, + [47] = { .offset = 0x11, .value = 0xa0, }, + [48] = { .offset = 0x12, .value = 0x02, }, + [49] = { .offset = 0x20, .value = 0x00, }, + [50] = { .offset = 0x22, .value = 0x00, }, + [51] = { .offset = 0x23, .value = 0x00, }, + [52] = { .offset = 0x24, .value = 0x00, }, + [53] = { .offset = 0x25, .value = 0x00, }, + [54] = { .offset = 0x8c, .value = 0x10, }, + [55] = { .offset = 0x8d, .value = 0x02, }, + [56] = { .offset = 0x8e, .value = 0x10, }, + [57] = { .offset = 0x8f, .value = 0x00, }, + [58] = { .offset = 0x90, .value = 0xff, }, + [59] = { .offset = 0x91, .value = 0x07, }, + [60] = { .offset = 0x92, .value = 0xa0, }, + [61] = { .offset = 0x93, .value = 0x02, }, + [62] = { .offset = 0xa5, .value = 0x00, }, + [63] = { .offset = 0xa6, .value = 0x00, }, + [64] = { .offset = 0xa7, .value = 0x00, }, + [65] = { .offset = 0xa8, .value = 0x00, }, + [66] = { .offset = 0xa9, .value = 0x04, }, + [67] = { .offset = 0xaa, .value = 0x70, }, + [68] = { .offset = 0xab, .value = 0x4f, }, + [69] = { .offset = 0xac, .value = 0x00, }, + [70] = { .offset = 0xa4, .value = 0x84, }, + [71] = { .offset = 0x7e, .value = 0x18, }, + [72] = { .offset = 0x84, .value = 0x00, }, + [73] = { .offset = 0x85, .value = 0x00, }, + [74] = { .offset = 0x86, .value = 0x00, }, + [75] = { .offset = 0x87, .value = 0x00, }, + [76] = { .offset = 0x88, .value = 0x00, }, + [77] = { .offset = 0x89, .value = 0x00, }, + [78] = { .offset = 0x8a, .value = 0x00, }, + [79] = { .offset = 0x8b, .value = 0x00, }, + [80] = { .offset = 0x26, .value = 0x00, }, + [81] = { .offset = 0x27, .value = 0x00, }, + [82] = { .offset = 0xad, .value = 0x00, }, + [83] = { .offset = 0x08, .value = 0x30, }, /* 0x31 */ + [84] = { .offset = 0x41, .value = 0x00, }, + [85] = { .offset = 0xc0, .value = 0x05, }, + }, + [MODE_800x600] = { + [0] = { .offset = 0x0a, .value = 0x81, }, + [1] = { .offset = 0x18, .value = 0x07, }, + [2] = { .offset = 0x19, .value = 0x00, }, + [3] = { .offset = 0x1a, .value = 0x00, }, + [4] = { .offset = 0x1b, .value = 0x19, }, + [5] = { .offset = 0x1c, .value = 0x64, }, + [6] = { .offset = 0x1d, .value = 0x02, }, + [7] = { .offset = 0x1e, .value = 0x02, }, + [8] = { .offset = 0xf3, .value = 0x90, }, + [9] = { .offset = 0xf9, .value = 0x00, }, + [10] = { .offset = 0xc1, .value = 0xd7, }, + [11] = { .offset = 0xc2, .value = 0x00, }, + [12] = { .offset = 0xc3, .value = 0xf8, }, + [13] = { .offset = 0xc4, .value = 0x03, }, + [14] = { .offset = 0xc5, .value = 0x1a, }, + [15] = { .offset = 0xc6, .value = 0x00, }, + [16] = { .offset = 0xc7, .value = 0x73, }, + [17] = { .offset = 0xc8, .value = 0x02, }, + [18] = { .offset = 0xf4, .value = 0x00, }, + [19] = { .offset = 0x80, .value = 0x27, }, + [20] = { .offset = 0x81, .value = 0x03, }, + [21] = { .offset = 0x82, .value = 0x41, }, + [22] = { .offset = 0x83, .value = 0x05, }, + [23] = { .offset = 0x94, .value = 0x00, }, + [24] = { .offset = 0x95, .value = 0x00, }, + [25] = { .offset = 0x96, .value = 0x05, }, + [26] = { .offset = 0x97, .value = 0x00, }, + [27] = { .offset = 0x9a, .value = 0x88, }, + [28] = { .offset = 0x9b, .value = 0x00, }, + [29] = { .offset = 0x98, .value = 0x00, }, + [30] = { .offset = 0x99, .value = 0x00, }, + [31] = { .offset = 0xf7, .value = 0x88, }, + [32] = { .offset = 0xf8, .value = 0x06, }, + [33] = { .offset = 0x9c, .value = 0x23, }, + [34] = { .offset = 0x9d, .value = 0x00, }, + [35] = { .offset = 0x9e, .value = 0x25, }, + [36] = { .offset = 0x9f, .value = 0x03, }, + [37] = { .offset = 0xa0, .value = 0x28, }, + [38] = { .offset = 0xa1, .value = 0x01, }, + [39] = { .offset = 0xa2, .value = 0x28, }, + [40] = { .offset = 0xa3, .value = 0x05, }, + [41] = { .offset = 0xb6, .value = 0x09, }, + [42] = { .offset = 0xb8, .value = 0x30, }, + [43] = { .offset = 0xb9, .value = 0xc8, }, + [44] = { .offset = 0xba, .value = 0x00, }, + [45] = { .offset = 0xbb, .value = 0x20, }, + [46] = { .offset = 0x10, .value = 0x20, }, + [47] = { .offset = 0x11, .value = 0xc8, }, + [48] = { .offset = 0x12, .value = 0x02, }, + [49] = { .offset = 0x20, .value = 0x00, }, + [50] = { .offset = 0x22, .value = 0x00, }, + [51] = { .offset = 0x23, .value = 0x00, }, + [52] = { .offset = 0x24, .value = 0x00, }, + [53] = { .offset = 0x25, .value = 0x00, }, + [54] = { .offset = 0x8c, .value = 0x10, }, + [55] = { .offset = 0x8d, .value = 0x02, }, + [56] = { .offset = 0x8e, .value = 0x04, }, + [57] = { .offset = 0x8f, .value = 0x00, }, + [58] = { .offset = 0x90, .value = 0xff, }, + [59] = { .offset = 0x91, .value = 0x07, }, + [60] = { .offset = 0x92, .value = 0xa0, }, + [61] = { .offset = 0x93, .value = 0x02, }, + [62] = { .offset = 0xa5, .value = 0x00, }, + [63] = { .offset = 0xa6, .value = 0x00, }, + [64] = { .offset = 0xa7, .value = 0x00, }, + [65] = { .offset = 0xa8, .value = 0x00, }, + [66] = { .offset = 0xa9, .value = 0x83, }, + [67] = { .offset = 0xaa, .value = 0x40, }, + [68] = { .offset = 0xab, .value = 0x32, }, + [69] = { .offset = 0xac, .value = 0x00, }, + [70] = { .offset = 0xa4, .value = 0x80, }, + [71] = { .offset = 0x7e, .value = 0x18, }, + [72] = { .offset = 0x84, .value = 0x00, }, + [73] = { .offset = 0x85, .value = 0x00, }, + [74] = { .offset = 0x86, .value = 0x00, }, + [75] = { .offset = 0x87, .value = 0x00, }, + [76] = { .offset = 0x88, .value = 0x00, }, + [77] = { .offset = 0x89, .value = 0x00, }, + [78] = { .offset = 0x8a, .value = 0x00, }, + [79] = { .offset = 0x8b, .value = 0x00, }, + [80] = { .offset = 0x26, .value = 0x00, }, + [81] = { .offset = 0x27, .value = 0x00, }, + [82] = { .offset = 0xad, .value = 0x00, }, + [83] = { .offset = 0x08, .value = 0x30, }, /* 0x31 */ + [84] = { .offset = 0x41, .value = 0x00, }, + [85] = { .offset = 0xc0, .value = 0x07, }, + }, + [MODE_1024x768] = { + [0] = { .offset = 0x0a, .value = 0x81, }, + [1] = { .offset = 0x18, .value = 0x07, }, + [2] = { .offset = 0x19, .value = 0x00, }, + [3] = { .offset = 0x1a, .value = 0x00, }, + [4] = { .offset = 0x1b, .value = 0x11, }, + [5] = { .offset = 0x1c, .value = 0x54, }, + [6] = { .offset = 0x1d, .value = 0x03, }, + [7] = { .offset = 0x1e, .value = 0x02, }, + [8] = { .offset = 0xf3, .value = 0x90, }, + [9] = { .offset = 0xf9, .value = 0x00, }, + [10] = { .offset = 0xc1, .value = 0x90, }, + [11] = { .offset = 0xc2, .value = 0x00, }, + [12] = { .offset = 0xc3, .value = 0x0f, }, + [13] = { .offset = 0xc4, .value = 0x03, }, + [14] = { .offset = 0xc5, .value = 0x16, }, + [15] = { .offset = 0xc6, .value = 0x00, }, + [16] = { .offset = 0xc7, .value = 0x02, }, + [17] = { .offset = 0xc8, .value = 0x02, }, + [18] = { .offset = 0xf4, .value = 0x00, }, + [19] = { .offset = 0x80, .value = 0xff, }, + [20] = { .offset = 0x81, .value = 0x07, }, + [21] = { .offset = 0x82, .value = 0x3d, }, + [22] = { .offset = 0x83, .value = 0x05, }, + [23] = { .offset = 0x94, .value = 0x00, }, + [24] = { .offset = 0x95, .value = 0x00, }, + [25] = { .offset = 0x96, .value = 0x05, }, + [26] = { .offset = 0x97, .value = 0x00, }, + [27] = { .offset = 0x9a, .value = 0x88, }, + [28] = { .offset = 0x9b, .value = 0x00, }, + [29] = { .offset = 0x98, .value = 0x00, }, + [30] = { .offset = 0x99, .value = 0x00, }, + [31] = { .offset = 0xf7, .value = 0x88, }, + [32] = { .offset = 0xf8, .value = 0x0a, }, + [33] = { .offset = 0x9c, .value = 0x24, }, + [34] = { .offset = 0x9d, .value = 0x00, }, + [35] = { .offset = 0x9e, .value = 0x25, }, + [36] = { .offset = 0x9f, .value = 0x03, }, + [37] = { .offset = 0xa0, .value = 0x28, }, + [38] = { .offset = 0xa1, .value = 0x01, }, + [39] = { .offset = 0xa2, .value = 0x28, }, + [40] = { .offset = 0xa3, .value = 0x05, }, + [41] = { .offset = 0xb6, .value = 0x09, }, + [42] = { .offset = 0xb8, .value = 0x00, }, + [43] = { .offset = 0xb9, .value = 0xa0, }, + [44] = { .offset = 0xba, .value = 0x00, }, + [45] = { .offset = 0xbb, .value = 0x20, }, + [46] = { .offset = 0x10, .value = 0x00, }, + [47] = { .offset = 0x11, .value = 0xa0, }, + [48] = { .offset = 0x12, .value = 0x02, }, + [49] = { .offset = 0x20, .value = 0x00, }, + [50] = { .offset = 0x22, .value = 0x00, }, + [51] = { .offset = 0x23, .value = 0x00, }, + [52] = { .offset = 0x24, .value = 0x00, }, + [53] = { .offset = 0x25, .value = 0x00, }, + [54] = { .offset = 0x8c, .value = 0x10, }, + [55] = { .offset = 0x8d, .value = 0x02, }, + [56] = { .offset = 0x8e, .value = 0x10, }, + [57] = { .offset = 0x8f, .value = 0x00, }, + [58] = { .offset = 0x90, .value = 0xff, }, + [59] = { .offset = 0x91, .value = 0x07, }, + [60] = { .offset = 0x92, .value = 0xa0, }, + [61] = { .offset = 0x93, .value = 0x02, }, + [62] = { .offset = 0xa5, .value = 0x00, }, + [63] = { .offset = 0xa6, .value = 0x00, }, + [64] = { .offset = 0xa7, .value = 0x00, }, + [65] = { .offset = 0xa8, .value = 0x00, }, + [66] = { .offset = 0xa9, .value = 0x04, }, + [67] = { .offset = 0xaa, .value = 0x70, }, + [68] = { .offset = 0xab, .value = 0x4f, }, + [69] = { .offset = 0xac, .value = 0x00, }, + [70] = { .offset = 0xa4, .value = 0x84, }, + [71] = { .offset = 0x7e, .value = 0x18, }, + [72] = { .offset = 0x84, .value = 0x00, }, + [73] = { .offset = 0x85, .value = 0x00, }, + [74] = { .offset = 0x86, .value = 0x00, }, + [75] = { .offset = 0x87, .value = 0x00, }, + [76] = { .offset = 0x88, .value = 0x00, }, + [77] = { .offset = 0x89, .value = 0x00, }, + [78] = { .offset = 0x8a, .value = 0x00, }, + [79] = { .offset = 0x8b, .value = 0x00, }, + [80] = { .offset = 0x26, .value = 0x00, }, + [81] = { .offset = 0x27, .value = 0x00, }, + [82] = { .offset = 0xad, .value = 0x00, }, + [83] = { .offset = 0x08, .value = 0x34, }, /* 0x35 */ + [84] = { .offset = 0x41, .value = 0x00, }, + [85] = { .offset = 0xc0, .value = 0x01, }, + }, +}; + struct ns2501_priv { - //I2CDevRec d; bool quiet; - int reg_8_shadow; - int reg_8_set; - // Shadow registers for i915 - int dvoc; - int pll_a; - int srcdim; - int fw_blc; + const struct ns2501_reg *regs; }; #define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr)) @@ -205,11 +480,9 @@ static bool ns2501_init(struct intel_dvo_device *dvo, goto out; } ns->quiet = false; - ns->reg_8_set = 0; - ns->reg_8_shadow = - NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN; DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n"); + return true; out: @@ -255,180 +528,26 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - bool ok; - int retries = 10; struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); + int mode_idx, i; DRM_DEBUG_KMS ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n", mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal); - /* - * Where do I find the native resolution for which scaling is not required??? - * - * First trigger the DVO on as otherwise the chip does not appear on the i2c - * bus. - */ - do { - ok = true; - - if (mode->hdisplay == 800 && mode->vdisplay == 600) { - /* mode 277 */ - ns->reg_8_shadow &= ~NS2501_8_BPAS; - DRM_DEBUG_KMS("switching to 800x600\n"); - - /* - * No, I do not know where this data comes from. - * It is just what the video bios left in the DVO, so - * I'm just copying it here over. - * This also means that I cannot support any other modes - * except the ones supported by the bios. - */ - ok &= ns2501_writeb(dvo, 0x11, 0xc8); // 0xc7 also works. - ok &= ns2501_writeb(dvo, 0x1b, 0x19); - ok &= ns2501_writeb(dvo, 0x1c, 0x62); // VBIOS left 0x64 here, but 0x62 works nicer - ok &= ns2501_writeb(dvo, 0x1d, 0x02); - - ok &= ns2501_writeb(dvo, 0x34, 0x03); - ok &= ns2501_writeb(dvo, 0x35, 0xff); - - ok &= ns2501_writeb(dvo, 0x80, 0x27); - ok &= ns2501_writeb(dvo, 0x81, 0x03); - ok &= ns2501_writeb(dvo, 0x82, 0x41); - ok &= ns2501_writeb(dvo, 0x83, 0x05); + if (mode->hdisplay == 640 && mode->vdisplay == 480) + mode_idx = MODE_640x480; + else if (mode->hdisplay == 800 && mode->vdisplay == 600) + mode_idx = MODE_800x600; + else if (mode->hdisplay == 1024 && mode->vdisplay == 768) + mode_idx = MODE_1024x768; + else + return; - ok &= ns2501_writeb(dvo, 0x8d, 0x02); - ok &= ns2501_writeb(dvo, 0x8e, 0x04); - ok &= ns2501_writeb(dvo, 0x8f, 0x00); + ns->regs = regs_1024x768[mode_idx]; - ok &= ns2501_writeb(dvo, 0x90, 0xfe); /* vertical. VBIOS left 0xff here, but 0xfe works better */ - ok &= ns2501_writeb(dvo, 0x91, 0x07); - ok &= ns2501_writeb(dvo, 0x94, 0x00); - ok &= ns2501_writeb(dvo, 0x95, 0x00); - - ok &= ns2501_writeb(dvo, 0x96, 0x00); - - ok &= ns2501_writeb(dvo, 0x99, 0x00); - ok &= ns2501_writeb(dvo, 0x9a, 0x88); - - ok &= ns2501_writeb(dvo, 0x9c, 0x23); /* Looks like first and last line of the image. */ - ok &= ns2501_writeb(dvo, 0x9d, 0x00); - ok &= ns2501_writeb(dvo, 0x9e, 0x25); - ok &= ns2501_writeb(dvo, 0x9f, 0x03); - - ok &= ns2501_writeb(dvo, 0xa4, 0x80); - - ok &= ns2501_writeb(dvo, 0xb6, 0x00); - - ok &= ns2501_writeb(dvo, 0xb9, 0xc8); /* horizontal? */ - ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */ - - ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */ - ok &= ns2501_writeb(dvo, 0xc1, 0xd7); - - ok &= ns2501_writeb(dvo, 0xc2, 0x00); - ok &= ns2501_writeb(dvo, 0xc3, 0xf8); - - ok &= ns2501_writeb(dvo, 0xc4, 0x03); - ok &= ns2501_writeb(dvo, 0xc5, 0x1a); - - ok &= ns2501_writeb(dvo, 0xc6, 0x00); - ok &= ns2501_writeb(dvo, 0xc7, 0x73); - ok &= ns2501_writeb(dvo, 0xc8, 0x02); - - } else if (mode->hdisplay == 640 && mode->vdisplay == 480) { - /* mode 274 */ - DRM_DEBUG_KMS("switching to 640x480\n"); - /* - * No, I do not know where this data comes from. - * It is just what the video bios left in the DVO, so - * I'm just copying it here over. - * This also means that I cannot support any other modes - * except the ones supported by the bios. - */ - ns->reg_8_shadow &= ~NS2501_8_BPAS; - - ok &= ns2501_writeb(dvo, 0x11, 0xa0); - ok &= ns2501_writeb(dvo, 0x1b, 0x11); - ok &= ns2501_writeb(dvo, 0x1c, 0x54); - ok &= ns2501_writeb(dvo, 0x1d, 0x03); - - ok &= ns2501_writeb(dvo, 0x34, 0x03); - ok &= ns2501_writeb(dvo, 0x35, 0xff); - - ok &= ns2501_writeb(dvo, 0x80, 0xff); - ok &= ns2501_writeb(dvo, 0x81, 0x07); - ok &= ns2501_writeb(dvo, 0x82, 0x3d); - ok &= ns2501_writeb(dvo, 0x83, 0x05); - - ok &= ns2501_writeb(dvo, 0x8d, 0x02); - ok &= ns2501_writeb(dvo, 0x8e, 0x10); - ok &= ns2501_writeb(dvo, 0x8f, 0x00); - - ok &= ns2501_writeb(dvo, 0x90, 0xff); /* vertical */ - ok &= ns2501_writeb(dvo, 0x91, 0x07); - ok &= ns2501_writeb(dvo, 0x94, 0x00); - ok &= ns2501_writeb(dvo, 0x95, 0x00); - - ok &= ns2501_writeb(dvo, 0x96, 0x05); - - ok &= ns2501_writeb(dvo, 0x99, 0x00); - ok &= ns2501_writeb(dvo, 0x9a, 0x88); - - ok &= ns2501_writeb(dvo, 0x9c, 0x24); - ok &= ns2501_writeb(dvo, 0x9d, 0x00); - ok &= ns2501_writeb(dvo, 0x9e, 0x25); - ok &= ns2501_writeb(dvo, 0x9f, 0x03); - - ok &= ns2501_writeb(dvo, 0xa4, 0x84); - - ok &= ns2501_writeb(dvo, 0xb6, 0x09); - - ok &= ns2501_writeb(dvo, 0xb9, 0xa0); /* horizontal? */ - ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */ - - ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */ - ok &= ns2501_writeb(dvo, 0xc1, 0x90); - - ok &= ns2501_writeb(dvo, 0xc2, 0x00); - ok &= ns2501_writeb(dvo, 0xc3, 0x0f); - - ok &= ns2501_writeb(dvo, 0xc4, 0x03); - ok &= ns2501_writeb(dvo, 0xc5, 0x16); - - ok &= ns2501_writeb(dvo, 0xc6, 0x00); - ok &= ns2501_writeb(dvo, 0xc7, 0x02); - ok &= ns2501_writeb(dvo, 0xc8, 0x02); - - } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) { - /* mode 280 */ - DRM_DEBUG_KMS("switching to 1024x768\n"); - /* - * This might or might not work, actually. I'm silently - * assuming here that the native panel resolution is - * 1024x768. If not, then this leaves the scaler disabled - * generating a picture that is likely not the expected. - * - * Problem is that I do not know where to take the panel - * dimensions from. - * - * Enable the bypass, scaling not required. - * - * The scaler registers are irrelevant here.... - * - */ - ns->reg_8_shadow |= NS2501_8_BPAS; - ok &= ns2501_writeb(dvo, 0x37, 0x44); - } else { - /* - * Data not known. Bummer! - * Hopefully, the code should not go here - * as mode_OK delivered no other modes. - */ - ns->reg_8_shadow |= NS2501_8_BPAS; - } - ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow); - } while (!ok && retries--); + for (i = 0; i < 84; i++) + ns2501_writeb(dvo, ns->regs[i].offset, ns->regs[i].value); } /* set the NS2501 power state */ @@ -439,43 +558,45 @@ static bool ns2501_get_hw_state(struct intel_dvo_device *dvo) if (!ns2501_readb(dvo, NS2501_REG8, &ch)) return false; - if (ch & NS2501_8_PD) - return true; - else - return false; + return ch & NS2501_8_PD; } /* set the NS2501 power state */ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) { - bool ok; - int retries = 10; struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); - unsigned char ch; DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable); - ch = ns->reg_8_shadow; + if (enable) { + if (WARN_ON(ns->regs[83].offset != 0x08 || + ns->regs[84].offset != 0x41 || + ns->regs[85].offset != 0xc0)) + return; - if (enable) - ch |= NS2501_8_PD; - else - ch &= ~NS2501_8_PD; - - if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) { - ns->reg_8_set = 1; - ns->reg_8_shadow = ch; - - do { - ok = true; - ok &= ns2501_writeb(dvo, NS2501_REG8, ch); - ok &= - ns2501_writeb(dvo, 0x34, - enable ? 0x03 : 0x00); - ok &= - ns2501_writeb(dvo, 0x35, - enable ? 0xff : 0x00); - } while (!ok && retries--); + ns2501_writeb(dvo, 0xc0, ns->regs[85].value | 0x08); + + ns2501_writeb(dvo, 0x41, ns->regs[84].value); + + ns2501_writeb(dvo, 0x34, 0x01); + msleep(15); + + ns2501_writeb(dvo, 0x08, 0x35); + if (!(ns->regs[83].value & NS2501_8_BPAS)) + ns2501_writeb(dvo, 0x08, 0x31); + msleep(200); + + ns2501_writeb(dvo, 0x34, 0x03); + + ns2501_writeb(dvo, 0xc0, ns->regs[85].value); + } else { + ns2501_writeb(dvo, 0x34, 0x01); + msleep(200); + + ns2501_writeb(dvo, 0x08, 0x34); + msleep(15); + + ns2501_writeb(dvo, 0x34, 0x00); } }