void lcd_ctrl_init(void *lcdbase)
{
	unsigned long value;
	struct lcd_dma_desc *desc;
	struct atmel_hlcd_regs *regs;
	int ret;

	if (!has_lcdc())
		return;     /* No lcdc */

	regs = (struct atmel_hlcd_regs *)panel_info.mmio;

	/* Disable DISP signal */
	writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable synchronization */
	writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable pixel clock */
	writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable PWM */
	writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);

	/* Set pixel clock */
	value = get_lcdc_clk_rate(0) / panel_info.vl_clk;
	if (get_lcdc_clk_rate(0) % panel_info.vl_clk)
		value++;

	if (value < 1) {
		/* Using system clock as pixel clock */
		writel(LCDC_LCDCFG0_CLKDIV(0)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| panel_info.vl_clk_pol
			| LCDC_LCDCFG0_CLKSEL,
			&regs->lcdc_lcdcfg0);

	} else {
		writel(LCDC_LCDCFG0_CLKDIV(value - 2)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| panel_info.vl_clk_pol,
			&regs->lcdc_lcdcfg0);
	}

	/* Initialize control register 5 */
	value = 0;

	value |= panel_info.vl_sync;

#ifndef LCD_OUTPUT_BPP
	/* Output is 24bpp */
	value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
#else
	switch (LCD_OUTPUT_BPP) {
	case 12:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
		break;
	case 16:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
		break;
	case 18:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
		break;
	case 24:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
		break;
	default:
		BUG();
		break;
	}
#endif

	value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME);
	value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
	writel(value, &regs->lcdc_lcdcfg5);

	/* Vertical & Horizontal Timing */
	value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1);
	value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1);
	writel(value, &regs->lcdc_lcdcfg1);

	value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin);
	value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1);
	writel(value, &regs->lcdc_lcdcfg2);

	value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1);
	value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1);
	writel(value, &regs->lcdc_lcdcfg3);

	/* Display size */
	value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1);
	value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1);
	writel(value, &regs->lcdc_lcdcfg4);

	writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
	       &regs->lcdc_basecfg0);

	switch (NBITS(panel_info.vl_bpix)) {
	case 16:
		writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
		       &regs->lcdc_basecfg1);
		break;
	case 32:
		writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
		       &regs->lcdc_basecfg1);
		break;
	default:
		BUG();
		break;
	}

	writel(LCDC_BASECFG2_XSTRIDE(0), &regs->lcdc_basecfg2);
	writel(0, &regs->lcdc_basecfg3);
	writel(LCDC_BASECFG4_DMA, &regs->lcdc_basecfg4);

	/* Disable all interrupts */
	writel(~0UL, &regs->lcdc_lcdidr);
	writel(~0UL, &regs->lcdc_baseidr);

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = (struct lcd_dma_desc *)(lcdbase - 16);

	desc->address = (u32)lcdbase;
	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
	desc->next = (u32)desc;

	/* Flush the DMA descriptor if we enabled dcache */
	flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));

	writel(desc->address, &regs->lcdc_baseaddr);
	writel(desc->control, &regs->lcdc_basectrl);
	writel(desc->next, &regs->lcdc_basenext);
	writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
	       &regs->lcdc_basecher);

	/* Enable LCD */
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);

	/* Enable flushing if we enabled dcache */
	lcd_set_flush_dcache(1);
}
Beispiel #2
0
void lcd_ctrl_init(void *lcdbase)
{
	unsigned long value;
	struct lcd_dma_desc *desc;
	struct atmel_hlcd_regs *regs;

	if (!has_lcdc())
		return;     /* No lcdc */

	regs = (struct atmel_hlcd_regs *)panel_info.mmio;

	/* Disable DISP signal */
	lcdc_writel(&regs->lcdc_lcddis, LCDC_LCDDIS_DISPDIS);
	while ((lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_DISPSTS))
		udelay(1);
	/* Disable synchronization */
	lcdc_writel(&regs->lcdc_lcddis, LCDC_LCDDIS_SYNCDIS);
	while ((lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_LCDSTS))
		udelay(1);
	/* Disable pixel clock */
	lcdc_writel(&regs->lcdc_lcddis, LCDC_LCDDIS_CLKDIS);
	while ((lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_CLKSTS))
		udelay(1);
	/* Disable PWM */
	lcdc_writel(&regs->lcdc_lcddis, LCDC_LCDDIS_PWMDIS);
	while ((lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_PWMSTS))
		udelay(1);

	/* Set pixel clock */
	value = get_lcdc_clk_rate(0) / panel_info.vl_clk;
	if (get_lcdc_clk_rate(0) % panel_info.vl_clk)
		value++;

	if (value < 1) {
		/* Using system clock as pixel clock */
		lcdc_writel(&regs->lcdc_lcdcfg0,
					LCDC_LCDCFG0_CLKDIV(0)
					| LCDC_LCDCFG0_CGDISHCR
					| LCDC_LCDCFG0_CGDISHEO
					| LCDC_LCDCFG0_CGDISOVR1
					| LCDC_LCDCFG0_CGDISBASE
					| panel_info.vl_clk_pol
					| LCDC_LCDCFG0_CLKSEL);

	} else {
		lcdc_writel(&regs->lcdc_lcdcfg0,
				LCDC_LCDCFG0_CLKDIV(value - 2)
				| LCDC_LCDCFG0_CGDISHCR
				| LCDC_LCDCFG0_CGDISHEO
				| LCDC_LCDCFG0_CGDISOVR1
				| LCDC_LCDCFG0_CGDISBASE
				| panel_info.vl_clk_pol);
	}

	/* Initialize control register 5 */
	value = 0;

	value |= panel_info.vl_sync;

#ifndef LCD_OUTPUT_BPP
	/* Output is 24bpp */
	value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
#else
	switch (LCD_OUTPUT_BPP) {
	case 12:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
		break;
	case 16:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
		break;
	case 18:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
		break;
	case 24:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
		break;
	default:
		BUG();
		break;
	}
#endif

	value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME);
	value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
	lcdc_writel(&regs->lcdc_lcdcfg5, value);

	/* Vertical & Horizontal Timing */
	value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1);
	value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1);
	lcdc_writel(&regs->lcdc_lcdcfg1, value);

	value = LCDC_LCDCFG2_VBPW(panel_info.vl_lower_margin);
	value |= LCDC_LCDCFG2_VFPW(panel_info.vl_upper_margin - 1);
	lcdc_writel(&regs->lcdc_lcdcfg2, value);

	value = LCDC_LCDCFG3_HBPW(panel_info.vl_right_margin - 1);
	value |= LCDC_LCDCFG3_HFPW(panel_info.vl_left_margin - 1);
	lcdc_writel(&regs->lcdc_lcdcfg3, value);

	/* Display size */
	value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1);
	value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1);
	lcdc_writel(&regs->lcdc_lcdcfg4, value);

	lcdc_writel(&regs->lcdc_basecfg0,
			LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO);

	switch (NBITS(panel_info.vl_bpix)) {
	case 16:
		lcdc_writel(&regs->lcdc_basecfg1,
			LCDC_BASECFG1_RGBMODE_16BPP_RGB_565);
		break;
	default:
		BUG();
		break;
	}

	lcdc_writel(&regs->lcdc_basecfg2, LCDC_BASECFG2_XSTRIDE(0));
	lcdc_writel(&regs->lcdc_basecfg3, 0);
	lcdc_writel(&regs->lcdc_basecfg4, LCDC_BASECFG4_DMA);

	/* Disable all interrupts */
	lcdc_writel(&regs->lcdc_lcdidr, ~0UL);
	lcdc_writel(&regs->lcdc_baseidr, ~0UL);

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = (struct lcd_dma_desc *)(lcdbase - 16);

	desc->address = (u32)lcdbase;
	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
	desc->next = (u32)desc;

	lcdc_writel(&regs->lcdc_baseaddr, desc->address);
	lcdc_writel(&regs->lcdc_basectrl, desc->control);
	lcdc_writel(&regs->lcdc_basenext, desc->next);
	lcdc_writel(&regs->lcdc_basecher, LCDC_BASECHER_CHEN |
					  LCDC_BASECHER_UPDATEEN);

	/* Enable LCD */
	value = lcdc_readl(&regs->lcdc_lcden);
	lcdc_writel(&regs->lcdc_lcden, value | LCDC_LCDEN_CLKEN);
	while (!(lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_CLKSTS))
		udelay(1);
	value = lcdc_readl(&regs->lcdc_lcden);
	lcdc_writel(&regs->lcdc_lcden, value | LCDC_LCDEN_SYNCEN);
	while (!(lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_LCDSTS))
		udelay(1);
	value = lcdc_readl(&regs->lcdc_lcden);
	lcdc_writel(&regs->lcdc_lcden, value | LCDC_LCDEN_DISPEN);
	while (!(lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_DISPSTS))
		udelay(1);
	value = lcdc_readl(&regs->lcdc_lcden);
	lcdc_writel(&regs->lcdc_lcden, value | LCDC_LCDEN_PWMEN);
	while (!(lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_PWMSTS))
		udelay(1);
}
static void atmel_hlcdc_init(struct udevice *dev)
{
	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
	struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
	struct atmel_hlcd_regs *regs = priv->regs;
	struct display_timing *timing = &priv->timing;
	struct lcd_dma_desc *desc;
	unsigned long value, vl_clk_pol;
	int ret;

	/* Disable DISP signal */
	writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable synchronization */
	writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable pixel clock */
	writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable PWM */
	writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);

	/* Set pixel clock */
	value = priv->clk_rate / timing->pixelclock.typ;
	if (priv->clk_rate % timing->pixelclock.typ)
		value++;

	vl_clk_pol = 0;
	if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
		vl_clk_pol = LCDC_LCDCFG0_CLKPOL;

	if (value < 1) {
		/* Using system clock as pixel clock */
		writel(LCDC_LCDCFG0_CLKDIV(0)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| vl_clk_pol
			| LCDC_LCDCFG0_CLKSEL,
			&regs->lcdc_lcdcfg0);

	} else {
		writel(LCDC_LCDCFG0_CLKDIV(value - 2)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| vl_clk_pol,
			&regs->lcdc_lcdcfg0);
	}

	/* Initialize control register 5 */
	value = 0;

	if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH))
		value |= LCDC_LCDCFG5_HSPOL;
	if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH))
		value |= LCDC_LCDCFG5_VSPOL;

	switch (priv->output_mode) {
	case 12:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
		break;
	case 16:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
		break;
	case 18:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
		break;
	case 24:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
		break;
	default:
		BUG();
		break;
	}

	value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time);
	value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
	writel(value, &regs->lcdc_lcdcfg5);

	/* Vertical & Horizontal Timing */
	value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1);
	value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1);
	writel(value, &regs->lcdc_lcdcfg1);

	value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ);
	value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1);
	writel(value, &regs->lcdc_lcdcfg2);

	value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1);
	value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1);
	writel(value, &regs->lcdc_lcdcfg3);

	/* Display size */
	value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1);
	value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1);
	writel(value, &regs->lcdc_lcdcfg4);

	writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
	       &regs->lcdc_basecfg0);

	switch (VNBITS(priv->vl_bpix)) {
	case 16:
		writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
		       &regs->lcdc_basecfg1);
		break;
	case 32:
		writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
		       &regs->lcdc_basecfg1);
		break;
	default:
		BUG();
		break;
	}

	writel(LCDC_BASECFG2_XSTRIDE(0), &regs->lcdc_basecfg2);
	writel(0, &regs->lcdc_basecfg3);
	writel(LCDC_BASECFG4_DMA, &regs->lcdc_basecfg4);

	/* Disable all interrupts */
	writel(~0UL, &regs->lcdc_lcdidr);
	writel(~0UL, &regs->lcdc_baseidr);

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
	if (!desc)
		return;

	desc->address = (u32)uc_plat->base;

	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
	desc->next = (u32)desc;

	/* Flush the DMA descriptor if we enabled dcache */
	flush_dcache_range((u32)desc,
			   ALIGN(((u32)desc + sizeof(*desc)),
			   CONFIG_SYS_CACHELINE_SIZE));

	writel(desc->address, &regs->lcdc_baseaddr);
	writel(desc->control, &regs->lcdc_basectrl);
	writel(desc->next, &regs->lcdc_basenext);
	writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
	       &regs->lcdc_basecher);

	/* Enable LCD */
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
}