Message ID | 20231029194607.379459-6-suijingfeng@loongson.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/loongson: Submit a mini VBIOS support and a display bridge driver | expand |
Hi Sui, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on linus/master v6.6-rc7 next-20231027] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sui-Jingfeng/drm-loongson-Introduce-a-minimal-support-for-Loongson-VBIOS/20231030-034730 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20231029194607.379459-6-suijingfeng%40loongson.cn patch subject: [PATCH 5/8] drm/loongson: Using vbios for the LS7A2000 output initialization config: loongarch-randconfig-002-20231030 (https://download.01.org/0day-ci/archive/20231030/202310301026.haj8ZOHJ-lkp@intel.com/config) compiler: loongarch64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231030/202310301026.haj8ZOHJ-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202310301026.haj8ZOHJ-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/loongson/lsdc_output_7a2000.c:568:1: warning: no previous prototype for 'ls7a2000_query_output_configuration' [-Wmissing-prototypes] 568 | ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned int pipe) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/loongson/lsdc_output_7a2000.c:498:46: warning: 'ls7a2000_encoder_helper_funcs' defined but not used [-Wunused-const-variable=] 498 | static const struct drm_encoder_helper_funcs ls7a2000_encoder_helper_funcs = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/loongson/lsdc_output_7a2000.c:272:39: warning: 'ls7a2000_encoder_funcs' defined but not used [-Wunused-const-variable=] 272 | static const struct drm_encoder_funcs ls7a2000_encoder_funcs[2] = { | ^~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/loongson/lsdc_output_7a2000.c:201:41: warning: 'ls7a2000_hdmi_connector_funcs' defined but not used [-Wunused-const-variable=] 201 | static const struct drm_connector_funcs ls7a2000_hdmi_connector_funcs[2] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/loongson/lsdc_output_7a2000.c:77:48: warning: 'ls7a2000_connector_helpers' defined but not used [-Wunused-const-variable=] 77 | static const struct drm_connector_helper_funcs ls7a2000_connector_helpers = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/ls7a2000_query_output_configuration +568 drivers/gpu/drm/loongson/lsdc_output_7a2000.c 559 560 /* 561 * For LS7A2000, the built-in VGA encoder is transparent. If there are 562 * external encoder exist, then the internal HDMI encoder MUST be enabled 563 * and initialized. As the internal HDMI encoder is always connected, so 564 * only the transmitters which take HDMI signal (such as HDMI to eDP, HDMI 565 * to LVDS, etc) are usable with. 566 */ 567 const struct lsdc_output_desc * > 568 ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned int pipe) 569 { 570 enum loongson_vbios_encoder_name encoder_name = 0; 571 bool ret; 572 573 ret = loongson_vbios_query_encoder_info(ddev, pipe, NULL, 574 &encoder_name, NULL); 575 if (!ret) 576 goto bailout; 577 578 if (pipe == 0) { 579 switch (encoder_name) { 580 case ENCODER_CHIP_INTERNAL_HDMI: 581 return &ls7a2000_hdmi_pipe0; 582 583 /* 584 * For LS7A2000, the built-in VGA encoder is transparent. 585 */ 586 case ENCODER_CHIP_INTERNAL_VGA: 587 return &ls7a2000_vga_pipe0; 588 589 /* 590 * External display bridge exists, the internal HDMI encoder 591 * MUST be enabled and initialized. Please add a drm bridge 592 * driver, and attach to this encoder. 593 */ 594 default: 595 return &ls7a2000_hdmi_pipe0; 596 } 597 } 598 599 if (pipe == 1) { 600 switch (encoder_name) { 601 case ENCODER_CHIP_INTERNAL_HDMI: 602 return &ls7a2000_hdmi_pipe1; 603 604 /* 605 * External display bridge exists, the internal HDMI encoder 606 * MUST be enabled and initialized. Please add a drm bridge 607 * driver, and attach it to this encoder. 608 */ 609 default: 610 return &ls7a2000_hdmi_pipe1; 611 } 612 } 613 614 bailout: 615 if (pipe == 0) 616 return &ls7a2000_vga_pipe0; 617 618 if (pipe == 1) 619 return &ls7a2000_hdmi_pipe1; 620 621 return NULL; 622 } 623
Hi Sui, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on linus/master v6.6 next-20231106] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sui-Jingfeng/drm-loongson-Introduce-a-minimal-support-for-Loongson-VBIOS/20231030-034730 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20231029194607.379459-6-suijingfeng%40loongson.cn patch subject: [PATCH 5/8] drm/loongson: Using vbios for the LS7A2000 output initialization config: x86_64-randconfig-122-20231102 (https://download.01.org/0day-ci/archive/20231107/202311070048.L62vVvHE-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231107/202311070048.L62vVvHE-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202311070048.L62vVvHE-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/gpu/drm/loongson/lsdc_output_7a2000.c:567:31: sparse: sparse: symbol 'ls7a2000_query_output_configuration' was not declared. Should it be static? vim +/ls7a2000_query_output_configuration +567 drivers/gpu/drm/loongson/lsdc_output_7a2000.c 559 560 /* 561 * For LS7A2000, the built-in VGA encoder is transparent. If there are 562 * external encoder exist, then the internal HDMI encoder MUST be enabled 563 * and initialized. As the internal HDMI encoder is always connected, so 564 * only the transmitters which take HDMI signal (such as HDMI to eDP, HDMI 565 * to LVDS, etc) are usable with. 566 */ > 567 const struct lsdc_output_desc * 568 ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned int pipe) 569 { 570 enum loongson_vbios_encoder_name encoder_name = 0; 571 bool ret; 572 573 ret = loongson_vbios_query_encoder_info(ddev, pipe, NULL, 574 &encoder_name, NULL); 575 if (!ret) 576 goto bailout; 577 578 if (pipe == 0) { 579 switch (encoder_name) { 580 case ENCODER_CHIP_INTERNAL_HDMI: 581 return &ls7a2000_hdmi_pipe0; 582 583 /* 584 * For LS7A2000, the built-in VGA encoder is transparent. 585 */ 586 case ENCODER_CHIP_INTERNAL_VGA: 587 return &ls7a2000_vga_pipe0; 588 589 /* 590 * External display bridge exists, the internal HDMI encoder 591 * MUST be enabled and initialized. Please add a drm bridge 592 * driver, and attach to this encoder. 593 */ 594 default: 595 return &ls7a2000_hdmi_pipe0; 596 } 597 } 598 599 if (pipe == 1) { 600 switch (encoder_name) { 601 case ENCODER_CHIP_INTERNAL_HDMI: 602 return &ls7a2000_hdmi_pipe1; 603 604 /* 605 * External display bridge exists, the internal HDMI encoder 606 * MUST be enabled and initialized. Please add a drm bridge 607 * driver, and attach it to this encoder. 608 */ 609 default: 610 return &ls7a2000_hdmi_pipe1; 611 } 612 } 613 614 bailout: 615 if (pipe == 0) 616 return &ls7a2000_vga_pipe0; 617 618 if (pipe == 1) 619 return &ls7a2000_hdmi_pipe1; 620 621 return NULL; 622 } 623
diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c index ce3dabec887e..bf558b61802b 100644 --- a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c +++ b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c @@ -501,6 +501,126 @@ static const struct drm_encoder_helper_funcs ls7a2000_encoder_helper_funcs = { .atomic_mode_set = ls7a2000_hdmi_atomic_mode_set, }; +/* The built-in tranparent VGA encoder is only available on display pipe 0 */ +static void ls7a2000_pipe0_vga_encoder_reset(struct drm_encoder *encoder) +{ + struct lsdc_device *ldev = to_lsdc(encoder->dev); + u32 val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN; + + lsdc_wreg32(ldev, LSDC_CRTC0_DVO_CONF_REG, val); + + /* + * The firmware set LSDC_HDMIx_CTRL_REG blindly to use hardware I2C, + * which is may not works because of hardware bug. We using built-in + * GPIO emulated I2C instead of the hardware I2C here. + */ + lsdc_ureg32_clr(ldev, LSDC_HDMI0_INTF_CTRL_REG, HW_I2C_EN); + + mdelay(20); +} + +static const struct drm_encoder_funcs ls7a2000_pipe0_vga_encoder_funcs = { + .reset = ls7a2000_pipe0_vga_encoder_reset, + .destroy = drm_encoder_cleanup, +}; + +static const struct lsdc_output_desc ls7a2000_vga_pipe0 = { + .pipe = 0, + .encoder_type = DRM_MODE_ENCODER_DAC, + .connector_type = DRM_MODE_CONNECTOR_VGA, + .encoder_funcs = &ls7a2000_pipe0_vga_encoder_funcs, + .encoder_helper_funcs = &lsdc_pipe0_hdmi_encoder_helper_funcs, + .connector_funcs = &lsdc_connector_funcs, + .connector_helper_funcs = &lsdc_connector_helper_funcs, + .name = "VGA-0", +}; + +static const struct lsdc_output_desc ls7a2000_hdmi_pipe0 = { + .pipe = 0, + .encoder_type = DRM_MODE_ENCODER_TMDS, + .connector_type = DRM_MODE_CONNECTOR_HDMIA, + .encoder_funcs = &lsdc_pipe0_hdmi_encoder_funcs, + .encoder_helper_funcs = &lsdc_pipe0_hdmi_encoder_helper_funcs, + .connector_funcs = &lsdc_pipe0_hdmi_connector_funcs, + .connector_helper_funcs = &lsdc_connector_helper_funcs, + .name = "HDMI-0", +}; + +static const struct lsdc_output_desc ls7a2000_hdmi_pipe1 = { + .pipe = 1, + .encoder_type = DRM_MODE_ENCODER_TMDS, + .connector_type = DRM_MODE_CONNECTOR_HDMIA, + .encoder_funcs = &lsdc_pipe1_hdmi_encoder_funcs, + .encoder_helper_funcs = &lsdc_pipe1_hdmi_encoder_helper_funcs, + .connector_funcs = &lsdc_pipe1_hdmi_connector_funcs, + .connector_helper_funcs = &lsdc_connector_helper_funcs, + .name = "HDMI-1", +}; + +/* + * For LS7A2000, the built-in VGA encoder is transparent. If there are + * external encoder exist, then the internal HDMI encoder MUST be enabled + * and initialized. As the internal HDMI encoder is always connected, so + * only the transmitters which take HDMI signal (such as HDMI to eDP, HDMI + * to LVDS, etc) are usable with. + */ +const struct lsdc_output_desc * +ls7a2000_query_output_configuration(struct drm_device *ddev, unsigned int pipe) +{ + enum loongson_vbios_encoder_name encoder_name = 0; + bool ret; + + ret = loongson_vbios_query_encoder_info(ddev, pipe, NULL, + &encoder_name, NULL); + if (!ret) + goto bailout; + + if (pipe == 0) { + switch (encoder_name) { + case ENCODER_CHIP_INTERNAL_HDMI: + return &ls7a2000_hdmi_pipe0; + + /* + * For LS7A2000, the built-in VGA encoder is transparent. + */ + case ENCODER_CHIP_INTERNAL_VGA: + return &ls7a2000_vga_pipe0; + + /* + * External display bridge exists, the internal HDMI encoder + * MUST be enabled and initialized. Please add a drm bridge + * driver, and attach to this encoder. + */ + default: + return &ls7a2000_hdmi_pipe0; + } + } + + if (pipe == 1) { + switch (encoder_name) { + case ENCODER_CHIP_INTERNAL_HDMI: + return &ls7a2000_hdmi_pipe1; + + /* + * External display bridge exists, the internal HDMI encoder + * MUST be enabled and initialized. Please add a drm bridge + * driver, and attach it to this encoder. + */ + default: + return &ls7a2000_hdmi_pipe1; + } + } + +bailout: + if (pipe == 0) + return &ls7a2000_vga_pipe0; + + if (pipe == 1) + return &ls7a2000_hdmi_pipe1; + + return NULL; +} + /* * For LS7A2000: * @@ -517,36 +637,10 @@ int ls7a2000_output_init(struct drm_device *ddev, unsigned int pipe) { struct lsdc_output *output = &dispipe->output; - struct drm_encoder *encoder = &output->encoder; - struct drm_connector *connector = &output->connector; - int ret; - - ret = drm_encoder_init(ddev, encoder, &ls7a2000_encoder_funcs[pipe], - DRM_MODE_ENCODER_TMDS, "encoder-%u", pipe); - if (ret) - return ret; - - encoder->possible_crtcs = BIT(pipe); - - drm_encoder_helper_add(encoder, &ls7a2000_encoder_helper_funcs); - - ret = drm_connector_init_with_ddc(ddev, connector, - &ls7a2000_hdmi_connector_funcs[pipe], - DRM_MODE_CONNECTOR_HDMIA, ddc); - if (ret) - return ret; - drm_info(ddev, "display pipe-%u has HDMI %s\n", pipe, pipe ? "" : "and/or VGA"); + output->descp = ls7a2000_query_output_configuration(ddev, pipe); + if (!output->descp) + return -EINVAL; - drm_connector_helper_add(connector, &ls7a2000_connector_helpers); - - drm_connector_attach_encoder(connector, encoder); - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT; - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - return 0; + return lsdc_output_init(ddev, dispipe, ddc, pipe); }
For LS7A2000, the built-in VGA encoder is transparent. Connect another external transmitter with this internal VGA encoder is not sane, thus is not allowed. Because there are two internal encoders hardware resource on the first display pipe, call loongson_vbios_query_encoder_info() to know what exatly the output configutaion is. Either VGA or HDMI display output interface, but not both. And formal products should not export three display connector interfaces. As the hardware has two-way I2Cs and two CRTCs. So with this observation, we can untangle more. If there a need to extend(transform) the output interface type, then the internal HDMI phy MUST be enabled and initialized. External transmitters must take the HDMI signal as input, this is the only choices. Such as lt6711(HDMI to eDP), lt8619(HDMI to LVDS) etc. Before apply this patch, ls7a2000_output_init() is simplified function which assumed that there is no external display bridge attached. This naive abstraction no longer suit the needs in the long run. Hence, switch to call the newly implemented lsdc_output_init() function, which allow us model the external encoder as a drm display bridge. The driver of this drm display bridge should reside in the same kernel module with drm/loongson. We will attach it by ourself, and rely on the VBIOS tell us which display pipe has what display bridge connected. Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn> --- drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 154 ++++++++++++++---- 1 file changed, 124 insertions(+), 30 deletions(-)