drm/tegra: Changes for v4.5-rc1
This adds support for the version of host1x found on Tegra210 SoCs. It also makes use of the new atomic suspend/resume functionality to bring this feature to Tegra. Other than that it's mostly small fixes and cleanups, with some prep- work for things that will hopefully get merged for the next release. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJWcZ2kAAoJEN0jrNd/PrOhkIMP+gIN8HuXN4p7LfpQ/SvOCios FvSz8qCAa00/PDVSUjykQtTeGwFyW/KXkQgsOXea8YignrZXHQkt/ldAS6D63+d6 NcHmu7S8Hd2D9K8yogaVccP3sILgrkatVl4WreqEVCvlD9v1pvhlw8Y9NHftSMop ghStN6QcKI/uT13MSqNI3LrfR/KfBb4g6QAZ5M+ElSN6+lOGkMGADv4a2wyIPfL0 nw3Vy0Zgq0qFwqLAKOPm89WFtKeZ0PSVPUT3bdKw82XPKJW7f20WoM8GWM3CQKVS gVcOGl1QJV/TEMnRsij3HvgU2KNAdyRCybdvGKJF+i0uFgXSDT0LKLxGOf6cDs7b TvnmBS0so8j/6bWo5Sj7gKC9LKFSuA282xTLBEE+PnZCAxHDoCH11tKplIvMH9Uy SaAnR8cwZnURu1ARflMK7AZFNiZXZTJYmP9qyiPT52HtU2xMIjWylnwsZVlmWNcz 9WxWt5Z6V2KtxXUuiqFbBjJl0I1ZUfKA1nyZsCGomBpqpj7RXU2ObrdcRZ1u2fMV 8ArRffd8lxFeLn0gDjopL3gUqWXV73Y/NerDAiHyoS6tLybvQg6AQaRuhonrFvcW kJabO6RDAxWMOwXmLca0IgX92DJXI373DHBSDeFW4ETs6yNT3Hc9fN5ZqyMr005G t0ym/jN1rVMUxHV67eTA =aaka -----END PGP SIGNATURE----- Merge tag 'drm/tegra/for-4.5-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next drm/tegra: Changes for v4.5-rc1 This adds support for the version of host1x found on Tegra210 SoCs. It also makes use of the new atomic suspend/resume functionality to bring this feature to Tegra. Other than that it's mostly small fixes and cleanups, with some prep- work for things that will hopefully get merged for the next release. * tag 'drm/tegra/for-4.5-rc1' of git://anongit.freedesktop.org/tegra/linux: drm/tegra: Advertise DRIVER_ATOMIC drm/tegra: Use DRIVER level for IOMMU aperture message drm/tegra: checking for IS_ERR() instead of NULL drm/tegra: dc: Add missing of_node_put() drm/tegra: Implement subsystem-level suspend/resume drm/tegra: sor: Remove unnecessary conditional drm/tegra: sor: Operate on struct drm_dp_aux * drm/tegra: Use drm_gem_object_unreference_unlocked() drm/tegra: Don't take dev->struct_mutex in mmap offset ioctl drm/tegra: Use unlocked gem unreferencing drm/tegra: Use new multi-driver module helpers gpu: host1x: Add Tegra210 support gpu: host1x: Remove core driver on unregister gpu: host1x: Use platform_register/unregister_drivers()
This commit is contained in:
commit
9a1123e894
|
@ -1955,8 +1955,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
|
|||
* cases where only a single display controller is used.
|
||||
*/
|
||||
for_each_matching_node(np, tegra_dc_of_match) {
|
||||
if (np == dc->dev->of_node)
|
||||
if (np == dc->dev->of_node) {
|
||||
of_node_put(np);
|
||||
break;
|
||||
}
|
||||
|
||||
value++;
|
||||
}
|
||||
|
|
|
@ -436,7 +436,7 @@ struct platform_driver tegra_dpaux_driver = {
|
|||
.remove = tegra_dpaux_remove,
|
||||
};
|
||||
|
||||
struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np)
|
||||
struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np)
|
||||
{
|
||||
struct tegra_dpaux *dpaux;
|
||||
|
||||
|
@ -445,7 +445,7 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np)
|
|||
list_for_each_entry(dpaux, &dpaux_list, list)
|
||||
if (np == dpaux->dev->of_node) {
|
||||
mutex_unlock(&dpaux_lock);
|
||||
return dpaux;
|
||||
return &dpaux->aux;
|
||||
}
|
||||
|
||||
mutex_unlock(&dpaux_lock);
|
||||
|
@ -453,8 +453,9 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output)
|
||||
int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = to_dpaux(aux);
|
||||
unsigned long timeout;
|
||||
int err;
|
||||
|
||||
|
@ -470,7 +471,7 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output)
|
|||
while (time_before(jiffies, timeout)) {
|
||||
enum drm_connector_status status;
|
||||
|
||||
status = tegra_dpaux_detect(dpaux);
|
||||
status = drm_dp_aux_detect(aux);
|
||||
if (status == connector_status_connected) {
|
||||
enable_irq(dpaux->irq);
|
||||
return 0;
|
||||
|
@ -482,8 +483,9 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
|
||||
int drm_dp_aux_detach(struct drm_dp_aux *aux)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = to_dpaux(aux);
|
||||
unsigned long timeout;
|
||||
int err;
|
||||
|
||||
|
@ -498,7 +500,7 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
|
|||
while (time_before(jiffies, timeout)) {
|
||||
enum drm_connector_status status;
|
||||
|
||||
status = tegra_dpaux_detect(dpaux);
|
||||
status = drm_dp_aux_detect(aux);
|
||||
if (status == connector_status_disconnected) {
|
||||
dpaux->output = NULL;
|
||||
return 0;
|
||||
|
@ -510,8 +512,9 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux)
|
||||
enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = to_dpaux(aux);
|
||||
u32 value;
|
||||
|
||||
value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
|
||||
|
@ -522,8 +525,9 @@ enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux)
|
|||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
int tegra_dpaux_enable(struct tegra_dpaux *dpaux)
|
||||
int drm_dp_aux_enable(struct drm_dp_aux *aux)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = to_dpaux(aux);
|
||||
u32 value;
|
||||
|
||||
value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
|
||||
|
@ -540,8 +544,9 @@ int tegra_dpaux_enable(struct tegra_dpaux *dpaux)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tegra_dpaux_disable(struct tegra_dpaux *dpaux)
|
||||
int drm_dp_aux_disable(struct drm_dp_aux *aux)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = to_dpaux(aux);
|
||||
u32 value;
|
||||
|
||||
value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
|
||||
|
@ -551,11 +556,11 @@ int tegra_dpaux_disable(struct tegra_dpaux *dpaux)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding)
|
||||
int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = drm_dp_dpcd_writeb(&dpaux->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
|
||||
err = drm_dp_dpcd_writeb(aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
|
||||
encoding);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -563,15 +568,15 @@ int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
|
||||
u8 pattern)
|
||||
int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
|
||||
u8 pattern)
|
||||
{
|
||||
u8 tp = pattern & DP_TRAINING_PATTERN_MASK;
|
||||
u8 status[DP_LINK_STATUS_SIZE], values[4];
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
err = drm_dp_dpcd_writeb(&dpaux->aux, DP_TRAINING_PATTERN_SET, pattern);
|
||||
err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET, pattern);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -584,14 +589,14 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
|
|||
DP_TRAIN_MAX_SWING_REACHED |
|
||||
DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
|
||||
|
||||
err = drm_dp_dpcd_write(&dpaux->aux, DP_TRAINING_LANE0_SET, values,
|
||||
err = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, values,
|
||||
link->num_lanes);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
usleep_range(500, 1000);
|
||||
|
||||
err = drm_dp_dpcd_read_link_status(&dpaux->aux, status);
|
||||
err = drm_dp_dpcd_read_link_status(aux, status);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -609,11 +614,11 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
|
|||
break;
|
||||
|
||||
default:
|
||||
dev_err(dpaux->dev, "unsupported training pattern %u\n", tp);
|
||||
dev_err(aux->dev, "unsupported training pattern %u\n", tp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = drm_dp_dpcd_writeb(&dpaux->aux, DP_EDP_CONFIGURATION_SET, 0);
|
||||
err = drm_dp_dpcd_writeb(aux, DP_EDP_CONFIGURATION_SET, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -137,8 +137,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
|
|||
start = geometry->aperture_start;
|
||||
end = geometry->aperture_end;
|
||||
|
||||
DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
|
||||
start, end);
|
||||
DRM_DEBUG_DRIVER("IOMMU aperture initialized (%#llx-%#llx)\n",
|
||||
start, end);
|
||||
drm_mm_init(&tegra->mm, start, end - start + 1);
|
||||
}
|
||||
|
||||
|
@ -277,9 +277,7 @@ host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
|
|||
if (!gem)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&drm->struct_mutex);
|
||||
drm_gem_object_unreference(gem);
|
||||
mutex_unlock(&drm->struct_mutex);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
bo = to_tegra_bo(gem);
|
||||
return &bo->base;
|
||||
|
@ -473,7 +471,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data,
|
|||
|
||||
args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -683,7 +681,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
|
|||
bo->tiling.mode = mode;
|
||||
bo->tiling.value = value;
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -723,7 +721,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
|
|||
break;
|
||||
}
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -748,7 +746,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data,
|
|||
if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
|
||||
bo->flags |= TEGRA_BO_BOTTOM_UP;
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -770,7 +768,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
|
|||
if (bo->flags & TEGRA_BO_BOTTOM_UP)
|
||||
args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -921,7 +919,8 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor)
|
|||
#endif
|
||||
|
||||
static struct drm_driver tegra_drm_driver = {
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
|
||||
DRIVER_ATOMIC,
|
||||
.load = tegra_drm_load,
|
||||
.unload = tegra_drm_unload,
|
||||
.open = tegra_drm_open,
|
||||
|
@ -1023,8 +1022,17 @@ static int host1x_drm_remove(struct host1x_device *dev)
|
|||
static int host1x_drm_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
|
||||
drm_kms_helper_poll_disable(drm);
|
||||
tegra_drm_fb_suspend(drm);
|
||||
|
||||
tegra->state = drm_atomic_helper_suspend(drm);
|
||||
if (IS_ERR(tegra->state)) {
|
||||
tegra_drm_fb_resume(drm);
|
||||
drm_kms_helper_poll_enable(drm);
|
||||
return PTR_ERR(tegra->state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1032,7 +1040,10 @@ static int host1x_drm_suspend(struct device *dev)
|
|||
static int host1x_drm_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
|
||||
drm_atomic_helper_resume(drm, tegra->state);
|
||||
tegra_drm_fb_resume(drm);
|
||||
drm_kms_helper_poll_enable(drm);
|
||||
|
||||
return 0;
|
||||
|
@ -1076,6 +1087,16 @@ static struct host1x_driver host1x_drm_driver = {
|
|||
.subdevs = host1x_drm_subdevs,
|
||||
};
|
||||
|
||||
static struct platform_driver * const drivers[] = {
|
||||
&tegra_dc_driver,
|
||||
&tegra_hdmi_driver,
|
||||
&tegra_dsi_driver,
|
||||
&tegra_dpaux_driver,
|
||||
&tegra_sor_driver,
|
||||
&tegra_gr2d_driver,
|
||||
&tegra_gr3d_driver,
|
||||
};
|
||||
|
||||
static int __init host1x_drm_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -1084,48 +1105,12 @@ static int __init host1x_drm_init(void)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = platform_driver_register(&tegra_dc_driver);
|
||||
err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
if (err < 0)
|
||||
goto unregister_host1x;
|
||||
|
||||
err = platform_driver_register(&tegra_dsi_driver);
|
||||
if (err < 0)
|
||||
goto unregister_dc;
|
||||
|
||||
err = platform_driver_register(&tegra_sor_driver);
|
||||
if (err < 0)
|
||||
goto unregister_dsi;
|
||||
|
||||
err = platform_driver_register(&tegra_hdmi_driver);
|
||||
if (err < 0)
|
||||
goto unregister_sor;
|
||||
|
||||
err = platform_driver_register(&tegra_dpaux_driver);
|
||||
if (err < 0)
|
||||
goto unregister_hdmi;
|
||||
|
||||
err = platform_driver_register(&tegra_gr2d_driver);
|
||||
if (err < 0)
|
||||
goto unregister_dpaux;
|
||||
|
||||
err = platform_driver_register(&tegra_gr3d_driver);
|
||||
if (err < 0)
|
||||
goto unregister_gr2d;
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_gr2d:
|
||||
platform_driver_unregister(&tegra_gr2d_driver);
|
||||
unregister_dpaux:
|
||||
platform_driver_unregister(&tegra_dpaux_driver);
|
||||
unregister_hdmi:
|
||||
platform_driver_unregister(&tegra_hdmi_driver);
|
||||
unregister_sor:
|
||||
platform_driver_unregister(&tegra_sor_driver);
|
||||
unregister_dsi:
|
||||
platform_driver_unregister(&tegra_dsi_driver);
|
||||
unregister_dc:
|
||||
platform_driver_unregister(&tegra_dc_driver);
|
||||
unregister_host1x:
|
||||
host1x_driver_unregister(&host1x_drm_driver);
|
||||
return err;
|
||||
|
@ -1134,13 +1119,7 @@ module_init(host1x_drm_init);
|
|||
|
||||
static void __exit host1x_drm_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tegra_gr3d_driver);
|
||||
platform_driver_unregister(&tegra_gr2d_driver);
|
||||
platform_driver_unregister(&tegra_dpaux_driver);
|
||||
platform_driver_unregister(&tegra_hdmi_driver);
|
||||
platform_driver_unregister(&tegra_sor_driver);
|
||||
platform_driver_unregister(&tegra_dsi_driver);
|
||||
platform_driver_unregister(&tegra_dc_driver);
|
||||
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
host1x_driver_unregister(&host1x_drm_driver);
|
||||
}
|
||||
module_exit(host1x_drm_exit);
|
||||
|
|
|
@ -57,6 +57,8 @@ struct tegra_drm {
|
|||
struct work_struct work;
|
||||
struct mutex lock;
|
||||
} commit;
|
||||
|
||||
struct drm_atomic_state *state;
|
||||
};
|
||||
|
||||
struct tegra_drm_client;
|
||||
|
@ -247,18 +249,17 @@ void tegra_output_connector_destroy(struct drm_connector *connector);
|
|||
void tegra_output_encoder_destroy(struct drm_encoder *encoder);
|
||||
|
||||
/* from dpaux.c */
|
||||
struct tegra_dpaux;
|
||||
struct drm_dp_link;
|
||||
|
||||
struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np);
|
||||
enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux);
|
||||
int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output);
|
||||
int tegra_dpaux_detach(struct tegra_dpaux *dpaux);
|
||||
int tegra_dpaux_enable(struct tegra_dpaux *dpaux);
|
||||
int tegra_dpaux_disable(struct tegra_dpaux *dpaux);
|
||||
int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding);
|
||||
int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
|
||||
u8 pattern);
|
||||
struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np);
|
||||
enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux);
|
||||
int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output);
|
||||
int drm_dp_aux_detach(struct drm_dp_aux *aux);
|
||||
int drm_dp_aux_enable(struct drm_dp_aux *aux);
|
||||
int drm_dp_aux_disable(struct drm_dp_aux *aux);
|
||||
int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding);
|
||||
int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
|
||||
u8 pattern);
|
||||
|
||||
/* from fb.c */
|
||||
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
|
||||
|
@ -273,16 +274,18 @@ int tegra_drm_fb_prepare(struct drm_device *drm);
|
|||
void tegra_drm_fb_free(struct drm_device *drm);
|
||||
int tegra_drm_fb_init(struct drm_device *drm);
|
||||
void tegra_drm_fb_exit(struct drm_device *drm);
|
||||
void tegra_drm_fb_suspend(struct drm_device *drm);
|
||||
void tegra_drm_fb_resume(struct drm_device *drm);
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
|
||||
void tegra_fb_output_poll_changed(struct drm_device *drm);
|
||||
#endif
|
||||
|
||||
extern struct platform_driver tegra_dc_driver;
|
||||
extern struct platform_driver tegra_dsi_driver;
|
||||
extern struct platform_driver tegra_sor_driver;
|
||||
extern struct platform_driver tegra_hdmi_driver;
|
||||
extern struct platform_driver tegra_dsi_driver;
|
||||
extern struct platform_driver tegra_dpaux_driver;
|
||||
extern struct platform_driver tegra_sor_driver;
|
||||
extern struct platform_driver tegra_gr2d_driver;
|
||||
extern struct platform_driver tegra_gr3d_driver;
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/console.h>
|
||||
|
||||
#include "drm.h"
|
||||
#include "gem.h"
|
||||
|
||||
|
@ -413,3 +415,25 @@ void tegra_drm_fb_exit(struct drm_device *drm)
|
|||
tegra_fbdev_exit(tegra->fbdev);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tegra_drm_fb_suspend(struct drm_device *drm)
|
||||
{
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
|
||||
console_lock();
|
||||
drm_fb_helper_set_suspend(&tegra->fbdev->base, 1);
|
||||
console_unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tegra_drm_fb_resume(struct drm_device *drm)
|
||||
{
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
|
||||
console_lock();
|
||||
drm_fb_helper_set_suspend(&tegra->fbdev->base, 0);
|
||||
console_unlock();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -28,11 +28,8 @@ static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
|
|||
static void tegra_bo_put(struct host1x_bo *bo)
|
||||
{
|
||||
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
|
||||
struct drm_device *drm = obj->gem.dev;
|
||||
|
||||
mutex_lock(&drm->struct_mutex);
|
||||
drm_gem_object_unreference(&obj->gem);
|
||||
mutex_unlock(&drm->struct_mutex);
|
||||
drm_gem_object_unreference_unlocked(&obj->gem);
|
||||
}
|
||||
|
||||
static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
|
||||
|
@ -72,11 +69,8 @@ static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page,
|
|||
static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
|
||||
{
|
||||
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
|
||||
struct drm_device *drm = obj->gem.dev;
|
||||
|
||||
mutex_lock(&drm->struct_mutex);
|
||||
drm_gem_object_reference(&obj->gem);
|
||||
mutex_unlock(&drm->struct_mutex);
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
@ -408,12 +402,9 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
|
|||
struct drm_gem_object *gem;
|
||||
struct tegra_bo *bo;
|
||||
|
||||
mutex_lock(&drm->struct_mutex);
|
||||
|
||||
gem = drm_gem_object_lookup(drm, file, handle);
|
||||
if (!gem) {
|
||||
dev_err(drm->dev, "failed to lookup GEM object\n");
|
||||
mutex_unlock(&drm->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -421,9 +412,7 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
|
|||
|
||||
*offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
|
||||
|
||||
drm_gem_object_unreference(gem);
|
||||
|
||||
mutex_unlock(&drm->struct_mutex);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ struct tegra_sor {
|
|||
struct clk *clk_dp;
|
||||
struct clk *clk;
|
||||
|
||||
struct tegra_dpaux *dpaux;
|
||||
struct drm_dp_aux *aux;
|
||||
|
||||
struct drm_info_list *debugfs_files;
|
||||
struct drm_minor *minor;
|
||||
|
@ -273,7 +273,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
|
|||
SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);
|
||||
tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
|
||||
|
||||
err = tegra_dpaux_prepare(sor->dpaux, DP_SET_ANSI_8B10B);
|
||||
err = drm_dp_aux_prepare(sor->aux, DP_SET_ANSI_8B10B);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -288,7 +288,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
|
|||
|
||||
pattern = DP_TRAINING_PATTERN_1;
|
||||
|
||||
err = tegra_dpaux_train(sor->dpaux, link, pattern);
|
||||
err = drm_dp_aux_train(sor->aux, link, pattern);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -309,7 +309,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
|
|||
|
||||
pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2;
|
||||
|
||||
err = tegra_dpaux_train(sor->dpaux, link, pattern);
|
||||
err = drm_dp_aux_train(sor->aux, link, pattern);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -324,7 +324,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
|
|||
|
||||
pattern = DP_TRAINING_PATTERN_DISABLE;
|
||||
|
||||
err = tegra_dpaux_train(sor->dpaux, link, pattern);
|
||||
err = drm_dp_aux_train(sor->aux, link, pattern);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1044,8 +1044,8 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force)
|
|||
struct tegra_output *output = connector_to_output(connector);
|
||||
struct tegra_sor *sor = to_sor(output);
|
||||
|
||||
if (sor->dpaux)
|
||||
return tegra_dpaux_detect(sor->dpaux);
|
||||
if (sor->aux)
|
||||
return drm_dp_aux_detect(sor->aux);
|
||||
|
||||
return tegra_output_connector_detect(connector, force);
|
||||
}
|
||||
|
@ -1066,13 +1066,13 @@ static int tegra_sor_connector_get_modes(struct drm_connector *connector)
|
|||
struct tegra_sor *sor = to_sor(output);
|
||||
int err;
|
||||
|
||||
if (sor->dpaux)
|
||||
tegra_dpaux_enable(sor->dpaux);
|
||||
if (sor->aux)
|
||||
drm_dp_aux_enable(sor->aux);
|
||||
|
||||
err = tegra_output_connector_get_modes(connector);
|
||||
|
||||
if (sor->dpaux)
|
||||
tegra_dpaux_disable(sor->dpaux);
|
||||
if (sor->aux)
|
||||
drm_dp_aux_disable(sor->aux);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1128,8 +1128,8 @@ static void tegra_sor_edp_disable(struct drm_encoder *encoder)
|
|||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to power down SOR: %d\n", err);
|
||||
|
||||
if (sor->dpaux) {
|
||||
err = tegra_dpaux_disable(sor->dpaux);
|
||||
if (sor->aux) {
|
||||
err = drm_dp_aux_disable(sor->aux);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to disable DP: %d\n", err);
|
||||
}
|
||||
|
@ -1196,7 +1196,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
|
|||
struct tegra_sor *sor = to_sor(output);
|
||||
struct tegra_sor_config config;
|
||||
struct drm_dp_link link;
|
||||
struct drm_dp_aux *aux;
|
||||
u8 rate, lanes;
|
||||
int err = 0;
|
||||
u32 value;
|
||||
|
||||
|
@ -1209,20 +1209,14 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
|
|||
if (output->panel)
|
||||
drm_panel_prepare(output->panel);
|
||||
|
||||
/* FIXME: properly convert to struct drm_dp_aux */
|
||||
aux = (struct drm_dp_aux *)sor->dpaux;
|
||||
err = drm_dp_aux_enable(sor->aux);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to enable DP: %d\n", err);
|
||||
|
||||
if (sor->dpaux) {
|
||||
err = tegra_dpaux_enable(sor->dpaux);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to enable DP: %d\n", err);
|
||||
|
||||
err = drm_dp_link_probe(aux, &link);
|
||||
if (err < 0) {
|
||||
dev_err(sor->dev, "failed to probe eDP link: %d\n",
|
||||
err);
|
||||
return;
|
||||
}
|
||||
err = drm_dp_link_probe(sor->aux, &link);
|
||||
if (err < 0) {
|
||||
dev_err(sor->dev, "failed to probe eDP link: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = clk_set_parent(sor->clk, sor->clk_safe);
|
||||
|
@ -1434,61 +1428,52 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
|
|||
value |= SOR_DP_PADCTL_PAD_CAL_PD;
|
||||
tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
|
||||
|
||||
if (sor->dpaux) {
|
||||
u8 rate, lanes;
|
||||
err = drm_dp_link_probe(sor->aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to probe eDP link: %d\n", err);
|
||||
|
||||
err = drm_dp_link_probe(aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to probe eDP link: %d\n",
|
||||
err);
|
||||
err = drm_dp_link_power_up(sor->aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to power up eDP link: %d\n", err);
|
||||
|
||||
err = drm_dp_link_power_up(aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to power up eDP link: %d\n",
|
||||
err);
|
||||
err = drm_dp_link_configure(sor->aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to configure eDP link: %d\n", err);
|
||||
|
||||
err = drm_dp_link_configure(aux, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to configure eDP link: %d\n",
|
||||
err);
|
||||
rate = drm_dp_link_rate_to_bw_code(link.rate);
|
||||
lanes = link.num_lanes;
|
||||
|
||||
rate = drm_dp_link_rate_to_bw_code(link.rate);
|
||||
lanes = link.num_lanes;
|
||||
value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
|
||||
value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
|
||||
value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
|
||||
tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
|
||||
|
||||
value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
|
||||
value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
|
||||
value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
|
||||
tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
|
||||
value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
|
||||
value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
|
||||
value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
|
||||
|
||||
value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
|
||||
value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
|
||||
value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
|
||||
if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
|
||||
value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
|
||||
|
||||
if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
|
||||
value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
|
||||
tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
|
||||
|
||||
tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
|
||||
/* disable training pattern generator */
|
||||
|
||||
/* disable training pattern generator */
|
||||
|
||||
for (i = 0; i < link.num_lanes; i++) {
|
||||
unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
|
||||
SOR_DP_TPG_SCRAMBLER_GALIOS |
|
||||
SOR_DP_TPG_PATTERN_NONE;
|
||||
value = (value << 8) | lane;
|
||||
}
|
||||
|
||||
tegra_sor_writel(sor, value, SOR_DP_TPG);
|
||||
|
||||
err = tegra_sor_dp_train_fast(sor, &link);
|
||||
if (err < 0) {
|
||||
dev_err(sor->dev, "DP fast link training failed: %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
dev_dbg(sor->dev, "fast link training succeeded\n");
|
||||
for (i = 0; i < link.num_lanes; i++) {
|
||||
unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
|
||||
SOR_DP_TPG_SCRAMBLER_GALIOS |
|
||||
SOR_DP_TPG_PATTERN_NONE;
|
||||
value = (value << 8) | lane;
|
||||
}
|
||||
|
||||
tegra_sor_writel(sor, value, SOR_DP_TPG);
|
||||
|
||||
err = tegra_sor_dp_train_fast(sor, &link);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "DP fast link training failed: %d\n", err);
|
||||
|
||||
dev_dbg(sor->dev, "fast link training succeeded\n");
|
||||
|
||||
err = tegra_sor_power_up(sor, 250);
|
||||
if (err < 0)
|
||||
dev_err(sor->dev, "failed to power up SOR: %d\n", err);
|
||||
|
@ -1961,9 +1946,9 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
|
|||
|
||||
/* production settings */
|
||||
settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);
|
||||
if (IS_ERR(settings)) {
|
||||
dev_err(sor->dev, "no settings for pixel clock %d Hz: %ld\n",
|
||||
mode->clock * 1000, PTR_ERR(settings));
|
||||
if (!settings) {
|
||||
dev_err(sor->dev, "no settings for pixel clock %d Hz\n",
|
||||
mode->clock * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2148,7 +2133,7 @@ static int tegra_sor_init(struct host1x_client *client)
|
|||
int encoder = DRM_MODE_ENCODER_NONE;
|
||||
int err;
|
||||
|
||||
if (!sor->dpaux) {
|
||||
if (!sor->aux) {
|
||||
if (sor->soc->supports_hdmi) {
|
||||
connector = DRM_MODE_CONNECTOR_HDMIA;
|
||||
encoder = DRM_MODE_ENCODER_TMDS;
|
||||
|
@ -2199,8 +2184,8 @@ static int tegra_sor_init(struct host1x_client *client)
|
|||
dev_err(sor->dev, "debugfs setup failed: %d\n", err);
|
||||
}
|
||||
|
||||
if (sor->dpaux) {
|
||||
err = tegra_dpaux_attach(sor->dpaux, &sor->output);
|
||||
if (sor->aux) {
|
||||
err = drm_dp_aux_attach(sor->aux, &sor->output);
|
||||
if (err < 0) {
|
||||
dev_err(sor->dev, "failed to attach DP: %d\n", err);
|
||||
return err;
|
||||
|
@ -2249,8 +2234,8 @@ static int tegra_sor_exit(struct host1x_client *client)
|
|||
|
||||
tegra_output_exit(&sor->output);
|
||||
|
||||
if (sor->dpaux) {
|
||||
err = tegra_dpaux_detach(sor->dpaux);
|
||||
if (sor->aux) {
|
||||
err = drm_dp_aux_detach(sor->aux);
|
||||
if (err < 0) {
|
||||
dev_err(sor->dev, "failed to detach DP: %d\n", err);
|
||||
return err;
|
||||
|
@ -2399,14 +2384,14 @@ static int tegra_sor_probe(struct platform_device *pdev)
|
|||
|
||||
np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);
|
||||
if (np) {
|
||||
sor->dpaux = tegra_dpaux_find_by_of_node(np);
|
||||
sor->aux = drm_dp_aux_find_by_of_node(np);
|
||||
of_node_put(np);
|
||||
|
||||
if (!sor->dpaux)
|
||||
if (!sor->aux)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
if (!sor->dpaux) {
|
||||
if (!sor->aux) {
|
||||
if (sor->soc->supports_hdmi) {
|
||||
sor->ops = &tegra_sor_hdmi_ops;
|
||||
} else if (sor->soc->supports_lvds) {
|
||||
|
|
|
@ -10,6 +10,7 @@ host1x-y = \
|
|||
mipi.o \
|
||||
hw/host1x01.o \
|
||||
hw/host1x02.o \
|
||||
hw/host1x04.o
|
||||
hw/host1x04.o \
|
||||
hw/host1x05.o
|
||||
|
||||
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
|
||||
|
|
|
@ -538,6 +538,8 @@ EXPORT_SYMBOL(host1x_driver_register_full);
|
|||
|
||||
void host1x_driver_unregister(struct host1x_driver *driver)
|
||||
{
|
||||
driver_unregister(&driver->driver);
|
||||
|
||||
mutex_lock(&drivers_lock);
|
||||
list_del_init(&driver->list);
|
||||
mutex_unlock(&drivers_lock);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "hw/host1x01.h"
|
||||
#include "hw/host1x02.h"
|
||||
#include "hw/host1x04.h"
|
||||
#include "hw/host1x05.h"
|
||||
|
||||
void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
|
||||
{
|
||||
|
@ -87,7 +88,17 @@ static const struct host1x_info host1x04_info = {
|
|||
.sync_offset = 0x2100,
|
||||
};
|
||||
|
||||
static const struct host1x_info host1x05_info = {
|
||||
.nb_channels = 14,
|
||||
.nb_pts = 192,
|
||||
.nb_mlocks = 16,
|
||||
.nb_bases = 64,
|
||||
.init = host1x05_init,
|
||||
.sync_offset = 0x2100,
|
||||
};
|
||||
|
||||
static struct of_device_id host1x_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
|
||||
{ .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, },
|
||||
{ .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
|
||||
{ .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
|
||||
|
@ -212,6 +223,11 @@ static struct platform_driver tegra_host1x_driver = {
|
|||
.remove = host1x_remove,
|
||||
};
|
||||
|
||||
static struct platform_driver * const drivers[] = {
|
||||
&tegra_host1x_driver,
|
||||
&tegra_mipi_driver,
|
||||
};
|
||||
|
||||
static int __init tegra_host1x_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -220,28 +236,17 @@ static int __init tegra_host1x_init(void)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = platform_driver_register(&tegra_host1x_driver);
|
||||
err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
if (err < 0)
|
||||
goto unregister_bus;
|
||||
bus_unregister(&host1x_bus_type);
|
||||
|
||||
err = platform_driver_register(&tegra_mipi_driver);
|
||||
if (err < 0)
|
||||
goto unregister_host1x;
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_host1x:
|
||||
platform_driver_unregister(&tegra_host1x_driver);
|
||||
unregister_bus:
|
||||
bus_unregister(&host1x_bus_type);
|
||||
return err;
|
||||
}
|
||||
module_init(tegra_host1x_init);
|
||||
|
||||
static void __exit tegra_host1x_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tegra_mipi_driver);
|
||||
platform_driver_unregister(&tegra_host1x_driver);
|
||||
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
bus_unregister(&host1x_bus_type);
|
||||
}
|
||||
module_exit(tegra_host1x_exit);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Host1x init for Tegra210 SoCs
|
||||
*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* include hw specification */
|
||||
#include "host1x05.h"
|
||||
#include "host1x05_hardware.h"
|
||||
|
||||
/* include code */
|
||||
#include "cdma_hw.c"
|
||||
#include "channel_hw.c"
|
||||
#include "debug_hw.c"
|
||||
#include "intr_hw.c"
|
||||
#include "syncpt_hw.c"
|
||||
|
||||
#include "../dev.h"
|
||||
|
||||
int host1x05_init(struct host1x *host)
|
||||
{
|
||||
host->channel_op = &host1x_channel_ops;
|
||||
host->cdma_op = &host1x_cdma_ops;
|
||||
host->cdma_pb_op = &host1x_pushbuffer_ops;
|
||||
host->syncpt_op = &host1x_syncpt_ops;
|
||||
host->intr_op = &host1x_intr_ops;
|
||||
host->debug_op = &host1x_debug_ops;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Host1x init for Tegra210 SoCs
|
||||
*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HOST1X_HOST1X05_H
|
||||
#define HOST1X_HOST1X05_H
|
||||
|
||||
struct host1x;
|
||||
|
||||
int host1x05_init(struct host1x *host);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Tegra host1x Register Offsets for Tegra210
|
||||
*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HOST1X_HOST1X05_HARDWARE_H
|
||||
#define __HOST1X_HOST1X05_HARDWARE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "hw_host1x05_channel.h"
|
||||
#include "hw_host1x05_sync.h"
|
||||
#include "hw_host1x05_uclass.h"
|
||||
|
||||
static inline u32 host1x_class_host_wait_syncpt(
|
||||
unsigned indx, unsigned threshold)
|
||||
{
|
||||
return host1x_uclass_wait_syncpt_indx_f(indx)
|
||||
| host1x_uclass_wait_syncpt_thresh_f(threshold);
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_load_syncpt_base(
|
||||
unsigned indx, unsigned threshold)
|
||||
{
|
||||
return host1x_uclass_load_syncpt_base_base_indx_f(indx)
|
||||
| host1x_uclass_load_syncpt_base_value_f(threshold);
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_wait_syncpt_base(
|
||||
unsigned indx, unsigned base_indx, unsigned offset)
|
||||
{
|
||||
return host1x_uclass_wait_syncpt_base_indx_f(indx)
|
||||
| host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
|
||||
| host1x_uclass_wait_syncpt_base_offset_f(offset);
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_incr_syncpt_base(
|
||||
unsigned base_indx, unsigned offset)
|
||||
{
|
||||
return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
|
||||
| host1x_uclass_incr_syncpt_base_offset_f(offset);
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_incr_syncpt(
|
||||
unsigned cond, unsigned indx)
|
||||
{
|
||||
return host1x_uclass_incr_syncpt_cond_f(cond)
|
||||
| host1x_uclass_incr_syncpt_indx_f(indx);
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_indoff_reg_write(
|
||||
unsigned mod_id, unsigned offset, bool auto_inc)
|
||||
{
|
||||
u32 v = host1x_uclass_indoff_indbe_f(0xf)
|
||||
| host1x_uclass_indoff_indmodid_f(mod_id)
|
||||
| host1x_uclass_indoff_indroffset_f(offset);
|
||||
if (auto_inc)
|
||||
v |= host1x_uclass_indoff_autoinc_f(1);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline u32 host1x_class_host_indoff_reg_read(
|
||||
unsigned mod_id, unsigned offset, bool auto_inc)
|
||||
{
|
||||
u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
|
||||
| host1x_uclass_indoff_indroffset_f(offset)
|
||||
| host1x_uclass_indoff_rwn_read_v();
|
||||
if (auto_inc)
|
||||
v |= host1x_uclass_indoff_autoinc_f(1);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* cdma opcodes */
|
||||
static inline u32 host1x_opcode_setclass(
|
||||
unsigned class_id, unsigned offset, unsigned mask)
|
||||
{
|
||||
return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_incr(unsigned offset, unsigned count)
|
||||
{
|
||||
return (1 << 28) | (offset << 16) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_nonincr(unsigned offset, unsigned count)
|
||||
{
|
||||
return (2 << 28) | (offset << 16) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_mask(unsigned offset, unsigned mask)
|
||||
{
|
||||
return (3 << 28) | (offset << 16) | mask;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_imm(unsigned offset, unsigned value)
|
||||
{
|
||||
return (4 << 28) | (offset << 16) | value;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
|
||||
{
|
||||
return host1x_opcode_imm(host1x_uclass_incr_syncpt_r(),
|
||||
host1x_class_host_incr_syncpt(cond, indx));
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_restart(unsigned address)
|
||||
{
|
||||
return (5 << 28) | (address >> 4);
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_gather(unsigned count)
|
||||
{
|
||||
return (6 << 28) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_gather_nonincr(unsigned offset, unsigned count)
|
||||
{
|
||||
return (6 << 28) | (offset << 16) | BIT(15) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
|
||||
{
|
||||
return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
|
||||
}
|
||||
|
||||
#define HOST1X_OPCODE_NOP host1x_opcode_nonincr(0, 0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function naming determines intended use:
|
||||
*
|
||||
* <x>_r(void) : Returns the offset for register <x>.
|
||||
*
|
||||
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
|
||||
*
|
||||
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
|
||||
*
|
||||
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
|
||||
* and masked to place it at field <y> of register <x>. This value
|
||||
* can be |'d with others to produce a full register value for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
|
||||
* value can be ~'d and then &'d to clear the value of field <y> for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
|
||||
* to place it at field <y> of register <x>. This value can be |'d
|
||||
* with others to produce a full register value for <x>.
|
||||
*
|
||||
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
|
||||
* <x> value 'r' after being shifted to place its LSB at bit 0.
|
||||
* This value is suitable for direct comparison with other unshifted
|
||||
* values appropriate for use in field <y> of register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
|
||||
* field <y> of register <x>. This value is suitable for direct
|
||||
* comparison with unshifted values appropriate for use in field <y>
|
||||
* of register <x>.
|
||||
*/
|
||||
|
||||
#ifndef HOST1X_HW_HOST1X05_CHANNEL_H
|
||||
#define HOST1X_HW_HOST1X05_CHANNEL_H
|
||||
|
||||
static inline u32 host1x_channel_fifostat_r(void)
|
||||
{
|
||||
return 0x0;
|
||||
}
|
||||
#define HOST1X_CHANNEL_FIFOSTAT \
|
||||
host1x_channel_fifostat_r()
|
||||
static inline u32 host1x_channel_fifostat_cfempty_v(u32 r)
|
||||
{
|
||||
return (r >> 11) & 0x1;
|
||||
}
|
||||
#define HOST1X_CHANNEL_FIFOSTAT_CFEMPTY_V(r) \
|
||||
host1x_channel_fifostat_cfempty_v(r)
|
||||
static inline u32 host1x_channel_dmastart_r(void)
|
||||
{
|
||||
return 0x14;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMASTART \
|
||||
host1x_channel_dmastart_r()
|
||||
static inline u32 host1x_channel_dmaput_r(void)
|
||||
{
|
||||
return 0x18;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMAPUT \
|
||||
host1x_channel_dmaput_r()
|
||||
static inline u32 host1x_channel_dmaget_r(void)
|
||||
{
|
||||
return 0x1c;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMAGET \
|
||||
host1x_channel_dmaget_r()
|
||||
static inline u32 host1x_channel_dmaend_r(void)
|
||||
{
|
||||
return 0x20;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMAEND \
|
||||
host1x_channel_dmaend_r()
|
||||
static inline u32 host1x_channel_dmactrl_r(void)
|
||||
{
|
||||
return 0x24;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMACTRL \
|
||||
host1x_channel_dmactrl_r()
|
||||
static inline u32 host1x_channel_dmactrl_dmastop(void)
|
||||
{
|
||||
return 1 << 0;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMACTRL_DMASTOP \
|
||||
host1x_channel_dmactrl_dmastop()
|
||||
static inline u32 host1x_channel_dmactrl_dmastop_v(u32 r)
|
||||
{
|
||||
return (r >> 0) & 0x1;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMACTRL_DMASTOP_V(r) \
|
||||
host1x_channel_dmactrl_dmastop_v(r)
|
||||
static inline u32 host1x_channel_dmactrl_dmagetrst(void)
|
||||
{
|
||||
return 1 << 1;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMACTRL_DMAGETRST \
|
||||
host1x_channel_dmactrl_dmagetrst()
|
||||
static inline u32 host1x_channel_dmactrl_dmainitget(void)
|
||||
{
|
||||
return 1 << 2;
|
||||
}
|
||||
#define HOST1X_CHANNEL_DMACTRL_DMAINITGET \
|
||||
host1x_channel_dmactrl_dmainitget()
|
||||
|
||||
#endif
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function naming determines intended use:
|
||||
*
|
||||
* <x>_r(void) : Returns the offset for register <x>.
|
||||
*
|
||||
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
|
||||
*
|
||||
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
|
||||
*
|
||||
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
|
||||
* and masked to place it at field <y> of register <x>. This value
|
||||
* can be |'d with others to produce a full register value for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
|
||||
* value can be ~'d and then &'d to clear the value of field <y> for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
|
||||
* to place it at field <y> of register <x>. This value can be |'d
|
||||
* with others to produce a full register value for <x>.
|
||||
*
|
||||
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
|
||||
* <x> value 'r' after being shifted to place its LSB at bit 0.
|
||||
* This value is suitable for direct comparison with other unshifted
|
||||
* values appropriate for use in field <y> of register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
|
||||
* field <y> of register <x>. This value is suitable for direct
|
||||
* comparison with unshifted values appropriate for use in field <y>
|
||||
* of register <x>.
|
||||
*/
|
||||
|
||||
#ifndef HOST1X_HW_HOST1X05_SYNC_H
|
||||
#define HOST1X_HW_HOST1X05_SYNC_H
|
||||
|
||||
#define REGISTER_STRIDE 4
|
||||
|
||||
static inline u32 host1x_sync_syncpt_r(unsigned int id)
|
||||
{
|
||||
return 0xf80 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT(id) \
|
||||
host1x_sync_syncpt_r(id)
|
||||
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(unsigned int id)
|
||||
{
|
||||
return 0xe80 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id) \
|
||||
host1x_sync_syncpt_thresh_cpu0_int_status_r(id)
|
||||
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(unsigned int id)
|
||||
{
|
||||
return 0xf00 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id) \
|
||||
host1x_sync_syncpt_thresh_int_disable_r(id)
|
||||
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(unsigned int id)
|
||||
{
|
||||
return 0xf20 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id) \
|
||||
host1x_sync_syncpt_thresh_int_enable_cpu0_r(id)
|
||||
static inline u32 host1x_sync_cf_setup_r(unsigned int channel)
|
||||
{
|
||||
return 0xc00 + channel * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_CF_SETUP(channel) \
|
||||
host1x_sync_cf_setup_r(channel)
|
||||
static inline u32 host1x_sync_cf_setup_base_v(u32 r)
|
||||
{
|
||||
return (r >> 0) & 0x3ff;
|
||||
}
|
||||
#define HOST1X_SYNC_CF_SETUP_BASE_V(r) \
|
||||
host1x_sync_cf_setup_base_v(r)
|
||||
static inline u32 host1x_sync_cf_setup_limit_v(u32 r)
|
||||
{
|
||||
return (r >> 16) & 0x3ff;
|
||||
}
|
||||
#define HOST1X_SYNC_CF_SETUP_LIMIT_V(r) \
|
||||
host1x_sync_cf_setup_limit_v(r)
|
||||
static inline u32 host1x_sync_cmdproc_stop_r(void)
|
||||
{
|
||||
return 0xac;
|
||||
}
|
||||
#define HOST1X_SYNC_CMDPROC_STOP \
|
||||
host1x_sync_cmdproc_stop_r()
|
||||
static inline u32 host1x_sync_ch_teardown_r(void)
|
||||
{
|
||||
return 0xb0;
|
||||
}
|
||||
#define HOST1X_SYNC_CH_TEARDOWN \
|
||||
host1x_sync_ch_teardown_r()
|
||||
static inline u32 host1x_sync_usec_clk_r(void)
|
||||
{
|
||||
return 0x1a4;
|
||||
}
|
||||
#define HOST1X_SYNC_USEC_CLK \
|
||||
host1x_sync_usec_clk_r()
|
||||
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
|
||||
{
|
||||
return 0x1a8;
|
||||
}
|
||||
#define HOST1X_SYNC_CTXSW_TIMEOUT_CFG \
|
||||
host1x_sync_ctxsw_timeout_cfg_r()
|
||||
static inline u32 host1x_sync_ip_busy_timeout_r(void)
|
||||
{
|
||||
return 0x1bc;
|
||||
}
|
||||
#define HOST1X_SYNC_IP_BUSY_TIMEOUT \
|
||||
host1x_sync_ip_busy_timeout_r()
|
||||
static inline u32 host1x_sync_mlock_owner_r(unsigned int id)
|
||||
{
|
||||
return 0x340 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_MLOCK_OWNER(id) \
|
||||
host1x_sync_mlock_owner_r(id)
|
||||
static inline u32 host1x_sync_mlock_owner_chid_v(u32 r)
|
||||
{
|
||||
return (r >> 8) & 0xf;
|
||||
}
|
||||
#define HOST1X_SYNC_MLOCK_OWNER_CHID_V(v) \
|
||||
host1x_sync_mlock_owner_chid_v(v)
|
||||
static inline u32 host1x_sync_mlock_owner_cpu_owns_v(u32 r)
|
||||
{
|
||||
return (r >> 1) & 0x1;
|
||||
}
|
||||
#define HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(r) \
|
||||
host1x_sync_mlock_owner_cpu_owns_v(r)
|
||||
static inline u32 host1x_sync_mlock_owner_ch_owns_v(u32 r)
|
||||
{
|
||||
return (r >> 0) & 0x1;
|
||||
}
|
||||
#define HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(r) \
|
||||
host1x_sync_mlock_owner_ch_owns_v(r)
|
||||
static inline u32 host1x_sync_syncpt_int_thresh_r(unsigned int id)
|
||||
{
|
||||
return 0x1380 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_INT_THRESH(id) \
|
||||
host1x_sync_syncpt_int_thresh_r(id)
|
||||
static inline u32 host1x_sync_syncpt_base_r(unsigned int id)
|
||||
{
|
||||
return 0x600 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_BASE(id) \
|
||||
host1x_sync_syncpt_base_r(id)
|
||||
static inline u32 host1x_sync_syncpt_cpu_incr_r(unsigned int id)
|
||||
{
|
||||
return 0xf60 + id * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_SYNCPT_CPU_INCR(id) \
|
||||
host1x_sync_syncpt_cpu_incr_r(id)
|
||||
static inline u32 host1x_sync_cbread_r(unsigned int channel)
|
||||
{
|
||||
return 0xc80 + channel * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_CBREAD(channel) \
|
||||
host1x_sync_cbread_r(channel)
|
||||
static inline u32 host1x_sync_cfpeek_ctrl_r(void)
|
||||
{
|
||||
return 0x74c;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_CTRL \
|
||||
host1x_sync_cfpeek_ctrl_r()
|
||||
static inline u32 host1x_sync_cfpeek_ctrl_addr_f(u32 v)
|
||||
{
|
||||
return (v & 0x3ff) << 0;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_CTRL_ADDR_F(v) \
|
||||
host1x_sync_cfpeek_ctrl_addr_f(v)
|
||||
static inline u32 host1x_sync_cfpeek_ctrl_channr_f(u32 v)
|
||||
{
|
||||
return (v & 0xf) << 16;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_CTRL_CHANNR_F(v) \
|
||||
host1x_sync_cfpeek_ctrl_channr_f(v)
|
||||
static inline u32 host1x_sync_cfpeek_ctrl_ena_f(u32 v)
|
||||
{
|
||||
return (v & 0x1) << 31;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_CTRL_ENA_F(v) \
|
||||
host1x_sync_cfpeek_ctrl_ena_f(v)
|
||||
static inline u32 host1x_sync_cfpeek_read_r(void)
|
||||
{
|
||||
return 0x750;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_READ \
|
||||
host1x_sync_cfpeek_read_r()
|
||||
static inline u32 host1x_sync_cfpeek_ptrs_r(void)
|
||||
{
|
||||
return 0x754;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_PTRS \
|
||||
host1x_sync_cfpeek_ptrs_r()
|
||||
static inline u32 host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(u32 r)
|
||||
{
|
||||
return (r >> 0) & 0x3ff;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_PTRS_CF_RD_PTR_V(r) \
|
||||
host1x_sync_cfpeek_ptrs_cf_rd_ptr_v(r)
|
||||
static inline u32 host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(u32 r)
|
||||
{
|
||||
return (r >> 16) & 0x3ff;
|
||||
}
|
||||
#define HOST1X_SYNC_CFPEEK_PTRS_CF_WR_PTR_V(r) \
|
||||
host1x_sync_cfpeek_ptrs_cf_wr_ptr_v(r)
|
||||
static inline u32 host1x_sync_cbstat_r(unsigned int channel)
|
||||
{
|
||||
return 0xcc0 + channel * REGISTER_STRIDE;
|
||||
}
|
||||
#define HOST1X_SYNC_CBSTAT(channel) \
|
||||
host1x_sync_cbstat_r(channel)
|
||||
static inline u32 host1x_sync_cbstat_cboffset_v(u32 r)
|
||||
{
|
||||
return (r >> 0) & 0xffff;
|
||||
}
|
||||
#define HOST1X_SYNC_CBSTAT_CBOFFSET_V(r) \
|
||||
host1x_sync_cbstat_cboffset_v(r)
|
||||
static inline u32 host1x_sync_cbstat_cbclass_v(u32 r)
|
||||
{
|
||||
return (r >> 16) & 0x3ff;
|
||||
}
|
||||
#define HOST1X_SYNC_CBSTAT_CBCLASS_V(r) \
|
||||
host1x_sync_cbstat_cbclass_v(r)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2015 NVIDIA Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function naming determines intended use:
|
||||
*
|
||||
* <x>_r(void) : Returns the offset for register <x>.
|
||||
*
|
||||
* <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
|
||||
*
|
||||
* <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
|
||||
*
|
||||
* <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
|
||||
* and masked to place it at field <y> of register <x>. This value
|
||||
* can be |'d with others to produce a full register value for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
|
||||
* value can be ~'d and then &'d to clear the value of field <y> for
|
||||
* register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
|
||||
* to place it at field <y> of register <x>. This value can be |'d
|
||||
* with others to produce a full register value for <x>.
|
||||
*
|
||||
* <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
|
||||
* <x> value 'r' after being shifted to place its LSB at bit 0.
|
||||
* This value is suitable for direct comparison with other unshifted
|
||||
* values appropriate for use in field <y> of register <x>.
|
||||
*
|
||||
* <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
|
||||
* field <y> of register <x>. This value is suitable for direct
|
||||
* comparison with unshifted values appropriate for use in field <y>
|
||||
* of register <x>.
|
||||
*/
|
||||
|
||||
#ifndef HOST1X_HW_HOST1X05_UCLASS_H
|
||||
#define HOST1X_HW_HOST1X05_UCLASS_H
|
||||
|
||||
static inline u32 host1x_uclass_incr_syncpt_r(void)
|
||||
{
|
||||
return 0x0;
|
||||
}
|
||||
#define HOST1X_UCLASS_INCR_SYNCPT \
|
||||
host1x_uclass_incr_syncpt_r()
|
||||
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 8;
|
||||
}
|
||||
#define HOST1X_UCLASS_INCR_SYNCPT_COND_F(v) \
|
||||
host1x_uclass_incr_syncpt_cond_f(v)
|
||||
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 0;
|
||||
}
|
||||
#define HOST1X_UCLASS_INCR_SYNCPT_INDX_F(v) \
|
||||
host1x_uclass_incr_syncpt_indx_f(v)
|
||||
static inline u32 host1x_uclass_wait_syncpt_r(void)
|
||||
{
|
||||
return 0x8;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT \
|
||||
host1x_uclass_wait_syncpt_r()
|
||||
static inline u32 host1x_uclass_wait_syncpt_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 24;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_INDX_F(v) \
|
||||
host1x_uclass_wait_syncpt_indx_f(v)
|
||||
static inline u32 host1x_uclass_wait_syncpt_thresh_f(u32 v)
|
||||
{
|
||||
return (v & 0xffffff) << 0;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_THRESH_F(v) \
|
||||
host1x_uclass_wait_syncpt_thresh_f(v)
|
||||
static inline u32 host1x_uclass_wait_syncpt_base_r(void)
|
||||
{
|
||||
return 0x9;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_BASE \
|
||||
host1x_uclass_wait_syncpt_base_r()
|
||||
static inline u32 host1x_uclass_wait_syncpt_base_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 24;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_INDX_F(v) \
|
||||
host1x_uclass_wait_syncpt_base_indx_f(v)
|
||||
static inline u32 host1x_uclass_wait_syncpt_base_base_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 16;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_BASE_INDX_F(v) \
|
||||
host1x_uclass_wait_syncpt_base_base_indx_f(v)
|
||||
static inline u32 host1x_uclass_wait_syncpt_base_offset_f(u32 v)
|
||||
{
|
||||
return (v & 0xffff) << 0;
|
||||
}
|
||||
#define HOST1X_UCLASS_WAIT_SYNCPT_BASE_OFFSET_F(v) \
|
||||
host1x_uclass_wait_syncpt_base_offset_f(v)
|
||||
static inline u32 host1x_uclass_load_syncpt_base_r(void)
|
||||
{
|
||||
return 0xb;
|
||||
}
|
||||
#define HOST1X_UCLASS_LOAD_SYNCPT_BASE \
|
||||
host1x_uclass_load_syncpt_base_r()
|
||||
static inline u32 host1x_uclass_load_syncpt_base_base_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 24;
|
||||
}
|
||||
#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(v) \
|
||||
host1x_uclass_load_syncpt_base_base_indx_f(v)
|
||||
static inline u32 host1x_uclass_load_syncpt_base_value_f(u32 v)
|
||||
{
|
||||
return (v & 0xffffff) << 0;
|
||||
}
|
||||
#define HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(v) \
|
||||
host1x_uclass_load_syncpt_base_value_f(v)
|
||||
static inline u32 host1x_uclass_incr_syncpt_base_base_indx_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 24;
|
||||
}
|
||||
#define HOST1X_UCLASS_INCR_SYNCPT_BASE_BASE_INDX_F(v) \
|
||||
host1x_uclass_incr_syncpt_base_base_indx_f(v)
|
||||
static inline u32 host1x_uclass_incr_syncpt_base_offset_f(u32 v)
|
||||
{
|
||||
return (v & 0xffffff) << 0;
|
||||
}
|
||||
#define HOST1X_UCLASS_INCR_SYNCPT_BASE_OFFSET_F(v) \
|
||||
host1x_uclass_incr_syncpt_base_offset_f(v)
|
||||
static inline u32 host1x_uclass_indoff_r(void)
|
||||
{
|
||||
return 0x2d;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF \
|
||||
host1x_uclass_indoff_r()
|
||||
static inline u32 host1x_uclass_indoff_indbe_f(u32 v)
|
||||
{
|
||||
return (v & 0xf) << 28;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF_INDBE_F(v) \
|
||||
host1x_uclass_indoff_indbe_f(v)
|
||||
static inline u32 host1x_uclass_indoff_autoinc_f(u32 v)
|
||||
{
|
||||
return (v & 0x1) << 27;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF_AUTOINC_F(v) \
|
||||
host1x_uclass_indoff_autoinc_f(v)
|
||||
static inline u32 host1x_uclass_indoff_indmodid_f(u32 v)
|
||||
{
|
||||
return (v & 0xff) << 18;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF_INDMODID_F(v) \
|
||||
host1x_uclass_indoff_indmodid_f(v)
|
||||
static inline u32 host1x_uclass_indoff_indroffset_f(u32 v)
|
||||
{
|
||||
return (v & 0xffff) << 2;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
|
||||
host1x_uclass_indoff_indroffset_f(v)
|
||||
static inline u32 host1x_uclass_indoff_rwn_read_v(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#define HOST1X_UCLASS_INDOFF_INDROFFSET_F(v) \
|
||||
host1x_uclass_indoff_indroffset_f(v)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue