예제 #1
0
void stmp3xxx_init_lcdif(void)
{
	stmp3xxx_clearl(BM_LCDIF_CTRL_CLKGATE, REGS_LCDIF_BASE + HW_LCDIF_CTRL);
	/* Reset controller */
	stmp3xxx_setl(BM_LCDIF_CTRL_SFTRST, REGS_LCDIF_BASE + HW_LCDIF_CTRL);
	udelay(10);

	/* Take controller out of reset */
	stmp3xxx_clearl(BM_LCDIF_CTRL_SFTRST | BM_LCDIF_CTRL_CLKGATE,
			REGS_LCDIF_BASE + HW_LCDIF_CTRL);

	/* Setup the bus protocol */
	stmp3xxx_clearl(BM_LCDIF_CTRL1_MODE86,
			REGS_LCDIF_BASE + HW_LCDIF_CTRL1);
	stmp3xxx_clearl(BM_LCDIF_CTRL1_BUSY_ENABLE,
			REGS_LCDIF_BASE + HW_LCDIF_CTRL1);

	/* Take display out of reset */
	stmp3xxx_setl(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1);

	/* VSYNC is an input by default */
	stmp3xxx_setl(BM_LCDIF_VDCTRL0_VSYNC_OEB,
		      REGS_LCDIF_BASE + HW_LCDIF_VDCTRL0);

	/* Reset display */
	stmp3xxx_clearl(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1);
	udelay(10);
	stmp3xxx_setl(BM_LCDIF_CTRL1_RESET, REGS_LCDIF_BASE + HW_LCDIF_CTRL1);
	udelay(10);
}
예제 #2
0
static int stmp3xxx_set_irqtype(unsigned irq, unsigned type)
{
	struct stmp3xxx_pinmux_bank *pm;
	unsigned gpio;
	int l, p;

	stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		l = 0; p = 1; break;
	case IRQ_TYPE_EDGE_FALLING:
		l = 0; p = 0; break;
	case IRQ_TYPE_LEVEL_HIGH:
		l = 1; p = 1; break;
	case IRQ_TYPE_LEVEL_LOW:
		l = 1; p = 0; break;
	default:
		pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n",
				__func__, type);
		return -ENXIO;
	}

	if (l)
		stmp3xxx_setl(1 << gpio, pm->irqlevel);
	else
		stmp3xxx_clearl(1 << gpio, pm->irqlevel);
	if (p)
		stmp3xxx_setl(1 << gpio, pm->irqpolarity);
	else
		stmp3xxx_clearl(1 << gpio, pm->irqpolarity);
	return 0;
}
static void wdt_enable(u32 value)
{
	spin_lock(&stmp3xxx_wdt_io_lock);
	__raw_writel(value, REGS_RTC_BASE + HW_RTC_WATCHDOG);
	stmp3xxx_setl(BM_RTC_CTRL_WATCHDOGEN, REGS_RTC_BASE + HW_RTC_CTRL);
	stmp3xxx_setl(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER,
			REGS_RTC_BASE + HW_RTC_PERSISTENT1);
	spin_unlock(&stmp3xxx_wdt_io_lock);
}
예제 #4
0
static void stmp3xxx_pin_unmask_irq(unsigned irq)
{
	struct stmp3xxx_pinmux_bank *pm;
	unsigned gpio;

	stmp3xxx_irq_to_gpio(irq, &pm, &gpio);
	stmp3xxx_setl(1 << gpio, pm->irqen);
	stmp3xxx_setl(1 << gpio, pm->pin2irq);
}
예제 #5
0
파일: stmp37xx.c 프로젝트: 0x0f/adam-kernel
void stmp3xxx_arch_dma_freeze(int channel)
{
	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
		break;
	case STMP3XXX_BUS_APBX:
		stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
		break;
	}
}
예제 #6
0
파일: stmp37xx.c 프로젝트: 0x0f/adam-kernel
/*
 * DMA interrupt handling
 */
void stmp3xxx_arch_dma_enable_interrupt(int channel)
{
	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
			REGS_APBH_BASE + HW_APBH_CTRL1);
		break;

	case STMP3XXX_BUS_APBX:
		stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
			REGS_APBX_BASE + HW_APBX_CTRL1);
		break;
	}
}
예제 #7
0
void stmp3xxx_lcdif_run(void)
{
	if (stmp378x_lcd_master) {
		stmp3xxx_setl(BM_LCDIF_CTRL_LCDIF_MASTER,
			      REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		stmp3xxx_setl(BM_LCDIF_CTRL_RUN,
			      REGS_LCDIF_BASE + HW_LCDIF_CTRL);
	} else {
		video_dma_descriptor[dma_chain_info_pos - 1].command->cmd &=
		    ~BM_APBH_CHn_CMD_SEMAPHORE;
		stmp3xxx_dma_go(STMP3XXX_DMA
				(LCD_DMA_CHANNEL, STMP3XXX_BUS_APBH),
				video_dma_descriptor, 1);
	}
}
예제 #8
0
void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
		const char *label)
{
	struct stmp3xxx_pinmux_bank *pbank;
	void __iomem *hwdrive;
	u32 shift, val;
	u32 bank, pin;

	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
	pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label,
		 bank, pin, strength);

	hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
	shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
	val = pbank->strengths[strength];
	if (val == 0xff) {
		printk(KERN_WARNING
		       "%s: strength is not supported for bank %d, caller %s",
		       __func__, bank, label);
		return;
	}

	if (stmp3xxx_check_pin(id, label))
		return;

	pr_debug("%s: writing 0x%x to 0x%p register\n", __func__,
			val << shift, hwdrive);
	stmp3xxx_clearl(HW_DRIVE_PINDRV_MASK << shift, hwdrive);
	stmp3xxx_setl(val << shift, hwdrive);
}
예제 #9
0
void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
			  const char *label)
{
	struct stmp3xxx_pinmux_bank *pbank;
	void __iomem *hwdrive;
	u32 shift;
	u32 bank, pin;

	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
	pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label,
		 bank, pin, voltage);

	hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
	shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;

	if (stmp3xxx_check_pin(id, label))
		return;

	pr_debug("%s: changing 0x%x bit in 0x%p register\n",
			__func__, HW_DRIVE_PINV_MASK << shift, hwdrive);
	if (voltage == PIN_1_8V)
		stmp3xxx_clearl(HW_DRIVE_PINV_MASK << shift, hwdrive);
	else
		stmp3xxx_setl(HW_DRIVE_PINV_MASK << shift, hwdrive);
}
예제 #10
0
static int blank_panel(int blank)
{
	int ret = 0, count;

	switch (blank) {
	case FB_BLANK_NORMAL:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_POWERDOWN:
		stmp3xxx_clearl(BM_LCDIF_CTRL_BYPASS_COUNT,
				REGS_LCDIF_BASE + HW_LCDIF_CTRL);

		/* Wait until current transfer is complete, max 30ms */
		for (count = 30000; count > 0; count--) {
			if (__raw_readl(REGS_LCDIF_BASE + HW_LCDIF_STAT) &
			    BM_LCDIF_STAT_TXFIFO_EMPTY)
				break;
			udelay(1);
		}
		break;

	case FB_BLANK_UNBLANK:
		stmp3xxx_setl(BM_LCDIF_CTRL_BYPASS_COUNT,
			      REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		break;

	default:
		ret = -EINVAL;
	}
	return ret;
}
예제 #11
0
void stmp3xxx_dma_set_alt_target(int channel, int function)
{
#if defined(CONFIG_ARCH_STMP37XX)
	unsigned bits = 4;
#elif defined(CONFIG_ARCH_STMP378X)
	unsigned bits = 2;
#else
#error wrong arch
#endif
	int shift = STMP3XXX_DMA_CHANNEL(channel) * bits;
	unsigned mask = (1<<bits) - 1;
	void __iomem *c;

	BUG_ON(function < 0 || function >= (1<<bits));
	pr_debug("%s: channel = %d, using mask %x, "
		 "shift = %d\n", __func__, channel, mask, shift);

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		c = REGS_APBH_BASE + HW_APBH_DEVSEL;
		break;
	case STMP3XXX_BUS_APBX:
		c = REGS_APBX_BASE + HW_APBX_DEVSEL;
		break;
	default:
		BUG();
	}
	stmp3xxx_clearl(mask << shift, c);
	stmp3xxx_setl(mask << shift, c);
}
예제 #12
0
static int init_bl(struct stmp3xxx_platform_bl_data *data)
{
	int ret = 0;

	pwm_clk = clk_get(NULL, "pwm");
	if (IS_ERR(pwm_clk)) {
		ret = PTR_ERR(pwm_clk);
		goto out;
	}
	clk_enable(pwm_clk);
	stmp3xxx_reset_block(REGS_PWM_BASE, 1);

	ret = stmp3xxx_request_pin(PINID_PWM2, PIN_FUN1, "lcd_hx8238a");
	if (ret)
		goto out_mux;
	stmp3xxx_pin_voltage(PINID_PWM2, PIN_12MA, "lcd_hx8238a");
	stmp3xxx_pin_strength(PINID_PWM2, PIN_3_3V, "lcd_hx8238a");

	stmp3xxx_clearl(BM_PWM_CTRL_PWM2_ENABLE, REGS_PWM_BASE + HW_PWM_CTRL);
	stmp3xxx_setl(BM_PWM_CTRL_PWM2_ANA_CTRL_ENABLE, REGS_PWM_BASE + HW_PWM_CTRL);
	__raw_writel(BF(10, PWM_ACTIVEn_INACTIVE) |
				BF(5, PWM_ACTIVEn_ACTIVE),
				REGS_PWM_BASE + HW_PWM_ACTIVEn(2));
	__raw_writel(BF(1, PWM_PERIODn_CDIV) | /* divide by 2 */
			BF(2, PWM_PERIODn_INACTIVE_STATE) | /* low */
			BF(3, PWM_PERIODn_ACTIVE_STATE) | /* high */
			BF(14, PWM_PERIODn_PERIOD),
			REGS_PWM_BASE + HW_PWM_PERIODn(2));
	return 0;

out_mux:
	clk_put(pwm_clk);
out:
	return ret;
}
예제 #13
0
void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
		unsigned count)
{
	void __iomem *c;
	u32 mask_clr, mask;
	BUG_ON(chain->free_count < count);

	chain->free_count -= count;
	chain->free_index += count;
	chain->free_index %= chain->total_count;
	chain->active_count += count;

	switch (chain->bus) {
	case STMP3XXX_BUS_APBH:
		c = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * chain->channel;
		mask_clr = BM_APBH_CHn_SEMA_INCREMENT_SEMA;
		mask = BF(count, APBH_CHn_SEMA_INCREMENT_SEMA);
		break;
	case STMP3XXX_BUS_APBX:
		c = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * chain->channel;
		mask_clr = BM_APBX_CHn_SEMA_INCREMENT_SEMA;
		mask = BF(count, APBX_CHn_SEMA_INCREMENT_SEMA);
		break;
	default:
		BUG();
		return;
	}

	/* Set counting semaphore (kicks off transfer). Assumes
	   peripheral has been set up correctly */
	stmp3xxx_clearl(mask_clr, c);
	stmp3xxx_setl(mask, c);
}
예제 #14
0
void stmp3xxx_suspend_timer(void)
{
	stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN | BM_TIMROT_TIMCTRLn_IRQ,
			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
	stmp3xxx_setl(BM_TIMROT_ROTCTRL_CLKGATE,
			REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
}
예제 #15
0
int usb_phy_enable(void)
{
	u32 tmp;
	/* Reset USBPHY module */
	stmp3xxx_setl(BM_USBPHY_CTRL_SFTRST,
		      REGS_USBPHY_BASE + HW_USBPHY_CTRL);
	udelay(10);

	/* Remove CLKGATE and SFTRST */
	stmp3xxx_clearl(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST,
		      REGS_USBPHY_BASE + HW_USBPHY_CTRL);

	/* Turn on the USB clocks */
	stmp3xxx_setl(BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
		     REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0);
	stmp3xxx_clearl(BM_DIGCTL_CTRL_USB_CLKGATE,
		      REGS_DIGCTL_BASE + HW_DIGCTL_CTRL);

	/* set UTMI xcvr */
	/* Workaround an IC issue for ehci driver:
	 * when turn off root hub port power, EHCI set
	 * PORTSC reserved bits to be 0, but PTW with 0
	 * means 8 bits tranceiver width, here change
	 * it back to be 16 bits and do PHY diable and
	 * then enable.
	 */
	tmp = __raw_readl(REGS_USBCTRL_BASE + HW_USBCTRL_PORTSC1) & ~PORTSC_PTS_MASK;
	tmp |= (PORTSC_PTS_UTMI | PORTSC_PTW);
	__raw_writel(tmp, REGS_USBCTRL_BASE + HW_USBCTRL_PORTSC1);

	/* Power up the PHY */
	__raw_writel(0, REGS_USBPHY_BASE + HW_USBPHY_PWD);

	/*
	* Set precharge bit to cure overshoot problems at the
	* start of packets
	*/
	stmp3xxx_setl(1, REGS_USBPHY_BASE + HW_USBPHY_CTRL);

#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
	/* enable disconnect detector */
	/* enable disconnect detector must be after entry high speed mode*/
	/*HW_USBPHY_CTRL_SET(BM_USBPHY_CTRL_ENHOSTDISCONDETECT);
	*/
#endif
	return 0;
}
예제 #16
0
static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v)
{
	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);

	stmp3xxx_setl(1 << offset, pm->hw_gpio_doe);
	stmp3xxx_gpio_set(chip, offset, v);
	return 0;
}
예제 #17
0
static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v)
{
	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);

	if (v)
		stmp3xxx_setl(1 << offset, pm->hw_gpio_out);
	else
		stmp3xxx_clearl(1 << offset, pm->hw_gpio_out);
}
예제 #18
0
파일: stmp37xx.c 프로젝트: 0x0f/adam-kernel
void stmp3xxx_arch_dma_reset_channel(int channel)
{
	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);

	switch (STMP3XXX_DMA_BUS(channel)) {
	case STMP3XXX_BUS_APBH:
		/* Reset channel and wait for it to complete */
		stmp3xxx_setl(chbit << BP_APBH_CTRL0_RESET_CHANNEL,
			REGS_APBH_BASE + HW_APBH_CTRL0);
		while (__raw_readl(REGS_APBH_BASE + HW_APBH_CTRL0) &
		       (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
				cpu_relax();
		break;

	case STMP3XXX_BUS_APBX:
		stmp3xxx_setl(chbit << BP_APBX_CTRL0_RESET_CHANNEL,
			REGS_APBX_BASE + HW_APBX_CTRL0);
		while (__raw_readl(REGS_APBX_BASE + HW_APBX_CTRL0) &
		       (chbit << BP_APBX_CTRL0_RESET_CHANNEL))
				cpu_relax();
		break;
	}
}
예제 #19
0
void stmp3xxx_lcdif_stop(void)
{
	if (stmp378x_lcd_master) {
		stmp3xxx_clearl(BM_LCDIF_CTRL_RUN,
				REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		stmp3xxx_clearl(BM_LCDIF_CTRL_LCDIF_MASTER,
				REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		udelay(100);
	} else {
		video_dma_descriptor[dma_chain_info_pos - 1].command->cmd |=
		    BM_APBH_CHn_CMD_SEMAPHORE;
		udelay(100);
	}
	stmp3xxx_setl(BM_LCDIF_CTRL_CLKGATE, REGS_LCDIF_BASE + HW_LCDIF_CTRL);
}
예제 #20
0
void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun)
{
	struct stmp3xxx_pinmux_bank *pbank;
	void __iomem *hwmux;
	u32 shift, val;
	u32 bank, pin;

	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);

	hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM];
	shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;

	val = pbank->functions[fun];
	shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
	pr_debug("%s: writing 0x%x to 0x%p register\n",
			__func__, val << shift, hwmux);
	stmp3xxx_clearl(HW_MUXSEL_PINFUN_MASK << shift, hwmux);
	stmp3xxx_setl(val << shift, hwmux);
}
예제 #21
0
static void set_bl_intensity(struct stmp3xxx_platform_bl_data *data,
			struct backlight_device *bd, int suspended)
{
	int intensity = bd->props.brightness;

	if (bd->props.power != FB_BLANK_UNBLANK)
		intensity = 0;
	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
		intensity = 0;
	if (suspended)
		intensity = 0;

	stmp3xxx_clearl(BM_PWM_CTRL_PWM2_ENABLE, REGS_PWM_BASE + HW_PWM_CTRL);
	if (intensity) {
		HW_LRADC_CTRL2_CLR(BM_LRADC_CTRL2_BL_BRIGHTNESS);
		HW_LRADC_CTRL2_SET(BM_LRADC_CTRL2_BL_ENABLE |
				BM_LRADC_CTRL2_BL_MUX_SELECT |
				BF(intensity - 1, LRADC_CTRL2_BL_BRIGHTNESS));
		stmp3xxx_setl(BM_PWM_CTRL_PWM2_ENABLE, REGS_PWM_BASE + HW_PWM_CTRL);
	}
}
예제 #22
0
static int blank_panel(int blank)
{
	int ret = 0;

	switch (blank) {
	case FB_BLANK_NORMAL:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_POWERDOWN:
		stmp3xxx_clearl(BM_LCDIF_CTRL_RUN, REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		break;

	case FB_BLANK_UNBLANK:
		stmp3xxx_setl(BM_LCDIF_CTRL_RUN, REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		break;

	default:
		ret = -EINVAL;
	}
	return ret;
}
예제 #23
0
int stmp3xxx_lcdif_dma_init(struct device *dev, dma_addr_t phys, int memsize,
			    int lcd_master)
{
	int ret = 0;

	stmp378x_lcd_master = lcd_master;
	if (lcd_master) {
		stmp3xxx_setl(BM_LCDIF_CTRL_LCDIF_MASTER,
			      REGS_LCDIF_BASE + HW_LCDIF_CTRL);

		__raw_writel(phys, REGS_LCDIF_BASE + HW_LCDIF_CUR_BUF);
		__raw_writel(phys, REGS_LCDIF_BASE + HW_LCDIF_NEXT_BUF);
	} else {
		ret =
		    stmp3xxx_dma_request(STMP3XXX_DMA
					 (LCD_DMA_CHANNEL, STMP3XXX_BUS_APBH),
					 dev, "lcdif");
		if (ret) {
			dev_err(dev,
				"stmp3xxx_dma_request failed: error %d\n", ret);
			goto out;
		}

		stmp3xxx_dma_reset_channel(STMP3XXX_DMA
					   (LCD_DMA_CHANNEL,
					    STMP3XXX_BUS_APBH));

		stmp3xxx_dma_clear_interrupt(STMP3XXX_DMA
					     (LCD_DMA_CHANNEL,
					      STMP3XXX_BUS_APBH));
		stmp3xxx_dma_enable_interrupt(STMP3XXX_DMA
					      (LCD_DMA_CHANNEL,
					       STMP3XXX_BUS_APBH));

		dotclk_dma_chain_init(memsize, phys, video_dma_descriptor,
				      dma_chain_info, &dma_chain_info_pos);
	}
out:
	return ret;
}
예제 #24
0
void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label)
{
	struct stmp3xxx_pinmux_bank *pbank;
	void __iomem *hwpull;
	u32 bank, pin;

	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
	pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label,
		 bank, pin, enable);

	hwpull = pbank->hw_pull;

	if (stmp3xxx_check_pin(id, label))
		return;

	pr_debug("%s: changing 0x%x bit in 0x%p register\n",
			__func__, 1 << pin, hwpull);
	if (enable)
		stmp3xxx_setl(1 << pin, hwpull);
	else
		stmp3xxx_clearl(1 << pin, hwpull);
}
예제 #25
0
파일: stmp37xx.c 프로젝트: 0x0f/adam-kernel
static void stmp37xx_unmask_irq(unsigned int irq)
{
	/* IRQ enable */
	stmp3xxx_setl(0x04 << ((irq % 4) * 8),
		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + irq / 4 * 0x10);
}
예제 #26
0
void stmp3xxx_dma_suspend(void)
{
	stmp3xxx_setl(BM_APBH_CTRL0_CLKGATE, REGS_APBH_BASE + HW_APBH_CTRL0);
	stmp3xxx_setl(BM_APBX_CTRL0_CLKGATE, REGS_APBX_BASE + HW_APBX_CTRL0);
}
예제 #27
0
static void init_tvenc_hw(int mode)
{
	/* Reset module */
	stmp3xxx_setl(BM_TVENC_CTRL_SFTRST, REGS_TVENC_BASE + HW_TVENC_CTRL);
	udelay(10);

	/* Take module out of reset */
	stmp3xxx_clearl(BM_TVENC_CTRL_SFTRST | BM_TVENC_CTRL_CLKGATE,
			REGS_TVENC_BASE + HW_TVENC_CTRL);

	if (mode == TVENC_MODE_NTSC) {
		/* Config NTSC-M mode, 8-bit Y/C in, SYNC out */
		stmp3xxx_clearl(BM_TVENC_CONFIG_SYNC_MODE |
				BM_TVENC_CONFIG_PAL_SHAPE |
				BM_TVENC_CONFIG_YGAIN_SEL |
				BM_TVENC_CONFIG_CGAIN,
				REGS_TVENC_BASE + HW_TVENC_CONFIG);
		stmp3xxx_setl(BM_TVENC_CONFIG_FSYNC_PHS |
			      BF(0x4, TVENC_CONFIG_SYNC_MODE),
			      REGS_TVENC_BASE + HW_TVENC_CONFIG);

		/* 859 pixels/line for NTSC */
		__raw_writel(857, REGS_TVENC_BASE + HW_TVENC_SYNCOFFSET);

		__raw_writel(0x21F07C1F, REGS_TVENC_BASE + HW_TVENC_COLORSUB0);
		stmp3xxx_clearl(BM_TVENC_COLORBURST_NBA |
				BM_TVENC_COLORBURST_PBA,
				REGS_TVENC_BASE + HW_TVENC_COLORBURST);
		stmp3xxx_setl(BF(0xc8, TVENC_COLORBURST_NBA) |
			      BF(0, TVENC_COLORBURST_PBA),
			      REGS_TVENC_BASE + HW_TVENC_COLORBURST);
	} else if (mode == TVENC_MODE_PAL) {
		/* Config PAL-B mode, 8-bit Y/C in, SYNC out */
		stmp3xxx_clearl(BM_TVENC_CONFIG_SYNC_MODE |
				BM_TVENC_CONFIG_ENCD_MODE |
				BM_TVENC_CONFIG_YGAIN_SEL |
				BM_TVENC_CONFIG_CGAIN |
				BM_TVENC_CONFIG_FSYNC_PHS,
				REGS_TVENC_BASE + HW_TVENC_CONFIG);
		stmp3xxx_setl(BM_TVENC_CONFIG_PAL_SHAPE |
			      BF(1, TVENC_CONFIG_YGAIN_SEL) | BF(1,
								 TVENC_CONFIG_CGAIN)
			      | BF(0x1, TVENC_CONFIG_ENCD_MODE) | BF(0x4,
								     TVENC_CONFIG_SYNC_MODE),
			      REGS_TVENC_BASE + HW_TVENC_CONFIG);

		/* 863 pixels/line for PAL */
		__raw_writel(863, REGS_TVENC_BASE + HW_TVENC_SYNCOFFSET);

		__raw_writel(0x2A098ACB, REGS_TVENC_BASE + HW_TVENC_COLORSUB0);
		stmp3xxx_clearl(BM_TVENC_COLORBURST_NBA |
				BM_TVENC_COLORBURST_PBA,
				REGS_TVENC_BASE + HW_TVENC_COLORBURST);
		stmp3xxx_setl(BF(0xd6, TVENC_COLORBURST_NBA) |
			      BF(0x2a, TVENC_COLORBURST_PBA),
			      REGS_TVENC_BASE + HW_TVENC_COLORBURST);
	}

	/* Power up DAC */
	__raw_writel(BM_TVENC_DACCTRL_GAINDN |
		     BM_TVENC_DACCTRL_GAINUP |
		     BM_TVENC_DACCTRL_PWRUP1 |
		     BM_TVENC_DACCTRL_DUMP_TOVDD1 |
		     BF(3, TVENC_DACCTRL_RVAL),
		     REGS_TVENC_BASE + HW_TVENC_DACCTRL);

	/* set all to zero is a requirement for NTSC */
	__raw_writel(0, REGS_TVENC_BASE + HW_TVENC_MACROVISION0);
	__raw_writel(0, REGS_TVENC_BASE + HW_TVENC_MACROVISION1);
	__raw_writel(0, REGS_TVENC_BASE + HW_TVENC_MACROVISION2);
	__raw_writel(0, REGS_TVENC_BASE + HW_TVENC_MACROVISION3);
	__raw_writel(0, REGS_TVENC_BASE + HW_TVENC_MACROVISION4);
}