Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux into drm-next

The big things this time around are:
1) support for hw cursor on newer mdp5 devices (snapdragon 820+,
tested on db820c)
2) dsi encoder cleanup
3) gpu dt bindings cleanup so we can get the gpu nodes merged upstream

* 'msm-next' of git://people.freedesktop.org/~robclark/linux: (32 commits)
drm/msm: return -EFAULT if copy_from_user() fails
drm/msm/dsi: Add PHY/PLL for 8x96
drm/msm/dsi: Add new method to calculate 14nm PHY timings
drm/msm/dsi: Move PHY operations out of host
drm/msm/dsi: Reset both PHYs before clock operation for dual DSI
drm/msm/dsi: Pass down use case to PHY
drm/msm/dsi: Return more timings from PHY to host
drm/msm/dsi: Add a PHY op that initializes version specific stuff
drm/msm/dsi: Add 8x96 info in dsi_cfg
drm/msm/dsi: Don't error if a DSI host doesn't have a device connected
drm/msm/mdp5: Add support for legacy cursor updates
drm/msm/mdp5: Refactor mdp5_plane_atomic_check
drm/msm/mdp5: Add cursor planes
drm/msm/mdp5: Misc cursor plane bits
drm/msm/mdp5: Configure COLOR3_OUT propagation
drm/msm/mdp5: Use plane helpers to configure src/dst rectangles
drm/msm/mdp5: Prepare CRTC/LM for empty stages
drm/msm/mdp5: Create only as many CRTCs as we need
drm/msm/mdp5: cfg: Change count to unsigned int
drm/msm/mdp5: Create single encoder per interface (INTF)
...

+2710 -554
+12 -26
Documentation/devicetree/bindings/display/msm/gpu.txt
··· 1 1 Qualcomm adreno/snapdragon GPU 2 2 3 3 Required properties: 4 - - compatible: "qcom,adreno-3xx" 4 + - compatible: "qcom,adreno-XYZ.W", "qcom,adreno" 5 + for example: "qcom,adreno-306.0", "qcom,adreno" 6 + Note that you need to list the less specific "qcom,adreno" (since this 7 + is what the device is matched on), in addition to the more specific 8 + with the chip-id. 5 9 - reg: Physical base address and length of the controller's registers. 6 10 - interrupts: The interrupt signal from the gpu. 7 11 - clocks: device clocks 8 12 See ../clocks/clock-bindings.txt for details. 9 13 - clock-names: the following clocks are required: 10 - * "core_clk" 11 - * "iface_clk" 12 - * "mem_iface_clk" 13 - - qcom,chipid: gpu chip-id. Note this may become optional for future 14 - devices if we can reliably read the chipid from hw 15 - - qcom,gpu-pwrlevels: list of operating points 16 - - compatible: "qcom,gpu-pwrlevels" 17 - - for each qcom,gpu-pwrlevel: 18 - - qcom,gpu-freq: requested gpu clock speed 19 - - NOTE: downstream android driver defines additional parameters to 20 - configure memory bandwidth scaling per OPP. 14 + * "core" 15 + * "iface" 16 + * "mem_iface" 21 17 22 18 Example: 23 19 ··· 21 25 ... 22 26 23 27 gpu: qcom,kgsl-3d0@4300000 { 24 - compatible = "qcom,adreno-3xx"; 28 + compatible = "qcom,adreno-320.2", "qcom,adreno"; 25 29 reg = <0x04300000 0x20000>; 26 30 reg-names = "kgsl_3d0_reg_memory"; 27 31 interrupts = <GIC_SPI 80 0>; 28 32 interrupt-names = "kgsl_3d0_irq"; 29 33 clock-names = 30 - "core_clk", 31 - "iface_clk", 32 - "mem_iface_clk"; 34 + "core", 35 + "iface", 36 + "mem_iface"; 33 37 clocks = 34 38 <&mmcc GFX3D_CLK>, 35 39 <&mmcc GFX3D_AHB_CLK>, 36 40 <&mmcc MMSS_IMEM_AHB_CLK>; 37 - qcom,chipid = <0x03020100>; 38 - qcom,gpu-pwrlevels { 39 - compatible = "qcom,gpu-pwrlevels"; 40 - qcom,gpu-pwrlevel@0 { 41 - qcom,gpu-freq = <450000000>; 42 - }; 43 - qcom,gpu-pwrlevel@1 { 44 - qcom,gpu-freq = <27000000>; 45 - }; 46 - }; 47 41 }; 48 42 };
+7
drivers/gpu/drm/msm/Kconfig
··· 72 72 help 73 73 Choose this option if the 28nm DSI PHY 8960 variant is used on the 74 74 platform. 75 + 76 + config DRM_MSM_DSI_14NM_PHY 77 + bool "Enable DSI 14nm PHY driver in MSM DRM (used by MSM8996/APQ8096)" 78 + depends on DRM_MSM_DSI 79 + default y 80 + help 81 + Choose this option if DSI PHY on 8996 is used on the platform.
+2
drivers/gpu/drm/msm/Makefile
··· 76 76 msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o 77 77 msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o 78 78 msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o 79 + msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o 79 80 80 81 ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y) 81 82 msm-y += dsi/pll/dsi_pll.o 82 83 msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/pll/dsi_pll_28nm.o 83 84 msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o 85 + msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o 84 86 endif 85 87 86 88 obj-$(CONFIG_DRM_MSM) += msm.o
+19 -2
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
··· 12 12 */ 13 13 14 14 #include "msm_gem.h" 15 + #include "msm_mmu.h" 15 16 #include "a5xx_gpu.h" 16 17 17 18 extern bool hang_debug; ··· 328 327 /* Enable RBBM error reporting bits */ 329 328 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001); 330 329 331 - if (adreno_gpu->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) { 330 + if (adreno_gpu->info->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) { 332 331 /* 333 332 * Mask out the activity signals from RB1-3 to avoid false 334 333 * positives ··· 382 381 383 382 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22)); 384 383 385 - if (adreno_gpu->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) 384 + if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) 386 385 gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); 387 386 388 387 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); ··· 572 571 } 573 572 574 573 return true; 574 + } 575 + 576 + static int a5xx_fault_handler(void *arg, unsigned long iova, int flags) 577 + { 578 + struct msm_gpu *gpu = arg; 579 + pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n", 580 + iova, flags, 581 + gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)), 582 + gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)), 583 + gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)), 584 + gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7))); 585 + 586 + return -EFAULT; 575 587 } 576 588 577 589 static void a5xx_cp_err_irq(struct msm_gpu *gpu) ··· 897 883 a5xx_destroy(&(a5xx_gpu->base.base)); 898 884 return ERR_PTR(ret); 899 885 } 886 + 887 + if (gpu->aspace) 888 + msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler); 900 889 901 890 return gpu; 902 891 }
+46 -16
drivers/gpu/drm/msm/adreno/adreno_device.c
··· 75 75 .gmem = (SZ_1M + SZ_512K), 76 76 .init = a4xx_gpu_init, 77 77 }, { 78 - .rev = ADRENO_REV(5, 3, 0, ANY_ID), 78 + .rev = ADRENO_REV(5, 3, 0, 2), 79 79 .revn = 530, 80 80 .name = "A530", 81 81 .pm4fw = "a530_pm4.fw", 82 82 .pfpfw = "a530_pfp.fw", 83 83 .gmem = SZ_1M, 84 + .quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI | 85 + ADRENO_QUIRK_FAULT_DETECT_MASK, 84 86 .init = a5xx_gpu_init, 85 87 .gpmufw = "a530v3_gpmu.fw2", 86 88 }, ··· 183 181 priv->gpu_pdev = pdev; 184 182 } 185 183 186 - static const struct { 187 - const char *str; 188 - uint32_t flag; 189 - } quirks[] = { 190 - { "qcom,gpu-quirk-two-pass-use-wfi", ADRENO_QUIRK_TWO_PASS_USE_WFI }, 191 - { "qcom,gpu-quirk-fault-detect-mask", ADRENO_QUIRK_FAULT_DETECT_MASK }, 192 - }; 184 + static int find_chipid(struct device *dev, u32 *chipid) 185 + { 186 + struct device_node *node = dev->of_node; 187 + const char *compat; 188 + int ret; 189 + 190 + /* first search the compat strings for qcom,adreno-XYZ.W: */ 191 + ret = of_property_read_string_index(node, "compatible", 0, &compat); 192 + if (ret == 0) { 193 + unsigned rev, patch; 194 + 195 + if (sscanf(compat, "qcom,adreno-%u.%u", &rev, &patch) == 2) { 196 + *chipid = 0; 197 + *chipid |= (rev / 100) << 24; /* core */ 198 + rev %= 100; 199 + *chipid |= (rev / 10) << 16; /* major */ 200 + rev %= 10; 201 + *chipid |= rev << 8; /* minor */ 202 + *chipid |= patch; 203 + 204 + return 0; 205 + } 206 + } 207 + 208 + /* and if that fails, fall back to legacy "qcom,chipid" property: */ 209 + ret = of_property_read_u32(node, "qcom,chipid", chipid); 210 + if (ret) 211 + return ret; 212 + 213 + dev_warn(dev, "Using legacy qcom,chipid binding!\n"); 214 + dev_warn(dev, "Use compatible qcom,adreno-%u%u%u.%u instead.\n", 215 + (*chipid >> 24) & 0xff, (*chipid >> 16) & 0xff, 216 + (*chipid >> 8) & 0xff, *chipid & 0xff); 217 + 218 + return 0; 219 + } 193 220 194 221 static int adreno_bind(struct device *dev, struct device *master, void *data) 195 222 { 196 223 static struct adreno_platform_config config = {}; 197 224 struct device_node *child, *node = dev->of_node; 198 225 u32 val; 199 - int ret, i; 226 + int ret; 200 227 201 - ret = of_property_read_u32(node, "qcom,chipid", &val); 228 + ret = find_chipid(dev, &val); 202 229 if (ret) { 203 230 dev_err(dev, "could not find chipid: %d\n", ret); 204 231 return ret; ··· 255 224 } 256 225 257 226 if (!config.fast_rate) { 258 - dev_err(dev, "could not find clk rates\n"); 259 - return -ENXIO; 227 + dev_warn(dev, "could not find clk rates\n"); 228 + /* This is a safe low speed for all devices: */ 229 + config.fast_rate = 200000000; 230 + config.slow_rate = 27000000; 260 231 } 261 - 262 - for (i = 0; i < ARRAY_SIZE(quirks); i++) 263 - if (of_property_read_bool(node, quirks[i].str)) 264 - config.quirks |= quirks[i].flag; 265 232 266 233 dev->platform_data = &config; 267 234 set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev)); ··· 289 260 } 290 261 291 262 static const struct of_device_id dt_match[] = { 263 + { .compatible = "qcom,adreno" }, 292 264 { .compatible = "qcom,adreno-3xx" }, 293 265 /* for backwards compat w/ downstream kgsl DT files: */ 294 266 { .compatible = "qcom,kgsl-3d0" },
-1
drivers/gpu/drm/msm/adreno/adreno_gpu.c
··· 352 352 adreno_gpu->gmem = adreno_gpu->info->gmem; 353 353 adreno_gpu->revn = adreno_gpu->info->revn; 354 354 adreno_gpu->rev = config->rev; 355 - adreno_gpu->quirks = config->quirks; 356 355 357 356 gpu->fast_rate = config->fast_rate; 358 357 gpu->slow_rate = config->slow_rate;
+1 -3
drivers/gpu/drm/msm/adreno/adreno_gpu.h
··· 75 75 const char *pm4fw, *pfpfw; 76 76 const char *gpmufw; 77 77 uint32_t gmem; 78 + enum adreno_quirks quirks; 78 79 struct msm_gpu *(*init)(struct drm_device *dev); 79 80 }; 80 81 ··· 117 116 * code (a3xx_gpu.c) and stored in this common location. 118 117 */ 119 118 const unsigned int *reg_offsets; 120 - 121 - uint32_t quirks; 122 119 }; 123 120 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) 124 121 ··· 127 128 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 128 129 struct msm_bus_scale_pdata *bus_scale_table; 129 130 #endif 130 - uint32_t quirks; 131 131 }; 132 132 133 133 #define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
+6 -12
drivers/gpu/drm/msm/dsi/dsi.c
··· 18 18 if (!msm_dsi || !msm_dsi_device_connected(msm_dsi)) 19 19 return NULL; 20 20 21 - return (msm_dsi->device_flags & MIPI_DSI_MODE_VIDEO) ? 22 - msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID] : 23 - msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID]; 21 + return msm_dsi->encoder; 24 22 } 25 23 26 24 static int dsi_get_phy(struct msm_dsi *msm_dsi) ··· 185 187 } 186 188 187 189 int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, 188 - struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]) 190 + struct drm_encoder *encoder) 189 191 { 190 192 struct msm_drm_private *priv = dev->dev_private; 191 193 struct drm_bridge *ext_bridge; 192 - int ret, i; 194 + int ret; 193 195 194 - if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] || 195 - !encoders[MSM_DSI_CMD_ENCODER_ID])) 196 + if (WARN_ON(!encoder)) 196 197 return -EINVAL; 197 198 198 199 msm_dsi->dev = dev; ··· 202 205 goto fail; 203 206 } 204 207 208 + msm_dsi->encoder = encoder; 209 + 205 210 msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id); 206 211 if (IS_ERR(msm_dsi->bridge)) { 207 212 ret = PTR_ERR(msm_dsi->bridge); 208 213 dev_err(dev->dev, "failed to create dsi bridge: %d\n", ret); 209 214 msm_dsi->bridge = NULL; 210 215 goto fail; 211 - } 212 - 213 - for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { 214 - encoders[i]->bridge = msm_dsi->bridge; 215 - msm_dsi->encoders[i] = encoders[i]; 216 216 } 217 217 218 218 /*
+41 -10
drivers/gpu/drm/msm/dsi/dsi.h
··· 27 27 #define DSI_1 1 28 28 #define DSI_MAX 2 29 29 30 + struct msm_dsi_phy_shared_timings; 31 + struct msm_dsi_phy_clk_request; 32 + 30 33 enum msm_dsi_phy_type { 31 34 MSM_DSI_PHY_28NM_HPM, 32 35 MSM_DSI_PHY_28NM_LP, 33 36 MSM_DSI_PHY_20NM, 34 37 MSM_DSI_PHY_28NM_8960, 38 + MSM_DSI_PHY_14NM, 35 39 MSM_DSI_PHY_MAX 40 + }; 41 + 42 + enum msm_dsi_phy_usecase { 43 + MSM_DSI_PHY_STANDALONE, 44 + MSM_DSI_PHY_MASTER, 45 + MSM_DSI_PHY_SLAVE, 36 46 }; 37 47 38 48 #define DSI_DEV_REGULATOR_MAX 8 ··· 83 73 struct device *phy_dev; 84 74 bool phy_enabled; 85 75 86 - /* the encoders we are hooked to (outside of dsi block) */ 87 - struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]; 76 + /* the encoder we are hooked to (outside of dsi block) */ 77 + struct drm_encoder *encoder; 88 78 89 79 int id; 90 80 }; ··· 94 84 void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge); 95 85 struct drm_connector *msm_dsi_manager_connector_init(u8 id); 96 86 struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id); 97 - int msm_dsi_manager_phy_enable(int id, 98 - const unsigned long bit_rate, const unsigned long esc_rate, 99 - u32 *clk_pre, u32 *clk_post); 100 - void msm_dsi_manager_phy_disable(int id); 101 87 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg); 102 88 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len); 89 + void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags); 103 90 int msm_dsi_manager_register(struct msm_dsi *msm_dsi); 104 91 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); 105 92 ··· 118 111 struct clk **byte_clk_provider, struct clk **pixel_clk_provider); 119 112 void msm_dsi_pll_save_state(struct msm_dsi_pll *pll); 120 113 int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll); 114 + int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll, 115 + enum msm_dsi_phy_usecase uc); 121 116 #else 122 117 static inline struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, 123 118 enum msm_dsi_phy_type type, int id) { ··· 140 131 { 141 132 return 0; 142 133 } 134 + static inline int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll, 135 + enum msm_dsi_phy_usecase uc) 136 + { 137 + return -ENODEV; 138 + } 143 139 #endif 144 140 145 141 /* dsi host */ ··· 160 146 u32 dma_base, u32 len); 161 147 int msm_dsi_host_enable(struct mipi_dsi_host *host); 162 148 int msm_dsi_host_disable(struct mipi_dsi_host *host); 163 - int msm_dsi_host_power_on(struct mipi_dsi_host *host); 149 + int msm_dsi_host_power_on(struct mipi_dsi_host *host, 150 + struct msm_dsi_phy_shared_timings *phy_shared_timings); 164 151 int msm_dsi_host_power_off(struct mipi_dsi_host *host); 165 152 int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, 166 153 struct drm_display_mode *mode); ··· 172 157 void msm_dsi_host_unregister(struct mipi_dsi_host *host); 173 158 int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, 174 159 struct msm_dsi_pll *src_pll); 160 + void msm_dsi_host_reset_phy(struct mipi_dsi_host *host); 161 + void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, 162 + struct msm_dsi_phy_clk_request *clk_req); 175 163 void msm_dsi_host_destroy(struct mipi_dsi_host *host); 176 164 int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, 177 165 struct drm_device *dev); ··· 182 164 183 165 /* dsi phy */ 184 166 struct msm_dsi_phy; 167 + struct msm_dsi_phy_shared_timings { 168 + u32 clk_post; 169 + u32 clk_pre; 170 + bool clk_pre_inc_by_2; 171 + }; 172 + 173 + struct msm_dsi_phy_clk_request { 174 + unsigned long bitclk_rate; 175 + unsigned long escclk_rate; 176 + }; 177 + 185 178 void msm_dsi_phy_driver_register(void); 186 179 void msm_dsi_phy_driver_unregister(void); 187 180 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 188 - const unsigned long bit_rate, const unsigned long esc_rate); 181 + struct msm_dsi_phy_clk_request *clk_req); 189 182 void msm_dsi_phy_disable(struct msm_dsi_phy *phy); 190 - void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy, 191 - u32 *clk_pre, u32 *clk_post); 183 + void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, 184 + struct msm_dsi_phy_shared_timings *shared_timing); 192 185 struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy); 186 + void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy, 187 + enum msm_dsi_phy_usecase uc); 193 188 194 189 #endif /* __DSI_CONNECTOR_H__ */ 195 190
+255 -12
drivers/gpu/drm/msm/dsi/dsi.xml.h
··· 8 8 git clone https://github.com/freedreno/envytools.git 9 9 10 10 The rules-ng-ng source files this header was generated from are: 11 - - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) 12 - - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) 13 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) 14 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) 15 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) 16 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) 17 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) 18 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) 19 - - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) 20 - - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) 21 - - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) 11 + - /local/mnt/workspace/source_trees/envytools/rnndb/../rnndb/dsi/dsi.xml ( 33004 bytes, from 2017-01-11 05:19:19) 12 + - /local/mnt/workspace/source_trees/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-05-09 06:32:54) 22 13 23 - Copyright (C) 2013-2015 by the following authors: 14 + Copyright (C) 2013-2017 by the following authors: 24 15 - Rob Clark <robdclark@gmail.com> (robclark) 25 16 - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) 26 17 ··· 1294 1303 #define REG_DSI_20nm_PHY_REGULATOR_CTRL_5 0x00000014 1295 1304 1296 1305 #define REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG 0x00000018 1306 + 1307 + #define REG_DSI_14nm_PHY_CMN_REVISION_ID0 0x00000000 1308 + 1309 + #define REG_DSI_14nm_PHY_CMN_REVISION_ID1 0x00000004 1310 + 1311 + #define REG_DSI_14nm_PHY_CMN_REVISION_ID2 0x00000008 1312 + 1313 + #define REG_DSI_14nm_PHY_CMN_REVISION_ID3 0x0000000c 1314 + 1315 + #define REG_DSI_14nm_PHY_CMN_CLK_CFG0 0x00000010 1316 + #define DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0__MASK 0x000000f0 1317 + #define DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0__SHIFT 4 1318 + static inline uint32_t DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0(uint32_t val) 1319 + { 1320 + return ((val) << DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0__SHIFT) & DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0__MASK; 1321 + } 1322 + #define DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4__MASK 0x000000f0 1323 + #define DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4__SHIFT 4 1324 + static inline uint32_t DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4(uint32_t val) 1325 + { 1326 + return ((val) << DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4__SHIFT) & DSI_14nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4__MASK; 1327 + } 1328 + 1329 + #define REG_DSI_14nm_PHY_CMN_CLK_CFG1 0x00000014 1330 + #define DSI_14nm_PHY_CMN_CLK_CFG1_DSICLK_SEL 0x00000001 1331 + 1332 + #define REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL 0x00000018 1333 + #define DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL 0x00000004 1334 + 1335 + #define REG_DSI_14nm_PHY_CMN_CTRL_0 0x0000001c 1336 + 1337 + #define REG_DSI_14nm_PHY_CMN_CTRL_1 0x00000020 1338 + 1339 + #define REG_DSI_14nm_PHY_CMN_HW_TRIGGER 0x00000024 1340 + 1341 + #define REG_DSI_14nm_PHY_CMN_SW_CFG0 0x00000028 1342 + 1343 + #define REG_DSI_14nm_PHY_CMN_SW_CFG1 0x0000002c 1344 + 1345 + #define REG_DSI_14nm_PHY_CMN_SW_CFG2 0x00000030 1346 + 1347 + #define REG_DSI_14nm_PHY_CMN_HW_CFG0 0x00000034 1348 + 1349 + #define REG_DSI_14nm_PHY_CMN_HW_CFG1 0x00000038 1350 + 1351 + #define REG_DSI_14nm_PHY_CMN_HW_CFG2 0x0000003c 1352 + 1353 + #define REG_DSI_14nm_PHY_CMN_HW_CFG3 0x00000040 1354 + 1355 + #define REG_DSI_14nm_PHY_CMN_HW_CFG4 0x00000044 1356 + 1357 + #define REG_DSI_14nm_PHY_CMN_PLL_CNTRL 0x00000048 1358 + #define DSI_14nm_PHY_CMN_PLL_CNTRL_PLL_START 0x00000001 1359 + 1360 + #define REG_DSI_14nm_PHY_CMN_LDO_CNTRL 0x0000004c 1361 + #define DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL__MASK 0x0000003f 1362 + #define DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL__SHIFT 0 1363 + static inline uint32_t DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL(uint32_t val) 1364 + { 1365 + return ((val) << DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL__SHIFT) & DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL__MASK; 1366 + } 1367 + 1368 + static inline uint32_t REG_DSI_14nm_PHY_LN(uint32_t i0) { return 0x00000000 + 0x80*i0; } 1369 + 1370 + static inline uint32_t REG_DSI_14nm_PHY_LN_CFG0(uint32_t i0) { return 0x00000000 + 0x80*i0; } 1371 + #define DSI_14nm_PHY_LN_CFG0_PREPARE_DLY__MASK 0x000000c0 1372 + #define DSI_14nm_PHY_LN_CFG0_PREPARE_DLY__SHIFT 6 1373 + static inline uint32_t DSI_14nm_PHY_LN_CFG0_PREPARE_DLY(uint32_t val) 1374 + { 1375 + return ((val) << DSI_14nm_PHY_LN_CFG0_PREPARE_DLY__SHIFT) & DSI_14nm_PHY_LN_CFG0_PREPARE_DLY__MASK; 1376 + } 1377 + 1378 + static inline uint32_t REG_DSI_14nm_PHY_LN_CFG1(uint32_t i0) { return 0x00000004 + 0x80*i0; } 1379 + #define DSI_14nm_PHY_LN_CFG1_HALFBYTECLK_EN 0x00000001 1380 + 1381 + static inline uint32_t REG_DSI_14nm_PHY_LN_CFG2(uint32_t i0) { return 0x00000008 + 0x80*i0; } 1382 + 1383 + static inline uint32_t REG_DSI_14nm_PHY_LN_CFG3(uint32_t i0) { return 0x0000000c + 0x80*i0; } 1384 + 1385 + static inline uint32_t REG_DSI_14nm_PHY_LN_TEST_DATAPATH(uint32_t i0) { return 0x00000010 + 0x80*i0; } 1386 + 1387 + static inline uint32_t REG_DSI_14nm_PHY_LN_TEST_STR(uint32_t i0) { return 0x00000014 + 0x80*i0; } 1388 + 1389 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_4(uint32_t i0) { return 0x00000018 + 0x80*i0; } 1390 + #define DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT__MASK 0x000000ff 1391 + #define DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT__SHIFT 0 1392 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT(uint32_t val) 1393 + { 1394 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT__MASK; 1395 + } 1396 + 1397 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_5(uint32_t i0) { return 0x0000001c + 0x80*i0; } 1398 + #define DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO__MASK 0x000000ff 1399 + #define DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO__SHIFT 0 1400 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO(uint32_t val) 1401 + { 1402 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO__MASK; 1403 + } 1404 + 1405 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_6(uint32_t i0) { return 0x00000020 + 0x80*i0; } 1406 + #define DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE__MASK 0x000000ff 1407 + #define DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE__SHIFT 0 1408 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE(uint32_t val) 1409 + { 1410 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE__MASK; 1411 + } 1412 + 1413 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_7(uint32_t i0) { return 0x00000024 + 0x80*i0; } 1414 + #define DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL__MASK 0x000000ff 1415 + #define DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL__SHIFT 0 1416 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL(uint32_t val) 1417 + { 1418 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL__MASK; 1419 + } 1420 + 1421 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_8(uint32_t i0) { return 0x00000028 + 0x80*i0; } 1422 + #define DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST__MASK 0x000000ff 1423 + #define DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST__SHIFT 0 1424 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST(uint32_t val) 1425 + { 1426 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST__MASK; 1427 + } 1428 + 1429 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_9(uint32_t i0) { return 0x0000002c + 0x80*i0; } 1430 + #define DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO__MASK 0x00000007 1431 + #define DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO__SHIFT 0 1432 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO(uint32_t val) 1433 + { 1434 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO__MASK; 1435 + } 1436 + #define DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE__MASK 0x00000070 1437 + #define DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE__SHIFT 4 1438 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE(uint32_t val) 1439 + { 1440 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE__MASK; 1441 + } 1442 + 1443 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_10(uint32_t i0) { return 0x00000030 + 0x80*i0; } 1444 + #define DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET__MASK 0x00000007 1445 + #define DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET__SHIFT 0 1446 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET(uint32_t val) 1447 + { 1448 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET__MASK; 1449 + } 1450 + 1451 + static inline uint32_t REG_DSI_14nm_PHY_LN_TIMING_CTRL_11(uint32_t i0) { return 0x00000034 + 0x80*i0; } 1452 + #define DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD__MASK 0x000000ff 1453 + #define DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD__SHIFT 0 1454 + static inline uint32_t DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(uint32_t val) 1455 + { 1456 + return ((val) << DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD__SHIFT) & DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD__MASK; 1457 + } 1458 + 1459 + static inline uint32_t REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_0(uint32_t i0) { return 0x00000038 + 0x80*i0; } 1460 + 1461 + static inline uint32_t REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_1(uint32_t i0) { return 0x0000003c + 0x80*i0; } 1462 + 1463 + static inline uint32_t REG_DSI_14nm_PHY_LN_VREG_CNTRL(uint32_t i0) { return 0x00000064 + 0x80*i0; } 1464 + 1465 + #define REG_DSI_14nm_PHY_PLL_IE_TRIM 0x00000000 1466 + 1467 + #define REG_DSI_14nm_PHY_PLL_IP_TRIM 0x00000004 1468 + 1469 + #define REG_DSI_14nm_PHY_PLL_IPTAT_TRIM 0x00000010 1470 + 1471 + #define REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN 0x0000001c 1472 + 1473 + #define REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET 0x00000028 1474 + 1475 + #define REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL 0x0000002c 1476 + 1477 + #define REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2 0x00000030 1478 + 1479 + #define REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL3 0x00000034 1480 + 1481 + #define REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL4 0x00000038 1482 + 1483 + #define REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5 0x0000003c 1484 + 1485 + #define REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1 0x00000040 1486 + 1487 + #define REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2 0x00000044 1488 + 1489 + #define REG_DSI_14nm_PHY_PLL_KVCO_COUNT1 0x00000048 1490 + 1491 + #define REG_DSI_14nm_PHY_PLL_KVCO_COUNT2 0x0000004c 1492 + 1493 + #define REG_DSI_14nm_PHY_PLL_VREF_CFG1 0x0000005c 1494 + 1495 + #define REG_DSI_14nm_PHY_PLL_KVCO_CODE 0x00000058 1496 + 1497 + #define REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1 0x0000006c 1498 + 1499 + #define REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2 0x00000070 1500 + 1501 + #define REG_DSI_14nm_PHY_PLL_VCO_COUNT1 0x00000074 1502 + 1503 + #define REG_DSI_14nm_PHY_PLL_VCO_COUNT2 0x00000078 1504 + 1505 + #define REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1 0x0000007c 1506 + 1507 + #define REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2 0x00000080 1508 + 1509 + #define REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3 0x00000084 1510 + 1511 + #define REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN 0x00000088 1512 + 1513 + #define REG_DSI_14nm_PHY_PLL_PLL_VCO_TUNE 0x0000008c 1514 + 1515 + #define REG_DSI_14nm_PHY_PLL_DEC_START 0x00000090 1516 + 1517 + #define REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER 0x00000094 1518 + 1519 + #define REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1 0x00000098 1520 + 1521 + #define REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2 0x0000009c 1522 + 1523 + #define REG_DSI_14nm_PHY_PLL_SSC_PER1 0x000000a0 1524 + 1525 + #define REG_DSI_14nm_PHY_PLL_SSC_PER2 0x000000a4 1526 + 1527 + #define REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1 0x000000a8 1528 + 1529 + #define REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2 0x000000ac 1530 + 1531 + #define REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1 0x000000b4 1532 + 1533 + #define REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2 0x000000b8 1534 + 1535 + #define REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3 0x000000bc 1536 + 1537 + #define REG_DSI_14nm_PHY_PLL_TXCLK_EN 0x000000c0 1538 + 1539 + #define REG_DSI_14nm_PHY_PLL_PLL_CRCTRL 0x000000c4 1540 + 1541 + #define REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS 0x000000cc 1542 + 1543 + #define REG_DSI_14nm_PHY_PLL_PLL_MISC1 0x000000e8 1544 + 1545 + #define REG_DSI_14nm_PHY_PLL_CP_SET_CUR 0x000000f0 1546 + 1547 + #define REG_DSI_14nm_PHY_PLL_PLL_ICPMSET 0x000000f4 1548 + 1549 + #define REG_DSI_14nm_PHY_PLL_PLL_ICPCSET 0x000000f8 1550 + 1551 + #define REG_DSI_14nm_PHY_PLL_PLL_ICP_SET 0x000000fc 1552 + 1553 + #define REG_DSI_14nm_PHY_PLL_PLL_LPF1 0x00000100 1554 + 1555 + #define REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV 0x00000104 1556 + 1557 + #define REG_DSI_14nm_PHY_PLL_PLL_BANDGAP 0x00000108 1297 1558 1298 1559 1299 1560 #endif /* DSI_XML */
+25
drivers/gpu/drm/msm/dsi/dsi_cfg.c
··· 94 94 .num_dsi = 2, 95 95 }; 96 96 97 + /* 98 + * TODO: core_mmss_clk fails to enable for some reason, but things work fine 99 + * without it too. Figure out why it doesn't enable and uncomment below 100 + */ 101 + static const char * const dsi_8996_bus_clk_names[] = { 102 + "mdp_core_clk", "iface_clk", "bus_clk", /* "core_mmss_clk", */ 103 + }; 104 + 105 + static const struct msm_dsi_config msm8996_dsi_cfg = { 106 + .io_offset = DSI_6G_REG_SHIFT, 107 + .reg_cfg = { 108 + .num = 2, 109 + .regs = { 110 + {"vdda", 18160, 1 }, /* 1.25 V */ 111 + {"vcca", 17000, 32 }, /* 0.925 V */ 112 + {"vddio", 100000, 100 },/* 1.8 V */ 113 + }, 114 + }, 115 + .bus_clk_names = dsi_8996_bus_clk_names, 116 + .num_bus_clks = ARRAY_SIZE(dsi_8996_bus_clk_names), 117 + .io_start = { 0x994000, 0x996000 }, 118 + .num_dsi = 2, 119 + }; 120 + 97 121 static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { 98 122 {MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064, &apq8064_dsi_cfg}, 99 123 {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0, ··· 130 106 &msm8974_apq8084_dsi_cfg}, 131 107 {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3, &msm8994_dsi_cfg}, 132 108 {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1, &msm8916_dsi_cfg}, 109 + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1, &msm8996_dsi_cfg}, 133 110 }; 134 111 135 112 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
+1
drivers/gpu/drm/msm/dsi/dsi_cfg.h
··· 24 24 #define MSM_DSI_6G_VER_MINOR_V1_2 0x10020000 25 25 #define MSM_DSI_6G_VER_MINOR_V1_3 0x10030000 26 26 #define MSM_DSI_6G_VER_MINOR_V1_3_1 0x10030001 27 + #define MSM_DSI_6G_VER_MINOR_V1_4_1 0x10040001 27 28 28 29 #define MSM_DSI_V2_VER_MINOR_8064 0x0 29 30
+49 -48
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 691 691 return 0; 692 692 } 693 693 694 - static void dsi_phy_sw_reset(struct msm_dsi_host *msm_host) 695 - { 696 - DBG(""); 697 - dsi_write(msm_host, REG_DSI_PHY_RESET, DSI_PHY_RESET_RESET); 698 - /* Make sure fully reset */ 699 - wmb(); 700 - udelay(1000); 701 - dsi_write(msm_host, REG_DSI_PHY_RESET, 0); 702 - udelay(100); 703 - } 704 - 705 694 static void dsi_intr_ctrl(struct msm_dsi_host *msm_host, u32 mask, int enable) 706 695 { 707 696 u32 intr; ··· 745 756 } 746 757 747 758 static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, 748 - u32 clk_pre, u32 clk_post) 759 + struct msm_dsi_phy_shared_timings *phy_shared_timings) 749 760 { 750 761 u32 flags = msm_host->mode_flags; 751 762 enum mipi_dsi_pixel_format mipi_fmt = msm_host->format; ··· 808 819 data |= DSI_TRIG_CTRL_BLOCK_DMA_WITHIN_FRAME; 809 820 dsi_write(msm_host, REG_DSI_TRIG_CTRL, data); 810 821 811 - data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(clk_post) | 812 - DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(clk_pre); 822 + data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(phy_shared_timings->clk_post) | 823 + DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(phy_shared_timings->clk_pre); 813 824 dsi_write(msm_host, REG_DSI_CLKOUT_TIMING_CTRL, data); 825 + 826 + if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) && 827 + (cfg_hnd->minor > MSM_DSI_6G_VER_MINOR_V1_0) && 828 + phy_shared_timings->clk_pre_inc_by_2) 829 + dsi_write(msm_host, REG_DSI_T_CLK_PRE_EXTEND, 830 + DSI_T_CLK_PRE_EXTEND_INC_BY_2_BYTECLK); 814 831 815 832 data = 0; 816 833 if (!(flags & MIPI_DSI_MODE_EOT_PACKET)) ··· 1477 1482 msm_host->format = dsi->format; 1478 1483 msm_host->mode_flags = dsi->mode_flags; 1479 1484 1485 + msm_dsi_manager_attach_dsi_device(msm_host->id, dsi->mode_flags); 1486 + 1480 1487 /* Some gpios defined in panel DT need to be controlled by host */ 1481 1488 ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev); 1482 1489 if (ret) ··· 1554 1557 1555 1558 prop = of_find_property(ep, "data-lanes", &len); 1556 1559 if (!prop) { 1557 - dev_dbg(dev, "failed to find data lane mapping\n"); 1558 - return -EINVAL; 1560 + dev_dbg(dev, 1561 + "failed to find data lane mapping, using default\n"); 1562 + return 0; 1559 1563 } 1560 1564 1561 1565 num_lanes = len / sizeof(u32); ··· 1613 1615 struct device *dev = &msm_host->pdev->dev; 1614 1616 struct device_node *np = dev->of_node; 1615 1617 struct device_node *endpoint, *device_node; 1616 - int ret; 1618 + int ret = 0; 1617 1619 1618 1620 /* 1619 1621 * Get the endpoint of the output port of the DSI host. In our case, ··· 1637 1639 /* Get panel node from the output port's endpoint data */ 1638 1640 device_node = of_graph_get_remote_port_parent(endpoint); 1639 1641 if (!device_node) { 1640 - dev_err(dev, "%s: no valid device\n", __func__); 1641 - ret = -ENODEV; 1642 + dev_dbg(dev, "%s: no valid device\n", __func__); 1642 1643 goto err; 1643 1644 } 1644 1645 ··· 2115 2118 return ret; 2116 2119 } 2117 2120 2121 + void msm_dsi_host_reset_phy(struct mipi_dsi_host *host) 2122 + { 2123 + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2124 + 2125 + DBG(""); 2126 + dsi_write(msm_host, REG_DSI_PHY_RESET, DSI_PHY_RESET_RESET); 2127 + /* Make sure fully reset */ 2128 + wmb(); 2129 + udelay(1000); 2130 + dsi_write(msm_host, REG_DSI_PHY_RESET, 0); 2131 + udelay(100); 2132 + } 2133 + 2134 + void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, 2135 + struct msm_dsi_phy_clk_request *clk_req) 2136 + { 2137 + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2138 + 2139 + clk_req->bitclk_rate = msm_host->byte_clk_rate * 8; 2140 + clk_req->escclk_rate = msm_host->esc_clk_rate; 2141 + } 2142 + 2118 2143 int msm_dsi_host_enable(struct mipi_dsi_host *host) 2119 2144 { 2120 2145 struct msm_dsi_host *msm_host = to_msm_dsi_host(host); ··· 2184 2165 SFPB_GPREG_MASTER_PORT_EN(en)); 2185 2166 } 2186 2167 2187 - int msm_dsi_host_power_on(struct mipi_dsi_host *host) 2168 + int msm_dsi_host_power_on(struct mipi_dsi_host *host, 2169 + struct msm_dsi_phy_shared_timings *phy_shared_timings) 2188 2170 { 2189 2171 struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2190 - u32 clk_pre = 0, clk_post = 0; 2191 2172 int ret = 0; 2192 2173 2193 2174 mutex_lock(&msm_host->dev_mutex); ··· 2198 2179 2199 2180 msm_dsi_sfpb_config(msm_host, true); 2200 2181 2201 - ret = dsi_calc_clk_rate(msm_host); 2202 - if (ret) { 2203 - pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); 2204 - goto unlock_ret; 2205 - } 2206 - 2207 2182 ret = dsi_host_regulator_enable(msm_host); 2208 2183 if (ret) { 2209 2184 pr_err("%s:Failed to enable vregs.ret=%d\n", 2210 2185 __func__, ret); 2211 2186 goto unlock_ret; 2212 - } 2213 - 2214 - ret = dsi_bus_clk_enable(msm_host); 2215 - if (ret) { 2216 - pr_err("%s: failed to enable bus clocks, %d\n", __func__, ret); 2217 - goto fail_disable_reg; 2218 - } 2219 - 2220 - dsi_phy_sw_reset(msm_host); 2221 - ret = msm_dsi_manager_phy_enable(msm_host->id, 2222 - msm_host->byte_clk_rate * 8, 2223 - msm_host->esc_clk_rate, 2224 - &clk_pre, &clk_post); 2225 - dsi_bus_clk_disable(msm_host); 2226 - if (ret) { 2227 - pr_err("%s: failed to enable phy, %d\n", __func__, ret); 2228 - goto fail_disable_reg; 2229 2187 } 2230 2188 2231 2189 ret = dsi_clk_ctrl(msm_host, 1); ··· 2220 2224 2221 2225 dsi_timing_setup(msm_host); 2222 2226 dsi_sw_reset(msm_host); 2223 - dsi_ctrl_config(msm_host, true, clk_pre, clk_post); 2227 + dsi_ctrl_config(msm_host, true, phy_shared_timings); 2224 2228 2225 2229 if (msm_host->disp_en_gpio) 2226 2230 gpiod_set_value(msm_host->disp_en_gpio, 1); ··· 2249 2253 goto unlock_ret; 2250 2254 } 2251 2255 2252 - dsi_ctrl_config(msm_host, false, 0, 0); 2256 + dsi_ctrl_config(msm_host, false, NULL); 2253 2257 2254 2258 if (msm_host->disp_en_gpio) 2255 2259 gpiod_set_value(msm_host->disp_en_gpio, 0); 2256 2260 2257 2261 pinctrl_pm_select_sleep_state(&msm_host->pdev->dev); 2258 - 2259 - msm_dsi_manager_phy_disable(msm_host->id); 2260 2262 2261 2263 dsi_clk_ctrl(msm_host, 0); 2262 2264 ··· 2275 2281 struct drm_display_mode *mode) 2276 2282 { 2277 2283 struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2284 + int ret; 2278 2285 2279 2286 if (msm_host->mode) { 2280 2287 drm_mode_destroy(msm_host->dev, msm_host->mode); ··· 2286 2291 if (!msm_host->mode) { 2287 2292 pr_err("%s: cannot duplicate mode\n", __func__); 2288 2293 return -ENOMEM; 2294 + } 2295 + 2296 + ret = dsi_calc_clk_rate(msm_host); 2297 + if (ret) { 2298 + pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); 2299 + return ret; 2289 2300 } 2290 2301 2291 2302 return 0;
+160 -94
drivers/gpu/drm/msm/dsi/dsi_manager.c
··· 72 72 return 0; 73 73 } 74 74 75 - static int dsi_mgr_host_register(int id) 75 + static int dsi_mgr_setup_components(int id) 76 76 { 77 77 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 78 78 struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); 79 79 struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 80 + struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 80 81 struct msm_dsi_pll *src_pll; 81 82 int ret; 82 83 ··· 86 85 if (ret) 87 86 return ret; 88 87 88 + msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE); 89 89 src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); 90 90 ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll); 91 91 } else if (!other_dsi) { 92 92 ret = 0; 93 93 } else { 94 - struct msm_dsi *mdsi = IS_MASTER_DSI_LINK(id) ? 95 - msm_dsi : other_dsi; 96 - struct msm_dsi *sdsi = IS_MASTER_DSI_LINK(id) ? 97 - other_dsi : msm_dsi; 94 + struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ? 95 + msm_dsi : other_dsi; 96 + struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ? 97 + other_dsi : msm_dsi; 98 98 /* Register slave host first, so that slave DSI device 99 99 * has a chance to probe, and do not block the master 100 100 * DSI device's probe. ··· 103 101 * because only master DSI device adds the panel to global 104 102 * panel list. The panel's device is the master DSI device. 105 103 */ 106 - ret = msm_dsi_host_register(sdsi->host, false); 104 + ret = msm_dsi_host_register(slave_link_dsi->host, false); 107 105 if (ret) 108 106 return ret; 109 - ret = msm_dsi_host_register(mdsi->host, true); 107 + ret = msm_dsi_host_register(master_link_dsi->host, true); 110 108 if (ret) 111 109 return ret; 112 110 113 111 /* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */ 112 + msm_dsi_phy_set_usecase(clk_master_dsi->phy, 113 + MSM_DSI_PHY_MASTER); 114 + msm_dsi_phy_set_usecase(clk_slave_dsi->phy, 115 + MSM_DSI_PHY_SLAVE); 114 116 src_pll = msm_dsi_phy_get_pll(clk_master_dsi->phy); 115 117 ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll); 116 118 if (ret) ··· 123 117 } 124 118 125 119 return ret; 120 + } 121 + 122 + static int enable_phy(struct msm_dsi *msm_dsi, int src_pll_id, 123 + struct msm_dsi_phy_shared_timings *shared_timings) 124 + { 125 + struct msm_dsi_phy_clk_request clk_req; 126 + int ret; 127 + 128 + msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req); 129 + 130 + ret = msm_dsi_phy_enable(msm_dsi->phy, src_pll_id, &clk_req); 131 + msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings); 132 + 133 + return ret; 134 + } 135 + 136 + static int 137 + dsi_mgr_phy_enable(int id, 138 + struct msm_dsi_phy_shared_timings shared_timings[DSI_MAX]) 139 + { 140 + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 141 + struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 142 + struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 143 + int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; 144 + int ret; 145 + 146 + /* In case of dual DSI, some registers in PHY1 have been programmed 147 + * during PLL0 clock's set_rate. The PHY1 reset called by host1 here 148 + * will silently reset those PHY1 registers. Therefore we need to reset 149 + * and enable both PHYs before any PLL clock operation. 150 + */ 151 + if (IS_DUAL_DSI() && mdsi && sdsi) { 152 + if (!mdsi->phy_enabled && !sdsi->phy_enabled) { 153 + msm_dsi_host_reset_phy(mdsi->host); 154 + msm_dsi_host_reset_phy(sdsi->host); 155 + 156 + ret = enable_phy(mdsi, src_pll_id, 157 + &shared_timings[DSI_CLOCK_MASTER]); 158 + if (ret) 159 + return ret; 160 + ret = enable_phy(sdsi, src_pll_id, 161 + &shared_timings[DSI_CLOCK_SLAVE]); 162 + if (ret) { 163 + msm_dsi_phy_disable(mdsi->phy); 164 + return ret; 165 + } 166 + } 167 + } else { 168 + msm_dsi_host_reset_phy(mdsi->host); 169 + ret = enable_phy(msm_dsi, src_pll_id, &shared_timings[id]); 170 + if (ret) 171 + return ret; 172 + } 173 + 174 + msm_dsi->phy_enabled = true; 175 + 176 + return 0; 177 + } 178 + 179 + static void dsi_mgr_phy_disable(int id) 180 + { 181 + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 182 + struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 183 + struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 184 + 185 + /* disable DSI phy 186 + * In dual-dsi configuration, the phy should be disabled for the 187 + * first controller only when the second controller is disabled. 188 + */ 189 + msm_dsi->phy_enabled = false; 190 + if (IS_DUAL_DSI() && mdsi && sdsi) { 191 + if (!mdsi->phy_enabled && !sdsi->phy_enabled) { 192 + msm_dsi_phy_disable(sdsi->phy); 193 + msm_dsi_phy_disable(mdsi->phy); 194 + } 195 + } else { 196 + msm_dsi_phy_disable(msm_dsi->phy); 197 + } 126 198 } 127 199 128 200 struct dsi_connector { ··· 251 167 !IS_MASTER_DSI_LINK(id) && other_dsi) 252 168 msm_dsi->panel = msm_dsi_host_get_panel( 253 169 other_dsi->host, NULL); 170 + 171 + 172 + if (msm_dsi->panel && kms->funcs->set_encoder_mode) { 173 + bool cmd_mode = !(msm_dsi->device_flags & 174 + MIPI_DSI_MODE_VIDEO); 175 + struct drm_encoder *encoder = 176 + msm_dsi_get_encoder(msm_dsi); 177 + 178 + kms->funcs->set_encoder_mode(kms, encoder, cmd_mode); 179 + } 254 180 255 181 if (msm_dsi->panel && IS_DUAL_DSI()) 256 182 drm_object_attach_property(&connector->base, ··· 438 344 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 439 345 struct mipi_dsi_host *host = msm_dsi->host; 440 346 struct drm_panel *panel = msm_dsi->panel; 347 + struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX]; 441 348 bool is_dual_dsi = IS_DUAL_DSI(); 442 349 int ret; 443 350 444 351 DBG("id=%d", id); 445 - if (!msm_dsi_device_connected(msm_dsi) || 446 - (is_dual_dsi && (DSI_1 == id))) 352 + if (!msm_dsi_device_connected(msm_dsi)) 447 353 return; 448 354 449 - ret = msm_dsi_host_power_on(host); 355 + ret = dsi_mgr_phy_enable(id, phy_shared_timings); 356 + if (ret) 357 + goto phy_en_fail; 358 + 359 + /* Do nothing with the host if it is DSI 1 in case of dual DSI */ 360 + if (is_dual_dsi && (DSI_1 == id)) 361 + return; 362 + 363 + ret = msm_dsi_host_power_on(host, &phy_shared_timings[id]); 450 364 if (ret) { 451 365 pr_err("%s: power on host %d failed, %d\n", __func__, id, ret); 452 366 goto host_on_fail; 453 367 } 454 368 455 369 if (is_dual_dsi && msm_dsi1) { 456 - ret = msm_dsi_host_power_on(msm_dsi1->host); 370 + ret = msm_dsi_host_power_on(msm_dsi1->host, 371 + &phy_shared_timings[DSI_1]); 457 372 if (ret) { 458 373 pr_err("%s: power on host1 failed, %d\n", 459 374 __func__, ret); ··· 521 418 host1_on_fail: 522 419 msm_dsi_host_power_off(host); 523 420 host_on_fail: 421 + dsi_mgr_phy_disable(id); 422 + phy_en_fail: 524 423 return; 525 424 } 526 425 ··· 548 443 549 444 DBG("id=%d", id); 550 445 551 - if (!msm_dsi_device_connected(msm_dsi) || 552 - (is_dual_dsi && (DSI_1 == id))) 446 + if (!msm_dsi_device_connected(msm_dsi)) 553 447 return; 448 + 449 + /* 450 + * Do nothing with the host if it is DSI 1 in case of dual DSI. 451 + * It is safe to call dsi_mgr_phy_disable() here because a single PHY 452 + * won't be diabled until both PHYs request disable. 453 + */ 454 + if (is_dual_dsi && (DSI_1 == id)) 455 + goto disable_phy; 554 456 555 457 if (panel) { 556 458 ret = drm_panel_disable(panel); ··· 593 481 pr_err("%s: host1 power off failed, %d\n", 594 482 __func__, ret); 595 483 } 484 + 485 + disable_phy: 486 + dsi_mgr_phy_disable(id); 596 487 } 597 488 598 489 static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, ··· 655 540 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 656 541 struct drm_connector *connector = NULL; 657 542 struct dsi_connector *dsi_connector; 658 - int ret, i; 543 + int ret; 659 544 660 545 dsi_connector = kzalloc(sizeof(*dsi_connector), GFP_KERNEL); 661 546 if (!dsi_connector) ··· 681 566 connector->interlace_allowed = 0; 682 567 connector->doublescan_allowed = 0; 683 568 684 - for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) 685 - drm_mode_connector_attach_encoder(connector, 686 - msm_dsi->encoders[i]); 569 + drm_mode_connector_attach_encoder(connector, msm_dsi->encoder); 687 570 688 571 return connector; 689 572 } ··· 704 591 705 592 dsi_bridge->id = id; 706 593 707 - /* 708 - * HACK: we may not know the external DSI bridge device's mode 709 - * flags here. We'll get to know them only when the device 710 - * attaches to the dsi host. For now, assume the bridge supports 711 - * DSI video mode 712 - */ 713 - encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; 594 + encoder = msm_dsi->encoder; 714 595 715 596 bridge = &dsi_bridge->base; 716 597 bridge->funcs = &dsi_mgr_bridge_funcs; ··· 735 628 ext_bridge = msm_dsi->external_bridge = 736 629 msm_dsi_host_get_bridge(msm_dsi->host); 737 630 738 - /* 739 - * HACK: we may not know the external DSI bridge device's mode 740 - * flags here. We'll get to know them only when the device 741 - * attaches to the dsi host. For now, assume the bridge supports 742 - * DSI video mode 743 - */ 744 - encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; 631 + encoder = msm_dsi->encoder; 745 632 746 633 /* link the internal dsi bridge to the external bridge */ 747 634 drm_bridge_attach(encoder, ext_bridge, int_bridge); ··· 761 660 762 661 void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge) 763 662 { 764 - } 765 - 766 - int msm_dsi_manager_phy_enable(int id, 767 - const unsigned long bit_rate, const unsigned long esc_rate, 768 - u32 *clk_pre, u32 *clk_post) 769 - { 770 - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 771 - struct msm_dsi_phy *phy = msm_dsi->phy; 772 - int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; 773 - struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 774 - int ret; 775 - 776 - ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate); 777 - if (ret) 778 - return ret; 779 - 780 - /* 781 - * Reset DSI PHY silently changes its PLL registers to reset status, 782 - * which will confuse clock driver and result in wrong output rate of 783 - * link clocks. Restore PLL status if its PLL is being used as clock 784 - * source. 785 - */ 786 - if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) { 787 - ret = msm_dsi_pll_restore_state(pll); 788 - if (ret) { 789 - pr_err("%s: failed to restore pll state\n", __func__); 790 - msm_dsi_phy_disable(phy); 791 - return ret; 792 - } 793 - } 794 - 795 - msm_dsi->phy_enabled = true; 796 - msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post); 797 - 798 - return 0; 799 - } 800 - 801 - void msm_dsi_manager_phy_disable(int id) 802 - { 803 - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 804 - struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 805 - struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 806 - struct msm_dsi_phy *phy = msm_dsi->phy; 807 - struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 808 - 809 - /* Save PLL status if it is a clock source */ 810 - if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) 811 - msm_dsi_pll_save_state(pll); 812 - 813 - /* disable DSI phy 814 - * In dual-dsi configuration, the phy should be disabled for the 815 - * first controller only when the second controller is disabled. 816 - */ 817 - msm_dsi->phy_enabled = false; 818 - if (IS_DUAL_DSI() && mdsi && sdsi) { 819 - if (!mdsi->phy_enabled && !sdsi->phy_enabled) { 820 - msm_dsi_phy_disable(sdsi->phy); 821 - msm_dsi_phy_disable(mdsi->phy); 822 - } 823 - } else { 824 - msm_dsi_phy_disable(phy); 825 - } 826 663 } 827 664 828 665 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) ··· 826 787 return true; 827 788 } 828 789 790 + void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags) 791 + { 792 + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 793 + struct drm_device *dev = msm_dsi->dev; 794 + struct msm_drm_private *priv; 795 + struct msm_kms *kms; 796 + struct drm_encoder *encoder; 797 + 798 + /* 799 + * drm_device pointer is assigned to msm_dsi only in the modeset_init 800 + * path. If mipi_dsi_attach() happens in DSI driver's probe path 801 + * (generally the case when we're connected to a drm_panel of the type 802 + * mipi_dsi_device), this would be NULL. In such cases, try to set the 803 + * encoder mode in the DSI connector's detect() op. 804 + */ 805 + if (!dev) 806 + return; 807 + 808 + priv = dev->dev_private; 809 + kms = priv->kms; 810 + encoder = msm_dsi_get_encoder(msm_dsi); 811 + 812 + if (encoder && kms->funcs->set_encoder_mode) 813 + if (!(device_flags & MIPI_DSI_MODE_VIDEO)) 814 + kms->funcs->set_encoder_mode(kms, encoder, true); 815 + } 816 + 829 817 int msm_dsi_manager_register(struct msm_dsi *msm_dsi) 830 818 { 831 819 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; ··· 877 811 goto fail; 878 812 } 879 813 880 - ret = dsi_mgr_host_register(id); 814 + ret = dsi_mgr_setup_components(id); 881 815 if (ret) { 882 816 pr_err("%s: failed to register mipi dsi host for DSI %d\n", 883 817 __func__, id);
+209 -30
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
··· 54 54 } 55 55 56 56 int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing, 57 - const unsigned long bit_rate, const unsigned long esc_rate) 57 + struct msm_dsi_phy_clk_request *clk_req) 58 58 { 59 + const unsigned long bit_rate = clk_req->bitclk_rate; 60 + const unsigned long esc_rate = clk_req->escclk_rate; 59 61 s32 ui, lpx; 60 62 s32 tmax, tmin; 61 63 s32 pcnt0 = 10; ··· 117 115 temp = ((timing->hs_exit >> 1) + 1) * 2 * ui; 118 116 temp = 60 * coeff + 52 * ui - 24 * ui - temp; 119 117 tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1; 120 - timing->clk_post = linear_inter(tmax, tmin, pcnt2, 0, false); 121 - 118 + timing->shared_timings.clk_post = linear_inter(tmax, tmin, pcnt2, 0, 119 + false); 122 120 tmax = 63; 123 121 temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui; 124 122 temp += ((timing->clk_zero >> 1) + 1) * 2 * ui; ··· 126 124 tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1; 127 125 if (tmin > tmax) { 128 126 temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false); 129 - timing->clk_pre = temp >> 1; 127 + timing->shared_timings.clk_pre = temp >> 1; 128 + timing->shared_timings.clk_pre_inc_by_2 = true; 130 129 } else { 131 - timing->clk_pre = linear_inter(tmax, tmin, pcnt2, 0, false); 130 + timing->shared_timings.clk_pre = 131 + linear_inter(tmax, tmin, pcnt2, 0, false); 132 + timing->shared_timings.clk_pre_inc_by_2 = false; 132 133 } 133 134 134 135 timing->ta_go = 3; 135 136 timing->ta_sure = 0; 136 137 timing->ta_get = 4; 137 138 138 - DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", 139 - timing->clk_pre, timing->clk_post, timing->clk_zero, 139 + DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", 140 + timing->shared_timings.clk_pre, timing->shared_timings.clk_post, 141 + timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero, 140 142 timing->clk_trail, timing->clk_prepare, timing->hs_exit, 141 143 timing->hs_zero, timing->hs_prepare, timing->hs_trail, 142 144 timing->hs_rqst); 145 + 146 + return 0; 147 + } 148 + 149 + int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, 150 + struct msm_dsi_phy_clk_request *clk_req) 151 + { 152 + const unsigned long bit_rate = clk_req->bitclk_rate; 153 + const unsigned long esc_rate = clk_req->escclk_rate; 154 + s32 ui, ui_x8, lpx; 155 + s32 tmax, tmin; 156 + s32 pcnt0 = 50; 157 + s32 pcnt1 = 50; 158 + s32 pcnt2 = 10; 159 + s32 pcnt3 = 30; 160 + s32 pcnt4 = 10; 161 + s32 pcnt5 = 2; 162 + s32 coeff = 1000; /* Precision, should avoid overflow */ 163 + s32 hb_en, hb_en_ckln, pd_ckln, pd; 164 + s32 val, val_ckln; 165 + s32 temp; 166 + 167 + if (!bit_rate || !esc_rate) 168 + return -EINVAL; 169 + 170 + timing->hs_halfbyte_en = 0; 171 + hb_en = 0; 172 + timing->hs_halfbyte_en_ckln = 0; 173 + hb_en_ckln = 0; 174 + timing->hs_prep_dly_ckln = (bit_rate > 100000000) ? 0 : 3; 175 + pd_ckln = timing->hs_prep_dly_ckln; 176 + timing->hs_prep_dly = (bit_rate > 120000000) ? 0 : 1; 177 + pd = timing->hs_prep_dly; 178 + 179 + val = (hb_en << 2) + (pd << 1); 180 + val_ckln = (hb_en_ckln << 2) + (pd_ckln << 1); 181 + 182 + ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); 183 + ui_x8 = ui << 3; 184 + lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000); 185 + 186 + temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8); 187 + tmin = max_t(s32, temp, 0); 188 + temp = (95 * coeff - val_ckln * ui) / ui_x8; 189 + tmax = max_t(s32, temp, 0); 190 + timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false); 191 + 192 + temp = 300 * coeff - ((timing->clk_prepare << 3) + val_ckln) * ui; 193 + tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3; 194 + tmax = (tmin > 255) ? 511 : 255; 195 + timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false); 196 + 197 + tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8); 198 + temp = 105 * coeff + 12 * ui - 20 * coeff; 199 + tmax = (temp + 3 * ui) / ui_x8; 200 + timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false); 201 + 202 + temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui - val * ui, ui_x8); 203 + tmin = max_t(s32, temp, 0); 204 + temp = (85 * coeff + 6 * ui - val * ui) / ui_x8; 205 + tmax = max_t(s32, temp, 0); 206 + timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false); 207 + 208 + temp = 145 * coeff + 10 * ui - ((timing->hs_prepare << 3) + val) * ui; 209 + tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3; 210 + tmax = 255; 211 + timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false); 212 + 213 + tmin = DIV_ROUND_UP(60 * coeff + 4 * ui + 3 * ui, ui_x8); 214 + temp = 105 * coeff + 12 * ui - 20 * coeff; 215 + tmax = (temp + 3 * ui) / ui_x8; 216 + timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false); 217 + 218 + temp = 50 * coeff + ((hb_en << 2) - 8) * ui; 219 + timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8); 220 + 221 + tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1; 222 + tmax = 255; 223 + timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false); 224 + 225 + temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui; 226 + timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8); 227 + 228 + temp = 60 * coeff + 52 * ui - 43 * ui; 229 + tmin = DIV_ROUND_UP(temp, ui_x8) - 1; 230 + tmax = 63; 231 + timing->shared_timings.clk_post = 232 + linear_inter(tmax, tmin, pcnt2, 0, false); 233 + 234 + temp = 8 * ui + ((timing->clk_prepare << 3) + val_ckln) * ui; 235 + temp += (((timing->clk_zero + 3) << 3) + 11 - (pd_ckln << 1)) * ui; 236 + temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) : 237 + (((timing->hs_rqst_ckln << 3) + 8) * ui); 238 + tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1; 239 + tmax = 63; 240 + if (tmin > tmax) { 241 + temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false); 242 + timing->shared_timings.clk_pre = temp >> 1; 243 + timing->shared_timings.clk_pre_inc_by_2 = 1; 244 + } else { 245 + timing->shared_timings.clk_pre = 246 + linear_inter(tmax, tmin, pcnt2, 0, false); 247 + timing->shared_timings.clk_pre_inc_by_2 = 0; 248 + } 249 + 250 + timing->ta_go = 3; 251 + timing->ta_sure = 0; 252 + timing->ta_get = 4; 253 + 254 + DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", 255 + timing->shared_timings.clk_pre, timing->shared_timings.clk_post, 256 + timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero, 257 + timing->clk_trail, timing->clk_prepare, timing->hs_exit, 258 + timing->hs_zero, timing->hs_prepare, timing->hs_trail, 259 + timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en, 260 + timing->hs_halfbyte_en_ckln, timing->hs_prep_dly, 261 + timing->hs_prep_dly_ckln); 143 262 144 263 return 0; 145 264 } ··· 391 268 { .compatible = "qcom,dsi-phy-28nm-8960", 392 269 .data = &dsi_phy_28nm_8960_cfgs }, 393 270 #endif 271 + #ifdef CONFIG_DRM_MSM_DSI_14NM_PHY 272 + { .compatible = "qcom,dsi-phy-14nm", 273 + .data = &dsi_phy_14nm_cfgs }, 274 + #endif 394 275 {} 395 276 }; 396 277 ··· 420 293 } 421 294 422 295 return -EINVAL; 296 + } 297 + 298 + int msm_dsi_phy_init_common(struct msm_dsi_phy *phy) 299 + { 300 + struct platform_device *pdev = phy->pdev; 301 + int ret = 0; 302 + 303 + phy->reg_base = msm_ioremap(pdev, "dsi_phy_regulator", 304 + "DSI_PHY_REG"); 305 + if (IS_ERR(phy->reg_base)) { 306 + dev_err(&pdev->dev, "%s: failed to map phy regulator base\n", 307 + __func__); 308 + ret = -ENOMEM; 309 + goto fail; 310 + } 311 + 312 + fail: 313 + return ret; 423 314 } 424 315 425 316 static int dsi_phy_driver_probe(struct platform_device *pdev) ··· 476 331 goto fail; 477 332 } 478 333 479 - phy->reg_base = msm_ioremap(pdev, "dsi_phy_regulator", 480 - "DSI_PHY_REG"); 481 - if (IS_ERR(phy->reg_base)) { 482 - dev_err(dev, "%s: failed to map phy regulator base\n", 483 - __func__); 484 - ret = -ENOMEM; 485 - goto fail; 486 - } 487 - 488 334 ret = dsi_phy_regulator_init(phy); 489 335 if (ret) { 490 336 dev_err(dev, "%s: failed to init regulator\n", __func__); ··· 487 351 dev_err(dev, "%s: Unable to get ahb clk\n", __func__); 488 352 ret = PTR_ERR(phy->ahb_clk); 489 353 goto fail; 354 + } 355 + 356 + if (phy->cfg->ops.init) { 357 + ret = phy->cfg->ops.init(phy); 358 + if (ret) 359 + goto fail; 490 360 } 491 361 492 362 /* PLL init will call into clk_register which requires ··· 552 410 } 553 411 554 412 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 555 - const unsigned long bit_rate, const unsigned long esc_rate) 413 + struct msm_dsi_phy_clk_request *clk_req) 556 414 { 557 415 struct device *dev = &phy->pdev->dev; 558 416 int ret; ··· 560 418 if (!phy || !phy->cfg->ops.enable) 561 419 return -EINVAL; 562 420 421 + ret = dsi_phy_enable_resource(phy); 422 + if (ret) { 423 + dev_err(dev, "%s: resource enable failed, %d\n", 424 + __func__, ret); 425 + goto res_en_fail; 426 + } 427 + 563 428 ret = dsi_phy_regulator_enable(phy); 564 429 if (ret) { 565 430 dev_err(dev, "%s: regulator enable failed, %d\n", 566 431 __func__, ret); 567 - return ret; 432 + goto reg_en_fail; 568 433 } 569 434 570 - ret = phy->cfg->ops.enable(phy, src_pll_id, bit_rate, esc_rate); 435 + ret = phy->cfg->ops.enable(phy, src_pll_id, clk_req); 571 436 if (ret) { 572 437 dev_err(dev, "%s: phy enable failed, %d\n", __func__, ret); 573 - dsi_phy_regulator_disable(phy); 574 - return ret; 438 + goto phy_en_fail; 439 + } 440 + 441 + /* 442 + * Resetting DSI PHY silently changes its PLL registers to reset status, 443 + * which will confuse clock driver and result in wrong output rate of 444 + * link clocks. Restore PLL status if its PLL is being used as clock 445 + * source. 446 + */ 447 + if (phy->usecase != MSM_DSI_PHY_SLAVE) { 448 + ret = msm_dsi_pll_restore_state(phy->pll); 449 + if (ret) { 450 + dev_err(dev, "%s: failed to restore pll state, %d\n", 451 + __func__, ret); 452 + goto pll_restor_fail; 453 + } 575 454 } 576 455 577 456 return 0; 457 + 458 + pll_restor_fail: 459 + if (phy->cfg->ops.disable) 460 + phy->cfg->ops.disable(phy); 461 + phy_en_fail: 462 + dsi_phy_regulator_disable(phy); 463 + reg_en_fail: 464 + dsi_phy_disable_resource(phy); 465 + res_en_fail: 466 + return ret; 578 467 } 579 468 580 469 void msm_dsi_phy_disable(struct msm_dsi_phy *phy) ··· 613 440 if (!phy || !phy->cfg->ops.disable) 614 441 return; 615 442 443 + /* Save PLL status if it is a clock source */ 444 + if (phy->usecase != MSM_DSI_PHY_SLAVE) 445 + msm_dsi_pll_save_state(phy->pll); 446 + 616 447 phy->cfg->ops.disable(phy); 617 448 618 449 dsi_phy_regulator_disable(phy); 450 + dsi_phy_disable_resource(phy); 619 451 } 620 452 621 - void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy, 622 - u32 *clk_pre, u32 *clk_post) 453 + void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy, 454 + struct msm_dsi_phy_shared_timings *shared_timings) 623 455 { 624 - if (!phy) 625 - return; 626 - 627 - if (clk_pre) 628 - *clk_pre = phy->timing.clk_pre; 629 - if (clk_post) 630 - *clk_post = phy->timing.clk_post; 456 + memcpy(shared_timings, &phy->timing.shared_timings, 457 + sizeof(*shared_timings)); 631 458 } 632 459 633 460 struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy) ··· 638 465 return phy->pll; 639 466 } 640 467 468 + void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy, 469 + enum msm_dsi_phy_usecase uc) 470 + { 471 + if (phy) 472 + phy->usecase = uc; 473 + }
+18 -2
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
··· 22 22 #define dsi_phy_write(offset, data) msm_writel((data), (offset)) 23 23 24 24 struct msm_dsi_phy_ops { 25 + int (*init) (struct msm_dsi_phy *phy); 25 26 int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, 26 - const unsigned long bit_rate, const unsigned long esc_rate); 27 + struct msm_dsi_phy_clk_request *clk_req); 27 28 void (*disable)(struct msm_dsi_phy *phy); 28 29 }; 29 30 ··· 47 46 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs; 48 47 extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs; 49 48 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs; 49 + extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs; 50 50 51 51 struct msm_dsi_dphy_timing { 52 52 u32 clk_pre; ··· 63 61 u32 ta_go; 64 62 u32 ta_sure; 65 63 u32 ta_get; 64 + 65 + struct msm_dsi_phy_shared_timings shared_timings; 66 + 67 + /* For PHY v2 only */ 68 + u32 hs_rqst_ckln; 69 + u32 hs_prep_dly; 70 + u32 hs_prep_dly_ckln; 71 + u8 hs_halfbyte_en; 72 + u8 hs_halfbyte_en_ckln; 66 73 }; 67 74 68 75 struct msm_dsi_phy { 69 76 struct platform_device *pdev; 70 77 void __iomem *base; 71 78 void __iomem *reg_base; 79 + void __iomem *lane_base; 72 80 int id; 73 81 74 82 struct clk *ahb_clk; ··· 87 75 struct msm_dsi_dphy_timing timing; 88 76 const struct msm_dsi_phy_cfg *cfg; 89 77 78 + enum msm_dsi_phy_usecase usecase; 90 79 bool regulator_ldo_mode; 91 80 92 81 struct msm_dsi_pll *pll; ··· 97 84 * PHY internal functions 98 85 */ 99 86 int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing, 100 - const unsigned long bit_rate, const unsigned long esc_rate); 87 + struct msm_dsi_phy_clk_request *clk_req); 88 + int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, 89 + struct msm_dsi_phy_clk_request *clk_req); 101 90 void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, 102 91 u32 bit_mask); 92 + int msm_dsi_phy_init_common(struct msm_dsi_phy *phy); 103 93 104 94 #endif /* __DSI_PHY_H__ */ 105 95
+169
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
··· 1 + /* 2 + * Copyright (c) 2016, The Linux Foundation. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 and 6 + * only version 2 as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include "dsi_phy.h" 15 + #include "dsi.xml.h" 16 + 17 + #define PHY_14NM_CKLN_IDX 4 18 + 19 + static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy, 20 + struct msm_dsi_dphy_timing *timing, 21 + int lane_idx) 22 + { 23 + void __iomem *base = phy->lane_base; 24 + bool clk_ln = (lane_idx == PHY_14NM_CKLN_IDX); 25 + u32 zero = clk_ln ? timing->clk_zero : timing->hs_zero; 26 + u32 prepare = clk_ln ? timing->clk_prepare : timing->hs_prepare; 27 + u32 trail = clk_ln ? timing->clk_trail : timing->hs_trail; 28 + u32 rqst = clk_ln ? timing->hs_rqst_ckln : timing->hs_rqst; 29 + u32 prep_dly = clk_ln ? timing->hs_prep_dly_ckln : timing->hs_prep_dly; 30 + u32 halfbyte_en = clk_ln ? timing->hs_halfbyte_en_ckln : 31 + timing->hs_halfbyte_en; 32 + 33 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_4(lane_idx), 34 + DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT(timing->hs_exit)); 35 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_5(lane_idx), 36 + DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO(zero)); 37 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_6(lane_idx), 38 + DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE(prepare)); 39 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_7(lane_idx), 40 + DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL(trail)); 41 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_8(lane_idx), 42 + DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST(rqst)); 43 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG0(lane_idx), 44 + DSI_14nm_PHY_LN_CFG0_PREPARE_DLY(prep_dly)); 45 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG1(lane_idx), 46 + halfbyte_en ? DSI_14nm_PHY_LN_CFG1_HALFBYTECLK_EN : 0); 47 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_9(lane_idx), 48 + DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO(timing->ta_go) | 49 + DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE(timing->ta_sure)); 50 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_10(lane_idx), 51 + DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET(timing->ta_get)); 52 + dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_11(lane_idx), 53 + DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(0xa0)); 54 + } 55 + 56 + static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 57 + struct msm_dsi_phy_clk_request *clk_req) 58 + { 59 + struct msm_dsi_dphy_timing *timing = &phy->timing; 60 + u32 data; 61 + int i; 62 + int ret; 63 + void __iomem *base = phy->base; 64 + void __iomem *lane_base = phy->lane_base; 65 + 66 + if (msm_dsi_dphy_timing_calc_v2(timing, clk_req)) { 67 + dev_err(&phy->pdev->dev, 68 + "%s: D-PHY timing calculation failed\n", __func__); 69 + return -EINVAL; 70 + } 71 + 72 + data = 0x1c; 73 + if (phy->usecase != MSM_DSI_PHY_STANDALONE) 74 + data |= DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL(32); 75 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); 76 + 77 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0x1); 78 + 79 + /* 4 data lanes + 1 clk lane configuration */ 80 + for (i = 0; i < 5; i++) { 81 + dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_VREG_CNTRL(i), 82 + 0x1d); 83 + 84 + dsi_phy_write(lane_base + 85 + REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_0(i), 0xff); 86 + dsi_phy_write(lane_base + 87 + REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_1(i), 88 + (i == PHY_14NM_CKLN_IDX) ? 0x00 : 0x06); 89 + 90 + dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG3(i), 91 + (i == PHY_14NM_CKLN_IDX) ? 0x8f : 0x0f); 92 + dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG2(i), 0x10); 93 + dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_DATAPATH(i), 94 + 0); 95 + dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_STR(i), 96 + 0x88); 97 + 98 + dsi_14nm_dphy_set_timing(phy, timing, i); 99 + } 100 + 101 + /* Make sure PLL is not start */ 102 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0x00); 103 + 104 + wmb(); /* make sure everything is written before reset and enable */ 105 + 106 + /* reset digital block */ 107 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x80); 108 + wmb(); /* ensure reset is asserted */ 109 + udelay(100); 110 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00); 111 + 112 + msm_dsi_phy_set_src_pll(phy, src_pll_id, 113 + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 114 + DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL); 115 + 116 + ret = msm_dsi_pll_set_usecase(phy->pll, phy->usecase); 117 + if (ret) { 118 + dev_err(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", 119 + __func__, ret); 120 + return ret; 121 + } 122 + 123 + /* Remove power down from PLL and all lanes */ 124 + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0xff); 125 + 126 + return 0; 127 + } 128 + 129 + static void dsi_14nm_phy_disable(struct msm_dsi_phy *phy) 130 + { 131 + dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0); 132 + dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0); 133 + 134 + /* ensure that the phy is completely disabled */ 135 + wmb(); 136 + } 137 + 138 + static int dsi_14nm_phy_init(struct msm_dsi_phy *phy) 139 + { 140 + struct platform_device *pdev = phy->pdev; 141 + 142 + phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane", 143 + "DSI_PHY_LANE"); 144 + if (IS_ERR(phy->lane_base)) { 145 + dev_err(&pdev->dev, "%s: failed to map phy lane base\n", 146 + __func__); 147 + return -ENOMEM; 148 + } 149 + 150 + return 0; 151 + } 152 + 153 + const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = { 154 + .type = MSM_DSI_PHY_14NM, 155 + .src_pll_truthtable = { {false, false}, {true, false} }, 156 + .reg_cfg = { 157 + .num = 1, 158 + .regs = { 159 + {"vcca", 17000, 32}, 160 + }, 161 + }, 162 + .ops = { 163 + .enable = dsi_14nm_phy_enable, 164 + .disable = dsi_14nm_phy_disable, 165 + .init = dsi_14nm_phy_init, 166 + }, 167 + .io_start = { 0x994400, 0x996400 }, 168 + .num_dsi_phy = 2, 169 + };
+3 -2
drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c
··· 72 72 } 73 73 74 74 static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 75 - const unsigned long bit_rate, const unsigned long esc_rate) 75 + struct msm_dsi_phy_clk_request *clk_req) 76 76 { 77 77 struct msm_dsi_dphy_timing *timing = &phy->timing; 78 78 int i; ··· 81 81 82 82 DBG(""); 83 83 84 - if (msm_dsi_dphy_timing_calc(timing, bit_rate, esc_rate)) { 84 + if (msm_dsi_dphy_timing_calc(timing, clk_req)) { 85 85 dev_err(&phy->pdev->dev, 86 86 "%s: D-PHY timing calculation failed\n", __func__); 87 87 return -EINVAL; ··· 145 145 .ops = { 146 146 .enable = dsi_20nm_phy_enable, 147 147 .disable = dsi_20nm_phy_disable, 148 + .init = msm_dsi_phy_init_common, 148 149 }, 149 150 .io_start = { 0xfd998300, 0xfd9a0300 }, 150 151 .num_dsi_phy = 2,
+4 -2
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
··· 67 67 } 68 68 69 69 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 70 - const unsigned long bit_rate, const unsigned long esc_rate) 70 + struct msm_dsi_phy_clk_request *clk_req) 71 71 { 72 72 struct msm_dsi_dphy_timing *timing = &phy->timing; 73 73 int i; ··· 75 75 76 76 DBG(""); 77 77 78 - if (msm_dsi_dphy_timing_calc(timing, bit_rate, esc_rate)) { 78 + if (msm_dsi_dphy_timing_calc(timing, clk_req)) { 79 79 dev_err(&phy->pdev->dev, 80 80 "%s: D-PHY timing calculation failed\n", __func__); 81 81 return -EINVAL; ··· 144 144 .ops = { 145 145 .enable = dsi_28nm_phy_enable, 146 146 .disable = dsi_28nm_phy_disable, 147 + .init = msm_dsi_phy_init_common, 147 148 }, 148 149 .io_start = { 0xfd922b00, 0xfd923100 }, 149 150 .num_dsi_phy = 2, ··· 162 161 .ops = { 163 162 .enable = dsi_28nm_phy_enable, 164 163 .disable = dsi_28nm_phy_disable, 164 + .init = msm_dsi_phy_init_common, 165 165 }, 166 166 .io_start = { 0x1a98500 }, 167 167 .num_dsi_phy = 1,
+3 -2
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
··· 124 124 } 125 125 126 126 static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, 127 - const unsigned long bit_rate, const unsigned long esc_rate) 127 + struct msm_dsi_phy_clk_request *clk_req) 128 128 { 129 129 struct msm_dsi_dphy_timing *timing = &phy->timing; 130 130 void __iomem *base = phy->base; 131 131 132 132 DBG(""); 133 133 134 - if (msm_dsi_dphy_timing_calc(timing, bit_rate, esc_rate)) { 134 + if (msm_dsi_dphy_timing_calc(timing, clk_req)) { 135 135 dev_err(&phy->pdev->dev, 136 136 "%s: D-PHY timing calculation failed\n", __func__); 137 137 return -EINVAL; ··· 191 191 .ops = { 192 192 .enable = dsi_28nm_phy_enable, 193 193 .disable = dsi_28nm_phy_disable, 194 + .init = msm_dsi_phy_init_common, 194 195 }, 195 196 .io_start = { 0x4700300, 0x5800300 }, 196 197 .num_dsi_phy = 2,
+12
drivers/gpu/drm/msm/dsi/pll/dsi_pll.c
··· 140 140 return 0; 141 141 } 142 142 143 + int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll, 144 + enum msm_dsi_phy_usecase uc) 145 + { 146 + if (pll->set_usecase) 147 + return pll->set_usecase(pll, uc); 148 + 149 + return 0; 150 + } 151 + 143 152 struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, 144 153 enum msm_dsi_phy_type type, int id) 145 154 { ··· 162 153 break; 163 154 case MSM_DSI_PHY_28NM_8960: 164 155 pll = msm_dsi_pll_28nm_8960_init(pdev, id); 156 + break; 157 + case MSM_DSI_PHY_14NM: 158 + pll = msm_dsi_pll_14nm_init(pdev, id); 165 159 break; 166 160 default: 167 161 pll = ERR_PTR(-ENXIO);
+11
drivers/gpu/drm/msm/dsi/pll/dsi_pll.h
··· 41 41 void (*destroy)(struct msm_dsi_pll *pll); 42 42 void (*save_state)(struct msm_dsi_pll *pll); 43 43 int (*restore_state)(struct msm_dsi_pll *pll); 44 + int (*set_usecase)(struct msm_dsi_pll *pll, 45 + enum msm_dsi_phy_usecase uc); 44 46 }; 45 47 46 48 #define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw) ··· 106 104 } 107 105 #endif 108 106 107 + #ifdef CONFIG_DRM_MSM_DSI_14NM_PHY 108 + struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id); 109 + #else 110 + static inline struct msm_dsi_pll * 111 + msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) 112 + { 113 + return ERR_PTR(-ENODEV); 114 + } 115 + #endif 109 116 #endif /* __DSI_PLL_H__ */ 110 117
+1104
drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c
··· 1 + /* 2 + * Copyright (c) 2016, The Linux Foundation. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 and 6 + * only version 2 as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/clk.h> 15 + #include <linux/clk-provider.h> 16 + 17 + #include "dsi_pll.h" 18 + #include "dsi.xml.h" 19 + 20 + /* 21 + * DSI PLL 14nm - clock diagram (eg: DSI0): 22 + * 23 + * dsi0n1_postdiv_clk 24 + * | 25 + * | 26 + * +----+ | +----+ 27 + * dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte 28 + * +----+ | +----+ 29 + * | dsi0n1_postdivby2_clk 30 + * | +----+ | 31 + * o---| /2 |--o--|\ 32 + * | +----+ | \ +----+ 33 + * | | |--| n2 |-- dsi0pll 34 + * o--------------| / +----+ 35 + * |/ 36 + */ 37 + 38 + #define POLL_MAX_READS 15 39 + #define POLL_TIMEOUT_US 1000 40 + 41 + #define NUM_PROVIDED_CLKS 2 42 + 43 + #define VCO_REF_CLK_RATE 19200000 44 + #define VCO_MIN_RATE 1300000000UL 45 + #define VCO_MAX_RATE 2600000000UL 46 + 47 + #define DSI_BYTE_PLL_CLK 0 48 + #define DSI_PIXEL_PLL_CLK 1 49 + 50 + #define DSI_PLL_DEFAULT_VCO_POSTDIV 1 51 + 52 + struct dsi_pll_input { 53 + u32 fref; /* reference clk */ 54 + u32 fdata; /* bit clock rate */ 55 + u32 dsiclk_sel; /* Mux configuration (see diagram) */ 56 + u32 ssc_en; /* SSC enable/disable */ 57 + u32 ldo_en; 58 + 59 + /* fixed params */ 60 + u32 refclk_dbler_en; 61 + u32 vco_measure_time; 62 + u32 kvco_measure_time; 63 + u32 bandgap_timer; 64 + u32 pll_wakeup_timer; 65 + u32 plllock_cnt; 66 + u32 plllock_rng; 67 + u32 ssc_center; 68 + u32 ssc_adj_period; 69 + u32 ssc_spread; 70 + u32 ssc_freq; 71 + u32 pll_ie_trim; 72 + u32 pll_ip_trim; 73 + u32 pll_iptat_trim; 74 + u32 pll_cpcset_cur; 75 + u32 pll_cpmset_cur; 76 + 77 + u32 pll_icpmset; 78 + u32 pll_icpcset; 79 + 80 + u32 pll_icpmset_p; 81 + u32 pll_icpmset_m; 82 + 83 + u32 pll_icpcset_p; 84 + u32 pll_icpcset_m; 85 + 86 + u32 pll_lpf_res1; 87 + u32 pll_lpf_cap1; 88 + u32 pll_lpf_cap2; 89 + u32 pll_c3ctrl; 90 + u32 pll_r3ctrl; 91 + }; 92 + 93 + struct dsi_pll_output { 94 + u32 pll_txclk_en; 95 + u32 dec_start; 96 + u32 div_frac_start; 97 + u32 ssc_period; 98 + u32 ssc_step_size; 99 + u32 plllock_cmp; 100 + u32 pll_vco_div_ref; 101 + u32 pll_vco_count; 102 + u32 pll_kvco_div_ref; 103 + u32 pll_kvco_count; 104 + u32 pll_misc1; 105 + u32 pll_lpf2_postdiv; 106 + u32 pll_resetsm_cntrl; 107 + u32 pll_resetsm_cntrl2; 108 + u32 pll_resetsm_cntrl5; 109 + u32 pll_kvco_code; 110 + 111 + u32 cmn_clk_cfg0; 112 + u32 cmn_clk_cfg1; 113 + u32 cmn_ldo_cntrl; 114 + 115 + u32 pll_postdiv; 116 + u32 fcvo; 117 + }; 118 + 119 + struct pll_14nm_cached_state { 120 + unsigned long vco_rate; 121 + u8 n2postdiv; 122 + u8 n1postdiv; 123 + }; 124 + 125 + struct dsi_pll_14nm { 126 + struct msm_dsi_pll base; 127 + 128 + int id; 129 + struct platform_device *pdev; 130 + 131 + void __iomem *phy_cmn_mmio; 132 + void __iomem *mmio; 133 + 134 + int vco_delay; 135 + 136 + struct dsi_pll_input in; 137 + struct dsi_pll_output out; 138 + 139 + /* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */ 140 + spinlock_t postdiv_lock; 141 + 142 + u64 vco_current_rate; 143 + u64 vco_ref_clk_rate; 144 + 145 + /* private clocks: */ 146 + struct clk_hw *hws[NUM_DSI_CLOCKS_MAX]; 147 + u32 num_hws; 148 + 149 + /* clock-provider: */ 150 + struct clk_hw_onecell_data *hw_data; 151 + 152 + struct pll_14nm_cached_state cached_state; 153 + 154 + enum msm_dsi_phy_usecase uc; 155 + struct dsi_pll_14nm *slave; 156 + }; 157 + 158 + #define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base) 159 + 160 + /* 161 + * Private struct for N1/N2 post-divider clocks. These clocks are similar to 162 + * the generic clk_divider class of clocks. The only difference is that it 163 + * also sets the slave DSI PLL's post-dividers if in Dual DSI mode 164 + */ 165 + struct dsi_pll_14nm_postdiv { 166 + struct clk_hw hw; 167 + 168 + /* divider params */ 169 + u8 shift; 170 + u8 width; 171 + u8 flags; /* same flags as used by clk_divider struct */ 172 + 173 + struct dsi_pll_14nm *pll; 174 + }; 175 + 176 + #define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw) 177 + 178 + /* 179 + * Global list of private DSI PLL struct pointers. We need this for Dual DSI 180 + * mode, where the master PLL's clk_ops needs access the slave's private data 181 + */ 182 + static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX]; 183 + 184 + static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, 185 + u32 nb_tries, u32 timeout_us) 186 + { 187 + bool pll_locked = false; 188 + void __iomem *base = pll_14nm->mmio; 189 + u32 tries, val; 190 + 191 + tries = nb_tries; 192 + while (tries--) { 193 + val = pll_read(base + 194 + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); 195 + pll_locked = !!(val & BIT(5)); 196 + 197 + if (pll_locked) 198 + break; 199 + 200 + udelay(timeout_us); 201 + } 202 + 203 + if (!pll_locked) { 204 + tries = nb_tries; 205 + while (tries--) { 206 + val = pll_read(base + 207 + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); 208 + pll_locked = !!(val & BIT(0)); 209 + 210 + if (pll_locked) 211 + break; 212 + 213 + udelay(timeout_us); 214 + } 215 + } 216 + 217 + DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); 218 + 219 + return pll_locked; 220 + } 221 + 222 + static void dsi_pll_14nm_input_init(struct dsi_pll_14nm *pll) 223 + { 224 + pll->in.fref = pll->vco_ref_clk_rate; 225 + pll->in.fdata = 0; 226 + pll->in.dsiclk_sel = 1; /* Use the /2 path in Mux */ 227 + pll->in.ldo_en = 0; /* disabled for now */ 228 + 229 + /* fixed input */ 230 + pll->in.refclk_dbler_en = 0; 231 + pll->in.vco_measure_time = 5; 232 + pll->in.kvco_measure_time = 5; 233 + pll->in.bandgap_timer = 4; 234 + pll->in.pll_wakeup_timer = 5; 235 + pll->in.plllock_cnt = 1; 236 + pll->in.plllock_rng = 0; 237 + 238 + /* 239 + * SSC is enabled by default. We might need DT props for configuring 240 + * some SSC params like PPM and center/down spread etc. 241 + */ 242 + pll->in.ssc_en = 1; 243 + pll->in.ssc_center = 0; /* down spread by default */ 244 + pll->in.ssc_spread = 5; /* PPM / 1000 */ 245 + pll->in.ssc_freq = 31500; /* default recommended */ 246 + pll->in.ssc_adj_period = 37; 247 + 248 + pll->in.pll_ie_trim = 4; 249 + pll->in.pll_ip_trim = 4; 250 + pll->in.pll_cpcset_cur = 1; 251 + pll->in.pll_cpmset_cur = 1; 252 + pll->in.pll_icpmset = 4; 253 + pll->in.pll_icpcset = 4; 254 + pll->in.pll_icpmset_p = 0; 255 + pll->in.pll_icpmset_m = 0; 256 + pll->in.pll_icpcset_p = 0; 257 + pll->in.pll_icpcset_m = 0; 258 + pll->in.pll_lpf_res1 = 3; 259 + pll->in.pll_lpf_cap1 = 11; 260 + pll->in.pll_lpf_cap2 = 1; 261 + pll->in.pll_iptat_trim = 7; 262 + pll->in.pll_c3ctrl = 2; 263 + pll->in.pll_r3ctrl = 1; 264 + } 265 + 266 + #define CEIL(x, y) (((x) + ((y) - 1)) / (y)) 267 + 268 + static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll) 269 + { 270 + u32 period, ssc_period; 271 + u32 ref, rem; 272 + u64 step_size; 273 + 274 + DBG("vco=%lld ref=%lld", pll->vco_current_rate, pll->vco_ref_clk_rate); 275 + 276 + ssc_period = pll->in.ssc_freq / 500; 277 + period = (u32)pll->vco_ref_clk_rate / 1000; 278 + ssc_period = CEIL(period, ssc_period); 279 + ssc_period -= 1; 280 + pll->out.ssc_period = ssc_period; 281 + 282 + DBG("ssc freq=%d spread=%d period=%d", pll->in.ssc_freq, 283 + pll->in.ssc_spread, pll->out.ssc_period); 284 + 285 + step_size = (u32)pll->vco_current_rate; 286 + ref = pll->vco_ref_clk_rate; 287 + ref /= 1000; 288 + step_size = div_u64(step_size, ref); 289 + step_size <<= 20; 290 + step_size = div_u64(step_size, 1000); 291 + step_size *= pll->in.ssc_spread; 292 + step_size = div_u64(step_size, 1000); 293 + step_size *= (pll->in.ssc_adj_period + 1); 294 + 295 + rem = 0; 296 + step_size = div_u64_rem(step_size, ssc_period + 1, &rem); 297 + if (rem) 298 + step_size++; 299 + 300 + DBG("step_size=%lld", step_size); 301 + 302 + step_size &= 0x0ffff; /* take lower 16 bits */ 303 + 304 + pll->out.ssc_step_size = step_size; 305 + } 306 + 307 + static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll) 308 + { 309 + struct dsi_pll_input *pin = &pll->in; 310 + struct dsi_pll_output *pout = &pll->out; 311 + u64 multiplier = BIT(20); 312 + u64 dec_start_multiple, dec_start, pll_comp_val; 313 + u32 duration, div_frac_start; 314 + u64 vco_clk_rate = pll->vco_current_rate; 315 + u64 fref = pll->vco_ref_clk_rate; 316 + 317 + DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref); 318 + 319 + dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref); 320 + div_u64_rem(dec_start_multiple, multiplier, &div_frac_start); 321 + 322 + dec_start = div_u64(dec_start_multiple, multiplier); 323 + 324 + pout->dec_start = (u32)dec_start; 325 + pout->div_frac_start = div_frac_start; 326 + 327 + if (pin->plllock_cnt == 0) 328 + duration = 1024; 329 + else if (pin->plllock_cnt == 1) 330 + duration = 256; 331 + else if (pin->plllock_cnt == 2) 332 + duration = 128; 333 + else 334 + duration = 32; 335 + 336 + pll_comp_val = duration * dec_start_multiple; 337 + pll_comp_val = div_u64(pll_comp_val, multiplier); 338 + do_div(pll_comp_val, 10); 339 + 340 + pout->plllock_cmp = (u32)pll_comp_val; 341 + 342 + pout->pll_txclk_en = 1; 343 + pout->cmn_ldo_cntrl = 0x3c; 344 + } 345 + 346 + static u32 pll_14nm_kvco_slop(u32 vrate) 347 + { 348 + u32 slop = 0; 349 + 350 + if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL) 351 + slop = 600; 352 + else if (vrate > 1800000000UL && vrate < 2300000000UL) 353 + slop = 400; 354 + else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE) 355 + slop = 280; 356 + 357 + return slop; 358 + } 359 + 360 + static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll) 361 + { 362 + struct dsi_pll_input *pin = &pll->in; 363 + struct dsi_pll_output *pout = &pll->out; 364 + u64 vco_clk_rate = pll->vco_current_rate; 365 + u64 fref = pll->vco_ref_clk_rate; 366 + u64 data; 367 + u32 cnt; 368 + 369 + data = fref * pin->vco_measure_time; 370 + do_div(data, 1000000); 371 + data &= 0x03ff; /* 10 bits */ 372 + data -= 2; 373 + pout->pll_vco_div_ref = data; 374 + 375 + data = div_u64(vco_clk_rate, 1000000); /* unit is Mhz */ 376 + data *= pin->vco_measure_time; 377 + do_div(data, 10); 378 + pout->pll_vco_count = data; 379 + 380 + data = fref * pin->kvco_measure_time; 381 + do_div(data, 1000000); 382 + data &= 0x03ff; /* 10 bits */ 383 + data -= 1; 384 + pout->pll_kvco_div_ref = data; 385 + 386 + cnt = pll_14nm_kvco_slop(vco_clk_rate); 387 + cnt *= 2; 388 + cnt /= 100; 389 + cnt *= pin->kvco_measure_time; 390 + pout->pll_kvco_count = cnt; 391 + 392 + pout->pll_misc1 = 16; 393 + pout->pll_resetsm_cntrl = 48; 394 + pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3; 395 + pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer; 396 + pout->pll_kvco_code = 0; 397 + } 398 + 399 + static void pll_db_commit_ssc(struct dsi_pll_14nm *pll) 400 + { 401 + void __iomem *base = pll->mmio; 402 + struct dsi_pll_input *pin = &pll->in; 403 + struct dsi_pll_output *pout = &pll->out; 404 + u8 data; 405 + 406 + data = pin->ssc_adj_period; 407 + data &= 0x0ff; 408 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data); 409 + data = (pin->ssc_adj_period >> 8); 410 + data &= 0x03; 411 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data); 412 + 413 + data = pout->ssc_period; 414 + data &= 0x0ff; 415 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data); 416 + data = (pout->ssc_period >> 8); 417 + data &= 0x0ff; 418 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data); 419 + 420 + data = pout->ssc_step_size; 421 + data &= 0x0ff; 422 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data); 423 + data = (pout->ssc_step_size >> 8); 424 + data &= 0x0ff; 425 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data); 426 + 427 + data = (pin->ssc_center & 0x01); 428 + data <<= 1; 429 + data |= 0x01; /* enable */ 430 + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data); 431 + 432 + wmb(); /* make sure register committed */ 433 + } 434 + 435 + static void pll_db_commit_common(struct dsi_pll_14nm *pll, 436 + struct dsi_pll_input *pin, 437 + struct dsi_pll_output *pout) 438 + { 439 + void __iomem *base = pll->mmio; 440 + u8 data; 441 + 442 + /* confgiure the non frequency dependent pll registers */ 443 + data = 0; 444 + pll_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data); 445 + 446 + data = pout->pll_txclk_en; 447 + pll_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, data); 448 + 449 + data = pout->pll_resetsm_cntrl; 450 + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, data); 451 + data = pout->pll_resetsm_cntrl2; 452 + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, data); 453 + data = pout->pll_resetsm_cntrl5; 454 + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, data); 455 + 456 + data = pout->pll_vco_div_ref & 0xff; 457 + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data); 458 + data = (pout->pll_vco_div_ref >> 8) & 0x3; 459 + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data); 460 + 461 + data = pout->pll_kvco_div_ref & 0xff; 462 + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data); 463 + data = (pout->pll_kvco_div_ref >> 8) & 0x3; 464 + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data); 465 + 466 + data = pout->pll_misc1; 467 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, data); 468 + 469 + data = pin->pll_ie_trim; 470 + pll_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, data); 471 + 472 + data = pin->pll_ip_trim; 473 + pll_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, data); 474 + 475 + data = pin->pll_cpmset_cur << 3 | pin->pll_cpcset_cur; 476 + pll_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, data); 477 + 478 + data = pin->pll_icpcset_p << 3 | pin->pll_icpcset_m; 479 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, data); 480 + 481 + data = pin->pll_icpmset_p << 3 | pin->pll_icpcset_m; 482 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, data); 483 + 484 + data = pin->pll_icpmset << 3 | pin->pll_icpcset; 485 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, data); 486 + 487 + data = pin->pll_lpf_cap2 << 4 | pin->pll_lpf_cap1; 488 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, data); 489 + 490 + data = pin->pll_iptat_trim; 491 + pll_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, data); 492 + 493 + data = pin->pll_c3ctrl | pin->pll_r3ctrl << 4; 494 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, data); 495 + } 496 + 497 + static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) 498 + { 499 + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; 500 + 501 + /* de assert pll start and apply pll sw reset */ 502 + 503 + /* stop pll */ 504 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); 505 + 506 + /* pll sw reset */ 507 + pll_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10); 508 + wmb(); /* make sure register committed */ 509 + 510 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0); 511 + wmb(); /* make sure register committed */ 512 + } 513 + 514 + static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, 515 + struct dsi_pll_input *pin, 516 + struct dsi_pll_output *pout) 517 + { 518 + void __iomem *base = pll->mmio; 519 + void __iomem *cmn_base = pll->phy_cmn_mmio; 520 + u8 data; 521 + 522 + DBG("DSI%d PLL", pll->id); 523 + 524 + data = pout->cmn_ldo_cntrl; 525 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); 526 + 527 + pll_db_commit_common(pll, pin, pout); 528 + 529 + pll_14nm_software_reset(pll); 530 + 531 + data = pin->dsiclk_sel; /* set dsiclk_sel = 1 */ 532 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, data); 533 + 534 + data = 0xff; /* data, clk, pll normal operation */ 535 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data); 536 + 537 + /* configure the frequency dependent pll registers */ 538 + data = pout->dec_start; 539 + pll_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data); 540 + 541 + data = pout->div_frac_start & 0xff; 542 + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data); 543 + data = (pout->div_frac_start >> 8) & 0xff; 544 + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data); 545 + data = (pout->div_frac_start >> 16) & 0xf; 546 + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data); 547 + 548 + data = pout->plllock_cmp & 0xff; 549 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data); 550 + 551 + data = (pout->plllock_cmp >> 8) & 0xff; 552 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data); 553 + 554 + data = (pout->plllock_cmp >> 16) & 0x3; 555 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data); 556 + 557 + data = pin->plllock_cnt << 1 | pin->plllock_rng << 3; 558 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data); 559 + 560 + data = pout->pll_vco_count & 0xff; 561 + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data); 562 + data = (pout->pll_vco_count >> 8) & 0xff; 563 + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data); 564 + 565 + data = pout->pll_kvco_count & 0xff; 566 + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data); 567 + data = (pout->pll_kvco_count >> 8) & 0x3; 568 + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data); 569 + 570 + data = (pout->pll_postdiv - 1) << 4 | pin->pll_lpf_res1; 571 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, data); 572 + 573 + if (pin->ssc_en) 574 + pll_db_commit_ssc(pll); 575 + 576 + wmb(); /* make sure register committed */ 577 + } 578 + 579 + /* 580 + * VCO clock Callbacks 581 + */ 582 + static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, 583 + unsigned long parent_rate) 584 + { 585 + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); 586 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 587 + struct dsi_pll_input *pin = &pll_14nm->in; 588 + struct dsi_pll_output *pout = &pll_14nm->out; 589 + 590 + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate, 591 + parent_rate); 592 + 593 + pll_14nm->vco_current_rate = rate; 594 + pll_14nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; 595 + 596 + dsi_pll_14nm_input_init(pll_14nm); 597 + 598 + /* 599 + * This configures the post divider internal to the VCO. It's 600 + * fixed to divide by 1 for now. 601 + * 602 + * tx_band = pll_postdiv. 603 + * 0: divided by 1 604 + * 1: divided by 2 605 + * 2: divided by 4 606 + * 3: divided by 8 607 + */ 608 + pout->pll_postdiv = DSI_PLL_DEFAULT_VCO_POSTDIV; 609 + 610 + pll_14nm_dec_frac_calc(pll_14nm); 611 + 612 + if (pin->ssc_en) 613 + pll_14nm_ssc_calc(pll_14nm); 614 + 615 + pll_14nm_calc_vco_count(pll_14nm); 616 + 617 + /* commit the slave DSI PLL registers if we're master. Note that we 618 + * don't lock the slave PLL. We just ensure that the PLL/PHY registers 619 + * of the master and slave are identical 620 + */ 621 + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { 622 + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; 623 + 624 + pll_db_commit_14nm(pll_14nm_slave, pin, pout); 625 + } 626 + 627 + pll_db_commit_14nm(pll_14nm, pin, pout); 628 + 629 + return 0; 630 + } 631 + 632 + static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, 633 + unsigned long parent_rate) 634 + { 635 + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); 636 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 637 + void __iomem *base = pll_14nm->mmio; 638 + u64 vco_rate, multiplier = BIT(20); 639 + u32 div_frac_start; 640 + u32 dec_start; 641 + u64 ref_clk = parent_rate; 642 + 643 + dec_start = pll_read(base + REG_DSI_14nm_PHY_PLL_DEC_START); 644 + dec_start &= 0x0ff; 645 + 646 + DBG("dec_start = %x", dec_start); 647 + 648 + div_frac_start = (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3) 649 + & 0xf) << 16; 650 + div_frac_start |= (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2) 651 + & 0xff) << 8; 652 + div_frac_start |= pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1) 653 + & 0xff; 654 + 655 + DBG("div_frac_start = %x", div_frac_start); 656 + 657 + vco_rate = ref_clk * dec_start; 658 + 659 + vco_rate += ((ref_clk * div_frac_start) / multiplier); 660 + 661 + /* 662 + * Recalculating the rate from dec_start and frac_start doesn't end up 663 + * the rate we originally set. Convert the freq to KHz, round it up and 664 + * convert it back to MHz. 665 + */ 666 + vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000; 667 + 668 + DBG("returning vco rate = %lu", (unsigned long)vco_rate); 669 + 670 + return (unsigned long)vco_rate; 671 + } 672 + 673 + static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { 674 + .round_rate = msm_dsi_pll_helper_clk_round_rate, 675 + .set_rate = dsi_pll_14nm_vco_set_rate, 676 + .recalc_rate = dsi_pll_14nm_vco_recalc_rate, 677 + .prepare = msm_dsi_pll_helper_clk_prepare, 678 + .unprepare = msm_dsi_pll_helper_clk_unprepare, 679 + }; 680 + 681 + /* 682 + * N1 and N2 post-divider clock callbacks 683 + */ 684 + #define div_mask(width) ((1 << (width)) - 1) 685 + static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, 686 + unsigned long parent_rate) 687 + { 688 + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); 689 + struct dsi_pll_14nm *pll_14nm = postdiv->pll; 690 + void __iomem *base = pll_14nm->phy_cmn_mmio; 691 + u8 shift = postdiv->shift; 692 + u8 width = postdiv->width; 693 + u32 val; 694 + 695 + DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate); 696 + 697 + val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; 698 + val &= div_mask(width); 699 + 700 + return divider_recalc_rate(hw, parent_rate, val, NULL, 701 + postdiv->flags); 702 + } 703 + 704 + static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw, 705 + unsigned long rate, 706 + unsigned long *prate) 707 + { 708 + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); 709 + struct dsi_pll_14nm *pll_14nm = postdiv->pll; 710 + 711 + DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate); 712 + 713 + return divider_round_rate(hw, rate, prate, NULL, 714 + postdiv->width, 715 + postdiv->flags); 716 + } 717 + 718 + static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, 719 + unsigned long parent_rate) 720 + { 721 + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); 722 + struct dsi_pll_14nm *pll_14nm = postdiv->pll; 723 + void __iomem *base = pll_14nm->phy_cmn_mmio; 724 + spinlock_t *lock = &pll_14nm->postdiv_lock; 725 + u8 shift = postdiv->shift; 726 + u8 width = postdiv->width; 727 + unsigned int value; 728 + unsigned long flags = 0; 729 + u32 val; 730 + 731 + DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate, 732 + parent_rate); 733 + 734 + value = divider_get_val(rate, parent_rate, NULL, postdiv->width, 735 + postdiv->flags); 736 + 737 + spin_lock_irqsave(lock, flags); 738 + 739 + val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); 740 + val &= ~(div_mask(width) << shift); 741 + 742 + val |= value << shift; 743 + pll_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); 744 + 745 + /* If we're master in dual DSI mode, then the slave PLL's post-dividers 746 + * follow the master's post dividers 747 + */ 748 + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { 749 + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; 750 + void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; 751 + 752 + pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); 753 + } 754 + 755 + spin_unlock_irqrestore(lock, flags); 756 + 757 + return 0; 758 + } 759 + 760 + static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { 761 + .recalc_rate = dsi_pll_14nm_postdiv_recalc_rate, 762 + .round_rate = dsi_pll_14nm_postdiv_round_rate, 763 + .set_rate = dsi_pll_14nm_postdiv_set_rate, 764 + }; 765 + 766 + /* 767 + * PLL Callbacks 768 + */ 769 + 770 + static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) 771 + { 772 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 773 + void __iomem *base = pll_14nm->mmio; 774 + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; 775 + bool locked; 776 + 777 + DBG(""); 778 + 779 + pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); 780 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); 781 + 782 + locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, 783 + POLL_TIMEOUT_US); 784 + 785 + if (unlikely(!locked)) 786 + dev_err(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); 787 + else 788 + DBG("DSI PLL lock success"); 789 + 790 + return locked ? 0 : -EINVAL; 791 + } 792 + 793 + static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll) 794 + { 795 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 796 + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; 797 + 798 + DBG(""); 799 + 800 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); 801 + } 802 + 803 + static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll) 804 + { 805 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 806 + struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; 807 + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; 808 + u32 data; 809 + 810 + data = pll_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); 811 + 812 + cached_state->n1postdiv = data & 0xf; 813 + cached_state->n2postdiv = (data >> 4) & 0xf; 814 + 815 + DBG("DSI%d PLL save state %x %x", pll_14nm->id, 816 + cached_state->n1postdiv, cached_state->n2postdiv); 817 + 818 + cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); 819 + } 820 + 821 + static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll) 822 + { 823 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 824 + struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; 825 + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; 826 + u32 data; 827 + int ret; 828 + 829 + ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw, 830 + cached_state->vco_rate, 0); 831 + if (ret) { 832 + dev_err(&pll_14nm->pdev->dev, 833 + "restore vco rate failed. ret=%d\n", ret); 834 + return ret; 835 + } 836 + 837 + data = cached_state->n1postdiv | (cached_state->n2postdiv << 4); 838 + 839 + DBG("DSI%d PLL restore state %x %x", pll_14nm->id, 840 + cached_state->n1postdiv, cached_state->n2postdiv); 841 + 842 + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); 843 + 844 + /* also restore post-dividers for slave DSI PLL */ 845 + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { 846 + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; 847 + void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; 848 + 849 + pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); 850 + } 851 + 852 + return 0; 853 + } 854 + 855 + static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll, 856 + enum msm_dsi_phy_usecase uc) 857 + { 858 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 859 + void __iomem *base = pll_14nm->mmio; 860 + u32 clkbuflr_en, bandgap = 0; 861 + 862 + switch (uc) { 863 + case MSM_DSI_PHY_STANDALONE: 864 + clkbuflr_en = 0x1; 865 + break; 866 + case MSM_DSI_PHY_MASTER: 867 + clkbuflr_en = 0x3; 868 + pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX]; 869 + break; 870 + case MSM_DSI_PHY_SLAVE: 871 + clkbuflr_en = 0x0; 872 + bandgap = 0x3; 873 + break; 874 + default: 875 + return -EINVAL; 876 + } 877 + 878 + pll_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en); 879 + if (bandgap) 880 + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap); 881 + 882 + pll_14nm->uc = uc; 883 + 884 + return 0; 885 + } 886 + 887 + static int dsi_pll_14nm_get_provider(struct msm_dsi_pll *pll, 888 + struct clk **byte_clk_provider, 889 + struct clk **pixel_clk_provider) 890 + { 891 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 892 + struct clk_hw_onecell_data *hw_data = pll_14nm->hw_data; 893 + 894 + if (byte_clk_provider) 895 + *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; 896 + if (pixel_clk_provider) 897 + *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; 898 + 899 + return 0; 900 + } 901 + 902 + static void dsi_pll_14nm_destroy(struct msm_dsi_pll *pll) 903 + { 904 + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); 905 + struct platform_device *pdev = pll_14nm->pdev; 906 + int num_hws = pll_14nm->num_hws; 907 + 908 + of_clk_del_provider(pdev->dev.of_node); 909 + 910 + while (num_hws--) 911 + clk_hw_unregister(pll_14nm->hws[num_hws]); 912 + } 913 + 914 + static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, 915 + const char *name, 916 + const char *parent_name, 917 + unsigned long flags, 918 + u8 shift) 919 + { 920 + struct dsi_pll_14nm_postdiv *pll_postdiv; 921 + struct device *dev = &pll_14nm->pdev->dev; 922 + struct clk_init_data postdiv_init = { 923 + .parent_names = (const char *[]) { parent_name }, 924 + .num_parents = 1, 925 + .name = name, 926 + .flags = flags, 927 + .ops = &clk_ops_dsi_pll_14nm_postdiv, 928 + }; 929 + int ret; 930 + 931 + pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL); 932 + if (!pll_postdiv) 933 + return ERR_PTR(-ENOMEM); 934 + 935 + pll_postdiv->pll = pll_14nm; 936 + pll_postdiv->shift = shift; 937 + /* both N1 and N2 postdividers are 4 bits wide */ 938 + pll_postdiv->width = 4; 939 + /* range of each divider is from 1 to 15 */ 940 + pll_postdiv->flags = CLK_DIVIDER_ONE_BASED; 941 + pll_postdiv->hw.init = &postdiv_init; 942 + 943 + ret = clk_hw_register(dev, &pll_postdiv->hw); 944 + if (ret) 945 + return ERR_PTR(ret); 946 + 947 + return &pll_postdiv->hw; 948 + } 949 + 950 + static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm) 951 + { 952 + char clk_name[32], parent[32], vco_name[32]; 953 + struct clk_init_data vco_init = { 954 + .parent_names = (const char *[]){ "xo" }, 955 + .num_parents = 1, 956 + .name = vco_name, 957 + .flags = CLK_IGNORE_UNUSED, 958 + .ops = &clk_ops_dsi_pll_14nm_vco, 959 + }; 960 + struct device *dev = &pll_14nm->pdev->dev; 961 + struct clk_hw **hws = pll_14nm->hws; 962 + struct clk_hw_onecell_data *hw_data; 963 + struct clk_hw *hw; 964 + int num = 0; 965 + int ret; 966 + 967 + DBG("DSI%d", pll_14nm->id); 968 + 969 + hw_data = devm_kzalloc(dev, sizeof(*hw_data) + 970 + NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), 971 + GFP_KERNEL); 972 + if (!hw_data) 973 + return -ENOMEM; 974 + 975 + snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id); 976 + pll_14nm->base.clk_hw.init = &vco_init; 977 + 978 + ret = clk_hw_register(dev, &pll_14nm->base.clk_hw); 979 + if (ret) 980 + return ret; 981 + 982 + hws[num++] = &pll_14nm->base.clk_hw; 983 + 984 + snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); 985 + snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id); 986 + 987 + /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ 988 + hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 989 + CLK_SET_RATE_PARENT, 0); 990 + if (IS_ERR(hw)) 991 + return PTR_ERR(hw); 992 + 993 + hws[num++] = hw; 994 + 995 + snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id); 996 + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); 997 + 998 + /* DSI Byte clock = VCO_CLK / N1 / 8 */ 999 + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 1000 + CLK_SET_RATE_PARENT, 1, 8); 1001 + if (IS_ERR(hw)) 1002 + return PTR_ERR(hw); 1003 + 1004 + hws[num++] = hw; 1005 + hw_data->hws[DSI_BYTE_PLL_CLK] = hw; 1006 + 1007 + snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); 1008 + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); 1009 + 1010 + /* 1011 + * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider 1012 + * on the way. Don't let it set parent. 1013 + */ 1014 + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); 1015 + if (IS_ERR(hw)) 1016 + return PTR_ERR(hw); 1017 + 1018 + hws[num++] = hw; 1019 + 1020 + snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id); 1021 + snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); 1022 + 1023 + /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 1024 + * This is the output of N2 post-divider, bits 4-7 in 1025 + * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent. 1026 + */ 1027 + hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4); 1028 + if (IS_ERR(hw)) 1029 + return PTR_ERR(hw); 1030 + 1031 + hws[num++] = hw; 1032 + hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; 1033 + 1034 + pll_14nm->num_hws = num; 1035 + 1036 + hw_data->num = NUM_PROVIDED_CLKS; 1037 + pll_14nm->hw_data = hw_data; 1038 + 1039 + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 1040 + pll_14nm->hw_data); 1041 + if (ret) { 1042 + dev_err(dev, "failed to register clk provider: %d\n", ret); 1043 + return ret; 1044 + } 1045 + 1046 + return 0; 1047 + } 1048 + 1049 + struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) 1050 + { 1051 + struct dsi_pll_14nm *pll_14nm; 1052 + struct msm_dsi_pll *pll; 1053 + int ret; 1054 + 1055 + if (!pdev) 1056 + return ERR_PTR(-ENODEV); 1057 + 1058 + pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL); 1059 + if (!pll_14nm) 1060 + return ERR_PTR(-ENOMEM); 1061 + 1062 + DBG("PLL%d", id); 1063 + 1064 + pll_14nm->pdev = pdev; 1065 + pll_14nm->id = id; 1066 + pll_14nm_list[id] = pll_14nm; 1067 + 1068 + pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); 1069 + if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) { 1070 + dev_err(&pdev->dev, "failed to map CMN PHY base\n"); 1071 + return ERR_PTR(-ENOMEM); 1072 + } 1073 + 1074 + pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); 1075 + if (IS_ERR_OR_NULL(pll_14nm->mmio)) { 1076 + dev_err(&pdev->dev, "failed to map PLL base\n"); 1077 + return ERR_PTR(-ENOMEM); 1078 + } 1079 + 1080 + spin_lock_init(&pll_14nm->postdiv_lock); 1081 + 1082 + pll = &pll_14nm->base; 1083 + pll->min_rate = VCO_MIN_RATE; 1084 + pll->max_rate = VCO_MAX_RATE; 1085 + pll->get_provider = dsi_pll_14nm_get_provider; 1086 + pll->destroy = dsi_pll_14nm_destroy; 1087 + pll->disable_seq = dsi_pll_14nm_disable_seq; 1088 + pll->save_state = dsi_pll_14nm_save_state; 1089 + pll->restore_state = dsi_pll_14nm_restore_state; 1090 + pll->set_usecase = dsi_pll_14nm_set_usecase; 1091 + 1092 + pll_14nm->vco_delay = 1; 1093 + 1094 + pll->en_seq_cnt = 1; 1095 + pll->enable_seqs[0] = dsi_pll_14nm_enable_seq; 1096 + 1097 + ret = pll_14nm_register(pll_14nm); 1098 + if (ret) { 1099 + dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); 1100 + return ERR_PTR(ret); 1101 + } 1102 + 1103 + return pll; 1104 + }
+12 -16
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
··· 260 260 struct drm_encoder *encoder; 261 261 struct drm_connector *connector; 262 262 struct device_node *panel_node; 263 - struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM]; 264 - int i, dsi_id; 263 + int dsi_id; 265 264 int ret; 266 265 267 266 switch (intf_type) { ··· 321 322 if (!priv->dsi[dsi_id]) 322 323 break; 323 324 324 - for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { 325 - dsi_encs[i] = mdp4_dsi_encoder_init(dev); 326 - if (IS_ERR(dsi_encs[i])) { 327 - ret = PTR_ERR(dsi_encs[i]); 328 - dev_err(dev->dev, 329 - "failed to construct DSI encoder: %d\n", 330 - ret); 331 - return ret; 332 - } 333 - 334 - /* TODO: Add DMA_S later? */ 335 - dsi_encs[i]->possible_crtcs = 1 << DMA_P; 336 - priv->encoders[priv->num_encoders++] = dsi_encs[i]; 325 + encoder = mdp4_dsi_encoder_init(dev); 326 + if (IS_ERR(encoder)) { 327 + ret = PTR_ERR(encoder); 328 + dev_err(dev->dev, 329 + "failed to construct DSI encoder: %d\n", ret); 330 + return ret; 337 331 } 338 332 339 - ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs); 333 + /* TODO: Add DMA_S later? */ 334 + encoder->possible_crtcs = 1 << DMA_P; 335 + priv->encoders[priv->num_encoders++] = encoder; 336 + 337 + ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder); 340 338 if (ret) { 341 339 dev_err(dev->dev, "failed to initialize DSI: %d\n", 342 340 ret);
+24 -22
drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
··· 8 8 git clone https://github.com/freedreno/envytools.git 9 9 10 10 The rules-ng-ng source files this header was generated from are: 11 - - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) 12 - - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-02-10 17:07:21) 13 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) 14 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) 15 - - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36965 bytes, from 2016-11-26 23:01:08) 16 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 27887 bytes, from 2015-10-22 16:34:52) 17 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 602 bytes, from 2015-10-22 16:35:02) 18 - - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) 19 - - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2015-05-20 20:03:07) 20 - - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 41472 bytes, from 2016-01-22 18:18:18) 21 - - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 10416 bytes, from 2015-05-20 20:03:14) 11 + - /local/mnt/workspace/source_trees/envytools/rnndb/../rnndb/mdp/mdp5.xml ( 37411 bytes, from 2017-01-11 05:19:19) 12 + - /local/mnt/workspace/source_trees/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2016-05-09 06:32:54) 13 + - /local/mnt/workspace/source_trees/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2016-01-07 08:45:55) 22 14 23 - Copyright (C) 2013-2016 by the following authors: 15 + Copyright (C) 2013-2017 by the following authors: 24 16 - Rob Clark <robdclark@gmail.com> (robclark) 25 17 - Ilia Mirkin <imirkin@alum.mit.edu> (imirkin) 26 18 ··· 57 65 }; 58 66 59 67 enum mdp5_pipe { 60 - SSPP_VIG0 = 0, 61 - SSPP_VIG1 = 1, 62 - SSPP_VIG2 = 2, 63 - SSPP_RGB0 = 3, 64 - SSPP_RGB1 = 4, 65 - SSPP_RGB2 = 5, 66 - SSPP_DMA0 = 6, 67 - SSPP_DMA1 = 7, 68 - SSPP_VIG3 = 8, 69 - SSPP_RGB3 = 9, 68 + SSPP_NONE = 0, 69 + SSPP_VIG0 = 1, 70 + SSPP_VIG1 = 2, 71 + SSPP_VIG2 = 3, 72 + SSPP_RGB0 = 4, 73 + SSPP_RGB1 = 5, 74 + SSPP_RGB2 = 6, 75 + SSPP_DMA0 = 7, 76 + SSPP_DMA1 = 8, 77 + SSPP_VIG3 = 9, 78 + SSPP_RGB3 = 10, 79 + SSPP_CURSOR0 = 11, 80 + SSPP_CURSOR1 = 12, 70 81 }; 71 82 72 83 enum mdp5_ctl_mode { ··· 527 532 static inline uint32_t __offset_PIPE(enum mdp5_pipe idx) 528 533 { 529 534 switch (idx) { 535 + case SSPP_NONE: return (INVALID_IDX(idx)); 530 536 case SSPP_VIG0: return (mdp5_cfg->pipe_vig.base[0]); 531 537 case SSPP_VIG1: return (mdp5_cfg->pipe_vig.base[1]); 532 538 case SSPP_VIG2: return (mdp5_cfg->pipe_vig.base[2]); ··· 538 542 case SSPP_DMA1: return (mdp5_cfg->pipe_dma.base[1]); 539 543 case SSPP_VIG3: return (mdp5_cfg->pipe_vig.base[3]); 540 544 case SSPP_RGB3: return (mdp5_cfg->pipe_rgb.base[3]); 545 + case SSPP_CURSOR0: return (mdp5_cfg->pipe_cursor.base[0]); 546 + case SSPP_CURSOR1: return (mdp5_cfg->pipe_cursor.base[1]); 541 547 default: return INVALID_IDX(idx); 542 548 } 543 549 } ··· 1071 1073 #define MDP5_LM_BLEND_COLOR_OUT_STAGE1_FG_ALPHA 0x00000004 1072 1074 #define MDP5_LM_BLEND_COLOR_OUT_STAGE2_FG_ALPHA 0x00000008 1073 1075 #define MDP5_LM_BLEND_COLOR_OUT_STAGE3_FG_ALPHA 0x00000010 1076 + #define MDP5_LM_BLEND_COLOR_OUT_STAGE4_FG_ALPHA 0x00000020 1077 + #define MDP5_LM_BLEND_COLOR_OUT_STAGE5_FG_ALPHA 0x00000040 1078 + #define MDP5_LM_BLEND_COLOR_OUT_STAGE6_FG_ALPHA 0x00000080 1079 + #define MDP5_LM_BLEND_COLOR_OUT_SPLIT_LEFT_RIGHT 0x80000000 1074 1080 1075 1081 static inline uint32_t REG_MDP5_LM_OUT_SIZE(uint32_t i0) { return 0x00000004 + __offset_LM(i0); } 1076 1082 #define MDP5_LM_OUT_SIZE_HEIGHT__MASK 0xffff0000
+10
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c
··· 421 421 MDP_PIPE_CAP_SW_PIX_EXT | 422 422 0, 423 423 }, 424 + .pipe_cursor = { 425 + .count = 2, 426 + .base = { 0x34000, 0x36000 }, 427 + .caps = MDP_PIPE_CAP_HFLIP | 428 + MDP_PIPE_CAP_VFLIP | 429 + MDP_PIPE_CAP_SW_PIX_EXT | 430 + MDP_PIPE_CAP_CURSOR | 431 + 0, 432 + }, 433 + 424 434 .lm = { 425 435 .count = 6, 426 436 .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
+2 -1
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h
··· 32 32 typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS); 33 33 34 34 #define MDP5_SUB_BLOCK_DEFINITION \ 35 - int count; \ 35 + unsigned int count; \ 36 36 uint32_t base[MAX_BASES] 37 37 38 38 struct mdp5_sub_block { ··· 85 85 struct mdp5_pipe_block pipe_vig; 86 86 struct mdp5_pipe_block pipe_rgb; 87 87 struct mdp5_pipe_block pipe_dma; 88 + struct mdp5_pipe_block pipe_cursor; 88 89 struct mdp5_lm_block lm; 89 90 struct mdp5_sub_block dspp; 90 91 struct mdp5_sub_block ad;
+13 -122
drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
··· 16 16 #include "drm_crtc.h" 17 17 #include "drm_crtc_helper.h" 18 18 19 - struct mdp5_cmd_encoder { 20 - struct drm_encoder base; 21 - struct mdp5_interface intf; 22 - bool enabled; 23 - uint32_t bsc; 24 - 25 - struct mdp5_ctl *ctl; 26 - }; 27 - #define to_mdp5_cmd_encoder(x) container_of(x, struct mdp5_cmd_encoder, base) 28 - 29 19 static struct mdp5_kms *get_kms(struct drm_encoder *encoder) 30 20 { 31 21 struct msm_drm_private *priv = encoder->dev->dev_private; ··· 26 36 #include <mach/board.h> 27 37 #include <linux/msm-bus.h> 28 38 #include <linux/msm-bus-board.h> 29 - #define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \ 30 - { \ 31 - .src = MSM_BUS_MASTER_MDP_PORT0, \ 32 - .dst = MSM_BUS_SLAVE_EBI_CH0, \ 33 - .ab = (ab_val), \ 34 - .ib = (ib_val), \ 35 - } 36 39 37 - static struct msm_bus_vectors mdp_bus_vectors[] = { 38 - MDP_BUS_VECTOR_ENTRY(0, 0), 39 - MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000), 40 - }; 41 - static struct msm_bus_paths mdp_bus_usecases[] = { { 42 - .num_paths = 1, 43 - .vectors = &mdp_bus_vectors[0], 44 - }, { 45 - .num_paths = 1, 46 - .vectors = &mdp_bus_vectors[1], 47 - } }; 48 - static struct msm_bus_scale_pdata mdp_bus_scale_table = { 49 - .usecase = mdp_bus_usecases, 50 - .num_usecases = ARRAY_SIZE(mdp_bus_usecases), 51 - .name = "mdss_mdp", 52 - }; 53 - 54 - static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) 55 - { 56 - mdp5_cmd_enc->bsc = msm_bus_scale_register_client( 57 - &mdp_bus_scale_table); 58 - DBG("bus scale client: %08x", mdp5_cmd_enc->bsc); 59 - } 60 - 61 - static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) 62 - { 63 - if (mdp5_cmd_enc->bsc) { 64 - msm_bus_scale_unregister_client(mdp5_cmd_enc->bsc); 65 - mdp5_cmd_enc->bsc = 0; 66 - } 67 - } 68 - 69 - static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) 40 + static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx) 70 41 { 71 42 if (mdp5_cmd_enc->bsc) { 72 43 DBG("set bus scaling: %d", idx); ··· 40 89 } 41 90 } 42 91 #else 43 - static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) {} 44 - static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) {} 45 - static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) {} 92 + static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx) {} 46 93 #endif 47 94 48 95 #define VSYNC_CLK_RATE 19200000 49 96 static int pingpong_tearcheck_setup(struct drm_encoder *encoder, 50 - struct drm_display_mode *mode) 97 + struct drm_display_mode *mode) 51 98 { 52 99 struct mdp5_kms *mdp5_kms = get_kms(encoder); 53 100 struct device *dev = encoder->dev->dev; ··· 125 176 clk_disable_unprepare(mdp5_kms->vsync_clk); 126 177 } 127 178 128 - static void mdp5_cmd_encoder_destroy(struct drm_encoder *encoder) 179 + void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, 180 + struct drm_display_mode *mode, 181 + struct drm_display_mode *adjusted_mode) 129 182 { 130 - struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 131 - bs_fini(mdp5_cmd_enc); 132 - drm_encoder_cleanup(encoder); 133 - kfree(mdp5_cmd_enc); 134 - } 135 - 136 - static const struct drm_encoder_funcs mdp5_cmd_encoder_funcs = { 137 - .destroy = mdp5_cmd_encoder_destroy, 138 - }; 139 - 140 - static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, 141 - struct drm_display_mode *mode, 142 - struct drm_display_mode *adjusted_mode) 143 - { 144 - struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 183 + struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); 145 184 146 185 mode = adjusted_mode; 147 186 ··· 146 209 mdp5_cmd_enc->ctl); 147 210 } 148 211 149 - static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) 212 + void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) 150 213 { 151 - struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 214 + struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); 152 215 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; 153 216 struct mdp5_interface *intf = &mdp5_cmd_enc->intf; 154 217 ··· 165 228 mdp5_cmd_enc->enabled = false; 166 229 } 167 230 168 - static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) 231 + void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) 169 232 { 170 - struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 233 + struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); 171 234 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; 172 235 struct mdp5_interface *intf = &mdp5_cmd_enc->intf; 173 236 ··· 185 248 mdp5_cmd_enc->enabled = true; 186 249 } 187 250 188 - static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = { 189 - .mode_set = mdp5_cmd_encoder_mode_set, 190 - .disable = mdp5_cmd_encoder_disable, 191 - .enable = mdp5_cmd_encoder_enable, 192 - }; 193 - 194 251 int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, 195 - struct drm_encoder *slave_encoder) 252 + struct drm_encoder *slave_encoder) 196 253 { 197 - struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 254 + struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); 198 255 struct mdp5_kms *mdp5_kms; 199 256 int intf_num; 200 257 u32 data = 0; ··· 222 291 mdp5_disable(mdp5_kms); 223 292 224 293 return 0; 225 - } 226 - 227 - /* initialize command mode encoder */ 228 - struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, 229 - struct mdp5_interface *intf, struct mdp5_ctl *ctl) 230 - { 231 - struct drm_encoder *encoder = NULL; 232 - struct mdp5_cmd_encoder *mdp5_cmd_enc; 233 - int ret; 234 - 235 - if (WARN_ON((intf->type != INTF_DSI) && 236 - (intf->mode != MDP5_INTF_DSI_MODE_COMMAND))) { 237 - ret = -EINVAL; 238 - goto fail; 239 - } 240 - 241 - mdp5_cmd_enc = kzalloc(sizeof(*mdp5_cmd_enc), GFP_KERNEL); 242 - if (!mdp5_cmd_enc) { 243 - ret = -ENOMEM; 244 - goto fail; 245 - } 246 - 247 - memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf)); 248 - encoder = &mdp5_cmd_enc->base; 249 - mdp5_cmd_enc->ctl = ctl; 250 - 251 - drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs, 252 - DRM_MODE_ENCODER_DSI, NULL); 253 - 254 - drm_encoder_helper_add(encoder, &mdp5_cmd_encoder_helper_funcs); 255 - 256 - bs_init(mdp5_cmd_enc); 257 - 258 - return encoder; 259 - 260 - fail: 261 - if (encoder) 262 - mdp5_cmd_encoder_destroy(encoder); 263 - 264 - return ERR_PTR(ret); 265 294 }
+68 -5
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
··· 177 177 kfree(mdp5_crtc); 178 178 } 179 179 180 + static inline u32 mdp5_lm_use_fg_alpha_mask(enum mdp_mixer_stage_id stage) 181 + { 182 + switch (stage) { 183 + case STAGE0: return MDP5_LM_BLEND_COLOR_OUT_STAGE0_FG_ALPHA; 184 + case STAGE1: return MDP5_LM_BLEND_COLOR_OUT_STAGE1_FG_ALPHA; 185 + case STAGE2: return MDP5_LM_BLEND_COLOR_OUT_STAGE2_FG_ALPHA; 186 + case STAGE3: return MDP5_LM_BLEND_COLOR_OUT_STAGE3_FG_ALPHA; 187 + case STAGE4: return MDP5_LM_BLEND_COLOR_OUT_STAGE4_FG_ALPHA; 188 + case STAGE5: return MDP5_LM_BLEND_COLOR_OUT_STAGE5_FG_ALPHA; 189 + case STAGE6: return MDP5_LM_BLEND_COLOR_OUT_STAGE6_FG_ALPHA; 190 + default: 191 + return 0; 192 + } 193 + } 194 + 180 195 /* 181 196 * blend_setup() - blend all the planes of a CRTC 182 197 * ··· 210 195 uint32_t lm = mdp5_crtc->lm; 211 196 uint32_t blend_op, fg_alpha, bg_alpha, ctl_blend_flags = 0; 212 197 unsigned long flags; 213 - uint8_t stage[STAGE_MAX + 1]; 198 + enum mdp5_pipe stage[STAGE_MAX + 1] = { SSPP_NONE }; 214 199 int i, plane_cnt = 0; 200 + bool bg_alpha_enabled = false; 201 + u32 mixer_op_mode = 0; 215 202 #define blender(stage) ((stage) - STAGE0) 216 203 217 204 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); ··· 235 218 if (!pstates[STAGE_BASE]) { 236 219 ctl_blend_flags |= MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT; 237 220 DBG("Border Color is enabled"); 221 + } else if (plane_cnt) { 222 + format = to_mdp_format(msm_framebuffer_format(pstates[STAGE_BASE]->base.fb)); 223 + 224 + if (format->alpha_enable) 225 + bg_alpha_enabled = true; 238 226 } 239 227 240 228 /* The reset for blending */ ··· 254 232 MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST); 255 233 fg_alpha = pstates[i]->alpha; 256 234 bg_alpha = 0xFF - pstates[i]->alpha; 235 + 236 + if (!format->alpha_enable && bg_alpha_enabled) 237 + mixer_op_mode = 0; 238 + else 239 + mixer_op_mode |= mdp5_lm_use_fg_alpha_mask(i); 240 + 257 241 DBG("Stage %d fg_alpha %x bg_alpha %x", i, fg_alpha, bg_alpha); 258 242 259 243 if (format->alpha_enable && pstates[i]->premultiplied) { ··· 295 267 mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(lm, 296 268 blender(i)), bg_alpha); 297 269 } 270 + 271 + mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm), mixer_op_mode); 298 272 299 273 mdp5_ctl_blend(mdp5_crtc->ctl, stage, plane_cnt, ctl_blend_flags); 300 274 ··· 400 370 struct plane_state pstates[STAGE_MAX + 1]; 401 371 const struct mdp5_cfg_hw *hw_cfg; 402 372 const struct drm_plane_state *pstate; 373 + bool cursor_plane = false; 403 374 int cnt = 0, base = 0, i; 404 375 405 376 DBG("%s: check", crtc->name); ··· 410 379 pstates[cnt].state = to_mdp5_plane_state(pstate); 411 380 412 381 cnt++; 382 + 383 + if (plane->type == DRM_PLANE_TYPE_CURSOR) 384 + cursor_plane = true; 413 385 } 414 386 415 387 /* assign a stage based on sorted zpos property */ ··· 423 389 */ 424 390 if ((cnt > 0) && !is_fullscreen(state, &pstates[0].state->base)) 425 391 base++; 392 + 393 + /* trigger a warning if cursor isn't the highest zorder */ 394 + WARN_ON(cursor_plane && 395 + (pstates[cnt - 1].plane->type != DRM_PLANE_TYPE_CURSOR)); 426 396 427 397 /* verify that there are not too many planes attached to crtc 428 398 * and that we don't have conflicting mixer stages: ··· 439 401 } 440 402 441 403 for (i = 0; i < cnt; i++) { 442 - pstates[i].state->stage = STAGE_BASE + i + base; 404 + if (cursor_plane && (i == (cnt - 1))) 405 + pstates[i].state->stage = hw_cfg->lm.nb_stages; 406 + else 407 + pstates[i].state->stage = STAGE_BASE + i + base; 443 408 DBG("%s: assign pipe %s on stage=%d", crtc->name, 444 409 pstates[i].plane->name, 445 410 pstates[i].state->stage); ··· 653 612 .cursor_move = mdp5_crtc_cursor_move, 654 613 }; 655 614 615 + static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { 616 + .set_config = drm_atomic_helper_set_config, 617 + .destroy = mdp5_crtc_destroy, 618 + .page_flip = drm_atomic_helper_page_flip, 619 + .set_property = drm_atomic_helper_crtc_set_property, 620 + .reset = drm_atomic_helper_crtc_reset, 621 + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 622 + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 623 + }; 624 + 656 625 static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { 657 626 .mode_set_nofb = mdp5_crtc_mode_set_nofb, 658 627 .disable = mdp5_crtc_disable, ··· 778 727 mdp5_ctl_set_pipeline(ctl, intf, lm); 779 728 } 780 729 730 + struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc) 731 + { 732 + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); 733 + 734 + return mdp5_crtc->ctl; 735 + } 736 + 781 737 int mdp5_crtc_get_lm(struct drm_crtc *crtc) 782 738 { 783 739 struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); ··· 803 745 804 746 /* initialize crtc */ 805 747 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, 806 - struct drm_plane *plane, int id) 748 + struct drm_plane *plane, 749 + struct drm_plane *cursor_plane, int id) 807 750 { 808 751 struct drm_crtc *crtc = NULL; 809 752 struct mdp5_crtc *mdp5_crtc; ··· 825 766 mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq; 826 767 mdp5_crtc->err.irq = mdp5_crtc_err_irq; 827 768 828 - drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs, 829 - NULL); 769 + if (cursor_plane) 770 + drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane, 771 + &mdp5_crtc_no_lm_cursor_funcs, NULL); 772 + else 773 + drm_crtc_init_with_planes(dev, crtc, plane, NULL, 774 + &mdp5_crtc_funcs, NULL); 830 775 831 776 drm_flip_work_init(&mdp5_crtc->unref_cursor_work, 832 777 "unref cursor", unref_cursor_worker);
+10 -4
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c
··· 326 326 case SSPP_DMA1: return MDP5_CTL_LAYER_REG_DMA1(stage); 327 327 case SSPP_VIG3: return MDP5_CTL_LAYER_REG_VIG3(stage); 328 328 case SSPP_RGB3: return MDP5_CTL_LAYER_REG_RGB3(stage); 329 + case SSPP_CURSOR0: 330 + case SSPP_CURSOR1: 329 331 default: return 0; 330 332 } 331 333 } ··· 335 333 static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe, 336 334 enum mdp_mixer_stage_id stage) 337 335 { 338 - if (stage < STAGE6) 336 + if (stage < STAGE6 && (pipe != SSPP_CURSOR0 && pipe != SSPP_CURSOR1)) 339 337 return 0; 340 338 341 339 switch (pipe) { ··· 349 347 case SSPP_DMA1: return MDP5_CTL_LAYER_EXT_REG_DMA1_BIT3; 350 348 case SSPP_VIG3: return MDP5_CTL_LAYER_EXT_REG_VIG3_BIT3; 351 349 case SSPP_RGB3: return MDP5_CTL_LAYER_EXT_REG_RGB3_BIT3; 350 + case SSPP_CURSOR0: return MDP5_CTL_LAYER_EXT_REG_CURSOR0(stage); 351 + case SSPP_CURSOR1: return MDP5_CTL_LAYER_EXT_REG_CURSOR1(stage); 352 352 default: return 0; 353 353 } 354 354 } 355 355 356 - int mdp5_ctl_blend(struct mdp5_ctl *ctl, u8 *stage, u32 stage_cnt, 357 - u32 ctl_blend_op_flags) 356 + int mdp5_ctl_blend(struct mdp5_ctl *ctl, enum mdp5_pipe *stage, u32 stage_cnt, 357 + u32 ctl_blend_op_flags) 358 358 { 359 359 unsigned long flags; 360 360 u32 blend_cfg = 0, blend_ext_cfg = 0; ··· 369 365 start_stage = STAGE_BASE; 370 366 } 371 367 372 - for (i = start_stage; i < start_stage + stage_cnt; i++) { 368 + for (i = start_stage; stage_cnt && i <= STAGE_MAX; i++) { 373 369 blend_cfg |= mdp_ctl_blend_mask(stage[i], i); 374 370 blend_ext_cfg |= mdp_ctl_blend_ext_mask(stage[i], i); 375 371 } ··· 426 422 case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1; 427 423 case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3; 428 424 case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3; 425 + case SSPP_CURSOR0: return MDP5_CTL_FLUSH_CURSOR_0; 426 + case SSPP_CURSOR1: return MDP5_CTL_FLUSH_CURSOR_1; 429 427 default: return 0; 430 428 } 431 429 }
+2 -2
drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h
··· 56 56 * (call mdp5_ctl_commit() with mdp_ctl_flush_mask_ctl() mask) 57 57 */ 58 58 #define MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT BIT(0) 59 - int mdp5_ctl_blend(struct mdp5_ctl *ctl, u8 *stage, u32 stage_cnt, 60 - u32 ctl_blend_op_flags); 59 + int mdp5_ctl_blend(struct mdp5_ctl *ctl, enum mdp5_pipe *stage, u32 stage_cnt, 60 + u32 ctl_blend_op_flags); 61 61 62 62 /** 63 63 * mdp_ctl_flush_mask...() - Register FLUSH masks
+59 -18
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
··· 21 21 #include "drm_crtc.h" 22 22 #include "drm_crtc_helper.h" 23 23 24 - struct mdp5_encoder { 25 - struct drm_encoder base; 26 - struct mdp5_interface intf; 27 - spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ 28 - bool enabled; 29 - uint32_t bsc; 30 - 31 - struct mdp5_ctl *ctl; 32 - }; 33 - #define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base) 34 - 35 24 static struct mdp5_kms *get_kms(struct drm_encoder *encoder) 36 25 { 37 26 struct msm_drm_private *priv = encoder->dev->dev_private; ··· 101 112 .destroy = mdp5_encoder_destroy, 102 113 }; 103 114 104 - static void mdp5_encoder_mode_set(struct drm_encoder *encoder, 105 - struct drm_display_mode *mode, 106 - struct drm_display_mode *adjusted_mode) 115 + static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, 116 + struct drm_display_mode *mode, 117 + struct drm_display_mode *adjusted_mode) 107 118 { 108 119 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 109 120 struct mdp5_kms *mdp5_kms = get_kms(encoder); ··· 210 221 mdp5_encoder->ctl); 211 222 } 212 223 213 - static void mdp5_encoder_disable(struct drm_encoder *encoder) 224 + static void mdp5_vid_encoder_disable(struct drm_encoder *encoder) 214 225 { 215 226 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 216 227 struct mdp5_kms *mdp5_kms = get_kms(encoder); ··· 245 256 mdp5_encoder->enabled = false; 246 257 } 247 258 248 - static void mdp5_encoder_enable(struct drm_encoder *encoder) 259 + static void mdp5_vid_encoder_enable(struct drm_encoder *encoder) 249 260 { 250 261 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 251 262 struct mdp5_kms *mdp5_kms = get_kms(encoder); ··· 266 277 mdp5_ctl_set_encoder_state(ctl, true); 267 278 268 279 mdp5_encoder->enabled = true; 280 + } 281 + 282 + static void mdp5_encoder_mode_set(struct drm_encoder *encoder, 283 + struct drm_display_mode *mode, 284 + struct drm_display_mode *adjusted_mode) 285 + { 286 + struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 287 + struct mdp5_interface *intf = &mdp5_encoder->intf; 288 + 289 + if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 290 + mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode); 291 + else 292 + mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode); 293 + } 294 + 295 + static void mdp5_encoder_disable(struct drm_encoder *encoder) 296 + { 297 + struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 298 + struct mdp5_interface *intf = &mdp5_encoder->intf; 299 + 300 + if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 301 + mdp5_cmd_encoder_disable(encoder); 302 + else 303 + mdp5_vid_encoder_disable(encoder); 304 + } 305 + 306 + static void mdp5_encoder_enable(struct drm_encoder *encoder) 307 + { 308 + struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 309 + struct mdp5_interface *intf = &mdp5_encoder->intf; 310 + 311 + if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 312 + mdp5_cmd_encoder_disable(encoder); 313 + else 314 + mdp5_vid_encoder_enable(encoder); 269 315 } 270 316 271 317 static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { ··· 327 303 return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf)); 328 304 } 329 305 330 - int mdp5_encoder_set_split_display(struct drm_encoder *encoder, 331 - struct drm_encoder *slave_encoder) 306 + int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, 307 + struct drm_encoder *slave_encoder) 332 308 { 333 309 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 334 310 struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder); ··· 364 340 mdp5_disable(mdp5_kms); 365 341 366 342 return 0; 343 + } 344 + 345 + void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode) 346 + { 347 + struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 348 + struct mdp5_interface *intf = &mdp5_encoder->intf; 349 + 350 + /* TODO: Expand this to set writeback modes too */ 351 + if (cmd_mode) { 352 + WARN_ON(intf->type != INTF_DSI); 353 + intf->mode = MDP5_INTF_DSI_MODE_COMMAND; 354 + } else { 355 + if (intf->type == INTF_DSI) 356 + intf->mode = MDP5_INTF_DSI_MODE_VIDEO; 357 + else 358 + intf->mode = MDP5_INTF_MODE_NONE; 359 + } 367 360 } 368 361 369 362 /* initialize encoder */
+80 -43
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
··· 148 148 return mdp5_cmd_encoder_set_split_display(encoder, 149 149 slave_encoder); 150 150 else 151 - return mdp5_encoder_set_split_display(encoder, slave_encoder); 151 + return mdp5_vid_encoder_set_split_display(encoder, 152 + slave_encoder); 153 + } 154 + 155 + static void mdp5_set_encoder_mode(struct msm_kms *kms, 156 + struct drm_encoder *encoder, 157 + bool cmd_mode) 158 + { 159 + mdp5_encoder_set_intf_mode(encoder, cmd_mode); 152 160 } 153 161 154 162 static void mdp5_kms_destroy(struct msm_kms *kms) ··· 238 230 .get_format = mdp_get_format, 239 231 .round_pixclk = mdp5_round_pixclk, 240 232 .set_split_display = mdp5_set_split_display, 233 + .set_encoder_mode = mdp5_set_encoder_mode, 241 234 .destroy = mdp5_kms_destroy, 242 235 #ifdef CONFIG_DEBUG_FS 243 236 .debugfs_init = mdp5_kms_debugfs_init, ··· 276 267 277 268 static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, 278 269 enum mdp5_intf_type intf_type, int intf_num, 279 - enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl) 270 + struct mdp5_ctl *ctl) 280 271 { 281 272 struct drm_device *dev = mdp5_kms->dev; 282 273 struct msm_drm_private *priv = dev->dev_private; ··· 284 275 struct mdp5_interface intf = { 285 276 .num = intf_num, 286 277 .type = intf_type, 287 - .mode = intf_mode, 278 + .mode = MDP5_INTF_MODE_NONE, 288 279 }; 289 280 290 - if ((intf_type == INTF_DSI) && 291 - (intf_mode == MDP5_INTF_DSI_MODE_COMMAND)) 292 - encoder = mdp5_cmd_encoder_init(dev, &intf, ctl); 293 - else 294 - encoder = mdp5_encoder_init(dev, &intf, ctl); 295 - 281 + encoder = mdp5_encoder_init(dev, &intf, ctl); 296 282 if (IS_ERR(encoder)) { 297 283 dev_err(dev->dev, "failed to construct encoder\n"); 298 284 return encoder; 299 285 } 300 286 301 - encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; 302 287 priv->encoders[priv->num_encoders++] = encoder; 303 288 304 289 return encoder; ··· 341 338 break; 342 339 } 343 340 344 - encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, 345 - MDP5_INTF_MODE_NONE, ctl); 341 + encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl); 346 342 if (IS_ERR(encoder)) { 347 343 ret = PTR_ERR(encoder); 348 344 break; ··· 359 357 break; 360 358 } 361 359 362 - encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, 363 - MDP5_INTF_MODE_NONE, ctl); 360 + encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl); 364 361 if (IS_ERR(encoder)) { 365 362 ret = PTR_ERR(encoder); 366 363 break; ··· 370 369 case INTF_DSI: 371 370 { 372 371 int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num); 373 - struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM]; 374 - enum mdp5_intf_mode mode; 375 - int i; 376 372 377 373 if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) { 378 374 dev_err(dev->dev, "failed to find dsi from intf %d\n", ··· 387 389 break; 388 390 } 389 391 390 - for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { 391 - mode = (i == MSM_DSI_CMD_ENCODER_ID) ? 392 - MDP5_INTF_DSI_MODE_COMMAND : 393 - MDP5_INTF_DSI_MODE_VIDEO; 394 - dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI, 395 - intf_num, mode, ctl); 396 - if (IS_ERR(dsi_encs[i])) { 397 - ret = PTR_ERR(dsi_encs[i]); 398 - break; 399 - } 392 + encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl); 393 + if (IS_ERR(encoder)) { 394 + ret = PTR_ERR(encoder); 395 + break; 400 396 } 401 397 402 - ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs); 398 + ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder); 403 399 break; 404 400 } 405 401 default: ··· 410 418 struct drm_device *dev = mdp5_kms->dev; 411 419 struct msm_drm_private *priv = dev->dev_private; 412 420 const struct mdp5_cfg_hw *hw_cfg; 413 - int i, ret; 421 + unsigned int num_crtcs; 422 + int i, ret, pi = 0, ci = 0; 423 + struct drm_plane *primary[MAX_BASES] = { NULL }; 424 + struct drm_plane *cursor[MAX_BASES] = { NULL }; 414 425 415 426 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); 416 427 417 - /* Construct planes equaling the number of hw pipes, and CRTCs 418 - * for the N layer-mixers (LM). The first N planes become primary 428 + /* 429 + * Construct encoders and modeset initialize connector devices 430 + * for each external display interface. 431 + */ 432 + for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) { 433 + ret = modeset_init_intf(mdp5_kms, i); 434 + if (ret) 435 + goto fail; 436 + } 437 + 438 + /* 439 + * We should ideally have less number of encoders (set up by parsing 440 + * the MDP5 interfaces) than the number of layer mixers present in HW, 441 + * but let's be safe here anyway 442 + */ 443 + num_crtcs = min(priv->num_encoders, mdp5_cfg->lm.count); 444 + 445 + /* 446 + * Construct planes equaling the number of hw pipes, and CRTCs for the 447 + * N encoders set up by the driver. The first N planes become primary 419 448 * planes for the CRTCs, with the remainder as overlay planes: 420 449 */ 421 450 for (i = 0; i < mdp5_kms->num_hwpipes; i++) { 422 - bool primary = i < mdp5_cfg->lm.count; 451 + struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i]; 423 452 struct drm_plane *plane; 424 - struct drm_crtc *crtc; 453 + enum drm_plane_type type; 425 454 426 - plane = mdp5_plane_init(dev, primary); 455 + if (i < num_crtcs) 456 + type = DRM_PLANE_TYPE_PRIMARY; 457 + else if (hwpipe->caps & MDP_PIPE_CAP_CURSOR) 458 + type = DRM_PLANE_TYPE_CURSOR; 459 + else 460 + type = DRM_PLANE_TYPE_OVERLAY; 461 + 462 + plane = mdp5_plane_init(dev, type); 427 463 if (IS_ERR(plane)) { 428 464 ret = PTR_ERR(plane); 429 465 dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret); ··· 459 439 } 460 440 priv->planes[priv->num_planes++] = plane; 461 441 462 - if (!primary) 463 - continue; 442 + if (type == DRM_PLANE_TYPE_PRIMARY) 443 + primary[pi++] = plane; 444 + if (type == DRM_PLANE_TYPE_CURSOR) 445 + cursor[ci++] = plane; 446 + } 464 447 465 - crtc = mdp5_crtc_init(dev, plane, i); 448 + for (i = 0; i < num_crtcs; i++) { 449 + struct drm_crtc *crtc; 450 + 451 + crtc = mdp5_crtc_init(dev, primary[i], cursor[i], i); 466 452 if (IS_ERR(crtc)) { 467 453 ret = PTR_ERR(crtc); 468 454 dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); ··· 477 451 priv->crtcs[priv->num_crtcs++] = crtc; 478 452 } 479 453 480 - /* Construct encoders and modeset initialize connector devices 481 - * for each external display interface. 454 + /* 455 + * Now that we know the number of crtcs we've created, set the possible 456 + * crtcs for the encoders 482 457 */ 483 - for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) { 484 - ret = modeset_init_intf(mdp5_kms, i); 485 - if (ret) 486 - goto fail; 458 + for (i = 0; i < priv->num_encoders; i++) { 459 + struct drm_encoder *encoder = priv->encoders[i]; 460 + 461 + encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; 487 462 } 488 463 489 464 return 0; ··· 800 773 static const enum mdp5_pipe dma_planes[] = { 801 774 SSPP_DMA0, SSPP_DMA1, 802 775 }; 776 + static const enum mdp5_pipe cursor_planes[] = { 777 + SSPP_CURSOR0, SSPP_CURSOR1, 778 + }; 803 779 const struct mdp5_cfg_hw *hw_cfg; 804 780 int ret; 805 781 ··· 823 793 /* Construct DMA pipes: */ 824 794 ret = construct_pipes(mdp5_kms, hw_cfg->pipe_dma.count, dma_planes, 825 795 hw_cfg->pipe_dma.base, hw_cfg->pipe_dma.caps); 796 + if (ret) 797 + return ret; 798 + 799 + /* Construct cursor pipes: */ 800 + ret = construct_pipes(mdp5_kms, hw_cfg->pipe_cursor.count, 801 + cursor_planes, hw_cfg->pipe_cursor.base, 802 + hw_cfg->pipe_cursor.caps); 826 803 if (ret) 827 804 return ret; 828 805
+35 -10
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
··· 126 126 enum mdp5_intf_mode mode; 127 127 }; 128 128 129 + struct mdp5_encoder { 130 + struct drm_encoder base; 131 + struct mdp5_interface intf; 132 + spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ 133 + bool enabled; 134 + uint32_t bsc; 135 + 136 + struct mdp5_ctl *ctl; 137 + }; 138 + #define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base) 139 + 129 140 static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) 130 141 { 131 142 msm_writel(data, mdp5_kms->mmio + reg); ··· 167 156 NAME(RGB0), NAME(RGB1), NAME(RGB2), 168 157 NAME(DMA0), NAME(DMA1), 169 158 NAME(VIG3), NAME(RGB3), 159 + NAME(CURSOR0), NAME(CURSOR1), 170 160 #undef NAME 171 161 }; 172 162 return names[pipe]; ··· 243 231 244 232 uint32_t mdp5_plane_get_flush(struct drm_plane *plane); 245 233 enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); 246 - struct drm_plane *mdp5_plane_init(struct drm_device *dev, bool primary); 234 + struct drm_plane *mdp5_plane_init(struct drm_device *dev, 235 + enum drm_plane_type type); 247 236 237 + struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc); 248 238 uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); 249 239 250 240 int mdp5_crtc_get_lm(struct drm_crtc *crtc); ··· 254 240 struct mdp5_interface *intf, struct mdp5_ctl *ctl); 255 241 void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc); 256 242 struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, 257 - struct drm_plane *plane, int id); 243 + struct drm_plane *plane, 244 + struct drm_plane *cursor_plane, int id); 258 245 259 246 struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, 260 247 struct mdp5_interface *intf, struct mdp5_ctl *ctl); 261 - int mdp5_encoder_set_split_display(struct drm_encoder *encoder, 262 - struct drm_encoder *slave_encoder); 248 + int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, 249 + struct drm_encoder *slave_encoder); 250 + void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode); 263 251 int mdp5_encoder_get_linecount(struct drm_encoder *encoder); 264 252 u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder); 265 253 266 254 #ifdef CONFIG_DRM_MSM_DSI 267 - struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, 268 - struct mdp5_interface *intf, struct mdp5_ctl *ctl); 255 + void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, 256 + struct drm_display_mode *mode, 257 + struct drm_display_mode *adjusted_mode); 258 + void mdp5_cmd_encoder_disable(struct drm_encoder *encoder); 259 + void mdp5_cmd_encoder_enable(struct drm_encoder *encoder); 269 260 int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, 270 - struct drm_encoder *slave_encoder); 261 + struct drm_encoder *slave_encoder); 271 262 #else 272 - static inline struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, 273 - struct mdp5_interface *intf, struct mdp5_ctl *ctl) 263 + static inline void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, 264 + struct drm_display_mode *mode, 265 + struct drm_display_mode *adjusted_mode) 274 266 { 275 - return ERR_PTR(-EINVAL); 267 + } 268 + static inline void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) 269 + { 270 + } 271 + static inline void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) 272 + { 276 273 } 277 274 static inline int mdp5_cmd_encoder_set_split_display( 278 275 struct drm_encoder *encoder, struct drm_encoder *slave_encoder)
+8
drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c
··· 53 53 if (caps & ~cur->caps) 54 54 continue; 55 55 56 + /* 57 + * don't assign a cursor pipe to a plane that isn't going to 58 + * be used as a cursor 59 + */ 60 + if (cur->caps & MDP_PIPE_CAP_CURSOR && 61 + plane->type != DRM_PLANE_TYPE_CURSOR) 62 + continue; 63 + 56 64 /* possible candidate, take the one with the 57 65 * fewest unneeded caps bits set: 58 66 */
+163 -18
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
··· 29 29 30 30 static int mdp5_plane_mode_set(struct drm_plane *plane, 31 31 struct drm_crtc *crtc, struct drm_framebuffer *fb, 32 + struct drm_rect *src, struct drm_rect *dest); 33 + 34 + static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane, 35 + struct drm_crtc *crtc, 36 + struct drm_framebuffer *fb, 32 37 int crtc_x, int crtc_y, 33 38 unsigned int crtc_w, unsigned int crtc_h, 34 39 uint32_t src_x, uint32_t src_y, ··· 50 45 51 46 static bool plane_enabled(struct drm_plane_state *state) 52 47 { 53 - return state->fb && state->crtc; 48 + return state->visible; 54 49 } 55 50 56 51 static void mdp5_plane_destroy(struct drm_plane *plane) ··· 251 246 .atomic_print_state = mdp5_plane_atomic_print_state, 252 247 }; 253 248 249 + static const struct drm_plane_funcs mdp5_cursor_plane_funcs = { 250 + .update_plane = mdp5_update_cursor_plane_legacy, 251 + .disable_plane = drm_atomic_helper_disable_plane, 252 + .destroy = mdp5_plane_destroy, 253 + .set_property = drm_atomic_helper_plane_set_property, 254 + .atomic_set_property = mdp5_plane_atomic_set_property, 255 + .atomic_get_property = mdp5_plane_atomic_get_property, 256 + .reset = mdp5_plane_reset, 257 + .atomic_duplicate_state = mdp5_plane_duplicate_state, 258 + .atomic_destroy_state = mdp5_plane_destroy_state, 259 + .atomic_print_state = mdp5_plane_atomic_print_state, 260 + }; 261 + 254 262 static int mdp5_plane_prepare_fb(struct drm_plane *plane, 255 263 struct drm_plane_state *new_state) 256 264 { ··· 290 272 msm_framebuffer_cleanup(fb, mdp5_kms->id); 291 273 } 292 274 293 - static int mdp5_plane_atomic_check(struct drm_plane *plane, 294 - struct drm_plane_state *state) 275 + #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) 276 + static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, 277 + struct drm_plane_state *state) 295 278 { 296 279 struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state); 280 + struct drm_plane *plane = state->plane; 297 281 struct drm_plane_state *old_state = plane->state; 298 282 struct mdp5_cfg *config = mdp5_cfg_get_config(get_kms(plane)->cfg); 299 283 bool new_hwpipe = false; 300 284 uint32_t max_width, max_height; 301 285 uint32_t caps = 0; 286 + struct drm_rect clip; 287 + int min_scale, max_scale; 288 + int ret; 302 289 303 290 DBG("%s: check (%d -> %d)", plane->name, 304 291 plane_enabled(old_state), plane_enabled(state)); ··· 318 295 DRM_RECT_FP_ARG(&src)); 319 296 return -ERANGE; 320 297 } 298 + 299 + clip.x1 = 0; 300 + clip.y1 = 0; 301 + clip.x2 = crtc_state->adjusted_mode.hdisplay; 302 + clip.y2 = crtc_state->adjusted_mode.vdisplay; 303 + min_scale = FRAC_16_16(1, 8); 304 + max_scale = FRAC_16_16(8, 1); 305 + 306 + ret = drm_plane_helper_check_state(state, &clip, min_scale, 307 + max_scale, true, true); 308 + if (ret) 309 + return ret; 321 310 322 311 if (plane_enabled(state)) { 323 312 unsigned int rotation; ··· 355 320 356 321 if (rotation & DRM_REFLECT_Y) 357 322 caps |= MDP_PIPE_CAP_VFLIP; 323 + 324 + if (plane->type == DRM_PLANE_TYPE_CURSOR) 325 + caps |= MDP_PIPE_CAP_CURSOR; 358 326 359 327 /* (re)allocate hw pipe if we don't have one or caps-mismatch: */ 360 328 if (!mdp5_state->hwpipe || (caps & ~mdp5_state->hwpipe->caps)) ··· 394 356 return 0; 395 357 } 396 358 359 + static int mdp5_plane_atomic_check(struct drm_plane *plane, 360 + struct drm_plane_state *state) 361 + { 362 + struct drm_crtc *crtc; 363 + struct drm_crtc_state *crtc_state; 364 + 365 + crtc = state->crtc ? state->crtc : plane->state->crtc; 366 + if (!crtc) 367 + return 0; 368 + 369 + crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); 370 + if (WARN_ON(!crtc_state)) 371 + return -EINVAL; 372 + 373 + return mdp5_plane_atomic_check_with_state(crtc_state, state); 374 + } 375 + 397 376 static void mdp5_plane_atomic_update(struct drm_plane *plane, 398 377 struct drm_plane_state *old_state) 399 378 { ··· 423 368 424 369 ret = mdp5_plane_mode_set(plane, 425 370 state->crtc, state->fb, 426 - state->crtc_x, state->crtc_y, 427 - state->crtc_w, state->crtc_h, 428 - state->src_x, state->src_y, 429 - state->src_w, state->src_h); 371 + &state->src, &state->dst); 430 372 /* atomic_check should have ensured that this doesn't fail */ 431 373 WARN_ON(ret < 0); 432 374 } ··· 716 664 717 665 static int mdp5_plane_mode_set(struct drm_plane *plane, 718 666 struct drm_crtc *crtc, struct drm_framebuffer *fb, 719 - int crtc_x, int crtc_y, 720 - unsigned int crtc_w, unsigned int crtc_h, 721 - uint32_t src_x, uint32_t src_y, 722 - uint32_t src_w, uint32_t src_h) 667 + struct drm_rect *src, struct drm_rect *dest) 723 668 { 724 669 struct drm_plane_state *pstate = plane->state; 725 670 struct mdp5_hw_pipe *hwpipe = to_mdp5_plane_state(pstate)->hwpipe; ··· 732 683 uint32_t pix_format; 733 684 unsigned int rotation; 734 685 bool vflip, hflip; 686 + int crtc_x, crtc_y; 687 + unsigned int crtc_w, crtc_h; 688 + uint32_t src_x, src_y; 689 + uint32_t src_w, src_h; 735 690 unsigned long flags; 736 691 int ret; 737 692 ··· 747 694 748 695 format = to_mdp_format(msm_framebuffer_format(fb)); 749 696 pix_format = format->base.pixel_format; 697 + 698 + src_x = src->x1; 699 + src_y = src->y1; 700 + src_w = drm_rect_width(src); 701 + src_h = drm_rect_height(src); 702 + 703 + crtc_x = dest->x1; 704 + crtc_y = dest->y1; 705 + crtc_w = drm_rect_width(dest); 706 + crtc_h = drm_rect_height(dest); 750 707 751 708 /* src values are in Q16 fixed point, convert to integer: */ 752 709 src_x = src_x >> 16; ··· 881 818 return ret; 882 819 } 883 820 821 + static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane, 822 + struct drm_crtc *crtc, struct drm_framebuffer *fb, 823 + int crtc_x, int crtc_y, 824 + unsigned int crtc_w, unsigned int crtc_h, 825 + uint32_t src_x, uint32_t src_y, 826 + uint32_t src_w, uint32_t src_h) 827 + { 828 + struct drm_plane_state *plane_state, *new_plane_state; 829 + struct mdp5_plane_state *mdp5_pstate; 830 + struct drm_crtc_state *crtc_state = crtc->state; 831 + int ret; 832 + 833 + if (!crtc_state->active || drm_atomic_crtc_needs_modeset(crtc_state)) 834 + goto slow; 835 + 836 + plane_state = plane->state; 837 + mdp5_pstate = to_mdp5_plane_state(plane_state); 838 + 839 + /* don't use fast path if we don't have a hwpipe allocated yet */ 840 + if (!mdp5_pstate->hwpipe) 841 + goto slow; 842 + 843 + /* only allow changing of position(crtc x/y or src x/y) in fast path */ 844 + if (plane_state->crtc != crtc || 845 + plane_state->src_w != src_w || 846 + plane_state->src_h != src_h || 847 + plane_state->crtc_w != crtc_w || 848 + plane_state->crtc_h != crtc_h || 849 + !plane_state->fb || 850 + plane_state->fb != fb) 851 + goto slow; 852 + 853 + new_plane_state = mdp5_plane_duplicate_state(plane); 854 + if (!new_plane_state) 855 + return -ENOMEM; 856 + 857 + new_plane_state->src_x = src_x; 858 + new_plane_state->src_y = src_y; 859 + new_plane_state->src_w = src_w; 860 + new_plane_state->src_h = src_h; 861 + new_plane_state->crtc_x = crtc_x; 862 + new_plane_state->crtc_y = crtc_y; 863 + new_plane_state->crtc_w = crtc_w; 864 + new_plane_state->crtc_h = crtc_h; 865 + 866 + ret = mdp5_plane_atomic_check_with_state(crtc_state, new_plane_state); 867 + if (ret) 868 + goto slow_free; 869 + 870 + if (new_plane_state->visible) { 871 + struct mdp5_ctl *ctl; 872 + 873 + ret = mdp5_plane_mode_set(plane, crtc, fb, 874 + &new_plane_state->src, 875 + &new_plane_state->dst); 876 + WARN_ON(ret < 0); 877 + 878 + ctl = mdp5_crtc_get_ctl(crtc); 879 + 880 + mdp5_ctl_commit(ctl, mdp5_plane_get_flush(plane)); 881 + } 882 + 883 + *to_mdp5_plane_state(plane_state) = 884 + *to_mdp5_plane_state(new_plane_state); 885 + 886 + mdp5_plane_destroy_state(plane, new_plane_state); 887 + 888 + return 0; 889 + slow_free: 890 + mdp5_plane_destroy_state(plane, new_plane_state); 891 + slow: 892 + return drm_atomic_helper_update_plane(plane, crtc, fb, 893 + crtc_x, crtc_y, crtc_w, crtc_h, 894 + src_x, src_y, src_w, src_h); 895 + } 896 + 884 897 enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) 885 898 { 886 899 struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state); 887 900 888 901 if (WARN_ON(!pstate->hwpipe)) 889 - return 0; 902 + return SSPP_NONE; 890 903 891 904 return pstate->hwpipe->pipe; 892 905 } ··· 978 839 } 979 840 980 841 /* initialize plane */ 981 - struct drm_plane *mdp5_plane_init(struct drm_device *dev, bool primary) 842 + struct drm_plane *mdp5_plane_init(struct drm_device *dev, 843 + enum drm_plane_type type) 982 844 { 983 845 struct drm_plane *plane = NULL; 984 846 struct mdp5_plane *mdp5_plane; 985 847 int ret; 986 - enum drm_plane_type type; 987 848 988 849 mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL); 989 850 if (!mdp5_plane) { ··· 996 857 mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats, 997 858 ARRAY_SIZE(mdp5_plane->formats), false); 998 859 999 - type = primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 1000 - ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, 1001 - mdp5_plane->formats, mdp5_plane->nformats, 1002 - type, NULL); 860 + if (type == DRM_PLANE_TYPE_CURSOR) 861 + ret = drm_universal_plane_init(dev, plane, 0xff, 862 + &mdp5_cursor_plane_funcs, 863 + mdp5_plane->formats, mdp5_plane->nformats, 864 + type, NULL); 865 + else 866 + ret = drm_universal_plane_init(dev, plane, 0xff, 867 + &mdp5_plane_funcs, 868 + mdp5_plane->formats, mdp5_plane->nformats, 869 + type, NULL); 1003 870 if (ret) 1004 871 goto fail; 1005 872
+1
drivers/gpu/drm/msm/mdp/mdp_kms.h
··· 112 112 #define MDP_PIPE_CAP_CSC BIT(3) 113 113 #define MDP_PIPE_CAP_DECIMATION BIT(4) 114 114 #define MDP_PIPE_CAP_SW_PIX_EXT BIT(5) 115 + #define MDP_PIPE_CAP_CURSOR BIT(6) 115 116 116 117 static inline bool pipe_supports_yuv(uint32_t pipe_caps) 117 118 {
+15 -11
drivers/gpu/drm/msm/msm_atomic.c
··· 93 93 if (!crtc->state->enable) 94 94 continue; 95 95 96 - /* Legacy cursor ioctls are completely unsynced, and userspace 97 - * relies on that (by doing tons of cursor updates). */ 98 - if (old_state->legacy_cursor_update) 99 - continue; 100 - 101 96 kms->funcs->wait_for_crtc_commit_done(kms, crtc); 102 97 } 103 98 } ··· 146 151 complete_commit(container_of(work, struct msm_commit, work), true); 147 152 } 148 153 154 + /* 155 + * this func is identical to the drm_atomic_helper_check, but we keep this 156 + * because we might eventually need to have a more finegrained check 157 + * sequence without using the atomic helpers. 158 + * 159 + * In the past, we first called drm_atomic_helper_check_planes, and then 160 + * drm_atomic_helper_check_modeset. We needed this because the MDP5 plane's 161 + * ->atomic_check could update ->mode_changed for pixel format changes. 162 + * This, however isn't needed now because if there is a pixel format change, 163 + * we just assign a new hwpipe for it with a new SMP allocation. We might 164 + * eventually hit a condition where we would need to do a full modeset if 165 + * we run out of planes. There, we'd probably need to set mode_changed. 166 + */ 149 167 int msm_atomic_check(struct drm_device *dev, 150 168 struct drm_atomic_state *state) 151 169 { 152 170 int ret; 153 171 154 - /* 155 - * msm ->atomic_check can update ->mode_changed for pixel format 156 - * changes, hence must be run before we check the modeset changes. 157 - */ 158 - ret = drm_atomic_helper_check_planes(dev, state); 172 + ret = drm_atomic_helper_check_modeset(dev, state); 159 173 if (ret) 160 174 return ret; 161 175 162 - ret = drm_atomic_helper_check_modeset(dev, state); 176 + ret = drm_atomic_helper_check_planes(dev, state); 163 177 if (ret) 164 178 return ret; 165 179
+20
drivers/gpu/drm/msm/msm_drv.c
··· 91 91 * Util/helpers: 92 92 */ 93 93 94 + struct clk *msm_clk_get(struct platform_device *pdev, const char *name) 95 + { 96 + struct clk *clk; 97 + char name2[32]; 98 + 99 + clk = devm_clk_get(&pdev->dev, name); 100 + if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 101 + return clk; 102 + 103 + snprintf(name2, sizeof(name2), "%s_clk", name); 104 + 105 + clk = devm_clk_get(&pdev->dev, name2); 106 + if (!IS_ERR(clk)) 107 + dev_warn(&pdev->dev, "Using legacy clk name binding. Use " 108 + "\"%s\" instead of \"%s\"\n", name, name2); 109 + 110 + return clk; 111 + } 112 + 94 113 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 95 114 const char *dbgname) 96 115 { ··· 1004 985 * as components. 1005 986 */ 1006 987 static const struct of_device_id msm_gpu_match[] = { 988 + { .compatible = "qcom,adreno" }, 1007 989 { .compatible = "qcom,adreno-3xx" }, 1008 990 { .compatible = "qcom,kgsl-3d0" }, 1009 991 { },
+4 -8
drivers/gpu/drm/msm/msm_drv.h
··· 275 275 struct drm_encoder *encoder); 276 276 277 277 struct msm_dsi; 278 - enum msm_dsi_encoder_id { 279 - MSM_DSI_VIDEO_ENCODER_ID = 0, 280 - MSM_DSI_CMD_ENCODER_ID = 1, 281 - MSM_DSI_ENCODER_NUM = 2 282 - }; 283 278 #ifdef CONFIG_DRM_MSM_DSI 284 279 void __init msm_dsi_register(void); 285 280 void __exit msm_dsi_unregister(void); 286 281 int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, 287 - struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]); 282 + struct drm_encoder *encoder); 288 283 #else 289 284 static inline void __init msm_dsi_register(void) 290 285 { ··· 288 293 { 289 294 } 290 295 static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, 291 - struct drm_device *dev, 292 - struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]) 296 + struct drm_device *dev, 297 + struct drm_encoder *encoder) 293 298 { 294 299 return -EINVAL; 295 300 } ··· 313 318 static inline void msm_rd_dump_submit(struct msm_gem_submit *submit) {} 314 319 #endif 315 320 321 + struct clk *msm_clk_get(struct platform_device *pdev, const char *name); 316 322 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, 317 323 const char *dbgname); 318 324 void msm_writel(u32 data, void __iomem *addr);
+7 -6
drivers/gpu/drm/msm/msm_gem_submit.c
··· 95 95 */ 96 96 submit->bos[i].flags = 0; 97 97 98 - ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo)); 99 - if (unlikely(ret)) { 98 + if (copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo))) { 100 99 pagefault_enable(); 101 100 spin_unlock(&file->table_lock); 102 - ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); 103 - if (ret) 101 + if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) { 102 + ret = -EFAULT; 104 103 goto out; 104 + } 105 105 spin_lock(&file->table_lock); 106 106 pagefault_disable(); 107 107 } ··· 317 317 uint64_t iova; 318 318 bool valid; 319 319 320 - ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc)); 321 - if (ret) 320 + if (copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc))) { 321 + ret = -EFAULT; 322 322 goto out; 323 + } 323 324 324 325 if (submit_reloc.submit_offset % 4) { 325 326 DRM_ERROR("non-aligned reloc offset: %u\n",
+3 -4
drivers/gpu/drm/msm/msm_gpu.c
··· 560 560 } 561 561 562 562 static const char *clk_names[] = { 563 - "core_clk", "iface_clk", "rbbmtimer_clk", "mem_clk", 564 - "mem_iface_clk", "alt_mem_iface_clk", 563 + "core", "iface", "rbbmtimer", "mem", "mem_iface", "alt_mem_iface", 565 564 }; 566 565 567 566 int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, ··· 624 625 625 626 /* Acquire clocks: */ 626 627 for (i = 0; i < ARRAY_SIZE(clk_names); i++) { 627 - gpu->grp_clks[i] = devm_clk_get(&pdev->dev, clk_names[i]); 628 + gpu->grp_clks[i] = msm_clk_get(pdev, clk_names[i]); 628 629 DBG("grp_clks[%s]: %p", clk_names[i], gpu->grp_clks[i]); 629 630 if (IS_ERR(gpu->grp_clks[i])) 630 631 gpu->grp_clks[i] = NULL; 631 632 } 632 633 633 - gpu->ebi1_clk = devm_clk_get(&pdev->dev, "bus_clk"); 634 + gpu->ebi1_clk = msm_clk_get(pdev, "bus"); 634 635 DBG("ebi1_clk: %p", gpu->ebi1_clk); 635 636 if (IS_ERR(gpu->ebi1_clk)) 636 637 gpu->ebi1_clk = NULL;
+5 -2
drivers/gpu/drm/msm/msm_iommu.c
··· 24 24 }; 25 25 #define to_msm_iommu(x) container_of(x, struct msm_iommu, base) 26 26 27 - static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, 27 + static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, 28 28 unsigned long iova, int flags, void *arg) 29 29 { 30 + struct msm_iommu *iommu = arg; 31 + if (iommu->base.handler) 32 + return iommu->base.handler(iommu->base.arg, iova, flags); 30 33 pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags); 31 34 return 0; 32 35 } ··· 139 136 140 137 iommu->domain = domain; 141 138 msm_mmu_init(&iommu->base, dev, &funcs); 142 - iommu_set_fault_handler(domain, msm_fault_handler, dev); 139 + iommu_set_fault_handler(domain, msm_fault_handler, iommu); 143 140 144 141 return &iommu->base; 145 142 }
+3
drivers/gpu/drm/msm/msm_kms.h
··· 56 56 struct drm_encoder *encoder, 57 57 struct drm_encoder *slave_encoder, 58 58 bool is_cmd_mode); 59 + void (*set_encoder_mode)(struct msm_kms *kms, 60 + struct drm_encoder *encoder, 61 + bool cmd_mode); 59 62 /* cleanup: */ 60 63 void (*destroy)(struct msm_kms *kms); 61 64 #ifdef CONFIG_DEBUG_FS
+9
drivers/gpu/drm/msm/msm_mmu.h
··· 33 33 struct msm_mmu { 34 34 const struct msm_mmu_funcs *funcs; 35 35 struct device *dev; 36 + int (*handler)(void *arg, unsigned long iova, int flags); 37 + void *arg; 36 38 }; 37 39 38 40 static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, ··· 46 44 47 45 struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain); 48 46 struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu); 47 + 48 + static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, 49 + int (*handler)(void *arg, unsigned long iova, int flags)) 50 + { 51 + mmu->arg = arg; 52 + mmu->handler = handler; 53 + } 49 54 50 55 #endif /* __MSM_MMU_H__ */