linux/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 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_PHY_TIMING_CTRL_0,
  23                DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
  24        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1,
  25                DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
  26        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2,
  27                DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
  28        if (timing->clk_zero & BIT(8))
  29                dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3,
  30                        DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
  31        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4,
  32                DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
  33        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5,
  34                DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
  35        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6,
  36                DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
  37        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7,
  38                DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
  39        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8,
  40                DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
  41        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9,
  42                DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
  43                DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
  44        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10,
  45                DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
  46        dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11,
  47                DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
  48}
  49
  50static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
  51{
  52        void __iomem *base = phy->reg_base;
  53
  54        if (!enable) {
  55                dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
  56                return;
  57        }
  58
  59        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
  60        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
  61        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
  62        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
  63        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3);
  64        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
  65        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
  66        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
  67}
  68
  69static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
  70                                struct msm_dsi_phy_clk_request *clk_req)
  71{
  72        struct msm_dsi_dphy_timing *timing = &phy->timing;
  73        int i;
  74        void __iomem *base = phy->base;
  75
  76        DBG("");
  77
  78        if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
  79                dev_err(&phy->pdev->dev,
  80                        "%s: D-PHY timing calculation failed\n", __func__);
  81                return -EINVAL;
  82        }
  83
  84        dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff);
  85
  86        dsi_28nm_phy_regulator_ctrl(phy, true);
  87
  88        dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
  89
  90        dsi_28nm_dphy_set_timing(phy, timing);
  91
  92        dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
  93        dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
  94
  95        dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6);
  96
  97        for (i = 0; i < 4; i++) {
  98                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0);
  99                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0);
 100                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0);
 101                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0);
 102                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(i), 0);
 103                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0);
 104                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0);
 105                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1);
 106                dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97);
 107        }
 108
 109        dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_4, 0);
 110        dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0);
 111        dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1);
 112        dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb);
 113
 114        dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
 115
 116        msm_dsi_phy_set_src_pll(phy, src_pll_id,
 117                                REG_DSI_28nm_PHY_GLBL_TEST_CTRL,
 118                                DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL);
 119
 120        return 0;
 121}
 122
 123static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
 124{
 125        dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0);
 126        dsi_28nm_phy_regulator_ctrl(phy, false);
 127
 128        /*
 129         * Wait for the registers writes to complete in order to
 130         * ensure that the phy is completely disabled
 131         */
 132        wmb();
 133}
 134
 135const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
 136        .type = MSM_DSI_PHY_28NM_HPM,
 137        .src_pll_truthtable = { {true, true}, {false, true} },
 138        .reg_cfg = {
 139                .num = 1,
 140                .regs = {
 141                        {"vddio", 100000, 100},
 142                },
 143        },
 144        .ops = {
 145                .enable = dsi_28nm_phy_enable,
 146                .disable = dsi_28nm_phy_disable,
 147                .init = msm_dsi_phy_init_common,
 148        },
 149        .io_start = { 0xfd922b00, 0xfd923100 },
 150        .num_dsi_phy = 2,
 151};
 152
 153const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
 154        .type = MSM_DSI_PHY_28NM_LP,
 155        .src_pll_truthtable = { {true, true}, {true, true} },
 156        .reg_cfg = {
 157                .num = 1,
 158                .regs = {
 159                        {"vddio", 100000, 100}, /* 1.8 V */
 160                },
 161        },
 162        .ops = {
 163                .enable = dsi_28nm_phy_enable,
 164                .disable = dsi_28nm_phy_disable,
 165                .init = msm_dsi_phy_init_common,
 166        },
 167        .io_start = { 0x1a98500 },
 168        .num_dsi_phy = 1,
 169};
 170
 171