[Intel-gfx] [PATCH] Enable all formats SDVO-TV support

Zhenyu Wang zhenyuw at linux.intel.com
Mon Jun 29 03:46:46 CEST 2009


On 2009.06.26 16:43:09 +0800, ling.ma at intel.com wrote:
> Currently SDVO TV only support NTSC-M format. In this patch
> we introduce all formats available and create seting-format
> property at init time. When user dynamically chose preferred
> format by xrandr command, it will refine all modelines
> provided by SDVO device based on the chosed format, at last 
> instruct SDVO device to execute.

Last time I tried this, not all formats work in testing, so
any update now?

> 
> Signed-off-by: Ma Ling <ling.ma at intel.com>
> ---
> Due to some dependency, KMS vesrion need more polishing and
> will send out next week.
> 
>  src/i830_sdvo.c      |  215 ++++++++++++++++++++++++++++++++++++++++++++------
>  src/i830_sdvo_regs.h |    1 +
>  2 files changed, 190 insertions(+), 26 deletions(-)
> 
> diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
> index acfe599..ceca3b2 100644
> --- a/src/i830_sdvo.c
> +++ b/src/i830_sdvo.c
> @@ -51,6 +51,31 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>  #include "i830_sdvo_regs.h"
>  #include "X11/Xatom.h"
>  
> +static char *tv_format_names[] = {
> +        "NTSC_M"   , "NTSC_J"  , "NTSC_443",
> +        "PAL_B"    , "PAL_D"   , "PAL_G"   ,
> +        "PAL_H"    , "PAL_I"   , "PAL_M"   ,
> +        "PAL_N"    , "PAL_NC"  , "PAL_60"  ,
> +        "SECAM_B"  , "SECAM_D" , "SECAM_G" ,
> +        "SECAM_K"  , "SECAM_K1", "SECAM_L" ,
> +        "SECAM_60" ,
> +        "240m_1080i_59", "240m_1080i_60",
> +        "260m_1080i_59", "260m_1080i_60",
> +        "274m_1080i_50", "274m_1080i_59",
> +        "274m_1080i_60", "274m_1080p_23",
> +        "274m_1080p_24", "274m_1080p_25",
> +        "274m_1080p_29", "274m_1080p_30",
> +        "274m_1080p_50", "274m_1080p_59",
> +        "274m_1080p_60", "295m_1080i_50",
> +        "295m_1080p_50", "296m_720p_59" ,
> +        "296m_720p_60" , "296m_720p_50" ,
> +        "293m_480p_59" , "170m_480i_59" ,
> +        "TURB_576i_50" , "TURB_576p_50" ,
> +        "EIA_480i_60"  , "EIA_480p_60"  ,
> +};
> +
> +#define TV_FORMAT_NUM  (sizeof(tv_format_names) / sizeof(*tv_format_names))
> +
>  /** SDVO driver private structure. */
>  struct i830_sdvo_priv {
>      /** SDVO device on SDVO I2C bus. */
> @@ -109,6 +134,9 @@ struct i830_sdvo_priv {
>       * convenience.
>       */
>      struct i830_sdvo_tv_format tv_format;
> +    char *tv_format_name;
> +    char *tv_format_supported[TV_FORMAT_NUM];
> +    int   format_supported_num;
>  
>      /** supported encoding mode, used to determine whether HDMI is supported */
>      struct i830_sdvo_encode encode;
> @@ -131,7 +159,10 @@ struct i830_sdvo_priv {
>      /** @} */
>  };
>  
> +#define TV_FORMAT_NAME	"TV_FORMAT"
>  static Atom broadcast_atom;
> +static Atom tv_format_atom;
> +static Atom tv_format_name_atoms[TV_FORMAT_NUM];
>  
>  static void
>  i830_sdvo_dump(ScrnInfoPtr pScrn);
> @@ -980,29 +1011,50 @@ static void i830_sdvo_set_avi_infoframe(xf86OutputPtr output,
>  			SDVO_HBUF_TX_VSYNC);
>  }
>  
> +/**
> + * This function checks the current TV format.
> + */
> +static void
> +i830_sdvo_check_tv_format(xf86OutputPtr output, char *tv_format_name,
> +                          struct i830_sdvo_sdtv_resolution_request *req)
> +{
> +    uint64_t format_map = 0;
> +    uint32_t i, size;
> +
> +    for (i = 0; i < TV_FORMAT_NUM; i++)
> +        if (strcmp(tv_format_name, tv_format_names[i]) == 0)
> +            break;
> +
> +    if (sizeof(*req) > sizeof(format_map))
> +        size = sizeof(format_map);
> +    else
> +        size = sizeof(*req);
> +
> +    memcpy(&format_map, req, size);
> +    format_map = 1 << i;
> +    memcpy(req, &format_map, size);
> +}
> +
>  static void
>  i830_sdvo_set_tv_format(xf86OutputPtr output)
>  {
>      ScrnInfoPtr pScrn = output->scrn;
>      I830OutputPrivatePtr intel_output = output->driver_private;
>      struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
> -    struct i830_sdvo_tv_format *format, unset;
> +    struct i830_sdvo_tv_format format;
>      uint8_t status;
>  
> -    format = &dev_priv->tv_format;
> -    memset(&unset, 0, sizeof(unset));
> -    if (memcmp(format, &unset, sizeof(*format))) {
> -	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
> -		   "%s: Choosing default TV format of NTSC-M\n",
> -		   SDVO_NAME(dev_priv));
> -	format->ntsc_m = 1;
> -	i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
> -		sizeof(*format));
> -	status = i830_sdvo_read_response(output, NULL, 0);
> -	if (status != SDVO_CMD_STATUS_SUCCESS)
> -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
> -		    "%s: Fail to set TV format\n", SDVO_NAME(dev_priv));
> -    }
> +    memset(&format, 0, sizeof(struct i830_sdvo_tv_format));
> +    i830_sdvo_check_tv_format(output, dev_priv->tv_format_name,
> +                              (struct i830_sdvo_sdtv_resolution_request *)
> +                              &format);
> +
> +    i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format,
> +                        sizeof(format));
> +    status = i830_sdvo_read_response(output, NULL, 0);
> +    if (status != SDVO_CMD_STATUS_SUCCESS)
> +        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
> +                   "%s: Fail to set TV format\n", SDVO_NAME(dev_priv));
>  }
>  
>  static Bool
> @@ -1610,6 +1662,15 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
>  	if (i830_sdvo_check_hdmi_encode (output))
>  	    name_prefix = "HDMI";
>      }
> +    else if (flag & SDVO_OUTPUT_YPRPB0)
> +    {
> +	dev_priv->controlled_output = SDVO_OUTPUT_YPRPB0;
> +	output->subpixel_order = SubPixelHorizontalRGB; /* XXX */
> +	name_prefix="TV";
> +	dev_priv->is_tv = TRUE;
> +	intel_output->needs_tv_clock = TRUE;
> +    }
> +
>      else if (flag & SDVO_OUTPUT_SVID0)
>      {
>  	dev_priv->controlled_output = SDVO_OUTPUT_SVID0;
> @@ -1861,23 +1922,36 @@ i830_sdvo_get_tv_mode(DisplayModePtr *head, int width, int height,
>  }
>  
>  /**
> - * This function checks the current TV format, and chooses a default if
> - * it hasn't been set.
> + * This function get all supported TV formats
>   */
>  static void
> -i830_sdvo_check_tv_format(xf86OutputPtr output)
> +i830_sdvo_get_tv_formats(xf86OutputPtr output)
>  {
>      I830OutputPrivatePtr intel_output = output->driver_private;
>      struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
> +    uint64_t format_map;
>      struct i830_sdvo_tv_format format;
> +    uint32_t i;
>      uint8_t status;
>  
> -    i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
> +    memset(&dev_priv->tv_format, 0, sizeof(struct i830_sdvo_tv_format));
> +
> +    i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMATS_SUPPORT, NULL, 0);
>      status = i830_sdvo_read_response(output, &format, sizeof(format));
>      if (status != SDVO_CMD_STATUS_SUCCESS)
> -	return;
> +        return;
>  
>      memcpy(&dev_priv->tv_format, &format, sizeof(format));
> +    memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ?
> +           sizeof(format_map) : sizeof(format));
> +    dev_priv->format_supported_num = 0;
> +    for (i = 0 ; i < TV_FORMAT_NUM; i++)
> +        if (format_map & (1 << i)) {
> +            dev_priv->tv_format_supported
> +            [dev_priv->format_supported_num++] = tv_format_names[i];
> +        }
> +
> +    dev_priv->tv_format_name = dev_priv->tv_format_supported[0];
>  }
>  
>  static DisplayModePtr
> @@ -1891,14 +1965,14 @@ i830_sdvo_get_tv_modes(xf86OutputPtr output)
>      uint8_t status;
>      float refresh = 60; /* XXX */
>  
> -    i830_sdvo_check_tv_format(output);
> +    memset(&tv_res, 0, sizeof(struct i830_sdvo_sdtv_resolution_request));
> +    i830_sdvo_check_tv_format(output, dev_priv->tv_format_name,
> +                              &tv_res);
>  
>      /* Read the list of supported input resolutions for the selected TV format.
>       */
> -    memset(&tv_res, 0, sizeof(tv_res));
> -    memcpy(&tv_res, &dev_priv->tv_format, sizeof(tv_res));
>      i830_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
> -	    &tv_res, sizeof(tv_res));
> +                        &tv_res, sizeof(tv_res));
>      status = i830_sdvo_read_response(output, res, sizeof(*res));
>      if (status != SDVO_CMD_STATUS_SUCCESS)
>  	return NULL;
> @@ -1976,6 +2050,7 @@ i830_sdvo_get_crtc(xf86OutputPtr output)
>  }
>  #endif
>  
> +
>  static void
>  i830_sdvo_create_resources(xf86OutputPtr output)
>  {
> @@ -1984,8 +2059,39 @@ i830_sdvo_create_resources(xf86OutputPtr output)
>      I830OutputPrivatePtr        intel_output = output->driver_private;
>      struct i830_sdvo_priv       *dev_priv = intel_output->dev_priv;
>      INT32			broadcast_range[2];
> -    int                         err;
> +    int                         err, i;
> +
> +    if (dev_priv->is_tv ) {
> +        /* Set up the tv_format property, which takes effect on mode set
> +         * and accepts strings that match exactly
> +         */
> +        tv_format_atom = MakeAtom(TV_FORMAT_NAME,
> +                                  sizeof(TV_FORMAT_NAME) - 1, TRUE);
> +
> +        for (i = 0; i < dev_priv->format_supported_num; i++)
> +            tv_format_name_atoms[i] = MakeAtom (
> +                                      dev_priv->tv_format_supported[i],
> +                                      strlen (
> +                                      dev_priv->tv_format_supported[i]),
> +                                      TRUE);
> +        err = RRConfigureOutputProperty(output->randr_output, tv_format_atom,
> +                                        TRUE, FALSE, FALSE,
> +                                        dev_priv->format_supported_num,
> +                                        (INT32 *) tv_format_name_atoms);
> +        if (err != 0)
> +            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> +                       "RRConfigureOutputProperty error, %d\n", err);
> +
> +        err = RRChangeOutputProperty (output->randr_output, tv_format_atom,
> +                                      XA_ATOM, 32, PropModeReplace, 1,
> +                                      &tv_format_name_atoms[0],
> +                                      FALSE, TRUE);
> +
> +	 if (err != 0)
> +             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> +                        "RRChangeOutputProperty error, %d\n", err);
>  
> +    }
>      /* only R G B are 8bit color mode */
>      if (pScrn->depth != 24 ||
>          /* only 965G and G4X platform */
> @@ -2021,6 +2127,18 @@ i830_sdvo_create_resources(xf86OutputPtr output)
>      }
>  }
>  
> +static int i830_sdvo_tv_mode_lookup(struct i830_sdvo_priv *dev_priv, char *val)
> +{
> +	int i;
> +	for (i = 0; i < dev_priv->format_supported_num; i++) {
> +	    if (strcmp(dev_priv->tv_format_supported[i], val)  == 0) {
> +		dev_priv->tv_format_name = dev_priv->tv_format_supported[i];
> +		return 0;
> +	    }
> +	}
> +	return -1;
> +}
> +
>  static Bool
>  i830_sdvo_set_property(xf86OutputPtr output, Atom property,
>  		       RRPropertyValuePtr value)
> @@ -2058,8 +2176,49 @@ i830_sdvo_set_property(xf86OutputPtr output, Atom property,
>          i830_sdvo_write_sdvox(output, temp);
>  
>          dev_priv->broadcast_rgb = val;
> +
> +	return TRUE;
>      }
> -    return TRUE;
> +
> +    if (property == tv_format_atom)
> +    {
> +        Atom			atom;
> +        const char		*name;
> +        DisplayModePtr		crtc_mode;
> +
> +        if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
> +            return FALSE;
> +
> +        memcpy (&atom, value->data, 4);
> +        name = NameForAtom (atom);
> +
> +        if (i830_sdvo_tv_mode_lookup(dev_priv, (char *)name))
> +            return FALSE;
> +
> +        if (pI830->starting)
> +            return TRUE;
> +
> +        /* TV format change will generate new modelines, try
> +	   to probe them and update outputs. */

I don't think this is correct, SDVO TV device can accept standard
vesa modes.

> +        xf86ProbeOutputModes(output->scrn, 0, 0);
> +        /* Mirror output modes to scrn mode list */
> +        xf86SetScrnInfoModes (output->scrn);
> +
> +        for (crtc_mode = output->probed_modes; crtc_mode;
> +             crtc_mode = crtc_mode->next) {
> +
> +        if (output->crtc->mode.HDisplay == crtc_mode->HDisplay &&
> +            output->crtc->mode.VDisplay == crtc_mode->VDisplay)
> +                break;
> +        }
> +        if (!crtc_mode)
> +            crtc_mode = output->probed_modes;
> +
> +        xf86CrtcSetMode(output->crtc, crtc_mode, output->crtc->rotation,
> +                        output->crtc->x, output->crtc->y);

> +        return TRUE;
> +    }
> +    return FALSE;
>  }
>  
>  static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
> @@ -2198,6 +2357,7 @@ void i830_find_sdvo_slave(ScrnInfoPtr pScrn, int output_device,
>      *slave_addr = temp_slave_addr;
>      return ;
>  }
> +
>  Bool
>  i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
>  {
> @@ -2327,6 +2487,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
>      /* Set the input timing to the screen. Assume always input 0. */
>      i830_sdvo_set_target_input(output, TRUE, FALSE);
>  
> +    if (dev_priv->is_tv)
> +        i830_sdvo_get_tv_formats(output);
> +
>      i830_sdvo_get_input_pixel_clock_range(output, &dev_priv->pixel_clock_min,
>  					  &dev_priv->pixel_clock_max);
>  
> diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h
> index ab38355..2d02926 100644
> --- a/src/i830_sdvo_regs.h
> +++ b/src/i830_sdvo_regs.h
> @@ -368,6 +368,7 @@ struct i830_sdvo_tv_format {
>      unsigned int pad:3;
>  } __attribute__((packed));
>  
> +#define SDVO_CMD_GET_TV_FORMATS_SUPPORT			0x27
>  #define SDVO_CMD_GET_TV_FORMAT				0x28
>  
>  /** This command should be run before SetOutputTimingsPart[12] */
> -- 
> 1.5.4.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090629/35f149f9/attachment.sig>


More information about the Intel-gfx mailing list