123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/err.h>
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/regulator/consumer.h>
- #include <mach/clk.h>
- #include "dsi_v2.h"
- #include "dsi_io_v2.h"
- #include "dsi_host_v2.h"
- struct msm_dsi_io_private {
- struct clk *dsi_byte_clk;
- struct clk *dsi_esc_clk;
- struct clk *dsi_pixel_clk;
- struct clk *dsi_ahb_clk;
- struct clk *dsi_clk;
- int msm_dsi_clk_on;
- int msm_dsi_ahb_clk_on;
- };
- static struct msm_dsi_io_private *dsi_io_private;
- #define DSI_VDDA_VOLTAGE 1200000
- void msm_dsi_ahb_ctrl(int enable)
- {
- if (enable) {
- dsi_io_private->msm_dsi_ahb_clk_on++;
- if (dsi_io_private->msm_dsi_ahb_clk_on == 1)
- clk_enable(dsi_io_private->dsi_ahb_clk);
- } else {
- dsi_io_private->msm_dsi_ahb_clk_on--;
- if (dsi_io_private->msm_dsi_ahb_clk_on == 0)
- clk_disable(dsi_io_private->dsi_ahb_clk);
- }
- }
- int msm_dsi_io_init(struct platform_device *pdev, struct dss_module_power *mp)
- {
- int rc;
- if (!dsi_io_private) {
- dsi_io_private = kzalloc(sizeof(struct msm_dsi_io_private),
- GFP_KERNEL);
- if (!dsi_io_private) {
- pr_err("fail to alloc dsi io private data structure\n");
- return -ENOMEM;
- }
- }
- rc = msm_dsi_clk_init(pdev);
- if (rc) {
- pr_err("fail to initialize DSI clock\n");
- return rc;
- }
- rc = msm_dss_config_vreg(&pdev->dev, mp->vreg_config,
- mp->num_vreg, 1);
- if (rc) {
- pr_err("fail to initialize DSI regulator\n");
- return rc;
- }
- return 0;
- }
- void msm_dsi_io_deinit(struct platform_device *pdev,
- struct dss_module_power *mp)
- {
- if (dsi_io_private) {
- msm_dsi_clk_deinit();
- msm_dss_config_vreg(&pdev->dev, mp->vreg_config,
- mp->num_vreg, 0);
- kfree(dsi_io_private);
- dsi_io_private = NULL;
- }
- }
- int msm_dsi_clk_init(struct platform_device *dev)
- {
- int rc = 0;
- dsi_io_private->dsi_clk = clk_get(&dev->dev, "dsi_clk");
- if (IS_ERR(dsi_io_private->dsi_clk)) {
- pr_err("can't find dsi core_clk\n");
- rc = PTR_ERR(dsi_io_private->dsi_clk);
- dsi_io_private->dsi_clk = NULL;
- return rc;
- }
- dsi_io_private->dsi_byte_clk = clk_get(&dev->dev, "byte_clk");
- if (IS_ERR(dsi_io_private->dsi_byte_clk)) {
- pr_err("can't find dsi byte_clk\n");
- rc = PTR_ERR(dsi_io_private->dsi_byte_clk);
- dsi_io_private->dsi_byte_clk = NULL;
- return rc;
- }
- dsi_io_private->dsi_esc_clk = clk_get(&dev->dev, "esc_clk");
- if (IS_ERR(dsi_io_private->dsi_esc_clk)) {
- pr_err("can't find dsi esc_clk\n");
- rc = PTR_ERR(dsi_io_private->dsi_esc_clk);
- dsi_io_private->dsi_esc_clk = NULL;
- return rc;
- }
- dsi_io_private->dsi_pixel_clk = clk_get(&dev->dev, "pixel_clk");
- if (IS_ERR(dsi_io_private->dsi_pixel_clk)) {
- pr_err("can't find dsi pixel\n");
- rc = PTR_ERR(dsi_io_private->dsi_pixel_clk);
- dsi_io_private->dsi_pixel_clk = NULL;
- return rc;
- }
- dsi_io_private->dsi_ahb_clk = clk_get(&dev->dev, "iface_clk");
- if (IS_ERR(dsi_io_private->dsi_ahb_clk)) {
- pr_err("can't find dsi iface_clk\n");
- rc = PTR_ERR(dsi_io_private->dsi_ahb_clk);
- dsi_io_private->dsi_ahb_clk = NULL;
- return rc;
- }
- clk_prepare(dsi_io_private->dsi_ahb_clk);
- return 0;
- }
- void msm_dsi_clk_deinit(void)
- {
- if (dsi_io_private->dsi_clk) {
- clk_put(dsi_io_private->dsi_clk);
- dsi_io_private->dsi_clk = NULL;
- }
- if (dsi_io_private->dsi_byte_clk) {
- clk_put(dsi_io_private->dsi_byte_clk);
- dsi_io_private->dsi_byte_clk = NULL;
- }
- if (dsi_io_private->dsi_esc_clk) {
- clk_put(dsi_io_private->dsi_esc_clk);
- dsi_io_private->dsi_esc_clk = NULL;
- }
- if (dsi_io_private->dsi_pixel_clk) {
- clk_put(dsi_io_private->dsi_pixel_clk);
- dsi_io_private->dsi_pixel_clk = NULL;
- }
- if (dsi_io_private->dsi_ahb_clk) {
- clk_unprepare(dsi_io_private->dsi_ahb_clk);
- clk_put(dsi_io_private->dsi_ahb_clk);
- dsi_io_private->dsi_ahb_clk = NULL;
- }
- }
- int msm_dsi_prepare_clocks(void)
- {
- clk_prepare(dsi_io_private->dsi_clk);
- clk_prepare(dsi_io_private->dsi_byte_clk);
- clk_prepare(dsi_io_private->dsi_esc_clk);
- clk_prepare(dsi_io_private->dsi_pixel_clk);
- return 0;
- }
- int msm_dsi_unprepare_clocks(void)
- {
- clk_unprepare(dsi_io_private->dsi_clk);
- clk_unprepare(dsi_io_private->dsi_esc_clk);
- clk_unprepare(dsi_io_private->dsi_byte_clk);
- clk_unprepare(dsi_io_private->dsi_pixel_clk);
- return 0;
- }
- int msm_dsi_clk_set_rate(unsigned long esc_rate,
- unsigned long dsi_rate,
- unsigned long byte_rate,
- unsigned long pixel_rate)
- {
- int rc;
- rc = clk_set_rate(dsi_io_private->dsi_clk, dsi_rate);
- if (rc) {
- pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
- return rc;
- }
- rc = clk_set_rate(dsi_io_private->dsi_esc_clk, esc_rate);
- if (rc) {
- pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
- return rc;
- }
- rc = clk_set_rate(dsi_io_private->dsi_byte_clk, byte_rate);
- if (rc) {
- pr_err("dsi_byte_clk - clk_set_rate faile = %dd\n", rc);
- return rc;
- }
- rc = clk_set_rate(dsi_io_private->dsi_pixel_clk, pixel_rate);
- if (rc) {
- pr_err("dsi_pixel_clk - clk_set_rate failed = %d\n", rc);
- return rc;
- }
- return 0;
- }
- int msm_dsi_clk_enable(void)
- {
- if (dsi_io_private->msm_dsi_clk_on) {
- pr_debug("dsi_clks on already\n");
- return 0;
- }
- clk_enable(dsi_io_private->dsi_clk);
- clk_enable(dsi_io_private->dsi_esc_clk);
- clk_enable(dsi_io_private->dsi_byte_clk);
- clk_enable(dsi_io_private->dsi_pixel_clk);
- dsi_io_private->msm_dsi_clk_on = 1;
- return 0;
- }
- int msm_dsi_clk_disable(void)
- {
- if (dsi_io_private->msm_dsi_clk_on == 0) {
- pr_debug("mdss_dsi_clks already OFF\n");
- return 0;
- }
- clk_disable(dsi_io_private->dsi_clk);
- clk_disable(dsi_io_private->dsi_byte_clk);
- clk_disable(dsi_io_private->dsi_esc_clk);
- clk_disable(dsi_io_private->dsi_pixel_clk);
- dsi_io_private->msm_dsi_clk_on = 0;
- return 0;
- }
- static void msm_dsi_phy_strength_init(unsigned char *ctrl_base,
- struct mdss_dsi_phy_ctrl *pd)
- {
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_STRENGTH_CTRL_0, pd->strength[0]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_STRENGTH_CTRL_2, pd->strength[1]);
- }
- static void msm_dsi_phy_ctrl_init(unsigned char *ctrl_base,
- struct mdss_panel_data *pdata)
- {
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_0, 0x5f);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_3, 0x10);
- }
- static void msm_dsi_phy_regulator_init(unsigned char *ctrl_base,
- struct mdss_dsi_phy_ctrl *pd)
- {
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_LDO_CNTRL, 0x25);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_0, pd->regulator[0]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_1, pd->regulator[1]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_2, pd->regulator[2]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_3, pd->regulator[3]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_4, pd->regulator[4]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CAL_PWR_CFG,
- pd->regulator[5]);
- }
- static int msm_dsi_phy_calibration(unsigned char *ctrl_base)
- {
- int i = 0, term_cnt = 5000, ret = 0, cal_busy;
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_SW_CFG2, 0x0);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG1, 0x5a);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG3, 0x10);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG4, 0x01);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG0, 0x01);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_TRIGGER, 0x01);
- usleep_range(5000, 5000); /*per DSI controller spec*/
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_TRIGGER, 0x00);
- cal_busy = MIPI_INP(ctrl_base + DSI_DSIPHY_REGULATOR_CAL_STATUS0);
- while (cal_busy & 0x10) {
- i++;
- if (i > term_cnt) {
- ret = -EINVAL;
- pr_err("msm_dsi_phy_calibration error\n");
- break;
- }
- cal_busy = MIPI_INP(ctrl_base +
- DSI_DSIPHY_REGULATOR_CAL_STATUS0);
- }
- return ret;
- }
- static void msm_dsi_phy_lane_init(unsigned char *ctrl_base,
- struct mdss_dsi_phy_ctrl *pd)
- {
- int ln, index;
- /*CFG0, CFG1, CFG2, TEST_DATAPATH, TEST_STR0, TEST_STR1*/
- for (ln = 0; ln < 5; ln++) {
- unsigned char *off = ctrl_base + 0x0300 + (ln * 0x40);
- index = ln * 6;
- MIPI_OUTP(off, pd->lanecfg[index]);
- MIPI_OUTP(off + 4, pd->lanecfg[index + 1]);
- MIPI_OUTP(off + 8, pd->lanecfg[index + 2]);
- MIPI_OUTP(off + 12, pd->lanecfg[index + 3]);
- MIPI_OUTP(off + 20, pd->lanecfg[index + 4]);
- MIPI_OUTP(off + 24, pd->lanecfg[index + 5]);
- }
- wmb();
- }
- static void msm_dsi_phy_timing_init(unsigned char *ctrl_base,
- struct mdss_dsi_phy_ctrl *pd)
- {
- int i, off = DSI_DSIPHY_TIMING_CTRL_0;
- for (i = 0; i < 12; i++) {
- MIPI_OUTP(ctrl_base + off, pd->timing[i]);
- off += 4;
- }
- wmb();
- }
- static void msm_dsi_phy_bist_init(unsigned char *ctrl_base,
- struct mdss_dsi_phy_ctrl *pd)
- {
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL4, pd->bistctrl[4]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL1, pd->bistctrl[1]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL0, pd->bistctrl[0]);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL4, 0);
- wmb();
- }
- int msm_dsi_phy_init(unsigned char *ctrl_base,
- struct mdss_panel_data *pdata)
- {
- struct mdss_dsi_phy_ctrl *pd;
- pd = &(pdata->panel_info.mipi.dsi_phy_db);
- msm_dsi_phy_strength_init(ctrl_base, pd);
- msm_dsi_phy_ctrl_init(ctrl_base, pdata);
- msm_dsi_phy_regulator_init(ctrl_base, pd);
- msm_dsi_phy_calibration(ctrl_base);
- msm_dsi_phy_lane_init(ctrl_base, pd);
- msm_dsi_phy_timing_init(ctrl_base, pd);
- msm_dsi_phy_bist_init(ctrl_base, pd);
- return 0;
- }
- void msm_dsi_phy_sw_reset(unsigned char *ctrl_base)
- {
- /* start phy sw reset */
- MIPI_OUTP(ctrl_base + DSI_PHY_SW_RESET, 0x0001);
- udelay(1000); /*per DSI controller spec*/
- wmb();
- /* end phy sw reset */
- MIPI_OUTP(ctrl_base + DSI_PHY_SW_RESET, 0x0000);
- udelay(100); /*per DSI controller spec*/
- wmb();
- }
- void msm_dsi_phy_off(unsigned char *ctrl_base)
- {
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_PLL_CTRL_5, 0x05f);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_0, 0x02);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_0, 0x00);
- MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_1, 0x7f);
- MIPI_OUTP(ctrl_base + DSI_CLK_CTRL, 0);
- }
|