/*!
 * Function to initialize Asynchronous Display Controller. It also initilizes
 * the ADC System 1 channel. Configure ADC display 0 parallel interface for
 * the panel.
 *
 * @param       fbi     framebuffer information pointer
 */
static void mxcfb_init_panel(struct fb_info *fbi)
{
	int msb;
	int panel_stride;
	struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;

#ifdef CONFIG_FB_MXC_ASYNC_PANEL_IFC_16_BIT
	uint32_t pix_fmt = IPU_PIX_FMT_RGB666;
	ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
		IPU_ADC_BURST_WCS,
		IPU_ADC_IFC_MODE_SYS80_TYPE2,
		16, 0, 0, IPU_ADC_SER_NO_RW
	};
	mxc_fbi->disp_num = DISP0;
#elif defined(CONFIG_FB_MXC_ASYNC_PANEL_IFC_8_BIT)
	uint32_t pix_fmt = IPU_PIX_FMT_RGB666;
	ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
		IPU_ADC_BURST_WCS,
		IPU_ADC_IFC_MODE_SYS80_TYPE2,
		8, 0, 0, IPU_ADC_SER_NO_RW
	};
	mxc_fbi->disp_num = DISP0;
#endif

#ifdef PARTIAL_REFRESH
	if (ipu_request_irq(IPU_IRQ_ADC_SYS2_EOF, mxcfb_sys2_eof_irq_handler, 0,
			    MXCFB_NAME, fbi) != 0) {
		dev_err(fbi->device, "Error registering SYS2 irq handler.\n");
		return;
	}

	if (ipu_request_irq(IPU_IRQ_ADC_SYS1_EOF, mxcfb_sys1_eof_irq_handler, 0,
			    MXCFB_NAME, fbi) != 0) {
		dev_err(fbi->device, "Error registering SYS1 irq handler.\n");
		return;
	}
	ipu_disable_irq(IPU_IRQ_ADC_SYS1_EOF);
	ipu_disable_irq(IPU_IRQ_ADC_SYS2_EOF);
#endif
	// Init DI interface
	msb = fls(MXCFB_SCREEN_WIDTH);
	if (!(MXCFB_SCREEN_WIDTH & ((1UL << msb) - 1)))
		msb--;		// Already aligned to power 2
	panel_stride = 1UL << msb;
	ipu_adc_init_panel(mxc_fbi->disp_num,
			   MXCFB_SCREEN_WIDTH + MXCFB_SCREEN_LEFT_OFFSET,
			   MXCFB_SCREEN_HEIGHT,
			   pix_fmt, panel_stride, sig, XY, 0, VsyncInternal);

	ipu_adc_init_ifc_timing(mxc_fbi->disp_num, true,
				190, 17, 104, 190, 5000000);
	ipu_adc_init_ifc_timing(mxc_fbi->disp_num, false, 90, 10, 60, 0, 0);

	_init_panel(mxc_fbi->disp_num);

	init_channel_template(mxc_fbi->disp_num);
}
static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
			 unsigned int cmd, unsigned long arg)
{
	int ret = 0;

	switch (cmd) {

	case IPU_INIT_CHANNEL:
		{
			ipu_channel_parm parm;
			if (copy_from_user
			    (&parm, (ipu_channel_parm *) arg,
			     sizeof(ipu_channel_parm))) {
				return -EFAULT;
			}
			if (!parm.flag) {
				ret =
				    ipu_init_channel(parm.channel,
						     &parm.params);
			} else {
				ret = ipu_init_channel(parm.channel, NULL);
			}
		}
		break;

	case IPU_UNINIT_CHANNEL:
		{
			ipu_channel_t ch;
			int __user *argp = (void __user *)arg;
			if (get_user(ch, argp))
				return -EFAULT;
			ipu_uninit_channel(ch);
		}
		break;

	case IPU_INIT_CHANNEL_BUFFER:
		{
			ipu_channel_buf_parm parm;
			if (copy_from_user
			    (&parm, (ipu_channel_buf_parm *) arg,
			     sizeof(ipu_channel_buf_parm))) {
				return -EFAULT;
			}
			ret =
			    ipu_init_channel_buffer(parm.channel, parm.type,
						    parm.pixel_fmt,
						    parm.width, parm.height,
						    parm.stride,
						    parm.rot_mode,
						    parm.phyaddr_0,
						    parm.phyaddr_1,
						    parm.u_offset,
						    parm.v_offset);

		}
		break;

	case IPU_UPDATE_CHANNEL_BUFFER:
		{
			ipu_channel_buf_parm parm;
			if (copy_from_user
			    (&parm, (ipu_channel_buf_parm *) arg,
			     sizeof(ipu_channel_buf_parm))) {
				return -EFAULT;
			}
			if ((parm.phyaddr_0 != (dma_addr_t) NULL)
			    && (parm.phyaddr_1 == (dma_addr_t) NULL)) {
				ret =
				    ipu_update_channel_buffer(parm.channel,
							      parm.type,
							      parm.bufNum,
							      parm.phyaddr_0);
			} else if ((parm.phyaddr_0 == (dma_addr_t) NULL)
				   && (parm.phyaddr_1 != (dma_addr_t) NULL)) {
				ret =
				    ipu_update_channel_buffer(parm.channel,
							      parm.type,
							      parm.bufNum,
							      parm.phyaddr_1);
			} else {
				ret = -1;
			}

		}
		break;
	case IPU_SELECT_CHANNEL_BUFFER:
		{
			ipu_channel_buf_parm parm;
			if (copy_from_user
			    (&parm, (ipu_channel_buf_parm *) arg,
			     sizeof(ipu_channel_buf_parm))) {
				return -EFAULT;
			}
			ret =
			    ipu_select_buffer(parm.channel, parm.type,
					      parm.bufNum);

		}
		break;
	case IPU_LINK_CHANNELS:
		{
			ipu_channel_link link;
			if (copy_from_user
			    (&link, (ipu_channel_link *) arg,
			     sizeof(ipu_channel_link))) {
				return -EFAULT;
			}
			ret = ipu_link_channels(link.src_ch, link.dest_ch);

		}
		break;
	case IPU_UNLINK_CHANNELS:
		{
			ipu_channel_link link;
			if (copy_from_user
			    (&link, (ipu_channel_link *) arg,
			     sizeof(ipu_channel_link))) {
				return -EFAULT;
			}
			ret = ipu_unlink_channels(link.src_ch, link.dest_ch);

		}
		break;
	case IPU_ENABLE_CHANNEL:
		{
			ipu_channel_t ch;
			int __user *argp = (void __user *)arg;
			if (get_user(ch, argp))
				return -EFAULT;
			ipu_enable_channel(ch);
		}
		break;
	case IPU_DISABLE_CHANNEL:
		{
			ipu_channel_info info;
			if (copy_from_user
			    (&info, (ipu_channel_info *) arg,
			     sizeof(ipu_channel_info))) {
				return -EFAULT;
			}
			ret = ipu_disable_channel(info.channel, info.stop);
		}
		break;
	case IPU_ENABLE_IRQ:
		{
			uint32_t irq;
			int __user *argp = (void __user *)arg;
			if (get_user(irq, argp))
				return -EFAULT;
			ipu_enable_irq(irq);
		}
		break;
	case IPU_DISABLE_IRQ:
		{
			uint32_t irq;
			int __user *argp = (void __user *)arg;
			if (get_user(irq, argp))
				return -EFAULT;
			ipu_disable_irq(irq);
		}
		break;
	case IPU_CLEAR_IRQ:
		{
			uint32_t irq;
			int __user *argp = (void __user *)arg;
			if (get_user(irq, argp))
				return -EFAULT;
			ipu_clear_irq(irq);
		}
		break;
	case IPU_FREE_IRQ:
		{
			ipu_irq_info info;
			if (copy_from_user
			    (&info, (ipu_irq_info *) arg,
			     sizeof(ipu_irq_info))) {
				return -EFAULT;
			}
			ipu_free_irq(info.irq, info.dev_id);
		}
		break;
	case IPU_REQUEST_IRQ_STATUS:
		{
			uint32_t irq;
			int __user *argp = (void __user *)arg;
			if (get_user(irq, argp))
				return -EFAULT;
			ret = ipu_get_irq_status(irq);
		}
		break;
	case IPU_SDC_INIT_PANEL:
		{
			ipu_sdc_panel_info sinfo;
			if (copy_from_user
			    (&sinfo, (ipu_sdc_panel_info *) arg,
			     sizeof(ipu_sdc_panel_info))) {
				return -EFAULT;
			}
			ret =
			    ipu_sdc_init_panel(sinfo.panel, sinfo.pixel_clk,
					       sinfo.width, sinfo.height,
					       sinfo.pixel_fmt,
					       sinfo.hStartWidth,
					       sinfo.hSyncWidth,
					       sinfo.hEndWidth,
					       sinfo.vStartWidth,
					       sinfo.vSyncWidth,
					       sinfo.vEndWidth, sinfo.signal);
		}
		break;
	case IPU_SDC_SET_WIN_POS:
		{
			ipu_sdc_window_pos pos;
			if (copy_from_user
			    (&pos, (ipu_sdc_window_pos *) arg,
			     sizeof(ipu_sdc_window_pos))) {
				return -EFAULT;
			}
			ret =
			    ipu_sdc_set_window_pos(pos.channel, pos.x_pos,
						   pos.y_pos);

		}
		break;
	case IPU_SDC_SET_GLOBAL_ALPHA:
		{
			ipu_sdc_global_alpha g;
			if (copy_from_user
			    (&g, (ipu_sdc_global_alpha *) arg,
			     sizeof(ipu_sdc_global_alpha))) {
				return -EFAULT;
			}
			ret = ipu_sdc_set_global_alpha(g.enable, g.alpha);
		}
		break;
	case IPU_SDC_SET_COLOR_KEY:
		{
			ipu_sdc_color_key c;
			if (copy_from_user
			    (&c, (ipu_sdc_color_key *) arg,
			     sizeof(ipu_sdc_color_key))) {
				return -EFAULT;
			}
			ret =
			    ipu_sdc_set_color_key(c.channel, c.enable,
						  c.colorKey);
		}
		break;
	case IPU_SDC_SET_BRIGHTNESS:
		{
			uint8_t b;
			int __user *argp = (void __user *)arg;
			if (get_user(b, argp))
				return -EFAULT;
			ret = ipu_sdc_set_brightness(b);

		}
		break;
	case IPU_REGISTER_GENERIC_ISR:
		{
			ipu_event_info info;
			if (copy_from_user
			    (&info, (ipu_event_info *) arg,
			     sizeof(ipu_event_info))) {
				return -EFAULT;
			}
			ret =
			    ipu_request_irq(info.irq, mxc_ipu_generic_handler,
					    0, "video_sink", info.dev);
		}
		break;
	case IPU_GET_EVENT:
		/* User will have to allocate event_type structure and pass the pointer in arg */
		{
			event_type ev;
			int r = -1;
			r = get_events(&ev);
			if (r == -1) {
				wait_event_interruptible(waitq,
							 (pending_events != 0));
				r = get_events(&ev);
			}
			ret = -1;
			if (r == 0) {
				if (!copy_to_user((event_type *) arg, &ev,
						  sizeof(event_type))) {
					ret = 0;
				}
			}
		}
		break;
	case IPU_ADC_WRITE_TEMPLATE:
		{
			ipu_adc_template temp;
			if (copy_from_user
			    (&temp, (ipu_adc_template *) arg, sizeof(temp))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_write_template(temp.disp, temp.pCmd,
						   temp.write);
		}
		break;
	case IPU_ADC_UPDATE:
		{
			ipu_adc_update update;
			if (copy_from_user
			    (&update, (ipu_adc_update *) arg, sizeof(update))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_set_update_mode(update.channel, update.mode,
						    update.refresh_rate,
						    update.addr, update.size);
		}
		break;
	case IPU_ADC_SNOOP:
		{
			ipu_adc_snoop snoop;
			if (copy_from_user
			    (&snoop, (ipu_adc_snoop *) arg, sizeof(snoop))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_get_snooping_status(snoop.statl,
							snoop.stath);
		}
		break;
	case IPU_ADC_CMD:
		{
			ipu_adc_cmd cmd;
			if (copy_from_user
			    (&cmd, (ipu_adc_cmd *) arg, sizeof(cmd))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_write_cmd(cmd.disp, cmd.type, cmd.cmd,
					      cmd.params, cmd.numParams);
		}
		break;
	case IPU_ADC_INIT_PANEL:
		{
			ipu_adc_panel panel;
			if (copy_from_user
			    (&panel, (ipu_adc_panel *) arg, sizeof(panel))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_init_panel(panel.disp, panel.width,
					       panel.height, panel.pixel_fmt,
					       panel.stride, panel.signal,
					       panel.addr, panel.vsync_width,
					       panel.mode);
		}
		break;
	case IPU_ADC_IFC_TIMING:
		{
			ipu_adc_ifc_timing t;
			if (copy_from_user
			    (&t, (ipu_adc_ifc_timing *) arg, sizeof(t))) {
				return -EFAULT;
			}
			ret =
			    ipu_adc_init_ifc_timing(t.disp, t.read,
						    t.cycle_time, t.up_time,
						    t.down_time,
						    t.read_latch_time,
						    t.pixel_clk);
		}
		break;
	case IPU_CSI_INIT_INTERFACE:
		{
			ipu_csi_interface c;
			if (copy_from_user
			    (&c, (ipu_csi_interface *) arg, sizeof(c)))
				return -EFAULT;
			ret =
			    ipu_csi_init_interface(c.width, c.height,
						   c.pixel_fmt, c.signal);
		}
		break;
	case IPU_CSI_ENABLE_MCLK:
		{
			ipu_csi_mclk m;
			if (copy_from_user(&m, (ipu_csi_mclk *) arg, sizeof(m)))
				return -EFAULT;
			ret = ipu_csi_enable_mclk(m.src, m.flag, m.wait);
		}
		break;
	case IPU_CSI_READ_MCLK_FLAG:
		{
			ret = ipu_csi_read_mclk_flag();
		}
		break;
	case IPU_CSI_FLASH_STROBE:
		{
			bool strobe;
			int __user *argp = (void __user *)arg;
			if (get_user(strobe, argp))
				return -EFAULT;
			ipu_csi_flash_strobe(strobe);
		}
		break;
	case IPU_CSI_GET_WIN_SIZE:
		{
			ipu_csi_window_size w;
			ipu_csi_get_window_size(&w.width, &w.height);
			if (copy_to_user
			    ((ipu_csi_window_size *) arg, &w, sizeof(w)))
				return -EFAULT;
		}
		break;
	case IPU_CSI_SET_WIN_SIZE:
		{
			ipu_csi_window_size w;
			if (copy_from_user
			    (&w, (ipu_csi_window_size *) arg, sizeof(w)))
				return -EFAULT;
			ipu_csi_set_window_size(w.width, w.height);
		}
		break;
	case IPU_CSI_SET_WINDOW:
		{
			ipu_csi_window p;
			if (copy_from_user
			    (&p, (ipu_csi_window *) arg, sizeof(p)))
				return -EFAULT;
			ipu_csi_set_window_pos(p.left, p.top);
		}
		break;
	case IPU_PF_SET_PAUSE_ROW:
		{
			uint32_t p;
			int __user *argp = (void __user *)arg;
			if (get_user(p, argp))
				return -EFAULT;
			ret = ipu_pf_set_pause_row(p);
		}
		break;
	default:
		break;

	}
	return ret;
}
Beispiel #3
0
bool bs_hw_init(void)
{

	bool result = true;
	bsaddr = ioremap(0x10000000, 4);

	//printk(KERN_ALERT "hello broadsheet!\n");

//reset broadsheet

	// GPC7  EINK_3.3V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 28);
		__raw_writel(gpcon | (0x1 << 28), S3C64XX_GPCCON);		
	//GPC7 EINK_3.3V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<7));
		__raw_writel(gpdata,S3C64XX_GPCDAT);

	//GPC6 EINK_1.8V_EN config output
		gpcon = __raw_readl(S3C64XX_GPCCON);
		gpcon = gpcon & ~(0xF << 24);
		__raw_writel(gpcon | (0x1 << 24), S3C64XX_GPCCON);
	
	//GPC6 EINK_1.8V_EN set low
		gpdata = __raw_readl(S3C64XX_GPCDAT);
		gpdata =(gpdata & ~(1<<6));
		__raw_writel(gpdata,S3C64XX_GPCDAT);
	
	//GPP2 OSC_EN config output
		gpcon = __raw_readl(S3C64XX_GPPCON);
		gpcon  = (gpcon & ~(3<<4));
		 __raw_writel(gpcon|(0x1<<4), S3C64XX_GPPCON);
	//GPP2 OSC_EN set high
		gpdata = __raw_readl(S3C64XX_GPPDAT);
		gpdata =(gpdata & ~(1<<2));
		__raw_writel(gpdata|(0x1<<2),S3C64XX_GPPDAT);
		mdelay(10);

	//GPP9 HnRST config output
	gpcon = __raw_readl(S3C64XX_GPPCON);
	gpcon  = (gpcon & ~(3<<18));
	__raw_writel(gpcon|(0x1<<18), S3C64XX_GPPCON);
	
      HIGH_RESET_PIN;
	mdelay(10);
      LOW_RESET_PIN;
      mdelay(100); 
      HIGH_RESET_PIN;


//setup HD/C signalconfig
	gpcon = __raw_readl(S3C64XX_GPOCON);
	gpcon =(gpcon & ~(3<<4));
	__raw_writel(gpcon|(0x1<<4),S3C64XX_GPOCON);

	gpdata = __raw_readl(S3C64XX_GPODAT);
        gpdata =(gpdata & ~(1<<2));
        __raw_writel(gpdata|(0x1<<2),S3C64XX_GPODAT);

	//GPO3 HIRQ config input
		gpcon = __raw_readl(S3C64XX_GPOCON);
		gpcon  = (gpcon & ~(3<<6));
		__raw_writel(gpcon, S3C64XX_GPOCON);

//now HRDY  setup to input
	gpcon = __raw_readl(S3C64XX_GPOCON);
        gpcon  = (gpcon & ~(3<<8));
        __raw_writel(gpcon, S3C64XX_GPOCON);


	sromdata = __raw_readl(S3C64XX_VA_SROMC);
        sromdata &=~(0xF<<0);
        sromdata |= (1<<3) | (1<<2) | (1<<0);
        __raw_writel(sromdata, S3C64XX_VA_SROMC);
		
	//SROM_BC0 config
		//__raw_writel((0x1<<28)|(0xf<<24)|(0x1c<<16)|(0x1<<12)|(0x6<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);
    __raw_writel((0x0<<28)|(0x0<<24)|(0xA<<16)|(0x1<<12)|(0x0<<8)|(0x2<<4)|(0x0<<0), S3C64XX_VA_SROMC+4);

	//printk(KERN_ALERT "Product id is %x\n",__raw_readw(bsaddr));
	//printk(KERN_ALERT "The new bs driver\n");
#ifdef MXC31
	for(i=0;i<100;i++)
	{
	mdelay(500);
	__raw_writew(0xffff,bsaddr);
	//printk(KERN_ALERT "write the %dth times data\n",i);
	}
#endif

#ifdef USE_BS_IRQ
    int  rqstatus;
#endif
#ifdef MXC31
    ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
            IPU_ADC_BURST_WCS,
            IPU_ADC_IFC_MODE_SYS80_TYPE2,
            16, 0, 0, IPU_ADC_SER_NO_RW
    };

    // Init DI interface
    if ( IS_NELL() || IS_MARIO() || IS_ADS() )
    {
        broadsheet_screen_height = BROADSHEET_SCREEN_HEIGHT_NELL;
        broadsheet_screen_width  = BROADSHEET_SCREEN_WIDTH_NELL;

        broadsheet_screen_size   = BROADSHEET_SCREEN_SIZE_NELL;
    }

    ipu_adc_init_panel(BROADSHEET_DISPLAY_NUMBER,
                       broadsheet_screen_width,
                       broadsheet_screen_height,
                       BROADSHEET_PIXEL_FORMAT, broadsheet_screen_size, sig, XY, 0, VsyncInternal);

    // Set IPU timing for read cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, true,
                            BROADSHEET_READ_CYCLE_TIME,
                            BROADSHEET_READ_UP_TIME,
                            BROADSHEET_READ_DOWN_TIME,
                            BROADSHEET_READ_LATCH_TIME,
                            BROADSHEET_PIXEL_CLK);
    // Set IPU timing for write cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, false,
                            BROADSHEET_WRITE_CYCLE_TIME,
                            BROADSHEET_WRITE_UP_TIME,
                            BROADSHEET_WRITE_DOWN_TIME,
                            0, 0);

    ipu_adc_set_update_mode(ADC_SYS1, IPU_ADC_REFRESH_NONE, 0, 0, 0);

    gpio_lcd_active();
    slcd_gpio_config();

#ifdef CONFIG_MACH_MX31ADS
    // Reset the level translator for the two GPIO inputs (HIRQ and HRDY)
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
#endif

#ifdef USE_BS_IRQ
    // Set up IRQ for for Broadsheet HIRQ line
    disable_irq(BROADSHEET_HIRQ_IRQ);
    set_irq_type(BROADSHEET_HIRQ_IRQ, IRQF_TRIGGER_RISING);
    rqstatus = request_irq(BROADSHEET_HIRQ_IRQ, (irq_handler_t) bs_irq_handler, 0, "eink_fb_hal_broads", NULL);
    if (rqstatus != 0) {
        einkfb_print_crit("Failed IRQ request for Broadsheet HIRQ line; request status = %d\n", rqstatus);
        result = false;
    }
#endif

     // Set up GPIO pins
    if (mxc_request_gpio(BROADSHEET_HIRQ_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HIRQ\n");
        result = false;
    }
    else {
        // Set HIRQ pin as input
        mxc_set_gpio_direction(BROADSHEET_HIRQ_LINE, 1);
    }
    if (mxc_request_gpio(BROADSHEET_HRDY_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HRDY\n");
        result = false;
    }
    else {
        // Set HRDY pin as input
        mxc_set_gpio_direction(BROADSHEET_HRDY_LINE, 1);
    }
#ifdef CONFIG_MACH_MARIO_MX
    if (mxc_request_gpio(BROADSHEET_RST_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for RST\n");
        result = false;
    }
    else {
        // Set RST pin as output and initialize to zero (it's active LOW)
        mxc_set_gpio_direction(BROADSHEET_RST_LINE, 0);
        mxc_set_gpio_dataout(BROADSHEET_RST_LINE, 0);
    }
#endif

#ifdef CONFIG_MACH_MX31ADS
    // Enable the level translator for the two GPIO inputs (HIRQ and HRDY)
    mdelay(100);    // Pause 100 ms to allow level translator to settle
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
#endif
    // Reset Broadsheet
    einkfb_debug("Sending RST signal to Broadsheet...\n");
    LOW_RESET_PIN;	//WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_RESET_VAL);     // Assert RST
    mdelay(100);    // Pause 100 ms during reset
    HIGH_RESET_PIN;
 //WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_NON_RESET_VAL); // Clear RST
    mdelay(400);    // Pause 400 ms to allow Broasheet time to come up
    einkfb_debug("Broadsheet reset done.\n");
//#ifdef TEST_BROADSHEET
//    test_broadsheet(disp);
//#endif
#endif
#ifdef USE_BS_IRQ
    // Set up Broadsheet for interrupt generation (enable all conditions)
    bs_cmd_wr_reg(BS_INTR_CTL_REG, BS_ALL_IRQS);
    bs_cmd_wr_reg(BS_INTR_RAW_STATUS_REG, BS_ALL_IRQS);

    // Enable all Broadsheet display engine interrupts
    bs_cmd_wr_reg(BS_DE_INTR_ENABLE_REG, BS_DE_ALL_IRQS);
    bs_cmd_wr_reg(BS_DE_INTR_RAW_STATUS_REG, BS_DE_ALL_IRQS);
#endif
    //ipu_adc_write_cmd(CMD,0x11);
    //ipu_adc_write_cmd(DAT,0x030a);
    //ipu_adc_write_cmd(DAT,0x0123);

/*
    	ipu_adc_write_cmd(CMD,0x10);
        __raw_writew(0x02,bsaddr);

        udelay(1);

        printk(KERN_ALERT "Product id re-get is %x\n",__raw_readw(bsaddr));
        //printk(KERN_ALERT "The new bs driver\n");
*/

#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT)  || defined(CONFIG_HW_EP1_DVT)  || defined(CONFIG_HW_EP2_DVT)			
    u16 rd_reg;
    unsigned short value = 0;	
    rd_reg = bs_cmd_rd_reg(0x00a) & ~(1 << 12);
    bs_cmd_wr_reg(0x00a, (value | (1 << 12)));		//REG[000Ah] bit 12 = 1b

 //Henry Li 0927 fro saving time in resume 	
    mdelay(4);
    
    bs_cmd_init_sys_run();
    udelay(EPD_CMD_DELAY);
    rd_reg=0;
    while(!value)
	{
		value = GET_HRDY_STATUS;
   	       udelay(50);
		rd_reg++;
		if (rd_reg > 60000)
			break;
	}
    //rd_reg = bs_cmd_rd_reg(0x0204) | (1 << 7);  // spi flash control reg: Display Engine access mode is selected.
       rd_reg = 0x99;
    bs_cmd_wr_reg(0x0204, rd_reg);
/* //Henry Li 0927 fro saving time in resume 	
    udelay(EPD_CMD_DELAY);
    printk("reg[0x0204] is 0x%x\n", rd_reg);
*/    
#endif	
/* //Henry Li 0927 fro saving time in resume 	
    ipu_adc_write_cmd(CMD,0x10);
    ipu_adc_write_cmd(DAT,0x02);
    printk(KERN_ALERT "register 0x0002 content is 0x%4x\n",ipu_adc_read_data());
*/
     einkfb_debug("GPIOs and IRQ set; Broadsheet has been reset\n");
#if defined(CONFIG_HW_EP3_DVT) || defined(CONFIG_HW_EP4_DVT) 
/* //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
*/    
    bs_cmd_wr_reg(0x300, BS97_INIT_VSIZE);	//Frame Data Length Register
    											//Henry: as instruction code init it as 825
/* //Henry Li 0927 fro saving time in resume 	
    mdelay(1);
*/    
#endif
    return ( result );
}
Beispiel #4
0
/*!
 * Function to initialize Asynchronous Display Controller. It also initilizes
 * the ADC System 1 channel. Configure ADC display 0 parallel interface for
 * the panel.
 *
 * @param       fbi     framebuffer information pointer
 */
static void mxcfb_init_panel(struct fb_info *fbi)
{
	int msb;
	int panel_stride;
	ipu_channel_params_t params;
	struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;

#ifdef CONFIG_FB_MXC_ASYNC_PANEL_IFC_16_BIT
	uint32_t pix_fmt = IPU_PIX_FMT_RGB565;
	ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
		IPU_ADC_BURST_WCS,
		IPU_ADC_IFC_MODE_SYS80_TYPE2,
		16, 0, 0, IPU_ADC_SER_NO_RW
	};
	mxc_fbi->disp_num = DISP0;
#elif defined(CONFIG_FB_MXC_ASYNC_PANEL_IFC_8_BIT)
	uint32_t pix_fmt = IPU_PIX_FMT_RGB666;
	ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
		IPU_ADC_BURST_WCS,
		IPU_ADC_IFC_MODE_SYS80_TYPE2,
		8, 0, 0, IPU_ADC_SER_NO_RW
	};
	mxc_fbi->disp_num = DISP0;
#else
	uint32_t pix_fmt = IPU_PIX_FMT_RGB565;
	ipu_adc_sig_cfg_t sig = { 0, 1, 0, 0, 0, 0, 0, 0,
		IPU_ADC_BURST_SERIAL,
		IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
		16, 0, 0, IPU_ADC_SER_NO_RW
	};
	fbi->disp_num = DISP1;
#endif

#ifdef PARTIAL_REFRESH
	if (ipu_request_irq(IPU_IRQ_ADC_SYS2_EOF, mxcfb_sys2_eof_irq_handler, 0,
			    MXCFB_NAME, fbi) != 0) {
		dev_err(fbi->device, "Error registering SYS2 irq handler.\n");
		return;
	}

	if (ipu_request_irq(IPU_IRQ_ADC_SYS1_EOF, mxcfb_sys1_eof_irq_handler, 0,
			    MXCFB_NAME, fbi) != 0) {
		dev_err(fbi->device, "Error registering SYS1 irq handler.\n");
		return;
	}
	ipu_disable_irq(IPU_IRQ_ADC_SYS1_EOF);
	ipu_disable_irq(IPU_IRQ_ADC_SYS2_EOF);
#endif
	/* Init DI interface */
	msb = fls(MXCFB_SCREEN_WIDTH);
	if (!(MXCFB_SCREEN_WIDTH & ((1UL << msb) - 1)))
		msb--;	/* Already aligned to power 2 */
	panel_stride = 1UL << msb;
	ipu_adc_init_panel(mxc_fbi->disp_num,
			   MXCFB_SCREEN_WIDTH + MXCFB_SCREEN_LEFT_OFFSET,
			   MXCFB_SCREEN_HEIGHT,
			   pix_fmt, panel_stride, sig, XY, 0, VsyncInternal);

	ipu_adc_init_ifc_timing(mxc_fbi->disp_num, true,
				190, 17, 104, 190, 5000000);
	ipu_adc_init_ifc_timing(mxc_fbi->disp_num, false, 123, 17, 68, 0, 0);

	/* Needed to turn on ADC clock for panel init */
	memset(&params, 0, sizeof(params));
	params.adc_sys1.disp = mxc_fbi->disp_num;
	params.adc_sys1.ch_mode = WriteTemplateNonSeq;
	params.adc_sys1.out_left = MXCFB_SCREEN_LEFT_OFFSET;
	params.adc_sys1.out_top = MXCFB_SCREEN_TOP_OFFSET;
	ipu_init_channel(ADC_SYS1, &params);

	_init_panel(mxc_fbi->disp_num);
	init_channel_template(mxc_fbi->disp_num);
}
Beispiel #5
0
bool bs_hw_init(void)
{
    bool result = true;
#ifdef USE_BS_IRQ
    int  rqstatus;
#endif
    
    ipu_adc_sig_cfg_t sig = { 0, 0, 0, 0, 0, 0, 0, 0,
            IPU_ADC_BURST_WCS,
            IPU_ADC_IFC_MODE_SYS80_TYPE2,
            16, 0, 0, IPU_ADC_SER_NO_RW
    };

    // Init DI interface
    if ( IS_NELL() || IS_MARIO() || IS_ADS() )
    {
        broadsheet_screen_height = BROADSHEET_SCREEN_HEIGHT_NELL;
        broadsheet_screen_width  = BROADSHEET_SCREEN_WIDTH_NELL;
        
        broadsheet_screen_size   = BROADSHEET_SCREEN_SIZE_NELL;
    }

    ipu_adc_init_panel(BROADSHEET_DISPLAY_NUMBER,
                       broadsheet_screen_width,
                       broadsheet_screen_height,
                       BROADSHEET_PIXEL_FORMAT, broadsheet_screen_size, sig, XY, 0, VsyncInternal);

    // Set IPU timing for read cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, true,
                            BROADSHEET_READ_CYCLE_TIME,
                            BROADSHEET_READ_UP_TIME,
                            BROADSHEET_READ_DOWN_TIME,
                            BROADSHEET_READ_LATCH_TIME,
                            BROADSHEET_PIXEL_CLK);
    // Set IPU timing for write cycles
    ipu_adc_init_ifc_timing(BROADSHEET_DISPLAY_NUMBER, false,
                            BROADSHEET_WRITE_CYCLE_TIME,
                            BROADSHEET_WRITE_UP_TIME,
                            BROADSHEET_WRITE_DOWN_TIME,
                            0, 0);

    ipu_adc_set_update_mode(ADC_SYS1, IPU_ADC_REFRESH_NONE, 0, 0, 0);

    gpio_lcd_active();
    slcd_gpio_config();

#ifdef CONFIG_MACH_MX31ADS
    // Reset the level translator for the two GPIO inputs (HIRQ and HRDY)
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
#endif

#ifdef USE_BS_IRQ
    // Set up IRQ for for Broadsheet HIRQ line
    disable_irq(BROADSHEET_HIRQ_IRQ);
    set_irq_type(BROADSHEET_HIRQ_IRQ, IRQF_TRIGGER_RISING);
    rqstatus = request_irq(BROADSHEET_HIRQ_IRQ, (irq_handler_t) bs_irq_handler, 0, "eink_fb_hal_broads", NULL);
    if (rqstatus != 0) {
        einkfb_print_crit("Failed IRQ request for Broadsheet HIRQ line; request status = %d\n", rqstatus);
        result = false;
    }
#endif

     // Set up GPIO pins
    if (mxc_request_gpio(BROADSHEET_HIRQ_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HIRQ\n");
        result = false;
    }
    else {
        // Set HIRQ pin as input
        mxc_set_gpio_direction(BROADSHEET_HIRQ_LINE, 1);
    }
    if (mxc_request_gpio(BROADSHEET_HRDY_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for HRDY\n");
        result = false;
    }
    else {
        // Set HRDY pin as input
        mxc_set_gpio_direction(BROADSHEET_HRDY_LINE, 1);
    }
#ifdef CONFIG_MACH_MARIO_MX
    if (mxc_request_gpio(BROADSHEET_RST_LINE)) {
        einkfb_print_crit("Could not obtain GPIO pin for RST\n");
        result = false;
    }
    else {
        // Set RST pin as output and initialize to zero (it's active LOW)
        mxc_set_gpio_direction(BROADSHEET_RST_LINE, 0);
        mxc_set_gpio_dataout(BROADSHEET_RST_LINE, 0);
    }
#endif

#ifdef CONFIG_MACH_MX31ADS
    // Enable the level translator for the two GPIO inputs (HIRQ and HRDY)
    mdelay(100);    // Pause 100 ms to allow level translator to settle
    pin_addr = PBC_BCTRL2_LDCIO_EN;
    __raw_writew(pin_addr, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
#endif

    // Reset Broadsheet
    einkfb_debug("Sending RST signal to Broadsheet...\n");
    WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_RESET_VAL);     // Assert RST
    mdelay(100);    // Pause 100 ms during reset
    WR_GPIO_LINE(BROADSHEET_RST_LINE, BROADSHEET_NON_RESET_VAL); // Clear RST
    mdelay(400);    // Pause 400 ms to allow Broasheet time to come up
    einkfb_debug("Broadsheet reset done.\n");

#ifdef TEST_BROADSHEET
    test_broadsheet(disp);
#endif

#ifdef USE_BS_IRQ
    // Set up Broadsheet for interrupt generation (enable all conditions)
    bs_cmd_wr_reg(BS_INTR_CTL_REG, BS_ALL_IRQS);
    bs_cmd_wr_reg(BS_INTR_RAW_STATUS_REG, BS_ALL_IRQS);

    // Enable all Broadsheet display engine interrupts
    bs_cmd_wr_reg(BS_DE_INTR_ENABLE_REG, BS_DE_ALL_IRQS);
    bs_cmd_wr_reg(BS_DE_INTR_RAW_STATUS_REG, BS_DE_ALL_IRQS);
#endif

    einkfb_debug("GPIOs and IRQ set; Broadsheet has been reset\n");
    
    return ( result );
}