linux/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 and
   6 * only version 2 as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#include "dsi_phy.h"
  15#include "dsi.xml.h"
  16
  17static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
  18                struct msm_dsi_dphy_timing *timing)
  19{
  20        void __iomem *base = phy->base;
  21
  22        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0,
  23                DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
  24        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1,
  25                DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
  26        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2,
  27                DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
  28        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3, 0x0);
  29        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4,
  30                DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
  31        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5,
  32                DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
  33        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6,
  34                DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
  35        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7,
  36                DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
  37        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8,
  38                DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
  39        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9,
  40                DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
  41                DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
  42        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10,
  43                DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
  44        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11,
  45                DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
  46}
  47
  48static void dsi_28nm_phy_regulator_init(struct msm_dsi_phy *phy)
  49{
  50        void __iomem *base = phy->reg_base;
  51
  52        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
  53        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 1);
  54        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 1);
  55        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0);
  56        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4,
  57                0x100);
  58}
  59
  60static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy)
  61{
  62        void __iomem *base = phy->reg_base;
  63
  64        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
  65        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 0xa);
  66        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 0x4);
  67        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0x0);
  68        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4, 0x20);
  69}
  70
  71static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy)
  72{
  73        void __iomem *base = phy->reg_base;
  74        u32 status;
  75        int i = 5000;
  76
  77        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG,
  78                        0x3);
  79
  80        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2, 0x0);
  81        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1, 0x5a);
  82        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3, 0x10);
  83        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4, 0x1);
  84        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0, 0x1);
  85
  86        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x1);
  87        usleep_range(5000, 6000);
  88        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x0);
  89
  90        do {
  91                status = dsi_phy_read(base +
  92                                REG_DSI_28nm_8960_PHY_MISC_CAL_STATUS);
  93
  94                if (!(status & DSI_28nm_8960_PHY_MISC_CAL_STATUS_CAL_BUSY))
  95                        break;
  96
  97                udelay(1);
  98        } while (--i > 0);
  99}
 100
 101static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy)
 102{
 103        void __iomem *base = phy->base;
 104        int i;
 105
 106        for (i = 0; i < 4; i++) {
 107                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i), 0x80);
 108                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i), 0x45);
 109                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i), 0x00);
 110                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i),
 111                        0x00);
 112                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i),
 113                        0x01);
 114                dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i),
 115                        0x66);
 116        }
 117
 118        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0, 0x40);
 119        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1, 0x67);
 120        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2, 0x0);
 121        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH, 0x0);
 122        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0, 0x1);
 123        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1, 0x88);
 124}
 125
 126static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
 127                                struct msm_dsi_phy_clk_request *clk_req)
 128{
 129        struct msm_dsi_dphy_timing *timing = &phy->timing;
 130        void __iomem *base = phy->base;
 131
 132        DBG("");
 133
 134        if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
 135                dev_err(&phy->pdev->dev,
 136                        "%s: D-PHY timing calculation failed\n", __func__);
 137                return -EINVAL;
 138        }
 139
 140        dsi_28nm_phy_regulator_init(phy);
 141
 142        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LDO_CTRL, 0x04);
 143
 144        /* strength control */
 145        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_0, 0xff);
 146        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_1, 0x00);
 147        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_2, 0x06);
 148
 149        /* phy ctrl */
 150        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x5f);
 151        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_1, 0x00);
 152        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_2, 0x00);
 153        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_3, 0x10);
 154
 155        dsi_28nm_phy_regulator_ctrl(phy);
 156
 157        dsi_28nm_phy_calibration(phy);
 158
 159        dsi_28nm_phy_lane_config(phy);
 160
 161        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0f);
 162        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1, 0x03);
 163        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0, 0x03);
 164        dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0);
 165
 166        dsi_28nm_dphy_set_timing(phy, timing);
 167
 168        return 0;
 169}
 170
 171static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
 172{
 173        dsi_phy_write(phy->base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x0);
 174
 175        /*
 176         * Wait for the registers writes to complete in order to
 177         * ensure that the phy is completely disabled
 178         */
 179        wmb();
 180}
 181
 182const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = {
 183        .type = MSM_DSI_PHY_28NM_8960,
 184        .src_pll_truthtable = { {true, true}, {false, true} },
 185        .reg_cfg = {
 186                .num = 1,
 187                .regs = {
 188                        {"vddio", 100000, 100}, /* 1.8 V */
 189                },
 190        },
 191        .ops = {
 192                .enable = dsi_28nm_phy_enable,
 193                .disable = dsi_28nm_phy_disable,
 194                .init = msm_dsi_phy_init_common,
 195        },
 196        .io_start = { 0x4700300, 0x5800300 },
 197        .num_dsi_phy = 2,
 198};
 199