/* * enables mainclk (DSS clocks on OMAP4 if any device is enabled. * Returns 0 on success. */ int dss_mainclk_state_enable(void) { int r; struct bus_type *bus = dss_get_bus(); r = bus_for_each_dev(bus, NULL, NULL, dss_check_state_disabled); if (r) { r = dss_mainclk_enable(); if (!r) restore_all_ctx(); return r; } else { /* All devices are disabled/suspended */ return -EAGAIN; } }
int dss_init(struct platform_device *pdev) { int r = 0, dss_irq; u32 rev; struct resource *dss_mem; bool skip_init = false; dss.pdata = pdev->dev.platform_data; dss.pdev = pdev; if (cpu_is_omap44xx()) dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); else dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dss_mem) { WARN_ON(1); r = -ENODEV; goto fail0; } dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; goto fail0; } dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M); dss_mainclk_enable(); #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT /* DISPC_CONTROL */ if (omap_readl(0x48050440) & 1) /* LCD enabled? */ skip_init = true; #endif if (!skip_init) { /* disable LCD and DIGIT output. This seems to fix the synclost * problem that we get, if the bootloader starts the DSS and * the kernel resets it */ omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); /* We need to wait here a bit, otherwise we sometimes start to * get synclost errors, and after that only power cycle will * restore DSS functionality. I have no idea why this happens. * And we have to wait _before_ resetting the DSS, but after * enabling clocks. */ msleep(50); } /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); #ifdef CONFIG_OMAP2_DSS_VENC REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ #endif if (!cpu_is_omap44xx()) r = request_irq(INT_24XX_DSS_IRQ, cpu_is_omap24xx() ? dss_irq_handler_omap2 : dss_irq_handler_omap3, 0, "OMAP DSS", NULL); else { dss_irq = platform_get_irq(pdev, 0); r = request_irq(dss_irq, dss_irq_handler_omap2, 0, "OMAP DSS", NULL); } if (r < 0) { DSSERR("omap2 dss: request_irq failed\n"); goto fail1; } if (cpu_is_omap34xx()) { dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); if (IS_ERR(dss.dpll4_m4_ck)) { DSSERR("Failed to get dpll4_m4_ck\n"); r = PTR_ERR(dss.dpll4_m4_ck); goto fail2; } } dss.dsi1_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.dsi2_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.lcd1_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.lcd2_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss_save_context(); rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M); return 0; fail2: if (!cpu_is_omap44xx()) free_irq(INT_24XX_DSS_IRQ, NULL); fail1: iounmap(dss.base); fail0: return r; }