1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2dec72739SThierry Reding /* 3dec72739SThierry Reding * Copyright (C) 2013 NVIDIA Corporation 4dec72739SThierry Reding */ 5dec72739SThierry Reding 681239c6fSStephen Warren #include <linux/errno.h> 7dec72739SThierry Reding #include <linux/kernel.h> 8dec72739SThierry Reding 9dec72739SThierry Reding #include "mipi-phy.h" 10dec72739SThierry Reding 11dec72739SThierry Reding /* 122dafd636SDavid Ung * Default D-PHY timings based on MIPI D-PHY specification. Derived from the 132dafd636SDavid Ung * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY 142dafd636SDavid Ung * specification (v1.2) with minor adjustments. 15dec72739SThierry Reding */ 16dec72739SThierry Reding int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing, 17dec72739SThierry Reding unsigned long period) 18dec72739SThierry Reding { 19dec72739SThierry Reding timing->clkmiss = 0; 20dec72739SThierry Reding timing->clkpost = 70 + 52 * period; 21dec72739SThierry Reding timing->clkpre = 8; 22dec72739SThierry Reding timing->clkprepare = 65; 23dec72739SThierry Reding timing->clksettle = 95; 24dec72739SThierry Reding timing->clktermen = 0; 25dec72739SThierry Reding timing->clktrail = 80; 26dec72739SThierry Reding timing->clkzero = 260; 27dec72739SThierry Reding timing->dtermen = 0; 28dec72739SThierry Reding timing->eot = 0; 29dec72739SThierry Reding timing->hsexit = 120; 30dec72739SThierry Reding timing->hsprepare = 65 + 5 * period; 31dec72739SThierry Reding timing->hszero = 145 + 5 * period; 32dec72739SThierry Reding timing->hssettle = 85 + 6 * period; 33dec72739SThierry Reding timing->hsskip = 40; 342dafd636SDavid Ung 352dafd636SDavid Ung /* 362dafd636SDavid Ung * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40) 372dafd636SDavid Ung * contains this formula as: 382dafd636SDavid Ung * 392dafd636SDavid Ung * T_HS-TRAIL = max(n * 8 * period, 60 + n * 4 * period) 402dafd636SDavid Ung * 412dafd636SDavid Ung * where n = 1 for forward-direction HS mode and n = 4 for reverse- 422dafd636SDavid Ung * direction HS mode. There's only one setting and this function does 432dafd636SDavid Ung * not parameterize on anything other that period, so this code will 442dafd636SDavid Ung * assumes that reverse-direction HS mode is supported and uses n = 4. 452dafd636SDavid Ung */ 462dafd636SDavid Ung timing->hstrail = max(4 * 8 * period, 60 + 4 * 4 * period); 472dafd636SDavid Ung 48dec72739SThierry Reding timing->init = 100000; 49dec72739SThierry Reding timing->lpx = 60; 50dec72739SThierry Reding timing->taget = 5 * timing->lpx; 51dec72739SThierry Reding timing->tago = 4 * timing->lpx; 52dec72739SThierry Reding timing->tasure = 2 * timing->lpx; 53dec72739SThierry Reding timing->wakeup = 1000000; 54dec72739SThierry Reding 55dec72739SThierry Reding return 0; 56dec72739SThierry Reding } 57dec72739SThierry Reding 58dec72739SThierry Reding /* 592dafd636SDavid Ung * Validate D-PHY timing according to MIPI D-PHY specification (v1.2, Section 602dafd636SDavid Ung * Section 6.9 "Global Operation Timing Parameters"). 61dec72739SThierry Reding */ 62dec72739SThierry Reding int mipi_dphy_timing_validate(struct mipi_dphy_timing *timing, 63dec72739SThierry Reding unsigned long period) 64dec72739SThierry Reding { 65dec72739SThierry Reding if (timing->clkmiss > 60) 66dec72739SThierry Reding return -EINVAL; 67dec72739SThierry Reding 68dec72739SThierry Reding if (timing->clkpost < (60 + 52 * period)) 69dec72739SThierry Reding return -EINVAL; 70dec72739SThierry Reding 71dec72739SThierry Reding if (timing->clkpre < 8) 72dec72739SThierry Reding return -EINVAL; 73dec72739SThierry Reding 74dec72739SThierry Reding if (timing->clkprepare < 38 || timing->clkprepare > 95) 75dec72739SThierry Reding return -EINVAL; 76dec72739SThierry Reding 77dec72739SThierry Reding if (timing->clksettle < 95 || timing->clksettle > 300) 78dec72739SThierry Reding return -EINVAL; 79dec72739SThierry Reding 80dec72739SThierry Reding if (timing->clktermen > 38) 81dec72739SThierry Reding return -EINVAL; 82dec72739SThierry Reding 83dec72739SThierry Reding if (timing->clktrail < 60) 84dec72739SThierry Reding return -EINVAL; 85dec72739SThierry Reding 86dec72739SThierry Reding if (timing->clkprepare + timing->clkzero < 300) 87dec72739SThierry Reding return -EINVAL; 88dec72739SThierry Reding 89dec72739SThierry Reding if (timing->dtermen > 35 + 4 * period) 90dec72739SThierry Reding return -EINVAL; 91dec72739SThierry Reding 92dec72739SThierry Reding if (timing->eot > 105 + 12 * period) 93dec72739SThierry Reding return -EINVAL; 94dec72739SThierry Reding 95dec72739SThierry Reding if (timing->hsexit < 100) 96dec72739SThierry Reding return -EINVAL; 97dec72739SThierry Reding 98dec72739SThierry Reding if (timing->hsprepare < 40 + 4 * period || 99dec72739SThierry Reding timing->hsprepare > 85 + 6 * period) 100dec72739SThierry Reding return -EINVAL; 101dec72739SThierry Reding 102dec72739SThierry Reding if (timing->hsprepare + timing->hszero < 145 + 10 * period) 103dec72739SThierry Reding return -EINVAL; 104dec72739SThierry Reding 105dec72739SThierry Reding if ((timing->hssettle < 85 + 6 * period) || 106dec72739SThierry Reding (timing->hssettle > 145 + 10 * period)) 107dec72739SThierry Reding return -EINVAL; 108dec72739SThierry Reding 109dec72739SThierry Reding if (timing->hsskip < 40 || timing->hsskip > 55 + 4 * period) 110dec72739SThierry Reding return -EINVAL; 111dec72739SThierry Reding 112dec72739SThierry Reding if (timing->hstrail < max(8 * period, 60 + 4 * period)) 113dec72739SThierry Reding return -EINVAL; 114dec72739SThierry Reding 115dec72739SThierry Reding if (timing->init < 100000) 116dec72739SThierry Reding return -EINVAL; 117dec72739SThierry Reding 118dec72739SThierry Reding if (timing->lpx < 50) 119dec72739SThierry Reding return -EINVAL; 120dec72739SThierry Reding 121dec72739SThierry Reding if (timing->taget != 5 * timing->lpx) 122dec72739SThierry Reding return -EINVAL; 123dec72739SThierry Reding 124dec72739SThierry Reding if (timing->tago != 4 * timing->lpx) 125dec72739SThierry Reding return -EINVAL; 126dec72739SThierry Reding 127dec72739SThierry Reding if (timing->tasure < timing->lpx || timing->tasure > 2 * timing->lpx) 128dec72739SThierry Reding return -EINVAL; 129dec72739SThierry Reding 130dec72739SThierry Reding if (timing->wakeup < 1000000) 131dec72739SThierry Reding return -EINVAL; 132dec72739SThierry Reding 133dec72739SThierry Reding return 0; 134dec72739SThierry Reding } 135