aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-04-19 23:16:04 -0400
committerDave Airlie <airlied@redhat.com>2010-04-19 23:16:04 -0400
commit7fff400be6fbf64f10abca9939718aaf1d61c255 (patch)
tree384118628f5c5aa2d74303cddd120de75308beea /drivers/gpu/drm/radeon
parent0bcb1d844ac638a4c4280f697d5bfac9791e9a70 (diff)
parentb1f201980eb4a7a59277a13cf18acdbb46167ad5 (diff)
Merge branch 'drm-fbdev-cleanup' into drm-core-next
* drm-fbdev-cleanup: drm/fb: remove drm_fb_helper_setcolreg drm/kms/fb: use slow work mechanism for normal hotplug also. drm/kms/fb: add polling support for when nothing is connected. drm/kms/fb: provide a 1024x768 fbcon if no outputs found. drm/kms/fb: separate fbdev connector list from core drm connectors drm/kms/fb: move to using fb helper crtc grouping instead of core crtc list drm/fb: fix fbdev object model + cleanup properly. Conflicts: drivers/gpu/drm/i915/i915_drv.h drivers/gpu/drm/nouveau/nouveau_drv.h
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c50
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c42
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c352
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h23
8 files changed, 259 insertions, 225 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4ac97ab28947..be7570ac901c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -938,9 +938,6 @@ struct radeon_device {
938 bool is_atom_bios; 938 bool is_atom_bios;
939 uint16_t bios_header_start; 939 uint16_t bios_header_start;
940 struct radeon_bo *stollen_vga_memory; 940 struct radeon_bo *stollen_vga_memory;
941 struct fb_info *fbdev_info;
942 struct radeon_bo *fbdev_rbo;
943 struct radeon_framebuffer *fbdev_rfb;
944 /* Register mmio */ 941 /* Register mmio */
945 resource_size_t rmmio_base; 942 resource_size_t rmmio_base;
946 resource_size_t rmmio_size; 943 resource_size_t rmmio_size;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 1331351c5178..c48934677adf 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1041,7 +1041,6 @@ radeon_add_atom_connector(struct drm_device *dev,
1041 struct radeon_connector_atom_dig *radeon_dig_connector; 1041 struct radeon_connector_atom_dig *radeon_dig_connector;
1042 uint32_t subpixel_order = SubPixelNone; 1042 uint32_t subpixel_order = SubPixelNone;
1043 bool shared_ddc = false; 1043 bool shared_ddc = false;
1044 int ret;
1045 1044
1046 /* fixme - tv/cv/din */ 1045 /* fixme - tv/cv/din */
1047 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1046 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -1076,9 +1075,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1076 switch (connector_type) { 1075 switch (connector_type) {
1077 case DRM_MODE_CONNECTOR_VGA: 1076 case DRM_MODE_CONNECTOR_VGA:
1078 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1077 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1079 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1078 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1080 if (ret)
1081 goto failed;
1082 if (i2c_bus->valid) { 1079 if (i2c_bus->valid) {
1083 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); 1080 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
1084 if (!radeon_connector->ddc_bus) 1081 if (!radeon_connector->ddc_bus)
@@ -1091,9 +1088,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1091 break; 1088 break;
1092 case DRM_MODE_CONNECTOR_DVIA: 1089 case DRM_MODE_CONNECTOR_DVIA:
1093 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1090 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1094 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1091 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1095 if (ret)
1096 goto failed;
1097 if (i2c_bus->valid) { 1092 if (i2c_bus->valid) {
1098 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1093 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1099 if (!radeon_connector->ddc_bus) 1094 if (!radeon_connector->ddc_bus)
@@ -1113,9 +1108,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1113 radeon_dig_connector->igp_lane_info = igp_lane_info; 1108 radeon_dig_connector->igp_lane_info = igp_lane_info;
1114 radeon_connector->con_priv = radeon_dig_connector; 1109 radeon_connector->con_priv = radeon_dig_connector;
1115 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1110 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1116 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1111 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1117 if (ret)
1118 goto failed;
1119 if (i2c_bus->valid) { 1112 if (i2c_bus->valid) {
1120 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1113 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1121 if (!radeon_connector->ddc_bus) 1114 if (!radeon_connector->ddc_bus)
@@ -1141,9 +1134,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1141 radeon_dig_connector->igp_lane_info = igp_lane_info; 1134 radeon_dig_connector->igp_lane_info = igp_lane_info;
1142 radeon_connector->con_priv = radeon_dig_connector; 1135 radeon_connector->con_priv = radeon_dig_connector;
1143 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1136 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1144 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1137 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1145 if (ret)
1146 goto failed;
1147 if (i2c_bus->valid) { 1138 if (i2c_bus->valid) {
1148 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); 1139 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
1149 if (!radeon_connector->ddc_bus) 1140 if (!radeon_connector->ddc_bus)
@@ -1163,9 +1154,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1163 radeon_dig_connector->igp_lane_info = igp_lane_info; 1154 radeon_dig_connector->igp_lane_info = igp_lane_info;
1164 radeon_connector->con_priv = radeon_dig_connector; 1155 radeon_connector->con_priv = radeon_dig_connector;
1165 drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); 1156 drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
1166 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); 1157 drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1167 if (ret)
1168 goto failed;
1169 if (i2c_bus->valid) { 1158 if (i2c_bus->valid) {
1170 /* add DP i2c bus */ 1159 /* add DP i2c bus */
1171 if (connector_type == DRM_MODE_CONNECTOR_eDP) 1160 if (connector_type == DRM_MODE_CONNECTOR_eDP)
@@ -1191,9 +1180,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1191 case DRM_MODE_CONNECTOR_9PinDIN: 1180 case DRM_MODE_CONNECTOR_9PinDIN:
1192 if (radeon_tv == 1) { 1181 if (radeon_tv == 1) {
1193 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1182 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1194 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1183 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1195 if (ret)
1196 goto failed;
1197 radeon_connector->dac_load_detect = true; 1184 radeon_connector->dac_load_detect = true;
1198 drm_connector_attach_property(&radeon_connector->base, 1185 drm_connector_attach_property(&radeon_connector->base,
1199 rdev->mode_info.load_detect_property, 1186 rdev->mode_info.load_detect_property,
@@ -1211,9 +1198,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1211 radeon_dig_connector->igp_lane_info = igp_lane_info; 1198 radeon_dig_connector->igp_lane_info = igp_lane_info;
1212 radeon_connector->con_priv = radeon_dig_connector; 1199 radeon_connector->con_priv = radeon_dig_connector;
1213 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1200 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1214 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 1201 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
1215 if (ret)
1216 goto failed;
1217 if (i2c_bus->valid) { 1202 if (i2c_bus->valid) {
1218 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); 1203 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
1219 if (!radeon_connector->ddc_bus) 1204 if (!radeon_connector->ddc_bus)
@@ -1250,7 +1235,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
1250 struct drm_connector *connector; 1235 struct drm_connector *connector;
1251 struct radeon_connector *radeon_connector; 1236 struct radeon_connector *radeon_connector;
1252 uint32_t subpixel_order = SubPixelNone; 1237 uint32_t subpixel_order = SubPixelNone;
1253 int ret;
1254 1238
1255 /* fixme - tv/cv/din */ 1239 /* fixme - tv/cv/din */
1256 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1240 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
@@ -1278,9 +1262,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1278 switch (connector_type) { 1262 switch (connector_type) {
1279 case DRM_MODE_CONNECTOR_VGA: 1263 case DRM_MODE_CONNECTOR_VGA:
1280 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1264 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1281 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1265 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1282 if (ret)
1283 goto failed;
1284 if (i2c_bus->valid) { 1266 if (i2c_bus->valid) {
1285 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); 1267 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
1286 if (!radeon_connector->ddc_bus) 1268 if (!radeon_connector->ddc_bus)
@@ -1293,9 +1275,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1293 break; 1275 break;
1294 case DRM_MODE_CONNECTOR_DVIA: 1276 case DRM_MODE_CONNECTOR_DVIA:
1295 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1277 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1296 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1278 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1297 if (ret)
1298 goto failed;
1299 if (i2c_bus->valid) { 1279 if (i2c_bus->valid) {
1300 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1280 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1301 if (!radeon_connector->ddc_bus) 1281 if (!radeon_connector->ddc_bus)
@@ -1309,9 +1289,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1309 case DRM_MODE_CONNECTOR_DVII: 1289 case DRM_MODE_CONNECTOR_DVII:
1310 case DRM_MODE_CONNECTOR_DVID: 1290 case DRM_MODE_CONNECTOR_DVID:
1311 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1291 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1312 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1292 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1313 if (ret)
1314 goto failed;
1315 if (i2c_bus->valid) { 1293 if (i2c_bus->valid) {
1316 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1294 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1317 if (!radeon_connector->ddc_bus) 1295 if (!radeon_connector->ddc_bus)
@@ -1328,9 +1306,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1328 case DRM_MODE_CONNECTOR_9PinDIN: 1306 case DRM_MODE_CONNECTOR_9PinDIN:
1329 if (radeon_tv == 1) { 1307 if (radeon_tv == 1) {
1330 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1308 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1331 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1309 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1332 if (ret)
1333 goto failed;
1334 radeon_connector->dac_load_detect = true; 1310 radeon_connector->dac_load_detect = true;
1335 /* RS400,RC410,RS480 chipset seems to report a lot 1311 /* RS400,RC410,RS480 chipset seems to report a lot
1336 * of false positive on load detect, we haven't yet 1312 * of false positive on load detect, we haven't yet
@@ -1349,9 +1325,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
1349 break; 1325 break;
1350 case DRM_MODE_CONNECTOR_LVDS: 1326 case DRM_MODE_CONNECTOR_LVDS:
1351 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1327 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1352 ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 1328 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
1353 if (ret)
1354 goto failed;
1355 if (i2c_bus->valid) { 1329 if (i2c_bus->valid) {
1356 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); 1330 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
1357 if (!radeon_connector->ddc_bus) 1331 if (!radeon_connector->ddc_bus)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 001779d678b5..26217ffe0355 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -730,9 +730,10 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
730 continue; 730 continue;
731 } 731 }
732 robj = rfb->obj->driver_private; 732 robj = rfb->obj->driver_private;
733 if (robj != rdev->fbdev_rbo) { 733 /* don't unpin kernel fb objects */
734 if (!radeon_fbdev_robj_is_fb(rdev, robj)) {
734 r = radeon_bo_reserve(robj, false); 735 r = radeon_bo_reserve(robj, false);
735 if (unlikely(r == 0)) { 736 if (r == 0) {
736 radeon_bo_unpin(robj); 737 radeon_bo_unpin(robj);
737 radeon_bo_unreserve(robj); 738 radeon_bo_unreserve(robj);
738 } 739 }
@@ -757,7 +758,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
757 pci_set_power_state(dev->pdev, PCI_D3hot); 758 pci_set_power_state(dev->pdev, PCI_D3hot);
758 } 759 }
759 acquire_console_sem(); 760 acquire_console_sem();
760 fb_set_suspend(rdev->fbdev_info, 1); 761 radeon_fbdev_set_suspend(rdev, 1);
761 release_console_sem(); 762 release_console_sem();
762 return 0; 763 return 0;
763} 764}
@@ -781,7 +782,7 @@ int radeon_resume_kms(struct drm_device *dev)
781 radeon_agp_resume(rdev); 782 radeon_agp_resume(rdev);
782 radeon_resume(rdev); 783 radeon_resume(rdev);
783 radeon_restore_bios_scratch_regs(rdev); 784 radeon_restore_bios_scratch_regs(rdev);
784 fb_set_suspend(rdev->fbdev_info, 0); 785 radeon_fbdev_set_suspend(rdev, 0);
785 release_console_sem(); 786 release_console_sem();
786 787
787 /* reset hpd state */ 788 /* reset hpd state */
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index b8d672828246..243c1c4bc836 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -831,10 +831,6 @@ void radeon_compute_pll(struct radeon_pll *pll,
831static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) 831static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
832{ 832{
833 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 833 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
834 struct drm_device *dev = fb->dev;
835
836 if (fb->fbdev)
837 radeonfb_remove(dev, fb);
838 834
839 if (radeon_fb->obj) 835 if (radeon_fb->obj)
840 drm_gem_object_unreference_unlocked(radeon_fb->obj); 836 drm_gem_object_unreference_unlocked(radeon_fb->obj);
@@ -856,21 +852,15 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
856 .create_handle = radeon_user_framebuffer_create_handle, 852 .create_handle = radeon_user_framebuffer_create_handle,
857}; 853};
858 854
859struct drm_framebuffer * 855void
860radeon_framebuffer_create(struct drm_device *dev, 856radeon_framebuffer_init(struct drm_device *dev,
861 struct drm_mode_fb_cmd *mode_cmd, 857 struct radeon_framebuffer *rfb,
862 struct drm_gem_object *obj) 858 struct drm_mode_fb_cmd *mode_cmd,
859 struct drm_gem_object *obj)
863{ 860{
864 struct radeon_framebuffer *radeon_fb; 861 rfb->obj = obj;
865 862 drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
866 radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); 863 drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
867 if (radeon_fb == NULL) {
868 return NULL;
869 }
870 drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs);
871 drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd);
872 radeon_fb->obj = obj;
873 return &radeon_fb->base;
874} 864}
875 865
876static struct drm_framebuffer * 866static struct drm_framebuffer *
@@ -879,6 +869,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
879 struct drm_mode_fb_cmd *mode_cmd) 869 struct drm_mode_fb_cmd *mode_cmd)
880{ 870{
881 struct drm_gem_object *obj; 871 struct drm_gem_object *obj;
872 struct radeon_framebuffer *radeon_fb;
882 873
883 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 874 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
884 if (obj == NULL) { 875 if (obj == NULL) {
@@ -886,12 +877,19 @@ radeon_user_framebuffer_create(struct drm_device *dev,
886 "can't create framebuffer\n", mode_cmd->handle); 877 "can't create framebuffer\n", mode_cmd->handle);
887 return NULL; 878 return NULL;
888 } 879 }
889 return radeon_framebuffer_create(dev, mode_cmd, obj); 880
881 radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
882 if (radeon_fb == NULL) {
883 return NULL;
884 }
885
886 radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
887
888 return &radeon_fb->base;
890} 889}
891 890
892static const struct drm_mode_config_funcs radeon_mode_funcs = { 891static const struct drm_mode_config_funcs radeon_mode_funcs = {
893 .fb_create = radeon_user_framebuffer_create, 892 .fb_create = radeon_user_framebuffer_create,
894 .fb_changed = radeonfb_probe,
895}; 893};
896 894
897struct drm_prop_enum_list { 895struct drm_prop_enum_list {
@@ -1031,12 +1029,14 @@ int radeon_modeset_init(struct radeon_device *rdev)
1031 } 1029 }
1032 /* initialize hpd */ 1030 /* initialize hpd */
1033 radeon_hpd_init(rdev); 1031 radeon_hpd_init(rdev);
1034 drm_helper_initial_config(rdev->ddev); 1032
1033 radeon_fbdev_init(rdev);
1035 return 0; 1034 return 0;
1036} 1035}
1037 1036
1038void radeon_modeset_fini(struct radeon_device *rdev) 1037void radeon_modeset_fini(struct radeon_device *rdev)
1039{ 1038{
1039 radeon_fbdev_fini(rdev);
1040 kfree(rdev->mode_info.bios_hardcoded_edid); 1040 kfree(rdev->mode_info.bios_hardcoded_edid);
1041 1041
1042 if (rdev->mode_info.mode_config_initialized) { 1042 if (rdev->mode_info.mode_config_initialized) {
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 9ac57a09784b..fcb5b52727b0 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -23,10 +23,6 @@
23 * Authors: 23 * Authors:
24 * David Airlie 24 * David Airlie
25 */ 25 */
26 /*
27 * Modularization
28 */
29
30#include <linux/module.h> 26#include <linux/module.h>
31#include <linux/slab.h> 27#include <linux/slab.h>
32#include <linux/fb.h> 28#include <linux/fb.h>
@@ -42,17 +38,21 @@
42 38
43#include <linux/vga_switcheroo.h> 39#include <linux/vga_switcheroo.h>
44 40
45struct radeon_fb_device { 41/* object hierarchy -
42 this contains a helper + a radeon fb
43 the helper contains a pointer to radeon framebuffer baseclass.
44*/
45struct radeon_fbdev {
46 struct drm_fb_helper helper; 46 struct drm_fb_helper helper;
47 struct radeon_framebuffer *rfb; 47 struct radeon_framebuffer rfb;
48 struct radeon_device *rdev; 48 struct list_head fbdev_list;
49 struct radeon_device *rdev;
49}; 50};
50 51
51static struct fb_ops radeonfb_ops = { 52static struct fb_ops radeonfb_ops = {
52 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
53 .fb_check_var = drm_fb_helper_check_var, 54 .fb_check_var = drm_fb_helper_check_var,
54 .fb_set_par = drm_fb_helper_set_par, 55 .fb_set_par = drm_fb_helper_set_par,
55 .fb_setcolreg = drm_fb_helper_setcolreg,
56 .fb_fillrect = cfb_fillrect, 56 .fb_fillrect = cfb_fillrect,
57 .fb_copyarea = cfb_copyarea, 57 .fb_copyarea = cfb_copyarea,
58 .fb_imageblit = cfb_imageblit, 58 .fb_imageblit = cfb_imageblit,
@@ -61,45 +61,6 @@ static struct fb_ops radeonfb_ops = {
61 .fb_setcmap = drm_fb_helper_setcmap, 61 .fb_setcmap = drm_fb_helper_setcmap,
62}; 62};
63 63
64/**
65 * Currently it is assumed that the old framebuffer is reused.
66 *
67 * LOCKING
68 * caller should hold the mode config lock.
69 *
70 */
71int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
72{
73 struct fb_info *info;
74 struct drm_framebuffer *fb;
75 struct drm_display_mode *mode = crtc->desired_mode;
76
77 fb = crtc->fb;
78 if (fb == NULL) {
79 return 1;
80 }
81 info = fb->fbdev;
82 if (info == NULL) {
83 return 1;
84 }
85 if (mode == NULL) {
86 return 1;
87 }
88 info->var.xres = mode->hdisplay;
89 info->var.right_margin = mode->hsync_start - mode->hdisplay;
90 info->var.hsync_len = mode->hsync_end - mode->hsync_start;
91 info->var.left_margin = mode->htotal - mode->hsync_end;
92 info->var.yres = mode->vdisplay;
93 info->var.lower_margin = mode->vsync_start - mode->vdisplay;
94 info->var.vsync_len = mode->vsync_end - mode->vsync_start;
95 info->var.upper_margin = mode->vtotal - mode->vsync_end;
96 info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
97 /* avoid overflow */
98 info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
99
100 return 0;
101}
102EXPORT_SYMBOL(radeonfb_resize);
103 64
104static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) 65static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
105{ 66{
@@ -125,57 +86,44 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
125 return aligned; 86 return aligned;
126} 87}
127 88
128static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { 89static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
129 .gamma_set = radeon_crtc_fb_gamma_set, 90{
130 .gamma_get = radeon_crtc_fb_gamma_get, 91 struct radeon_bo *rbo = gobj->driver_private;
131}; 92 int ret;
93
94 ret = radeon_bo_reserve(rbo, false);
95 if (likely(ret == 0)) {
96 radeon_bo_kunmap(rbo);
97 radeon_bo_unreserve(rbo);
98 }
99 drm_gem_object_unreference_unlocked(gobj);
100}
132 101
133int radeonfb_create(struct drm_device *dev, 102static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
134 uint32_t fb_width, uint32_t fb_height, 103 struct drm_mode_fb_cmd *mode_cmd,
135 uint32_t surface_width, uint32_t surface_height, 104 struct drm_gem_object **gobj_p)
136 uint32_t surface_depth, uint32_t surface_bpp,
137 struct drm_framebuffer **fb_p)
138{ 105{
139 struct radeon_device *rdev = dev->dev_private; 106 struct radeon_device *rdev = rfbdev->rdev;
140 struct fb_info *info;
141 struct radeon_fb_device *rfbdev;
142 struct drm_framebuffer *fb = NULL;
143 struct radeon_framebuffer *rfb;
144 struct drm_mode_fb_cmd mode_cmd;
145 struct drm_gem_object *gobj = NULL; 107 struct drm_gem_object *gobj = NULL;
146 struct radeon_bo *rbo = NULL; 108 struct radeon_bo *rbo = NULL;
147 struct device *device = &rdev->pdev->dev;
148 int size, aligned_size, ret;
149 u64 fb_gpuaddr;
150 void *fbptr = NULL;
151 unsigned long tmp;
152 bool fb_tiled = false; /* useful for testing */ 109 bool fb_tiled = false; /* useful for testing */
153 u32 tiling_flags = 0; 110 u32 tiling_flags = 0;
111 int ret;
112 int aligned_size, size;
154 113
155 mode_cmd.width = surface_width;
156 mode_cmd.height = surface_height;
157
158 /* avivo can't scanout real 24bpp */
159 if ((surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
160 surface_bpp = 32;
161
162 mode_cmd.bpp = surface_bpp;
163 /* need to align pitch with crtc limits */ 114 /* need to align pitch with crtc limits */
164 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); 115 mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8);
165 mode_cmd.depth = surface_depth;
166 116
167 size = mode_cmd.pitch * mode_cmd.height; 117 size = mode_cmd->pitch * mode_cmd->height;
168 aligned_size = ALIGN(size, PAGE_SIZE); 118 aligned_size = ALIGN(size, PAGE_SIZE);
169
170 ret = radeon_gem_object_create(rdev, aligned_size, 0, 119 ret = radeon_gem_object_create(rdev, aligned_size, 0,
171 RADEON_GEM_DOMAIN_VRAM, 120 RADEON_GEM_DOMAIN_VRAM,
172 false, ttm_bo_type_kernel, 121 false, ttm_bo_type_kernel,
173 &gobj); 122 &gobj);
174 if (ret) { 123 if (ret) {
175 printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", 124 printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
176 surface_width, surface_height); 125 aligned_size);
177 ret = -ENOMEM; 126 return -ENOMEM;
178 goto out;
179 } 127 }
180 rbo = gobj->driver_private; 128 rbo = gobj->driver_private;
181 129
@@ -183,7 +131,7 @@ int radeonfb_create(struct drm_device *dev,
183 tiling_flags = RADEON_TILING_MACRO; 131 tiling_flags = RADEON_TILING_MACRO;
184 132
185#ifdef __BIG_ENDIAN 133#ifdef __BIG_ENDIAN
186 switch (mode_cmd.bpp) { 134 switch (mode_cmd->bpp) {
187 case 32: 135 case 32:
188 tiling_flags |= RADEON_TILING_SWAP_32BIT; 136 tiling_flags |= RADEON_TILING_SWAP_32BIT;
189 break; 137 break;
@@ -196,57 +144,81 @@ int radeonfb_create(struct drm_device *dev,
196 144
197 if (tiling_flags) { 145 if (tiling_flags) {
198 ret = radeon_bo_set_tiling_flags(rbo, 146 ret = radeon_bo_set_tiling_flags(rbo,
199 tiling_flags | RADEON_TILING_SURFACE, 147 tiling_flags | RADEON_TILING_SURFACE,
200 mode_cmd.pitch); 148 mode_cmd->pitch);
201 if (ret) 149 if (ret)
202 dev_err(rdev->dev, "FB failed to set tiling flags\n"); 150 dev_err(rdev->dev, "FB failed to set tiling flags\n");
203 } 151 }
204 mutex_lock(&rdev->ddev->struct_mutex); 152
205 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); 153
206 if (fb == NULL) {
207 DRM_ERROR("failed to allocate fb.\n");
208 ret = -ENOMEM;
209 goto out_unref;
210 }
211 ret = radeon_bo_reserve(rbo, false); 154 ret = radeon_bo_reserve(rbo, false);
212 if (unlikely(ret != 0)) 155 if (unlikely(ret != 0))
213 goto out_unref; 156 goto out_unref;
214 ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); 157 ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, NULL);
215 if (ret) { 158 if (ret) {
216 radeon_bo_unreserve(rbo); 159 radeon_bo_unreserve(rbo);
217 goto out_unref; 160 goto out_unref;
218 } 161 }
219 if (fb_tiled) 162 if (fb_tiled)
220 radeon_bo_check_tiling(rbo, 0, 0); 163 radeon_bo_check_tiling(rbo, 0, 0);
221 ret = radeon_bo_kmap(rbo, &fbptr); 164 ret = radeon_bo_kmap(rbo, NULL);
222 radeon_bo_unreserve(rbo); 165 radeon_bo_unreserve(rbo);
223 if (ret) { 166 if (ret) {
224 goto out_unref; 167 goto out_unref;
225 } 168 }
226 169
227 list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); 170 *gobj_p = gobj;
171 return 0;
172out_unref:
173 radeonfb_destroy_pinned_object(gobj);
174 *gobj_p = NULL;
175 return ret;
176}
177
178static int radeonfb_create(struct radeon_fbdev *rfbdev,
179 struct drm_fb_helper_surface_size *sizes)
180{
181 struct radeon_device *rdev = rfbdev->rdev;
182 struct fb_info *info;
183 struct drm_framebuffer *fb = NULL;
184 struct drm_mode_fb_cmd mode_cmd;
185 struct drm_gem_object *gobj = NULL;
186 struct radeon_bo *rbo = NULL;
187 struct device *device = &rdev->pdev->dev;
188 int ret;
189 unsigned long tmp;
190
191 mode_cmd.width = sizes->surface_width;
192 mode_cmd.height = sizes->surface_height;
193
194 /* avivo can't scanout real 24bpp */
195 if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
196 sizes->surface_bpp = 32;
197
198 mode_cmd.bpp = sizes->surface_bpp;
199 mode_cmd.depth = sizes->surface_depth;
228 200
229 *fb_p = fb; 201 ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
230 rfb = to_radeon_framebuffer(fb); 202 rbo = gobj->driver_private;
231 rdev->fbdev_rfb = rfb;
232 rdev->fbdev_rbo = rbo;
233 203
234 info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); 204 /* okay we have an object now allocate the framebuffer */
205 info = framebuffer_alloc(0, device);
235 if (info == NULL) { 206 if (info == NULL) {
236 ret = -ENOMEM; 207 ret = -ENOMEM;
237 goto out_unref; 208 goto out_unref;
238 } 209 }
239 210
240 rdev->fbdev_info = info; 211 info->par = rfbdev;
241 rfbdev = info->par;
242 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
243 rfbdev->helper.dev = dev;
244 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, rdev->num_crtc,
245 RADEONFB_CONN_LIMIT);
246 if (ret)
247 goto out_unref;
248 212
249 memset_io(fbptr, 0x0, aligned_size); 213 radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
214
215 fb = &rfbdev->rfb.base;
216
217 /* setup helper */
218 rfbdev->helper.fb = fb;
219 rfbdev->helper.fbdev = info;
220
221 memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
250 222
251 strcpy(info->fix.id, "radeondrmfb"); 223 strcpy(info->fix.id, "radeondrmfb");
252 224
@@ -255,13 +227,13 @@ int radeonfb_create(struct drm_device *dev,
255 info->flags = FBINFO_DEFAULT; 227 info->flags = FBINFO_DEFAULT;
256 info->fbops = &radeonfb_ops; 228 info->fbops = &radeonfb_ops;
257 229
258 tmp = fb_gpuaddr - rdev->mc.vram_start; 230 tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
259 info->fix.smem_start = rdev->mc.aper_base + tmp; 231 info->fix.smem_start = rdev->mc.aper_base + tmp;
260 info->fix.smem_len = size; 232 info->fix.smem_len = radeon_bo_size(rbo);
261 info->screen_base = fbptr; 233 info->screen_base = rbo->kptr;
262 info->screen_size = size; 234 info->screen_size = radeon_bo_size(rbo);
263 235
264 drm_fb_helper_fill_var(info, fb, fb_width, fb_height); 236 drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
265 237
266 /* setup aperture base/size for vesafb takeover */ 238 /* setup aperture base/size for vesafb takeover */
267 info->aperture_base = rdev->ddev->mode_config.fb_base; 239 info->aperture_base = rdev->ddev->mode_config.fb_base;
@@ -274,44 +246,55 @@ int radeonfb_create(struct drm_device *dev,
274 info->pixmap.access_align = 32; 246 info->pixmap.access_align = 32;
275 info->pixmap.flags = FB_PIXMAP_SYSTEM; 247 info->pixmap.flags = FB_PIXMAP_SYSTEM;
276 info->pixmap.scan_align = 1; 248 info->pixmap.scan_align = 1;
249
277 if (info->screen_base == NULL) { 250 if (info->screen_base == NULL) {
278 ret = -ENOSPC; 251 ret = -ENOSPC;
279 goto out_unref; 252 goto out_unref;
280 } 253 }
254
255 ret = fb_alloc_cmap(&info->cmap, 256, 0);
256 if (ret) {
257 ret = -ENOMEM;
258 goto out_unref;
259 }
260
281 DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); 261 DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
282 DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); 262 DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base);
283 DRM_INFO("size %lu\n", (unsigned long)size); 263 DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
284 DRM_INFO("fb depth is %d\n", fb->depth); 264 DRM_INFO("fb depth is %d\n", fb->depth);
285 DRM_INFO(" pitch is %d\n", fb->pitch); 265 DRM_INFO(" pitch is %d\n", fb->pitch);
286 266
287 fb->fbdev = info;
288 rfbdev->rfb = rfb;
289 rfbdev->rdev = rdev;
290
291 mutex_unlock(&rdev->ddev->struct_mutex);
292 vga_switcheroo_client_fb_set(rdev->ddev->pdev, info); 267 vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
293 return 0; 268 return 0;
294 269
295out_unref: 270out_unref:
296 if (rbo) { 271 if (rbo) {
297 ret = radeon_bo_reserve(rbo, false); 272
298 if (likely(ret == 0)) {
299 radeon_bo_kunmap(rbo);
300 radeon_bo_unreserve(rbo);
301 }
302 } 273 }
303 if (fb && ret) { 274 if (fb && ret) {
304 list_del(&fb->filp_head);
305 drm_gem_object_unreference(gobj); 275 drm_gem_object_unreference(gobj);
306 drm_framebuffer_cleanup(fb); 276 drm_framebuffer_cleanup(fb);
307 kfree(fb); 277 kfree(fb);
308 } 278 }
309 drm_gem_object_unreference(gobj);
310 mutex_unlock(&rdev->ddev->struct_mutex);
311out:
312 return ret; 279 return ret;
313} 280}
314 281
282static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper,
283 struct drm_fb_helper_surface_size *sizes)
284{
285 struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper;
286 int new_fb = 0;
287 int ret;
288
289 if (!helper->fb) {
290 ret = radeonfb_create(rfbdev, sizes);
291 if (ret)
292 return ret;
293 new_fb = 1;
294 }
295 return new_fb;
296}
297
315static char *mode_option; 298static char *mode_option;
316int radeon_parse_options(char *options) 299int radeon_parse_options(char *options)
317{ 300{
@@ -328,46 +311,111 @@ int radeon_parse_options(char *options)
328 return 0; 311 return 0;
329} 312}
330 313
331int radeonfb_probe(struct drm_device *dev) 314void radeonfb_hotplug(struct drm_device *dev, bool polled)
332{ 315{
333 struct radeon_device *rdev = dev->dev_private; 316 struct radeon_device *rdev = dev->dev_private;
334 int bpp_sel = 32;
335 317
336 /* select 8 bpp console on RN50 or 16MB cards */ 318 drm_helper_fb_hpd_irq_event(&rdev->mode_info.rfbdev->helper);
337 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024)) 319}
338 bpp_sel = 8;
339 320
340 return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create); 321static void radeon_fb_output_status_changed(struct drm_fb_helper *fb_helper)
322{
323 drm_helper_fb_hotplug_event(fb_helper, true);
341} 324}
342 325
343int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) 326static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
344{ 327{
345 struct fb_info *info; 328 struct fb_info *info;
346 struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb); 329 struct radeon_framebuffer *rfb = &rfbdev->rfb;
347 struct radeon_bo *rbo; 330 struct radeon_bo *rbo;
348 int r; 331 int r;
349 332
350 if (!fb) { 333 if (rfbdev->helper.fbdev) {
351 return -EINVAL; 334 info = rfbdev->helper.fbdev;
335
336 unregister_framebuffer(info);
337 if (info->cmap.len)
338 fb_dealloc_cmap(&info->cmap);
339 framebuffer_release(info);
352 } 340 }
353 info = fb->fbdev; 341
354 if (info) { 342 if (rfb->obj) {
355 struct radeon_fb_device *rfbdev = info->par;
356 rbo = rfb->obj->driver_private; 343 rbo = rfb->obj->driver_private;
357 unregister_framebuffer(info);
358 r = radeon_bo_reserve(rbo, false); 344 r = radeon_bo_reserve(rbo, false);
359 if (likely(r == 0)) { 345 if (likely(r == 0)) {
360 radeon_bo_kunmap(rbo); 346 radeon_bo_kunmap(rbo);
361 radeon_bo_unpin(rbo); 347 radeon_bo_unpin(rbo);
362 radeon_bo_unreserve(rbo); 348 radeon_bo_unreserve(rbo);
363 } 349 }
364 drm_fb_helper_free(&rfbdev->helper); 350 drm_gem_object_unreference_unlocked(rfb->obj);
365 framebuffer_release(info);
366 } 351 }
352 drm_fb_helper_fini(&rfbdev->helper);
353 drm_framebuffer_cleanup(&rfb->base);
367 354
368 printk(KERN_INFO "unregistered panic notifier\n"); 355 return 0;
356}
369 357
358static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
359 .gamma_set = radeon_crtc_fb_gamma_set,
360 .gamma_get = radeon_crtc_fb_gamma_get,
361 .fb_probe = radeon_fb_find_or_create_single,
362 .fb_output_status_changed = radeon_fb_output_status_changed,
363};
364
365int radeon_fbdev_init(struct radeon_device *rdev)
366{
367 struct radeon_fbdev *rfbdev;
368 int bpp_sel = 32;
369
370 /* select 8 bpp console on RN50 or 16MB cards */
371 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
372 bpp_sel = 8;
373
374 rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
375 if (!rfbdev)
376 return -ENOMEM;
377
378 rfbdev->rdev = rdev;
379 rdev->mode_info.rfbdev = rfbdev;
380 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
381
382 drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
383 rdev->num_crtc,
384 RADEONFB_CONN_LIMIT, true);
385 drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
386 drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
370 return 0; 387 return 0;
388
389}
390
391void radeon_fbdev_fini(struct radeon_device *rdev)
392{
393 if (!rdev->mode_info.rfbdev)
394 return;
395
396 radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
397 kfree(rdev->mode_info.rfbdev);
398 rdev->mode_info.rfbdev = NULL;
399}
400
401void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
402{
403 fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
404}
405
406int radeon_fbdev_total_size(struct radeon_device *rdev)
407{
408 struct radeon_bo *robj;
409 int size = 0;
410
411 robj = rdev->mode_info.rfbdev->rfb.obj->driver_private;
412 size += radeon_bo_size(robj);
413 return size;
414}
415
416bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
417{
418 if (robj == rdev->mode_info.rfbdev->rfb.obj->driver_private)
419 return true;
420 return false;
371} 421}
372EXPORT_SYMBOL(radeonfb_remove);
373MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index ef92d147d8f0..28dd3e1b9c3a 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -158,8 +158,7 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
158 args->vram_visible = rdev->mc.real_vram_size; 158 args->vram_visible = rdev->mc.real_vram_size;
159 if (rdev->stollen_vga_memory) 159 if (rdev->stollen_vga_memory)
160 args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); 160 args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
161 if (rdev->fbdev_rbo) 161 args->vram_visible -= radeon_fbdev_total_size(rdev);
162 args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo);
163 args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 - 162 args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
164 RADEON_IB_POOL_SIZE*64*1024; 163 RADEON_IB_POOL_SIZE*64*1024;
165 return 0; 164 return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a212041e8b0b..a95907aa7eae 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -55,6 +55,8 @@ static void radeon_hotplug_work_func(struct work_struct *work)
55 radeon_connector_hotplug(connector); 55 radeon_connector_hotplug(connector);
56 } 56 }
57 /* Just fire off a uevent and let userspace tell us what to do */ 57 /* Just fire off a uevent and let userspace tell us what to do */
58 radeonfb_hotplug(dev, false);
59
58 drm_sysfs_hotplug_event(dev); 60 drm_sysfs_hotplug_event(dev);
59} 61}
60 62
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 0b8e32776b10..4a086c09e117 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -39,6 +39,7 @@
39#include <linux/i2c-algo-bit.h> 39#include <linux/i2c-algo-bit.h>
40#include "radeon_fixed.h" 40#include "radeon_fixed.h"
41 41
42struct radeon_bo;
42struct radeon_device; 43struct radeon_device;
43 44
44#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base) 45#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base)
@@ -202,6 +203,8 @@ enum radeon_dvo_chip {
202 DVO_SIL1178, 203 DVO_SIL1178,
203}; 204};
204 205
206struct radeon_fbdev;
207
205struct radeon_mode_info { 208struct radeon_mode_info {
206 struct atom_context *atom_context; 209 struct atom_context *atom_context;
207 struct card_info *atom_card_info; 210 struct card_info *atom_card_info;
@@ -218,6 +221,9 @@ struct radeon_mode_info {
218 struct drm_property *tmds_pll_property; 221 struct drm_property *tmds_pll_property;
219 /* hardcoded DFP edid from BIOS */ 222 /* hardcoded DFP edid from BIOS */
220 struct edid *bios_hardcoded_edid; 223 struct edid *bios_hardcoded_edid;
224
225 /* pointer to fbdev info structure */
226 struct radeon_fbdev *rfbdev;
221}; 227};
222 228
223#define MAX_H_CODE_TIMING_LEN 32 229#define MAX_H_CODE_TIMING_LEN 32
@@ -532,11 +538,10 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
532 u16 blue, int regno); 538 u16 blue, int regno);
533extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, 539extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
534 u16 *blue, int regno); 540 u16 *blue, int regno);
535struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, 541void radeon_framebuffer_init(struct drm_device *dev,
536 struct drm_mode_fb_cmd *mode_cmd, 542 struct radeon_framebuffer *rfb,
537 struct drm_gem_object *obj); 543 struct drm_mode_fb_cmd *mode_cmd,
538 544 struct drm_gem_object *obj);
539int radeonfb_probe(struct drm_device *dev);
540 545
541int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); 546int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
542bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev); 547bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev);
@@ -573,4 +578,12 @@ void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
573void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, 578void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
574 struct drm_display_mode *mode, 579 struct drm_display_mode *mode,
575 struct drm_display_mode *adjusted_mode); 580 struct drm_display_mode *adjusted_mode);
581
582/* fbdev layer */
583int radeon_fbdev_init(struct radeon_device *rdev);
584void radeon_fbdev_fini(struct radeon_device *rdev);
585void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
586int radeon_fbdev_total_size(struct radeon_device *rdev);
587bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
588void radeonfb_hotplug(struct drm_device *dev, bool polled);
576#endif 589#endif