File drivers/gpu/alga/amd/atombios/dce.c changed (mode: 100644) (index 2678caf..5da883c) |
... |
... |
static int default_disp_clk_freq(struct atombios *atb, u32 *clk) |
358 |
358 |
return 0; |
return 0; |
359 |
359 |
} |
} |
360 |
360 |
|
|
361 |
|
static int dp_mode_ext_clk_freq(struct atombios *atb, u16 *clk) |
|
362 |
|
{ |
|
363 |
|
u16 of; |
|
364 |
|
struct master_data_tbl *data_tbl; |
|
365 |
|
struct firmware_info_v2_1 *info; |
|
366 |
|
|
|
367 |
|
of = get_unaligned_le16(&atb->hdr->master_data_tbl_of); |
|
368 |
|
data_tbl = atb->adev.rom + of; |
|
369 |
|
|
|
370 |
|
of = get_unaligned_le16(&data_tbl->list.firmware_info); |
|
371 |
|
info = atb->adev.rom + of; |
|
372 |
|
|
|
373 |
|
if (info->subset.hdr.tbl_fmt_rev != 2 |
|
374 |
|
&& info->subset.hdr.tbl_content_rev != 1) { |
|
375 |
|
dev_err(atb->adev.dev, "atombios: firmware_info (0x%04x) " |
|
376 |
|
"revision %u.%u not supported\n", of, |
|
377 |
|
info->subset.hdr.tbl_fmt_rev, |
|
378 |
|
info->subset.hdr.tbl_content_rev); |
|
379 |
|
return -ATB_ERR; |
|
380 |
|
} |
|
381 |
|
*clk = get_unaligned_le16(&info->uniphy_dp_mode_ext_clk_freq); |
|
382 |
|
return 0; |
|
383 |
|
} |
|
384 |
|
|
|
385 |
361 |
int atb_crtc_blank(struct atombios *atb, unsigned i, bool on) |
int atb_crtc_blank(struct atombios *atb, unsigned i, bool on) |
386 |
362 |
{ |
{ |
387 |
363 |
u16 of; |
u16 of; |
|
... |
... |
int atb_crtc_dcpll(struct atombios *atb) |
569 |
545 |
goto unlock_mutex; |
goto unlock_mutex; |
570 |
546 |
} |
} |
571 |
547 |
|
|
572 |
|
/* |
|
573 |
|
* if the default dcpll clock is specified, pixel_clk_set provides the |
|
574 |
|
* dividers |
|
575 |
|
*/ |
|
|
548 |
|
/* defaults to ppll0, then dividers are provided */ |
576 |
549 |
put_unaligned_le16((u16)clk_freq, &ps->disp_eng_clk); |
put_unaligned_le16((u16)clk_freq, &ps->disp_eng_clk); |
577 |
|
ps->ppll = PPLL0; |
|
|
550 |
|
ps->ppll = PIXEL_CLK_SET_PPLL0; |
578 |
551 |
|
|
579 |
552 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
580 |
553 |
atb->g_ctx.regs_blk = 0; |
atb->g_ctx.regs_blk = 0; |
|
... |
... |
int atb_crtc_virtual_pixel_clk(struct atombios *atb, unsigned i, unsigned clk) |
626 |
599 |
ps = (struct pixel_clk_set_params *)atb->g_ctx.ps_top; |
ps = (struct pixel_clk_set_params *)atb->g_ctx.ps_top; |
627 |
600 |
put_unaligned_le16(SET(CRTC, i) | SET(PIXEL_CLK, clk / 10), |
put_unaligned_le16(SET(CRTC, i) | SET(PIXEL_CLK, clk / 10), |
628 |
601 |
&ps->crtc_pixel_clk); |
&ps->crtc_pixel_clk); |
629 |
|
ps->ppll = PPLL_INVALID; /* invalid pll id for dp virtual pixel clk */ |
|
|
602 |
|
/* real pll used to compute the virtual dp clock: always ppll0 on si */ |
|
603 |
|
ps->ppll = PIXEL_CLK_SET_PPLL0; |
630 |
604 |
|
|
631 |
605 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
632 |
606 |
atb->g_ctx.regs_blk = 0; |
atb->g_ctx.regs_blk = 0; |
|
... |
... |
static int trans_link(struct atombios *atb, struct trans_ctl_params *ps) |
670 |
644 |
"space (stack)\n"); |
"space (stack)\n"); |
671 |
645 |
return -ATB_ERR; |
return -ATB_ERR; |
672 |
646 |
} |
} |
|
647 |
|
/* always ppll0 on si */ |
|
648 |
|
ps->cfg |= SET(TRANS_CFG_CLK_REF_ID, TRANS_CFG_PPLL0); |
673 |
649 |
memcpy(atb->g_ctx.ps_top, ps, sizeof(*ps)); |
memcpy(atb->g_ctx.ps_top, ps, sizeof(*ps)); |
674 |
650 |
|
|
675 |
651 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
|
... |
... |
static int trans_link(struct atombios *atb, struct trans_ctl_params *ps) |
681 |
657 |
return r; |
return r; |
682 |
658 |
} |
} |
683 |
659 |
|
|
684 |
|
int atb_enc_video(struct atombios *atb, unsigned i, bool on) |
|
|
660 |
|
int atb_enc_video(struct atombios *atb, unsigned i, u8 hpd, bool on) |
685 |
661 |
{ |
{ |
686 |
662 |
u16 of; |
u16 of; |
687 |
663 |
struct master_cmd_tbl *cmd_tbl; |
struct master_cmd_tbl *cmd_tbl; |
|
... |
... |
int atb_enc_video(struct atombios *atb, unsigned i, bool on) |
702 |
678 |
|
|
703 |
679 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
704 |
680 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
705 |
|
&& enc_ctl->hdr.tbl_content_rev != 3)) { |
|
|
681 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
706 |
682 |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
707 |
683 |
"supported"); |
"supported"); |
708 |
684 |
r = -ATB_ERR; |
r = -ATB_ERR; |
|
... |
... |
int atb_enc_video(struct atombios *atb, unsigned i, bool on) |
718 |
694 |
} |
} |
719 |
695 |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
720 |
696 |
if (on) |
if (on) |
721 |
|
ps->action = ENC_ACTION_DP_VIDEO_ON; |
|
|
697 |
|
ps->action = ENC_CTL_ACTION_DP_VIDEO_ON; |
722 |
698 |
else |
else |
723 |
|
ps->action = ENC_ACTION_DP_VIDEO_OFF; |
|
724 |
|
ps->cfg = (i << ENC_CFG_SEL_SHIFT); |
|
|
699 |
|
ps->action = ENC_CTL_ACTION_DP_VIDEO_OFF; |
|
700 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
701 |
|
if (hpd != 0xff) /* no hpd */ |
|
702 |
|
ps->hpd = hpd + 1; |
725 |
703 |
|
|
726 |
704 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
727 |
705 |
atb->g_ctx.regs_blk = 0; |
atb->g_ctx.regs_blk = 0; |
|
... |
... |
unlock_mutex: |
736 |
714 |
} |
} |
737 |
715 |
EXPORT_SYMBOL_GPL(atb_enc_video); |
EXPORT_SYMBOL_GPL(atb_enc_video); |
738 |
716 |
|
|
739 |
|
int atb_enc_dp_training_start(struct atombios *atb, unsigned i) |
|
|
717 |
|
int atb_enc_dp_training_start(struct atombios *atb, unsigned i, u8 hpd) |
740 |
718 |
{ |
{ |
741 |
719 |
u16 of; |
u16 of; |
742 |
720 |
struct master_cmd_tbl *cmd_tbl; |
struct master_cmd_tbl *cmd_tbl; |
|
... |
... |
int atb_enc_dp_training_start(struct atombios *atb, unsigned i) |
757 |
735 |
|
|
758 |
736 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
759 |
737 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
760 |
|
&& enc_ctl->hdr.tbl_content_rev != 3)) { |
|
|
738 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
761 |
739 |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
762 |
740 |
"supported"); |
"supported"); |
763 |
741 |
r = -ATB_ERR; |
r = -ATB_ERR; |
|
... |
... |
int atb_enc_dp_training_start(struct atombios *atb, unsigned i) |
772 |
750 |
return -ATB_ERR; |
return -ATB_ERR; |
773 |
751 |
} |
} |
774 |
752 |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
775 |
|
ps->action = ENC_ACTION_DP_LINK_TRAINING_START; |
|
776 |
|
ps->cfg = (i << ENC_CFG_SEL_SHIFT); |
|
|
753 |
|
ps->action = ENC_CTL_ACTION_DP_LINK_TRAINING_START; |
|
754 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
755 |
|
if (hpd != 0xff) /* no hpd */ |
|
756 |
|
ps->hpd = hpd + 1; |
777 |
757 |
|
|
778 |
758 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
779 |
759 |
atb->g_ctx.regs_blk = 0; |
atb->g_ctx.regs_blk = 0; |
|
... |
... |
unlock_mutex: |
788 |
768 |
} |
} |
789 |
769 |
EXPORT_SYMBOL_GPL(atb_enc_dp_training_start); |
EXPORT_SYMBOL_GPL(atb_enc_dp_training_start); |
790 |
770 |
|
|
791 |
|
int atb_enc_dp_training_complete(struct atombios *atb, unsigned i) |
|
|
771 |
|
int atb_enc_dp_training_complete(struct atombios *atb, unsigned i, u8 hpd) |
792 |
772 |
{ |
{ |
793 |
773 |
u16 of; |
u16 of; |
794 |
774 |
struct master_cmd_tbl *cmd_tbl; |
struct master_cmd_tbl *cmd_tbl; |
|
... |
... |
int atb_enc_dp_training_complete(struct atombios *atb, unsigned i) |
808 |
788 |
|
|
809 |
789 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
810 |
790 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
811 |
|
&& enc_ctl->hdr.tbl_content_rev != 3)) { |
|
|
791 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
812 |
792 |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
813 |
793 |
"supported"); |
"supported"); |
814 |
794 |
r = -ATB_ERR; |
r = -ATB_ERR; |
|
... |
... |
int atb_enc_dp_training_complete(struct atombios *atb, unsigned i) |
823 |
803 |
return -ATB_ERR; |
return -ATB_ERR; |
824 |
804 |
} |
} |
825 |
805 |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
826 |
|
ps->action = ENC_ACTION_DP_LINK_TRAINING_COMPLETE; |
|
827 |
|
ps->cfg = (i << ENC_CFG_SEL_SHIFT); |
|
|
806 |
|
ps->action = ENC_CTL_ACTION_DP_LINK_TRAINING_COMPLETE; |
|
807 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
808 |
|
if (hpd != 0xff) /* no hpd */ |
|
809 |
|
ps->hpd = hpd + 1; |
828 |
810 |
|
|
829 |
811 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
830 |
812 |
atb->g_ctx.regs_blk = 0; |
atb->g_ctx.regs_blk = 0; |
|
... |
... |
unlock_mutex: |
839 |
821 |
} |
} |
840 |
822 |
EXPORT_SYMBOL_GPL(atb_enc_dp_training_complete); |
EXPORT_SYMBOL_GPL(atb_enc_dp_training_complete); |
841 |
823 |
|
|
842 |
|
int atb_enc_dp_tp(struct atombios *atb, unsigned i, unsigned link_rate, |
|
|
824 |
|
int atb_enc_dp_tp(struct atombios *atb, unsigned i, u8 hpd, unsigned link_rate, |
843 |
825 |
unsigned lanes_n, unsigned tp) |
unsigned lanes_n, unsigned tp) |
844 |
826 |
{ |
{ |
845 |
827 |
u16 of; |
u16 of; |
|
... |
... |
int atb_enc_dp_tp(struct atombios *atb, unsigned i, unsigned link_rate, |
860 |
842 |
|
|
861 |
843 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
862 |
844 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
863 |
|
&& enc_ctl->hdr.tbl_content_rev != 3)) { |
|
|
845 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
864 |
846 |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
dev_err(atb->adev.dev, "atombios: enc_ctl revision not " |
865 |
847 |
"supported"); |
"supported"); |
866 |
848 |
r = -ATB_ERR; |
r = -ATB_ERR; |
|
... |
... |
int atb_enc_dp_tp(struct atombios *atb, unsigned i, unsigned link_rate, |
878 |
860 |
|
|
879 |
861 |
switch (tp) { |
switch (tp) { |
880 |
862 |
case 1: |
case 1: |
881 |
|
ps->action = ENC_ACTION_DP_LINK_TRAINING_PATTERN1; |
|
|
863 |
|
ps->action = ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_1; |
882 |
864 |
break; |
break; |
883 |
865 |
case 2: |
case 2: |
884 |
|
ps->action = ENC_ACTION_DP_LINK_TRAINING_PATTERN2; |
|
|
866 |
|
ps->action = ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_2; |
885 |
867 |
break; |
break; |
886 |
868 |
case 3: |
case 3: |
887 |
|
ps->action = ENC_ACTION_DP_LINK_TRAINING_PATTERN3; |
|
|
869 |
|
ps->action = ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_3; |
888 |
870 |
break; |
break; |
889 |
871 |
default: |
default: |
890 |
872 |
dev_err(atb->adev.dev, "atombios: unknown dp training pattern " |
dev_err(atb->adev.dev, "atombios: unknown dp training pattern " |
|
... |
... |
int atb_enc_dp_tp(struct atombios *atb, unsigned i, unsigned link_rate, |
892 |
874 |
r = -ATB_ERR; |
r = -ATB_ERR; |
893 |
875 |
goto free_ps; |
goto free_ps; |
894 |
876 |
} |
} |
895 |
|
ps->cfg = (i << ENC_CFG_SEL_SHIFT); |
|
|
877 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
878 |
|
if (hpd != 0xff) /* no hpd */ |
|
879 |
|
ps->hpd = hpd + 1; |
896 |
880 |
ps->lanes_n = lanes_n; |
ps->lanes_n = lanes_n; |
897 |
881 |
switch (link_rate) {/* multiple of 270MHz */ |
switch (link_rate) {/* multiple of 270MHz */ |
898 |
882 |
case 6: |
case 6: |
899 |
|
ps->cfg |= ENC_CFG_LINK_RATE_1_62_GHZ; |
|
|
883 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_1_62_GHZ; |
900 |
884 |
break; |
break; |
901 |
885 |
case 10: |
case 10: |
902 |
|
ps->cfg |= ENC_CFG_LINK_RATE_2_7_GHZ; |
|
|
886 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_2_70_GHZ; |
|
887 |
|
break; |
|
888 |
|
case 12: |
|
889 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_3_24_GHZ; |
903 |
890 |
break; |
break; |
904 |
891 |
case 20: |
case 20: |
905 |
|
ps->cfg |= ENC_CFG_LINK_CATE_5_4_GHZ; |
|
|
892 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_5_40_GHZ; |
906 |
893 |
break; |
break; |
907 |
894 |
} |
} |
908 |
895 |
|
|
|
... |
... |
unlock_mutex: |
921 |
908 |
} |
} |
922 |
909 |
EXPORT_SYMBOL_GPL(atb_enc_dp_tp); |
EXPORT_SYMBOL_GPL(atb_enc_dp_tp); |
923 |
910 |
|
|
924 |
|
int atb_enc_setup(struct atombios *atb, unsigned i, unsigned dp_lanes_n, |
|
|
911 |
|
int atb_enc_setup(struct atombios *atb, unsigned i, u8 hpd, unsigned dp_lanes_n, |
925 |
912 |
unsigned dp_link_rate, unsigned bpc, unsigned pixel_clk) |
unsigned dp_link_rate, unsigned bpc, unsigned pixel_clk) |
926 |
913 |
|
|
927 |
914 |
{ |
{ |
|
... |
... |
int atb_enc_setup(struct atombios *atb, unsigned i, unsigned dp_lanes_n, |
943 |
930 |
|
|
944 |
931 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
945 |
932 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|| (enc_ctl->hdr.tbl_content_rev != 2 |
946 |
|
&& enc_ctl->hdr.tbl_content_rev != 3)) { |
|
|
933 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
947 |
934 |
dev_err(atb->adev.dev, "atombios: enc_video revision not " |
dev_err(atb->adev.dev, "atombios: enc_video revision not " |
948 |
935 |
"supported"); |
"supported"); |
949 |
936 |
r = -ATB_ERR; |
r = -ATB_ERR; |
|
... |
... |
int atb_enc_setup(struct atombios *atb, unsigned i, unsigned dp_lanes_n, |
959 |
946 |
} |
} |
960 |
947 |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
961 |
948 |
|
|
962 |
|
ps->cfg = (i << ENC_CFG_SEL_SHIFT); |
|
963 |
|
ps->action = ENC_ACTION_SETUP; |
|
|
949 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
950 |
|
if (hpd != 0xff) /* no hpd */ |
|
951 |
|
ps->hpd = hpd + 1; |
|
952 |
|
ps->action = ENC_CTL_ACTION_SETUP; |
964 |
953 |
put_unaligned_le16((u16)(pixel_clk / 10), &ps->pixel_clk); |
put_unaligned_le16((u16)(pixel_clk / 10), &ps->pixel_clk); |
965 |
954 |
switch (dp_link_rate) {/* multiple of 270MHz */ |
switch (dp_link_rate) {/* multiple of 270MHz */ |
966 |
955 |
case 6: |
case 6: |
967 |
|
ps->cfg |= ENC_CFG_LINK_RATE_1_62_GHZ; |
|
|
956 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_1_62_GHZ; |
968 |
957 |
break; |
break; |
969 |
958 |
case 10: |
case 10: |
970 |
|
ps->cfg |= ENC_CFG_LINK_RATE_2_7_GHZ; |
|
|
959 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_2_70_GHZ; |
|
960 |
|
break; |
|
961 |
|
case 12: |
|
962 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_3_24_GHZ; |
971 |
963 |
break; |
break; |
972 |
964 |
case 20: |
case 20: |
973 |
|
ps->cfg |= ENC_CFG_LINK_CATE_5_4_GHZ; |
|
|
965 |
|
ps->cfg |= ENC_CTL_CFG_LINK_RATE_5_40_GHZ; |
974 |
966 |
break; |
break; |
975 |
967 |
} |
} |
976 |
968 |
ps->lanes_n = dp_lanes_n; |
ps->lanes_n = dp_lanes_n; |
977 |
969 |
switch (bpc) { |
switch (bpc) { |
978 |
970 |
case 0: |
case 0: |
979 |
|
ps->bpc = ENC_BPC_UNDEFINE; |
|
|
971 |
|
ps->bpc = ENC_CTL_BPC_UNDEFINE; |
980 |
972 |
break; |
break; |
981 |
973 |
case 6: |
case 6: |
982 |
|
ps->bpc = ENC_6BITS_PER_COLOR; |
|
|
974 |
|
ps->bpc = ENC_CTL_6BITS_PER_COLOR; |
983 |
975 |
break; |
break; |
984 |
976 |
case 8: |
case 8: |
985 |
|
ps->bpc = ENC_8BITS_PER_COLOR; |
|
|
977 |
|
ps->bpc = ENC_CTL_8BITS_PER_COLOR; |
986 |
978 |
break; |
break; |
987 |
979 |
case 10: |
case 10: |
988 |
|
ps->bpc = ENC_10BITS_PER_COLOR; |
|
|
980 |
|
ps->bpc = ENC_CTL_10BITS_PER_COLOR; |
989 |
981 |
break; |
break; |
990 |
982 |
case 12: |
case 12: |
991 |
|
ps->bpc = ENC_12BITS_PER_COLOR; |
|
|
983 |
|
ps->bpc = ENC_CTL_12BITS_PER_COLOR; |
992 |
984 |
break; |
break; |
993 |
985 |
case 16: |
case 16: |
994 |
|
ps->bpc = ENC_16BITS_PER_COLOR; |
|
|
986 |
|
ps->bpc = ENC_CTL_16BITS_PER_COLOR; |
995 |
987 |
break; |
break; |
996 |
988 |
}; |
}; |
997 |
989 |
|
|
|
... |
... |
unlock_mutex: |
1008 |
1000 |
} |
} |
1009 |
1001 |
EXPORT_SYMBOL_GPL(atb_enc_setup); |
EXPORT_SYMBOL_GPL(atb_enc_setup); |
1010 |
1002 |
|
|
|
1003 |
|
int atb_enc_setup_panel_mode(struct atombios *atb, unsigned i, u8 hpd) |
|
1004 |
|
{ |
|
1005 |
|
u16 of; |
|
1006 |
|
struct master_cmd_tbl *cmd_tbl; |
|
1007 |
|
struct common_cmd_tbl_hdr *enc_ctl; |
|
1008 |
|
struct enc_ctl_params *ps; |
|
1009 |
|
int r; |
|
1010 |
|
|
|
1011 |
|
mutex_lock(&atb->mutex); |
|
1012 |
|
|
|
1013 |
|
of = get_unaligned_le16(&atb->hdr->master_cmd_tbl_of); |
|
1014 |
|
cmd_tbl = atb->adev.rom + of; |
|
1015 |
|
of = get_unaligned_le16(&cmd_tbl->list.enc_ctl); |
|
1016 |
|
|
|
1017 |
|
enc_ctl = atb->adev.rom + of; |
|
1018 |
|
dev_info(atb->adev.dev, "atombios: enc_video (0x%04x) revision %u.%u\n", |
|
1019 |
|
of, enc_ctl->hdr.tbl_fmt_rev, enc_ctl->hdr.tbl_content_rev); |
|
1020 |
|
|
|
1021 |
|
if (enc_ctl->hdr.tbl_fmt_rev != 1 |
|
1022 |
|
|| (enc_ctl->hdr.tbl_content_rev != 2 |
|
1023 |
|
&& enc_ctl->hdr.tbl_content_rev != 4)) { |
|
1024 |
|
dev_err(atb->adev.dev, "atombios: enc_video revision not " |
|
1025 |
|
"supported"); |
|
1026 |
|
r = -ATB_ERR; |
|
1027 |
|
goto unlock_mutex; |
|
1028 |
|
} |
|
1029 |
|
|
|
1030 |
|
atb->g_ctx.ps_dws = 0x80;/* max for ps index */ |
|
1031 |
|
atb->g_ctx.ps_top = kzalloc(atb->g_ctx.ps_dws * 4, GFP_KERNEL); |
|
1032 |
|
if (!atb->g_ctx.ps_top) { |
|
1033 |
|
dev_err(atb->adev.dev, "atombios: unable to allocate parameter " |
|
1034 |
|
" space (stack)\n"); |
|
1035 |
|
return -ATB_ERR; |
|
1036 |
|
} |
|
1037 |
|
ps = (struct enc_ctl_params *)atb->g_ctx.ps_top; |
|
1038 |
|
|
|
1039 |
|
ps->cfg = SET(ENC_CTL_CFG_ENC, i); |
|
1040 |
|
if (hpd != 0xff) /* no hpd */ |
|
1041 |
|
ps->hpd = hpd + 1; |
|
1042 |
|
ps->action = ENC_CTL_ACTION_SETUP_PANEL_MODE; |
|
1043 |
|
|
|
1044 |
|
atb->g_ctx.fb_wnd = 0; |
|
1045 |
|
atb->g_ctx.regs_blk = 0; |
|
1046 |
|
atb->g_ctx.io_mode = IO_MM; |
|
1047 |
|
|
|
1048 |
|
r = interpret(atb, of, 0, 0); |
|
1049 |
|
kfree(atb->g_ctx.ps_top); |
|
1050 |
|
|
|
1051 |
|
unlock_mutex: |
|
1052 |
|
mutex_unlock(&atb->mutex); |
|
1053 |
|
return r; |
|
1054 |
|
} |
|
1055 |
|
EXPORT_SYMBOL_GPL(atb_enc_setup_panel_mode); |
|
1056 |
|
|
1011 |
1057 |
int atb_trans_link_pwr(struct atombios *atb, unsigned i, bool on) |
int atb_trans_link_pwr(struct atombios *atb, unsigned i, bool on) |
1012 |
1058 |
{ |
{ |
1013 |
1059 |
struct trans_ctl_params ps; |
struct trans_ctl_params ps; |
|
... |
... |
int atb_trans_link_off(struct atombios *atb, unsigned i) |
1047 |
1093 |
} |
} |
1048 |
1094 |
EXPORT_SYMBOL_GPL(atb_trans_link_off); |
EXPORT_SYMBOL_GPL(atb_trans_link_off); |
1049 |
1095 |
|
|
1050 |
|
static int trans_link_clk_ref(struct atombios *atb, struct trans_ctl_params *ps) |
|
1051 |
|
{ |
|
1052 |
|
int r; |
|
1053 |
|
u16 dp_ext_clk; |
|
1054 |
|
|
|
1055 |
|
r = dp_mode_ext_clk_freq(atb, &dp_ext_clk); |
|
1056 |
|
if (r != 0) |
|
1057 |
|
return r; |
|
1058 |
|
|
|
1059 |
|
/* |
|
1060 |
|
* the reference clock is external or generated by one of the internal |
|
1061 |
|
* plls (we use p0pll) |
|
1062 |
|
*/ |
|
1063 |
|
if (dp_ext_clk > 0) { |
|
1064 |
|
ps->cfg |= SET(TRANS_CFG_CLK_REF_ID, TRANS_CFG_EXT); |
|
1065 |
|
dev_info(atb->adev.dev, "atombios: transmitter link uses" |
|
1066 |
|
" external clock\n"); |
|
1067 |
|
} else { |
|
1068 |
|
ps->cfg |= SET(TRANS_CFG_CLK_REF_ID, TRANS_CFG_P0PLL); |
|
1069 |
|
dev_info(atb->adev.dev, "atombios: transmitter link uses" |
|
1070 |
|
" internal P0PLL\n"); |
|
1071 |
|
return r; |
|
1072 |
|
} |
|
1073 |
|
return 0; |
|
1074 |
|
} |
|
1075 |
|
|
|
1076 |
1096 |
static void trans_link_path(struct trans_ctl_params *ps, unsigned i) |
static void trans_link_path(struct trans_ctl_params *ps, unsigned i) |
1077 |
1097 |
{ |
{ |
1078 |
1098 |
ps->id = i; |
ps->id = i; |
|
... |
... |
int atb_trans_link_on(struct atombios *atb, unsigned i, unsigned dp_lanes_n, |
1098 |
1118 |
ps.cfg = TRANS_CFG_COHERENT_MODE; |
ps.cfg = TRANS_CFG_COHERENT_MODE; |
1099 |
1119 |
ps.lanes_n = dp_lanes_n; |
ps.lanes_n = dp_lanes_n; |
1100 |
1120 |
|
|
1101 |
|
r = trans_link_clk_ref(atb, &ps); |
|
1102 |
|
if (r != 0) |
|
1103 |
|
goto unlock_mutex; |
|
1104 |
|
|
|
1105 |
1121 |
r = trans_link(atb, &ps); |
r = trans_link(atb, &ps); |
1106 |
1122 |
|
|
1107 |
|
unlock_mutex: |
|
1108 |
1123 |
mutex_unlock(&atb->mutex); |
mutex_unlock(&atb->mutex); |
1109 |
1124 |
return r; |
return r; |
1110 |
1125 |
} |
} |
|
... |
... |
int atb_trans_link_vs_pre_emph(struct atombios *atb, unsigned i, u8 vs_pre_emph) |
1120 |
1135 |
memset(&ps, 0, sizeof(ps)); |
memset(&ps, 0, sizeof(ps)); |
1121 |
1136 |
ps.action = TRANS_ACTION_SETUP_VSEMPH; |
ps.action = TRANS_ACTION_SETUP_VSEMPH; |
1122 |
1137 |
|
|
1123 |
|
/* TODO: check dce6 supports discrect lane settings */ |
|
|
1138 |
|
/* TODO: check if dce6 supports discret lane settings */ |
1124 |
1139 |
ps.lanes_n = 4; |
ps.lanes_n = 4; |
1125 |
1140 |
ps.lanes_set = vs_pre_emph; |
ps.lanes_set = vs_pre_emph; |
1126 |
1141 |
trans_link_path(&ps, i); |
trans_link_path(&ps, i); |
File drivers/gpu/alga/amd/atombios/tables/enc_ctl.h changed (mode: 100644) (index 496b5b6..d22e37e) |
5 |
5 |
* This fork is protected by the GNU affero GPLv3 with additionnal rights |
* This fork is protected by the GNU affero GPLv3 with additionnal rights |
6 |
6 |
* Original code from Advanced Micro Devices, Inc. |
* Original code from Advanced Micro Devices, Inc. |
7 |
7 |
*/ |
*/ |
8 |
|
|
|
9 |
|
#define ENC_ACTION_DISABLE 0x00 |
|
10 |
|
#define ENC_ACTION_ENA 0x01 |
|
11 |
|
#define ENC_ACTION_DP_LINK_TRAINING_START 0x08 |
|
12 |
|
#define ENC_ACTION_DP_LINK_TRAINING_PATTERN1 0x09 |
|
13 |
|
#define ENC_ACTION_DP_LINK_TRAINING_PATTERN2 0x0a |
|
14 |
|
#define ENC_ACTION_DP_LINK_TRAINING_PATTERN3 0x13 |
|
15 |
|
#define ENC_ACTION_DP_LINK_TRAINING_COMPLETE 0x0b |
|
16 |
|
#define ENC_ACTION_DP_VIDEO_OFF 0x0c |
|
17 |
|
#define ENC_ACTION_DP_VIDEO_ON 0x0d |
|
18 |
|
#define ENC_ACTION_QUERY_DP_LINK_TRAINING_STATUS 0x0e |
|
19 |
|
#define ENC_ACTION_SETUP 0x0f |
|
20 |
|
#define ENC_ACTION_SETUP_PANEL_MODE 0x10 |
|
21 |
|
|
|
22 |
|
#define ENC_CFG_SEL_MASK 0x70 |
|
23 |
|
#define ENC_CFG_SEL_SHIFT 4 |
|
24 |
|
#define ENC_CFG_LINK_RATE_1_62_GHZ 0x0 |
|
25 |
|
#define ENC_CFG_LINK_RATE_2_7_GHZ 0x1 |
|
26 |
|
#define ENC_CFG_LINK_CATE_5_4_GHZ 0x2 |
|
27 |
|
|
|
28 |
|
#define ENC_BPC_UNDEFINE 0x00 |
|
29 |
|
#define ENC_6BITS_PER_COLOR 0x01 |
|
30 |
|
#define ENC_8BITS_PER_COLOR 0x02 |
|
31 |
|
#define ENC_10BITS_PER_COLOR 0x03 |
|
32 |
|
#define ENC_12BITS_PER_COLOR 0x04 |
|
33 |
|
#define ENC_16BITS_PER_COLOR 0x05 |
|
34 |
|
|
|
35 |
8 |
struct enc_ctl_params { |
struct enc_ctl_params { |
36 |
|
u16 pixel_clk; /* in 10kHz unit */ |
|
37 |
|
u8 cfg; /* [7] rsvd |
|
38 |
|
[6:4] encoder selection 0~5 |
|
39 |
|
[3:1] rsvd |
|
40 |
|
[0] link rate |
|
41 |
|
0: 1.62GHz |
|
42 |
|
1: 2.7 GHz */ |
|
|
9 |
|
__le16 pixel_clk; /* in 10kHz units */ |
|
10 |
|
u8 cfg; |
|
11 |
|
#define ENC_CTL_CFG_LINK_RATE_MASK 0x03 |
|
12 |
|
#define ENC_CTL_CFG_LINK_RATE_SHIFT 0 |
|
13 |
|
#define ENC_CTL_CFG_LINK_RATE_1_62_GHZ 0 |
|
14 |
|
#define ENC_CTL_CFG_LINK_RATE_2_70_GHZ 1 |
|
15 |
|
#define ENC_CTL_CFG_LINK_RATE_5_40_GHZ 2 |
|
16 |
|
#define ENC_CTL_CFG_LINK_RATE_3_24_GHZ 3 |
|
17 |
|
#define ENC_CTL_CFG_ENC_MASK 0x70 |
|
18 |
|
#define ENC_CTL_CFG_ENC_SHIFT 4 |
43 |
19 |
u8 action; |
u8 action; |
|
20 |
|
#define ENC_CTL_ACTION_DISABLE 0x00 |
|
21 |
|
#define ENC_CTL_ACTION_ENA 0x01 |
|
22 |
|
#define ENC_CTL_ACTION_DP_LINK_TRAINING_START 0x08 |
|
23 |
|
#define ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_1 0x09 |
|
24 |
|
#define ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_2 0x0a |
|
25 |
|
#define ENC_CTL_ACTION_DP_LINK_TRAINING_PATTERN_3 0x13 |
|
26 |
|
#define ENC_CTL_ACTION_DP_LINK_TRAINING_COMPLETE 0x0b |
|
27 |
|
#define ENC_CTL_ACTION_DP_VIDEO_OFF 0x0c |
|
28 |
|
#define ENC_CTL_ACTION_DP_VIDEO_ON 0x0d |
|
29 |
|
#define ENC_CTL_ACTION_QUERY_DP_LINK_TRAINING_STATUS 0x0e |
|
30 |
|
#define ENC_CTL_ACTION_SETUP 0x0f |
|
31 |
|
#define ENC_CTL_ACTION_SETUP_PANEL_MODE 0x10 |
44 |
32 |
union { |
union { |
45 |
|
u8 mode; /* 0: DP encoder |
|
46 |
|
1: LVDS encoder |
|
47 |
|
2: DVI encoder |
|
48 |
|
3: HDMI encoder |
|
49 |
|
4: SDVO encoder |
|
50 |
|
5: DP audio */ |
|
51 |
|
u8 panel_mode; /* valid when action |
|
52 |
|
= ENC_ACTION_SETUP_PANEL_MODE |
|
53 |
|
0: external DP |
|
54 |
|
1: internal DP2 |
|
55 |
|
0x11: internal DP1 for NutMeg/Travis DP |
|
56 |
|
translator */ |
|
|
33 |
|
u8 enc_mode; /* dp is mode 0 */ |
|
34 |
|
u8 panel_mode; /* valid when action = |
|
35 |
|
ENC_ACTION_SETUP_PANEL_MODE */ |
|
36 |
|
#define ENC_CTL_PANEL_MODE_EXTERNAL_DP_MODE 0x00 |
|
37 |
|
#define ENC_CTL_PANEL_MODE_INTERNAL_DP2_MODE 0x01 |
|
38 |
|
#define ENC_CTL_PANEL_MODE_INTERNAL_DP1_MODE 0x11 |
57 |
39 |
}; |
}; |
58 |
|
u8 lanes_n; /* how many lanes to enable */ |
|
59 |
|
u8 bpc; /* bit per color component, valid for DP mode |
|
60 |
|
when action = ENCODER_ACTION_SETUP */ |
|
61 |
|
u8 rsvd; |
|
|
40 |
|
u8 lanes_n; |
|
41 |
|
u8 bpc; /* bit per color component, valid for dp mode |
|
42 |
|
when action = ENC_ACTION_SETUP */ |
|
43 |
|
#define ENC_CTL_BPC_UNDEFINE 0x00 |
|
44 |
|
#define ENC_CTL_6BITS_PER_COLOR 0x01 |
|
45 |
|
#define ENC_CTL_8BITS_PER_COLOR 0x02 |
|
46 |
|
#define ENC_CTL_10BITS_PER_COLOR 0x03 |
|
47 |
|
#define ENC_CTL_12BITS_PER_COLOR 0x04 |
|
48 |
|
#define ENC_CTL_16BITS_PER_COLOR 0x05 |
|
49 |
|
u8 hpd; /* 1-6, with 0 meaning skipping */ |
62 |
50 |
} __packed; |
} __packed; |
63 |
51 |
#endif |
#endif |
File drivers/gpu/alga/amd/dce6/sink.c changed (mode: 100644) (index c52ebdc..32d50db) |
... |
... |
static void link_rate_cfg(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
130 |
130 |
if ((bw_overhead < link_rate_bw_max) || (GHZ_1_62 == max)) { |
if ((bw_overhead < link_rate_bw_max) || (GHZ_1_62 == max)) { |
131 |
131 |
dce->dps[i].link_rate = GHZ_1_62; |
dce->dps[i].link_rate = GHZ_1_62; |
132 |
132 |
} else { |
} else { |
133 |
|
link_rate_bw_max = GHZ_2_7 * DP_LINK_RATE_UNIT_MHZ |
|
|
133 |
|
link_rate_bw_max = GHZ_2_70 * DP_LINK_RATE_UNIT_MHZ |
134 |
134 |
* dce->dps[i].lanes_n; |
* dce->dps[i].lanes_n; |
135 |
|
if ((bw_overhead < link_rate_bw_max) || (GHZ_2_7 == max)) { |
|
136 |
|
dce->dps[i].link_rate = GHZ_2_7; |
|
|
135 |
|
if ((bw_overhead < link_rate_bw_max) || (GHZ_2_70 == max)) { |
|
136 |
|
dce->dps[i].link_rate = GHZ_2_70; |
137 |
137 |
} else { |
} else { |
138 |
|
link_rate_bw_max = GHZ_5_4 * DP_LINK_RATE_UNIT_MHZ |
|
|
138 |
|
link_rate_bw_max = GHZ_5_40 * DP_LINK_RATE_UNIT_MHZ |
139 |
139 |
* dce->dps[i].lanes_n; |
* dce->dps[i].lanes_n; |
140 |
140 |
if ((bw_overhead < link_rate_bw_max) |
if ((bw_overhead < link_rate_bw_max) |
141 |
|
|| (GHZ_5_4 == max)) { |
|
142 |
|
dce->dps[i].link_rate = GHZ_5_4; |
|
|
141 |
|
|| (GHZ_5_40 == max)) { |
|
142 |
|
dce->dps[i].link_rate = GHZ_5_40; |
143 |
143 |
} |
} |
144 |
144 |
} |
} |
145 |
145 |
} |
} |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
188 |
188 |
goto unlock_atb; |
goto unlock_atb; |
189 |
189 |
} |
} |
190 |
190 |
|
|
191 |
|
r = atb_enc_video(atb, i, false); |
|
|
191 |
|
r = atb_enc_video(atb, i, dce->dps[i].hpd, false); |
192 |
192 |
if (r != 0) { |
if (r != 0) { |
193 |
193 |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to switch off " |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to switch off " |
194 |
194 |
"encoder video output\n", i); |
"encoder video output\n", i); |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
250 |
250 |
dce->crtcs_pwr_gate[i] = false; |
dce->crtcs_pwr_gate[i] = false; |
251 |
251 |
|
|
252 |
252 |
/* crtc mode set */ |
/* crtc mode set */ |
253 |
|
|
|
254 |
|
/* TODO: may need to program the PLL0 to be the reference clock */ |
|
255 |
253 |
r = atb_crtc_virtual_pixel_clk(atb, i, db_fb->timing.pixel_clk); |
r = atb_crtc_virtual_pixel_clk(atb, i, db_fb->timing.pixel_clk); |
256 |
254 |
if (r != 0) { |
if (r != 0) { |
257 |
255 |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to program the " |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to program the " |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
292 |
290 |
} |
} |
293 |
291 |
|
|
294 |
292 |
/* encoder and transmitter mode set */ |
/* encoder and transmitter mode set */ |
295 |
|
r = atb_enc_setup(atb, i, dce->dps[i].lanes_n, |
|
|
293 |
|
r = atb_enc_setup(atb, i, dce->dps[i].hpd, dce->dps[i].lanes_n, |
296 |
294 |
dce->dps[i].link_rate, alga_pixel_fmts_bpc[db_fb->pixel_fmt], |
dce->dps[i].link_rate, alga_pixel_fmts_bpc[db_fb->pixel_fmt], |
297 |
295 |
db_fb->timing.pixel_clk); |
db_fb->timing.pixel_clk); |
298 |
296 |
if (r != 0) { |
if (r != 0) { |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
302 |
300 |
goto unlock_atb; |
goto unlock_atb; |
303 |
301 |
} |
} |
304 |
302 |
|
|
305 |
|
/* TODO: may need to set the panel mode set: see radeon_atom_encoder_mode_set */ |
|
|
303 |
|
r = atb_enc_setup_panel_mode(atb, i, dce->dps[i].hpd); |
|
304 |
|
if (r != 0) { |
|
305 |
|
dev_err(dce->ddev.dev, "dce6:dp%u: unable to setup the " |
|
306 |
|
"encoder panel mode\n", i); |
|
307 |
|
r = -DCE6_ERR; |
|
308 |
|
goto unlock_atb; |
|
309 |
|
} |
306 |
310 |
|
|
307 |
311 |
/* crtc commit */ |
/* crtc commit */ |
308 |
312 |
r = atb_crtc(atb, i, true); |
r = atb_crtc(atb, i, true); |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
333 |
337 |
|
|
334 |
338 |
/* encoder and transmitter commit */ |
/* encoder and transmitter commit */ |
335 |
339 |
/* XXX: this is a bug of some boards */ |
/* XXX: this is a bug of some boards */ |
336 |
|
r = atb_enc_video(atb, i, false); |
|
|
340 |
|
r = atb_enc_video(atb, i, dce->dps[i].hpd, false); |
337 |
341 |
if (r != 0) { |
if (r != 0) { |
338 |
342 |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to switch off " |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to switch off " |
339 |
343 |
"encoder video output\n", i); |
"encoder video output\n", i); |
|
... |
... |
int sink_mode_set(struct dce6 *dce, unsigned i, struct db_fb *db_fb) |
359 |
363 |
goto unlock_atb; |
goto unlock_atb; |
360 |
364 |
} |
} |
361 |
365 |
|
|
362 |
|
r = atb_enc_video(atb, i, true); |
|
|
366 |
|
r = atb_enc_video(atb, i, dce->dps[i].hpd, true); |
363 |
367 |
if (r != 0) { |
if (r != 0) { |
364 |
368 |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to enable the video " |
dev_err(dce->ddev.dev, "dce6:dp%u: unable to enable the video " |
365 |
369 |
"output on encoder\n", i); |
"output on encoder\n", i); |
File drivers/gpu/alga/amd/si/drv.c changed (mode: 100644) (index 8242a40..8ae9b74) |
32 |
32 |
#include "fops.h" |
#include "fops.h" |
33 |
33 |
#include "tiling.h" |
#include "tiling.h" |
34 |
34 |
|
|
35 |
|
//static struct class *class; |
|
|
35 |
|
static struct class *class; |
36 |
36 |
|
|
37 |
37 |
static struct atb_dev adev; |
static struct atb_dev adev; |
38 |
38 |
static struct dce6_dev ddev; |
static struct dce6_dev ddev; |
|
... |
... |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
833 |
833 |
|
|
834 |
834 |
//dce6_hpds_intr_ena(dd->dce); |
//dce6_hpds_intr_ena(dd->dce); |
835 |
835 |
|
|
836 |
|
///* userland interface setup */ |
|
837 |
|
//cdev_init(&dd->evergreen_cdev, &fops); |
|
838 |
|
//err = cdev_add(&dd->evergreen_cdev, devt, 1); |
|
839 |
|
//if (err) { |
|
840 |
|
// dev_err(&dev->dev, "cannot add register char device\n"); |
|
841 |
|
// goto err_clr_master; |
|
842 |
|
//} |
|
843 |
|
|
|
844 |
|
//dd->evergreen_dev = device_create(class, &dev->dev, |
|
845 |
|
// dd->evergreen_cdev.dev, NULL, "evergreen0"); |
|
846 |
|
//if (IS_ERR(dd->evergreen_dev)) { |
|
847 |
|
// dev_err(&dev->dev, "cannot create userspace char device\n"); |
|
848 |
|
// goto err_cdev_del; |
|
849 |
|
//} |
|
|
836 |
|
/* userland interface setup */ |
|
837 |
|
cdev_init(&dd->si_cdev, &fops); |
|
838 |
|
err = cdev_add(&dd->si_cdev, devt, 1); |
|
839 |
|
if (err) { |
|
840 |
|
dev_err(&dev->dev, "cannot add register char device\n"); |
|
841 |
|
goto err_clr_master; |
|
842 |
|
} |
|
843 |
|
|
|
844 |
|
dd->si_dev = device_create(class, &dev->dev, dd->si_cdev.dev, NULL, |
|
845 |
|
"si0"); |
|
846 |
|
if (IS_ERR(dd->si_dev)) { |
|
847 |
|
dev_err(&dev->dev, "cannot create userspace char device\n"); |
|
848 |
|
goto err_cdev_del; |
|
849 |
|
} |
850 |
850 |
|
|
851 |
851 |
dev_info(&dev->dev, "ready\n"); |
dev_info(&dev->dev, "ready\n"); |
852 |
852 |
return 0; |
return 0; |
853 |
853 |
|
|
854 |
|
//err_cdev_del: |
|
855 |
|
// cdev_del(&dd->evergreen_cdev); |
|
856 |
|
// |
|
|
854 |
|
err_cdev_del: |
|
855 |
|
cdev_del(&dd->si_cdev); |
|
856 |
|
|
857 |
857 |
err_clr_master: |
err_clr_master: |
858 |
858 |
// pci_clear_master(dev); |
// pci_clear_master(dev); |
859 |
859 |
cps_engines_stop(dev); |
cps_engines_stop(dev); |
|
... |
... |
static void __devexit remove(struct pci_dev *dev) |
914 |
914 |
dd = pci_get_drvdata(dev); |
dd = pci_get_drvdata(dev); |
915 |
915 |
|
|
916 |
916 |
/* remove userland interface */ |
/* remove userland interface */ |
917 |
|
//device_destroy(class, dd->evergreen_cdev.dev); |
|
918 |
|
//cdev_del(&dd->evergreen_cdev); |
|
|
917 |
|
device_destroy(class, dd->si_cdev.dev); |
|
918 |
|
cdev_del(&dd->si_cdev); |
919 |
919 |
|
|
920 |
920 |
//pci_clear_master(dev); |
//pci_clear_master(dev); |
921 |
921 |
cps_engines_stop(dev); |
cps_engines_stop(dev); |
|
... |
... |
static void __devexit remove(struct pci_dev *dev) |
928 |
928 |
//ba_unmap(dev); |
//ba_unmap(dev); |
929 |
929 |
|
|
930 |
930 |
//TEST |
//TEST |
931 |
|
ba_shutdown(dev); |
|
|
931 |
|
//ba_shutdown(dev); |
932 |
932 |
|
|
933 |
933 |
ucode_release(dev); |
ucode_release(dev); |
934 |
934 |
|
|
|
... |
... |
static int __init init(void) |
970 |
970 |
{ |
{ |
971 |
971 |
int r; |
int r; |
972 |
972 |
|
|
973 |
|
//class = class_create(THIS_MODULE, "si"); |
|
974 |
|
//if (IS_ERR(class)) |
|
975 |
|
// return PTR_ERR(class); |
|
976 |
|
|
|
977 |
|
//r = alloc_chrdev_region(&devt, 0, 1, pci_driver.name); |
|
978 |
|
//if (r < 0) { |
|
979 |
|
// printk(KERN_ERR "%s:cannot allocate major/minor range\n", |
|
980 |
|
// pci_driver.name); |
|
981 |
|
// goto class_destroy; |
|
982 |
|
//} |
|
983 |
|
// |
|
|
973 |
|
class = class_create(THIS_MODULE, "si"); |
|
974 |
|
if (IS_ERR(class)) |
|
975 |
|
return PTR_ERR(class); |
|
976 |
|
|
|
977 |
|
r = alloc_chrdev_region(&devt, 0, 1, pci_driver.name); |
|
978 |
|
if (r < 0) { |
|
979 |
|
printk(KERN_ERR "%s:cannot allocate major/minor range\n", |
|
980 |
|
pci_driver.name); |
|
981 |
|
goto class_destroy; |
|
982 |
|
} |
|
983 |
|
|
984 |
984 |
r = pci_register_driver(&pci_driver); |
r = pci_register_driver(&pci_driver); |
985 |
985 |
if (r != 0) { |
if (r != 0) { |
986 |
986 |
printk(KERN_ERR "%s:cannot register PCI driver\n", |
printk(KERN_ERR "%s:cannot register PCI driver\n", |
|
... |
... |
static int __init init(void) |
990 |
990 |
return 0; |
return 0; |
991 |
991 |
|
|
992 |
992 |
chrdev_region_unregister: |
chrdev_region_unregister: |
993 |
|
// unregister_chrdev_region(devt, 1); |
|
994 |
|
// |
|
995 |
|
//class_destroy: |
|
996 |
|
// class_destroy(class); |
|
|
993 |
|
unregister_chrdev_region(devt, 1); |
|
994 |
|
|
|
995 |
|
class_destroy: |
|
996 |
|
class_destroy(class); |
997 |
997 |
return r; |
return r; |
998 |
998 |
} |
} |
999 |
999 |
|
|
1000 |
1000 |
static void __exit cleanup(void) |
static void __exit cleanup(void) |
1001 |
1001 |
{ |
{ |
1002 |
1002 |
pci_unregister_driver(&pci_driver); |
pci_unregister_driver(&pci_driver); |
1003 |
|
// unregister_chrdev_region(devt, 1); |
|
1004 |
|
// class_destroy(class); |
|
|
1003 |
|
unregister_chrdev_region(devt, 1); |
|
1004 |
|
class_destroy(class); |
1005 |
1005 |
} |
} |
1006 |
1006 |
|
|
1007 |
1007 |
module_init(init); |
module_init(init); |
File drivers/gpu/alga/amd/si/fops.c changed (mode: 100644) (index 4d1ff6d..a5b8ec5) |
16 |
16 |
#include <alga/rng_mng.h> |
#include <alga/rng_mng.h> |
17 |
17 |
#include <alga/pixel_fmts.h> |
#include <alga/pixel_fmts.h> |
18 |
18 |
#include <alga/timing.h> |
#include <alga/timing.h> |
19 |
|
#include <alga/amd/dce4/dce4.h> |
|
20 |
|
#include <alga/amd/evergreen/ioctl.h> |
|
|
19 |
|
#include <alga/amd/dce6/dce6.h> |
|
20 |
|
#include <alga/amd/si/ioctl.h> |
21 |
21 |
|
|
22 |
22 |
#include "regs.h" |
#include "regs.h" |
23 |
23 |
|
|
|
... |
... |
static int open(struct inode *i, struct file *f) |
33 |
33 |
{ |
{ |
34 |
34 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
35 |
35 |
//DEBUG |
//DEBUG |
36 |
|
printk(KERN_INFO "EVERGREEN OPEN\n"); |
|
37 |
|
dd = container_of(i->i_cdev, struct dev_drv_data, evergreen_cdev); |
|
|
36 |
|
printk(KERN_INFO "SI OPEN\n"); |
|
37 |
|
dd = container_of(i->i_cdev, struct dev_drv_data, si_cdev); |
38 |
38 |
f->private_data = dd->dev; |
f->private_data = dd->dev; |
39 |
39 |
return 0; |
return 0; |
40 |
40 |
} |
} |
|
... |
... |
static int dce_dps_info(struct pci_dev *dev, void __user *user) |
43 |
43 |
{ |
{ |
44 |
44 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
45 |
45 |
int r; |
int r; |
46 |
|
struct evergreen_dce_dps_info *info; |
|
47 |
|
|
|
|
46 |
|
struct si_dce_dps_info *info; |
48 |
47 |
|
|
49 |
48 |
/* too big for a kernel stack */ |
/* too big for a kernel stack */ |
50 |
49 |
info = kzalloc(sizeof(*info), GFP_KERNEL); |
info = kzalloc(sizeof(*info), GFP_KERNEL); |
|
... |
... |
static int dce_dps_info(struct pci_dev *dev, void __user *user) |
53 |
52 |
|
|
54 |
53 |
dd = pci_get_drvdata(dev); |
dd = pci_get_drvdata(dev); |
55 |
54 |
|
|
56 |
|
r = dce4_dps_info(dd->dce, &info->used, &info->connected, |
|
|
55 |
|
r = dce6_dps_info(dd->dce, &info->used, &info->connected, |
57 |
56 |
&info->pixel_fmts, &info->timings); |
&info->pixel_fmts, &info->timings); |
58 |
57 |
if (r != 0) { |
if (r != 0) { |
59 |
58 |
r = -ENODEV; |
r = -ENODEV; |
|
... |
... |
free_info: |
70 |
69 |
static int dce_dp_set(struct pci_dev *dev, void __user *user) |
static int dce_dp_set(struct pci_dev *dev, void __user *user) |
71 |
70 |
{ |
{ |
72 |
71 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
73 |
|
struct evergreen_dce_dp_set dp_set; |
|
|
72 |
|
struct si_dce_dp_set dp_set; |
74 |
73 |
struct db_fb db_fb; |
struct db_fb db_fb; |
75 |
74 |
int r; |
int r; |
76 |
75 |
|
|
|
... |
... |
static int dce_dp_set(struct pci_dev *dev, void __user *user) |
85 |
84 |
|
|
86 |
85 |
dd = pci_get_drvdata(dev); |
dd = pci_get_drvdata(dev); |
87 |
86 |
|
|
88 |
|
r = dce4_sink_mode_set(dd->dce, dp_set.i, &db_fb); |
|
|
87 |
|
r = dce6_sink_mode_set(dd->dce, dp_set.i, &db_fb); |
89 |
88 |
if (r != 0) |
if (r != 0) |
90 |
89 |
return -ENODEV; |
return -ENODEV; |
91 |
90 |
return 0; |
return 0; |
|
... |
... |
static int dce_dp_dpm(struct pci_dev *dev, unsigned __user *user_i) |
101 |
100 |
|
|
102 |
101 |
dd = pci_get_drvdata(dev); |
dd = pci_get_drvdata(dev); |
103 |
102 |
|
|
104 |
|
r = dce4_dp_dpm(dd->dce, i); |
|
|
103 |
|
r = dce6_dp_dpm(dd->dce, i); |
105 |
104 |
if (r != 0) |
if (r != 0) |
106 |
105 |
return -ENODEV; |
return -ENODEV; |
107 |
106 |
return 0; |
return 0; |
|
... |
... |
static int dce_pf(struct pci_dev *dev, unsigned __user *user) |
118 |
117 |
|
|
119 |
118 |
dd = pci_get_drvdata(dev); |
dd = pci_get_drvdata(dev); |
120 |
119 |
|
|
121 |
|
r = dce4_pf(dd->dce, i, &vblanks_n); |
|
|
120 |
|
r = dce6_pf(dd->dce, i, &vblanks_n); |
122 |
121 |
if (r != 0) |
if (r != 0) |
123 |
122 |
return -ENODEV; |
return -ENODEV; |
124 |
123 |
put_user(vblanks_n, user); |
put_user(vblanks_n, user); |
125 |
124 |
return 0; |
return 0; |
126 |
125 |
} |
} |
127 |
126 |
|
|
128 |
|
static int evergreen_mem_alloc(struct pci_dev *dev, |
|
129 |
|
struct evergreen_mem __user *mem) |
|
|
127 |
|
static int si_mem_alloc(struct pci_dev *dev, struct si_mem __user *mem) |
130 |
128 |
{ |
{ |
131 |
129 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
132 |
130 |
u64 sz; |
u64 sz; |
|
... |
... |
static int evergreen_mem_alloc(struct pci_dev *dev, |
147 |
145 |
return r; |
return r; |
148 |
146 |
} |
} |
149 |
147 |
|
|
150 |
|
static void evergreen_mem_free(struct pci_dev *dev, u64 __user *user_gpu_addr) |
|
|
148 |
|
static void si_mem_free(struct pci_dev *dev, u64 __user *user_gpu_addr) |
151 |
149 |
{ |
{ |
152 |
150 |
u64 gpu_addr; |
u64 gpu_addr; |
153 |
151 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
|
... |
... |
static long unlocked_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
170 |
168 |
|
|
171 |
169 |
r = 0; |
r = 0; |
172 |
170 |
switch (nr) { |
switch (nr) { |
173 |
|
case EVERGREEN_DCE_DPS_INFO: |
|
|
171 |
|
case SI_DCE_DPS_INFO: |
174 |
172 |
//DEBUG |
//DEBUG |
175 |
|
printk(KERN_INFO "IOCTL_EVERGREEN_DCE_DPS_INFO\n"); |
|
|
173 |
|
printk(KERN_INFO "IOCTL_SI_DCE_DPS_INFO\n"); |
176 |
174 |
r = dce_dps_info(dev, (void __user *)arg); |
r = dce_dps_info(dev, (void __user *)arg); |
177 |
175 |
break; |
break; |
178 |
|
case EVERGREEN_DCE_DP_SET: |
|
|
176 |
|
case SI_DCE_DP_SET: |
179 |
177 |
//DEBUG |
//DEBUG |
180 |
|
printk(KERN_INFO "EVERGREEN_DCE_DP_SET\n"); |
|
|
178 |
|
printk(KERN_INFO "SI_DCE_DP_SET\n"); |
181 |
179 |
r = dce_dp_set(dev, (void __user *)arg); |
r = dce_dp_set(dev, (void __user *)arg); |
182 |
180 |
break; |
break; |
183 |
|
case EVERGREEN_DCE_DP_DPM: |
|
|
181 |
|
case SI_DCE_DP_DPM: |
184 |
182 |
//DEBUG |
//DEBUG |
185 |
|
printk(KERN_INFO "EVERGREEN_DCE_DP_DPM\n"); |
|
|
183 |
|
printk(KERN_INFO "SI_DCE_DP_DPM\n"); |
186 |
184 |
r = dce_dp_dpm(dev, (unsigned __user *)arg); |
r = dce_dp_dpm(dev, (unsigned __user *)arg); |
187 |
185 |
break; |
break; |
188 |
|
case EVERGREEN_DCE_PF: |
|
|
186 |
|
case SI_DCE_PF: |
189 |
187 |
//DEBUG |
//DEBUG |
190 |
|
printk(KERN_INFO "EVERGREEN_DCE_PF\n"); |
|
|
188 |
|
printk(KERN_INFO "SI_DCE_PF\n"); |
191 |
189 |
r = dce_pf(dev, (unsigned __user *)arg); |
r = dce_pf(dev, (unsigned __user *)arg); |
192 |
190 |
break; |
break; |
193 |
|
case EVERGREEN_MEM_ALLOC: |
|
|
191 |
|
case SI_MEM_ALLOC: |
194 |
192 |
//DEBUG |
//DEBUG |
195 |
|
printk(KERN_INFO "EVERGREEN_MEM_ALLOC\n"); |
|
196 |
|
r = evergreen_mem_alloc(dev, |
|
197 |
|
(struct evergreen_mem __user *)arg); |
|
|
193 |
|
printk(KERN_INFO "SI_MEM_ALLOC\n"); |
|
194 |
|
r = si_mem_alloc(dev, (struct si_mem __user *)arg); |
198 |
195 |
break; |
break; |
199 |
|
case EVERGREEN_MEM_FREE: |
|
|
196 |
|
case SI_MEM_FREE: |
200 |
197 |
//DEBUG |
//DEBUG |
201 |
|
printk(KERN_INFO "EVERGREEN_MEM_FREE\n"); |
|
202 |
|
evergreen_mem_free(dev, (u64 __user *)arg); |
|
|
198 |
|
printk(KERN_INFO "SI_MEM_FREE\n"); |
|
199 |
|
si_mem_free(dev, (u64 __user *)arg); |
203 |
200 |
break; |
break; |
204 |
|
case EVERGREEN_INFO: |
|
|
201 |
|
case SI_INFO: |
205 |
202 |
//DEBUG |
//DEBUG |
206 |
|
printk(KERN_INFO "EVERGREEN_INFO\n"); |
|
|
203 |
|
printk(KERN_INFO "SI_INFO\n"); |
207 |
204 |
break; |
break; |
208 |
205 |
default: |
default: |
209 |
206 |
r = -EINVAL; |
r = -EINVAL; |
|
... |
... |
static long unlocked_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
215 |
212 |
static int release(struct inode *i, struct file *f) |
static int release(struct inode *i, struct file *f) |
216 |
213 |
{ |
{ |
217 |
214 |
//DEBUG |
//DEBUG |
218 |
|
printk(KERN_INFO "EVERGREEN RELEASE\n"); |
|
|
215 |
|
printk(KERN_INFO "SI RELEASE\n"); |
219 |
216 |
return 0; |
return 0; |
220 |
217 |
} |
} |
221 |
218 |
|
|