Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/omapdrm/dss/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  hdmi_wp.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * HDMI wrapper
 *
 * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/
 */


#define DSS_SUBSYS_NAME "HDMIWP"

#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>

#include "omapdss.h"
#include "dss.h"
#include "hdmi.h"

void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n"#r, hdmi_read_reg(wp->base, r))

 DUMPREG(HDMI_WP_REVISION);
 DUMPREG(HDMI_WP_SYSCONFIG);
 DUMPREG(HDMI_WP_IRQSTATUS_RAW);
 DUMPREG(HDMI_WP_IRQSTATUS);
 DUMPREG(HDMI_WP_IRQENABLE_SET);
 DUMPREG(HDMI_WP_IRQENABLE_CLR);
 DUMPREG(HDMI_WP_IRQWAKEEN);
 DUMPREG(HDMI_WP_PWR_CTRL);
 DUMPREG(HDMI_WP_DEBOUNCE);
 DUMPREG(HDMI_WP_VIDEO_CFG);
 DUMPREG(HDMI_WP_VIDEO_SIZE);
 DUMPREG(HDMI_WP_VIDEO_TIMING_H);
 DUMPREG(HDMI_WP_VIDEO_TIMING_V);
 DUMPREG(HDMI_WP_CLK);
 DUMPREG(HDMI_WP_AUDIO_CFG);
 DUMPREG(HDMI_WP_AUDIO_CFG2);
 DUMPREG(HDMI_WP_AUDIO_CTRL);
 DUMPREG(HDMI_WP_AUDIO_DATA);
}

u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp)
{
 return hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS);
}

void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus)
{
 hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, irqstatus);
 /* flush posted write */
 hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS);
}

void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask)
{
 hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_SET, mask);
}

void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask)
{
 hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_CLR, mask);
}

/* PHY_PWR_CMD */
int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val)
{
 /* Return if already the state */
 if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val)
  return 0;

 /* Command for power control of HDMI PHY */
 REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6);

 /* Status of the power control of HDMI PHY */
 if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val)
   != val) {
  DSSERR("Failed to set PHY power mode to %d\n", val);
  return -ETIMEDOUT;
 }

 return 0;
}

/* PLL_PWR_CMD */
int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val)
{
 /* Command for power control of HDMI PLL */
 REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2);

 /* wait till PHY_PWR_STATUS is set */
 if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val)
   != val) {
  DSSERR("Failed to set PLL_PWR_STATUS\n");
  return -ETIMEDOUT;
 }

 return 0;
}

int hdmi_wp_video_start(struct hdmi_wp_data *wp)
{
 REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, true, 31, 31);

 return 0;
}

void hdmi_wp_video_stop(struct hdmi_wp_data *wp)
{
 int i;

 hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_FRAME_DONE);

 REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31);

 for (i = 0; i < 50; ++i) {
  u32 v;

  msleep(20);

  v = hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS_RAW);
  if (v & HDMI_IRQ_VIDEO_FRAME_DONE)
   return;
 }

 DSSERR("no HDMI FRAMEDONE when disabling output\n");
}

void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
  const struct hdmi_video_format *video_fmt)
{
 u32 l = 0;

 REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode,
  10, 8);

 l |= FLD_VAL(video_fmt->y_res, 31, 16);
 l |= FLD_VAL(video_fmt->x_res, 15, 0);
 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l);
}

void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
        const struct videomode *vm)
{
 u32 r;
 bool vsync_inv, hsync_inv;
 DSSDBG("Enter hdmi_wp_video_config_interface\n");

 vsync_inv = !!(vm->flags & DISPLAY_FLAGS_VSYNC_LOW);
 hsync_inv = !!(vm->flags & DISPLAY_FLAGS_HSYNC_LOW);

 r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG);
 r = FLD_MOD(r, 1, 7, 7); /* VSYNC_POL to dispc active high */
 r = FLD_MOD(r, 1, 6, 6); /* HSYNC_POL to dispc active high */
 r = FLD_MOD(r, vsync_inv, 5, 5); /* CORE_VSYNC_INV */
 r = FLD_MOD(r, hsync_inv, 4, 4); /* CORE_HSYNC_INV */
 r = FLD_MOD(r, !!(vm->flags & DISPLAY_FLAGS_INTERLACED), 3, 3);
 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r);
}

void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
     const struct videomode *vm)
{
 u32 timing_h = 0;
 u32 timing_v = 0;
 unsigned int hsync_len_offset = 1;

 DSSDBG("Enter hdmi_wp_video_config_timing\n");

 /*
 * On OMAP4 and OMAP5 ES1 the HSW field is programmed as is. On OMAP5
 * ES2+ (including DRA7/AM5 SoCs) HSW field is programmed to hsync_len-1.
 * However, we don't support OMAP5 ES1 at all, so we can just check for
 * OMAP4 here.
 */

 if (wp->version == 4)
  hsync_len_offset = 0;

 timing_h |= FLD_VAL(vm->hback_porch, 31, 20);
 timing_h |= FLD_VAL(vm->hfront_porch, 19, 8);
 timing_h |= FLD_VAL(vm->hsync_len - hsync_len_offset, 7, 0);
 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_H, timing_h);

 timing_v |= FLD_VAL(vm->vback_porch, 31, 20);
 timing_v |= FLD_VAL(vm->vfront_porch, 19, 8);
 timing_v |= FLD_VAL(vm->vsync_len, 7, 0);
 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_V, timing_v);
}

void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
  struct videomode *vm, const struct hdmi_config *param)
{
 DSSDBG("Enter hdmi_wp_video_init_format\n");

 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
 video_fmt->y_res = param->vm.vactive;
 video_fmt->x_res = param->vm.hactive;

 vm->hback_porch = param->vm.hback_porch;
 vm->hfront_porch = param->vm.hfront_porch;
 vm->hsync_len = param->vm.hsync_len;
 vm->vback_porch = param->vm.vback_porch;
 vm->vfront_porch = param->vm.vfront_porch;
 vm->vsync_len = param->vm.vsync_len;

 vm->flags = param->vm.flags;

 if (param->vm.flags & DISPLAY_FLAGS_INTERLACED) {
  video_fmt->y_res /= 2;
  vm->vback_porch /= 2;
  vm->vfront_porch /= 2;
  vm->vsync_len /= 2;
 }

 if (param->vm.flags & DISPLAY_FLAGS_DOUBLECLK) {
  video_fmt->x_res *= 2;
  vm->hfront_porch *= 2;
  vm->hsync_len *= 2;
  vm->hback_porch *= 2;
 }
}

void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
  struct hdmi_audio_format *aud_fmt)
{
 u32 r;

 DSSDBG("Enter hdmi_wp_audio_config_format\n");

 r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG);
 if (wp->version == 4) {
  r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
  r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
 }
 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
 r = FLD_MOD(r, aud_fmt->type, 4, 4);
 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
 r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
 r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
 r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
 hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG, r);
}

void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
  struct hdmi_audio_dma *aud_dma)
{
 u32 r;

 DSSDBG("Enter hdmi_wp_audio_config_dma\n");

 r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG2);
 r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
 r = FLD_MOD(r, aud_dma->block_size, 7, 0);
 hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG2, r);

 r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CTRL);
 r = FLD_MOD(r, aud_dma->mode, 9, 9);
 r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
 hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CTRL, r);
}

int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable)
{
 REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 31, 31);

 return 0;
}

int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
{
 REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 30, 30);

 return 0;
}

int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
   unsigned int version)
{
 struct resource *res;

 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp");
 wp->base = devm_ioremap_resource(&pdev->dev, res);
 if (IS_ERR(wp->base))
  return PTR_ERR(wp->base);

 wp->phys_base = res->start;
 wp->version = version;

 return 0;
}

phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp)
{
 return wp->phys_base + HDMI_WP_AUDIO_DATA;
}

Messung V0.5
C=97 H=91 G=93

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.