static int msm_iommu_probe(struct platform_device *pdev)
{
	struct resource *r, *r2;
	struct clk *iommu_clk = NULL;
	struct clk *iommu_pclk = NULL;
	struct msm_iommu_drvdata *drvdata;
	struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
	void __iomem *regs_base;
	resource_size_t	len;
	int ret, irq, par;

	if (pdev->id == -1) {
		msm_iommu_root_dev = pdev;
		return 0;
	}

	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);

	if (!drvdata) {
		ret = -ENOMEM;
		goto fail;
	}

	if (!iommu_dev) {
		ret = -ENODEV;
		goto fail;
	}

	iommu_pclk = clk_get_sys("msm_iommu", "iface_clk");
	if (IS_ERR(iommu_pclk)) {
		ret = -ENODEV;
		goto fail;
	}

	ret = clk_enable(iommu_pclk);
	if (ret)
		goto fail_enable;

	iommu_clk = clk_get(&pdev->dev, "core_clk");

	if (!IS_ERR(iommu_clk))	{
		if (clk_get_rate(iommu_clk) == 0) {
			ret = clk_round_rate(iommu_clk, 1);
			clk_set_rate(iommu_clk, ret);
		}

		ret = clk_enable(iommu_clk);
		if (ret) {
			clk_put(iommu_clk);
			goto fail_pclk;
		}
	} else
		iommu_clk = NULL;

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase");

	if (!r) {
		ret = -ENODEV;
		goto fail_clk;
	}

	len = resource_size(r);

	r2 = request_mem_region(r->start, len, r->name);
	if (!r2) {
		pr_err("Could not request memory region: start=%p, len=%d\n",
							(void *) r->start, len);
		ret = -EBUSY;
		goto fail_clk;
	}

	regs_base = ioremap(r2->start, len);

	if (!regs_base) {
		pr_err("Could not ioremap: start=%p, len=%d\n",
			 (void *) r2->start, len);
		ret = -EBUSY;
		goto fail_mem;
	}

	irq = platform_get_irq_byname(pdev, "nonsecure_irq");
	if (irq < 0) {
		ret = -ENODEV;
		goto fail_io;
	}

	msm_iommu_reset(regs_base, iommu_dev->ncb);

	SET_M(regs_base, 0, 1);
	SET_PAR(regs_base, 0, 0);
	SET_V2PCFG(regs_base, 0, 1);
	SET_V2PPR(regs_base, 0, 0);
	mb();
	par = GET_PAR(regs_base, 0);
	SET_V2PCFG(regs_base, 0, 0);
	SET_M(regs_base, 0, 0);
	mb();

	if (!par) {
		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
		ret = -ENODEV;
		goto fail_io;
	}

	ret = request_irq(irq, msm_iommu_fault_handler, 0,
			"msm_iommu_secure_irpt_handler", drvdata);
	if (ret) {
		pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
		goto fail_io;
	}


	drvdata->pclk = iommu_pclk;
	drvdata->clk = iommu_clk;
	drvdata->base = regs_base;
	drvdata->irq = irq;
	drvdata->ncb = iommu_dev->ncb;
	drvdata->name = iommu_dev->name;

	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
		iommu_dev->name, regs_base, irq, iommu_dev->ncb);

	platform_set_drvdata(pdev, drvdata);

	if (iommu_clk)
		clk_disable(iommu_clk);

	clk_disable(iommu_pclk);

	return 0;
fail_io:
	iounmap(regs_base);
fail_mem:
	release_mem_region(r->start, len);
fail_clk:
	if (iommu_clk) {
		clk_disable(iommu_clk);
		clk_put(iommu_clk);
	}
fail_pclk:
	clk_disable(iommu_pclk);
fail_enable:
	clk_put(iommu_pclk);
fail:
	kfree(drvdata);
	return ret;
}
long parent_round_rate(struct clk *c, unsigned long rate)
{
	return clk_round_rate(c->parent, rate);
}
int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
		struct clk **clk_ptr, int num_clk, int enable)
{
	int i;
	int rc = 0;
	long clk_rate;
	if (enable) {
		for (i = 0; i < num_clk; i++) {
			CDBG("%s enable %s\n", __func__, clk_info[i].clk_name);
			clk_ptr[i] = clk_get(dev, clk_info[i].clk_name);
			if (IS_ERR(clk_ptr[i])) {
				pr_err("%s get failed\n", clk_info[i].clk_name);
				rc = PTR_ERR(clk_ptr[i]);
				goto cam_clk_get_err;
			}
			if (clk_info[i].clk_rate > 0) {
				clk_rate = clk_round_rate(clk_ptr[i],
					clk_info[i].clk_rate);
				if (clk_rate < 0) {
					pr_err("%s round failed\n",
						   clk_info[i].clk_name);
					goto cam_clk_set_err;
				}
				rc = clk_set_rate(clk_ptr[i],
					clk_rate);
				if (rc < 0) {
					pr_err("%s set failed\n",
						clk_info[i].clk_name);
					goto cam_clk_set_err;
				}

			} else if (clk_info[i].clk_rate == INIT_RATE) {
				clk_rate = clk_get_rate(clk_ptr[i]);
				if (clk_rate == 0) {
					clk_rate =
						  clk_round_rate(clk_ptr[i], 0);
					if (clk_rate < 0) {
						pr_err("%s round rate failed\n",
							  clk_info[i].clk_name);
						goto cam_clk_set_err;
					}
					rc = clk_set_rate(clk_ptr[i],
								clk_rate);
					if (rc < 0) {
						pr_err("%s set rate failed\n",
							  clk_info[i].clk_name);
						goto cam_clk_set_err;
					}
				}
			}
			rc = clk_prepare(clk_ptr[i]);
			if (rc < 0) {
				pr_err("%s prepare failed\n",
					   clk_info[i].clk_name);
				goto cam_clk_prepare_err;
			}

			rc = clk_enable(clk_ptr[i]);
			if (rc < 0) {
				pr_err("%s enable failed\n",
					   clk_info[i].clk_name);
				goto cam_clk_enable_err;
			}
			if (clk_info[i].delay > 20) {
				msleep(clk_info[i].delay);
			} else if (clk_info[i].delay) {
				usleep_range(clk_info[i].delay * 1000,
					(clk_info[i].delay * 1000) + 1000);
			}
		}
	} else {
		for (i = num_clk - 1; i >= 0; i--) {
			if (clk_ptr[i] != NULL) {
				CDBG("%s disable %s\n", __func__,
					clk_info[i].clk_name);
				clk_disable(clk_ptr[i]);
				clk_unprepare(clk_ptr[i]);
				clk_put(clk_ptr[i]);
			}
		}
	}
	return rc;


cam_clk_enable_err:
	clk_unprepare(clk_ptr[i]);
cam_clk_prepare_err:
cam_clk_set_err:
	clk_put(clk_ptr[i]);
cam_clk_get_err:
	for (i--; i >= 0; i--) {
		if (clk_ptr[i] != NULL) {
			clk_disable(clk_ptr[i]);
			clk_unprepare(clk_ptr[i]);
			clk_put(clk_ptr[i]);
		}
	}
	return rc;
}
Esempio n. 4
0
int __init db1200_dev_setup(void)
{
    unsigned long pfc;
    unsigned short sw;
    int swapped, bid;
    struct clk *c;

    bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
    if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
            (bid == BCSR_WHOAMI_PB1200_DDR2)) {
        if (pb1200_res_fixup())
            return -ENODEV;
    }

    /* GPIO7 is low-level triggered CPLD cascade */
    irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW);
    bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);

    /* SMBus/SPI on PSC0, Audio on PSC1 */
    pfc = alchemy_rdsys(AU1000_SYS_PINFUNC);
    pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
    pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
    pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
    alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);

    /* get 50MHz for I2C driver on PSC0 */
    c = clk_get(NULL, "psc0_intclk");
    if (!IS_ERR(c)) {
        pfc = clk_round_rate(c, 50000000);
        if ((pfc < 1) || (abs(50000000 - pfc) > 2500000))
            pr_warn("DB1200: cant get I2C close to 50MHz\n");
        else
            clk_set_rate(c, pfc);
        clk_put(c);
    }

    /* insert/eject pairs: one of both is always screaming.	 To avoid
     * issues they must not be automatically enabled when initially
     * requested.
     */
    irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
    irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
    irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
    irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
    irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
    irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);

    i2c_register_board_info(0, db1200_i2c_devs,
                            ARRAY_SIZE(db1200_i2c_devs));
    spi_register_board_info(db1200_spi_devs,
                            ARRAY_SIZE(db1200_i2c_devs));

    /* SWITCHES:	S6.8 I2C/SPI selector  (OFF=I2C	 ON=SPI)
     *		S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
     *		or S12 on the PB1200.
     */

    /* NOTE: GPIO215 controls OTG VBUS supply.  In SPI mode however
     * this pin is claimed by PSC0 (unused though, but pinmux doesn't
     * allow to free it without crippling the SPI interface).
     * As a result, in SPI mode, OTG simply won't work (PSC0 uses
     * it as an input pin which is pulled high on the boards).
     */
    pfc = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PINFUNC_P0A;

    /* switch off OTG VBUS supply */
    gpio_request(215, "otg-vbus");
    gpio_direction_output(215, 1);

    printk(KERN_INFO "%s device configuration:\n", get_system_type());

    sw = bcsr_read(BCSR_SWITCHES);
    if (sw & BCSR_SWITCHES_DIP_8) {
        db1200_devs[0] = &db1200_i2c_dev;
        bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);

        pfc |= (2 << 17);	/* GPIO2 block owns GPIO215 */

        printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
        printk(KERN_INFO "   OTG port VBUS supply available!\n");
    } else {
        db1200_devs[0] = &db1200_spi_dev;
        bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);

        pfc |= (1 << 17);	/* PSC0 owns GPIO215 */

        printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
        printk(KERN_INFO "   OTG port VBUS supply disabled\n");
    }
    alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);

    /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
     * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
     */
    sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
    if (sw == BCSR_SWITCHES_DIP_8) {
        bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
        db1200_audio_dev.name = "au1xpsc_i2s";
        db1200_sound_dev.name = "db1200-i2s";
        printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
    } else {
        bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
        db1200_audio_dev.name = "au1xpsc_ac97";
        db1200_sound_dev.name = "db1200-ac97";
        printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
    }

    /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
    c = clk_get(NULL, "psc1_intclk");
    if (!IS_ERR(c)) {
        clk_prepare_enable(c);
        clk_put(c);
    }
    __raw_writel(PSC_SEL_CLK_SERCLK,
                 (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
    wmb();

    db1x_register_pcmcia_socket(
        AU1000_PCMCIA_ATTR_PHYS_ADDR,
        AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
        AU1000_PCMCIA_MEM_PHYS_ADDR,
        AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
        AU1000_PCMCIA_IO_PHYS_ADDR,
        AU1000_PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
        DB1200_PC0_INT, DB1200_PC0_INSERT_INT,
        /*DB1200_PC0_STSCHG_INT*/0, DB1200_PC0_EJECT_INT, 0);

    db1x_register_pcmcia_socket(
        AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
        AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
        AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004000000,
        AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
        AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004000000,
        AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
        DB1200_PC1_INT, DB1200_PC1_INSERT_INT,
        /*DB1200_PC1_STSCHG_INT*/0, DB1200_PC1_EJECT_INT, 1);

    swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
    db1x_register_norflash(64 << 20, 2, swapped);

    platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));

    /* PB1200 is a DB1200 with a 2nd MMC and Camera connector */
    if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
            (bid == BCSR_WHOAMI_PB1200_DDR2))
        platform_add_devices(pb1200_devs, ARRAY_SIZE(pb1200_devs));

    return 0;
}
Esempio n. 5
0
static int msm_ehci_init_clocks(struct msm_hcd *mhcd, u32 init)
{
	int ret = 0;

	if (!init)
		goto put_clocks;

	/* iface_clk is required for data transfers */
	mhcd->iface_clk = devm_clk_get(mhcd->dev, "iface_clk");
	if (IS_ERR(mhcd->iface_clk)) {
		ret = PTR_ERR(mhcd->iface_clk);
		mhcd->iface_clk = NULL;
		if (ret != -EPROBE_DEFER)
			dev_err(mhcd->dev, "failed to get iface_clk\n");
		return ret;
	}

	/* Link's protocol engine is based on pclk which must
	 * be running >55Mhz and frequency should also not change.
	 * Hence, vote for maximum clk frequency on its source
	 */
	mhcd->core_clk = devm_clk_get(mhcd->dev, "core_clk");
	if (IS_ERR(mhcd->core_clk)) {
		ret = PTR_ERR(mhcd->core_clk);
		mhcd->core_clk = NULL;
		if (ret != -EPROBE_DEFER)
			dev_err(mhcd->dev, "failed to get core_clk\n");
		return ret;
	}

	/*
	 * Get Max supported clk frequency for USB Core CLK and request
	 * to set the same.
	 */
	mhcd->core_clk_rate = clk_round_rate(mhcd->core_clk, LONG_MAX);
	if (IS_ERR_VALUE(mhcd->core_clk_rate)) {
		ret = mhcd->core_clk_rate;
		dev_err(mhcd->dev, "fail to get core clk max freq\n");
		return ret;
	}

	ret = clk_set_rate(mhcd->core_clk, mhcd->core_clk_rate);
	if (ret) {
		dev_err(mhcd->dev, "fail to set core_clk: %d\n", ret);
		return ret;
	}

	clk_prepare_enable(mhcd->core_clk);
	clk_prepare_enable(mhcd->iface_clk);

	mhcd->phy_sleep_clk = devm_clk_get(mhcd->dev, "sleep_clk");
	if (IS_ERR(mhcd->phy_sleep_clk)) {
		mhcd->phy_sleep_clk = NULL;
		dev_dbg(mhcd->dev, "failed to get sleep_clk\n");
	} else {
		clk_prepare_enable(mhcd->phy_sleep_clk);
	}

	/* 60MHz alt_core_clk is for LINK to be used during PHY RESET  */
	mhcd->alt_core_clk = devm_clk_get(mhcd->dev, "alt_core_clk");
	if (IS_ERR(mhcd->alt_core_clk)) {
		mhcd->alt_core_clk = NULL;
		dev_dbg(mhcd->dev, "failed to get alt_core_clk\n");
	} else {
		clk_set_rate(mhcd->alt_core_clk, 60000000);
	}

	return 0;

put_clocks:
	if (!atomic_read(&mhcd->in_lpm)) {
		clk_disable_unprepare(mhcd->iface_clk);
		clk_disable_unprepare(mhcd->core_clk);
	}
	if (mhcd->phy_sleep_clk)
		clk_disable_unprepare(mhcd->phy_sleep_clk);

	return 0;
}
Esempio n. 6
0
static void enter_lpm_imx6sl(void)
{
	if (high_bus_freq_mode) {
		pll2_org_rate = clk_get_rate(pll2_bus);
		/* Set periph_clk to be sourced from OSC_CLK */
		imx_clk_set_parent(periph_clk2_sel, osc_clk);
		imx_clk_set_parent(periph_clk, periph_clk2);
		/* Ensure AHB/AXI clks are at 24MHz. */
		imx_clk_set_rate(ahb_clk, LPAPM_CLK);
		imx_clk_set_rate(ocram_clk, LPAPM_CLK);
	}
	if (audio_bus_count) {
		/* Set AHB to 8MHz to lower pwer.*/
		imx_clk_set_rate(ahb_clk, LPAPM_CLK / 3);

		/* Set up DDR to 100MHz. */
		update_lpddr2_freq(HIGH_AUDIO_CLK);

		/* Fix the clock tree in kernel */
		imx_clk_set_parent(periph2_pre_clk, pll2_200);
		imx_clk_set_parent(periph2_clk, periph2_pre_clk);

		if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
			/*
			 * Fix the clock tree in kernel, make sure
			 * pll2_bypass is updated as it is
			 * sourced from PLL2.
			 */
			imx_clk_set_parent(pll2_bypass, pll2);
			/*
			 * Swtich ARM to run off PLL2_PFD2_400MHz
			 * since DDR is anyway at 100MHz.
			 */
			imx_clk_set_parent(step_clk, pll2_400);
			imx_clk_set_parent(pll1_sw_clk, step_clk);
			/*
			  * Need to ensure that PLL1 is bypassed and enabled
			  * before ARM-PODF is set.
			  */
			clk_set_parent(pll1_bypass, pll1_bypass_src);

			/*
			 * Ensure that the clock will be
			 * at original speed.
			 */
			imx_clk_set_rate(cpu_clk, org_arm_rate);
		}
		low_bus_freq_mode = 0;
		ultra_low_bus_freq_mode = 0;
		audio_bus_freq_mode = 1;
		cur_bus_freq_mode = BUS_FREQ_AUDIO;
	} else {
		u32 arm_div, pll1_rate;
		org_arm_rate = clk_get_rate(cpu_clk);
		if (low_bus_freq_mode && low_bus_count == 0) {
			/*
			 * We are already in DDR @ 24MHz state, but
			 * no one but ARM needs the DDR. In this case,
			 * we can lower the DDR freq to 1MHz when ARM
			 * enters WFI in this state. Keep track of this state.
			 */
			ultra_low_bus_freq_mode = 1;
			low_bus_freq_mode = 0;
			audio_bus_freq_mode = 0;
			cur_bus_freq_mode = BUS_FREQ_ULTRA_LOW;
		} else {
			if (!ultra_low_bus_freq_mode && !low_bus_freq_mode) {
				/*
				 * Anyway, make sure the AHB is running at 24MHz
				 * in low_bus_freq_mode.
				 */
				if (audio_bus_freq_mode)
					imx_clk_set_rate(ahb_clk, LPAPM_CLK);
				/*
				 * Set DDR to 24MHz.
				 * Since we are going to bypass PLL2,
				 * we need to move ARM clk off PLL2_PFD2
				 * to PLL1. Make sure the PLL1 is running
				 * at the lowest possible freq.
				 * To work well with CPUFREQ we want to ensure that
				 * the CPU freq does not change, so attempt to
				 * get a freq as close to 396MHz as possible.
				 */
				imx_clk_set_rate(pll1,
					clk_round_rate(pll1, (org_arm_rate * 2)));
				pll1_rate = clk_get_rate(pll1);
				arm_div = pll1_rate / org_arm_rate;
				if (pll1_rate / arm_div > org_arm_rate)
					arm_div++;
				/*
				  * Need to ensure that PLL1 is bypassed and enabled
				  * before ARM-PODF is set.
				  */
				clk_set_parent(pll1_bypass, pll1);
				/*
				 * Ensure ARM CLK is lower before
				 * changing the parent.
				 */
				imx_clk_set_rate(cpu_clk, org_arm_rate / arm_div);
				/* Now set the ARM clk parent to PLL1_SYS. */
				imx_clk_set_parent(pll1_sw_clk, pll1_sys);

				/*
				 * Set STEP_CLK back to OSC to save power and
				 * also to maintain the parent.The WFI iram code
				 * will switch step_clk to osc, but the clock API
				 * is not aware of the change and when a new request
				 * to change the step_clk parent to pll2_pfd2_400M
				 * is requested sometime later, the change is ignored.
				 */
				imx_clk_set_parent(step_clk, osc_clk);
				/* Now set DDR to 24MHz. */
				update_lpddr2_freq(LPAPM_CLK);

				/*
				 * Fix the clock tree in kernel.
				 * Make sure PLL2 rate is updated as it gets
				 * bypassed in the DDR freq change code.
				 */
				imx_clk_set_parent(pll2_bypass, pll2_bypass_src);
				imx_clk_set_parent(periph2_clk2_sel, pll2_bus);
				imx_clk_set_parent(periph2_clk, periph2_clk2);
			}
			if (low_bus_count == 0) {
				ultra_low_bus_freq_mode = 1;
				low_bus_freq_mode = 0;
				cur_bus_freq_mode = BUS_FREQ_ULTRA_LOW;
			} else {
				ultra_low_bus_freq_mode = 0;
				low_bus_freq_mode = 1;
				cur_bus_freq_mode = BUS_FREQ_LOW;
			}
			audio_bus_freq_mode = 0;
		}
	}
}
Esempio n. 7
0
static
int omap_bandgap_probe(struct platform_device *pdev)
{
	struct omap_bandgap *bg_ptr;
	int clk_rate, ret = 0, i;

	bg_ptr = omap_bandgap_build(pdev);
	if (IS_ERR_OR_NULL(bg_ptr)) {
		dev_err(&pdev->dev, "failed to fetch platform data\n");
		return PTR_ERR(bg_ptr);
	}
	bg_ptr->dev = &pdev->dev;

	if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
		ret = omap_bandgap_tshut_init(bg_ptr, pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"failed to initialize system tshut IRQ\n");
			return ret;
		}
	}

	bg_ptr->fclock = clk_get(NULL, bg_ptr->conf->fclock_name);
	ret = IS_ERR_OR_NULL(bg_ptr->fclock);
	if (ret) {
		dev_err(&pdev->dev, "failed to request fclock reference\n");
		goto free_irqs;
	}

	bg_ptr->div_clk = clk_get(NULL,  bg_ptr->conf->div_ck_name);
	ret = IS_ERR_OR_NULL(bg_ptr->div_clk);
	if (ret) {
		dev_err(&pdev->dev,
			"failed to request div_ts_ck clock ref\n");
		goto free_irqs;
	}

	bg_ptr->conv_table = bg_ptr->conf->conv_table;
	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		struct temp_sensor_registers *tsr;
		u32 val;

		tsr = bg_ptr->conf->sensors[i].registers;
		/*
		 * check if the efuse has a non-zero value if not
		 * it is an untrimmed sample and the temperatures
		 * may not be accurate
		 */
		val = omap_bandgap_readl(bg_ptr, tsr->bgap_efuse);
		if (ret || !val)
			dev_info(&pdev->dev,
				 "Non-trimmed BGAP, Temp not accurate\n");
	}

	clk_rate = clk_round_rate(bg_ptr->div_clk,
				  bg_ptr->conf->sensors[0].ts_data->max_freq);
	if (clk_rate < bg_ptr->conf->sensors[0].ts_data->min_freq ||
	    clk_rate == 0xffffffff) {
		ret = -ENODEV;
		dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
		goto put_clks;
	}

	ret = clk_set_rate(bg_ptr->div_clk, clk_rate);
	if (ret)
		dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n");

	bg_ptr->clk_rate = clk_rate;
	clk_enable(bg_ptr->fclock);

	mutex_init(&bg_ptr->bg_mutex);
	bg_ptr->dev = &pdev->dev;
	platform_set_drvdata(pdev, bg_ptr);

	omap_bandgap_power(bg_ptr, true);

	/* Set default counter to 1 for now */
	if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
		for (i = 0; i < bg_ptr->conf->sensor_count; i++)
			configure_temp_sensor_counter(bg_ptr, i, 1);

	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		struct temp_sensor_data *ts_data;

		ts_data = bg_ptr->conf->sensors[i].ts_data;

		if (OMAP_BANDGAP_HAS(bg_ptr, TALERT))
			temp_sensor_init_talert_thresholds(bg_ptr, i,
							   ts_data->t_hot,
							   ts_data->t_cold);
		if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) {
			temp_sensor_configure_tshut_hot(bg_ptr, i,
							ts_data->tshut_hot);
			temp_sensor_configure_tshut_cold(bg_ptr, i,
							 ts_data->tshut_cold);
		}
	}

	if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
		enable_continuous_mode(bg_ptr);

	/* Set .250 seconds time as default counter */
	if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
		for (i = 0; i < bg_ptr->conf->sensor_count; i++)
			configure_temp_sensor_counter(bg_ptr, i,
						      bg_ptr->clk_rate / 4);

	/* Every thing is good? Then expose the sensors */
	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		char *domain;

		if (bg_ptr->conf->sensors[i].register_cooling)
			bg_ptr->conf->sensors[i].register_cooling(bg_ptr, i);

		domain = bg_ptr->conf->sensors[i].domain;
		if (bg_ptr->conf->expose_sensor)
			bg_ptr->conf->expose_sensor(bg_ptr, i, domain);
	}

	/*
	 * Enable the Interrupts once everything is set. Otherwise irq handler
	 * might be called as soon as it is enabled where as rest of framework
	 * is still getting initialised.
	 */
	if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
		ret = omap_bandgap_talert_init(bg_ptr, pdev);
		if (ret) {
			dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
			i = bg_ptr->conf->sensor_count;
			goto disable_clk;
		}
	}

	return 0;

disable_clk:
	clk_disable(bg_ptr->fclock);
put_clks:
	clk_put(bg_ptr->fclock);
	clk_put(bg_ptr->div_clk);
free_irqs:
	if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT)) {
		free_irq(gpio_to_irq(bg_ptr->tshut_gpio), NULL);
		gpio_free(bg_ptr->tshut_gpio);
	}

	return ret;
}
Esempio n. 8
0
/**
 * omap_opp_register() - Initialize opp table as per the CPU type
 * @dev: device registering for OPP
 * @hwmod_name: hemod name of registering device
 *
 * Register the given device with the OPP/DVFS framework. Intended to
 * be called when omap_device is built.
 */
int omap_opp_register(struct device *dev, const char *hwmod_name)
{
	int i, r;
	struct clk *clk;
	long round_rate;
	struct omap_opp_def *opp_def = opp_table;
	u32 opp_def_size = opp_table_size;

	if (!opp_def || !opp_def_size) {
		pr_err("%s: invalid params!\n", __func__);
		return -EINVAL;
	}

	if (IS_ERR(dev)) {
		pr_err("%s: Unable to get dev pointer\n", __func__);
		return -EINVAL;
	}


	/* Lets now register with OPP library */
	for (i = 0; i < opp_def_size; i++, opp_def++) {
		if (!opp_def->default_available)
			continue;

		if (!opp_def->dev_info->hwmod_name) {
			WARN_ONCE(1, "%s: NULL name of omap_hwmod, failing [%d].\n",
				  __func__, i);
			return -EINVAL;
		}

		if (!strcmp(hwmod_name, opp_def->dev_info->hwmod_name)) {
			clk = omap_clk_get_by_name(opp_def->dev_info->clk_name);
			if (clk) {
				round_rate = clk_round_rate(clk, opp_def->freq);
				if (round_rate > 0) {
					opp_def->freq = round_rate;
				} else {
				pr_warn("%s: round_rate for clock %s failed\n",
					__func__, opp_def->dev_info->clk_name);
				continue; /* skip Bad OPP */
				}
			} else {
				pr_warn("%s: No clock by name %s found\n",
					__func__, opp_def->dev_info->clk_name);
				continue; /* skip Bad OPP */
			}
			r = opp_add(dev, opp_def->freq, opp_def->u_volt);
			if (r) {
				dev_err(dev,
					"%s: add OPP %ld failed for %s [%d] result=%d\n",
					__func__, opp_def->freq,
				       opp_def->dev_info->hwmod_name, i, r);
				continue;
			}

			r  = omap_dvfs_register_device(dev,
				       opp_def->dev_info->voltdm_name,
				       opp_def->dev_info->clk_name);
			if (r)
				dev_err(dev, "%s:%s:err dvfs register %d %d\n",
					__func__, opp_def->dev_info->hwmod_name,
					r, i);
		}
	}
	return 0;
}
/*!
 * Board specific initialization.
 */
static void __init mx6_sabresd_board_init(void)
{
	int i;
	struct clk *clko, *clko2;
	struct clk *new_parent;
	int rate;

	if (cpu_is_mx6q())
		mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
			ARRAY_SIZE(mx6q_sabresd_pads));
	else if (cpu_is_mx6dl()) {
		mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_pads,
			ARRAY_SIZE(mx6dl_sabresd_pads));
	}

	dsa2lb_init();

#ifdef CONFIG_FEC_1588
	/* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
	 * For MX6 GPR1 bit21 meaning:
	 * Bit21:       0 - GPIO_16 pad output
	 *              1 - GPIO_16 pad input
	 */
	 mxc_iomux_set_gpr_register(1, 21, 1, 1);
#endif

	gp_reg_id = sabresd_dvfscore_data.reg_id;
	soc_reg_id = sabresd_dvfscore_data.soc_id;
	mx6q_sabresd_init_uart();
	imx6x_add_ram_console();

	/*
	 * MX6DL/Solo only supports single IPU
	 * The following codes are used to change ipu id
	 * and display id information for MX6DL/Solo. Then
	 * register 1 IPU device and up to 2 displays for
	 * MX6DL/Solo
	 */
	if (cpu_is_mx6dl()) {
		/* [Walker Chen], 2014/01/08 - modified for dual display mode
			mx6dl only have one ipu
			ipu0:disp0 for HDMI
			ipu0:disp1 for LVDS
		*/
		ldb_data.ipu_id = 0;
		ldb_data.disp_id = 1;
		hdmi_core_data.ipu_id = 0;
		hdmi_core_data.disp_id = 0;
		//mipi_dsi_pdata.ipu_id = 0;
		//mipi_dsi_pdata.disp_id = 1;
		ldb_data.sec_ipu_id = 0;
		ldb_data.sec_disp_id = 0;
	}
	imx6q_add_mxc_hdmi_core(&hdmi_core_data);

	imx6q_add_ipuv3(0, &ipu_data[0]);
	if (cpu_is_mx6q()) {
		imx6q_add_ipuv3(1, &ipu_data[1]);
		for (i = 0; i < 4 && i < ARRAY_SIZE(sabresd_fb_data); i++)
			imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);
	} else
		for (i = 0; i < 2 && i < ARRAY_SIZE(sabresd_fb_data); i++)
			imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);

	imx6q_add_vdoa();
	//imx6q_add_mipi_dsi(&mipi_dsi_pdata);
	imx6q_add_lcdif(&lcdif_data);
	imx6q_add_ldb(&ldb_data);
	imx6q_add_v4l2_output(0);
	//imx6q_add_v4l2_capture(0, &capture_data[0]);
	//imx6q_add_v4l2_capture(1, &capture_data[1]);
	//imx6q_add_imx_snvs_rtc();

	if (1 == caam_enabled)
		imx6q_add_imx_caam();

	strcpy(mxc_i2c0_board_info[0].type, "wm8962");
	mxc_i2c0_board_info[0].platform_data = &wm8962_config_data;
	imx6q_add_device_gpio_leds();

	imx6q_add_imx_i2c(0, &mx6q_sabresd_i2c_data);
	imx6q_add_imx_i2c(1, &mx6q_sabresd_i2c_data);
	imx6q_add_imx_i2c(2, &mx6q_sabresd_i2c_data);
	i2c_register_board_info(0, mxc_i2c0_board_info,
			ARRAY_SIZE(mxc_i2c0_board_info));
	i2c_register_board_info(1, mxc_i2c1_board_info,
			ARRAY_SIZE(mxc_i2c1_board_info));
	//i2c_register_board_info(2, mxc_i2c2_board_info,
	//		ARRAY_SIZE(mxc_i2c2_board_info));
	mx6q_dsa2lb_init_wm8326();

	/* spdif */
	mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0", NULL);
	clk_put(mxc_spdif_data.spdif_core_clk);
	imx6q_add_spdif(&mxc_spdif_data);
	imx6q_add_spdif_dai();
	imx6q_add_spdif_audio_device();
	
	/* SPI */
	imx6q_add_ecspi(0, &mx6q_sabresd_spi_data);
	spi_device_init();

	imx6q_add_mxc_hdmi(&hdmi_data);

	imx6q_add_anatop_thermal_imx(1, &mx6q_sabresd_anatop_thermal_data);
	imx6_init_fec(fec_data);
#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
	/* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
	mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
		OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
#endif

	imx6q_add_pm_imx(0, &mx6q_sabresd_pm_data);

	/* Move sd4 to first because sd4 connect to emmc.
	   Mfgtools want emmc is mmcblk0 and other sd card is mmcblk1.
	*/
	//imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabresd_sd4_data);
	//imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabresd_sd3_data);
	imx6q_add_sdhci_usdhc_imx(1, &mx6q_sabresd_sd2_data);
	imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
	imx6q_sabresd_init_usb();
	/* SATA is not supported by MX6DL/Solo */
	if (cpu_is_mx6q()) {
#ifdef CONFIG_SATA_AHCI_PLATFORM
		imx6q_add_ahci(0, &mx6q_sabresd_sata_data);
#else
		mx6q_sabresd_sata_init(NULL,
			(void __iomem *)ioremap(MX6Q_SATA_BASE_ADDR, SZ_4K));
#endif
	}
	imx6q_add_vpu();
	imx6q_init_audio();
	platform_device_register(&sabresd_vmmc_reg_devices);
	imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
	imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
	imx6q_add_asrc(&imx_asrc_data);

	/*
	 * Disable HannStar touch panel CABC function,
	 * this function turns the panel's backlight automatically
	 * according to the content shown on the panel which
	 * may cause annoying unstable backlight issue.
	 */
	//gpio_request(SABRESD_CABC_EN0, "cabc-en0");
	//gpio_direction_output(SABRESD_CABC_EN0, 0);
	//gpio_request(SABRESD_CABC_EN1, "cabc-en1");
	//gpio_direction_output(SABRESD_CABC_EN1, 0);

	imx6q_add_mxc_pwm(0);
	imx6q_add_mxc_pwm(1);
	imx6q_add_mxc_pwm(2);
	imx6q_add_mxc_pwm(3);
	imx6q_add_mxc_pwm_backlight(0, &mx6_sabresd_pwm_backlight_data);

	imx6q_add_otp();
	imx6q_add_viim();
	imx6q_add_imx2_wdt(0, NULL);
	imx6q_add_dma();

	imx6q_add_dvfs_core(&sabresd_dvfscore_data);

	if (imx_ion_data.heaps[0].size)
		imx6q_add_ion(0, &imx_ion_data,
			sizeof(imx_ion_data) + sizeof(struct ion_platform_heap));

	imx6q_add_device_buttons();

	///* enable sensor 3v3 and 1v8 */
	//gpio_request(SABRESD_SENSOR_EN, "sensor-en");
	//gpio_direction_output(SABRESD_SENSOR_EN, 1);

	/* enable ecompass intr */
	//gpio_request(SABRESD_eCOMPASS_INT, "ecompass-int");
	//gpio_direction_input(SABRESD_eCOMPASS_INT);
	/* enable light sensor intr */
	//gpio_request(SABRESD_ALS_INT, "als-int");
	//gpio_direction_input(SABRESD_ALS_INT);

	imx6q_add_hdmi_soc();
	imx6q_add_hdmi_soc_dai();

	if (cpu_is_mx6dl()) {
		imx6dl_add_imx_pxp();
		imx6dl_add_imx_pxp_client();
	}

	clko2 = clk_get(NULL, "clko2_clk");
	if (IS_ERR(clko2))
		pr_err("can't get CLKO2 clock.\n");

	new_parent = clk_get(NULL, "osc_clk");
	if (!IS_ERR(new_parent)) {
		clk_set_parent(clko2, new_parent);
		clk_put(new_parent);
	}
	rate = clk_round_rate(clko2, 24000000);
	clk_set_rate(clko2, rate);
	clk_enable(clko2);

	/* Camera and audio use osc clock */
	clko = clk_get(NULL, "clko_clk");
	if (!IS_ERR(clko))
		clk_set_parent(clko, clko2);

	/* Enable Aux_5V */
	//gpio_request(SABRESD_AUX_5V_EN, "aux_5v_en");
	//gpio_direction_output(SABRESD_AUX_5V_EN, 1);
	//gpio_set_value(SABRESD_AUX_5V_EN, 1);

	//gps_power_on(true);
	/* Register charger chips */
	platform_device_register(&sabresd_max8903_charger_1);
	//pm_power_off = mx6_snvs_poweroff;
	pm_power_off = arch_poweroff;
	imx6q_add_busfreq();

	/* Add PCIe RC interface support
	 * uart5 has pin mux with pcie. or you will use uart5 or use pcie
	 */
	if (cpu_is_mx6dl()) {
		mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_elan_pads,
						ARRAY_SIZE(mx6dl_arm2_elan_pads));
	}

	imx6_add_armpmu();
	imx6q_add_perfmon(0);
	imx6q_add_perfmon(1);
	imx6q_add_perfmon(2);
}
Esempio n. 10
0
static int __init sh_mipi_probe(struct platform_device *pdev)
{
	struct sh_mipi *mipi;
	struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	unsigned long rate, f_current;
	int idx = pdev->id, ret;

	if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
		return -ENODEV;

	if (!pdata->set_dot_clock)
		return -EINVAL;

	mutex_lock(&array_lock);
	if (idx < 0)
		for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
			;

	if (idx == ARRAY_SIZE(mipi_dsi)) {
		ret = -EBUSY;
		goto efindslot;
	}

	mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
	if (!mipi) {
		ret = -ENOMEM;
		goto ealloc;
	}

	mipi->entity.owner = THIS_MODULE;
	mipi->entity.ops = &mipi_ops;

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_err(&pdev->dev, "MIPI register region already claimed\n");
		ret = -EBUSY;
		goto ereqreg;
	}

	mipi->base = ioremap(res->start, resource_size(res));
	if (!mipi->base) {
		ret = -ENOMEM;
		goto emap;
	}

	if (!request_mem_region(res2->start, resource_size(res2), pdev->name)) {
		dev_err(&pdev->dev, "MIPI register region 2 already claimed\n");
		ret = -EBUSY;
		goto ereqreg2;
	}

	mipi->linkbase = ioremap(res2->start, resource_size(res2));
	if (!mipi->linkbase) {
		ret = -ENOMEM;
		goto emap2;
	}

	mipi->pdev = pdev;

	mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
	if (IS_ERR(mipi->dsit_clk)) {
		ret = PTR_ERR(mipi->dsit_clk);
		goto eclktget;
	}

	f_current = clk_get_rate(mipi->dsit_clk);
	/* 80MHz required by the datasheet */
	rate = clk_round_rate(mipi->dsit_clk, 80000000);
	if (rate > 0 && rate != f_current)
		ret = clk_set_rate(mipi->dsit_clk, rate);
	else
		ret = rate;
	if (ret < 0)
		goto esettrate;

	dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);

	ret = clk_enable(mipi->dsit_clk);
	if (ret < 0)
		goto eclkton;

	mipi_dsi[idx] = mipi;

	pm_runtime_enable(&pdev->dev);
	pm_runtime_resume(&pdev->dev);

	mutex_unlock(&array_lock);
	platform_set_drvdata(pdev, &mipi->entity);

	return 0;

eclkton:
esettrate:
	clk_put(mipi->dsit_clk);
eclktget:
	iounmap(mipi->linkbase);
emap2:
	release_mem_region(res2->start, resource_size(res2));
ereqreg2:
	iounmap(mipi->base);
emap:
	release_mem_region(res->start, resource_size(res));
ereqreg:
	kfree(mipi);
ealloc:
efindslot:
	mutex_unlock(&array_lock);

	return ret;
}
Esempio n. 11
0
static void __init mackerel_init(void)
{
	struct pm_domain_device domain_devices[] = {
		{ "A4LC", &lcdc_device, },
		{ "A4LC", &hdmi_lcdc_device, },
		{ "A4LC", &meram_device, },
		{ "A4MP", &fsi_device, },
		{ "A3SP", &usbhs0_device, },
		{ "A3SP", &usbhs1_device, },
		{ "A3SP", &nand_flash_device, },
		{ "A3SP", &sdhi0_device, },
#if !IS_ENABLED(CONFIG_MMC_SH_MMCIF)
		{ "A3SP", &sdhi1_device, },
#else
		{ "A3SP", &sh_mmcif_device, },
#endif
		{ "A3SP", &sdhi2_device, },
		{ "A4R", &ceu_device, },
	};
	u32 srcr4;
	struct clk *clk;

	regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
				     ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
	regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
	regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));

	/* External clock source */
	clk_set_rate(&sh7372_dv_clki_clk, 27000000);

	pinctrl_register_mappings(mackerel_pinctrl_map,
				  ARRAY_SIZE(mackerel_pinctrl_map));
	sh7372_pinmux_init();

	/* enable SCIFA0 */
	gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
	gpio_request(GPIO_FN_SCIFA0_RXD, NULL);

	/* enable SMSC911X */
	gpio_request(GPIO_FN_CS5A,	NULL);
	gpio_request(GPIO_FN_IRQ6_39,	NULL);

	/* LCDC */
	gpio_request(GPIO_FN_LCDD23,   NULL);
	gpio_request(GPIO_FN_LCDD22,   NULL);
	gpio_request(GPIO_FN_LCDD21,   NULL);
	gpio_request(GPIO_FN_LCDD20,   NULL);
	gpio_request(GPIO_FN_LCDD19,   NULL);
	gpio_request(GPIO_FN_LCDD18,   NULL);
	gpio_request(GPIO_FN_LCDD17,   NULL);
	gpio_request(GPIO_FN_LCDD16,   NULL);
	gpio_request(GPIO_FN_LCDD15,   NULL);
	gpio_request(GPIO_FN_LCDD14,   NULL);
	gpio_request(GPIO_FN_LCDD13,   NULL);
	gpio_request(GPIO_FN_LCDD12,   NULL);
	gpio_request(GPIO_FN_LCDD11,   NULL);
	gpio_request(GPIO_FN_LCDD10,   NULL);
	gpio_request(GPIO_FN_LCDD9,    NULL);
	gpio_request(GPIO_FN_LCDD8,    NULL);
	gpio_request(GPIO_FN_LCDD7,    NULL);
	gpio_request(GPIO_FN_LCDD6,    NULL);
	gpio_request(GPIO_FN_LCDD5,    NULL);
	gpio_request(GPIO_FN_LCDD4,    NULL);
	gpio_request(GPIO_FN_LCDD3,    NULL);
	gpio_request(GPIO_FN_LCDD2,    NULL);
	gpio_request(GPIO_FN_LCDD1,    NULL);
	gpio_request(GPIO_FN_LCDD0,    NULL);
	gpio_request(GPIO_FN_LCDDISP,  NULL);
	gpio_request(GPIO_FN_LCDDCK,   NULL);

	/* backlight, off by default */
	gpio_request_one(31, GPIOF_OUT_INIT_LOW, NULL);

	gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */

	/* USBHS0 */
	gpio_request(GPIO_FN_VBUS0_0, NULL);
	gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */

	/* USBHS1 */
	gpio_request(GPIO_FN_VBUS0_1, NULL);
	gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */
	gpio_request(GPIO_FN_IDIN_1_113, NULL);

	/* enable FSI2 port A (ak4643) */
	gpio_request(GPIO_FN_FSIAIBT,	NULL);
	gpio_request(GPIO_FN_FSIAILR,	NULL);
	gpio_request(GPIO_FN_FSIAISLD,	NULL);
	gpio_request(GPIO_FN_FSIAOSLD,	NULL);
	gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */

	gpio_request(9,  NULL);
	gpio_request(10, NULL);
	gpio_direction_none(GPIO_PORT9CR);  /* FSIAOBT needs no direction */
	gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */

	intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */

	/* setup FSI2 port B (HDMI) */
	gpio_request(GPIO_FN_FSIBCK, NULL);
	__raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */

	/* set SPU2 clock to 119.6 MHz */
	clk = clk_get(NULL, "spu_clk");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, clk_round_rate(clk, 119600000));
		clk_put(clk);
	}

	/* enable Keypad */
	gpio_request(GPIO_FN_IRQ9_42,	NULL);
	irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);

	/* enable Touchscreen */
	gpio_request(GPIO_FN_IRQ7_40,	NULL);
	irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);

	/* enable Accelerometer */
	gpio_request(GPIO_FN_IRQ21,	NULL);
	irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);

	/* SDHI0 PORT172 card-detect IRQ26 */
	gpio_request(GPIO_FN_IRQ26_172, NULL);

	/* FLCTL */
	gpio_request(GPIO_FN_D0_NAF0, NULL);
	gpio_request(GPIO_FN_D1_NAF1, NULL);
	gpio_request(GPIO_FN_D2_NAF2, NULL);
	gpio_request(GPIO_FN_D3_NAF3, NULL);
	gpio_request(GPIO_FN_D4_NAF4, NULL);
	gpio_request(GPIO_FN_D5_NAF5, NULL);
	gpio_request(GPIO_FN_D6_NAF6, NULL);
	gpio_request(GPIO_FN_D7_NAF7, NULL);
	gpio_request(GPIO_FN_D8_NAF8, NULL);
	gpio_request(GPIO_FN_D9_NAF9, NULL);
	gpio_request(GPIO_FN_D10_NAF10, NULL);
	gpio_request(GPIO_FN_D11_NAF11, NULL);
	gpio_request(GPIO_FN_D12_NAF12, NULL);
	gpio_request(GPIO_FN_D13_NAF13, NULL);
	gpio_request(GPIO_FN_D14_NAF14, NULL);
	gpio_request(GPIO_FN_D15_NAF15, NULL);
	gpio_request(GPIO_FN_FCE0, NULL);
	gpio_request(GPIO_FN_WE0_FWE, NULL);
	gpio_request(GPIO_FN_FRB, NULL);
	gpio_request(GPIO_FN_A4_FOE, NULL);
	gpio_request(GPIO_FN_A5_FCDE, NULL);
	gpio_request(GPIO_FN_RD_FSC, NULL);

	/* enable GPS module (GT-720F) */
	gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
	gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);

	/* CEU */
	gpio_request(GPIO_FN_VIO_CLK, NULL);
	gpio_request(GPIO_FN_VIO_VD, NULL);
	gpio_request(GPIO_FN_VIO_HD, NULL);
	gpio_request(GPIO_FN_VIO_FIELD, NULL);
	gpio_request(GPIO_FN_VIO_CKO, NULL);
	gpio_request(GPIO_FN_VIO_D7, NULL);
	gpio_request(GPIO_FN_VIO_D6, NULL);
	gpio_request(GPIO_FN_VIO_D5, NULL);
	gpio_request(GPIO_FN_VIO_D4, NULL);
	gpio_request(GPIO_FN_VIO_D3, NULL);
	gpio_request(GPIO_FN_VIO_D2, NULL);
	gpio_request(GPIO_FN_VIO_D1, NULL);
	gpio_request(GPIO_FN_VIO_D0, NULL);

	/* HDMI */
	gpio_request(GPIO_FN_HDMI_HPD, NULL);
	gpio_request(GPIO_FN_HDMI_CEC, NULL);

	/* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
	srcr4 = __raw_readl(SRCR4);
	__raw_writel(srcr4 | (1 << 13), SRCR4);
	udelay(50);
	__raw_writel(srcr4 & ~(1 << 13), SRCR4);

	i2c_register_board_info(0, i2c0_devices,
				ARRAY_SIZE(i2c0_devices));
	i2c_register_board_info(1, i2c1_devices,
				ARRAY_SIZE(i2c1_devices));

	sh7372_add_standard_devices();

	platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));

	rmobile_add_devices_to_domains(domain_devices,
				       ARRAY_SIZE(domain_devices));

	hdmi_init_pm_clock();
	sh7372_pm_init();
	pm_clk_add(&fsi_device.dev, "spu2");
	pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
}
Esempio n. 12
0
static int __init arch_setup(void)
{
	struct clk *clk;
	bool cn12_enabled = false;

	/* register board specific self-refresh code */
	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
					SUSP_SH_RSTANDBY,
					&ecovec24_sdram_enter_start,
					&ecovec24_sdram_enter_end,
					&ecovec24_sdram_leave_start,
					&ecovec24_sdram_leave_end);

	/* enable STATUS0, STATUS2 and PDSTATUS */
	gpio_request(GPIO_FN_STATUS0, NULL);
	gpio_request(GPIO_FN_STATUS2, NULL);
	gpio_request(GPIO_FN_PDSTATUS, NULL);

	/* enable SCIFA0 */
	gpio_request(GPIO_FN_SCIF0_TXD, NULL);
	gpio_request(GPIO_FN_SCIF0_RXD, NULL);

	/* enable debug LED */
	gpio_request(GPIO_PTG0, NULL);
	gpio_request(GPIO_PTG1, NULL);
	gpio_request(GPIO_PTG2, NULL);
	gpio_request(GPIO_PTG3, NULL);
	gpio_direction_output(GPIO_PTG0, 0);
	gpio_direction_output(GPIO_PTG1, 0);
	gpio_direction_output(GPIO_PTG2, 0);
	gpio_direction_output(GPIO_PTG3, 0);
	__raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);

	/* enable SH-Eth */
	gpio_request(GPIO_PTA1, NULL);
	gpio_direction_output(GPIO_PTA1, 1);
	mdelay(20);

	gpio_request(GPIO_FN_RMII_RXD0,    NULL);
	gpio_request(GPIO_FN_RMII_RXD1,    NULL);
	gpio_request(GPIO_FN_RMII_TXD0,    NULL);
	gpio_request(GPIO_FN_RMII_TXD1,    NULL);
	gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
	gpio_request(GPIO_FN_RMII_TX_EN,   NULL);
	gpio_request(GPIO_FN_RMII_RX_ER,   NULL);
	gpio_request(GPIO_FN_RMII_CRS_DV,  NULL);
	gpio_request(GPIO_FN_MDIO,         NULL);
	gpio_request(GPIO_FN_MDC,          NULL);
	gpio_request(GPIO_FN_LNKSTA,       NULL);

	/* enable USB */
	__raw_writew(0x0000, 0xA4D80000);
	__raw_writew(0x0000, 0xA4D90000);
	gpio_request(GPIO_PTB3,  NULL);
	gpio_request(GPIO_PTB4,  NULL);
	gpio_request(GPIO_PTB5,  NULL);
	gpio_direction_input(GPIO_PTB3);
	gpio_direction_output(GPIO_PTB4, 0);
	gpio_direction_output(GPIO_PTB5, 0);
	__raw_writew(0x0600, 0xa40501d4);
	__raw_writew(0x0600, 0xa4050192);

	if (gpio_get_value(GPIO_PTB3)) {
		printk(KERN_INFO "USB1 function is selected\n");
		usb1_common_device.name = "r8a66597_udc";
	} else {
		printk(KERN_INFO "USB1 host is selected\n");
		usb1_common_device.name = "r8a66597_hcd";
	}

	/* enable LCDC */
	gpio_request(GPIO_FN_LCDD23,   NULL);
	gpio_request(GPIO_FN_LCDD22,   NULL);
	gpio_request(GPIO_FN_LCDD21,   NULL);
	gpio_request(GPIO_FN_LCDD20,   NULL);
	gpio_request(GPIO_FN_LCDD19,   NULL);
	gpio_request(GPIO_FN_LCDD18,   NULL);
	gpio_request(GPIO_FN_LCDD17,   NULL);
	gpio_request(GPIO_FN_LCDD16,   NULL);
	gpio_request(GPIO_FN_LCDD15,   NULL);
	gpio_request(GPIO_FN_LCDD14,   NULL);
	gpio_request(GPIO_FN_LCDD13,   NULL);
	gpio_request(GPIO_FN_LCDD12,   NULL);
	gpio_request(GPIO_FN_LCDD11,   NULL);
	gpio_request(GPIO_FN_LCDD10,   NULL);
	gpio_request(GPIO_FN_LCDD9,    NULL);
	gpio_request(GPIO_FN_LCDD8,    NULL);
	gpio_request(GPIO_FN_LCDD7,    NULL);
	gpio_request(GPIO_FN_LCDD6,    NULL);
	gpio_request(GPIO_FN_LCDD5,    NULL);
	gpio_request(GPIO_FN_LCDD4,    NULL);
	gpio_request(GPIO_FN_LCDD3,    NULL);
	gpio_request(GPIO_FN_LCDD2,    NULL);
	gpio_request(GPIO_FN_LCDD1,    NULL);
	gpio_request(GPIO_FN_LCDD0,    NULL);
	gpio_request(GPIO_FN_LCDDISP,  NULL);
	gpio_request(GPIO_FN_LCDHSYN,  NULL);
	gpio_request(GPIO_FN_LCDDCK,   NULL);
	gpio_request(GPIO_FN_LCDVSYN,  NULL);
	gpio_request(GPIO_FN_LCDDON,   NULL);
	gpio_request(GPIO_FN_LCDLCLK,  NULL);
	__raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);

	gpio_request(GPIO_PTE6, NULL);
	gpio_request(GPIO_PTU1, NULL);
	gpio_request(GPIO_PTR1, NULL);
	gpio_request(GPIO_PTA2, NULL);
	gpio_direction_input(GPIO_PTE6);
	gpio_direction_output(GPIO_PTU1, 0);
	gpio_direction_output(GPIO_PTR1, 0);
	gpio_direction_output(GPIO_PTA2, 0);

	/* I/O buffer drive ability is high */
	__raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);

	if (gpio_get_value(GPIO_PTE6)) {
		/* DVI */
		lcdc_info.clock_source			= LCDC_CLK_EXTERNAL;
		lcdc_info.ch[0].clock_divider		= 1;
		lcdc_info.ch[0].lcd_modes		= ecovec_dvi_modes;
		lcdc_info.ch[0].num_modes		= ARRAY_SIZE(ecovec_dvi_modes);

		gpio_set_value(GPIO_PTA2, 1);
		gpio_set_value(GPIO_PTU1, 1);
	} else {
		/* Panel */
		lcdc_info.clock_source			= LCDC_CLK_PERIPHERAL;
		lcdc_info.ch[0].clock_divider		= 2;
		lcdc_info.ch[0].lcd_modes		= ecovec_lcd_modes;
		lcdc_info.ch[0].num_modes		= ARRAY_SIZE(ecovec_lcd_modes);

		gpio_set_value(GPIO_PTR1, 1);

		/* FIXME
		 *
		 * LCDDON control is needed for Panel,
		 * but current sh_mobile_lcdc driver doesn't control it.
		 * It is temporary correspondence
		 */
		gpio_request(GPIO_PTF4, NULL);
		gpio_direction_output(GPIO_PTF4, 1);

		/* enable TouchScreen */
		i2c_register_board_info(0, &ts_i2c_clients, 1);
		irq_set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
	}

	/* enable CEU0 */
	gpio_request(GPIO_FN_VIO0_D15, NULL);
	gpio_request(GPIO_FN_VIO0_D14, NULL);
	gpio_request(GPIO_FN_VIO0_D13, NULL);
	gpio_request(GPIO_FN_VIO0_D12, NULL);
	gpio_request(GPIO_FN_VIO0_D11, NULL);
	gpio_request(GPIO_FN_VIO0_D10, NULL);
	gpio_request(GPIO_FN_VIO0_D9,  NULL);
	gpio_request(GPIO_FN_VIO0_D8,  NULL);
	gpio_request(GPIO_FN_VIO0_D7,  NULL);
	gpio_request(GPIO_FN_VIO0_D6,  NULL);
	gpio_request(GPIO_FN_VIO0_D5,  NULL);
	gpio_request(GPIO_FN_VIO0_D4,  NULL);
	gpio_request(GPIO_FN_VIO0_D3,  NULL);
	gpio_request(GPIO_FN_VIO0_D2,  NULL);
	gpio_request(GPIO_FN_VIO0_D1,  NULL);
	gpio_request(GPIO_FN_VIO0_D0,  NULL);
	gpio_request(GPIO_FN_VIO0_VD,  NULL);
	gpio_request(GPIO_FN_VIO0_CLK, NULL);
	gpio_request(GPIO_FN_VIO0_FLD, NULL);
	gpio_request(GPIO_FN_VIO0_HD,  NULL);
	platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20);

	/* enable CEU1 */
	gpio_request(GPIO_FN_VIO1_D7,  NULL);
	gpio_request(GPIO_FN_VIO1_D6,  NULL);
	gpio_request(GPIO_FN_VIO1_D5,  NULL);
	gpio_request(GPIO_FN_VIO1_D4,  NULL);
	gpio_request(GPIO_FN_VIO1_D3,  NULL);
	gpio_request(GPIO_FN_VIO1_D2,  NULL);
	gpio_request(GPIO_FN_VIO1_D1,  NULL);
	gpio_request(GPIO_FN_VIO1_D0,  NULL);
	gpio_request(GPIO_FN_VIO1_FLD, NULL);
	gpio_request(GPIO_FN_VIO1_HD,  NULL);
	gpio_request(GPIO_FN_VIO1_VD,  NULL);
	gpio_request(GPIO_FN_VIO1_CLK, NULL);
	platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20);

	/* enable KEYSC */
	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
	gpio_request(GPIO_FN_KEYOUT3,     NULL);
	gpio_request(GPIO_FN_KEYOUT2,     NULL);
	gpio_request(GPIO_FN_KEYOUT1,     NULL);
	gpio_request(GPIO_FN_KEYOUT0,     NULL);
	gpio_request(GPIO_FN_KEYIN0,      NULL);

	/* enable user debug switch */
	gpio_request(GPIO_PTR0, NULL);
	gpio_request(GPIO_PTR4, NULL);
	gpio_request(GPIO_PTR5, NULL);
	gpio_request(GPIO_PTR6, NULL);
	gpio_direction_input(GPIO_PTR0);
	gpio_direction_input(GPIO_PTR4);
	gpio_direction_input(GPIO_PTR5);
	gpio_direction_input(GPIO_PTR6);

	/* SD-card slot CN11 */
	/* Card-detect, used on CN11, either with SDHI0 or with SPI */
	gpio_request(GPIO_PTY7, NULL);
	gpio_direction_input(GPIO_PTY7);

#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
	/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
	gpio_request(GPIO_FN_SDHI0WP,  NULL);
	gpio_request(GPIO_FN_SDHI0CMD, NULL);
	gpio_request(GPIO_FN_SDHI0CLK, NULL);
	gpio_request(GPIO_FN_SDHI0D3,  NULL);
	gpio_request(GPIO_FN_SDHI0D2,  NULL);
	gpio_request(GPIO_FN_SDHI0D1,  NULL);
	gpio_request(GPIO_FN_SDHI0D0,  NULL);
	gpio_request(GPIO_PTB6, NULL);
	gpio_direction_output(GPIO_PTB6, 0);
#else
	/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
	gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
	gpio_request(GPIO_FN_MSIOF0_RXD, NULL);
	gpio_request(GPIO_FN_MSIOF0_TSCK, NULL);
	gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */
	gpio_direction_output(GPIO_PTM4, 1); /* active low CS */
	gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */
	gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */
	gpio_request(GPIO_PTY6, NULL); /* write protect */
	gpio_direction_input(GPIO_PTY6);

	spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
#endif

	/* MMC/SD-card slot CN12 */
#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
	/* enable MMCIF (needs DS2.6,7 set to OFF,ON) */
	gpio_request(GPIO_FN_MMC_D7, NULL);
	gpio_request(GPIO_FN_MMC_D6, NULL);
	gpio_request(GPIO_FN_MMC_D5, NULL);
	gpio_request(GPIO_FN_MMC_D4, NULL);
	gpio_request(GPIO_FN_MMC_D3, NULL);
	gpio_request(GPIO_FN_MMC_D2, NULL);
	gpio_request(GPIO_FN_MMC_D1, NULL);
	gpio_request(GPIO_FN_MMC_D0, NULL);
	gpio_request(GPIO_FN_MMC_CLK, NULL);
	gpio_request(GPIO_FN_MMC_CMD, NULL);
	gpio_request(GPIO_PTB7, NULL);
	gpio_direction_output(GPIO_PTB7, 0);

	cn12_enabled = true;
#elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
	/* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */
	gpio_request(GPIO_FN_SDHI1WP,  NULL);
	gpio_request(GPIO_FN_SDHI1CMD, NULL);
	gpio_request(GPIO_FN_SDHI1CLK, NULL);
	gpio_request(GPIO_FN_SDHI1D3,  NULL);
	gpio_request(GPIO_FN_SDHI1D2,  NULL);
	gpio_request(GPIO_FN_SDHI1D1,  NULL);
	gpio_request(GPIO_FN_SDHI1D0,  NULL);
	gpio_request(GPIO_PTB7, NULL);
	gpio_direction_output(GPIO_PTB7, 0);

	/* Card-detect, used on CN12 with SDHI1 */
	gpio_request(GPIO_PTW7, NULL);
	gpio_direction_input(GPIO_PTW7);

	cn12_enabled = true;
#endif

	if (cn12_enabled)
		/* I/O buffer drive ability is high for CN12 */
		__raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000,
			     IODRIVEA);

	/* enable Video */
	gpio_request(GPIO_PTU2, NULL);
	gpio_direction_output(GPIO_PTU2, 1);

	/* enable Camera */
	gpio_request(GPIO_PTA3, NULL);
	gpio_request(GPIO_PTA4, NULL);
	gpio_direction_output(GPIO_PTA3, 0);
	gpio_direction_output(GPIO_PTA4, 0);

	/* enable FSI */
	gpio_request(GPIO_FN_FSIMCKB,    NULL);
	gpio_request(GPIO_FN_FSIIBSD,    NULL);
	gpio_request(GPIO_FN_FSIOBSD,    NULL);
	gpio_request(GPIO_FN_FSIIBBCK,   NULL);
	gpio_request(GPIO_FN_FSIIBLRCK,  NULL);
	gpio_request(GPIO_FN_FSIOBBCK,   NULL);
	gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
	gpio_request(GPIO_FN_CLKAUDIOBO, NULL);

	/* set SPU2 clock to 83.4 MHz */
	clk = clk_get(NULL, "spu_clk");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, clk_round_rate(clk, 83333333));
		clk_put(clk);
	}

	/* change parent of FSI B */
	clk = clk_get(NULL, "fsib_clk");
	if (!IS_ERR(clk)) {
		/* 48kHz dummy clock was used to make sure 1/1 divide */
		clk_set_rate(&sh7724_fsimckb_clk, 48000);
		clk_set_parent(clk, &sh7724_fsimckb_clk);
		clk_set_rate(clk, 48000);
		clk_put(clk);
	}

	gpio_request(GPIO_PTU0, NULL);
	gpio_direction_output(GPIO_PTU0, 0);
	mdelay(20);

	/* enable motion sensor */
	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
	gpio_direction_input(GPIO_FN_INTC_IRQ1);

	/* set VPU clock to 166 MHz */
	clk = clk_get(NULL, "vpu_clk");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, clk_round_rate(clk, 166000000));
		clk_put(clk);
	}

	/* enable IrDA */
	gpio_request(GPIO_FN_IRDA_OUT, NULL);
	gpio_request(GPIO_FN_IRDA_IN,  NULL);
	gpio_request(GPIO_PTU5, NULL);
	gpio_direction_output(GPIO_PTU5, 0);

	/* enable I2C device */
	i2c_register_board_info(0, i2c0_devices,
				ARRAY_SIZE(i2c0_devices));

	i2c_register_board_info(1, i2c1_devices,
				ARRAY_SIZE(i2c1_devices));

#if defined(CONFIG_VIDEO_SH_VOU) || defined(CONFIG_VIDEO_SH_VOU_MODULE)
	/* VOU */
	gpio_request(GPIO_FN_DV_D15, NULL);
	gpio_request(GPIO_FN_DV_D14, NULL);
	gpio_request(GPIO_FN_DV_D13, NULL);
	gpio_request(GPIO_FN_DV_D12, NULL);
	gpio_request(GPIO_FN_DV_D11, NULL);
	gpio_request(GPIO_FN_DV_D10, NULL);
	gpio_request(GPIO_FN_DV_D9, NULL);
	gpio_request(GPIO_FN_DV_D8, NULL);
	gpio_request(GPIO_FN_DV_CLKI, NULL);
	gpio_request(GPIO_FN_DV_CLK, NULL);
	gpio_request(GPIO_FN_DV_VSYNC, NULL);
	gpio_request(GPIO_FN_DV_HSYNC, NULL);

	/* AK8813 power / reset sequence */
	gpio_request(GPIO_PTG4, NULL);
	gpio_request(GPIO_PTU3, NULL);
	/* Reset */
	gpio_direction_output(GPIO_PTG4, 0);
	/* Power down */
	gpio_direction_output(GPIO_PTU3, 1);

	udelay(10);

	/* Power up, reset */
	gpio_set_value(GPIO_PTU3, 0);

	udelay(10);

	/* Remove reset */
	gpio_set_value(GPIO_PTG4, 1);
#endif

	return platform_add_devices(ecovec_devices,
				    ARRAY_SIZE(ecovec_devices));
}
Esempio n. 13
0
static int tegra_camera_clk_set_rate(struct tegra_camera_dev *dev)
{
    struct clk *clk, *clk_parent;
    struct tegra_camera_clk_info *info = &dev->info;
    unsigned long parent_rate, parent_div_rate, parent_div_rate_pre;

    if (!info) {
        dev_err(dev->dev,
                "%s: no clock info %d\n",
                __func__, info->id);
        return -EINVAL;
    }

    if (info->id != TEGRA_CAMERA_MODULE_VI) {
        dev_err(dev->dev,
                "%s: set rate only aplies to vi module %d\n",
                __func__, info->id);
        return -EINVAL;
    }

    switch (info->clk_id) {
    case TEGRA_CAMERA_VI_CLK:
        clk = dev->vi_clk;
        break;
    case TEGRA_CAMERA_VI_SENSOR_CLK:
        clk = dev->vi_sensor_clk;
        break;
    default:
        dev_err(dev->dev,
                "%s: invalid clk id for set rate %d\n",
                __func__, info->clk_id);
        return -EINVAL;
    }

    clk_parent = clk_get_parent(clk);
    parent_rate = clk_get_rate(clk_parent);
    dev_dbg(dev->dev, "%s: clk_id=%d, parent_rate=%lu, clk_rate=%lu\n",
            __func__, info->clk_id, parent_rate, info->rate);
    parent_div_rate = parent_rate;
    parent_div_rate_pre = parent_rate;

    /*
     * The requested clock rate from user space should be respected.
     * This loop is to search the clock rate that is higher than requested
     * clock.
     */
    while (parent_div_rate >= info->rate) {
        parent_div_rate_pre = parent_div_rate;
        parent_div_rate = clk_round_rate(clk, parent_div_rate-1);
    }

    dev_dbg(dev->dev, "%s: set_rate=%lu",
            __func__, parent_div_rate_pre);

    clk_set_rate(clk, parent_div_rate_pre);

    if (info->clk_id == TEGRA_CAMERA_VI_CLK) {
        /*
         * bit 25: 0 = pd2vi_Clk, 1 = vi_sensor_clk
         * bit 24: 0 = internal clock, 1 = external clock(pd2vi_clk)
         */
        if (info->flag == TEGRA_CAMERA_ENABLE_PD2VI_CLK)
            tegra_clk_cfg_ex(clk, TEGRA_CLK_VI_INP_SEL, 2);

#ifdef CONFIG_ARCH_TEGRA_2x_SOC
        u32 val;
        void __iomem *apb_misc = IO_ADDRESS(TEGRA_APB_MISC_BASE);
        val = readl(apb_misc + 0x42c);
        writel(val | 0x1, apb_misc + 0x42c);
#endif
    }

    info->rate = clk_get_rate(clk);
    dev_dbg(dev->dev, "%s: get_rate=%lu",
            __func__, info->rate);
    return 0;

}
Esempio n. 14
0
PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
{
#if !defined(NO_HARDWARE)
	SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
#if !defined(PM_RUNTIME_SUPPORT)
	IMG_INT res;
	long lRate,lNewRate;
#endif
	if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)
	{
		return PVRSRV_OK;
	}
#if !defined(PM_RUNTIME_SUPPORT)
	PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));
	res=clk_enable(psSysSpecData->psSGX_FCK);
	if (res < 0)
        {
                PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));
                return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
        }

	lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);
        if (lNewRate <= 0)
        {
                PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));
                return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE;
        }


        lRate = clk_get_rate(psSysSpecData->psSGX_FCK);
        if (lRate != lNewRate)
        {
                res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);
                if (res < 0)
                {
                        PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res));
			return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE;
                }
        }

#if defined(DEBUG)
        {
                IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);
                PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));
        }
#endif

#endif
#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
#if defined(PM_RUNTIME_SUPPORT)
	{
		int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev);
		if (res < 0)
		{
			PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res));
			return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
		}
	}
#endif
#endif


	atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);

#else
	PVR_UNREFERENCED_PARAMETER(psSysData);
#endif
	return PVRSRV_OK;
}
void nvhost_scale3d_actmon_init(struct platform_device *dev)
{
	struct nvhost_devfreq_ext_stat *ext_stat;
	struct nvhost_device_data *pdata = platform_get_drvdata(dev);

	if (power_profile.init)
		return;

	/* Get clocks */
	power_profile.dev = dev;
	power_profile.clk_3d = pdata->clk[0];
	if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) {
		power_profile.clk_3d2 = pdata->clk[1];
		power_profile.clk_3d_emc = pdata->clk[2];
	} else
		power_profile.clk_3d_emc = pdata->clk[1];

	/* Get frequency settings */
	power_profile.max_rate_3d =
		clk_round_rate(power_profile.clk_3d, UINT_MAX);
	power_profile.min_rate_3d =
		clk_round_rate(power_profile.clk_3d, 0);

	nvhost_scale3d_devfreq_profile.initial_freq = power_profile.max_rate_3d;

	if (power_profile.max_rate_3d == power_profile.min_rate_3d) {
		pr_warn("scale3d: 3d max rate = min rate (%lu), disabling\n",
			power_profile.max_rate_3d);
		goto err_bad_power_profile;
	}

	/* Reserve space for devfreq structures (dev_stat and ext_dev_stat) */
	power_profile.dev_stat =
		kzalloc(sizeof(struct power_profile_gr3d), GFP_KERNEL);
	if (!power_profile.dev_stat)
		goto err_devfreq_alloc;
	ext_stat = kzalloc(sizeof(struct nvhost_devfreq_ext_stat), GFP_KERNEL);
	if (!ext_stat)
		goto err_devfreq_ext_stat_alloc;

	/* Initialise the dev_stat and ext_stat structures */
	power_profile.dev_stat->private_data = ext_stat;
	power_profile.last_event_type = DEVICE_UNKNOWN;
	ext_stat->min_freq = power_profile.min_rate_3d;
	ext_stat->max_freq = power_profile.max_rate_3d;

	power_profile.last_request_time = ktime_get();

	nvhost_scale3d_calibrate_emc();

	/* Start using devfreq */
	pdata->power_manager = devfreq_add_device(&dev->dev,
				&nvhost_scale3d_devfreq_profile,
				&nvhost_podgov,
				NULL);

	power_profile.init = 1;
	return;

err_devfreq_ext_stat_alloc:
	kfree(power_profile.dev_stat);
err_devfreq_alloc:
err_bad_power_profile:

	return;

}
Esempio n. 16
0
int kgsl_pwrctrl_init(struct kgsl_device *device)
{
	int i, result = 0;
	struct clk *clk;
	struct platform_device *pdev =
		container_of(device->parentdev, struct platform_device, dev);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct kgsl_device_platform_data *pdata_dev = pdev->dev.platform_data;
	struct kgsl_device_pwr_data *pdata_pwr = &pdata_dev->pwr_data;
	const char *clk_names[KGSL_MAX_CLKS] = {pwr->src_clk_name,
						pdata_dev->clk.name.clk,
						pdata_dev->clk.name.pclk,
						pdata_dev->imem_clk_name.clk,
						pdata_dev->imem_clk_name.pclk};

	/*acquire clocks */
	for (i = 1; i < KGSL_MAX_CLKS; i++) {
		if (clk_names[i]) {
			clk = clk_get(&pdev->dev, clk_names[i]);
			if (IS_ERR(clk))
				goto clk_err;
			pwr->grp_clks[i] = clk;
		}
	}
	/* Make sure we have a source clk for freq setting */
	clk = clk_get(&pdev->dev, clk_names[0]);
	pwr->grp_clks[0] = (IS_ERR(clk)) ? pwr->grp_clks[1] : clk;

	/* put the AXI bus into asynchronous mode with the graphics cores */
	if (pdata_pwr->set_grp_async != NULL)
		pdata_pwr->set_grp_async();

	if (pdata_pwr->num_levels > KGSL_MAX_PWRLEVELS) {
		KGSL_PWR_ERR(device, "invalid power level count: %d\n",
					 pdata_pwr->num_levels);
		result = -EINVAL;
		goto done;
	}
	pwr->num_pwrlevels = pdata_pwr->num_levels;
	pwr->active_pwrlevel = pdata_pwr->init_level;
	for (i = 0; i < pdata_pwr->num_levels; i++) {
		pwr->pwrlevels[i].gpu_freq =
		(pdata_pwr->pwrlevel[i].gpu_freq > 0) ?
		clk_round_rate(pwr->grp_clks[0],
					   pdata_pwr->pwrlevel[i].
					   gpu_freq) : 0;
		pwr->pwrlevels[i].bus_freq =
			pdata_pwr->pwrlevel[i].bus_freq;
	}
	/* Do not set_rate for targets in sync with AXI */
	if (pwr->pwrlevels[0].gpu_freq > 0)
		clk_set_rate(pwr->grp_clks[0], pwr->
				pwrlevels[pwr->num_pwrlevels - 1].gpu_freq);

	pwr->gpu_reg = regulator_get(NULL, pwr->regulator_name);
	if (IS_ERR(pwr->gpu_reg))
		pwr->gpu_reg = NULL;
	if (internal_pwr_rail_mode(device->pwrctrl.pwr_rail,
						PWR_RAIL_CTL_MANUAL)) {
		KGSL_PWR_ERR(device, "internal_pwr_rail_mode failed\n");
		result = -EINVAL;
		goto done;
	}

	pwr->power_flags = 0;

	pwr->nap_allowed = pdata_pwr->nap_allowed;
	pwr->interval_timeout = pdata_pwr->idle_timeout;
	pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(pwr->ebi1_clk))
		pwr->ebi1_clk = NULL;
	else
		clk_set_rate(pwr->ebi1_clk,
					 pwr->pwrlevels[pwr->active_pwrlevel].
						bus_freq);

//	pm_qos_add_request(PM_QOS_SYSTEM_BUS_FREQ,
//				PM_QOS_DEFAULT_VALUE);

	/*acquire interrupt */
	pwr->interrupt_num =
		platform_get_irq_byname(pdev, pwr->irq_name);

	if (pwr->interrupt_num <= 0) {
		KGSL_PWR_ERR(device, "platform_get_irq_byname failed: %d\n",
					 pwr->interrupt_num);
		result = -EINVAL;
		goto done;
	}

	register_early_suspend(&device->display_off);
	return result;

clk_err:
	result = PTR_ERR(clk);
	KGSL_PWR_ERR(device, "clk_get(%s) failed: %d\n",
				 clk_names[i], result);

done:
	return result;
}
Esempio n. 17
0
static void __init mackerel_init(void)
{
	struct pm_domain_device domain_devices[] = {
		{ "A4LC", &lcdc_device, },
		{ "A4LC", &hdmi_lcdc_device, },
		{ "A4LC", &meram_device, },
		{ "A4MP", &fsi_device, },
		{ "A3SP", &usbhs0_device, },
		{ "A3SP", &usbhs1_device, },
		{ "A3SP", &nand_flash_device, },
		{ "A3SP", &sdhi0_device, },
#if !IS_ENABLED(CONFIG_MMC_SH_MMCIF)
		{ "A3SP", &sdhi1_device, },
#else
		{ "A3SP", &sh_mmcif_device, },
#endif
		{ "A3SP", &sdhi2_device, },
		{ "A4R", &ceu_device, },
	};
	u32 srcr4;
	struct clk *clk;

	regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
				     ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
	regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
	regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));

	/* External clock source */
	clk_set_rate(&sh7372_dv_clki_clk, 27000000);

	pinctrl_register_mappings(mackerel_pinctrl_map,
				  ARRAY_SIZE(mackerel_pinctrl_map));
	sh7372_pinmux_init();

	gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */

	/* USBHS0 */
	gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */

	/* USBHS1 */
	gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */

	/* FSI2 port A (ak4643) */
	gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */

	gpio_request(9,  NULL);
	gpio_request(10, NULL);
	gpio_direction_none(GPIO_PORT9CR);  /* FSIAOBT needs no direction */
	gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */

	intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */

	/* FSI2 port B (HDMI) */
	__raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */

	/* set SPU2 clock to 119.6 MHz */
	clk = clk_get(NULL, "spu_clk");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, clk_round_rate(clk, 119600000));
		clk_put(clk);
	}

	/* Keypad */
	irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);

	/* Touchscreen */
	irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);

	/* Accelerometer */
	irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);

	/* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
	srcr4 = __raw_readl(SRCR4);
	__raw_writel(srcr4 | (1 << 13), SRCR4);
	udelay(50);
	__raw_writel(srcr4 & ~(1 << 13), SRCR4);

	i2c_register_board_info(0, i2c0_devices,
				ARRAY_SIZE(i2c0_devices));
	i2c_register_board_info(1, i2c1_devices,
				ARRAY_SIZE(i2c1_devices));

	sh7372_add_standard_devices();

	platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));

	rmobile_add_devices_to_domains(domain_devices,
				       ARRAY_SIZE(domain_devices));

	hdmi_init_pm_clock();
	sh7372_pm_init();
	pm_clk_add(&fsi_device.dev, "spu2");
	pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
}
Esempio n. 18
0
long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
{
	struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
	return clk_round_rate(mdp4_dtv_encoder->src_clk, rate);
}
Esempio n. 19
0
/*!
 * @brief Update LCDC registers
 * @param info	framebuffer information pointer
 */
static void _update_lcdc(struct fb_info *info)
{
	unsigned long base;
	unsigned long perclk, pcd, pcr;
	struct fb_var_screeninfo *var = &info->var;
	struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par;

	if (mx2fbi->type == MX2FB_TYPE_GW) {
		_enable_graphic_window(info);
		return;
	}

	base = (var->yoffset * var->xres_virtual + var->xoffset);
	base *= (var->bits_per_pixel) / 8;
	base += info->fix.smem_start;

	/* Screen start address register */
	__raw_writel(base, LCDC_REG(LCDC_LSSAR));

	/* Size register */
	dev_dbg(info->device, "xres = %d, yres = %d\n",
		info->var.xres, info->var.yres);
	__raw_writel(((info->var.xres >> 4) << 20) + info->var.yres,
		     LCDC_REG(LCDC_LSR));

	/* Virtual page width register */
	__raw_writel(info->var.xres_virtual >> 1, LCDC_REG(LCDC_LVPWR));

	/* To setup LCDC pixel clock */
	perclk = clk_round_rate(lcdc_clk, 134000000);
	if (clk_set_rate(lcdc_clk, perclk)) {
		printk(KERN_INFO "mx2fb: Unable to set clock to %lu\n", perclk);
		perclk = clk_get_rate(lcdc_clk);
	}

	/* Calculate pixel clock divider, and round to the nearest integer */
	pcd = (perclk * 8 / (PICOS2KHZ(var->pixclock) * 1000UL) + 4) / 8;
	if (--pcd > 0x3F)
		pcd = 0x3F;

	/* Panel configuration register */
	pcr = 0xFA008B80 | pcd;
	pcr |= (var->sync & FB_SYNC_CLK_LAT_FALL) ? 0x00200000 : 0;
	pcr |= (var->sync & FB_SYNC_DATA_INVERT) ? 0x01000000 : 0;
	pcr |= (var->sync & FB_SYNC_SHARP_MODE) ? 0x00000040 : 0;
	pcr |= (var->sync & FB_SYNC_OE_LOW_ACT) ? 0x00100000 : 0;
	__raw_writel(pcr, LCDC_REG(LCDC_LPCR));

	/* Horizontal and vertical configuration register */
	__raw_writel(((var->hsync_len - 1) << 26)
		     + ((var->right_margin - 1) << 8)
		     + (var->left_margin - 3), LCDC_REG(LCDC_LHCR));
	__raw_writel((var->vsync_len << 26)
		     + (var->lower_margin << 8)
		     + var->upper_margin, LCDC_REG(LCDC_LVCR));

	/* Sharp configuration register */
	__raw_writel(0x00120300, LCDC_REG(LCDC_LSCR));

	/* Refresh mode control reigster */
	__raw_writel(0x00000000, LCDC_REG(LCDC_LRMCR));

	/* DMA control register */
	if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0)
		__raw_writel(0x00040060, LCDC_REG(LCDC_LDCR));
	else
		__raw_writel(0x00020010, LCDC_REG(LCDC_LDCR));
}
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
{
	int rc = 0;
	struct clk *clk = NULL;

	switch (clktype) {
	case CAMIO_VFE_MDC_CLK:
		camio_vfe_mdc_clk =
		clk = clk_get(NULL, "vfe_mdc_clk");
		break;

	case CAMIO_MDC_CLK:
		camio_mdc_clk =
		clk = clk_get(NULL, "mdc_clk");
		break;

	case CAMIO_VFE_CLK:
		camio_vfe_clk =
		clk = clk_get(NULL, "vfe_clk");
		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
		break;

	case CAMIO_VFE_CAMIF_CLK:
		camio_vfe_camif_clk =
		clk = clk_get(NULL, "vfe_camif_clk");
		break;

	case CAMIO_VFE_PBDG_CLK:
		camio_vfe_pbdg_clk =
		clk = clk_get(NULL, "vfe_pclk");
		break;

	case CAMIO_CAM_MCLK_CLK:
		camio_cam_m_clk =
		clk = clk_get(NULL, "cam_m_clk");
		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
		break;

	case CAMIO_CAMIF_PAD_PBDG_CLK:
		camio_camif_pad_pbdg_clk =
		clk = clk_get(NULL, "camif_pad_pclk");
		break;

	case CAMIO_CSI0_CLK:
		camio_csi_clk =
		clk = clk_get(NULL, "csi_clk");
		msm_camio_clk_rate_set_2(clk, 153600000);
		break;
	case CAMIO_CSI0_VFE_CLK:
		camio_csi_vfe_clk =
		clk = clk_get(NULL, "csi_vfe_clk");
		break;
	case CAMIO_CSI0_PCLK:
		camio_csi_pclk =
		clk = clk_get(NULL, "csi_pclk");
		break;

	case CAMIO_VPE_CLK:
		camio_vpe_clk =
		clk = clk_get(NULL, "vpe_clk");
		vpe_clk_rate = clk_round_rate(clk, vpe_clk_rate);
		clk_set_rate(clk, vpe_clk_rate);
		break;
	default:
		break;
	}

	if (!IS_ERR(clk))
		clk_prepare_enable(clk);
	else
		rc = -1;
	return rc;
}
int msm_camio_jpeg_clk_enable(void)
{
	/* MP*fps*(1 + %blanking)
	   2MP: 24MHz  ------ 2 x 10 x 1.2
	   3MP: 36MHz  ------ 3 x 10 x 1.2
	   5MP: 60MHz  ------ 5 x 10 x 1.2
	   8MP: 96MHz  ------ 8 x 10 x 1.2
	  12MP: 144MHz ------12 x 10 x 1.2
	 */
	int rc = -1;
	u32 rate = 144000000;

	if (jpeg_clk  == NULL) {
		jpeg_clk  = clk_get(NULL, "jpeg_clk");
		if (jpeg_clk  == NULL) {
			pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__,
				rc);
			goto fail;
		}
	}

	rate = clk_round_rate(jpeg_clk, rate);
	rc = clk_set_rate(jpeg_clk, rate);
	if (rc) {
		pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	rc = clk_enable(jpeg_clk);
	if (rc) {
		pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	if (jpeg_pclk == NULL) {
		jpeg_pclk = clk_get(NULL, "jpeg_pclk");
		if (jpeg_pclk == NULL) {
			pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__,
				rc);
			goto fail;
		}
	}

	rc = clk_enable(jpeg_pclk);
	if (rc) {
		pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	/*rc = pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ,
		"msm_gemini", MSM_SYSTEM_BUS_RATE);
	if (rc) {
		GMN_PR_ERR("request AXI bus QOS fails. rc = %d\n", rc);
		goto fail;
	}*/

	return rc;

fail:
	pr_err("[CAM] %s:%d] fail rc = %d\n", __func__, __LINE__, rc);
	return rc;
}
Esempio n. 22
0
static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);

	return clk_round_rate(pltfm_host->clk, UINT_MAX);
}
static int msm_iommu_probe(struct platform_device *pdev)
{
	struct iommu_pmon *pmon_info;
	struct msm_iommu_drvdata *drvdata;
	struct resource *r;
	int ret, needs_alt_core_clk, needs_alt_iface_clk;
	int global_cfg_irq, global_client_irq;
	u32 temp;

	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iommu_base");
	if (!r)
		return -EINVAL;

	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!drvdata->base)
		return -ENOMEM;

	drvdata->phys_base = r->start;

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					"smmu_local_base");
	if (r) {
		drvdata->smmu_local_base =
			devm_ioremap(&pdev->dev, r->start, resource_size(r));
		if (!drvdata->smmu_local_base)
			return -ENOMEM;
	}

	drvdata->glb_base = drvdata->base;

	if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-mmu-500"))
		drvdata->model = MMU_500;

	if (of_get_property(pdev->dev.of_node, "vdd-supply", NULL)) {

		drvdata->gdsc = devm_regulator_get(&pdev->dev, "vdd");
		if (IS_ERR(drvdata->gdsc))
			return PTR_ERR(drvdata->gdsc);

		drvdata->alt_gdsc = devm_regulator_get(&pdev->dev,
							"qcom,alt-vdd");
		if (IS_ERR(drvdata->alt_gdsc))
			drvdata->alt_gdsc = NULL;
	} else {
		pr_debug("Warning: No regulator specified for IOMMU\n");
	}

	drvdata->pclk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(drvdata->pclk))
		return PTR_ERR(drvdata->pclk);

	drvdata->clk = devm_clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(drvdata->clk))
		return PTR_ERR(drvdata->clk);

	needs_alt_core_clk = of_property_read_bool(pdev->dev.of_node,
						   "qcom,needs-alt-core-clk");
	if (needs_alt_core_clk) {
		drvdata->aclk = devm_clk_get(&pdev->dev, "alt_core_clk");
		if (IS_ERR(drvdata->aclk))
			return PTR_ERR(drvdata->aclk);
	}

	needs_alt_iface_clk = of_property_read_bool(pdev->dev.of_node,
						   "qcom,needs-alt-iface-clk");
	if (needs_alt_iface_clk) {
		drvdata->aiclk = devm_clk_get(&pdev->dev, "alt_iface_clk");
		if (IS_ERR(drvdata->aiclk))
			return PTR_ERR(drvdata->aiclk);
	}

	if (!of_property_read_u32(pdev->dev.of_node,
				"qcom,cb-base-offset",
				&temp))
		drvdata->cb_base = drvdata->base + temp;
	else
		drvdata->cb_base = drvdata->base + 0x8000;

	if (clk_get_rate(drvdata->clk) == 0) {
		ret = clk_round_rate(drvdata->clk, 1000);
		clk_set_rate(drvdata->clk, ret);
	}

	if (drvdata->aclk && clk_get_rate(drvdata->aclk) == 0) {
		ret = clk_round_rate(drvdata->aclk, 1000);
		clk_set_rate(drvdata->aclk, ret);
	}

	if (drvdata->aiclk && clk_get_rate(drvdata->aiclk) == 0) {
		ret = clk_round_rate(drvdata->aiclk, 1000);
		clk_set_rate(drvdata->aiclk, ret);
	}

	ret = msm_iommu_parse_dt(pdev, drvdata);
	if (ret)
		return ret;

	dev_info(&pdev->dev,
		"device %s (model: %d) mapped at %p, with %d ctx banks\n",
		drvdata->name, drvdata->model, drvdata->base, drvdata->ncb);

	platform_set_drvdata(pdev, drvdata);

	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
	if (pmon_info != NULL) {
		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
		if (ret) {
			msm_iommu_pm_free(&pdev->dev);
			pr_info("%s: pmon not available.\n", drvdata->name);
		} else {
			pmon_info->iommu.base = drvdata->base;
			pmon_info->iommu.ops = msm_get_iommu_access_ops();
			pmon_info->iommu.hw_ops = iommu_pm_get_hw_ops_v1();
			pmon_info->iommu.iommu_name = drvdata->name;
			ret = msm_iommu_pm_iommu_register(pmon_info);
			if (ret) {
				pr_err("%s iommu register fail\n",
								drvdata->name);
				msm_iommu_pm_free(&pdev->dev);
			} else {
				pr_debug("%s iommu registered for pmon\n",
						pmon_info->iommu.iommu_name);
			}
		}
	}

	global_cfg_irq =
		platform_get_irq_byname(pdev, "global_cfg_NS_irq");
	if (global_cfg_irq > 0) {
		ret = devm_request_threaded_irq(&pdev->dev, global_cfg_irq,
				NULL,
				msm_iommu_global_fault_handler,
				IRQF_ONESHOT | IRQF_SHARED |
				IRQF_TRIGGER_RISING,
				"msm_iommu_global_cfg_irq", pdev);
		if (ret < 0)
			pr_err("Request Global CFG IRQ %d failed with ret=%d\n",
					global_cfg_irq, ret);
	}

	global_client_irq =
		platform_get_irq_byname(pdev, "global_client_NS_irq");
	if (global_client_irq > 0) {
		ret = devm_request_threaded_irq(&pdev->dev, global_client_irq,
				NULL,
				msm_iommu_global_fault_handler,
				IRQF_ONESHOT | IRQF_SHARED |
				IRQF_TRIGGER_RISING,
				"msm_iommu_global_client_irq", pdev);
		if (ret < 0)
			pr_err("Request Global Client IRQ %d failed with ret=%d\n",
					global_client_irq, ret);
	}

	return 0;
}
Esempio n. 24
0
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
{
	int rc = 0;
	struct clk *clk = NULL;

	switch (clktype) {
	case CAMIO_CAM_MCLK_CLK:
		camio_cam_clk =
		clk = clk_get(NULL, "cam_clk");
		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
		break;

	case CAMIO_VFE_CLK:
		camio_vfe_clk =
		clk = clk_get(NULL, "vfe_clk");
		msm_camio_clk_rate_set_2(clk, camio_clk.vfe_clk_rate);
		break;

	case CAMIO_CSI0_VFE_CLK:
		camio_csi0_vfe_clk =
		clk = clk_get(NULL, "csi_vfe_clk");
		break;

	case CAMIO_CSI1_VFE_CLK:
		camio_csi1_vfe_clk =
		clk = clk_get(&camio_dev->dev, "csi_vfe_clk");
		break;

	case CAMIO_CSI_SRC_CLK:
		camio_csi_src_clk =
		clk = clk_get(NULL, "csi_src_clk");
		msm_camio_clk_rate_set_2(clk, 384000000);
		break;

	case CAMIO_CSI0_CLK:
		camio_csi0_clk =
		clk = clk_get(NULL, "csi_clk");
		break;

	case CAMIO_CSI1_CLK:
		camio_csi1_clk =
		clk = clk_get(&camio_dev->dev, "csi_clk");
		break;

	case CAMIO_VFE_PCLK:
		camio_vfe_pclk =
		clk = clk_get(NULL, "vfe_pclk");
		break;

	case CAMIO_CSI0_PCLK:
		camio_csi0_pclk =
		clk = clk_get(NULL, "csi_pclk");
		break;

	case CAMIO_CSI1_PCLK:
		camio_csi1_pclk =
		clk = clk_get(&camio_dev->dev, "csi_pclk");
		break;

	case CAMIO_JPEG_CLK:
		camio_jpeg_clk =
		clk = clk_get(NULL, "ijpeg_clk");
		msm_camio_clk_rate_set_2(clk, 228571000);
		break;

	case CAMIO_JPEG_PCLK:
		camio_jpeg_pclk =
		clk = clk_get(NULL, "ijpeg_pclk");
		break;

	case CAMIO_VPE_CLK:
		camio_vpe_clk =
		clk = clk_get(NULL, "vpe_clk");
		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
		break;

	case CAMIO_VPE_PCLK:
		camio_vpe_pclk =
		clk = clk_get(NULL, "vpe_pclk");
		break;

	default:
		break;
	}

	if (!IS_ERR(clk))
		clk_enable(clk);
	else
		rc = -1;
	return rc;
}
Esempio n. 25
0
/* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/
static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_s3c *ourhost = to_s3c(host);

	return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX);
}
Esempio n. 26
0
File: setup.c Progetto: 168519/linux
static int __init devices_setup(void)
{
	u16 sw = __raw_readw(SW4140); /* select camera, monitor */
	struct clk *clk;
	u16 fpga_out;

	/* register board specific self-refresh code */
	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
					SUSP_SH_RSTANDBY,
					&ms7724se_sdram_enter_start,
					&ms7724se_sdram_enter_end,
					&ms7724se_sdram_leave_start,
					&ms7724se_sdram_leave_end);

	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);

	/* Reset Release */
	fpga_out = __raw_readw(FPGA_OUT);
	/* bit4: NTSC_PDN, bit5: NTSC_RESET */
	fpga_out &= ~((1 << 1)  | /* LAN */
		      (1 << 4)  | /* AK8813 PDN */
		      (1 << 5)  | /* AK8813 RESET */
		      (1 << 6)  | /* VIDEO DAC */
		      (1 << 7)  | /* AK4643 */
		      (1 << 8)  | /* IrDA */
		      (1 << 12) | /* USB0 */
		      (1 << 14)); /* RMII */
	__raw_writew(fpga_out | (1 << 4), FPGA_OUT);

	udelay(10);

	/* AK8813 RESET */
	__raw_writew(fpga_out | (1 << 5), FPGA_OUT);

	udelay(10);

	__raw_writew(fpga_out, FPGA_OUT);

	/* turn on USB clocks, use external clock */
	__raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);

	/* Let LED9 show STATUS2 */
	gpio_request(GPIO_FN_STATUS2, NULL);

	/* Lit LED10 show STATUS0 */
	gpio_request(GPIO_FN_STATUS0, NULL);

	/* Lit LED11 show PDSTATUS */
	gpio_request(GPIO_FN_PDSTATUS, NULL);

	/* enable USB0 port */
	__raw_writew(0x0600, 0xa40501d4);

	/* enable USB1 port */
	__raw_writew(0x0600, 0xa4050192);

	/* enable IRQ 0,1,2 */
	gpio_request(GPIO_FN_INTC_IRQ0, NULL);
	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
	gpio_request(GPIO_FN_INTC_IRQ2, NULL);

	/* enable SCIFA3 */
	gpio_request(GPIO_FN_SCIF3_I_SCK, NULL);
	gpio_request(GPIO_FN_SCIF3_I_RXD, NULL);
	gpio_request(GPIO_FN_SCIF3_I_TXD, NULL);
	gpio_request(GPIO_FN_SCIF3_I_CTS, NULL);
	gpio_request(GPIO_FN_SCIF3_I_RTS, NULL);

	/* enable LCDC */
	gpio_request(GPIO_FN_LCDD23,   NULL);
	gpio_request(GPIO_FN_LCDD22,   NULL);
	gpio_request(GPIO_FN_LCDD21,   NULL);
	gpio_request(GPIO_FN_LCDD20,   NULL);
	gpio_request(GPIO_FN_LCDD19,   NULL);
	gpio_request(GPIO_FN_LCDD18,   NULL);
	gpio_request(GPIO_FN_LCDD17,   NULL);
	gpio_request(GPIO_FN_LCDD16,   NULL);
	gpio_request(GPIO_FN_LCDD15,   NULL);
	gpio_request(GPIO_FN_LCDD14,   NULL);
	gpio_request(GPIO_FN_LCDD13,   NULL);
	gpio_request(GPIO_FN_LCDD12,   NULL);
	gpio_request(GPIO_FN_LCDD11,   NULL);
	gpio_request(GPIO_FN_LCDD10,   NULL);
	gpio_request(GPIO_FN_LCDD9,    NULL);
	gpio_request(GPIO_FN_LCDD8,    NULL);
	gpio_request(GPIO_FN_LCDD7,    NULL);
	gpio_request(GPIO_FN_LCDD6,    NULL);
	gpio_request(GPIO_FN_LCDD5,    NULL);
	gpio_request(GPIO_FN_LCDD4,    NULL);
	gpio_request(GPIO_FN_LCDD3,    NULL);
	gpio_request(GPIO_FN_LCDD2,    NULL);
	gpio_request(GPIO_FN_LCDD1,    NULL);
	gpio_request(GPIO_FN_LCDD0,    NULL);
	gpio_request(GPIO_FN_LCDDISP,  NULL);
	gpio_request(GPIO_FN_LCDHSYN,  NULL);
	gpio_request(GPIO_FN_LCDDCK,   NULL);
	gpio_request(GPIO_FN_LCDVSYN,  NULL);
	gpio_request(GPIO_FN_LCDDON,   NULL);
	gpio_request(GPIO_FN_LCDVEPWC, NULL);
	gpio_request(GPIO_FN_LCDVCPWC, NULL);
	gpio_request(GPIO_FN_LCDRD,    NULL);
	gpio_request(GPIO_FN_LCDLCLK,  NULL);
	__raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);

	/* enable CEU0 */
	gpio_request(GPIO_FN_VIO0_D15, NULL);
	gpio_request(GPIO_FN_VIO0_D14, NULL);
	gpio_request(GPIO_FN_VIO0_D13, NULL);
	gpio_request(GPIO_FN_VIO0_D12, NULL);
	gpio_request(GPIO_FN_VIO0_D11, NULL);
	gpio_request(GPIO_FN_VIO0_D10, NULL);
	gpio_request(GPIO_FN_VIO0_D9,  NULL);
	gpio_request(GPIO_FN_VIO0_D8,  NULL);
	gpio_request(GPIO_FN_VIO0_D7,  NULL);
	gpio_request(GPIO_FN_VIO0_D6,  NULL);
	gpio_request(GPIO_FN_VIO0_D5,  NULL);
	gpio_request(GPIO_FN_VIO0_D4,  NULL);
	gpio_request(GPIO_FN_VIO0_D3,  NULL);
	gpio_request(GPIO_FN_VIO0_D2,  NULL);
	gpio_request(GPIO_FN_VIO0_D1,  NULL);
	gpio_request(GPIO_FN_VIO0_D0,  NULL);
	gpio_request(GPIO_FN_VIO0_VD,  NULL);
	gpio_request(GPIO_FN_VIO0_CLK, NULL);
	gpio_request(GPIO_FN_VIO0_FLD, NULL);
	gpio_request(GPIO_FN_VIO0_HD,  NULL);
	platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20);

	/* enable CEU1 */
	gpio_request(GPIO_FN_VIO1_D7,  NULL);
	gpio_request(GPIO_FN_VIO1_D6,  NULL);
	gpio_request(GPIO_FN_VIO1_D5,  NULL);
	gpio_request(GPIO_FN_VIO1_D4,  NULL);
	gpio_request(GPIO_FN_VIO1_D3,  NULL);
	gpio_request(GPIO_FN_VIO1_D2,  NULL);
	gpio_request(GPIO_FN_VIO1_D1,  NULL);
	gpio_request(GPIO_FN_VIO1_D0,  NULL);
	gpio_request(GPIO_FN_VIO1_FLD, NULL);
	gpio_request(GPIO_FN_VIO1_HD,  NULL);
	gpio_request(GPIO_FN_VIO1_VD,  NULL);
	gpio_request(GPIO_FN_VIO1_CLK, NULL);
	platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20);

	/* KEYSC */
	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
	gpio_request(GPIO_FN_KEYIN4,      NULL);
	gpio_request(GPIO_FN_KEYIN3,      NULL);
	gpio_request(GPIO_FN_KEYIN2,      NULL);
	gpio_request(GPIO_FN_KEYIN1,      NULL);
	gpio_request(GPIO_FN_KEYIN0,      NULL);
	gpio_request(GPIO_FN_KEYOUT3,     NULL);
	gpio_request(GPIO_FN_KEYOUT2,     NULL);
	gpio_request(GPIO_FN_KEYOUT1,     NULL);
	gpio_request(GPIO_FN_KEYOUT0,     NULL);

	/* enable FSI */
	gpio_request(GPIO_FN_FSIMCKA,    NULL);
	gpio_request(GPIO_FN_FSIIASD,    NULL);
	gpio_request(GPIO_FN_FSIOASD,    NULL);
	gpio_request(GPIO_FN_FSIIABCK,   NULL);
	gpio_request(GPIO_FN_FSIIALRCK,  NULL);
	gpio_request(GPIO_FN_FSIOABCK,   NULL);
	gpio_request(GPIO_FN_FSIOALRCK,  NULL);
	gpio_request(GPIO_FN_CLKAUDIOAO, NULL);

	/* set SPU2 clock to 83.4 MHz */
	clk = clk_get(NULL, "spu_clk");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, clk_round_rate(clk, 83333333));
		clk_put(clk);
	}

	/* change parent of FSI A */
	clk = clk_get(NULL, "fsia_clk");
	if (!IS_ERR(clk)) {
		/* 48kHz dummy clock was used to make sure 1/1 divide */
		clk_set_rate(&sh7724_fsimcka_clk, 48000);
		clk_set_parent(clk, &sh7724_fsimcka_clk);
		clk_set_rate(clk, 48000);
		clk_put(clk);
	}

	/* SDHI0 connected to cn7 */
	gpio_request(GPIO_FN_SDHI0CD, NULL);
	gpio_request(GPIO_FN_SDHI0WP, NULL);
	gpio_request(GPIO_FN_SDHI0D3, NULL);
	gpio_request(GPIO_FN_SDHI0D2, NULL);
	gpio_request(GPIO_FN_SDHI0D1, NULL);
	gpio_request(GPIO_FN_SDHI0D0, NULL);
	gpio_request(GPIO_FN_SDHI0CMD, NULL);
	gpio_request(GPIO_FN_SDHI0CLK, NULL);

	/* SDHI1 connected to cn8 */
	gpio_request(GPIO_FN_SDHI1CD, NULL);
	gpio_request(GPIO_FN_SDHI1WP, NULL);
	gpio_request(GPIO_FN_SDHI1D3, NULL);
	gpio_request(GPIO_FN_SDHI1D2, NULL);
	gpio_request(GPIO_FN_SDHI1D1, NULL);
	gpio_request(GPIO_FN_SDHI1D0, NULL);
	gpio_request(GPIO_FN_SDHI1CMD, NULL);
	gpio_request(GPIO_FN_SDHI1CLK, NULL);

	/* enable IrDA */
	gpio_request(GPIO_FN_IRDA_OUT, NULL);
	gpio_request(GPIO_FN_IRDA_IN,  NULL);

	/*
	 * enable SH-Eth
	 *
	 * please remove J33 pin from your board !!
	 *
	 * ms7724 board should not use GPIO_FN_LNKSTA pin
	 * So, This time PTX5 is set to input pin
	 */
	gpio_request(GPIO_FN_RMII_RXD0,    NULL);
	gpio_request(GPIO_FN_RMII_RXD1,    NULL);
	gpio_request(GPIO_FN_RMII_TXD0,    NULL);
	gpio_request(GPIO_FN_RMII_TXD1,    NULL);
	gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
	gpio_request(GPIO_FN_RMII_TX_EN,   NULL);
	gpio_request(GPIO_FN_RMII_RX_ER,   NULL);
	gpio_request(GPIO_FN_RMII_CRS_DV,  NULL);
	gpio_request(GPIO_FN_MDIO,         NULL);
	gpio_request(GPIO_FN_MDC,          NULL);
	gpio_request(GPIO_PTX5, NULL);
	gpio_direction_input(GPIO_PTX5);
	sh_eth_init();

	if (sw & SW41_B) {
		/* 720p */
		lcdc_info.ch[0].lcd_modes = lcdc_720p_modes;
		lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_720p_modes);
	} else {
		/* VGA */
		lcdc_info.ch[0].lcd_modes = lcdc_vga_modes;
		lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_vga_modes);
	}

	if (sw & SW41_A) {
		/* Digital monitor */
		lcdc_info.ch[0].interface_type = RGB18;
		lcdc_info.ch[0].flags          = 0;
	} else {
		/* Analog monitor */
		lcdc_info.ch[0].interface_type = RGB24;
		lcdc_info.ch[0].flags          = LCDC_FLAGS_DWPOL;
	}

	/* VOU */
	gpio_request(GPIO_FN_DV_D15, NULL);
	gpio_request(GPIO_FN_DV_D14, NULL);
	gpio_request(GPIO_FN_DV_D13, NULL);
	gpio_request(GPIO_FN_DV_D12, NULL);
	gpio_request(GPIO_FN_DV_D11, NULL);
	gpio_request(GPIO_FN_DV_D10, NULL);
	gpio_request(GPIO_FN_DV_D9, NULL);
	gpio_request(GPIO_FN_DV_D8, NULL);
	gpio_request(GPIO_FN_DV_CLKI, NULL);
	gpio_request(GPIO_FN_DV_CLK, NULL);
	gpio_request(GPIO_FN_DV_VSYNC, NULL);
	gpio_request(GPIO_FN_DV_HSYNC, NULL);

	return platform_add_devices(ms7724se_devices,
				    ARRAY_SIZE(ms7724se_devices));
}
Esempio n. 27
0
static int mux_set_rate(struct clk *c, unsigned long rate)
{
	struct mux_clk *mux = to_mux_clk(c);
	struct clk *new_parent = NULL;
	int rc = 0, i;
	unsigned long new_par_curr_rate;
	unsigned long flags;

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_SAFE_PARENT_INIT);
#endif

	for (i = 0; i < mux->num_parents && mux->try_get_rate; i++) {
		struct clk *p = mux->parents[i].src;
		if (p->rate == rate && clk_round_rate(p, rate) == rate) {
			new_parent = mux->parents[i].src;
			break;
		}
	}

	for (i = 0; i < mux->num_parents && !(!i && new_parent); i++) {
		if (clk_round_rate(mux->parents[i].src, rate) == rate) {
			new_parent = mux->parents[i].src;
			if (!mux->try_new_parent)
				break;
			if (mux->try_new_parent && new_parent != c->parent)
				break;
		}
	}

	if (new_parent == NULL)
		return -EINVAL;

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_SET_SAFE_RATE);
#endif

	if (mux->safe_sel >= 0 &&
		!(mux->try_new_parent && (new_parent != c->parent))) {
		if (mux->safe_freq) {
			rc = clk_set_rate(mux->safe_parent, mux->safe_freq);
			if (rc) {
				pr_err("Failed to set safe rate on %s\n",
					clk_name(mux->safe_parent));
				return rc;
			}
		}

		spin_lock_irqsave(&c->lock, flags);
		rc = mux->ops->set_mux_sel(mux, mux->safe_sel);
		spin_unlock_irqrestore(&c->lock, flags);
		if (rc)
			return rc;

	}

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_SET_PARENT_RATE);
#endif
	new_par_curr_rate = clk_get_rate(new_parent);
	rc = clk_set_rate(new_parent, rate);
	if (rc)
		goto set_rate_fail;

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_CLK_UNPREPARE);
#endif

	rc = mux_set_parent(c, new_parent);
	if (rc)
		goto set_par_fail;

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_cpu_freq_footprint_by_clk(FT_CUR_RATE, c, rate);
	set_acpuclk_l2_freq_footprint_by_clk(FT_CUR_RATE, c, rate);
#endif

#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_RETURN);
#endif
	return 0;

set_par_fail:
#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_ERR_CLK_UNPREPARE);
#endif
	clk_set_rate(new_parent, new_par_curr_rate);
set_rate_fail:
#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_ERR_SET_PARENT_RATE);
#endif
	WARN(mux->ops->set_mux_sel(mux,
		mux_parent_to_src_sel(mux, c->parent)),
		"Set rate failed for %s. Also in bad state!\n", c->dbg_name);
#if defined(CONFIG_HTC_DEBUG_FOOTPRINT)
	set_acpuclk_footprint_by_clk(c, ACPU_BEFORE_ERR_RETURN);
#endif
	return rc;
}
static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
	struct msm_camera_csiphy_params *csiphy_params)
{
	int rc = 0;
	int j = 0, curr_lane = 0;
	uint32_t val = 0, clk_rate = 0, round_rate = 0;
	uint8_t lane_cnt = 0;
	uint16_t lane_mask = 0;
	void __iomem *csiphybase;
	uint8_t csiphy_id = csiphy_dev->pdev->id;
	int32_t lane_val = 0, lane_right = 0, num_lanes = 0;
	struct clk **csid_phy_clk_ptr;
	int ratio = 1;

	csiphybase = csiphy_dev->base;
	if (!csiphybase) {
		pr_err("%s: csiphybase NULL\n", __func__);
		return -EINVAL;
	}

	csiphy_dev->lane_mask[csiphy_id] |= csiphy_params->lane_mask;
	lane_mask = csiphy_dev->lane_mask[csiphy_id];
	lane_cnt = csiphy_params->lane_cnt;
	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
		pr_err("%s: unsupported lane cnt %d\n",
			__func__, csiphy_params->lane_cnt);
		return rc;
	}

	csid_phy_clk_ptr = csiphy_dev->csiphy_clk;
	if (!csid_phy_clk_ptr) {
		pr_err("csiphy_timer_src_clk get failed\n");
		return -EINVAL;
	}

	clk_rate = (csiphy_params->csiphy_clk > 0)
			? csiphy_params->csiphy_clk :
			csiphy_dev->csiphy_max_clk;
	round_rate = clk_round_rate(
			csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index],
			clk_rate);
	if (round_rate >= csiphy_dev->csiphy_max_clk)
		round_rate = csiphy_dev->csiphy_max_clk;
	else {
		ratio = csiphy_dev->csiphy_max_clk/round_rate;
		csiphy_params->settle_cnt = csiphy_params->settle_cnt/ratio;
	}

	CDBG("set from usr csiphy_clk clk_rate = %u round_rate = %u\n",
			clk_rate, round_rate);
	rc = clk_set_rate(
		csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index],
		round_rate);
	if (rc < 0) {
		pr_err("csiphy_timer_src_clk set failed\n");
		return rc;
	}

	CDBG("%s csiphy_params, mask = 0x%x cnt = %d\n",
		__func__,
		csiphy_params->lane_mask,
		csiphy_params->lane_cnt);
	CDBG("%s csiphy_params, settle cnt = 0x%x csid %d\n",
		__func__, csiphy_params->settle_cnt,
		csiphy_params->csid_core);

	if (csiphy_dev->hw_version >= CSIPHY_VERSION_V30) {
		val = msm_camera_io_r(csiphy_dev->clk_mux_base);
		if (csiphy_params->combo_mode &&
			(csiphy_params->lane_mask & 0x18) == 0x18) {
			val &= ~0xf0;
			val |= csiphy_params->csid_core << 4;
		} else {
			val &= ~0xf;
			val |= csiphy_params->csid_core;
		}
		msm_camera_io_w(val, csiphy_dev->clk_mux_base);
		CDBG("%s clk mux addr %p val 0x%x\n", __func__,
			csiphy_dev->clk_mux_base, val);
		mb();
	}
	msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg->
		csiphy_reg.mipi_csiphy_glbl_t_init_cfg0_addr);
	msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg->
		csiphy_reg.mipi_csiphy_t_wakeup_cfg0_addr);

	if (csiphy_dev->hw_version < CSIPHY_VERSION_V30) {
		val = 0x3;
		msm_camera_io_w((lane_mask << 2) | val,
				csiphybase +
				csiphy_dev->ctrl_reg->
				csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr);
		msm_camera_io_w(0x10, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnck_cfg2_addr);
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnck_cfg3_addr);
		msm_camera_io_w(0x24,
			csiphybase + csiphy_dev->ctrl_reg->
			csiphy_reg.mipi_csiphy_interrupt_mask0_addr);
		msm_camera_io_w(0x24,
			csiphybase + csiphy_dev->ctrl_reg->
			csiphy_reg.mipi_csiphy_interrupt_clear0_addr);
	} else {
		val = 0x1;
		msm_camera_io_w((lane_mask << 1) | val,
				csiphybase +
				csiphy_dev->ctrl_reg->
				csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr);
		msm_camera_io_w(csiphy_params->combo_mode <<
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_mode_config_shift,
			csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_glbl_reset_addr);
	}

	lane_mask &= 0x1f;
	while (lane_mask & 0x1f) {
		if (!(lane_mask & 0x1)) {
			j++;
			lane_mask >>= 1;
			continue;
		}
		msm_camera_io_w(0x10,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg2_addr + 0x40*j);
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg3_addr + 0x40*j);
		/* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) begin*/
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg4_addr + 0x40*j);
		/* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) end*/
		msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_val, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_addr + 0x4*j);
		msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_val, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_clear_addr + 0x4*j);
		if (csiphy_dev->is_3_1_20nm_hw == 1) {
			if (j > CLK_LANE_OFFSET) {
				lane_right = 0x8;
				num_lanes = (lane_cnt - curr_lane)
					<< NUM_LANES_OFFSET;
				if (lane_cnt < curr_lane) {
					pr_err("%s: Lane_cnt is less than curr_lane number\n",
						__func__);
					return -EINVAL;
				}
				lane_val = lane_right|num_lanes;
			} else if (j == 1) {
				lane_val = 0x4;
			}
			if (csiphy_params->combo_mode == 1) {
				/*
				* In the case of combo mode, the clock is always
				* 4th lane for the second sensor.
				* So check whether the sensor is of one lane
				* sensor and curr_lane for 0.
				*/
				if (curr_lane == 0 &&
					((csiphy_params->lane_mask &
						0x18) == 0x18))
					lane_val = 0x4;
			}
			msm_camera_io_w(lane_val, csiphybase +
				csiphy_dev->ctrl_reg->csiphy_reg.
				mipi_csiphy_lnn_misc1_addr + 0x40*j);
			msm_camera_io_w(0x17, csiphybase +
				csiphy_dev->ctrl_reg->csiphy_reg.
				mipi_csiphy_lnn_test_imp + 0x40*j);
			curr_lane++;
		}
		j++;
		lane_mask >>= 1;
	}
Esempio n. 29
0
static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);

	return clk_round_rate(sprd_host->clk_sdio, ULONG_MAX);
}
Esempio n. 30
0
static inline void setup_dotclk_panel(u32 pixel_clk,
				      u16 v_pulse_width,
				      u16 v_period,
				      u16 v_wait_cnt,
				      u16 v_active,
				      u16 h_pulse_width,
				      u16 h_period,
				      u16 h_wait_cnt,
				      u16 h_active,
				      int in_pixel_format,
				      int out_pixel_format,
				      struct elcdif_signal_cfg sig_cfg,
				      int enable_present)
{
	u32 val, rounded_pixel_clk;
	u32 rounded_parent_clk;
	struct clk *clk_parent;

	if (!g_elcdif_axi_clk_enable) {
		clk_enable(g_elcdif_axi_clk);
		g_elcdif_axi_clk_enable = true;
	}

	/* Init clocking */
	dev_dbg(g_elcdif_dev, "pixel clk = %d\n", pixel_clk);

	clk_parent = clk_get_parent(g_elcdif_pix_clk);
	if (clk_parent == NULL)
		dev_err(g_elcdif_dev, "%s Failed get clk parent\n", __func__);

	rounded_pixel_clk = pixel_clk * 2;

	rounded_parent_clk = clk_round_rate(clk_parent,
				rounded_pixel_clk);

	while (rounded_pixel_clk < rounded_parent_clk) {
		/* the max divider from parent to di is 8 */
		if (rounded_parent_clk / pixel_clk < 8)
			rounded_pixel_clk += pixel_clk * 2;
	}

	clk_set_rate(clk_parent, rounded_pixel_clk);
	rounded_pixel_clk =
		clk_round_rate(g_elcdif_pix_clk, pixel_clk);
	clk_set_rate(g_elcdif_pix_clk, rounded_pixel_clk);

	msleep(5);

	__raw_writel(BM_ELCDIF_CTRL_DATA_SHIFT_DIR,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);

	__raw_writel(BM_ELCDIF_CTRL_SHIFT_NUM_BITS,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);

	__raw_writel(BM_ELCDIF_CTRL2_OUTSTANDING_REQS,
		     elcdif_base + HW_ELCDIF_CTRL2_CLR);
	__raw_writel(BF_ELCDIF_CTRL2_OUTSTANDING_REQS
		    (BV_ELCDIF_CTRL2_OUTSTANDING_REQS__REQ_16),
		     elcdif_base + HW_ELCDIF_CTRL2_SET);

	/* Recover on underflow */
	__raw_writel(BM_ELCDIF_CTRL1_RECOVER_ON_UNDERFLOW,
		     elcdif_base + HW_ELCDIF_CTRL1_SET);

	/* Configure the input pixel format */
	__raw_writel(BM_ELCDIF_CTRL_WORD_LENGTH |
		     BM_ELCDIF_CTRL_INPUT_DATA_SWIZZLE |
		     BM_ELCDIF_CTRL_DATA_FORMAT_16_BIT |
		     BM_ELCDIF_CTRL_DATA_FORMAT_18_BIT |
		     BM_ELCDIF_CTRL_DATA_FORMAT_24_BIT,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);
	__raw_writel(BM_ELCDIF_CTRL1_BYTE_PACKING_FORMAT,
		     elcdif_base + HW_ELCDIF_CTRL1_CLR);
	switch (in_pixel_format) {
	case ELCDIF_PIX_FMT_RGB565:
		__raw_writel(BF_ELCDIF_CTRL1_BYTE_PACKING_FORMAT(0xF),
			     elcdif_base + HW_ELCDIF_CTRL1_SET);
		__raw_writel(BF_ELCDIF_CTRL_WORD_LENGTH(0) |
			     BF_ELCDIF_CTRL_INPUT_DATA_SWIZZLE(0),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	case ELCDIF_PIX_FMT_RGB24:
		__raw_writel(BF_ELCDIF_CTRL1_BYTE_PACKING_FORMAT(0xF),
			     elcdif_base + HW_ELCDIF_CTRL1_SET);
		__raw_writel(BF_ELCDIF_CTRL_WORD_LENGTH(3) |
			     BF_ELCDIF_CTRL_INPUT_DATA_SWIZZLE(0),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	case ELCDIF_PIX_FMT_RGB32:
		__raw_writel(BF_ELCDIF_CTRL1_BYTE_PACKING_FORMAT(0x7),
			     elcdif_base + HW_ELCDIF_CTRL1_SET);
		__raw_writel(BF_ELCDIF_CTRL_WORD_LENGTH(3) |
			     BF_ELCDIF_CTRL_INPUT_DATA_SWIZZLE(0),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	default:
		dev_err(g_elcdif_dev, "ELCDIF unsupported input pixel format "
		       "%d\n", in_pixel_format);
		break;
	}

	/* Configure the output pixel format */
	__raw_writel(BM_ELCDIF_CTRL_LCD_DATABUS_WIDTH,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);
	switch (out_pixel_format) {
	case ELCDIF_PIX_FMT_RGB565:
		__raw_writel(BF_ELCDIF_CTRL_LCD_DATABUS_WIDTH(0),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	case ELCDIF_PIX_FMT_RGB666:
		__raw_writel(BF_ELCDIF_CTRL_LCD_DATABUS_WIDTH(2),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	case ELCDIF_PIX_FMT_RGB24:
		__raw_writel(BF_ELCDIF_CTRL_LCD_DATABUS_WIDTH(3),
			     elcdif_base + HW_ELCDIF_CTRL_SET);
		break;
	default:
		dev_err(g_elcdif_dev, "ELCDIF unsupported output pixel format "
		       "%d\n", out_pixel_format);
		break;
	}

	val = __raw_readl(elcdif_base + HW_ELCDIF_TRANSFER_COUNT);
	val &= ~(BM_ELCDIF_TRANSFER_COUNT_V_COUNT |
		 BM_ELCDIF_TRANSFER_COUNT_H_COUNT);
	val |= BF_ELCDIF_TRANSFER_COUNT_H_COUNT(h_active) |
	       BF_ELCDIF_TRANSFER_COUNT_V_COUNT(v_active);
	__raw_writel(val, elcdif_base + HW_ELCDIF_TRANSFER_COUNT);

	__raw_writel(BM_ELCDIF_CTRL_VSYNC_MODE,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);
	__raw_writel(BM_ELCDIF_CTRL_WAIT_FOR_VSYNC_EDGE,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);
	__raw_writel(BM_ELCDIF_CTRL_DVI_MODE,
		     elcdif_base + HW_ELCDIF_CTRL_CLR);
	__raw_writel(BM_ELCDIF_CTRL_DOTCLK_MODE,
		     elcdif_base + HW_ELCDIF_CTRL_SET);
	__raw_writel(BM_ELCDIF_CTRL_BYPASS_COUNT,
		     elcdif_base + HW_ELCDIF_CTRL_SET);

	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL0);
	val &= ~(BM_ELCDIF_VDCTRL0_VSYNC_POL |
		 BM_ELCDIF_VDCTRL0_HSYNC_POL |
		 BM_ELCDIF_VDCTRL0_ENABLE_POL |
		 BM_ELCDIF_VDCTRL0_DOTCLK_POL);
	if (sig_cfg.Vsync_pol)
		val |= BM_ELCDIF_VDCTRL0_VSYNC_POL;
	if (sig_cfg.Hsync_pol)
		val |= BM_ELCDIF_VDCTRL0_HSYNC_POL;
	if (sig_cfg.clk_pol)
		val |= BM_ELCDIF_VDCTRL0_DOTCLK_POL;
	if (sig_cfg.enable_pol)
		val |= BM_ELCDIF_VDCTRL0_ENABLE_POL;
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL0);

	/* vsync is output */
	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL0);
	val &= ~(BM_ELCDIF_VDCTRL0_VSYNC_OEB);
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL0);

	/*
	 * need enable sig for true RGB i/f.  Or, if not true RGB, leave it
	 * zero.
	 */
	if (enable_present) {
		val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL0);
		val |= BM_ELCDIF_VDCTRL0_ENABLE_PRESENT;
		__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL0);
	}

	/*
	 * For DOTCLK mode, count VSYNC_PERIOD in terms of complete hz lines
	 */
	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL0);
	val &= ~(BM_ELCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
		 BM_ELCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT);
	val |= BM_ELCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
	       BM_ELCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL0);

	__raw_writel(BM_ELCDIF_VDCTRL0_VSYNC_PULSE_WIDTH,
		     elcdif_base + HW_ELCDIF_VDCTRL0_CLR);
	__raw_writel(v_pulse_width, elcdif_base + HW_ELCDIF_VDCTRL0_SET);

	__raw_writel(BF_ELCDIF_VDCTRL1_VSYNC_PERIOD(v_period),
		     elcdif_base + HW_ELCDIF_VDCTRL1);

	__raw_writel(BF_ELCDIF_VDCTRL2_HSYNC_PULSE_WIDTH(h_pulse_width) |
		     BF_ELCDIF_VDCTRL2_HSYNC_PERIOD(h_period),
		     elcdif_base + HW_ELCDIF_VDCTRL2);

	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL4);
	val &= ~BM_ELCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT;
	val |= BF_ELCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT(h_active);
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL4);

	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL3);
	val &= ~(BM_ELCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT |
		 BM_ELCDIF_VDCTRL3_VERTICAL_WAIT_CNT);
	val |= BF_ELCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT(h_wait_cnt) |
	       BF_ELCDIF_VDCTRL3_VERTICAL_WAIT_CNT(v_wait_cnt);
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL3);

	val = __raw_readl(elcdif_base + HW_ELCDIF_VDCTRL4);
	val |= BM_ELCDIF_VDCTRL4_SYNC_SIGNALS_ON;
	__raw_writel(val, elcdif_base + HW_ELCDIF_VDCTRL4);

	return;
}