static int sossi_init(struct omapfb_device *fbdev) { u32 l, k; struct clk *dpll_clk; int r; sossi.fbdev = fbdev; sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE); dpll_clk = clk_get(fbdev->dev, "ck_dpll1"); if (IS_ERR(dpll_clk)) { dev_err(fbdev->dev, "can't get dpll1 clock\n"); return PTR_ERR(dpll_clk); } sossi.dpll_khz = clk_get_rate(dpll_clk) / 1000; clk_put(dpll_clk); /* Reset and enable the SoSSI module */ l = omap_readl(MOD_CONF_CTRL_1); l |= CONF_SOSSI_RESET_R; omap_writel(l, MOD_CONF_CTRL_1); l &= ~CONF_SOSSI_RESET_R; omap_writel(l, MOD_CONF_CTRL_1); l |= CONF_MOD_SOSSI_CLK_EN_R; omap_writel(l, MOD_CONF_CTRL_1); omap_writel(omap_readl(ARM_IDLECT2) | (1 << 11), ARM_IDLECT2); omap_writel(omap_readl(ARM_IDLECT1) | (1 << 6), ARM_IDLECT1); l = sossi_read_reg(SOSSI_INIT2_REG); /* Enable and reset the SoSSI block */ l |= (1 << 0) | (1 << 1); sossi_write_reg(SOSSI_INIT2_REG, l); /* Take SoSSI out of reset */ l &= ~(1 << 1); sossi_write_reg(SOSSI_INIT2_REG, l); sossi_write_reg(SOSSI_ID_REG, 0); l = sossi_read_reg(SOSSI_ID_REG); k = sossi_read_reg(SOSSI_ID_REG); if (l != 0x55555555 || k != 0xaaaaaaaa) { dev_err(fbdev->dev, "invalid SoSSI sync pattern: %08x, %08x\n", l, k); return -ENODEV; } if ((r = omap_lcdc_set_dma_callback(sossi_dma_callback, NULL)) < 0) { dev_err(fbdev->dev, "can't get LCDC IRQ\n"); return r; } l = sossi_read_reg(SOSSI_ID_REG); /* Component code */ l = sossi_read_reg(SOSSI_ID_REG); pr_info("omapfb: SoSSI version %d.%d initialized\n", l >> 16, l & 0xffff); l = sossi_read_reg(SOSSI_INIT1_REG); l |= (1 << 19); /* DMA_MODE */ l &= ~(1 << 31); /* REORDERING */ sossi_write_reg(SOSSI_INIT1_REG, l); return 0; }
static int sossi_init(struct omapfb_device *fbdev) { u32 l, k; struct clk *fck; struct clk *dpll1out_ck; int r; sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE); sossi.fbdev = fbdev; spin_lock_init(&sossi.lock); dpll1out_ck = clk_get(fbdev->dev, "ck_dpll1out"); if (IS_ERR(dpll1out_ck)) { dev_err(fbdev->dev, "can't get DPLL1OUT clock\n"); return PTR_ERR(dpll1out_ck); } /* * We need the parent clock rate, which we might divide further * depending on the timing requirements of the controller. See * _set_timings. */ sossi.fck_hz = clk_get_rate(dpll1out_ck); clk_put(dpll1out_ck); fck = clk_get(fbdev->dev, "ck_sossi"); if (IS_ERR(fck)) { dev_err(fbdev->dev, "can't get SoSSI functional clock\n"); return PTR_ERR(fck); } sossi.fck = fck; /* Reset and enable the SoSSI module */ l = omap_readl(MOD_CONF_CTRL_1); l |= CONF_SOSSI_RESET_R; omap_writel(l, MOD_CONF_CTRL_1); l &= ~CONF_SOSSI_RESET_R; omap_writel(l, MOD_CONF_CTRL_1); clk_enable(sossi.fck); l = omap_readl(ARM_IDLECT2); l &= ~(1 << 8); /* DMACK_REQ */ omap_writel(l, ARM_IDLECT2); l = sossi_read_reg(SOSSI_INIT2_REG); /* Enable and reset the SoSSI block */ l |= (1 << 0) | (1 << 1); sossi_write_reg(SOSSI_INIT2_REG, l); /* Take SoSSI out of reset */ l &= ~(1 << 1); sossi_write_reg(SOSSI_INIT2_REG, l); sossi_write_reg(SOSSI_ID_REG, 0); l = sossi_read_reg(SOSSI_ID_REG); k = sossi_read_reg(SOSSI_ID_REG); if (l != 0x55555555 || k != 0xaaaaaaaa) { dev_err(fbdev->dev, "invalid SoSSI sync pattern: %08x, %08x\n", l, k); r = -ENODEV; goto err; } if ((r = omap_lcdc_set_dma_callback(sossi_dma_callback, NULL)) < 0) { dev_err(fbdev->dev, "can't get LCDC IRQ\n"); r = -ENODEV; goto err; } l = sossi_read_reg(SOSSI_ID_REG); /* Component code */ l = sossi_read_reg(SOSSI_ID_REG); dev_info(fbdev->dev, "SoSSI version %d.%d initialized\n", l >> 16, l & 0xffff); l = sossi_read_reg(SOSSI_INIT1_REG); l |= (1 << 19); /* DMA_MODE */ l &= ~(1 << 31); /* REORDERING */ sossi_write_reg(SOSSI_INIT1_REG, l); if ((r = request_irq(INT_1610_SoSSI_MATCH, sossi_match_irq, IRQT_FALLING, "sossi_match", sossi.fbdev->dev)) < 0) { dev_err(sossi.fbdev->dev, "can't get SoSSI match IRQ\n"); goto err; } clk_disable(sossi.fck); return 0; err: clk_disable(sossi.fck); clk_put(sossi.fck); return r; }