linux/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <linux/clk-provider.h>
   7#include <linux/platform_device.h>
   8#include <dt-bindings/phy/phy.h>
   9
  10#include "dsi_phy.h"
  11
  12#define S_DIV_ROUND_UP(n, d)    \
  13        (((n) >= 0) ? (((n) + (d) - 1) / (d)) : (((n) - (d) + 1) / (d)))
  14
  15static inline s32 linear_inter(s32 tmax, s32 tmin, s32 percent,
  16                                s32 min_result, bool even)
  17{
  18        s32 v;
  19
  20        v = (tmax - tmin) * percent;
  21        v = S_DIV_ROUND_UP(v, 100) + tmin;
  22        if (even && (v & 0x1))
  23                return max_t(s32, min_result, v - 1);
  24        else
  25                return max_t(s32, min_result, v);
  26}
  27
  28static void dsi_dphy_timing_calc_clk_zero(struct msm_dsi_dphy_timing *timing,
  29                                        s32 ui, s32 coeff, s32 pcnt)
  30{
  31        s32 tmax, tmin, clk_z;
  32        s32 temp;
  33
  34        /* reset */
  35        temp = 300 * coeff - ((timing->clk_prepare >> 1) + 1) * 2 * ui;
  36        tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  37        if (tmin > 255) {
  38                tmax = 511;
  39                clk_z = linear_inter(2 * tmin, tmin, pcnt, 0, true);
  40        } else {
  41                tmax = 255;
  42                clk_z = linear_inter(tmax, tmin, pcnt, 0, true);
  43        }
  44
  45        /* adjust */
  46        temp = (timing->hs_rqst + timing->clk_prepare + clk_z) & 0x7;
  47        timing->clk_zero = clk_z + 8 - temp;
  48}
  49
  50int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
  51                             struct msm_dsi_phy_clk_request *clk_req)
  52{
  53        const unsigned long bit_rate = clk_req->bitclk_rate;
  54        const unsigned long esc_rate = clk_req->escclk_rate;
  55        s32 ui, lpx;
  56        s32 tmax, tmin;
  57        s32 pcnt0 = 10;
  58        s32 pcnt1 = (bit_rate > 1200000000) ? 15 : 10;
  59        s32 pcnt2 = 10;
  60        s32 pcnt3 = (bit_rate > 180000000) ? 10 : 40;
  61        s32 coeff = 1000; /* Precision, should avoid overflow */
  62        s32 temp;
  63
  64        if (!bit_rate || !esc_rate)
  65                return -EINVAL;
  66
  67        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
  68        lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
  69
  70        tmax = S_DIV_ROUND_UP(95 * coeff, ui) - 2;
  71        tmin = S_DIV_ROUND_UP(38 * coeff, ui) - 2;
  72        timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, true);
  73
  74        temp = lpx / ui;
  75        if (temp & 0x1)
  76                timing->hs_rqst = temp;
  77        else
  78                timing->hs_rqst = max_t(s32, 0, temp - 2);
  79
  80        /* Calculate clk_zero after clk_prepare and hs_rqst */
  81        dsi_dphy_timing_calc_clk_zero(timing, ui, coeff, pcnt2);
  82
  83        temp = 105 * coeff + 12 * ui - 20 * coeff;
  84        tmax = S_DIV_ROUND_UP(temp, ui) - 2;
  85        tmin = S_DIV_ROUND_UP(60 * coeff, ui) - 2;
  86        timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
  87
  88        temp = 85 * coeff + 6 * ui;
  89        tmax = S_DIV_ROUND_UP(temp, ui) - 2;
  90        temp = 40 * coeff + 4 * ui;
  91        tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  92        timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, true);
  93
  94        tmax = 255;
  95        temp = ((timing->hs_prepare >> 1) + 1) * 2 * ui + 2 * ui;
  96        temp = 145 * coeff + 10 * ui - temp;
  97        tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  98        timing->hs_zero = linear_inter(tmax, tmin, pcnt2, 24, true);
  99
 100        temp = 105 * coeff + 12 * ui - 20 * coeff;
 101        tmax = S_DIV_ROUND_UP(temp, ui) - 2;
 102        temp = 60 * coeff + 4 * ui;
 103        tmin = DIV_ROUND_UP(temp, ui) - 2;
 104        timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
 105
 106        tmax = 255;
 107        tmin = S_DIV_ROUND_UP(100 * coeff, ui) - 2;
 108        timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, true);
 109
 110        tmax = 63;
 111        temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
 112        temp = 60 * coeff + 52 * ui - 24 * ui - temp;
 113        tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
 114        timing->shared_timings.clk_post = linear_inter(tmax, tmin, pcnt2, 0,
 115                                                       false);
 116        tmax = 63;
 117        temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
 118        temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
 119        temp += 8 * ui + lpx;
 120        tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
 121        if (tmin > tmax) {
 122                temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false);
 123                timing->shared_timings.clk_pre = temp >> 1;
 124                timing->shared_timings.clk_pre_inc_by_2 = true;
 125        } else {
 126                timing->shared_timings.clk_pre =
 127                                linear_inter(tmax, tmin, pcnt2, 0, false);
 128                timing->shared_timings.clk_pre_inc_by_2 = false;
 129        }
 130
 131        timing->ta_go = 3;
 132        timing->ta_sure = 0;
 133        timing->ta_get = 4;
 134
 135        DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
 136                timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
 137                timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
 138                timing->clk_trail, timing->clk_prepare, timing->hs_exit,
 139                timing->hs_zero, timing->hs_prepare, timing->hs_trail,
 140                timing->hs_rqst);
 141
 142        return 0;
 143}
 144
 145int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
 146                                struct msm_dsi_phy_clk_request *clk_req)
 147{
 148        const unsigned long bit_rate = clk_req->bitclk_rate;
 149        const unsigned long esc_rate = clk_req->escclk_rate;
 150        s32 ui, ui_x8;
 151        s32 tmax, tmin;
 152        s32 pcnt0 = 50;
 153        s32 pcnt1 = 50;
 154        s32 pcnt2 = 10;
 155        s32 pcnt3 = 30;
 156        s32 pcnt4 = 10;
 157        s32 pcnt5 = 2;
 158        s32 coeff = 1000; /* Precision, should avoid overflow */
 159        s32 hb_en, hb_en_ckln, pd_ckln, pd;
 160        s32 val, val_ckln;
 161        s32 temp;
 162
 163        if (!bit_rate || !esc_rate)
 164                return -EINVAL;
 165
 166        timing->hs_halfbyte_en = 0;
 167        hb_en = 0;
 168        timing->hs_halfbyte_en_ckln = 0;
 169        hb_en_ckln = 0;
 170        timing->hs_prep_dly_ckln = (bit_rate > 100000000) ? 0 : 3;
 171        pd_ckln = timing->hs_prep_dly_ckln;
 172        timing->hs_prep_dly = (bit_rate > 120000000) ? 0 : 1;
 173        pd = timing->hs_prep_dly;
 174
 175        val = (hb_en << 2) + (pd << 1);
 176        val_ckln = (hb_en_ckln << 2) + (pd_ckln << 1);
 177
 178        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 179        ui_x8 = ui << 3;
 180
 181        temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8);
 182        tmin = max_t(s32, temp, 0);
 183        temp = (95 * coeff - val_ckln * ui) / ui_x8;
 184        tmax = max_t(s32, temp, 0);
 185        timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
 186
 187        temp = 300 * coeff - ((timing->clk_prepare << 3) + val_ckln) * ui;
 188        tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3;
 189        tmax = (tmin > 255) ? 511 : 255;
 190        timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
 191
 192        tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
 193        temp = 105 * coeff + 12 * ui - 20 * coeff;
 194        tmax = (temp + 3 * ui) / ui_x8;
 195        timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
 196
 197        temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui - val * ui, ui_x8);
 198        tmin = max_t(s32, temp, 0);
 199        temp = (85 * coeff + 6 * ui - val * ui) / ui_x8;
 200        tmax = max_t(s32, temp, 0);
 201        timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
 202
 203        temp = 145 * coeff + 10 * ui - ((timing->hs_prepare << 3) + val) * ui;
 204        tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3;
 205        tmax = 255;
 206        timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
 207
 208        tmin = DIV_ROUND_UP(60 * coeff + 4 * ui + 3 * ui, ui_x8);
 209        temp = 105 * coeff + 12 * ui - 20 * coeff;
 210        tmax = (temp + 3 * ui) / ui_x8;
 211        timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
 212
 213        temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
 214        timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
 215
 216        tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
 217        tmax = 255;
 218        timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
 219
 220        temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
 221        timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
 222
 223        temp = 60 * coeff + 52 * ui - 43 * ui;
 224        tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
 225        tmax = 63;
 226        timing->shared_timings.clk_post =
 227                                linear_inter(tmax, tmin, pcnt2, 0, false);
 228
 229        temp = 8 * ui + ((timing->clk_prepare << 3) + val_ckln) * ui;
 230        temp += (((timing->clk_zero + 3) << 3) + 11 - (pd_ckln << 1)) * ui;
 231        temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
 232                                (((timing->hs_rqst_ckln << 3) + 8) * ui);
 233        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 234        tmax = 63;
 235        if (tmin > tmax) {
 236                temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
 237                timing->shared_timings.clk_pre = temp >> 1;
 238                timing->shared_timings.clk_pre_inc_by_2 = 1;
 239        } else {
 240                timing->shared_timings.clk_pre =
 241                                linear_inter(tmax, tmin, pcnt2, 0, false);
 242                timing->shared_timings.clk_pre_inc_by_2 = 0;
 243        }
 244
 245        timing->ta_go = 3;
 246        timing->ta_sure = 0;
 247        timing->ta_get = 4;
 248
 249        DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
 250            timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
 251            timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
 252            timing->clk_trail, timing->clk_prepare, timing->hs_exit,
 253            timing->hs_zero, timing->hs_prepare, timing->hs_trail,
 254            timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
 255            timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
 256            timing->hs_prep_dly_ckln);
 257
 258        return 0;
 259}
 260
 261int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
 262        struct msm_dsi_phy_clk_request *clk_req)
 263{
 264        const unsigned long bit_rate = clk_req->bitclk_rate;
 265        const unsigned long esc_rate = clk_req->escclk_rate;
 266        s32 ui, ui_x8;
 267        s32 tmax, tmin;
 268        s32 pcnt0 = 50;
 269        s32 pcnt1 = 50;
 270        s32 pcnt2 = 10;
 271        s32 pcnt3 = 30;
 272        s32 pcnt4 = 10;
 273        s32 pcnt5 = 2;
 274        s32 coeff = 1000; /* Precision, should avoid overflow */
 275        s32 hb_en, hb_en_ckln;
 276        s32 temp;
 277
 278        if (!bit_rate || !esc_rate)
 279                return -EINVAL;
 280
 281        timing->hs_halfbyte_en = 0;
 282        hb_en = 0;
 283        timing->hs_halfbyte_en_ckln = 0;
 284        hb_en_ckln = 0;
 285
 286        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 287        ui_x8 = ui << 3;
 288
 289        temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
 290        tmin = max_t(s32, temp, 0);
 291        temp = (95 * coeff) / ui_x8;
 292        tmax = max_t(s32, temp, 0);
 293        timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
 294
 295        temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
 296        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 297        tmax = (tmin > 255) ? 511 : 255;
 298        timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
 299
 300        tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
 301        temp = 105 * coeff + 12 * ui - 20 * coeff;
 302        tmax = (temp + 3 * ui) / ui_x8;
 303        timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
 304
 305        temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
 306        tmin = max_t(s32, temp, 0);
 307        temp = (85 * coeff + 6 * ui) / ui_x8;
 308        tmax = max_t(s32, temp, 0);
 309        timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
 310
 311        temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
 312        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 313        tmax = 255;
 314        timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
 315
 316        tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
 317        temp = 105 * coeff + 12 * ui - 20 * coeff;
 318        tmax = (temp / ui_x8) - 1;
 319        timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
 320
 321        temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
 322        timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
 323
 324        tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
 325        tmax = 255;
 326        timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
 327
 328        temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
 329        timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
 330
 331        temp = 60 * coeff + 52 * ui - 43 * ui;
 332        tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
 333        tmax = 63;
 334        timing->shared_timings.clk_post =
 335                linear_inter(tmax, tmin, pcnt2, 0, false);
 336
 337        temp = 8 * ui + (timing->clk_prepare << 3) * ui;
 338        temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
 339        temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
 340                (((timing->hs_rqst_ckln << 3) + 8) * ui);
 341        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 342        tmax = 63;
 343        if (tmin > tmax) {
 344                temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
 345                timing->shared_timings.clk_pre = temp >> 1;
 346                timing->shared_timings.clk_pre_inc_by_2 = 1;
 347        } else {
 348                timing->shared_timings.clk_pre =
 349                        linear_inter(tmax, tmin, pcnt2, 0, false);
 350                        timing->shared_timings.clk_pre_inc_by_2 = 0;
 351        }
 352
 353        timing->ta_go = 3;
 354        timing->ta_sure = 0;
 355        timing->ta_get = 4;
 356
 357        DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
 358                timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
 359                timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
 360                timing->clk_trail, timing->clk_prepare, timing->hs_exit,
 361                timing->hs_zero, timing->hs_prepare, timing->hs_trail,
 362                timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
 363                timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
 364                timing->hs_prep_dly_ckln);
 365
 366        return 0;
 367}
 368
 369int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
 370        struct msm_dsi_phy_clk_request *clk_req)
 371{
 372        const unsigned long bit_rate = clk_req->bitclk_rate;
 373        const unsigned long esc_rate = clk_req->escclk_rate;
 374        s32 ui, ui_x8;
 375        s32 tmax, tmin;
 376        s32 pcnt_clk_prep = 50;
 377        s32 pcnt_clk_zero = 2;
 378        s32 pcnt_clk_trail = 30;
 379        s32 pcnt_hs_prep = 50;
 380        s32 pcnt_hs_zero = 10;
 381        s32 pcnt_hs_trail = 30;
 382        s32 pcnt_hs_exit = 10;
 383        s32 coeff = 1000; /* Precision, should avoid overflow */
 384        s32 hb_en;
 385        s32 temp;
 386
 387        if (!bit_rate || !esc_rate)
 388                return -EINVAL;
 389
 390        hb_en = 0;
 391
 392        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 393        ui_x8 = ui << 3;
 394
 395        /* TODO: verify these calculations against latest downstream driver
 396         * everything except clk_post/clk_pre uses calculations from v3 based
 397         * on the downstream driver having the same calculations for v3 and v4
 398         */
 399
 400        temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
 401        tmin = max_t(s32, temp, 0);
 402        temp = (95 * coeff) / ui_x8;
 403        tmax = max_t(s32, temp, 0);
 404        timing->clk_prepare = linear_inter(tmax, tmin, pcnt_clk_prep, 0, false);
 405
 406        temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
 407        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 408        tmax = (tmin > 255) ? 511 : 255;
 409        timing->clk_zero = linear_inter(tmax, tmin, pcnt_clk_zero, 0, false);
 410
 411        tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
 412        temp = 105 * coeff + 12 * ui - 20 * coeff;
 413        tmax = (temp + 3 * ui) / ui_x8;
 414        timing->clk_trail = linear_inter(tmax, tmin, pcnt_clk_trail, 0, false);
 415
 416        temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
 417        tmin = max_t(s32, temp, 0);
 418        temp = (85 * coeff + 6 * ui) / ui_x8;
 419        tmax = max_t(s32, temp, 0);
 420        timing->hs_prepare = linear_inter(tmax, tmin, pcnt_hs_prep, 0, false);
 421
 422        temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
 423        tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
 424        tmax = 255;
 425        timing->hs_zero = linear_inter(tmax, tmin, pcnt_hs_zero, 0, false);
 426
 427        tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
 428        temp = 105 * coeff + 12 * ui - 20 * coeff;
 429        tmax = (temp / ui_x8) - 1;
 430        timing->hs_trail = linear_inter(tmax, tmin, pcnt_hs_trail, 0, false);
 431
 432        temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
 433        timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
 434
 435        tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
 436        tmax = 255;
 437        timing->hs_exit = linear_inter(tmax, tmin, pcnt_hs_exit, 0, false);
 438
 439        /* recommended min
 440         * = roundup((mipi_min_ns + t_hs_trail_ns)/(16*bit_clk_ns), 0) - 1
 441         */
 442        temp = 60 * coeff + 52 * ui + + (timing->hs_trail + 1) * ui_x8;
 443        tmin = DIV_ROUND_UP(temp, 16 * ui) - 1;
 444        tmax = 255;
 445        timing->shared_timings.clk_post = linear_inter(tmax, tmin, 5, 0, false);
 446
 447        /* recommended min
 448         * val1 = (tlpx_ns + clk_prepare_ns + clk_zero_ns + hs_rqst_ns)
 449         * val2 = (16 * bit_clk_ns)
 450         * final = roundup(val1/val2, 0) - 1
 451         */
 452        temp = 52 * coeff + (timing->clk_prepare + timing->clk_zero + 1) * ui_x8 + 54 * coeff;
 453        tmin = DIV_ROUND_UP(temp, 16 * ui) - 1;
 454        tmax = 255;
 455        timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 10000) + tmin;
 456
 457        DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
 458                timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
 459                timing->clk_zero, timing->clk_trail, timing->clk_prepare, timing->hs_exit,
 460                timing->hs_zero, timing->hs_prepare, timing->hs_trail, timing->hs_rqst);
 461
 462        return 0;
 463}
 464
 465int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
 466        struct msm_dsi_phy_clk_request *clk_req)
 467{
 468        const unsigned long bit_rate = clk_req->bitclk_rate;
 469        const unsigned long esc_rate = clk_req->escclk_rate;
 470        s32 ui, ui_x7;
 471        s32 tmax, tmin;
 472        s32 coeff = 1000; /* Precision, should avoid overflow */
 473        s32 temp;
 474
 475        if (!bit_rate || !esc_rate)
 476                return -EINVAL;
 477
 478        ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
 479        ui_x7 = ui * 7;
 480
 481        temp = S_DIV_ROUND_UP(38 * coeff, ui_x7);
 482        tmin = max_t(s32, temp, 0);
 483        temp = (95 * coeff) / ui_x7;
 484        tmax = max_t(s32, temp, 0);
 485        timing->clk_prepare = linear_inter(tmax, tmin, 50, 0, false);
 486
 487        tmin = DIV_ROUND_UP(50 * coeff, ui_x7);
 488        tmax = 255;
 489        timing->hs_rqst = linear_inter(tmax, tmin, 1, 0, false);
 490
 491        tmin = DIV_ROUND_UP(100 * coeff, ui_x7) - 1;
 492        tmax = 255;
 493        timing->hs_exit = linear_inter(tmax, tmin, 10, 0, false);
 494
 495        tmin = 1;
 496        tmax = 32;
 497        timing->shared_timings.clk_post = linear_inter(tmax, tmin, 80, 0, false);
 498
 499        tmin = min_t(s32, 64, S_DIV_ROUND_UP(262 * coeff, ui_x7) - 1);
 500        tmax = 64;
 501        timing->shared_timings.clk_pre = linear_inter(tmax, tmin, 20, 0, false);
 502
 503        DBG("%d, %d, %d, %d, %d",
 504                timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
 505                timing->clk_prepare, timing->hs_exit, timing->hs_rqst);
 506
 507        return 0;
 508}
 509
 510static int dsi_phy_regulator_init(struct msm_dsi_phy *phy)
 511{
 512        struct regulator_bulk_data *s = phy->supplies;
 513        const struct dsi_reg_entry *regs = phy->cfg->reg_cfg.regs;
 514        struct device *dev = &phy->pdev->dev;
 515        int num = phy->cfg->reg_cfg.num;
 516        int i, ret;
 517
 518        for (i = 0; i < num; i++)
 519                s[i].supply = regs[i].name;
 520
 521        ret = devm_regulator_bulk_get(dev, num, s);
 522        if (ret < 0) {
 523                if (ret != -EPROBE_DEFER) {
 524                        DRM_DEV_ERROR(dev,
 525                                      "%s: failed to init regulator, ret=%d\n",
 526                                      __func__, ret);
 527                }
 528
 529                return ret;
 530        }
 531
 532        return 0;
 533}
 534
 535static void dsi_phy_regulator_disable(struct msm_dsi_phy *phy)
 536{
 537        struct regulator_bulk_data *s = phy->supplies;
 538        const struct dsi_reg_entry *regs = phy->cfg->reg_cfg.regs;
 539        int num = phy->cfg->reg_cfg.num;
 540        int i;
 541
 542        DBG("");
 543        for (i = num - 1; i >= 0; i--)
 544                if (regs[i].disable_load >= 0)
 545                        regulator_set_load(s[i].consumer, regs[i].disable_load);
 546
 547        regulator_bulk_disable(num, s);
 548}
 549
 550static int dsi_phy_regulator_enable(struct msm_dsi_phy *phy)
 551{
 552        struct regulator_bulk_data *s = phy->supplies;
 553        const struct dsi_reg_entry *regs = phy->cfg->reg_cfg.regs;
 554        struct device *dev = &phy->pdev->dev;
 555        int num = phy->cfg->reg_cfg.num;
 556        int ret, i;
 557
 558        DBG("");
 559        for (i = 0; i < num; i++) {
 560                if (regs[i].enable_load >= 0) {
 561                        ret = regulator_set_load(s[i].consumer,
 562                                                        regs[i].enable_load);
 563                        if (ret < 0) {
 564                                DRM_DEV_ERROR(dev,
 565                                        "regulator %d set op mode failed, %d\n",
 566                                        i, ret);
 567                                goto fail;
 568                        }
 569                }
 570        }
 571
 572        ret = regulator_bulk_enable(num, s);
 573        if (ret < 0) {
 574                DRM_DEV_ERROR(dev, "regulator enable failed, %d\n", ret);
 575                goto fail;
 576        }
 577
 578        return 0;
 579
 580fail:
 581        for (i--; i >= 0; i--)
 582                regulator_set_load(s[i].consumer, regs[i].disable_load);
 583        return ret;
 584}
 585
 586static int dsi_phy_enable_resource(struct msm_dsi_phy *phy)
 587{
 588        struct device *dev = &phy->pdev->dev;
 589        int ret;
 590
 591        pm_runtime_get_sync(dev);
 592
 593        ret = clk_prepare_enable(phy->ahb_clk);
 594        if (ret) {
 595                DRM_DEV_ERROR(dev, "%s: can't enable ahb clk, %d\n", __func__, ret);
 596                pm_runtime_put_sync(dev);
 597        }
 598
 599        return ret;
 600}
 601
 602static void dsi_phy_disable_resource(struct msm_dsi_phy *phy)
 603{
 604        clk_disable_unprepare(phy->ahb_clk);
 605        pm_runtime_put_autosuspend(&phy->pdev->dev);
 606}
 607
 608static const struct of_device_id dsi_phy_dt_match[] = {
 609#ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
 610        { .compatible = "qcom,dsi-phy-28nm-hpm",
 611          .data = &dsi_phy_28nm_hpm_cfgs },
 612        { .compatible = "qcom,dsi-phy-28nm-hpm-fam-b",
 613          .data = &dsi_phy_28nm_hpm_famb_cfgs },
 614        { .compatible = "qcom,dsi-phy-28nm-lp",
 615          .data = &dsi_phy_28nm_lp_cfgs },
 616#endif
 617#ifdef CONFIG_DRM_MSM_DSI_20NM_PHY
 618        { .compatible = "qcom,dsi-phy-20nm",
 619          .data = &dsi_phy_20nm_cfgs },
 620#endif
 621#ifdef CONFIG_DRM_MSM_DSI_28NM_8960_PHY
 622        { .compatible = "qcom,dsi-phy-28nm-8960",
 623          .data = &dsi_phy_28nm_8960_cfgs },
 624#endif
 625#ifdef CONFIG_DRM_MSM_DSI_14NM_PHY
 626        { .compatible = "qcom,dsi-phy-14nm",
 627          .data = &dsi_phy_14nm_cfgs },
 628        { .compatible = "qcom,dsi-phy-14nm-660",
 629          .data = &dsi_phy_14nm_660_cfgs },
 630        { .compatible = "qcom,dsi-phy-14nm-8953",
 631          .data = &dsi_phy_14nm_8953_cfgs },
 632#endif
 633#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
 634        { .compatible = "qcom,dsi-phy-10nm",
 635          .data = &dsi_phy_10nm_cfgs },
 636        { .compatible = "qcom,dsi-phy-10nm-8998",
 637          .data = &dsi_phy_10nm_8998_cfgs },
 638#endif
 639#ifdef CONFIG_DRM_MSM_DSI_7NM_PHY
 640        { .compatible = "qcom,dsi-phy-7nm",
 641          .data = &dsi_phy_7nm_cfgs },
 642        { .compatible = "qcom,dsi-phy-7nm-8150",
 643          .data = &dsi_phy_7nm_8150_cfgs },
 644        { .compatible = "qcom,sc7280-dsi-phy-7nm",
 645          .data = &dsi_phy_7nm_7280_cfgs },
 646#endif
 647        {}
 648};
 649
 650/*
 651 * Currently, we only support one SoC for each PHY type. When we have multiple
 652 * SoCs for the same PHY, we can try to make the index searching a bit more
 653 * clever.
 654 */
 655static int dsi_phy_get_id(struct msm_dsi_phy *phy)
 656{
 657        struct platform_device *pdev = phy->pdev;
 658        const struct msm_dsi_phy_cfg *cfg = phy->cfg;
 659        struct resource *res;
 660        int i;
 661
 662        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_phy");
 663        if (!res)
 664                return -EINVAL;
 665
 666        for (i = 0; i < cfg->num_dsi_phy; i++) {
 667                if (cfg->io_start[i] == res->start)
 668                        return i;
 669        }
 670
 671        return -EINVAL;
 672}
 673
 674static int dsi_phy_driver_probe(struct platform_device *pdev)
 675{
 676        struct msm_dsi_phy *phy;
 677        struct device *dev = &pdev->dev;
 678        u32 phy_type;
 679        int ret;
 680
 681        phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
 682        if (!phy)
 683                return -ENOMEM;
 684
 685        phy->provided_clocks = devm_kzalloc(dev,
 686                        struct_size(phy->provided_clocks, hws, NUM_PROVIDED_CLKS),
 687                        GFP_KERNEL);
 688        if (!phy->provided_clocks)
 689                return -ENOMEM;
 690
 691        phy->provided_clocks->num = NUM_PROVIDED_CLKS;
 692
 693        phy->cfg = of_device_get_match_data(&pdev->dev);
 694        if (!phy->cfg)
 695                return -ENODEV;
 696
 697        phy->pdev = pdev;
 698
 699        phy->id = dsi_phy_get_id(phy);
 700        if (phy->id < 0) {
 701                ret = phy->id;
 702                DRM_DEV_ERROR(dev, "%s: couldn't identify PHY index, %d\n",
 703                        __func__, ret);
 704                goto fail;
 705        }
 706
 707        phy->regulator_ldo_mode = of_property_read_bool(dev->of_node,
 708                                "qcom,dsi-phy-regulator-ldo-mode");
 709        if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type))
 710                phy->cphy_mode = (phy_type == PHY_TYPE_CPHY);
 711
 712        phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size);
 713        if (IS_ERR(phy->base)) {
 714                DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__);
 715                ret = -ENOMEM;
 716                goto fail;
 717        }
 718
 719        phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", "DSI_PLL", &phy->pll_size);
 720        if (IS_ERR(phy->pll_base)) {
 721                DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__);
 722                ret = -ENOMEM;
 723                goto fail;
 724        }
 725
 726        if (phy->cfg->has_phy_lane) {
 727                phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", "DSI_PHY_LANE", &phy->lane_size);
 728                if (IS_ERR(phy->lane_base)) {
 729                        DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy lane base\n", __func__);
 730                        ret = -ENOMEM;
 731                        goto fail;
 732                }
 733        }
 734
 735        if (phy->cfg->has_phy_regulator) {
 736                phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", "DSI_PHY_REG", &phy->reg_size);
 737                if (IS_ERR(phy->reg_base)) {
 738                        DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy regulator base\n", __func__);
 739                        ret = -ENOMEM;
 740                        goto fail;
 741                }
 742        }
 743
 744        ret = dsi_phy_regulator_init(phy);
 745        if (ret)
 746                goto fail;
 747
 748        phy->ahb_clk = msm_clk_get(pdev, "iface");
 749        if (IS_ERR(phy->ahb_clk)) {
 750                DRM_DEV_ERROR(dev, "%s: Unable to get ahb clk\n", __func__);
 751                ret = PTR_ERR(phy->ahb_clk);
 752                goto fail;
 753        }
 754
 755        /* PLL init will call into clk_register which requires
 756         * register access, so we need to enable power and ahb clock.
 757         */
 758        ret = dsi_phy_enable_resource(phy);
 759        if (ret)
 760                goto fail;
 761
 762        if (phy->cfg->ops.pll_init) {
 763                ret = phy->cfg->ops.pll_init(phy);
 764                if (ret) {
 765                        DRM_DEV_INFO(dev,
 766                                "%s: pll init failed: %d, need separate pll clk driver\n",
 767                                __func__, ret);
 768                        goto fail;
 769                }
 770        }
 771
 772        ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
 773                                     phy->provided_clocks);
 774        if (ret) {
 775                DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
 776                goto fail;
 777        }
 778
 779        dsi_phy_disable_resource(phy);
 780
 781        platform_set_drvdata(pdev, phy);
 782
 783        return 0;
 784
 785fail:
 786        return ret;
 787}
 788
 789static struct platform_driver dsi_phy_platform_driver = {
 790        .probe      = dsi_phy_driver_probe,
 791        .driver     = {
 792                .name   = "msm_dsi_phy",
 793                .of_match_table = dsi_phy_dt_match,
 794        },
 795};
 796
 797void __init msm_dsi_phy_driver_register(void)
 798{
 799        platform_driver_register(&dsi_phy_platform_driver);
 800}
 801
 802void __exit msm_dsi_phy_driver_unregister(void)
 803{
 804        platform_driver_unregister(&dsi_phy_platform_driver);
 805}
 806
 807int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
 808                        struct msm_dsi_phy_clk_request *clk_req,
 809                        struct msm_dsi_phy_shared_timings *shared_timings)
 810{
 811        struct device *dev = &phy->pdev->dev;
 812        int ret;
 813
 814        if (!phy || !phy->cfg->ops.enable)
 815                return -EINVAL;
 816
 817        ret = dsi_phy_enable_resource(phy);
 818        if (ret) {
 819                DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n",
 820                        __func__, ret);
 821                goto res_en_fail;
 822        }
 823
 824        ret = dsi_phy_regulator_enable(phy);
 825        if (ret) {
 826                DRM_DEV_ERROR(dev, "%s: regulator enable failed, %d\n",
 827                        __func__, ret);
 828                goto reg_en_fail;
 829        }
 830
 831        ret = phy->cfg->ops.enable(phy, clk_req);
 832        if (ret) {
 833                DRM_DEV_ERROR(dev, "%s: phy enable failed, %d\n", __func__, ret);
 834                goto phy_en_fail;
 835        }
 836
 837        memcpy(shared_timings, &phy->timing.shared_timings,
 838               sizeof(*shared_timings));
 839
 840        /*
 841         * Resetting DSI PHY silently changes its PLL registers to reset status,
 842         * which will confuse clock driver and result in wrong output rate of
 843         * link clocks. Restore PLL status if its PLL is being used as clock
 844         * source.
 845         */
 846        if (phy->usecase != MSM_DSI_PHY_SLAVE) {
 847                ret = msm_dsi_phy_pll_restore_state(phy);
 848                if (ret) {
 849                        DRM_DEV_ERROR(dev, "%s: failed to restore phy state, %d\n",
 850                                __func__, ret);
 851                        goto pll_restor_fail;
 852                }
 853        }
 854
 855        return 0;
 856
 857pll_restor_fail:
 858        if (phy->cfg->ops.disable)
 859                phy->cfg->ops.disable(phy);
 860phy_en_fail:
 861        dsi_phy_regulator_disable(phy);
 862reg_en_fail:
 863        dsi_phy_disable_resource(phy);
 864res_en_fail:
 865        return ret;
 866}
 867
 868void msm_dsi_phy_disable(struct msm_dsi_phy *phy)
 869{
 870        if (!phy || !phy->cfg->ops.disable)
 871                return;
 872
 873        phy->cfg->ops.disable(phy);
 874
 875        dsi_phy_regulator_disable(phy);
 876        dsi_phy_disable_resource(phy);
 877}
 878
 879void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
 880                             enum msm_dsi_phy_usecase uc)
 881{
 882        if (phy)
 883                phy->usecase = uc;
 884}
 885
 886/* Returns true if we have to clear DSI_LANE_CTRL.HS_REQ_SEL_PHY */
 887bool msm_dsi_phy_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
 888{
 889        if (!phy || !phy->cfg->ops.set_continuous_clock)
 890                return false;
 891
 892        return phy->cfg->ops.set_continuous_clock(phy, enable);
 893}
 894
 895int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
 896        struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
 897{
 898        if (byte_clk_provider)
 899                *byte_clk_provider = phy->provided_clocks->hws[DSI_BYTE_PLL_CLK]->clk;
 900        if (pixel_clk_provider)
 901                *pixel_clk_provider = phy->provided_clocks->hws[DSI_PIXEL_PLL_CLK]->clk;
 902
 903        return 0;
 904}
 905
 906void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy)
 907{
 908        if (phy->cfg->ops.save_pll_state) {
 909                phy->cfg->ops.save_pll_state(phy);
 910                phy->state_saved = true;
 911        }
 912}
 913
 914int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy)
 915{
 916        int ret;
 917
 918        if (phy->cfg->ops.restore_pll_state && phy->state_saved) {
 919                ret = phy->cfg->ops.restore_pll_state(phy);
 920                if (ret)
 921                        return ret;
 922
 923                phy->state_saved = false;
 924        }
 925
 926        return 0;
 927}
 928
 929void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct msm_dsi_phy *phy)
 930{
 931        msm_disp_snapshot_add_block(disp_state,
 932                        phy->base_size, phy->base,
 933                        "dsi%d_phy", phy->id);
 934
 935        /* Do not try accessing PLL registers if it is switched off */
 936        if (phy->pll_on)
 937                msm_disp_snapshot_add_block(disp_state,
 938                        phy->pll_size, phy->pll_base,
 939                        "dsi%d_pll", phy->id);
 940
 941        if (phy->lane_base)
 942                msm_disp_snapshot_add_block(disp_state,
 943                        phy->lane_size, phy->lane_base,
 944                        "dsi%d_lane", phy->id);
 945
 946        if (phy->reg_base)
 947                msm_disp_snapshot_add_block(disp_state,
 948                        phy->reg_size, phy->reg_base,
 949                        "dsi%d_reg", phy->id);
 950}
 951