Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2007, 2008  Luc Verhaegen <lverhaegen@novell.com>
  3.  * Copyright 2007, 2008  Matthias Hopf <mhopf@novell.com>
  4.  * Copyright 2007, 2008  Egbert Eich   <eich@novell.com>
  5.  * Copyright 2007, 2008  Advanced Micro Devices, Inc.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included in
  15.  * all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23.  * OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29.  
  30. #include "xf86.h"
  31.  
  32. #if HAVE_XF86_ANSIC_H
  33. # include "xf86_ansic.h"
  34. #else
  35. # include <unistd.h>
  36. #endif
  37.  
  38. #include "rhd.h"
  39. #include "rhd_crtc.h"
  40. #include "rhd_pll.h"
  41. #include "rhd_lut.h"
  42. #include "rhd_regs.h"
  43. #include "rhd_modes.h"
  44. #include "rhd_mc.h"
  45. #if defined (ATOM_BIOS) && defined (ATOM_BIOS_PARSER)
  46. # include "rhd_atombios.h"
  47.  
  48. # define D1_REG_OFFSET 0x0000
  49. # define D2_REG_OFFSET 0x0800
  50.  
  51. struct rhdCrtcScalePrivate {
  52.     void *RegList;
  53.     CARD32 StoreViewportSize;
  54.     CARD32 StoreViewportStart;
  55. };
  56.  
  57. /*
  58.  *
  59.  */
  60. static void
  61. rhdAtomCrtcRestore(struct rhdCrtc *Crtc, void *Store)
  62. {
  63.     RHDPtr rhdPtr = RHDPTRI(Crtc);
  64.     union AtomBiosArg data;
  65.  
  66.     RHDFUNC(rhdPtr);
  67.  
  68.     data.Address = Store;
  69.     RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_RESTORE_REGISTERS, &data);
  70. }
  71.  
  72. /*
  73.  *
  74.  */
  75. static void
  76. rhdAtomScaleSet(struct rhdCrtc *Crtc, enum rhdCrtcScaleType Type,
  77.            DisplayModePtr Mode, DisplayModePtr ScaledToMode)
  78. {
  79.     RHDPtr rhdPtr = RHDPTRI(Crtc);
  80.     struct rhdScalerOverscan Overscan;
  81.     struct atomCrtcOverscan AtomOverscan;
  82.     enum atomCrtc AtomCrtc = RHD_CRTC_1;
  83.     enum atomScaler Scaler  = 0;
  84.     enum atomScaleMode ScaleMode = 0;
  85.     union AtomBiosArg data;
  86.     CARD32 RegOff = 0;
  87.  
  88.     RHDDebug(Crtc->scrnIndex, "FUNCTION: %s: %s viewport: %ix%i\n", __func__, Crtc->Name,
  89.              Mode->CrtcHDisplay, Mode->CrtcVDisplay);
  90.  
  91.     /* D1Mode registers */
  92.     if (Crtc->Id == RHD_CRTC_1)
  93.         RegOff = D1_REG_OFFSET;
  94.     else
  95.         RegOff = D2_REG_OFFSET;
  96.  
  97.     RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE,
  98.                 Mode->CrtcVDisplay | (Mode->CrtcHDisplay << 16));
  99.     RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, 0);
  100.  
  101.     Overscan = rhdCalculateOverscan(Mode, ScaledToMode, Type);
  102.     Type = Overscan.Type;
  103.  
  104.     ASSERT(Crtc->ScalePriv);
  105.     data.Address = &((Crtc->ScalePriv)->RegList);
  106.     RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  107.  
  108.     AtomOverscan.ovscnLeft = Overscan.OverscanLeft;
  109.     AtomOverscan.ovscnRight = Overscan.OverscanRight;
  110.     AtomOverscan.ovscnTop = Overscan.OverscanTop;
  111.     AtomOverscan.ovscnBottom = Overscan.OverscanBottom;
  112.  
  113.     switch (Crtc->Id) {
  114.         case  RHD_CRTC_1:
  115.             Scaler = atomScaler1;
  116.             AtomCrtc = atomCrtc1;
  117.             break;
  118.         case RHD_CRTC_2:
  119.             Scaler = atomScaler2;
  120.             AtomCrtc = atomCrtc2;
  121.             break;
  122.     }
  123.  
  124.     rhdAtomSetCRTCOverscan(rhdPtr->atomBIOS, AtomCrtc, &AtomOverscan);
  125.  
  126.     switch (Type) {
  127.         case RHD_CRTC_SCALE_TYPE_NONE:
  128.             ScaleMode = atomScaleDisable;
  129.             break;
  130.         case RHD_CRTC_SCALE_TYPE_CENTER:
  131.             ScaleMode = atomScaleCenter;
  132.             break;
  133.         case RHD_CRTC_SCALE_TYPE_SCALE:
  134.         case RHD_CRTC_SCALE_TYPE_SCALE_KEEP_ASPECT_RATIO: /* scaled to fullscreen */
  135.             ScaleMode = atomScaleExpand;
  136.             break;
  137.     }
  138.     rhdAtomSetScaler(rhdPtr->atomBIOS, Scaler, ScaleMode);
  139.  
  140.     data.Address = NULL;
  141.     RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  142.  
  143.     RHDMCTuneAccessForDisplay(rhdPtr, Crtc->Id, Mode,
  144.                               ScaledToMode ? ScaledToMode : Mode);
  145. }
  146.  
  147. /*
  148.  *
  149.  */
  150. static void
  151. rhdAtomScaleSave(struct rhdCrtc *Crtc)
  152. {
  153.     struct rhdCrtcScalePrivate* ScalePriv;
  154.     CARD32 RegOff = 0;
  155.  
  156.     RHDFUNC(Crtc);
  157.  
  158.     if (!Crtc->ScalePriv) {
  159.         if(!(ScalePriv = (struct rhdCrtcScalePrivate*)xnfcalloc(1, sizeof(struct rhdCrtcScalePrivate))))
  160.             return;
  161.         Crtc->ScalePriv = ScalePriv;
  162.     } else
  163.         ScalePriv = Crtc->ScalePriv;
  164.  
  165.     if (Crtc->Id == RHD_CRTC_1)
  166.         RegOff = D1_REG_OFFSET;
  167.     else
  168.         RegOff = D2_REG_OFFSET;
  169.  
  170.     ScalePriv->StoreViewportSize  = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_SIZE);
  171.     ScalePriv->StoreViewportStart = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_START);
  172.     ScalePriv->RegList = NULL;
  173. }
  174.  
  175. /*
  176.  *
  177.  */
  178. static void
  179. rhdAtomCrtcScaleRestore(struct rhdCrtc *Crtc)
  180. {
  181.     struct rhdCrtcScalePrivate* ScalePriv;
  182.     CARD32 RegOff = 0;
  183.  
  184.     RHDFUNC(Crtc);
  185.  
  186.     rhdAtomCrtcRestore(Crtc, &(((struct rhdCrtcScalePrivate*)Crtc->ScalePriv)->RegList));
  187.  
  188.     if (Crtc->Id == RHD_CRTC_1)
  189.         RegOff = D1_REG_OFFSET;
  190.     else
  191.         RegOff = D2_REG_OFFSET;
  192.  
  193.     ScalePriv = (struct rhdCrtcScalePrivate*)Crtc->ScalePriv;
  194.     RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE, ScalePriv->StoreViewportSize);
  195.     RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, ScalePriv->StoreViewportStart);
  196. }
  197.  
  198. /*
  199.  *
  200.  */
  201. static void
  202. rhdAtomCrtcScaleDestroy(struct rhdCrtc *Crtc)
  203. {
  204.     RHDFUNC(Crtc);
  205.  
  206.     if (Crtc->ScalePriv) {
  207.         xfree(Crtc->ScalePriv->RegList);
  208.         xfree(Crtc->ScalePriv);
  209.         Crtc->ScalePriv = NULL;
  210.     }
  211. }
  212.  
  213. /*
  214.  *
  215.  */
  216. struct rhdCrtcModePrivate {
  217.     void *RegList;
  218.     CARD32 StoreModeDataFormat;
  219. };
  220.  
  221. static void
  222. rhdAtomModeSet(struct rhdCrtc *Crtc, DisplayModePtr Mode)
  223. {
  224.     RHDPtr rhdPtr = RHDPTRI(Crtc);
  225.     union AtomBiosArg data;
  226.     CARD32 RegOff = 0;
  227.  
  228.     RHDFUNC(rhdPtr);
  229.  
  230.     ASSERT(Crtc->ModePriv);
  231.     data.Address = &((Crtc->ModePriv)->RegList);
  232.     RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  233.  
  234.     if (!rhdAtomSetCRTCTimings(rhdPtr->atomBIOS,
  235.                               Crtc->Id == RHD_CRTC_1 ? atomCrtc1 : atomCrtc2,
  236.                   Mode, 32))
  237.         xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: failed to set mode.\n",__func__);
  238.  
  239.     /* set interlaced - AtomBIOS never sets the data format - never tested? */
  240.     if (Crtc->Id == RHD_CRTC_1)
  241.         RegOff = D1_REG_OFFSET;
  242.     else
  243.         RegOff = D2_REG_OFFSET;
  244.  
  245.     if (Mode->Flags & V_INTERLACE)
  246.         RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x1);
  247.     else
  248.         RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x0);
  249.  
  250.     data.Address = NULL;
  251.     RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  252. }
  253.  
  254. /*
  255.  *
  256.  */
  257. static Bool
  258. rhdAtomCrtcPower(struct rhdCrtc *Crtc, int Power)
  259. {
  260.     RHDPtr rhdPtr = RHDPTRI(Crtc);
  261.     enum atomCrtc AtomCrtc = atomCrtc1;
  262.     union AtomBiosArg data;
  263.  
  264.     RHDFUNC(Crtc);
  265.  
  266.     switch (Crtc->Id) {
  267.         case RHD_CRTC_1:
  268.             AtomCrtc = atomCrtc1;
  269.             break;
  270.         case RHD_CRTC_2:
  271.             AtomCrtc = atomCrtc2;
  272.             break;
  273.     }
  274.     data.Address = &((Crtc->ModePriv)->RegList);
  275.     RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  276.  
  277.     /*
  278.      * We call  rhdAtomEnableCrtcMemReq blindly as this table seemed to have existed in all
  279.      * versions of AtomBIOS on the hardware we support
  280.      */
  281.     switch (Power) {
  282.         case RHD_POWER_ON:
  283.             rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
  284.             rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
  285.             break;
  286.         case RHD_POWER_RESET:
  287.         case RHD_POWER_SHUTDOWN:
  288.         default:
  289.             rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
  290.             rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
  291.             break;
  292.     }
  293.     data.Address = NULL;
  294.     RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  295.  
  296.     /*
  297.      * we always claim we succeeded here, after all, we know, AtomBIOS knows
  298.      * how to do things, right?
  299.      * Err, no, when we use AtomBIOS we should not have a clue how to find out.
  300.      */
  301.     return TRUE;
  302. }
  303.  
  304. /*
  305.  *
  306.  */
  307. static void
  308. rhdAtomCrtcBlank(struct rhdCrtc *Crtc, Bool Blank)
  309. {
  310.     RHDPtr rhdPtr = RHDPTRI(Crtc);
  311.     enum atomCrtc AtomCrtc = atomCrtc1;
  312.     struct atomCrtcBlank Config;
  313.     union AtomBiosArg data;
  314.  
  315.     RHDFUNC(Crtc);
  316.  
  317.     switch (Crtc->Id) {
  318.         case RHD_CRTC_1:
  319.             AtomCrtc = atomCrtc1;
  320.             break;
  321.         case RHD_CRTC_2:
  322.             AtomCrtc = atomCrtc2;
  323.             break;
  324.     }
  325.     if (Blank)
  326.         Config.Action = atomBlankOn;
  327.     else
  328.         Config.Action = atomBlankOff;
  329.  
  330.     Config.r = Config.g = Config.b = 0;
  331.  
  332.     data.Address = &((Crtc->ModePriv)->RegList);
  333.     RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  334.  
  335.     rhdAtomBlankCRTC(rhdPtr->atomBIOS, AtomCrtc , &Config);
  336.  
  337.     data.Address = NULL;
  338.     RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
  339. }
  340.  
  341. /*
  342.  *
  343.  */
  344. static void
  345. rhdAtomModeSave(struct rhdCrtc *Crtc)
  346. {
  347.     struct rhdCrtcModePrivate* ModePriv;
  348.     CARD32 RegOff = 0;
  349.  
  350.     if (!Crtc->ModePriv) {
  351.         if(!(ModePriv = (struct rhdCrtcModePrivate*)xnfcalloc(1, sizeof(struct rhdCrtcModePrivate))))
  352.             return;
  353.         Crtc->ModePriv = ModePriv;
  354.     } else
  355.         ModePriv = Crtc->ModePriv;
  356.  
  357.     if (Crtc->Id == RHD_CRTC_1)
  358.         RegOff = D1_REG_OFFSET;
  359.     else
  360.         RegOff = D2_REG_OFFSET;
  361.  
  362.     ModePriv->StoreModeDataFormat  = RHDRegRead(Crtc, RegOff + D1MODE_DATA_FORMAT);
  363.     ModePriv->RegList = NULL;
  364. }
  365.  
  366. /*
  367.  *
  368.  */
  369. static void
  370. rhdAtomModeRestore(struct rhdCrtc *Crtc)
  371. {
  372.     struct rhdCrtcModePrivate* ModePriv;
  373.     CARD32 RegOff = 0;
  374.  
  375.     if (Crtc->Id == RHD_CRTC_1)
  376.         RegOff = D1_REG_OFFSET;
  377.     else
  378.         RegOff = D2_REG_OFFSET;
  379.  
  380.     ModePriv = Crtc->ModePriv;
  381.  
  382.     rhdAtomCrtcRestore(Crtc, &ModePriv->RegList);
  383.  
  384.    RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, ModePriv->StoreModeDataFormat);
  385. }
  386.  
  387. /*
  388.  *
  389.  */
  390. static void
  391. rhdAtomModeDestroy(struct rhdCrtc *Crtc)
  392. {
  393.     RHDFUNC(Crtc);
  394.  
  395.     if (Crtc->ModePriv) {
  396.         xfree(Crtc->ModePriv->RegList);
  397.         xfree(Crtc->ModePriv);
  398.         Crtc->ModePriv = NULL;
  399.     }
  400. }
  401.  
  402. /*
  403.  *
  404.  */
  405. void
  406. RHDAtomCrtcsInit(RHDPtr rhdPtr)
  407. {
  408.     struct rhdCrtc *Crtc;
  409.     int i;
  410.  
  411.     RHDFUNC(rhdPtr);
  412.  
  413.     if (rhdPtr->Crtc[0] == NULL || rhdPtr->Crtc[1] == NULL) {
  414.         xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: CRTCs not initialized\n",__func__);
  415.         return;
  416.     }
  417.  
  418.     for (i = 0; i < 2; i++) {
  419.  
  420.         Crtc = rhdPtr->Crtc[i];
  421.  
  422.         if (i == 0) {
  423.             Crtc->Name = "ATOM CRTC 1";
  424.             Crtc->Id = RHD_CRTC_1;
  425.         } else {
  426.             Crtc->Name = "ATOM CRTC 2";
  427.             Crtc->Id = RHD_CRTC_2;
  428.         }
  429.  
  430.         /* EnableGraphSurfaces is only a BIOS internal table. So use the hardcoded path.
  431.         Crtc->FBValid = atomFBValid;
  432.         Crtc->FBSet = atomFBSet;
  433.         Crtc->FBSave = atomSave;
  434.         Crtc->FBRestore = atomRestore;
  435.         */
  436.  
  437.         /* There is no separate function to set up the LUT thru AtomBIOS */
  438.  
  439.         /* Crtc->ScaleValid: From rhd_crtc.c */
  440.         Crtc->ScaleSet = rhdAtomScaleSet;
  441.         Crtc->ScaleSave = rhdAtomScaleSave;
  442.         Crtc->ScaleRestore = rhdAtomCrtcScaleRestore;
  443.         Crtc->ScaleDestroy = rhdAtomCrtcScaleDestroy;
  444.  
  445.         /* No such AtomBIOS table */
  446.         /* Crtc->FrameSet = atomViewPortStart; */
  447.  
  448.         /* Crtc->ModeValid: From rhd_crtc.c */
  449.         Crtc->ModeSet = rhdAtomModeSet;
  450.         Crtc->ModeSave = rhdAtomModeSave;
  451.         Crtc->ModeRestore = rhdAtomModeRestore;
  452.         Crtc->ModeDestroy = rhdAtomModeDestroy;
  453.  
  454.         Crtc->Power = rhdAtomCrtcPower;
  455.         Crtc->Blank = rhdAtomCrtcBlank;
  456.     }
  457. }
  458.  
  459. #endif /* ATOM_BIOS && ATOM_BIOS_PARSER */
  460.