Subversion Repositories Kolibri OS

Rev

Rev 4560 | Rev 6084 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *
  3.  * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter
  4.  *
  5.  * All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the
  9.  * "Software"), to deal in the Software without restriction, including
  10.  * without limitation the rights to use, copy, modify, merge, publish,
  11.  * distribute, sub license, and/or sell copies of the Software, and to
  12.  * permit persons to whom the Software is furnished to do so, subject to
  13.  * the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the
  16.  * next paragraph) shall be included in all copies or substantial portions
  17.  * of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  23.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26.  *
  27.  */
  28.  
  29. #include "dvo.h"
  30. #include "i915_reg.h"
  31. #include "i915_drv.h"
  32.  
  33. #define NS2501_VID 0x1305
  34. #define NS2501_DID 0x6726
  35.  
  36. #define NS2501_VID_LO 0x00
  37. #define NS2501_VID_HI 0x01
  38. #define NS2501_DID_LO 0x02
  39. #define NS2501_DID_HI 0x03
  40. #define NS2501_REV 0x04
  41. #define NS2501_RSVD 0x05
  42. #define NS2501_FREQ_LO 0x06
  43. #define NS2501_FREQ_HI 0x07
  44.  
  45. #define NS2501_REG8 0x08
  46. #define NS2501_8_VEN (1<<5)
  47. #define NS2501_8_HEN (1<<4)
  48. #define NS2501_8_DSEL (1<<3)
  49. #define NS2501_8_BPAS (1<<2)
  50. #define NS2501_8_RSVD (1<<1)
  51. #define NS2501_8_PD (1<<0)
  52.  
  53. #define NS2501_REG9 0x09
  54. #define NS2501_9_VLOW (1<<7)
  55. #define NS2501_9_MSEL_MASK (0x7<<4)
  56. #define NS2501_9_TSEL (1<<3)
  57. #define NS2501_9_RSEN (1<<2)
  58. #define NS2501_9_RSVD (1<<1)
  59. #define NS2501_9_MDI (1<<0)
  60.  
  61. #define NS2501_REGC 0x0c
  62.  
  63. struct ns2501_priv {
  64.         //I2CDevRec d;
  65.         bool quiet;
  66.         int reg_8_shadow;
  67.         int reg_8_set;
  68.         // Shadow registers for i915
  69.         int dvoc;
  70.         int pll_a;
  71.         int srcdim;
  72.         int fw_blc;
  73. };
  74.  
  75. #define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
  76.  
  77. /*
  78.  * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
  79.  * laptops does not react on the i2c bus unless
  80.  * both the PLL is running and the display is configured in its native
  81.  * resolution.
  82.  * This function forces the DVO on, and stores the registers it touches.
  83.  * Afterwards, registers are restored to regular values.
  84.  *
  85.  * This is pretty much a hack, though it works.
  86.  * Without that, ns2501_readb and ns2501_writeb fail
  87.  * when switching the resolution.
  88.  */
  89.  
  90. /*
  91. ** Read a register from the ns2501.
  92. ** Returns true if successful, false otherwise.
  93. ** If it returns false, it might be wise to enable the
  94. ** DVO with the above function.
  95. */
  96. static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
  97. {
  98.         struct ns2501_priv *ns = dvo->dev_priv;
  99.         struct i2c_adapter *adapter = dvo->i2c_bus;
  100.         u8 out_buf[2];
  101.         u8 in_buf[2];
  102.  
  103.         struct i2c_msg msgs[] = {
  104.                 {
  105.                  .addr = dvo->slave_addr,
  106.                  .flags = 0,
  107.                  .len = 1,
  108.                  .buf = out_buf,
  109.                  },
  110.                 {
  111.                  .addr = dvo->slave_addr,
  112.                  .flags = I2C_M_RD,
  113.                  .len = 1,
  114.                  .buf = in_buf,
  115.                  }
  116.         };
  117.  
  118.         out_buf[0] = addr;
  119.         out_buf[1] = 0;
  120.  
  121.         if (i2c_transfer(adapter, msgs, 2) == 2) {
  122.                 *ch = in_buf[0];
  123.                 return true;
  124.         }
  125.  
  126.         if (!ns->quiet) {
  127.                 DRM_DEBUG_KMS
  128.                     ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
  129.                      adapter->name, dvo->slave_addr);
  130.         }
  131.  
  132.         return false;
  133. }
  134.  
  135. /*
  136. ** Write a register to the ns2501.
  137. ** Returns true if successful, false otherwise.
  138. ** If it returns false, it might be wise to enable the
  139. ** DVO with the above function.
  140. */
  141. static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
  142. {
  143.         struct ns2501_priv *ns = dvo->dev_priv;
  144.         struct i2c_adapter *adapter = dvo->i2c_bus;
  145.         uint8_t out_buf[2];
  146.  
  147.         struct i2c_msg msg = {
  148.                 .addr = dvo->slave_addr,
  149.                 .flags = 0,
  150.                 .len = 2,
  151.                 .buf = out_buf,
  152.         };
  153.  
  154.         out_buf[0] = addr;
  155.         out_buf[1] = ch;
  156.  
  157.         if (i2c_transfer(adapter, &msg, 1) == 1) {
  158.                 return true;
  159.         }
  160.  
  161.         if (!ns->quiet) {
  162.                 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
  163.                               addr, adapter->name, dvo->slave_addr);
  164.         }
  165.  
  166.         return false;
  167. }
  168.  
  169. /* National Semiconductor 2501 driver for chip on i2c bus
  170.  * scan for the chip on the bus.
  171.  * Hope the VBIOS initialized the PLL correctly so we can
  172.  * talk to it. If not, it will not be seen and not detected.
  173.  * Bummer!
  174.  */
  175. static bool ns2501_init(struct intel_dvo_device *dvo,
  176.                         struct i2c_adapter *adapter)
  177. {
  178.         /* this will detect the NS2501 chip on the specified i2c bus */
  179.         struct ns2501_priv *ns;
  180.         unsigned char ch;
  181.  
  182.         ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
  183.         if (ns == NULL)
  184.                 return false;
  185.  
  186.         dvo->i2c_bus = adapter;
  187.         dvo->dev_priv = ns;
  188.         ns->quiet = true;
  189.  
  190.         if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
  191.                 goto out;
  192.  
  193.         if (ch != (NS2501_VID & 0xff)) {
  194.                 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
  195.                               ch, adapter->name, dvo->slave_addr);
  196.                 goto out;
  197.         }
  198.  
  199.         if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
  200.                 goto out;
  201.  
  202.         if (ch != (NS2501_DID & 0xff)) {
  203.                 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
  204.                               ch, adapter->name, dvo->slave_addr);
  205.                 goto out;
  206.         }
  207.         ns->quiet = false;
  208.         ns->reg_8_set = 0;
  209.         ns->reg_8_shadow =
  210.             NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;
  211.  
  212.         DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
  213.         return true;
  214.  
  215. out:
  216.         kfree(ns);
  217.         return false;
  218. }
  219.  
  220. static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
  221. {
  222.         /*
  223.          * This is a Laptop display, it doesn't have hotplugging.
  224.          * Even if not, the detection bit of the 2501 is unreliable as
  225.          * it only works for some display types.
  226.          * It is even more unreliable as the PLL must be active for
  227.          * allowing reading from the chiop.
  228.          */
  229.         return connector_status_connected;
  230. }
  231.  
  232. static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
  233.                                               struct drm_display_mode *mode)
  234. {
  235.         DRM_DEBUG_KMS
  236.             ("is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
  237.              mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
  238.  
  239.         /*
  240.          * Currently, these are all the modes I have data from.
  241.          * More might exist. Unclear how to find the native resolution
  242.          * of the panel in here so we could always accept it
  243.          * by disabling the scaler.
  244.          */
  245.         if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
  246.             (mode->hdisplay == 640 && mode->vdisplay == 480) ||
  247.             (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
  248.                 return MODE_OK;
  249.         } else {
  250.                 return MODE_ONE_SIZE;   /* Is this a reasonable error? */
  251.         }
  252. }
  253.  
  254. static void ns2501_mode_set(struct intel_dvo_device *dvo,
  255.                             struct drm_display_mode *mode,
  256.                             struct drm_display_mode *adjusted_mode)
  257. {
  258.         bool ok;
  259.         int retries = 10;
  260.         struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
  261.  
  262.         DRM_DEBUG_KMS
  263.             ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
  264.              mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
  265.  
  266.         /*
  267.          * Where do I find the native resolution for which scaling is not required???
  268.          *
  269.          * First trigger the DVO on as otherwise the chip does not appear on the i2c
  270.          * bus.
  271.          */
  272.         do {
  273.                 ok = true;
  274.  
  275.                 if (mode->hdisplay == 800 && mode->vdisplay == 600) {
  276.                         /* mode 277 */
  277.                         ns->reg_8_shadow &= ~NS2501_8_BPAS;
  278.                         DRM_DEBUG_KMS("switching to 800x600\n");
  279.  
  280.                         /*
  281.                          * No, I do not know where this data comes from.
  282.                          * It is just what the video bios left in the DVO, so
  283.                          * I'm just copying it here over.
  284.                          * This also means that I cannot support any other modes
  285.                          * except the ones supported by the bios.
  286.                          */
  287.                         ok &= ns2501_writeb(dvo, 0x11, 0xc8);   // 0xc7 also works.
  288.                         ok &= ns2501_writeb(dvo, 0x1b, 0x19);
  289.                         ok &= ns2501_writeb(dvo, 0x1c, 0x62);   // VBIOS left 0x64 here, but 0x62 works nicer
  290.                         ok &= ns2501_writeb(dvo, 0x1d, 0x02);
  291.  
  292.                         ok &= ns2501_writeb(dvo, 0x34, 0x03);
  293.                         ok &= ns2501_writeb(dvo, 0x35, 0xff);
  294.  
  295.                         ok &= ns2501_writeb(dvo, 0x80, 0x27);
  296.                         ok &= ns2501_writeb(dvo, 0x81, 0x03);
  297.                         ok &= ns2501_writeb(dvo, 0x82, 0x41);
  298.                         ok &= ns2501_writeb(dvo, 0x83, 0x05);
  299.  
  300.                         ok &= ns2501_writeb(dvo, 0x8d, 0x02);
  301.                         ok &= ns2501_writeb(dvo, 0x8e, 0x04);
  302.                         ok &= ns2501_writeb(dvo, 0x8f, 0x00);
  303.  
  304.                         ok &= ns2501_writeb(dvo, 0x90, 0xfe);   /* vertical. VBIOS left 0xff here, but 0xfe works better */
  305.                         ok &= ns2501_writeb(dvo, 0x91, 0x07);
  306.                         ok &= ns2501_writeb(dvo, 0x94, 0x00);
  307.                         ok &= ns2501_writeb(dvo, 0x95, 0x00);
  308.  
  309.                         ok &= ns2501_writeb(dvo, 0x96, 0x00);
  310.  
  311.                         ok &= ns2501_writeb(dvo, 0x99, 0x00);
  312.                         ok &= ns2501_writeb(dvo, 0x9a, 0x88);
  313.  
  314.                         ok &= ns2501_writeb(dvo, 0x9c, 0x23);   /* Looks like first and last line of the image. */
  315.                         ok &= ns2501_writeb(dvo, 0x9d, 0x00);
  316.                         ok &= ns2501_writeb(dvo, 0x9e, 0x25);
  317.                         ok &= ns2501_writeb(dvo, 0x9f, 0x03);
  318.  
  319.                         ok &= ns2501_writeb(dvo, 0xa4, 0x80);
  320.  
  321.                         ok &= ns2501_writeb(dvo, 0xb6, 0x00);
  322.  
  323.                         ok &= ns2501_writeb(dvo, 0xb9, 0xc8);   /* horizontal? */
  324.                         ok &= ns2501_writeb(dvo, 0xba, 0x00);   /* horizontal? */
  325.  
  326.                         ok &= ns2501_writeb(dvo, 0xc0, 0x05);   /* horizontal? */
  327.                         ok &= ns2501_writeb(dvo, 0xc1, 0xd7);
  328.  
  329.                         ok &= ns2501_writeb(dvo, 0xc2, 0x00);
  330.                         ok &= ns2501_writeb(dvo, 0xc3, 0xf8);
  331.  
  332.                         ok &= ns2501_writeb(dvo, 0xc4, 0x03);
  333.                         ok &= ns2501_writeb(dvo, 0xc5, 0x1a);
  334.  
  335.                         ok &= ns2501_writeb(dvo, 0xc6, 0x00);
  336.                         ok &= ns2501_writeb(dvo, 0xc7, 0x73);
  337.                         ok &= ns2501_writeb(dvo, 0xc8, 0x02);
  338.  
  339.                 } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
  340.                         /* mode 274 */
  341.                         DRM_DEBUG_KMS("switching to 640x480\n");
  342.                         /*
  343.                          * No, I do not know where this data comes from.
  344.                          * It is just what the video bios left in the DVO, so
  345.                          * I'm just copying it here over.
  346.                          * This also means that I cannot support any other modes
  347.                          * except the ones supported by the bios.
  348.                          */
  349.                         ns->reg_8_shadow &= ~NS2501_8_BPAS;
  350.  
  351.                         ok &= ns2501_writeb(dvo, 0x11, 0xa0);
  352.                         ok &= ns2501_writeb(dvo, 0x1b, 0x11);
  353.                         ok &= ns2501_writeb(dvo, 0x1c, 0x54);
  354.                         ok &= ns2501_writeb(dvo, 0x1d, 0x03);
  355.  
  356.                         ok &= ns2501_writeb(dvo, 0x34, 0x03);
  357.                         ok &= ns2501_writeb(dvo, 0x35, 0xff);
  358.  
  359.                         ok &= ns2501_writeb(dvo, 0x80, 0xff);
  360.                         ok &= ns2501_writeb(dvo, 0x81, 0x07);
  361.                         ok &= ns2501_writeb(dvo, 0x82, 0x3d);
  362.                         ok &= ns2501_writeb(dvo, 0x83, 0x05);
  363.  
  364.                         ok &= ns2501_writeb(dvo, 0x8d, 0x02);
  365.                         ok &= ns2501_writeb(dvo, 0x8e, 0x10);
  366.                         ok &= ns2501_writeb(dvo, 0x8f, 0x00);
  367.  
  368.                         ok &= ns2501_writeb(dvo, 0x90, 0xff);   /* vertical */
  369.                         ok &= ns2501_writeb(dvo, 0x91, 0x07);
  370.                         ok &= ns2501_writeb(dvo, 0x94, 0x00);
  371.                         ok &= ns2501_writeb(dvo, 0x95, 0x00);
  372.  
  373.                         ok &= ns2501_writeb(dvo, 0x96, 0x05);
  374.  
  375.                         ok &= ns2501_writeb(dvo, 0x99, 0x00);
  376.                         ok &= ns2501_writeb(dvo, 0x9a, 0x88);
  377.  
  378.                         ok &= ns2501_writeb(dvo, 0x9c, 0x24);
  379.                         ok &= ns2501_writeb(dvo, 0x9d, 0x00);
  380.                         ok &= ns2501_writeb(dvo, 0x9e, 0x25);
  381.                         ok &= ns2501_writeb(dvo, 0x9f, 0x03);
  382.  
  383.                         ok &= ns2501_writeb(dvo, 0xa4, 0x84);
  384.  
  385.                         ok &= ns2501_writeb(dvo, 0xb6, 0x09);
  386.  
  387.                         ok &= ns2501_writeb(dvo, 0xb9, 0xa0);   /* horizontal? */
  388.                         ok &= ns2501_writeb(dvo, 0xba, 0x00);   /* horizontal? */
  389.  
  390.                         ok &= ns2501_writeb(dvo, 0xc0, 0x05);   /* horizontal? */
  391.                         ok &= ns2501_writeb(dvo, 0xc1, 0x90);
  392.  
  393.                         ok &= ns2501_writeb(dvo, 0xc2, 0x00);
  394.                         ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
  395.  
  396.                         ok &= ns2501_writeb(dvo, 0xc4, 0x03);
  397.                         ok &= ns2501_writeb(dvo, 0xc5, 0x16);
  398.  
  399.                         ok &= ns2501_writeb(dvo, 0xc6, 0x00);
  400.                         ok &= ns2501_writeb(dvo, 0xc7, 0x02);
  401.                         ok &= ns2501_writeb(dvo, 0xc8, 0x02);
  402.  
  403.                 } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
  404.                         /* mode 280 */
  405.                         DRM_DEBUG_KMS("switching to 1024x768\n");
  406.                         /*
  407.                          * This might or might not work, actually. I'm silently
  408.                          * assuming here that the native panel resolution is
  409.                          * 1024x768. If not, then this leaves the scaler disabled
  410.                          * generating a picture that is likely not the expected.
  411.                          *
  412.                          * Problem is that I do not know where to take the panel
  413.                          * dimensions from.
  414.                          *
  415.                          * Enable the bypass, scaling not required.
  416.                          *
  417.                          * The scaler registers are irrelevant here....
  418.                          *
  419.                          */
  420.                         ns->reg_8_shadow |= NS2501_8_BPAS;
  421.                         ok &= ns2501_writeb(dvo, 0x37, 0x44);
  422.                 } else {
  423.                         /*
  424.                          * Data not known. Bummer!
  425.                          * Hopefully, the code should not go here
  426.                          * as mode_OK delivered no other modes.
  427.                          */
  428.                         ns->reg_8_shadow |= NS2501_8_BPAS;
  429.                 }
  430.                 ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
  431.         } while (!ok && retries--);
  432. }
  433.  
  434. /* set the NS2501 power state */
  435. static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
  436. {
  437.         unsigned char ch;
  438.  
  439.         if (!ns2501_readb(dvo, NS2501_REG8, &ch))
  440.                 return false;
  441.  
  442.         if (ch & NS2501_8_PD)
  443.                 return true;
  444.         else
  445.                 return false;
  446. }
  447.  
  448. /* set the NS2501 power state */
  449. static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
  450. {
  451.         bool ok;
  452.         int retries = 10;
  453.         struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
  454.         unsigned char ch;
  455.  
  456.         DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable);
  457.  
  458.         ch = ns->reg_8_shadow;
  459.  
  460.         if (enable)
  461.                 ch |= NS2501_8_PD;
  462.         else
  463.                 ch &= ~NS2501_8_PD;
  464.  
  465.         if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
  466.                 ns->reg_8_set = 1;
  467.                 ns->reg_8_shadow = ch;
  468.  
  469.                 do {
  470.                         ok = true;
  471.                         ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
  472.                         ok &=
  473.                             ns2501_writeb(dvo, 0x34,
  474.                                           enable ? 0x03 : 0x00);
  475.                         ok &=
  476.                             ns2501_writeb(dvo, 0x35,
  477.                                           enable ? 0xff : 0x00);
  478.                 } while (!ok && retries--);
  479.         }
  480. }
  481.  
  482. static void ns2501_dump_regs(struct intel_dvo_device *dvo)
  483. {
  484.         uint8_t val;
  485.  
  486.         ns2501_readb(dvo, NS2501_FREQ_LO, &val);
  487.         DRM_DEBUG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
  488.         ns2501_readb(dvo, NS2501_FREQ_HI, &val);
  489.         DRM_DEBUG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
  490.         ns2501_readb(dvo, NS2501_REG8, &val);
  491.         DRM_DEBUG_KMS("NS2501_REG8: 0x%02x\n", val);
  492.         ns2501_readb(dvo, NS2501_REG9, &val);
  493.         DRM_DEBUG_KMS("NS2501_REG9: 0x%02x\n", val);
  494.         ns2501_readb(dvo, NS2501_REGC, &val);
  495.         DRM_DEBUG_KMS("NS2501_REGC: 0x%02x\n", val);
  496. }
  497.  
  498. static void ns2501_destroy(struct intel_dvo_device *dvo)
  499. {
  500.         struct ns2501_priv *ns = dvo->dev_priv;
  501.  
  502.         if (ns) {
  503.                 kfree(ns);
  504.                 dvo->dev_priv = NULL;
  505.         }
  506. }
  507.  
  508. struct intel_dvo_dev_ops ns2501_ops = {
  509.         .init = ns2501_init,
  510.         .detect = ns2501_detect,
  511.         .mode_valid = ns2501_mode_valid,
  512.         .mode_set = ns2501_mode_set,
  513.         .dpms = ns2501_dpms,
  514.         .get_hw_state = ns2501_get_hw_state,
  515.         .dump_regs = ns2501_dump_regs,
  516.         .destroy = ns2501_destroy,
  517. };
  518.