1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* Copyright (c) 2024 Hisilicon Limited. */ 3 4 #ifndef DP_COMM_H 5 #define DP_COMM_H 6 7 #include <linux/types.h> 8 #include <linux/bitops.h> 9 #include <linux/errno.h> 10 #include <linux/mutex.h> 11 #include <linux/kernel.h> 12 #include <linux/bitfield.h> 13 #include <linux/io.h> 14 #include <drm/display/drm_dp_helper.h> 15 16 #define HIBMC_DP_LANE_NUM_MAX 2 17 18 struct hibmc_link_status { 19 bool clock_recovered; 20 bool channel_equalized; 21 }; 22 23 struct hibmc_link_cap { 24 u8 link_rate; 25 u8 lanes; 26 }; 27 28 struct hibmc_dp_link { 29 struct hibmc_link_status status; 30 u8 train_set[HIBMC_DP_LANE_NUM_MAX]; 31 struct hibmc_link_cap cap; 32 }; 33 34 struct hibmc_dp_dev { 35 struct drm_dp_aux aux; 36 struct drm_device *dev; 37 void __iomem *base; 38 struct mutex lock; /* protects concurrent RW in hibmc_dp_reg_write_field() */ 39 struct hibmc_dp_link link; 40 u8 dpcd[DP_RECEIVER_CAP_SIZE]; 41 }; 42 43 #define dp_field_modify(reg_value, mask, val) \ 44 do { \ 45 (reg_value) &= ~(mask); \ 46 (reg_value) |= FIELD_PREP(mask, val); \ 47 } while (0) \ 48 49 #define hibmc_dp_reg_write_field(dp, offset, mask, val) \ 50 do { \ 51 typeof(dp) _dp = dp; \ 52 typeof(_dp->base) addr = (_dp->base + (offset)); \ 53 mutex_lock(&_dp->lock); \ 54 u32 reg_value = readl(addr); \ 55 dp_field_modify(reg_value, mask, val); \ 56 writel(reg_value, addr); \ 57 mutex_unlock(&_dp->lock); \ 58 } while (0) 59 60 void hibmc_dp_aux_init(struct hibmc_dp_dev *dp); 61 int hibmc_dp_link_training(struct hibmc_dp_dev *dp); 62 63 #endif 64