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

Configure Feed

Select the types of activity you want to include in your feed.

drm/msm/dp: move all IO handling to dp_catalog

Rather than parsing the I/O addresses from dp_parser and then passing
them via a struct pointer to dp_catalog, handle I/O region parsing in
dp_catalog and drop it from dp_parser.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
Reviewed-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/576108/
Link: https://lore.kernel.org/r/20240126-dp-power-parser-cleanup-v3-12-098d5f581dd3@linaro.org

+115 -119
+106 -21
drivers/gpu/drm/msm/dp/dp_catalog.c
··· 7 7 8 8 #include <linux/delay.h> 9 9 #include <linux/iopoll.h> 10 + #include <linux/platform_device.h> 10 11 #include <linux/rational.h> 11 12 #include <drm/display/drm_dp_helper.h> 12 13 #include <drm/drm_print.h> ··· 54 53 (PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \ 55 54 PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK) 56 55 56 + #define DP_DEFAULT_AHB_OFFSET 0x0000 57 + #define DP_DEFAULT_AHB_SIZE 0x0200 58 + #define DP_DEFAULT_AUX_OFFSET 0x0200 59 + #define DP_DEFAULT_AUX_SIZE 0x0200 60 + #define DP_DEFAULT_LINK_OFFSET 0x0400 61 + #define DP_DEFAULT_LINK_SIZE 0x0C00 62 + #define DP_DEFAULT_P0_OFFSET 0x1000 63 + #define DP_DEFAULT_P0_SIZE 0x0400 64 + 65 + struct dss_io_region { 66 + size_t len; 67 + void __iomem *base; 68 + }; 69 + 70 + struct dss_io_data { 71 + struct dss_io_region ahb; 72 + struct dss_io_region aux; 73 + struct dss_io_region link; 74 + struct dss_io_region p0; 75 + }; 76 + 57 77 struct dp_catalog_private { 58 78 struct device *dev; 59 79 struct drm_device *drm_dev; 60 - struct dp_io *io; 80 + struct dss_io_data io; 61 81 u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX]; 62 82 struct dp_catalog dp_catalog; 63 83 u8 aux_lut_cfg_index[PHY_AUX_CFG_MAX]; ··· 88 66 { 89 67 struct dp_catalog_private *catalog = container_of(dp_catalog, 90 68 struct dp_catalog_private, dp_catalog); 91 - struct dss_io_data *dss = &catalog->io->dp_controller; 69 + struct dss_io_data *dss = &catalog->io; 92 70 93 71 msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb"); 94 72 msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux"); ··· 98 76 99 77 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset) 100 78 { 101 - return readl_relaxed(catalog->io->dp_controller.aux.base + offset); 79 + return readl_relaxed(catalog->io.aux.base + offset); 102 80 } 103 81 104 82 static inline void dp_write_aux(struct dp_catalog_private *catalog, ··· 108 86 * To make sure aux reg writes happens before any other operation, 109 87 * this function uses writel() instread of writel_relaxed() 110 88 */ 111 - writel(data, catalog->io->dp_controller.aux.base + offset); 89 + writel(data, catalog->io.aux.base + offset); 112 90 } 113 91 114 92 static inline u32 dp_read_ahb(const struct dp_catalog_private *catalog, u32 offset) 115 93 { 116 - return readl_relaxed(catalog->io->dp_controller.ahb.base + offset); 94 + return readl_relaxed(catalog->io.ahb.base + offset); 117 95 } 118 96 119 97 static inline void dp_write_ahb(struct dp_catalog_private *catalog, ··· 123 101 * To make sure phy reg writes happens before any other operation, 124 102 * this function uses writel() instread of writel_relaxed() 125 103 */ 126 - writel(data, catalog->io->dp_controller.ahb.base + offset); 104 + writel(data, catalog->io.ahb.base + offset); 127 105 } 128 106 129 107 static inline void dp_write_p0(struct dp_catalog_private *catalog, ··· 133 111 * To make sure interface reg writes happens before any other operation, 134 112 * this function uses writel() instread of writel_relaxed() 135 113 */ 136 - writel(data, catalog->io->dp_controller.p0.base + offset); 114 + writel(data, catalog->io.p0.base + offset); 137 115 } 138 116 139 117 static inline u32 dp_read_p0(struct dp_catalog_private *catalog, ··· 143 121 * To make sure interface reg writes happens before any other operation, 144 122 * this function uses writel() instread of writel_relaxed() 145 123 */ 146 - return readl_relaxed(catalog->io->dp_controller.p0.base + offset); 124 + return readl_relaxed(catalog->io.p0.base + offset); 147 125 } 148 126 149 127 static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset) 150 128 { 151 - return readl_relaxed(catalog->io->dp_controller.link.base + offset); 129 + return readl_relaxed(catalog->io.link.base + offset); 152 130 } 153 131 154 132 static inline void dp_write_link(struct dp_catalog_private *catalog, ··· 158 136 * To make sure link reg writes happens before any other operation, 159 137 * this function uses writel() instread of writel_relaxed() 160 138 */ 161 - writel(data, catalog->io->dp_controller.link.base + offset); 139 + writel(data, catalog->io.link.base + offset); 162 140 } 163 141 164 142 /* aux related catalog functions */ ··· 270 248 struct dp_catalog_private, dp_catalog); 271 249 272 250 /* poll for hpd connected status every 2ms and timeout after 500ms */ 273 - return readl_poll_timeout(catalog->io->dp_controller.aux.base + 251 + return readl_poll_timeout(catalog->io.aux.base + 274 252 REG_DP_DP_HPD_INT_STATUS, 275 253 state, state & DP_DP_HPD_STATE_STATUS_CONNECTED, 276 254 2000, 500000); ··· 298 276 { 299 277 struct dp_catalog_private *catalog = container_of(dp_catalog, 300 278 struct dp_catalog_private, dp_catalog); 301 - struct dss_io_data *io = &catalog->io->dp_controller; 279 + struct dss_io_data *io = &catalog->io; 302 280 303 281 pr_info("AHB regs\n"); 304 282 dump_regs(io->ahb.base, io->ahb.len); ··· 522 500 bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; 523 501 524 502 /* Poll for mainlink ready status */ 525 - ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base + 503 + ret = readx_poll_timeout(readl, catalog->io.link.base + 526 504 REG_DP_MAINLINK_READY, 527 505 data, data & bit, 528 506 POLLING_SLEEP_US, POLLING_TIMEOUT_US); ··· 585 563 struct dp_catalog_private, dp_catalog); 586 564 587 565 /* Poll for mainlink ready status */ 588 - ret = readl_poll_timeout(catalog->io->dp_controller.link.base + 566 + ret = readl_poll_timeout(catalog->io.link.base + 589 567 REG_DP_MAINLINK_READY, 590 568 data, data & DP_MAINLINK_READY_FOR_VIDEO, 591 569 POLLING_SLEEP_US, POLLING_TIMEOUT_US); ··· 967 945 dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0); 968 946 } 969 947 970 - struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io) 948 + static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len) 949 + { 950 + struct resource *res; 951 + void __iomem *base; 952 + 953 + base = devm_platform_get_and_ioremap_resource(pdev, idx, &res); 954 + if (!IS_ERR(base)) 955 + *len = resource_size(res); 956 + 957 + return base; 958 + } 959 + 960 + static int dp_catalog_get_io(struct dp_catalog_private *catalog) 961 + { 962 + struct platform_device *pdev = to_platform_device(catalog->dev); 963 + struct dss_io_data *dss = &catalog->io; 964 + 965 + dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len); 966 + if (IS_ERR(dss->ahb.base)) 967 + return PTR_ERR(dss->ahb.base); 968 + 969 + dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len); 970 + if (IS_ERR(dss->aux.base)) { 971 + /* 972 + * The initial binding had a single reg, but in order to 973 + * support variation in the sub-region sizes this was split. 974 + * dp_ioremap() will fail with -EINVAL here if only a single 975 + * reg is specified, so fill in the sub-region offsets and 976 + * lengths based on this single region. 977 + */ 978 + if (PTR_ERR(dss->aux.base) == -EINVAL) { 979 + if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) { 980 + DRM_ERROR("legacy memory region not large enough\n"); 981 + return -EINVAL; 982 + } 983 + 984 + dss->ahb.len = DP_DEFAULT_AHB_SIZE; 985 + dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET; 986 + dss->aux.len = DP_DEFAULT_AUX_SIZE; 987 + dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET; 988 + dss->link.len = DP_DEFAULT_LINK_SIZE; 989 + dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET; 990 + dss->p0.len = DP_DEFAULT_P0_SIZE; 991 + } else { 992 + DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base); 993 + return PTR_ERR(dss->aux.base); 994 + } 995 + } else { 996 + dss->link.base = dp_ioremap(pdev, 2, &dss->link.len); 997 + if (IS_ERR(dss->link.base)) { 998 + DRM_ERROR("unable to remap link region: %pe\n", dss->link.base); 999 + return PTR_ERR(dss->link.base); 1000 + } 1001 + 1002 + dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len); 1003 + if (IS_ERR(dss->p0.base)) { 1004 + DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base); 1005 + return PTR_ERR(dss->p0.base); 1006 + } 1007 + } 1008 + 1009 + return 0; 1010 + } 1011 + 1012 + struct dp_catalog *dp_catalog_get(struct device *dev) 971 1013 { 972 1014 struct dp_catalog_private *catalog; 973 - 974 - if (!io) { 975 - DRM_ERROR("invalid input\n"); 976 - return ERR_PTR(-EINVAL); 977 - } 1015 + int ret; 978 1016 979 1017 catalog = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL); 980 1018 if (!catalog) 981 1019 return ERR_PTR(-ENOMEM); 982 1020 983 1021 catalog->dev = dev; 984 - catalog->io = io; 1022 + 1023 + ret = dp_catalog_get_io(catalog); 1024 + if (ret) 1025 + return ERR_PTR(ret); 985 1026 986 1027 return &catalog->dp_catalog; 987 1028 }
+1 -1
drivers/gpu/drm/msm/dp/dp_catalog.h
··· 126 126 struct drm_display_mode *drm_mode); 127 127 void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog); 128 128 129 - struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io); 129 + struct dp_catalog *dp_catalog_get(struct device *dev); 130 130 131 131 /* DP Audio APIs */ 132 132 void dp_catalog_audio_get_header(struct dp_catalog *catalog);
+3 -3
drivers/gpu/drm/msm/dp/dp_display.c
··· 722 722 goto error; 723 723 } 724 724 725 - dp->catalog = dp_catalog_get(dev, &dp->parser->io); 725 + dp->catalog = dp_catalog_get(dev); 726 726 if (IS_ERR(dp->catalog)) { 727 727 rc = PTR_ERR(dp->catalog); 728 728 DRM_ERROR("failed to initialize catalog, rc = %d\n", rc); ··· 731 731 } 732 732 733 733 dp->aux = dp_aux_get(dev, dp->catalog, 734 - dp->parser->io.phy, 734 + dp->parser->phy, 735 735 dp->dp_display.is_edp); 736 736 if (IS_ERR(dp->aux)) { 737 737 rc = PTR_ERR(dp->aux); ··· 762 762 763 763 dp->ctrl = dp_ctrl_get(dev, dp->link, dp->panel, dp->aux, 764 764 dp->catalog, 765 - dp->parser->io.phy); 765 + dp->parser->phy); 766 766 if (IS_ERR(dp->ctrl)) { 767 767 rc = PTR_ERR(dp->ctrl); 768 768 DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
+3 -70
drivers/gpu/drm/msm/dp/dp_parser.c
··· 13 13 #include "dp_parser.h" 14 14 #include "dp_reg.h" 15 15 16 - #define DP_DEFAULT_AHB_OFFSET 0x0000 17 - #define DP_DEFAULT_AHB_SIZE 0x0200 18 - #define DP_DEFAULT_AUX_OFFSET 0x0200 19 - #define DP_DEFAULT_AUX_SIZE 0x0200 20 - #define DP_DEFAULT_LINK_OFFSET 0x0400 21 - #define DP_DEFAULT_LINK_SIZE 0x0C00 22 - #define DP_DEFAULT_P0_OFFSET 0x1000 23 - #define DP_DEFAULT_P0_SIZE 0x0400 24 - 25 - static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len) 26 - { 27 - struct resource *res; 28 - void __iomem *base; 29 - 30 - base = devm_platform_get_and_ioremap_resource(pdev, idx, &res); 31 - if (!IS_ERR(base)) 32 - *len = resource_size(res); 33 - 34 - return base; 35 - } 36 - 37 16 static int dp_parser_ctrl_res(struct dp_parser *parser) 38 17 { 39 18 struct platform_device *pdev = parser->pdev; 40 - struct dp_io *io = &parser->io; 41 - struct dss_io_data *dss = &io->dp_controller; 42 19 43 - dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len); 44 - if (IS_ERR(dss->ahb.base)) 45 - return PTR_ERR(dss->ahb.base); 46 - 47 - dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len); 48 - if (IS_ERR(dss->aux.base)) { 49 - /* 50 - * The initial binding had a single reg, but in order to 51 - * support variation in the sub-region sizes this was split. 52 - * dp_ioremap() will fail with -EINVAL here if only a single 53 - * reg is specified, so fill in the sub-region offsets and 54 - * lengths based on this single region. 55 - */ 56 - if (PTR_ERR(dss->aux.base) == -EINVAL) { 57 - if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) { 58 - DRM_ERROR("legacy memory region not large enough\n"); 59 - return -EINVAL; 60 - } 61 - 62 - dss->ahb.len = DP_DEFAULT_AHB_SIZE; 63 - dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET; 64 - dss->aux.len = DP_DEFAULT_AUX_SIZE; 65 - dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET; 66 - dss->link.len = DP_DEFAULT_LINK_SIZE; 67 - dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET; 68 - dss->p0.len = DP_DEFAULT_P0_SIZE; 69 - } else { 70 - DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base); 71 - return PTR_ERR(dss->aux.base); 72 - } 73 - } else { 74 - dss->link.base = dp_ioremap(pdev, 2, &dss->link.len); 75 - if (IS_ERR(dss->link.base)) { 76 - DRM_ERROR("unable to remap link region: %pe\n", dss->link.base); 77 - return PTR_ERR(dss->link.base); 78 - } 79 - 80 - dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len); 81 - if (IS_ERR(dss->p0.base)) { 82 - DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base); 83 - return PTR_ERR(dss->p0.base); 84 - } 85 - } 86 - 87 - io->phy = devm_phy_get(&pdev->dev, "dp"); 88 - if (IS_ERR(io->phy)) 89 - return PTR_ERR(io->phy); 20 + parser->phy = devm_phy_get(&pdev->dev, "dp"); 21 + if (IS_ERR(parser->phy)) 22 + return PTR_ERR(parser->phy); 90 23 91 24 return 0; 92 25 }
+2 -24
drivers/gpu/drm/msm/dp/dp_parser.h
··· 14 14 #define DP_MAX_NUM_DP_LANES 4 15 15 #define DP_LINK_RATE_HBR2 540000 /* kbytes */ 16 16 17 - struct dss_io_region { 18 - size_t len; 19 - void __iomem *base; 20 - }; 21 - 22 - struct dss_io_data { 23 - struct dss_io_region ahb; 24 - struct dss_io_region aux; 25 - struct dss_io_region link; 26 - struct dss_io_region p0; 27 - }; 28 - 29 - /** 30 - * struct dp_ctrl_resource - controller's IO related data 31 - * 32 - * @dp_controller: Display Port controller mapped memory address 33 - * @phy_io: phy's mapped memory address 34 - */ 35 - struct dp_io { 36 - struct dss_io_data dp_controller; 37 - struct phy *phy; 38 - }; 39 - 40 17 /** 41 18 * struct dp_parser - DP parser's data exposed to clients 42 19 * 43 20 * @pdev: platform data of the client 21 + * @phy: PHY handle 44 22 */ 45 23 struct dp_parser { 46 24 struct platform_device *pdev; 47 - struct dp_io io; 25 + struct phy *phy; 48 26 u32 max_dp_lanes; 49 27 u32 max_dp_link_rate; 50 28 struct drm_bridge *next_bridge;