0001
0002
0003
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
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
0055 pll->vco_band = 0x0;
0056
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;
0073 pll->sdm_en = true;
0074 pll->fdk_s = 0x1;
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
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
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
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
0232
0233
0234
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
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
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
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
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
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
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 }