Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2020 Unisoc Inc.
0004  */
0005 
0006 #include <asm/div64.h>
0007 #include <linux/delay.h>
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/regmap.h>
0011 #include <linux/string.h>
0012 
0013 #include "sprd_dsi.h"
0014 
0015 #define L                       0
0016 #define H                       1
0017 #define CLK                     0
0018 #define DATA                    1
0019 #define INFINITY                0xffffffff
0020 #define MIN_OUTPUT_FREQ         (100)
0021 
0022 #define AVERAGE(a, b) (min(a, b) + abs((b) - (a)) / 2)
0023 
0024 /* sharkle */
0025 #define VCO_BAND_LOW    750
0026 #define VCO_BAND_MID    1100
0027 #define VCO_BAND_HIGH   1500
0028 #define PHY_REF_CLK 26000
0029 
0030 static int dphy_calc_pll_param(struct dphy_pll *pll)
0031 {
0032     const u32 khz = 1000;
0033     const u32 mhz = 1000000;
0034     const unsigned long long factor = 100;
0035     unsigned long long tmp;
0036     int i;
0037 
0038     pll->potential_fvco = pll->freq / khz;
0039     pll->ref_clk = PHY_REF_CLK / khz;
0040 
0041     for (i = 0; i < 4; ++i) {
0042         if (pll->potential_fvco >= VCO_BAND_LOW &&
0043             pll->potential_fvco <= VCO_BAND_HIGH) {
0044             pll->fvco = pll->potential_fvco;
0045             pll->out_sel = BIT(i);
0046             break;
0047         }
0048         pll->potential_fvco <<= 1;
0049     }
0050     if (pll->fvco == 0)
0051         return -EINVAL;
0052 
0053     if (pll->fvco >= VCO_BAND_LOW && pll->fvco <= VCO_BAND_MID) {
0054         /* vco band control */
0055         pll->vco_band = 0x0;
0056         /* low pass filter control */
0057         pll->lpf_sel = 1;
0058     } else if (pll->fvco > VCO_BAND_MID && pll->fvco <= VCO_BAND_HIGH) {
0059         pll->vco_band = 0x1;
0060         pll->lpf_sel = 0;
0061     } else {
0062         return -EINVAL;
0063     }
0064 
0065     pll->nint = pll->fvco / pll->ref_clk;
0066     tmp = pll->fvco * factor * mhz;
0067     do_div(tmp, pll->ref_clk);
0068     tmp = tmp - pll->nint * factor * mhz;
0069     tmp *= BIT(20);
0070     do_div(tmp, 100000000);
0071     pll->kint = (u32)tmp;
0072     pll->refin = 3; /* pre-divider bypass */
0073     pll->sdm_en = true; /* use fraction N PLL */
0074     pll->fdk_s = 0x1; /* fraction */
0075     pll->cp_s = 0x0;
0076     pll->det_delay = 0x1;
0077 
0078     return 0;
0079 }
0080 
0081 static void dphy_set_pll_reg(struct dphy_pll *pll, struct regmap *regmap)
0082 {
0083     u8 reg_val[9] = {0};
0084     int i;
0085 
0086     u8 reg_addr[] = {
0087         0x03, 0x04, 0x06, 0x08, 0x09,
0088         0x0a, 0x0b, 0x0e, 0x0f
0089     };
0090 
0091     reg_val[0] = 1 | (1 << 1) |  (pll->lpf_sel << 2);
0092     reg_val[1] = pll->div | (1 << 3) | (pll->cp_s << 5) | (pll->fdk_s << 7);
0093     reg_val[2] = pll->nint;
0094     reg_val[3] = pll->vco_band | (pll->sdm_en << 1) | (pll->refin << 2);
0095     reg_val[4] = pll->kint >> 12;
0096     reg_val[5] = pll->kint >> 4;
0097     reg_val[6] = pll->out_sel | ((pll->kint << 4) & 0xf);
0098     reg_val[7] = 1 << 4;
0099     reg_val[8] = pll->det_delay;
0100 
0101     for (i = 0; i < sizeof(reg_addr); ++i) {
0102         regmap_write(regmap, reg_addr[i], reg_val[i]);
0103         DRM_DEBUG("%02x: %02x\n", reg_addr[i], reg_val[i]);
0104     }
0105 }
0106 
0107 int dphy_pll_config(struct dsi_context *ctx)
0108 {
0109     struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);
0110     struct regmap *regmap = ctx->regmap;
0111     struct dphy_pll *pll = &ctx->pll;
0112     int ret;
0113 
0114     pll->freq = dsi->slave->hs_rate;
0115 
0116     /* FREQ = 26M * (NINT + KINT / 2^20) / out_sel */
0117     ret = dphy_calc_pll_param(pll);
0118     if (ret) {
0119         drm_err(dsi->drm, "failed to calculate dphy pll parameters\n");
0120         return ret;
0121     }
0122     dphy_set_pll_reg(pll, regmap);
0123 
0124     return 0;
0125 }
0126 
0127 static void dphy_set_timing_reg(struct regmap *regmap, int type, u8 val[])
0128 {
0129     switch (type) {
0130     case REQUEST_TIME:
0131         regmap_write(regmap, 0x31, val[CLK]);
0132         regmap_write(regmap, 0x41, val[DATA]);
0133         regmap_write(regmap, 0x51, val[DATA]);
0134         regmap_write(regmap, 0x61, val[DATA]);
0135         regmap_write(regmap, 0x71, val[DATA]);
0136 
0137         regmap_write(regmap, 0x90, val[CLK]);
0138         regmap_write(regmap, 0xa0, val[DATA]);
0139         regmap_write(regmap, 0xb0, val[DATA]);
0140         regmap_write(regmap, 0xc0, val[DATA]);
0141         regmap_write(regmap, 0xd0, val[DATA]);
0142         break;
0143     case PREPARE_TIME:
0144         regmap_write(regmap, 0x32, val[CLK]);
0145         regmap_write(regmap, 0x42, val[DATA]);
0146         regmap_write(regmap, 0x52, val[DATA]);
0147         regmap_write(regmap, 0x62, val[DATA]);
0148         regmap_write(regmap, 0x72, val[DATA]);
0149 
0150         regmap_write(regmap, 0x91, val[CLK]);
0151         regmap_write(regmap, 0xa1, val[DATA]);
0152         regmap_write(regmap, 0xb1, val[DATA]);
0153         regmap_write(regmap, 0xc1, val[DATA]);
0154         regmap_write(regmap, 0xd1, val[DATA]);
0155         break;
0156     case ZERO_TIME:
0157         regmap_write(regmap, 0x33, val[CLK]);
0158         regmap_write(regmap, 0x43, val[DATA]);
0159         regmap_write(regmap, 0x53, val[DATA]);
0160         regmap_write(regmap, 0x63, val[DATA]);
0161         regmap_write(regmap, 0x73, val[DATA]);
0162 
0163         regmap_write(regmap, 0x92, val[CLK]);
0164         regmap_write(regmap, 0xa2, val[DATA]);
0165         regmap_write(regmap, 0xb2, val[DATA]);
0166         regmap_write(regmap, 0xc2, val[DATA]);
0167         regmap_write(regmap, 0xd2, val[DATA]);
0168         break;
0169     case TRAIL_TIME:
0170         regmap_write(regmap, 0x34, val[CLK]);
0171         regmap_write(regmap, 0x44, val[DATA]);
0172         regmap_write(regmap, 0x54, val[DATA]);
0173         regmap_write(regmap, 0x64, val[DATA]);
0174         regmap_write(regmap, 0x74, val[DATA]);
0175 
0176         regmap_write(regmap, 0x93, val[CLK]);
0177         regmap_write(regmap, 0xa3, val[DATA]);
0178         regmap_write(regmap, 0xb3, val[DATA]);
0179         regmap_write(regmap, 0xc3, val[DATA]);
0180         regmap_write(regmap, 0xd3, val[DATA]);
0181         break;
0182     case EXIT_TIME:
0183         regmap_write(regmap, 0x36, val[CLK]);
0184         regmap_write(regmap, 0x46, val[DATA]);
0185         regmap_write(regmap, 0x56, val[DATA]);
0186         regmap_write(regmap, 0x66, val[DATA]);
0187         regmap_write(regmap, 0x76, val[DATA]);
0188 
0189         regmap_write(regmap, 0x95, val[CLK]);
0190         regmap_write(regmap, 0xA5, val[DATA]);
0191         regmap_write(regmap, 0xB5, val[DATA]);
0192         regmap_write(regmap, 0xc5, val[DATA]);
0193         regmap_write(regmap, 0xd5, val[DATA]);
0194         break;
0195     case CLKPOST_TIME:
0196         regmap_write(regmap, 0x35, val[CLK]);
0197         regmap_write(regmap, 0x94, val[CLK]);
0198         break;
0199 
0200     /* the following just use default value */
0201     case SETTLE_TIME:
0202         fallthrough;
0203     case TA_GET:
0204         fallthrough;
0205     case TA_GO:
0206         fallthrough;
0207     case TA_SURE:
0208         fallthrough;
0209     default:
0210         break;
0211     }
0212 }
0213 
0214 void dphy_timing_config(struct dsi_context *ctx)
0215 {
0216     struct regmap *regmap = ctx->regmap;
0217     struct dphy_pll *pll = &ctx->pll;
0218     const u32 factor = 2;
0219     const u32 scale = 100;
0220     u32 t_ui, t_byteck, t_half_byteck;
0221     u32 range[2], constant;
0222     u8 val[2];
0223     u32 tmp = 0;
0224 
0225     /* t_ui: 1 ui, byteck: 8 ui, half byteck: 4 ui */
0226     t_ui = 1000 * scale / (pll->freq / 1000);
0227     t_byteck = t_ui << 3;
0228     t_half_byteck = t_ui << 2;
0229     constant = t_ui << 1;
0230 
0231     /* REQUEST_TIME: HS T-LPX: LP-01
0232      * For T-LPX, mipi spec defined min value is 50ns,
0233      * but maybe it shouldn't be too small, because BTA,
0234      * LP-10, LP-00, LP-01, all of this is related to T-LPX.
0235      */
0236     range[L] = 50 * scale;
0237     range[H] = INFINITY;
0238     val[CLK] = DIV_ROUND_UP(range[L] * (factor << 1), t_byteck) - 2;
0239     val[DATA] = val[CLK];
0240     dphy_set_timing_reg(regmap, REQUEST_TIME, val);
0241 
0242     /* PREPARE_TIME: HS sequence: LP-00 */
0243     range[L] = 38 * scale;
0244     range[H] = 95 * scale;
0245     tmp = AVERAGE(range[L], range[H]);
0246     val[CLK] = DIV_ROUND_UP(AVERAGE(range[L], range[H]), t_half_byteck) - 1;
0247     range[L] = 40 * scale + 4 * t_ui;
0248     range[H] = 85 * scale + 6 * t_ui;
0249     tmp |= AVERAGE(range[L], range[H]) << 16;
0250     val[DATA] = DIV_ROUND_UP(AVERAGE(range[L], range[H]), t_half_byteck) - 1;
0251     dphy_set_timing_reg(regmap, PREPARE_TIME, val);
0252 
0253     /* ZERO_TIME: HS-ZERO */
0254     range[L] = 300 * scale;
0255     range[H] = INFINITY;
0256     val[CLK] = DIV_ROUND_UP(range[L] * factor + (tmp & 0xffff)
0257             - 525 * t_byteck / 100, t_byteck) - 2;
0258     range[L] = 145 * scale + 10 * t_ui;
0259     val[DATA] = DIV_ROUND_UP(range[L] * factor
0260             + ((tmp >> 16) & 0xffff) - 525 * t_byteck / 100,
0261             t_byteck) - 2;
0262     dphy_set_timing_reg(regmap, ZERO_TIME, val);
0263 
0264     /* TRAIL_TIME: HS-TRAIL */
0265     range[L] = 60 * scale;
0266     range[H] = INFINITY;
0267     val[CLK] = DIV_ROUND_UP(range[L] * factor - constant, t_half_byteck);
0268     range[L] = max(8 * t_ui, 60 * scale + 4 * t_ui);
0269     val[DATA] = DIV_ROUND_UP(range[L] * 3 / 2 - constant, t_half_byteck) - 2;
0270     dphy_set_timing_reg(regmap, TRAIL_TIME, val);
0271 
0272     /* EXIT_TIME: */
0273     range[L] = 100 * scale;
0274     range[H] = INFINITY;
0275     val[CLK] = DIV_ROUND_UP(range[L] * factor, t_byteck) - 2;
0276     val[DATA] = val[CLK];
0277     dphy_set_timing_reg(regmap, EXIT_TIME, val);
0278 
0279     /* CLKPOST_TIME: */
0280     range[L] = 60 * scale + 52 * t_ui;
0281     range[H] = INFINITY;
0282     val[CLK] = DIV_ROUND_UP(range[L] * factor, t_byteck) - 2;
0283     val[DATA] = val[CLK];
0284     dphy_set_timing_reg(regmap, CLKPOST_TIME, val);
0285 
0286     /* SETTLE_TIME:
0287      * This time is used for receiver. So for transmitter,
0288      * it can be ignored.
0289      */
0290 
0291     /* TA_GO:
0292      * transmitter drives bridge state(LP-00) before releasing control,
0293      * reg 0x1f default value: 0x04, which is good.
0294      */
0295 
0296     /* TA_SURE:
0297      * After LP-10 state and before bridge state(LP-00),
0298      * reg 0x20 default value: 0x01, which is good.
0299      */
0300 
0301     /* TA_GET:
0302      * receiver drives Bridge state(LP-00) before releasing control
0303      * reg 0x21 default value: 0x03, which is good.
0304      */
0305 }