diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_i2c.c | 133 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 8 |
3 files changed, 64 insertions, 79 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index ee0083f982d8..60d59816b94f 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -940,7 +940,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) | |||
| 940 | if (radeon_connector->edid) | 940 | if (radeon_connector->edid) |
| 941 | kfree(radeon_connector->edid); | 941 | kfree(radeon_connector->edid); |
| 942 | if (radeon_dig_connector->dp_i2c_bus) | 942 | if (radeon_dig_connector->dp_i2c_bus) |
| 943 | radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus); | 943 | radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); |
| 944 | kfree(radeon_connector->con_priv); | 944 | kfree(radeon_connector->con_priv); |
| 945 | drm_sysfs_connector_remove(connector); | 945 | drm_sysfs_connector_remove(connector); |
| 946 | drm_connector_cleanup(connector); | 946 | drm_connector_cleanup(connector); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index f007fcb1191b..352110fd68f6 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -59,6 +59,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
| 59 | return false; | 59 | return false; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | /* bit banging i2c */ | ||
| 62 | 63 | ||
| 63 | static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | 64 | static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) |
| 64 | { | 65 | { |
| @@ -181,6 +182,24 @@ static void set_data(void *i2c_priv, int data) | |||
| 181 | WREG32(rec->en_data_reg, val); | 182 | WREG32(rec->en_data_reg, val); |
| 182 | } | 183 | } |
| 183 | 184 | ||
| 185 | static int pre_xfer(struct i2c_adapter *i2c_adap) | ||
| 186 | { | ||
| 187 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
| 188 | |||
| 189 | radeon_i2c_do_lock(i2c, 1); | ||
| 190 | |||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | |||
| 194 | static void post_xfer(struct i2c_adapter *i2c_adap) | ||
| 195 | { | ||
| 196 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
| 197 | |||
| 198 | radeon_i2c_do_lock(i2c, 0); | ||
| 199 | } | ||
| 200 | |||
| 201 | /* hw i2c */ | ||
| 202 | |||
| 184 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) | 203 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
| 185 | { | 204 | { |
| 186 | u32 sclk = radeon_get_engine_clock(rdev); | 205 | u32 sclk = radeon_get_engine_clock(rdev); |
| @@ -757,26 +776,13 @@ done: | |||
| 757 | return ret; | 776 | return ret; |
| 758 | } | 777 | } |
| 759 | 778 | ||
| 760 | static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap, | 779 | static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, |
| 761 | struct i2c_msg *msgs, int num) | 780 | struct i2c_msg *msgs, int num) |
| 762 | { | 781 | { |
| 763 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | 782 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
| 764 | int ret; | ||
| 765 | |||
| 766 | radeon_i2c_do_lock(i2c, 1); | ||
| 767 | ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num); | ||
| 768 | radeon_i2c_do_lock(i2c, 0); | ||
| 769 | |||
| 770 | return ret; | ||
| 771 | } | ||
| 772 | |||
| 773 | static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
| 774 | struct i2c_msg *msgs, int num) | ||
| 775 | { | ||
| 776 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
| 777 | struct radeon_device *rdev = i2c->dev->dev_private; | 783 | struct radeon_device *rdev = i2c->dev->dev_private; |
| 778 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 784 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
| 779 | int ret; | 785 | int ret = 0; |
| 780 | 786 | ||
| 781 | switch (rdev->family) { | 787 | switch (rdev->family) { |
| 782 | case CHIP_R100: | 788 | case CHIP_R100: |
| @@ -797,16 +803,12 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 797 | case CHIP_RV410: | 803 | case CHIP_RV410: |
| 798 | case CHIP_RS400: | 804 | case CHIP_RS400: |
| 799 | case CHIP_RS480: | 805 | case CHIP_RS480: |
| 800 | if (rec->hw_capable) | 806 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); |
| 801 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); | ||
| 802 | else | ||
| 803 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 804 | break; | 807 | break; |
| 805 | case CHIP_RS600: | 808 | case CHIP_RS600: |
| 806 | case CHIP_RS690: | 809 | case CHIP_RS690: |
| 807 | case CHIP_RS740: | 810 | case CHIP_RS740: |
| 808 | /* XXX fill in hw i2c implementation */ | 811 | /* XXX fill in hw i2c implementation */ |
| 809 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 810 | break; | 812 | break; |
| 811 | case CHIP_RV515: | 813 | case CHIP_RV515: |
| 812 | case CHIP_R520: | 814 | case CHIP_R520: |
| @@ -814,20 +816,16 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 814 | case CHIP_RV560: | 816 | case CHIP_RV560: |
| 815 | case CHIP_RV570: | 817 | case CHIP_RV570: |
| 816 | case CHIP_R580: | 818 | case CHIP_R580: |
| 817 | if (rec->hw_capable) { | 819 | if (rec->mm_i2c) |
| 818 | if (rec->mm_i2c) | 820 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); |
| 819 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); | 821 | else |
| 820 | else | 822 | ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); |
| 821 | ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); | ||
| 822 | } else | ||
| 823 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 824 | break; | 823 | break; |
| 825 | case CHIP_R600: | 824 | case CHIP_R600: |
| 826 | case CHIP_RV610: | 825 | case CHIP_RV610: |
| 827 | case CHIP_RV630: | 826 | case CHIP_RV630: |
| 828 | case CHIP_RV670: | 827 | case CHIP_RV670: |
| 829 | /* XXX fill in hw i2c implementation */ | 828 | /* XXX fill in hw i2c implementation */ |
| 830 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 831 | break; | 829 | break; |
| 832 | case CHIP_RV620: | 830 | case CHIP_RV620: |
| 833 | case CHIP_RV635: | 831 | case CHIP_RV635: |
| @@ -838,7 +836,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 838 | case CHIP_RV710: | 836 | case CHIP_RV710: |
| 839 | case CHIP_RV740: | 837 | case CHIP_RV740: |
| 840 | /* XXX fill in hw i2c implementation */ | 838 | /* XXX fill in hw i2c implementation */ |
| 841 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 842 | break; | 839 | break; |
| 843 | case CHIP_CEDAR: | 840 | case CHIP_CEDAR: |
| 844 | case CHIP_REDWOOD: | 841 | case CHIP_REDWOOD: |
| @@ -846,7 +843,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 846 | case CHIP_CYPRESS: | 843 | case CHIP_CYPRESS: |
| 847 | case CHIP_HEMLOCK: | 844 | case CHIP_HEMLOCK: |
| 848 | /* XXX fill in hw i2c implementation */ | 845 | /* XXX fill in hw i2c implementation */ |
| 849 | ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); | ||
| 850 | break; | 846 | break; |
| 851 | default: | 847 | default: |
| 852 | DRM_ERROR("i2c: unhandled radeon chip\n"); | 848 | DRM_ERROR("i2c: unhandled radeon chip\n"); |
| @@ -857,20 +853,21 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 857 | return ret; | 853 | return ret; |
| 858 | } | 854 | } |
| 859 | 855 | ||
| 860 | static u32 radeon_i2c_func(struct i2c_adapter *adap) | 856 | static u32 radeon_hw_i2c_func(struct i2c_adapter *adap) |
| 861 | { | 857 | { |
| 862 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 858 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
| 863 | } | 859 | } |
| 864 | 860 | ||
| 865 | static const struct i2c_algorithm radeon_i2c_algo = { | 861 | static const struct i2c_algorithm radeon_i2c_algo = { |
| 866 | .master_xfer = radeon_i2c_xfer, | 862 | .master_xfer = radeon_hw_i2c_xfer, |
| 867 | .functionality = radeon_i2c_func, | 863 | .functionality = radeon_hw_i2c_func, |
| 868 | }; | 864 | }; |
| 869 | 865 | ||
| 870 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 866 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
| 871 | struct radeon_i2c_bus_rec *rec, | 867 | struct radeon_i2c_bus_rec *rec, |
| 872 | const char *name) | 868 | const char *name) |
| 873 | { | 869 | { |
| 870 | struct radeon_device *rdev = dev->dev_private; | ||
| 874 | struct radeon_i2c_chan *i2c; | 871 | struct radeon_i2c_chan *i2c; |
| 875 | int ret; | 872 | int ret; |
| 876 | 873 | ||
| @@ -878,37 +875,41 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 878 | if (i2c == NULL) | 875 | if (i2c == NULL) |
| 879 | return NULL; | 876 | return NULL; |
| 880 | 877 | ||
| 881 | /* set the internal bit adapter */ | ||
| 882 | i2c->algo.radeon.bit_adapter.owner = THIS_MODULE; | ||
| 883 | i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c); | ||
| 884 | sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name); | ||
| 885 | i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data; | ||
| 886 | i2c->algo.radeon.bit_data.setsda = set_data; | ||
| 887 | i2c->algo.radeon.bit_data.setscl = set_clock; | ||
| 888 | i2c->algo.radeon.bit_data.getsda = get_data; | ||
| 889 | i2c->algo.radeon.bit_data.getscl = get_clock; | ||
| 890 | i2c->algo.radeon.bit_data.udelay = 20; | ||
| 891 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | ||
| 892 | * make this, 2 jiffies is a lot more reliable */ | ||
| 893 | i2c->algo.radeon.bit_data.timeout = 2; | ||
| 894 | i2c->algo.radeon.bit_data.data = i2c; | ||
| 895 | ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter); | ||
| 896 | if (ret) { | ||
| 897 | DRM_ERROR("Failed to register internal bit i2c %s\n", name); | ||
| 898 | goto out_free; | ||
| 899 | } | ||
| 900 | /* set the radeon i2c adapter */ | ||
| 901 | i2c->dev = dev; | ||
| 902 | i2c->rec = *rec; | 878 | i2c->rec = *rec; |
| 903 | i2c->adapter.owner = THIS_MODULE; | 879 | i2c->adapter.owner = THIS_MODULE; |
| 880 | i2c->dev = dev; | ||
| 904 | i2c_set_adapdata(&i2c->adapter, i2c); | 881 | i2c_set_adapdata(&i2c->adapter, i2c); |
| 905 | sprintf(i2c->adapter.name, "Radeon i2c %s", name); | 882 | if (rec->hw_capable && |
| 906 | i2c->adapter.algo_data = &i2c->algo.radeon; | 883 | ((rdev->family <= CHIP_RS480) || |
| 907 | i2c->adapter.algo = &radeon_i2c_algo; | 884 | ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580)))) { |
| 908 | ret = i2c_add_adapter(&i2c->adapter); | 885 | /* set the radeon hw i2c adapter */ |
| 909 | if (ret) { | 886 | sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name); |
| 910 | DRM_ERROR("Failed to register i2c %s\n", name); | 887 | i2c->adapter.algo = &radeon_i2c_algo; |
| 911 | goto out_free; | 888 | ret = i2c_add_adapter(&i2c->adapter); |
| 889 | if (ret) { | ||
| 890 | DRM_ERROR("Failed to register hw i2c %s\n", name); | ||
| 891 | goto out_free; | ||
| 892 | } | ||
| 893 | } else { | ||
| 894 | /* set the radeon bit adapter */ | ||
| 895 | sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name); | ||
| 896 | i2c->adapter.algo_data = &i2c->algo.bit; | ||
| 897 | i2c->algo.bit.pre_xfer = pre_xfer; | ||
| 898 | i2c->algo.bit.post_xfer = post_xfer; | ||
| 899 | i2c->algo.bit.setsda = set_data; | ||
| 900 | i2c->algo.bit.setscl = set_clock; | ||
| 901 | i2c->algo.bit.getsda = get_data; | ||
| 902 | i2c->algo.bit.getscl = get_clock; | ||
| 903 | i2c->algo.bit.udelay = 20; | ||
| 904 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | ||
| 905 | * make this, 2 jiffies is a lot more reliable */ | ||
| 906 | i2c->algo.bit.timeout = 2; | ||
| 907 | i2c->algo.bit.data = i2c; | ||
| 908 | ret = i2c_bit_add_bus(&i2c->adapter); | ||
| 909 | if (ret) { | ||
| 910 | DRM_ERROR("Failed to register bit i2c %s\n", name); | ||
| 911 | goto out_free; | ||
| 912 | } | ||
| 912 | } | 913 | } |
| 913 | 914 | ||
| 914 | return i2c; | 915 | return i2c; |
| @@ -953,16 +954,6 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | |||
| 953 | { | 954 | { |
| 954 | if (!i2c) | 955 | if (!i2c) |
| 955 | return; | 956 | return; |
| 956 | i2c_del_adapter(&i2c->algo.radeon.bit_adapter); | ||
| 957 | i2c_del_adapter(&i2c->adapter); | ||
| 958 | kfree(i2c); | ||
| 959 | } | ||
| 960 | |||
| 961 | void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c) | ||
| 962 | { | ||
| 963 | if (!i2c) | ||
| 964 | return; | ||
| 965 | |||
| 966 | i2c_del_adapter(&i2c->adapter); | 957 | i2c_del_adapter(&i2c->adapter); |
| 967 | kfree(i2c); | 958 | kfree(i2c); |
| 968 | } | 959 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 55a41757eed1..0b8e32776b10 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -173,17 +173,12 @@ struct radeon_pll { | |||
| 173 | enum radeon_pll_algo algo; | 173 | enum radeon_pll_algo algo; |
| 174 | }; | 174 | }; |
| 175 | 175 | ||
| 176 | struct i2c_algo_radeon_data { | ||
| 177 | struct i2c_adapter bit_adapter; | ||
| 178 | struct i2c_algo_bit_data bit_data; | ||
| 179 | }; | ||
| 180 | |||
| 181 | struct radeon_i2c_chan { | 176 | struct radeon_i2c_chan { |
| 182 | struct i2c_adapter adapter; | 177 | struct i2c_adapter adapter; |
| 183 | struct drm_device *dev; | 178 | struct drm_device *dev; |
| 184 | union { | 179 | union { |
| 180 | struct i2c_algo_bit_data bit; | ||
| 185 | struct i2c_algo_dp_aux_data dp; | 181 | struct i2c_algo_dp_aux_data dp; |
| 186 | struct i2c_algo_radeon_data radeon; | ||
| 187 | } algo; | 182 | } algo; |
| 188 | struct radeon_i2c_bus_rec rec; | 183 | struct radeon_i2c_bus_rec rec; |
| 189 | }; | 184 | }; |
| @@ -435,7 +430,6 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 435 | struct radeon_i2c_bus_rec *rec, | 430 | struct radeon_i2c_bus_rec *rec, |
| 436 | const char *name); | 431 | const char *name); |
| 437 | extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); | 432 | extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); |
| 438 | extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c); | ||
| 439 | extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, | 433 | extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, |
| 440 | u8 slave_addr, | 434 | u8 slave_addr, |
| 441 | u8 addr, | 435 | u8 addr, |
