@@ -377,6 +377,189 @@ static void dwc2_get_device_properties(struct dwc2_hsotg *hsotg)
377377 }
378378}
379379
380+ static void dwc2_check_param_otg_cap (struct dwc2_hsotg * hsotg )
381+ {
382+ int valid = 1 ;
383+
384+ switch (hsotg -> params .otg_cap ) {
385+ case DWC2_CAP_PARAM_HNP_SRP_CAPABLE :
386+ if (hsotg -> hw_params .op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE )
387+ valid = 0 ;
388+ break ;
389+ case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE :
390+ switch (hsotg -> hw_params .op_mode ) {
391+ case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE :
392+ case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE :
393+ case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE :
394+ case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST :
395+ break ;
396+ default :
397+ valid = 0 ;
398+ break ;
399+ }
400+ break ;
401+ case DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE :
402+ /* always valid */
403+ break ;
404+ default :
405+ valid = 0 ;
406+ break ;
407+ }
408+
409+ if (!valid )
410+ dwc2_set_param_otg_cap (hsotg );
411+ }
412+
413+ static void dwc2_check_param_phy_type (struct dwc2_hsotg * hsotg )
414+ {
415+ int valid = 0 ;
416+ u32 hs_phy_type ;
417+ u32 fs_phy_type ;
418+
419+ hs_phy_type = hsotg -> hw_params .hs_phy_type ;
420+ fs_phy_type = hsotg -> hw_params .fs_phy_type ;
421+
422+ switch (hsotg -> params .phy_type ) {
423+ case DWC2_PHY_TYPE_PARAM_FS :
424+ if (fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED )
425+ valid = 1 ;
426+ break ;
427+ case DWC2_PHY_TYPE_PARAM_UTMI :
428+ if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ) ||
429+ (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI ))
430+ valid = 1 ;
431+ break ;
432+ case DWC2_PHY_TYPE_PARAM_ULPI :
433+ if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ) ||
434+ (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI ))
435+ valid = 1 ;
436+ break ;
437+ default :
438+ break ;
439+ }
440+
441+ if (!valid )
442+ dwc2_set_param_phy_type (hsotg );
443+ }
444+
445+ static void dwc2_check_param_speed (struct dwc2_hsotg * hsotg )
446+ {
447+ int valid = 1 ;
448+ int phy_type = hsotg -> params .phy_type ;
449+ int speed = hsotg -> params .speed ;
450+
451+ switch (speed ) {
452+ case DWC2_SPEED_PARAM_HIGH :
453+ if ((hsotg -> params .speed == DWC2_SPEED_PARAM_HIGH ) &&
454+ (phy_type == DWC2_PHY_TYPE_PARAM_FS ))
455+ valid = 0 ;
456+ break ;
457+ case DWC2_SPEED_PARAM_FULL :
458+ case DWC2_SPEED_PARAM_LOW :
459+ break ;
460+ default :
461+ valid = 0 ;
462+ break ;
463+ }
464+
465+ if (!valid )
466+ dwc2_set_param_speed (hsotg );
467+ }
468+
469+ static void dwc2_check_param_phy_utmi_width (struct dwc2_hsotg * hsotg )
470+ {
471+ int valid = 0 ;
472+ int param = hsotg -> params .phy_utmi_width ;
473+ int width = hsotg -> hw_params .utmi_phy_data_width ;
474+
475+ switch (width ) {
476+ case GHWCFG4_UTMI_PHY_DATA_WIDTH_8 :
477+ valid = (param == 8 );
478+ break ;
479+ case GHWCFG4_UTMI_PHY_DATA_WIDTH_16 :
480+ valid = (param == 16 );
481+ break ;
482+ case GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 :
483+ valid = (param == 8 || param == 16 );
484+ break ;
485+ }
486+
487+ if (!valid )
488+ dwc2_set_param_phy_utmi_width (hsotg );
489+ }
490+
491+ #define CHECK_RANGE (_param , _min , _max , _def ) do { \
492+ if ((hsotg->params._param) < (_min) || \
493+ (hsotg->params._param) > (_max)) { \
494+ dev_warn(hsotg->dev, "%s: Invalid parameter %s=%d\n", \
495+ __func__, #_param, hsotg->params._param); \
496+ hsotg->params._param = (_def); \
497+ } \
498+ } while (0)
499+
500+ #define CHECK_BOOL (_param , _check ) do { \
501+ if (hsotg->params._param && !(_check)) { \
502+ dev_warn(hsotg->dev, "%s: Invalid parameter %s=%d\n", \
503+ __func__, #_param, hsotg->params._param); \
504+ hsotg->params._param = false; \
505+ } \
506+ } while (0)
507+
508+ static void dwc2_check_params (struct dwc2_hsotg * hsotg )
509+ {
510+ struct dwc2_hw_params * hw = & hsotg -> hw_params ;
511+ struct dwc2_core_params * p = & hsotg -> params ;
512+ bool dma_capable = !(hw -> arch == GHWCFG2_SLAVE_ONLY_ARCH );
513+
514+ dwc2_check_param_otg_cap (hsotg );
515+ dwc2_check_param_phy_type (hsotg );
516+ dwc2_check_param_speed (hsotg );
517+ dwc2_check_param_phy_utmi_width (hsotg );
518+ CHECK_BOOL (enable_dynamic_fifo , hw -> enable_dynamic_fifo );
519+ CHECK_BOOL (en_multiple_tx_fifo , hw -> en_multiple_tx_fifo );
520+ CHECK_BOOL (i2c_enable , hw -> i2c_enable );
521+ CHECK_BOOL (reload_ctl , (hsotg -> hw_params .snpsid > DWC2_CORE_REV_2_92a ));
522+ CHECK_RANGE (max_packet_count ,
523+ 15 , hw -> max_packet_count ,
524+ hw -> max_packet_count );
525+ CHECK_RANGE (max_transfer_size ,
526+ 2047 , hw -> max_transfer_size ,
527+ hw -> max_transfer_size );
528+
529+ if ((hsotg -> dr_mode == USB_DR_MODE_HOST ) ||
530+ (hsotg -> dr_mode == USB_DR_MODE_OTG )) {
531+ CHECK_BOOL (host_dma , dma_capable );
532+ CHECK_BOOL (dma_desc_enable , p -> host_dma );
533+ CHECK_BOOL (dma_desc_fs_enable , p -> dma_desc_enable );
534+ CHECK_BOOL (host_ls_low_power_phy_clk ,
535+ p -> phy_type == DWC2_PHY_TYPE_PARAM_FS );
536+ CHECK_RANGE (host_channels ,
537+ 1 , hw -> host_channels ,
538+ hw -> host_channels );
539+ CHECK_RANGE (host_rx_fifo_size ,
540+ 16 , hw -> rx_fifo_size ,
541+ hw -> rx_fifo_size );
542+ CHECK_RANGE (host_nperio_tx_fifo_size ,
543+ 16 , hw -> host_nperio_tx_fifo_size ,
544+ hw -> host_nperio_tx_fifo_size );
545+ CHECK_RANGE (host_perio_tx_fifo_size ,
546+ 16 , hw -> host_perio_tx_fifo_size ,
547+ hw -> host_perio_tx_fifo_size );
548+ }
549+
550+ if ((hsotg -> dr_mode == USB_DR_MODE_PERIPHERAL ) ||
551+ (hsotg -> dr_mode == USB_DR_MODE_OTG )) {
552+ CHECK_BOOL (g_dma , dma_capable );
553+ CHECK_BOOL (g_dma_desc , (p -> g_dma && hw -> dma_desc_enable ));
554+ CHECK_RANGE (g_rx_fifo_size ,
555+ 16 , hw -> rx_fifo_size ,
556+ hw -> rx_fifo_size );
557+ CHECK_RANGE (g_np_tx_fifo_size ,
558+ 16 , hw -> dev_nperio_tx_fifo_size ,
559+ hw -> dev_nperio_tx_fifo_size );
560+ }
561+ }
562+
380563/*
381564 * Gets host hardware parameters. Forces host mode if not currently in
382565 * host mode. Should be called immediately after a core soft reset in
@@ -591,5 +774,7 @@ int dwc2_init_params(struct dwc2_hsotg *hsotg)
591774 dwc2_set_default_params (hsotg );
592775 dwc2_get_device_properties (hsotg );
593776
777+ dwc2_check_params (hsotg );
778+
594779 return 0 ;
595780}
0 commit comments