X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fexynos%2Fexynos_drm_core.c;h=4c9f972eaa0771c0b2d9c5ff0f5480da3dc1e93d;hb=f37cd5e8098441af6447a87574fbb78eb5b4f9bf;hp=0e9e06ce36b860ae8fb5a91d40faf31d917b180a;hpb=121692eb0895c5c16f29f3b2141d2913021584ac;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 0e9e06ce36b8..4c9f972eaa07 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -19,21 +19,19 @@ #include "exynos_drm_fbdev.h" static LIST_HEAD(exynos_drm_subdrv_list); -static LIST_HEAD(exynos_drm_manager_list); -static LIST_HEAD(exynos_drm_display_list); -static int exynos_drm_create_enc_conn(struct drm_device *dev, +int exynos_drm_create_enc_conn(struct drm_device *dev, struct exynos_drm_display *display) { struct drm_encoder *encoder; - struct exynos_drm_manager *manager; int ret; unsigned long possible_crtcs = 0; - /* Find possible crtcs for this display */ - list_for_each_entry(manager, &exynos_drm_manager_list, list) - if (manager->type == display->type) - possible_crtcs |= 1 << manager->pipe; + ret = exynos_drm_crtc_get_pipe_from_type(dev, display->type); + if (ret < 0) + return ret; + + possible_crtcs |= 1 << ret; /* create and initialize a encoder for this sub driver. */ encoder = exynos_drm_encoder_create(dev, display, possible_crtcs); @@ -57,127 +55,29 @@ err_destroy_encoder: return ret; } -static int exynos_drm_subdrv_probe(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - if (subdrv->probe) { - int ret; - - subdrv->drm_dev = dev; - - /* - * this probe callback would be called by sub driver - * after setting of all resources to this sub driver, - * such as clock, irq and register map are done or by load() - * of exynos drm driver. - * - * P.S. note that this driver is considered for modularization. - */ - ret = subdrv->probe(dev, subdrv->dev); - if (ret) - return ret; - } - - return 0; -} - -static void exynos_drm_subdrv_remove(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - if (subdrv->remove) - subdrv->remove(dev, subdrv->dev); -} - -int exynos_drm_initialize_managers(struct drm_device *dev) +int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) { - struct exynos_drm_manager *manager, *n; - int ret, pipe = 0; - - list_for_each_entry(manager, &exynos_drm_manager_list, list) { - if (manager->ops->initialize) { - ret = manager->ops->initialize(manager, dev, pipe); - if (ret) { - DRM_ERROR("Mgr init [%d] failed with %d\n", - manager->type, ret); - goto err; - } - } + if (!subdrv) + return -EINVAL; - manager->drm_dev = dev; - manager->pipe = pipe++; + list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); - ret = exynos_drm_crtc_create(manager); - if (ret) { - DRM_ERROR("CRTC create [%d] failed with %d\n", - manager->type, ret); - goto err; - } - } return 0; - -err: - list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list) { - if (pipe-- > 0) - exynos_drm_manager_unregister(manager); - else - list_del(&manager->list); - } - return ret; -} - -void exynos_drm_remove_managers(struct drm_device *dev) -{ - struct exynos_drm_manager *manager, *n; - - list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list) - exynos_drm_manager_unregister(manager); } +EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register); -int exynos_drm_initialize_displays(struct drm_device *dev) +int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) { - struct exynos_drm_display *display, *n; - int ret, initialized = 0; - - list_for_each_entry(display, &exynos_drm_display_list, list) { - if (display->ops->initialize) { - ret = display->ops->initialize(display, dev); - if (ret) { - DRM_ERROR("Display init [%d] failed with %d\n", - display->type, ret); - goto err; - } - } + if (!subdrv) + return -EINVAL; - initialized++; + list_del(&subdrv->list); - ret = exynos_drm_create_enc_conn(dev, display); - if (ret) { - DRM_ERROR("Encoder create [%d] failed with %d\n", - display->type, ret); - goto err; - } - } return 0; - -err: - list_for_each_entry_safe(display, n, &exynos_drm_display_list, list) { - if (initialized-- > 0) - exynos_drm_display_unregister(display); - else - list_del(&display->list); - } - return ret; -} - -void exynos_drm_remove_displays(struct drm_device *dev) -{ - struct exynos_drm_display *display, *n; - - list_for_each_entry_safe(display, n, &exynos_drm_display_list, list) - exynos_drm_display_unregister(display); } +EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); -int exynos_drm_device_register(struct drm_device *dev) +int exynos_drm_device_subdrv_probe(struct drm_device *dev) { struct exynos_drm_subdrv *subdrv, *n; int err; @@ -186,19 +86,28 @@ int exynos_drm_device_register(struct drm_device *dev) return -EINVAL; list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { - err = exynos_drm_subdrv_probe(dev, subdrv); - if (err) { - DRM_DEBUG("exynos drm subdrv probe failed.\n"); - list_del(&subdrv->list); - continue; + if (subdrv->probe) { + subdrv->drm_dev = dev; + + /* + * this probe callback would be called by sub driver + * after setting of all resources to this sub driver, + * such as clock, irq and register map are done. + */ + err = subdrv->probe(dev, subdrv->dev); + if (err) { + DRM_DEBUG("exynos drm subdrv probe failed.\n"); + list_del(&subdrv->list); + continue; + } } } return 0; } -EXPORT_SYMBOL_GPL(exynos_drm_device_register); +EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_probe); -int exynos_drm_device_unregister(struct drm_device *dev) +int exynos_drm_device_subdrv_remove(struct drm_device *dev) { struct exynos_drm_subdrv *subdrv; @@ -208,66 +117,13 @@ int exynos_drm_device_unregister(struct drm_device *dev) } list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { - exynos_drm_subdrv_remove(dev, subdrv); + if (subdrv->remove) + subdrv->remove(dev, subdrv->dev); } return 0; } -EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); - -int exynos_drm_manager_register(struct exynos_drm_manager *manager) -{ - BUG_ON(!manager->ops); - list_add_tail(&manager->list, &exynos_drm_manager_list); - return 0; -} - -int exynos_drm_manager_unregister(struct exynos_drm_manager *manager) -{ - if (manager->ops->remove) - manager->ops->remove(manager); - - list_del(&manager->list); - return 0; -} - -int exynos_drm_display_register(struct exynos_drm_display *display) -{ - BUG_ON(!display->ops); - list_add_tail(&display->list, &exynos_drm_display_list); - return 0; -} - -int exynos_drm_display_unregister(struct exynos_drm_display *display) -{ - if (display->ops->remove) - display->ops->remove(display); - - list_del(&display->list); - return 0; -} - -int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) -{ - if (!subdrv) - return -EINVAL; - - list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register); - -int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) -{ - if (!subdrv) - return -EINVAL; - - list_del(&subdrv->list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); +EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_remove); int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) {