コード例 #1
0
static void hdmi_phy_8960_reset(struct hdmi_phy *phy)
{
	struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
	struct hdmi *hdmi = phy_8960->hdmi;
	unsigned int val;

	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);

	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET);
	} else {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET);
	}

	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
	} else {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET_PLL);
	}

	msleep(100);

	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET);
	} else {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET);
	}

	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET_PLL);
	} else {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
	}
}
コード例 #2
0
ファイル: hdmi_connector.c プロジェクト: ezequielgarcia/linux
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
{
	uint32_t hpd_int_status;

	pm_runtime_get_sync(&hdmi->pdev->dev);
	enable_hpd_clocks(hdmi, true);

	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);

	enable_hpd_clocks(hdmi, false);
	pm_runtime_put_autosuspend(&hdmi->pdev->dev);

	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
			connector_status_connected : connector_status_disconnected;
}
コード例 #3
0
static void tpi_clear_pending_event(struct hdmi_info *hdmi)
{
	int retry = 100;

	if (hdmi->sleeping == SLEEP) return;
	while (retry--) {
		hdmi_write_byte(hdmi->client, 0x3c, 1);
		hdmi_write_byte(hdmi->client, 0x3d, 1);
		if (hdmi_read(hdmi->client, 0x3d) & 0x01)
			msleep(1);
		else
			break;
	}
	if (retry < 19) HDMI_DBG("%s: retry=%d\n", __func__, 19 - retry);
}
コード例 #4
0
ファイル: sh_mobile_hdmi.c プロジェクト: 3sOx/asuswrt-merlin
static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
{
	struct fb_var_screeninfo *var = &hdmi->var;
	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
	struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg;
	unsigned long height = var->height, width = var->width;
	int i;
	u8 edid[128];

	/* Read EDID */
	pr_debug("Read back EDID code:");
	for (i = 0; i < 128; i++) {
		edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
#ifdef DEBUG
		if ((i % 16) == 0) {
			printk(KERN_CONT "\n");
			printk(KERN_DEBUG "%02X | %02X", i, edid[i]);
		} else {
			printk(KERN_CONT " %02X", edid[i]);
		}
#endif
	}
#ifdef DEBUG
	printk(KERN_CONT "\n");
#endif
	fb_parse_edid(edid, var);
	pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n",
		 var->left_margin, var->xres, var->right_margin, var->hsync_len,
		 var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
		 PICOS2KHZ(var->pixclock));

	var->width		= width;
	var->xres		= lcd_cfg->xres;
	var->xres_virtual	= lcd_cfg->xres;
	var->left_margin	= lcd_cfg->left_margin;
	var->right_margin	= lcd_cfg->right_margin;
	var->hsync_len		= lcd_cfg->hsync_len;
	var->height		= height;
	var->yres		= lcd_cfg->yres;
	var->yres_virtual	= lcd_cfg->yres * 2;
	var->upper_margin	= lcd_cfg->upper_margin;
	var->lower_margin	= lcd_cfg->lower_margin;
	var->vsync_len		= lcd_cfg->vsync_len;
	var->sync		= lcd_cfg->sync;
	var->pixclock		= lcd_cfg->pixclock;

	hdmi_external_video_param(hdmi);
}
コード例 #5
0
ファイル: hdmi_connector.c プロジェクト: ezequielgarcia/linux
static void msm_hdmi_phy_reset(struct hdmi *hdmi)
{
	unsigned int val;

	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);

	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET);
	} else {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET);
	}

	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
	} else {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET_PLL);
	}

	msleep(100);

	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET);
	} else {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET);
	}

	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
		/* pull high */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val | HDMI_PHY_CTRL_SW_RESET_PLL);
	} else {
		/* pull low */
		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
	}
}
コード例 #6
0
irqreturn_t hdmi_irq_handler(int irq, void *dev_data)
{
	struct hdmi_device *hdev = dev_data;
	u32 intc_flag;

	(void)irq;
	intc_flag = hdmi_read(hdev, HDMI_INTC_FLAG);
	/* clearing flags for HPD plug/unplug */
	if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
		printk(KERN_INFO "unplugged\n");
		hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
			HDMI_INTC_FLAG_HPD_UNPLUG);
	}
	if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
		printk(KERN_INFO "plugged\n");
		hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
			HDMI_INTC_FLAG_HPD_PLUG);
	}

	return IRQ_HANDLED;
}
コード例 #7
0
unsigned int bsp_hdmi_get_hpd()
{
	unsigned int ret = 0;

	hdmi_write(0x10010,0x45);
	hdmi_write(0x10011,0x45);
	hdmi_write(0x10012,0x52);
	hdmi_write(0x10013,0x54);

	if( (hdmi_read(0x0243) & 0x2) == 0x2)
		ret = 1;
	else
		ret = 0;

	hdmi_write(0x10010,0x52);
	hdmi_write(0x10011,0x54);
	hdmi_write(0x10012,0x41);
	hdmi_write(0x10013,0x57);

	return ret;
}
コード例 #8
0
/**
 * Stop hdmi phy macro cell tx3g4c28
 *
 * @hdmi: pointer on the hdmi internal structure
 */
static void sti_hdmi_tx3g4c28phy_stop(struct sti_hdmi *hdmi)
{
	int val = 0;

	DRM_DEBUG_DRIVER("\n");

	hdmi->event_received = false;

	val = HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION;
	val |= HDMI_SRZ_CFG_EN_BIASRES_DETECTION;

	hdmi_write(hdmi, val, HDMI_SRZ_CFG);
	hdmi_write(hdmi, 0, HDMI_SRZ_PLL_CFG);

	/* wait PLL interrupt */
	wait_event_interruptible_timeout(hdmi->wait_event,
					 hdmi->event_received == true,
					 msecs_to_jiffies
					 (HDMI_TIMEOUT_PLL_LOCK));

	if (hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK)
		DRM_ERROR("hdmi phy pll not well disabled\n");
}
コード例 #9
0
ファイル: tda19988.c プロジェクト: Hooman3/minix
static int
hdmi_clear(uint8_t page, uint8_t reg, uint8_t mask)
{

	int r;
	uint8_t val;

	val = 0x00;

	r = hdmi_read(page, reg, &val);
	if (r != OK) {
		return r;
	}

	val &= ~mask;

	r = hdmi_write(page, reg, val);
	if (r != OK) {
		return r;
	}

	return OK;
}
コード例 #10
0
ファイル: hdmi_connector.c プロジェクト: 383530895/linux
static int hdmi_connector_get_modes(struct drm_connector *connector)
{
	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
	struct hdmi *hdmi = hdmi_connector->hdmi;
	struct edid *edid;
	uint32_t hdmi_ctrl;
	int ret = 0;

	hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);

	edid = drm_get_edid(connector, hdmi->i2c);

	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);

	drm_mode_connector_update_edid_property(connector, edid);

	if (edid) {
		ret = drm_add_edid_modes(connector, edid);
		kfree(edid);
	}

	return ret;
}
コード例 #11
0
/**
 * Start hdmi phy macro cell tx3g4c28
 *
 * @hdmi: pointer on the hdmi internal structure
 *
 * Return false if an error occur
 */
static bool sti_hdmi_tx3g4c28phy_start(struct sti_hdmi *hdmi)
{
	u32 ckpxpll = hdmi->mode.clock * 1000;
	u32 val, tmdsck, idf, odf, pllctrl = 0;
	bool foundplldivides = false;
	int i;

	DRM_DEBUG_DRIVER("ckpxpll = %dHz\n", ckpxpll);

	for (i = 0; i < NB_PLL_MODE; i++) {
		if (ckpxpll >= plldividers[i].min &&
		    ckpxpll < plldividers[i].max) {
			idf = plldividers[i].idf;
			odf = plldividers[i].odf;
			foundplldivides = true;
			break;
		}
	}

	if (!foundplldivides) {
		DRM_ERROR("input TMDS clock speed (%d) not supported\n",
			  ckpxpll);
		goto err;
	}

	/* Assuming no pixel repetition and 24bits color */
	tmdsck = ckpxpll;
	pllctrl |= 40 << PLL_CFG_NDIV_SHIFT;

	if (tmdsck > 340000000) {
		DRM_ERROR("output TMDS clock (%d) out of range\n", tmdsck);
		goto err;
	}

	pllctrl |= idf << PLL_CFG_IDF_SHIFT;
	pllctrl |= odf << PLL_CFG_ODF_SHIFT;

	/*
	 * Configure and power up the PHY PLL
	 */
	hdmi->event_received = false;
	DRM_DEBUG_DRIVER("pllctrl = 0x%x\n", pllctrl);
	hdmi_write(hdmi, (pllctrl | PLL_CFG_EN), HDMI_SRZ_PLL_CFG);

	/* wait PLL interrupt */
	wait_event_interruptible_timeout(hdmi->wait_event,
					 hdmi->event_received == true,
					 msecs_to_jiffies
					 (HDMI_TIMEOUT_PLL_LOCK));

	if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK) == 0) {
		DRM_ERROR("hdmi phy pll not locked\n");
		goto err;
	}

	DRM_DEBUG_DRIVER("got PHY PLL Lock\n");

	val = (HDMI_SRZ_CFG_EN |
	       HDMI_SRZ_CFG_EXTERNAL_DATA |
	       HDMI_SRZ_CFG_EN_BIASRES_DETECTION |
	       HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION);

	if (tmdsck > 165000000)
		val |= HDMI_SRZ_CFG_EN_SRC_TERMINATION;

	/*
	 * To configure the source termination and pre-emphasis appropriately
	 * for different high speed TMDS clock frequencies a phy configuration
	 * table must be provided, tailored to the SoC and board combination.
	 */
	for (i = 0; i < NB_HDMI_PHY_CONFIG; i++) {
		if ((hdmiphy_config[i].min_tmds_freq <= tmdsck) &&
		    (hdmiphy_config[i].max_tmds_freq >= tmdsck)) {
			val |= (hdmiphy_config[i].config[0]
				& ~HDMI_SRZ_CFG_INTERNAL_MASK);
			hdmi_write(hdmi, val, HDMI_SRZ_CFG);

			val = hdmiphy_config[i].config[1];
			hdmi_write(hdmi, val, HDMI_SRZ_ICNTL);

			val = hdmiphy_config[i].config[2];
			hdmi_write(hdmi, val, HDMI_SRZ_CALCODE_EXT);

			DRM_DEBUG_DRIVER("serializer cfg 0x%x 0x%x 0x%x\n",
					 hdmiphy_config[i].config[0],
					 hdmiphy_config[i].config[1],
					 hdmiphy_config[i].config[2]);
			return true;
		}
	}

	/*
	 * Default, power up the serializer with no pre-emphasis or
	 * output swing correction
	 */
	hdmi_write(hdmi, val,  HDMI_SRZ_CFG);
	hdmi_write(hdmi, 0x0, HDMI_SRZ_ICNTL);
	hdmi_write(hdmi, 0x0, HDMI_SRZ_CALCODE_EXT);

	return true;

err:
	return false;
}
コード例 #12
0
ファイル: hdmi_connector.c プロジェクト: 383530895/linux
static int hpd_enable(struct hdmi_connector *hdmi_connector)
{
	struct hdmi *hdmi = hdmi_connector->hdmi;
	const struct hdmi_platform_config *config = hdmi->config;
	struct drm_device *dev = hdmi_connector->base.dev;
	struct hdmi_phy *phy = hdmi->phy;
	uint32_t hpd_ctrl;
	int i, ret;

	ret = gpio_config(hdmi, true);
	if (ret) {
		dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret);
		goto fail;
	}

	for (i = 0; i < config->hpd_clk_cnt; i++) {
		if (config->hpd_freq && config->hpd_freq[i]) {
			ret = clk_set_rate(hdmi->hpd_clks[i],
					config->hpd_freq[i]);
			if (ret)
				dev_warn(dev->dev, "failed to set clk %s (%d)\n",
						config->hpd_clk_names[i], ret);
		}

		ret = clk_prepare_enable(hdmi->hpd_clks[i]);
		if (ret) {
			dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n",
					config->hpd_clk_names[i], ret);
			goto fail;
		}
	}

	for (i = 0; i < config->hpd_reg_cnt; i++) {
		ret = regulator_enable(hdmi->hpd_regs[i]);
		if (ret) {
			dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n",
					config->hpd_reg_names[i], ret);
			goto fail;
		}
	}

	hdmi_set_mode(hdmi, false);
	phy->funcs->reset(phy);
	hdmi_set_mode(hdmi, true);

	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);

	/* enable HPD events: */
	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
			HDMI_HPD_INT_CTRL_INT_CONNECT |
			HDMI_HPD_INT_CTRL_INT_EN);

	/* set timeout to 4.1ms (max) for hardware debounce */
	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);

	/* Toggle HPD circuit to trigger HPD sense */
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);

	return 0;

fail:
	return ret;
}
コード例 #13
0
static int hdmi_streamon(struct hdmi_device *hdev)
{
	struct device *dev = hdev->dev;
	int ret;
	u32 val0, val1, val2;

	dev_dbg(dev, "%s\n", __func__);

	/* 3D test */
	hdmi_set_infoframe(hdev);

	/* set packets for audio */
	hdmi_set_packets(hdev);

	/* init audio */
#if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S)
	//printk("=============================> HDMI IIS\n");
	hdmi_reg_i2s_audio_init(hdev);
#elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF)
	hdmi_reg_spdif_audio_init(hdev);
#endif
	/* enbale HDMI audio */
	if (hdev->audio_enable)
	{
	    //printk("<+++++++++++++++++++++++++++++++++++++++++++ HDMI  ENABLE\n");
		hdmi_audio_enable(hdev, 1);
	    //printk("<+++++++++++++++++++++++++++++++++++++++++++ HDMI  ENABLE\n");
	}

	hdmi_set_dvi_mode(hdev);

	/* controls the pixel value limitation */
	hdmi_reg_set_limits(hdev);

	/* enable HDMI and timing generator */
	hdmi_enable(hdev, 1);
	hdmi_tg_enable(hdev, 1);

	hdmi_reg_set_int_hpd(hdev);

	hdev->streaming = HDMI_STREAMING;

//	if (edid_supports_hdmi(hdev)) {
#if 1 
		/* start HDCP if enabled */
		if (hdev->hdcp_info.hdcp_enable) {
			ret = hdcp_start(hdev);
			if (ret)
				return ret;
		}
#endif
//	}

	val0 = hdmi_read(hdev, HDMI_ACR_MCTS0);
	val1 = hdmi_read(hdev, HDMI_ACR_MCTS1);
	val2 = hdmi_read(hdev, HDMI_ACR_MCTS2);
	dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0);
	dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1);
	dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2);

	hdmi_dumpregs(hdev, "streamon");
	return 0;
}
コード例 #14
0
static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
{
	struct fb_var_screeninfo tmpvar;
	struct fb_var_screeninfo *var = &tmpvar;
	const struct fb_videomode *mode, *found = NULL;
	struct fb_info *info = hdmi->info;
	struct fb_modelist *modelist = NULL;
	unsigned int f_width = 0, f_height = 0, f_refresh = 0;
	unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
	bool exact_match = false;
	u8 edid[128];
	char *forced;
	int i;

	/* Read EDID */
	dev_dbg(hdmi->dev, "Read back EDID code:");
	for (i = 0; i < 128; i++) {
		edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
#ifdef DEBUG
		if ((i % 16) == 0) {
			printk(KERN_CONT "\n");
			printk(KERN_DEBUG "%02X | %02X", i, edid[i]);
		} else {
			printk(KERN_CONT " %02X", edid[i]);
		}
#endif
	}
#ifdef DEBUG
	printk(KERN_CONT "\n");
#endif

	fb_edid_to_monspecs(edid, &hdmi->monspec);

	fb_get_options("sh_mobile_lcdc", &forced);
	if (forced && *forced) {
		/* Only primitive parsing so far */
		i = sscanf(forced, "%ux%u@%u",
			   &f_width, &f_height, &f_refresh);
		if (i < 2) {
			f_width = 0;
			f_height = 0;
		}
		dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
			f_width, f_height, f_refresh);
	}

	/* Walk monitor modes to find the best or the exact match */
	for (i = 0, mode = hdmi->monspec.modedb;
	     f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match;
	     i++, mode++) {
		unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode);

		/* No interest in unmatching modes */
		if (f_width != mode->xres || f_height != mode->yres)
			continue;
		if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
			/*
			 * Exact match if either the refresh rate matches or it
			 * hasn't been specified and we've found a mode, for
			 * which we can configure the clock precisely
			 */
			exact_match = true;
		else if (found && found_rate_error <= rate_error)
			/*
			 * We otherwise search for the closest matching clock
			 * rate - either if no refresh rate has been specified
			 * or we cannot find an exactly matching one
			 */
			continue;

		/* Check if supported: sufficient fb memory, supported clock-rate */
		fb_videomode_to_var(var, mode);

		if (info && info->fbops->fb_check_var &&
		    info->fbops->fb_check_var(var, info)) {
			exact_match = false;
			continue;
		}

		found = mode;
		found_rate_error = rate_error;
	}

	/*
	 * TODO 1: if no ->info is present, postpone running the config until
	 * after ->info first gets registered.
	 * TODO 2: consider registering the HDMI platform device from the LCDC
	 * driver, and passing ->info with HDMI platform data.
	 */
	if (info && !found) {
		modelist = hdmi->info->modelist.next &&
			!list_empty(&hdmi->info->modelist) ?
			list_entry(hdmi->info->modelist.next,
				   struct fb_modelist, list) :
			NULL;

		if (modelist) {
			found = &modelist->mode;
			found_rate_error = sh_hdmi_rate_error(hdmi, found);
		}
	}
コード例 #15
0
int bsp_hdmi_video(struct video_para *video)
{
	unsigned id = get_vid(video->vic);
	glb_video.vic = video->vic;

	bsp_hdmi_init();
	
	hdmi_write(0x0840, 0x01);
	hdmi_write(0x4845, 0x00);
	hdmi_write(0x0040, ptbl[id].para[3] |	0x10);
	hdmi_write(0x10001, ( (ptbl[id].para[3] < 96) ? 0x03 : 0x00 ) );
	hdmi_write(0x8040, ptbl[id].para[4]);
	hdmi_write(0x4043, ptbl[id].para[5]);
	hdmi_write(0x8042, ptbl[id].para[6]);
	hdmi_write(0x0042, ptbl[id].para[7]);
	hdmi_write(0x4042, ptbl[id].para[8]);
	hdmi_write(0x4041, ptbl[id].para[9]);
	hdmi_write(0xC041, ptbl[id].para[10]);
	hdmi_write(0x0041, ptbl[id].para[11]);
	hdmi_write(0x8041, ptbl[id].para[12]);
	hdmi_write(0x4040, ptbl[id].para[13]);
	hdmi_write(0xC040, ptbl[id].para[14]);
	hdmi_write(0x0043, ptbl[id].para[15]);
	hdmi_write(0x8043, ptbl[id].para[16]);
	hdmi_write(0x0045, 0x0c);
	hdmi_write(0x8044, 0x20);
	hdmi_write(0x8045, 0x01);
	hdmi_write(0x0046, 0x0b);
	hdmi_write(0x0047, 0x16);
	hdmi_write(0x8046, 0x21);
	hdmi_write(0x3048, ptbl[id].para[2] ? 0x21 : 0x10);
	hdmi_write(0x0401, ptbl[id].para[2] ? 0x41 : 0x40);
	hdmi_write(0x8400, 0x07);
	hdmi_write(0x8401, 0x00);
	hdmi_write(0x0402, 0x47);
	hdmi_write(0x0800, video->is_yuv ? 0x09 : 0x01);
	hdmi_write(0x0801, 0x07);
	hdmi_write(0x8800, 0x00);
	hdmi_write(0x8801, 0x00);
	hdmi_write(0x0802, 0x00);
	hdmi_write(0x0803, 0x00);
	hdmi_write(0x8802, 0x00);
	hdmi_write(0x8803, 0x00);

	if(video->is_hdmi)
	{
		hdmi_write(0xB045, 0x08);
		hdmi_write(0x2045, 0x00);
		hdmi_write(0x2044, 0x0c);
		hdmi_write(0x6041, 0x03);
		hdmi_write(0xA044, ((ptbl[id].para[0]&0x100) == 0x100) ? 0x20 : ( ((ptbl[id].para[0]&0x80) == 0x80) ? 0x40 : 0x00) );
		hdmi_write(0xA045, ((ptbl[id].para[0]&0x100) == 0x100) ? (ptbl[id].para[0]&0x7f) : 0x00);
		hdmi_write(0x2046, 0x00);
		hdmi_write(0x3046, 0x01);
		hdmi_write(0x3047, 0x11);
		hdmi_write(0x4044, 0x00);
		hdmi_write(0x0052, 0x00);
		hdmi_write(0x8051, 0x11);
		hdmi_write(0x10010,0x45);
		hdmi_write(0x10011,0x45);
		hdmi_write(0x10012,0x52);
		hdmi_write(0x10013,0x54);
		hdmi_write(0x0040, hdmi_read(0x0040) | 0x08 );
		hdmi_write(0x10010,0x52);
		hdmi_write(0x10011,0x54);
		hdmi_write(0x10012,0x41);
		hdmi_write(0x10013,0x57);
		hdmi_write(0x4045, video->is_yuv ? 0x02 : 0x00);
		if(ptbl[id].para[16] == 0)
			hdmi_write(0xC044, (video->csc << 6) | 0x18);
		else if(ptbl[id].para[16] == 1)
			hdmi_write(0xC044, (video->csc << 6) | 0x28);
		else
			hdmi_write(0xC044, (video->csc << 6) | 0x08);

		hdmi_write(0xC045, 0x00);
		hdmi_write(0x4046, ptbl[id].para[0]&0x7f);
	}

	if(video->is_hcts)
	{
		hdmi_write(0x10010,0x45);
		hdmi_write(0x10011,0x45);
		hdmi_write(0x10012,0x52);
		hdmi_write(0x10013,0x54);
		hdmi_write(0x0040, hdmi_read(0x0040) | 0x80 );
		hdmi_write(0x10010,0x52);
		hdmi_write(0x10011,0x54);
		hdmi_write(0x10012,0x41);
		hdmi_write(0x10013,0x57);
	}

	hdmi_write(0x0082, 0x00);
	hdmi_write(0x0081, 0x00);

	if(hdmi_phy_set(video)!=0)
		return -1;

	hdmi_write(0x0840, 0x00);

	if(video->is_hcts)
	{

	}

	return 0;
}
コード例 #16
0
static int hdmi_streamon(struct hdmi_device *hdev)
{
    const struct hdmi_timings *conf = hdev->cur_conf;
    struct device *dev = hdev->dev;
    int ret;
    u32 val0, val1, val2;

    dev_dbg(dev, "%s\n", __func__);

    /* 3D test */
    hdmi_set_infoframe(hdev);

    /* set packets for audio */
    hdmi_set_packets(hdev);

    /* init audio */
#if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S)
    hdmi_reg_i2s_audio_init(hdev);
#elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF)
    hdmi_reg_spdif_audio_init(hdev);
#endif
    /* enbale HDMI audio */
    if (hdev->audio_enable)
        hdmi_audio_enable(hdev, 1);

    hdmi_set_dvi_mode(hdev);

    /* controls the pixel value limitation */
    hdmi_reg_set_limits(hdev);

    /* setting core registers */
    hdmi_timing_apply(hdev, conf);

    /* enable HDMI and timing generator */
    hdmi_enable(hdev, 1);
    hdmi_tg_enable(hdev, 1);

    hdev->streaming = HDMI_STREAMING;

    /* change the HPD interrupt: External -> Internal */
    disable_irq(hdev->ext_irq);
    cancel_delayed_work_sync(&hdev->hpd_work_ext);
    hdmi_reg_set_int_hpd(hdev);
    enable_irq(hdev->int_irq);
    dev_info(hdev->dev, "HDMI interrupt changed to internal\n");

    /* start HDCP if enabled */
    if (hdev->hdcp_info.hdcp_enable) {
        ret = hdcp_start(hdev);
        if (ret)
            return ret;
    }

    val0 = hdmi_read(hdev, HDMI_ACR_MCTS0);
    val1 = hdmi_read(hdev, HDMI_ACR_MCTS1);
    val2 = hdmi_read(hdev, HDMI_ACR_MCTS2);
    dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0);
    dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1);
    dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2);

    hdmi_dumpregs(hdev, "streamon");
    return 0;
}
コード例 #17
0
int tpi_set_bit(struct hdmi_info *hdmi, u8 reg, u8 pattern)
{
	return hdmi_write_byte(hdmi->client, reg,
		hdmi_read(hdmi->client, reg) | pattern);
}
コード例 #18
0
void tpi_clear_bit(struct hdmi_info *hdmi, u8 reg, u8 pattern)
{
	hdmi_write_byte(hdmi->client, reg,
		hdmi_read(hdmi->client, reg) & pattern);
}
コード例 #19
0
ファイル: hdmi_drv.c プロジェクト: advx9600/kernel-4.4-RuiEr
static int hdmi_streamon(struct hdmi_device *hdev)
{
	struct device *dev = hdev->dev;
	struct hdmi_resources *res = &hdev->res;
	int ret, tries;
	u32 val0, val1, val2;

	dev_dbg(dev, "%s\n", __func__);

	hdev->streaming = 1;
	ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
	if (ret)
		return ret;

	/* waiting for HDMIPHY's PLL to get to steady state */
	for (tries = 100; tries; --tries) {
		if (is_hdmiphy_ready(hdev))
			break;

		mdelay(1);
	}
	/* steady state not achieved */
	if (tries == 0) {
		dev_err(dev, "hdmiphy's pll could not reach steady state.\n");
		v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
		hdmi_dumpregs(hdev, "s_stream");
		return -EIO;
	}

	/* hdmiphy clock is used for HDMI in streaming mode */
	clk_disable(res->sclk_hdmi);
	clk_set_parent(res->sclk_hdmi, res->sclk_hdmiphy);
	clk_enable(res->sclk_hdmi);

	/* 3D test */
	hdmi_set_infoframe(hdev);

	/* set packets for audio */
	hdmi_set_packets(hdev);

	/* init audio */
#if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S)
	hdmi_reg_i2s_audio_init(hdev);
#elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF)
	hdmi_reg_spdif_audio_init(hdev);
#endif
	/* enbale HDMI audio */
	if (hdev->audio_enable)
		hdmi_audio_enable(hdev, 1);

	hdmi_set_dvi_mode(hdev);

	/* enable HDMI and timing generator */
	hdmi_enable(hdev, 1);
	hdmi_tg_enable(hdev, 1);

	mdelay(5);
	val0 = hdmi_read(hdev, HDMI_ACR_MCTS0);
	val1 = hdmi_read(hdev, HDMI_ACR_MCTS1);
	val2 = hdmi_read(hdev, HDMI_ACR_MCTS2);
	dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0);
	dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1);
	dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2);

	/* start HDCP if enabled */
	if (hdev->hdcp_info.hdcp_enable) {
		ret = hdcp_start(hdev);
		if (ret)
			return ret;
	}

	hdmi_dumpregs(hdev, "streamon");
	return 0;
}
コード例 #20
0
ファイル: sh_mobile_hdmi.c プロジェクト: 3sOx/asuswrt-merlin
static int __init sh_hdmi_probe(struct platform_device *pdev)
{
	struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	int irq = platform_get_irq(pdev, 0), ret;
	struct sh_hdmi *hdmi;
	long rate;

	if (!res || !pdata || irq < 0)
		return -ENODEV;

	hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
	if (!hdmi) {
		dev_err(&pdev->dev, "Cannot allocate device data\n");
		return -ENOMEM;
	}

	hdmi->dev = &pdev->dev;

	hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
	if (IS_ERR(hdmi->hdmi_clk)) {
		ret = PTR_ERR(hdmi->hdmi_clk);
		dev_err(&pdev->dev, "Unable to get clock: %d\n", ret);
		goto egetclk;
	}

	rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000;

	rate = clk_round_rate(hdmi->hdmi_clk, rate);
	if (rate < 0) {
		ret = rate;
		dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
		goto erate;
	}

	ret = clk_set_rate(hdmi->hdmi_clk, rate);
	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
		goto erate;
	}

	pr_debug("HDMI set frequency %lu\n", rate);

	ret = clk_enable(hdmi->hdmi_clk);
	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret);
		goto eclkenable;
	}

	dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);

	if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "HDMI register region already claimed\n");
		ret = -EBUSY;
		goto ereqreg;
	}

	hdmi->base = ioremap(res->start, resource_size(res));
	if (!hdmi->base) {
		dev_err(&pdev->dev, "HDMI register region already claimed\n");
		ret = -ENOMEM;
		goto emap;
	}

	platform_set_drvdata(pdev, hdmi);

	/* Product and revision IDs are 0 in sh-mobile version */
	dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
		 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));

	/* Set up LCDC callbacks */
	pdata->lcd_chan->board_cfg.board_data = hdmi;
	pdata->lcd_chan->board_cfg.display_on = hdmi_display_on;
	pdata->lcd_chan->board_cfg.display_off = hdmi_display_off;

	INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn);

	pm_runtime_enable(&pdev->dev);
	pm_runtime_resume(&pdev->dev);

	ret = request_irq(irq, sh_hdmi_hotplug, 0,
			  dev_name(&pdev->dev), hdmi);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to request irq: %d\n", ret);
		goto ereqirq;
	}

	return 0;

ereqirq:
	pm_runtime_disable(&pdev->dev);
	iounmap(hdmi->base);
emap:
	release_mem_region(res->start, resource_size(res));
ereqreg:
	clk_disable(hdmi->hdmi_clk);
eclkenable:
erate:
	clk_put(hdmi->hdmi_clk);
egetclk:
	kfree(hdmi);

	return ret;
}
コード例 #21
0
static int hdmi_pll_enable(struct clk_hw *hw)
{
	struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw);
	struct hdmi *hdmi = phy_8960->hdmi;
	int timeout_count, pll_lock_retry = 10;
	unsigned int val;

	DBG("");

	/* Assert PLL S/W reset */
	hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
	hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10);
	hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a);

	/* Wait for a short time before de-asserting
	 * to allow the hardware to complete its job.
	 * This much of delay should be fine for hardware
	 * to assert and de-assert.
	 */
	udelay(10);

	/* De-assert PLL S/W reset */
	hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);

	val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12);
	val |= HDMI_8960_PHY_REG12_SW_RESET;
	/* Assert PHY S/W reset */
	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
	val &= ~HDMI_8960_PHY_REG12_SW_RESET;
	/* Wait for a short time before de-asserting
	   to allow the hardware to complete its job.
	   This much of delay should be fine for hardware
	   to assert and de-assert. */
	udelay(10);
	/* De-assert PHY S/W reset */
	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2,  0x3f);

	val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12);
	val |= HDMI_8960_PHY_REG12_PWRDN_B;
	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
	/* Wait 10 us for enabling global power for PHY */
	mb();
	udelay(10);

	val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B);
	val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B;
	val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL;
	hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B, val);
	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x80);

	timeout_count = 1000;
	while (--pll_lock_retry > 0) {

		/* are we there yet? */
		val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_STATUS0);
		if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK)
			break;

		udelay(1);

		if (--timeout_count > 0)
			continue;

		/*
		 * PLL has still not locked.
		 * Do a software reset and try again
		 * Assert PLL S/W reset first
		 */
		hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
		udelay(10);
		hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);

		/*
		 * Wait for a short duration for the PLL calibration
		 * before checking if the PLL gets locked
		 */
		udelay(350);

		timeout_count = 1000;
	}

	return 0;
}
コード例 #22
0
ファイル: hdmi_connector.c プロジェクト: 383530895/linux
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
{
	uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
			connector_status_connected : connector_status_disconnected;
}
コード例 #23
0
ファイル: hdmi_connector.c プロジェクト: ezequielgarcia/linux
int msm_hdmi_hpd_enable(struct drm_connector *connector)
{
	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
	struct hdmi *hdmi = hdmi_connector->hdmi;
	const struct hdmi_platform_config *config = hdmi->config;
	struct device *dev = &hdmi->pdev->dev;
	uint32_t hpd_ctrl;
	int i, ret;
	unsigned long flags;

	for (i = 0; i < config->hpd_reg_cnt; i++) {
		ret = regulator_enable(hdmi->hpd_regs[i]);
		if (ret) {
			dev_err(dev, "failed to enable hpd regulator: %s (%d)\n",
					config->hpd_reg_names[i], ret);
			goto fail;
		}
	}

	ret = pinctrl_pm_select_default_state(dev);
	if (ret) {
		dev_err(dev, "pinctrl state chg failed: %d\n", ret);
		goto fail;
	}

	ret = gpio_config(hdmi, true);
	if (ret) {
		dev_err(dev, "failed to configure GPIOs: %d\n", ret);
		goto fail;
	}

	pm_runtime_get_sync(dev);
	enable_hpd_clocks(hdmi, true);

	msm_hdmi_set_mode(hdmi, false);
	msm_hdmi_phy_reset(hdmi);
	msm_hdmi_set_mode(hdmi, true);

	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);

	/* enable HPD events: */
	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
			HDMI_HPD_INT_CTRL_INT_CONNECT |
			HDMI_HPD_INT_CTRL_INT_EN);

	/* set timeout to 4.1ms (max) for hardware debounce */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);

	/* Toggle HPD circuit to trigger HPD sense */
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	return 0;

fail:
	return ret;
}
コード例 #24
0
ファイル: tda19988.c プロジェクト: Hooman3/minix
static int
read_edid(uint8_t * buf, size_t count)
{
	int r;
	int i, j;
	int tries;
	int edid_ready;
	uint8_t val;

	log_debug(&log, "Reading edid...\n");

	if (buf == NULL || count < EDID_LEN) {
		log_warn(&log, "Expected 128 byte data buffer\n");
		return -1;
	}

	r = hdmi_clear(HDMI_HDCP_OTP_PAGE, HDMI_HDCP_OTP_SOME_REG,
	    HDMI_HDCP_OTP_SOME_MASK);
	if (r != OK) {
		log_warn(&log, "Failed to clear bit in HDCP OTP reg\n");
		return -1;
	}

	/* Enable EDID Block Read Interrupt */
	r = hdmi_set(HDMI_CTRL_PAGE, HDMI_CTRL_INT_REG,
	    HDMI_CTRL_INT_EDID_MASK);
	if (r != OK) {
		log_warn(&log, "Failed to enable EDID Block Read interrupt\n");
		return -1;
	}

	/* enable global interrupts */
	r = hdmi_write(HDMI_CTRL_PAGE, HDMI_CTRL_INTR_CTRL_REG,
	    HDMI_CTRL_INTR_EN_GLO_MASK);
	if (r != OK) {
		log_warn(&log, "Failed to enable interrupts\n");
		return -1;
	}

	/* Set Device Address */
	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_DEV_ADDR_REG,
	    HDMI_EDID_DEV_ADDR);
	if (r != OK) {
		log_warn(&log, "Couldn't set device address\n");
		return -1;
	}

	/* Set Offset */
	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_OFFSET_REG, HDMI_EDID_OFFSET);
	if (r != OK) {
		log_warn(&log, "Couldn't set offset\n");
		return -1;
	}

	/* Set Segment Pointer Address */
	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_SEG_PTR_ADDR_REG,
	    HDMI_EDID_SEG_PTR_ADDR);
	if (r != OK) {
		log_warn(&log, "Couldn't set segment pointer address\n");
		return -1;
	}

	/* Set Segment Address */
	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_SEG_ADDR_REG,
	    HDMI_EDID_SEG_ADDR);
	if (r != OK) {
		log_warn(&log, "Couldn't set segment address\n");
		return -1;
	}

	/* 
	 * Toggle EDID Read Request Bit to request a read.
	 */

	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_REQ_REG,
	    HDMI_EDID_REQ_READ_MASK);
	if (r != OK) {
		log_warn(&log, "Couldn't set Read Request bit\n");
		return -1;
	}

	r = hdmi_write(HDMI_EDID_PAGE, HDMI_EDID_REQ_REG, 0x00);
	if (r != OK) {
		log_warn(&log, "Couldn't clear Read Request bit\n");
		return -1;
	}

	log_debug(&log, "Starting polling\n");

	/* poll interrupt status flag */
	edid_ready = 0;
	for (tries = 0; tries < 100; tries++) {

		r = hdmi_read(HDMI_CTRL_PAGE, HDMI_CTRL_INT_REG, &val);
		if (r != OK) {
			log_warn(&log, "Read failed while polling int flag\n");
			return -1;
		}

		if (val & HDMI_CTRL_INT_EDID_MASK) {
			log_debug(&log, "Mask Set\n");
			edid_ready = 1;
			break;
		}

		micro_delay(1000);
	}

	if (!edid_ready) {
		log_warn(&log, "Data Ready interrupt never fired.\n");
		return EBUSY;
	}

	log_debug(&log, "Ready to read\n");

	/* Finally, perform the read. */
	memset(buf, '\0', count);
	r = hdmi_read_block(HDMI_EDID_PAGE, HDMI_EDID_DATA_REG, buf, EDID_LEN);
	if (r != OK) {
		log_warn(&log, "Failed to read EDID data\n");
		return -1;
	}

	/* Disable EDID Block Read Interrupt */
	r = hdmi_clear(HDMI_CTRL_PAGE, HDMI_CTRL_INT_REG,
	    HDMI_CTRL_INT_EDID_MASK);
	if (r != OK) {
		log_warn(&log,
		    "Failed to disable EDID Block Read interrupt\n");
		return -1;
	}

	r = hdmi_set(HDMI_HDCP_OTP_PAGE, HDMI_HDCP_OTP_SOME_REG,
	    HDMI_HDCP_OTP_SOME_MASK);
	if (r != OK) {
		log_warn(&log, "Failed to set bit in HDCP/OTP reg\n");
		return -1;
	}

	log_debug(&log, "Done EDID Reading\n");

	return OK;
}
コード例 #25
0
int bsp_hdmi_ddc_read(char cmd,char pointer,char offset,int nbyte,char * pbuf)
{
	unsigned char off = offset;
	unsigned int to_cnt;
	int ret = 0;

	hdmi_write(0x10010,0x45);
	hdmi_write(0x10011,0x45);
	hdmi_write(0x10012,0x52);
	hdmi_write(0x10013,0x54);
	hdmi_write(0x4EE1, 0x00);

	to_cnt = 50;
	while((hdmi_read(0x4EE1)&0x01)!=0x01)
	{
		hdmi_udelay(10);
		to_cnt--;	//wait for 500us for timeout
		if(to_cnt == 0)
		{
			pr_warn("ddc rst timeout\n");
			break;
		}
	}

	hdmi_write(0x8EE3, 0x05);
	hdmi_write(0x0EE3, 0x08);
	hdmi_write(0x4EE2, 0xd8);
	hdmi_write(0xCEE2, 0xfe);

	to_cnt = 10;
	while(nbyte > 0)
	{
		to_cnt = 10;
		hdmi_write(0x0EE0, 0xa0 >> 1);
		hdmi_write(0x0EE1, off);
		hdmi_write(0x4EE0, 0x60 >> 1);
		hdmi_write(0xCEE0, pointer);
		hdmi_write(0x0EE2, 0x02);

		while(1)
	  {
			to_cnt--;	//wait for 10ms for timeout
			if(to_cnt == 0)
			{
				pr_warn("ddc read timeout, byte cnt = %d\n",nbyte);
				break;
			}
			if( (hdmi_read(0x0013) & 0x02) == 0x02)
			{
				hdmi_write(0x0013, hdmi_read(0x0013) & 0x02);
				* pbuf++ =  hdmi_read(0x8EE1);
				break;
			}
			else if( (hdmi_read(0x0013) & 0x01) == 0x01)
			{
				hdmi_write(0x0013, hdmi_read(0x0013) & 0x01);
				ret = -1;
				break;
			}
			hdmi_udelay(1000);
	  }
	  nbyte --;
	  off ++;
	}
	hdmi_write(0x10010,0x52);
	hdmi_write(0x10011,0x54);
	hdmi_write(0x10012,0x41);
	hdmi_write(0x10013,0x57);

	return ret;
}
コード例 #26
0
ファイル: sh_mobile_hdmi.c プロジェクト: 3sOx/asuswrt-merlin
static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
{
	struct sh_hdmi *hdmi = dev_id;
	u8 status1, status2, mask1, mask2;

	/* mode_b and PLLA and PLLB reset */
	hdmi_write(hdmi, 0x2C, HDMI_SYSTEM_CTRL);

	/* How long shall reset be held? */
	udelay(10);

	/* mode_b and PLLA and PLLB reset release */
	hdmi_write(hdmi, 0x20, HDMI_SYSTEM_CTRL);

	status1 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_1);
	status2 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_2);

	mask1 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_1);
	mask2 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_2);

	/* Correct would be to ack only set bits, but the datasheet requires 0xff */
	hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_1);
	hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);

	if (printk_ratelimit())
		pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
			 irq, status1, mask1, status2, mask2);

	if (!((status1 & mask1) | (status2 & mask2))) {
		return IRQ_NONE;
	} else if (status1 & 0xc0) {
		u8 msens;

		/* Datasheet specifies 10ms... */
		udelay(500);

		msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
		pr_debug("MSENS 0x%x\n", msens);
		/* Check, if hot plug & MSENS pin status are both high */
		if ((msens & 0xC0) == 0xC0) {
			/* Display plug in */
			hdmi->hp_state = HDMI_HOTPLUG_CONNECTED;

			/* Set EDID word address  */
			hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS);
			/* Set EDID segment pointer */
			hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
			/* Enable EDID interrupt */
			hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1);
		} else if (!(status1 & 0x80)) {
			/* Display unplug, beware multiple interrupts */
			if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED)
				schedule_delayed_work(&hdmi->edid_work, 0);

			hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
			/* display_off will switch back to mode_a */
		}
	} else if (status1 & 2) {
		/* EDID error interrupt: retry */
		/* Set EDID word address  */
		hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS);
		/* Set EDID segment pointer */
		hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
	} else if (status1 & 4) {
		/* Disable EDID interrupt */
		hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1);
		hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
		schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10));
	}

	return IRQ_HANDLED;
}
コード例 #27
0
                {
                        .addr = 0x30, .flags = 0, .len = 1, .buf = &pbuf[2],
                },
                {
                        .addr = 0x50, .flags = 0, .len = 1, .buf = &pbuf[3],
                },
                {       //Block-3
                        .addr = 0x50, .flags = I2C_M_RD, .len = 128, .buf = &hdmi->edid_buf[384],
                },
	};

	HDMI_DBG("%s\n", __func__);
#if 0
	DisableTMDS(hdmi);
#else
	val = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL);
	//hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, val|BIT_4|BIT_6);
	hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, val|BIT_4);
#endif

	if (!GetDDC_Access(hdmi, &SysCtrlReg)) {
		pr_err("%s: DDC bus request failed\n", __func__);
		return DDC_BUS_REQ_FAILURE;
	}

	// Block-0
	memset(hdmi->edid_buf, 0, 512);

	msg.addr = 0x50;
	msg.flags = 0;
	msg.len = 1;
コード例 #28
0
ファイル: hdmi_bsp_sun8iw7.c プロジェクト: Aorjoa/bootloader
int bsp_hdmi_video(struct video_para *video)
{
	unsigned int id = get_vid(video->vic);
	glb_video.vic = video->vic;

	switch(glb_video.vic)
	{
		case 2:
		case 4:
		case 6:
		case 17:
		case 19:
		case 21:
			video->csc = BT601;
			break;
		default:
			video->csc = BT709;
			break;
	}
	if(hdmi_phy_set(video)!=0)
		return -1;

	bsp_hdmi_inner_init();

	hdmi_write(0x0840, 0x01);
	hdmi_write(0x4845, 0x00);
	hdmi_write(0x0040, ptbl[id].para[3] |	0x10);
	hdmi_write(0x10001, ( (ptbl[id].para[3] < 96) ? 0x03 : 0x00 ) );
	hdmi_write(0x8040, ptbl[id].para[4]);
	hdmi_write(0x4043, ptbl[id].para[5]);
	hdmi_write(0x8042, ptbl[id].para[6]);
	hdmi_write(0x0042, ptbl[id].para[7]);
	hdmi_write(0x4042, ptbl[id].para[8]);
	hdmi_write(0x4041, ptbl[id].para[9]);
	hdmi_write(0xC041, ptbl[id].para[10]);
	hdmi_write(0x0041, ptbl[id].para[11]);
	hdmi_write(0x8041, ptbl[id].para[12]);
	hdmi_write(0x4040, ptbl[id].para[13]);
	hdmi_write(0xC040, ptbl[id].para[14]);
	hdmi_write(0x0043, ptbl[id].para[15]);
	hdmi_write(0x8043, ptbl[id].para[16]);
	hdmi_write(0x0045, 0x0c);
	hdmi_write(0x8044, 0x20);
	hdmi_write(0x8045, 0x01);
	hdmi_write(0x0046, 0x0b);
	hdmi_write(0x0047, 0x16);
	hdmi_write(0x8046, 0x21);
	hdmi_write(0x3048, ptbl[id].para[2] ? 0x21 : 0x10);
	hdmi_write(0x0401, ptbl[id].para[2] ? 0x41 : 0x40);
	hdmi_write(0x8400, 0x07);
	hdmi_write(0x8401, 0x00);
	hdmi_write(0x0402, 0x47);
	hdmi_write(0x0800, 0x01);
	hdmi_write(0x0801, 0x07);
	hdmi_write(0x8800, 0x00);
	hdmi_write(0x8801, 0x00);
	hdmi_write(0x0802, 0x00);
	hdmi_write(0x0803, 0x00);
	hdmi_write(0x8802, 0x00);
	hdmi_write(0x8803, 0x00);

	if(video->is_hdmi)
	{
		hdmi_write(0xB045, 0x08);
		hdmi_write(0x2045, 0x00);
		hdmi_write(0x2044, 0x0c);
		hdmi_write(0x6041, 0x03);
		hdmi_write(0xA044, ((ptbl[id].para[0]&0x100) == 0x100) ? 0x20 : ( ((ptbl[id].para[0]&0x80) == 0x80) ? 0x40 : 0x00) );
		hdmi_write(0xA045, ((ptbl[id].para[0]&0x100) == 0x100) ? (ptbl[id].para[0]&0x7f) : 0x00);
		hdmi_write(0x2046, 0x00);
		hdmi_write(0x3046, 0x01);
		hdmi_write(0x3047, 0x11);
		hdmi_write(0x4044, 0x00);
		hdmi_write(0x0052, 0x00);
		hdmi_write(0x8051, 0x11);
		hdmi_write(0x10010,0x45);
		hdmi_write(0x10011,0x45);
		hdmi_write(0x10012,0x52);
		hdmi_write(0x10013,0x54);
		hdmi_write(0x0040, hdmi_read(0x0040) | 0x08 );
		hdmi_write(0x10010,0x52);
		hdmi_write(0x10011,0x54);
		hdmi_write(0x10012,0x41);
		hdmi_write(0x10013,0x57);
		hdmi_write(0x4045, video->is_yuv ? 0x02 : 0x00);
		if(ptbl[id].para[17] == 0)
			hdmi_write(0xC044, (video->csc << 6) | 0x18);
		else if(ptbl[id].para[17] == 1)
			hdmi_write(0xC044, (video->csc << 6) | 0x28);
		else
			hdmi_write(0xC044, (video->csc << 6) | 0x08);

		if((ptbl[id].para[0] == 32) ||
				(ptbl[id].para[0] == 160)||
		 		(ptbl[id].para[0] == 257)||
		 		(ptbl[id].para[0] == 258))
		{
			hdmi_write(0xC045, 0x01);
		}
		else
		{
			hdmi_write(0xC045, 0x00);
		}

		hdmi_write(0x4046, ptbl[id].para[0]&0x7f);
	}

	if(video->is_hcts)
	{
		hdmi_write(0x00C0, video->is_hdmi ? 0x91 : 0x90 );
		hdmi_write(0x00C1, 0x05);
		hdmi_write(0x40C1, (ptbl[id].para[3] < 96) ? 0x10 : 0x1a);
		hdmi_write(0x80C2, 0xff);
		hdmi_write(0x40C0, 0xfd);
		hdmi_write(0xC0C0, 0x40);
		hdmi_write(0x00C1, 0x04);
		hdmi_write(0x10010,0x45);
		hdmi_write(0x10011,0x45);
		hdmi_write(0x10012,0x52);
		hdmi_write(0x10013,0x54);
		hdmi_write(0x0040, hdmi_read(0x0040) | 0x80 );
		hdmi_write(0x00C0, video->is_hdmi ? 0x95 : 0x94 );
		hdmi_write(0x10010,0x52);
		hdmi_write(0x10011,0x54);
		hdmi_write(0x10012,0x41);
		hdmi_write(0x10013,0x57);
	}

	hdmi_write(0x0082, 0x00);
	hdmi_write(0x0081, 0x00);

	hdmi_write(0x0840, 0x00);

	if(video->is_hcts)
	{

	}

	return 0;
}
コード例 #29
0
ファイル: hdmi_connector.c プロジェクト: 03199618/linux
static int hpd_enable(struct hdmi_connector *hdmi_connector)
{
	struct hdmi *hdmi = hdmi_connector->hdmi;
	struct drm_device *dev = hdmi_connector->base.dev;
	struct hdmi_phy *phy = hdmi->phy;
	uint32_t hpd_ctrl;
	int ret;

	ret = gpio_config(hdmi, true);
	if (ret) {
		dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret);
		goto fail;
	}

	ret = clk_prepare_enable(hdmi->clk);
	if (ret) {
		dev_err(dev->dev, "failed to enable 'clk': %d\n", ret);
		goto fail;
	}

	ret = clk_prepare_enable(hdmi->m_pclk);
	if (ret) {
		dev_err(dev->dev, "failed to enable 'm_pclk': %d\n", ret);
		goto fail;
	}

	ret = clk_prepare_enable(hdmi->s_pclk);
	if (ret) {
		dev_err(dev->dev, "failed to enable 's_pclk': %d\n", ret);
		goto fail;
	}

	if (hdmi->mpp0)
		ret = regulator_enable(hdmi->mpp0);
	if (!ret)
		ret = regulator_enable(hdmi->mvs);
	if (ret) {
		dev_err(dev->dev, "failed to enable regulators: %d\n", ret);
		goto fail;
	}

	hdmi_set_mode(hdmi, false);
	phy->funcs->reset(phy);
	hdmi_set_mode(hdmi, true);

	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);

	/* enable HPD events: */
	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
			HDMI_HPD_INT_CTRL_INT_CONNECT |
			HDMI_HPD_INT_CTRL_INT_EN);

	/* set timeout to 4.1ms (max) for hardware debounce */
	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);

	/* Toggle HPD circuit to trigger HPD sense */
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);

	return 0;

fail:
	return ret;
}