Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013 NVIDIA Corporation
0004  */
0005 
0006 #include <linux/errno.h>
0007 #include <linux/kernel.h>
0008 
0009 #include "mipi-phy.h"
0010 
0011 /*
0012  * Default D-PHY timings based on MIPI D-PHY specification. Derived from the
0013  * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY
0014  * specification (v1.2) with minor adjustments.
0015  */
0016 int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
0017                  unsigned long period)
0018 {
0019     timing->clkmiss = 0;
0020     timing->clkpost = 70 + 52 * period;
0021     timing->clkpre = 8;
0022     timing->clkprepare = 65;
0023     timing->clksettle = 95;
0024     timing->clktermen = 0;
0025     timing->clktrail = 80;
0026     timing->clkzero = 260;
0027     timing->dtermen = 0;
0028     timing->eot = 0;
0029     timing->hsexit = 120;
0030     timing->hsprepare = 65 + 5 * period;
0031     timing->hszero = 145 + 5 * period;
0032     timing->hssettle = 85 + 6 * period;
0033     timing->hsskip = 40;
0034 
0035     /*
0036      * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40)
0037      * contains this formula as:
0038      *
0039      *     T_HS-TRAIL = max(n * 8 * period, 60 + n * 4 * period)
0040      *
0041      * where n = 1 for forward-direction HS mode and n = 4 for reverse-
0042      * direction HS mode. There's only one setting and this function does
0043      * not parameterize on anything other that period, so this code will
0044      * assumes that reverse-direction HS mode is supported and uses n = 4.
0045      */
0046     timing->hstrail = max(4 * 8 * period, 60 + 4 * 4 * period);
0047 
0048     timing->init = 100000;
0049     timing->lpx = 60;
0050     timing->taget = 5 * timing->lpx;
0051     timing->tago = 4 * timing->lpx;
0052     timing->tasure = 2 * timing->lpx;
0053     timing->wakeup = 1000000;
0054 
0055     return 0;
0056 }
0057 
0058 /*
0059  * Validate D-PHY timing according to MIPI D-PHY specification (v1.2, Section
0060  * Section 6.9 "Global Operation Timing Parameters").
0061  */
0062 int mipi_dphy_timing_validate(struct mipi_dphy_timing *timing,
0063                   unsigned long period)
0064 {
0065     if (timing->clkmiss > 60)
0066         return -EINVAL;
0067 
0068     if (timing->clkpost < (60 + 52 * period))
0069         return -EINVAL;
0070 
0071     if (timing->clkpre < 8)
0072         return -EINVAL;
0073 
0074     if (timing->clkprepare < 38 || timing->clkprepare > 95)
0075         return -EINVAL;
0076 
0077     if (timing->clksettle < 95 || timing->clksettle > 300)
0078         return -EINVAL;
0079 
0080     if (timing->clktermen > 38)
0081         return -EINVAL;
0082 
0083     if (timing->clktrail < 60)
0084         return -EINVAL;
0085 
0086     if (timing->clkprepare + timing->clkzero < 300)
0087         return -EINVAL;
0088 
0089     if (timing->dtermen > 35 + 4 * period)
0090         return -EINVAL;
0091 
0092     if (timing->eot > 105 + 12 * period)
0093         return -EINVAL;
0094 
0095     if (timing->hsexit < 100)
0096         return -EINVAL;
0097 
0098     if (timing->hsprepare < 40 + 4 * period ||
0099         timing->hsprepare > 85 + 6 * period)
0100         return -EINVAL;
0101 
0102     if (timing->hsprepare + timing->hszero < 145 + 10 * period)
0103         return -EINVAL;
0104 
0105     if ((timing->hssettle < 85 + 6 * period) ||
0106         (timing->hssettle > 145 + 10 * period))
0107         return -EINVAL;
0108 
0109     if (timing->hsskip < 40 || timing->hsskip > 55 + 4 * period)
0110         return -EINVAL;
0111 
0112     if (timing->hstrail < max(8 * period, 60 + 4 * period))
0113         return -EINVAL;
0114 
0115     if (timing->init < 100000)
0116         return -EINVAL;
0117 
0118     if (timing->lpx < 50)
0119         return -EINVAL;
0120 
0121     if (timing->taget != 5 * timing->lpx)
0122         return -EINVAL;
0123 
0124     if (timing->tago != 4 * timing->lpx)
0125         return -EINVAL;
0126 
0127     if (timing->tasure < timing->lpx || timing->tasure > 2 * timing->lpx)
0128         return -EINVAL;
0129 
0130     if (timing->wakeup < 1000000)
0131         return -EINVAL;
0132 
0133     return 0;
0134 }