uboot/drivers/video/rockchip/rk_mipi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
   4 * Author: Eric Gao <eric.gao@rock-chips.com>
   5 */
   6
   7#include <common.h>
   8#include <clk.h>
   9#include <display.h>
  10#include <dm.h>
  11#include <log.h>
  12#include <panel.h>
  13#include <regmap.h>
  14#include <asm/global_data.h>
  15#include "rk_mipi.h"
  16#include <syscon.h>
  17#include <asm/gpio.h>
  18#include <asm/io.h>
  19#include <dm/uclass-internal.h>
  20#include <linux/kernel.h>
  21#include <asm/arch-rockchip/clock.h>
  22#include <asm/arch-rockchip/cru.h>
  23#include <asm/arch-rockchip/grf_rk3399.h>
  24#include <asm/arch-rockchip/rockchip_mipi_dsi.h>
  25
  26DECLARE_GLOBAL_DATA_PTR;
  27
  28int rk_mipi_read_timing(struct udevice *dev,
  29                        struct display_timing *timing)
  30{
  31        int ret;
  32
  33        ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, timing);
  34        if (ret) {
  35                debug("%s: Failed to decode display timing (ret=%d)\n",
  36                      __func__, ret);
  37                return -EINVAL;
  38        }
  39
  40        return 0;
  41}
  42
  43/*
  44 * Register write function used only for mipi dsi controller.
  45 * Parameter:
  46 *  @regs: mipi controller address
  47 *  @reg: combination of regaddr(16bit)|bitswidth(8bit)|offset(8bit) you can
  48 *        use define in rk_mipi.h directly for this parameter
  49 *  @val: value that will be write to specified bits of register
  50 */
  51static void rk_mipi_dsi_write(uintptr_t regs, u32 reg, u32 val)
  52{
  53        u32 dat;
  54        u32 mask;
  55        u32 offset = (reg >> OFFSET_SHIFT) & 0xff;
  56        u32 bits = (reg >> BITS_SHIFT) & 0xff;
  57        uintptr_t addr = (reg >> ADDR_SHIFT) + regs;
  58
  59        /* Mask for specifiled bits,the corresponding bits will be clear */
  60        mask = ~((0xffffffff << offset) & (0xffffffff >> (32 - offset - bits)));
  61
  62        /* Make sure val in the available range */
  63        val &= ~(0xffffffff << bits);
  64
  65        /* Get register's original val */
  66        dat = readl(addr);
  67
  68        /* Clear specified bits */
  69        dat &= mask;
  70
  71        /* Fill specified bits */
  72        dat |= val << offset;
  73
  74        writel(dat, addr);
  75}
  76
  77int rk_mipi_dsi_enable(struct udevice *dev,
  78                       const struct display_timing *timing)
  79{
  80        ofnode node, timing_node;
  81        int val;
  82        struct rk_mipi_priv *priv = dev_get_priv(dev);
  83        uintptr_t regs = priv->regs;
  84        u32 txbyte_clk = priv->txbyte_clk;
  85        u32 txesc_clk = priv->txesc_clk;
  86
  87        txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1);
  88
  89        /* Set Display timing parameter */
  90        rk_mipi_dsi_write(regs, VID_HSA_TIME, timing->hsync_len.typ);
  91        rk_mipi_dsi_write(regs, VID_HBP_TIME, timing->hback_porch.typ);
  92        rk_mipi_dsi_write(regs, VID_HLINE_TIME, (timing->hsync_len.typ
  93                          + timing->hback_porch.typ + timing->hactive.typ
  94                          + timing->hfront_porch.typ));
  95        rk_mipi_dsi_write(regs, VID_VSA_LINES, timing->vsync_len.typ);
  96        rk_mipi_dsi_write(regs, VID_VBP_LINES, timing->vback_porch.typ);
  97        rk_mipi_dsi_write(regs, VID_VFP_LINES, timing->vfront_porch.typ);
  98        rk_mipi_dsi_write(regs, VID_ACTIVE_LINES, timing->vactive.typ);
  99
 100        /* Set Signal Polarity */
 101        val = (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) ? 1 : 0;
 102        rk_mipi_dsi_write(regs, HSYNC_ACTIVE_LOW, val);
 103
 104        val = (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) ? 1 : 0;
 105        rk_mipi_dsi_write(regs, VSYNC_ACTIVE_LOW, val);
 106
 107        val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
 108        rk_mipi_dsi_write(regs, DATAEN_ACTIVE_LOW, val);
 109
 110        val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
 111        rk_mipi_dsi_write(regs, COLORM_ACTIVE_LOW, val);
 112
 113        /* Set video mode */
 114        rk_mipi_dsi_write(regs, CMD_VIDEO_MODE, VIDEO_MODE);
 115
 116        /* Set video mode transmission type as burst mode */
 117        rk_mipi_dsi_write(regs, VID_MODE_TYPE, BURST_MODE);
 118
 119        /* Set pix num in a video package */
 120        rk_mipi_dsi_write(regs, VID_PKT_SIZE, 0x4b0);
 121
 122        /* Set dpi color coding depth 24 bit */
 123        timing_node = ofnode_find_subnode(dev_ofnode(dev), "display-timings");
 124        node = ofnode_first_subnode(timing_node);
 125
 126        val = ofnode_read_u32_default(node, "bits-per-pixel", -1);
 127        switch (val) {
 128        case 16:
 129                rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_16BIT_CFG_1);
 130                break;
 131        case 24:
 132                rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
 133                break;
 134        case 30:
 135                rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_30BIT);
 136                break;
 137        default:
 138                rk_mipi_dsi_write(regs, DPI_COLOR_CODING, DPI_24BIT);
 139        }
 140        /* Enable low power mode */
 141        rk_mipi_dsi_write(regs, LP_CMD_EN, 1);
 142        rk_mipi_dsi_write(regs, LP_HFP_EN, 1);
 143        rk_mipi_dsi_write(regs, LP_VACT_EN, 1);
 144        rk_mipi_dsi_write(regs, LP_VFP_EN, 1);
 145        rk_mipi_dsi_write(regs, LP_VBP_EN, 1);
 146        rk_mipi_dsi_write(regs, LP_VSA_EN, 1);
 147
 148        /* Division for timeout counter clk */
 149        rk_mipi_dsi_write(regs, TO_CLK_DIVISION, 0x0a);
 150
 151        /* Tx esc clk division from txbyte clk */
 152        rk_mipi_dsi_write(regs, TX_ESC_CLK_DIVISION, txbyte_clk/txesc_clk);
 153
 154        /* Timeout count for hs<->lp transation between Line period */
 155        rk_mipi_dsi_write(regs, HSTX_TO_CNT, 0x3e8);
 156
 157        /* Phy State transfer timing */
 158        rk_mipi_dsi_write(regs, PHY_STOP_WAIT_TIME, 32);
 159        rk_mipi_dsi_write(regs, PHY_TXREQUESTCLKHS, 1);
 160        rk_mipi_dsi_write(regs, PHY_HS2LP_TIME, 0x14);
 161        rk_mipi_dsi_write(regs, PHY_LP2HS_TIME, 0x10);
 162        rk_mipi_dsi_write(regs, MAX_RD_TIME, 0x2710);
 163
 164        /* Power on */
 165        rk_mipi_dsi_write(regs, SHUTDOWNZ, 1);
 166
 167        return 0;
 168}
 169
 170/* rk mipi dphy write function. It is used to write test data to dphy */
 171static void rk_mipi_phy_write(uintptr_t regs, unsigned char test_code,
 172                              unsigned char *test_data, unsigned char size)
 173{
 174        int i = 0;
 175
 176        /* Write Test code */
 177        rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
 178        rk_mipi_dsi_write(regs, PHY_TESTDIN, test_code);
 179        rk_mipi_dsi_write(regs, PHY_TESTEN, 1);
 180        rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
 181        rk_mipi_dsi_write(regs, PHY_TESTEN, 0);
 182
 183        /* Write Test data */
 184        for (i = 0; i < size; i++) {
 185                rk_mipi_dsi_write(regs, PHY_TESTCLK, 0);
 186                rk_mipi_dsi_write(regs, PHY_TESTDIN, test_data[i]);
 187                rk_mipi_dsi_write(regs, PHY_TESTCLK, 1);
 188        }
 189}
 190
 191/*
 192 * Mipi dphy config function. Calculate the suitable prediv, feedback div,
 193 * fsfreqrang value ,cap ,lpf and so on according to the given pix clk rate,
 194 * and then enable phy.
 195 */
 196int rk_mipi_phy_enable(struct udevice *dev)
 197{
 198        int i;
 199        struct rk_mipi_priv *priv = dev_get_priv(dev);
 200        uintptr_t regs = priv->regs;
 201        u64 fbdiv;
 202        u64 prediv = 1;
 203        u32 max_fbdiv = 512;
 204        u32 max_prediv, min_prediv;
 205        u64 ddr_clk = priv->phy_clk;
 206        u32 refclk = priv->ref_clk;
 207        u32 remain = refclk;
 208        unsigned char test_data[2] = {0};
 209
 210        int freq_rang[][2] = {
 211                {90, 0x01},   {100, 0x10},  {110, 0x20},  {130, 0x01},
 212                {140, 0x11},  {150, 0x21},  {170, 0x02},  {180, 0x12},
 213                {200, 0x22},  {220, 0x03},  {240, 0x13},  {250, 0x23},
 214                {270, 0x04},  {300, 0x14},  {330, 0x05},  {360, 0x15},
 215                {400, 0x25},  {450, 0x06},  {500, 0x16},  {550, 0x07},
 216                {600, 0x17},  {650, 0x08},  {700, 0x18},  {750, 0x09},
 217                {800, 0x19},  {850, 0x29},  {900, 0x39},  {950, 0x0a},
 218                {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
 219                {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
 220                {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
 221        };
 222
 223        /* Shutdown mode */
 224        rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 0);
 225        rk_mipi_dsi_write(regs, PHY_RSTZ, 0);
 226        rk_mipi_dsi_write(regs, PHY_TESTCLR, 1);
 227
 228        /* Pll locking */
 229        rk_mipi_dsi_write(regs, PHY_TESTCLR, 0);
 230
 231        /* config cp and lfp */
 232        test_data[0] = 0x80 | (ddr_clk / (200 * MHz)) << 3 | 0x3;
 233        rk_mipi_phy_write(regs, CODE_PLL_VCORANGE_VCOCAP, test_data, 1);
 234
 235        test_data[0] = 0x8;
 236        rk_mipi_phy_write(regs, CODE_PLL_CPCTRL, test_data, 1);
 237
 238        test_data[0] = 0x80 | 0x40;
 239        rk_mipi_phy_write(regs, CODE_PLL_LPF_CP, test_data, 1);
 240
 241        /* select the suitable value for fsfreqrang reg */
 242        for (i = 0; i < ARRAY_SIZE(freq_rang); i++) {
 243                if (ddr_clk / (MHz) <= freq_rang[i][0])
 244                        break;
 245        }
 246        if (i == ARRAY_SIZE(freq_rang)) {
 247                debug("%s: Dphy freq out of range!\n", __func__);
 248                return -EINVAL;
 249        }
 250        test_data[0] = freq_rang[i][1] << 1;
 251        rk_mipi_phy_write(regs, CODE_HS_RX_LANE0, test_data, 1);
 252
 253        /*
 254         * Calculate the best ddrclk and it's corresponding div value. If the
 255         * given pixelclock is great than 250M, ddrclk will be fix 1500M.
 256         * Otherwise,
 257         * it's equal to ddr_clk= pixclk * 6. 40MHz >= refclk / prediv >= 5MHz
 258         * according to spec.
 259         */
 260        max_prediv = (refclk / (5 * MHz));
 261        min_prediv = ((refclk / (40 * MHz)) ? (refclk / (40 * MHz) + 1) : 1);
 262
 263        debug("%s: DEBUG: max_prediv=%u, min_prediv=%u\n", __func__, max_prediv,
 264              min_prediv);
 265
 266        if (max_prediv < min_prediv) {
 267                debug("%s: Invalid refclk value\n", __func__);
 268                return -EINVAL;
 269        }
 270
 271        /* Calculate the best refclk and feedback division value for dphy pll */
 272        for (i = min_prediv; i < max_prediv; i++) {
 273                if ((ddr_clk * i % refclk < remain) &&
 274                    (ddr_clk * i / refclk) < max_fbdiv) {
 275                        prediv = i;
 276                        remain = ddr_clk * i % refclk;
 277                }
 278        }
 279        fbdiv = ddr_clk * prediv / refclk;
 280        ddr_clk = refclk * fbdiv / prediv;
 281        priv->phy_clk = ddr_clk;
 282
 283        debug("%s: DEBUG: refclk=%u, refclk=%llu, fbdiv=%llu, phyclk=%llu\n",
 284              __func__, refclk, prediv, fbdiv, ddr_clk);
 285
 286        /* config prediv and feedback reg */
 287        test_data[0] = prediv - 1;
 288        rk_mipi_phy_write(regs, CODE_PLL_INPUT_DIV_RAT, test_data, 1);
 289        test_data[0] = (fbdiv - 1) & 0x1f;
 290        rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
 291        test_data[0] = (fbdiv - 1) >> 5 | 0x80;
 292        rk_mipi_phy_write(regs, CODE_PLL_LOOP_DIV_RAT, test_data, 1);
 293        test_data[0] = 0x30;
 294        rk_mipi_phy_write(regs, CODE_PLL_INPUT_LOOP_DIV_RAT, test_data, 1);
 295
 296        /* rest config */
 297        test_data[0] = 0x4d;
 298        rk_mipi_phy_write(regs, CODE_BANDGAP_BIAS_CTRL, test_data, 1);
 299
 300        test_data[0] = 0x3d;
 301        rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
 302
 303        test_data[0] = 0xdf;
 304        rk_mipi_phy_write(regs, CODE_TERMINATION_CTRL, test_data, 1);
 305
 306        test_data[0] =  0x7;
 307        rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
 308
 309        test_data[0] = 0x80 | 0x7;
 310        rk_mipi_phy_write(regs, CODE_AFE_BIAS_BANDGAP_ANOLOG, test_data, 1);
 311
 312        test_data[0] = 0x80 | 15;
 313        rk_mipi_phy_write(regs, CODE_HSTXDATALANEREQUSETSTATETIME,
 314                          test_data, 1);
 315        test_data[0] = 0x80 | 85;
 316        rk_mipi_phy_write(regs, CODE_HSTXDATALANEPREPARESTATETIME,
 317                          test_data, 1);
 318        test_data[0] = 0x40 | 10;
 319        rk_mipi_phy_write(regs, CODE_HSTXDATALANEHSZEROSTATETIME,
 320                          test_data, 1);
 321
 322        /* enter into stop mode */
 323        rk_mipi_dsi_write(regs, N_LANES, 0x03);
 324        rk_mipi_dsi_write(regs, PHY_ENABLECLK, 1);
 325        rk_mipi_dsi_write(regs, PHY_FORCEPLL, 1);
 326        rk_mipi_dsi_write(regs, PHY_SHUTDOWNZ, 1);
 327        rk_mipi_dsi_write(regs, PHY_RSTZ, 1);
 328
 329        return 0;
 330}
 331