Commit 9a1123e8 authored by Dave Airlie's avatar Dave Airlie

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()
parents 07ade844 ad906599
...@@ -1955,8 +1955,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) ...@@ -1955,8 +1955,10 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
* cases where only a single display controller is used. * cases where only a single display controller is used.
*/ */
for_each_matching_node(np, tegra_dc_of_match) { 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; break;
}
value++; value++;
} }
......
...@@ -436,7 +436,7 @@ struct platform_driver tegra_dpaux_driver = { ...@@ -436,7 +436,7 @@ struct platform_driver tegra_dpaux_driver = {
.remove = tegra_dpaux_remove, .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; struct tegra_dpaux *dpaux;
...@@ -445,7 +445,7 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np) ...@@ -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) list_for_each_entry(dpaux, &dpaux_list, list)
if (np == dpaux->dev->of_node) { if (np == dpaux->dev->of_node) {
mutex_unlock(&dpaux_lock); mutex_unlock(&dpaux_lock);
return dpaux; return &dpaux->aux;
} }
mutex_unlock(&dpaux_lock); mutex_unlock(&dpaux_lock);
...@@ -453,8 +453,9 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np) ...@@ -453,8 +453,9 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np)
return NULL; 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; unsigned long timeout;
int err; int err;
...@@ -470,7 +471,7 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output) ...@@ -470,7 +471,7 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output)
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
enum drm_connector_status status; enum drm_connector_status status;
status = tegra_dpaux_detect(dpaux); status = drm_dp_aux_detect(aux);
if (status == connector_status_connected) { if (status == connector_status_connected) {
enable_irq(dpaux->irq); enable_irq(dpaux->irq);
return 0; return 0;
...@@ -482,8 +483,9 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output) ...@@ -482,8 +483,9 @@ int tegra_dpaux_attach(struct tegra_dpaux *dpaux, struct tegra_output *output)
return -ETIMEDOUT; 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; unsigned long timeout;
int err; int err;
...@@ -498,7 +500,7 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux) ...@@ -498,7 +500,7 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
enum drm_connector_status status; enum drm_connector_status status;
status = tegra_dpaux_detect(dpaux); status = drm_dp_aux_detect(aux);
if (status == connector_status_disconnected) { if (status == connector_status_disconnected) {
dpaux->output = NULL; dpaux->output = NULL;
return 0; return 0;
...@@ -510,8 +512,9 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux) ...@@ -510,8 +512,9 @@ int tegra_dpaux_detach(struct tegra_dpaux *dpaux)
return -ETIMEDOUT; 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; u32 value;
value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT); value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
...@@ -522,8 +525,9 @@ enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux) ...@@ -522,8 +525,9 @@ enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux)
return connector_status_disconnected; 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; u32 value;
value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) | value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) |
...@@ -540,8 +544,9 @@ int tegra_dpaux_enable(struct tegra_dpaux *dpaux) ...@@ -540,8 +544,9 @@ int tegra_dpaux_enable(struct tegra_dpaux *dpaux)
return 0; 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; u32 value;
value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE); value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
...@@ -551,11 +556,11 @@ int tegra_dpaux_disable(struct tegra_dpaux *dpaux) ...@@ -551,11 +556,11 @@ int tegra_dpaux_disable(struct tegra_dpaux *dpaux)
return 0; 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; 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); encoding);
if (err < 0) if (err < 0)
return err; return err;
...@@ -563,15 +568,15 @@ int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding) ...@@ -563,15 +568,15 @@ int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding)
return 0; return 0;
} }
int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
u8 pattern) u8 pattern)
{ {
u8 tp = pattern & DP_TRAINING_PATTERN_MASK; u8 tp = pattern & DP_TRAINING_PATTERN_MASK;
u8 status[DP_LINK_STATUS_SIZE], values[4]; u8 status[DP_LINK_STATUS_SIZE], values[4];
unsigned int i; unsigned int i;
int err; 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) if (err < 0)
return err; return err;
...@@ -584,14 +589,14 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, ...@@ -584,14 +589,14 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
DP_TRAIN_MAX_SWING_REACHED | DP_TRAIN_MAX_SWING_REACHED |
DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 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); link->num_lanes);
if (err < 0) if (err < 0)
return err; return err;
usleep_range(500, 1000); 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) if (err < 0)
return err; return err;
...@@ -609,11 +614,11 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, ...@@ -609,11 +614,11 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
break; break;
default: default:
dev_err(dpaux->dev, "unsupported training pattern %u\n", tp); dev_err(aux->dev, "unsupported training pattern %u\n", tp);
return -EINVAL; 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) if (err < 0)
return err; return err;
......
...@@ -137,8 +137,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) ...@@ -137,8 +137,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
start = geometry->aperture_start; start = geometry->aperture_start;
end = geometry->aperture_end; end = geometry->aperture_end;
DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n", DRM_DEBUG_DRIVER("IOMMU aperture initialized (%#llx-%#llx)\n",
start, end); start, end);
drm_mm_init(&tegra->mm, start, end - start + 1); 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) ...@@ -277,9 +277,7 @@ host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
if (!gem) if (!gem)
return NULL; return NULL;
mutex_lock(&drm->struct_mutex); drm_gem_object_unreference_unlocked(gem);
drm_gem_object_unreference(gem);
mutex_unlock(&drm->struct_mutex);
bo = to_tegra_bo(gem); bo = to_tegra_bo(gem);
return &bo->base; return &bo->base;
...@@ -473,7 +471,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data, ...@@ -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); args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
return 0; return 0;
} }
...@@ -683,7 +681,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data, ...@@ -683,7 +681,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
bo->tiling.mode = mode; bo->tiling.mode = mode;
bo->tiling.value = value; bo->tiling.value = value;
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
return 0; return 0;
} }
...@@ -723,7 +721,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data, ...@@ -723,7 +721,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
break; break;
} }
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
return err; return err;
} }
...@@ -748,7 +746,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data, ...@@ -748,7 +746,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data,
if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP) if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
bo->flags |= TEGRA_BO_BOTTOM_UP; bo->flags |= TEGRA_BO_BOTTOM_UP;
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
return 0; return 0;
} }
...@@ -770,7 +768,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data, ...@@ -770,7 +768,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
if (bo->flags & TEGRA_BO_BOTTOM_UP) if (bo->flags & TEGRA_BO_BOTTOM_UP)
args->flags |= DRM_TEGRA_GEM_BOTTOM_UP; args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
return 0; return 0;
} }
...@@ -921,7 +919,8 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor) ...@@ -921,7 +919,8 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor)
#endif #endif
static struct drm_driver tegra_drm_driver = { 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, .load = tegra_drm_load,
.unload = tegra_drm_unload, .unload = tegra_drm_unload,
.open = tegra_drm_open, .open = tegra_drm_open,
...@@ -1023,8 +1022,17 @@ static int host1x_drm_remove(struct host1x_device *dev) ...@@ -1023,8 +1022,17 @@ static int host1x_drm_remove(struct host1x_device *dev)
static int host1x_drm_suspend(struct device *dev) static int host1x_drm_suspend(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct tegra_drm *tegra = drm->dev_private;
drm_kms_helper_poll_disable(drm); 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; return 0;
} }
...@@ -1032,7 +1040,10 @@ static int host1x_drm_suspend(struct device *dev) ...@@ -1032,7 +1040,10 @@ static int host1x_drm_suspend(struct device *dev)
static int host1x_drm_resume(struct device *dev) static int host1x_drm_resume(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(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); drm_kms_helper_poll_enable(drm);
return 0; return 0;
...@@ -1076,6 +1087,16 @@ static struct host1x_driver host1x_drm_driver = { ...@@ -1076,6 +1087,16 @@ static struct host1x_driver host1x_drm_driver = {
.subdevs = host1x_drm_subdevs, .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) static int __init host1x_drm_init(void)
{ {
int err; int err;
...@@ -1084,48 +1105,12 @@ static int __init host1x_drm_init(void) ...@@ -1084,48 +1105,12 @@ static int __init host1x_drm_init(void)
if (err < 0) if (err < 0)
return err; return err;
err = platform_driver_register(&tegra_dc_driver); err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
if (err < 0) if (err < 0)
goto unregister_host1x; 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; 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: unregister_host1x:
host1x_driver_unregister(&host1x_drm_driver); host1x_driver_unregister(&host1x_drm_driver);
return err; return err;
...@@ -1134,13 +1119,7 @@ module_init(host1x_drm_init); ...@@ -1134,13 +1119,7 @@ module_init(host1x_drm_init);
static void __exit host1x_drm_exit(void) static void __exit host1x_drm_exit(void)
{ {
platform_driver_unregister(&tegra_gr3d_driver); platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
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);
host1x_driver_unregister(&host1x_drm_driver); host1x_driver_unregister(&host1x_drm_driver);
} }
module_exit(host1x_drm_exit); module_exit(host1x_drm_exit);
......
...@@ -57,6 +57,8 @@ struct tegra_drm { ...@@ -57,6 +57,8 @@ struct tegra_drm {
struct work_struct work; struct work_struct work;
struct mutex lock; struct mutex lock;
} commit; } commit;
struct drm_atomic_state *state;
}; };
struct tegra_drm_client; struct tegra_drm_client;
...@@ -247,18 +249,17 @@ void tegra_output_connector_destroy(struct drm_connector *connector); ...@@ -247,18 +249,17 @@ void tegra_output_connector_destroy(struct drm_connector *connector);
void tegra_output_encoder_destroy(struct drm_encoder *encoder); void tegra_output_encoder_destroy(struct drm_encoder *encoder);
/* from dpaux.c */ /* from dpaux.c */
struct tegra_dpaux;
struct drm_dp_link; struct drm_dp_link;
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);
enum drm_connector_status tegra_dpaux_detect(struct tegra_dpaux *dpaux); enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux);
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);
int tegra_dpaux_detach(struct tegra_dpaux *dpaux); int drm_dp_aux_detach(struct drm_dp_aux *aux);
int tegra_dpaux_enable(struct tegra_dpaux *dpaux); int drm_dp_aux_enable(struct drm_dp_aux *aux);
int tegra_dpaux_disable(struct tegra_dpaux *dpaux); int drm_dp_aux_disable(struct drm_dp_aux *aux);
int tegra_dpaux_prepare(struct tegra_dpaux *dpaux, u8 encoding); int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding);
int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link, int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
u8 pattern); u8 pattern);
/* from fb.c */ /* from fb.c */
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer, struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
...@@ -273,16 +274,18 @@ int tegra_drm_fb_prepare(struct drm_device *drm); ...@@ -273,16 +274,18 @@ int tegra_drm_fb_prepare(struct drm_device *drm);
void tegra_drm_fb_free(struct drm_device *drm); void tegra_drm_fb_free(struct drm_device *drm);
int tegra_drm_fb_init(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_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 #ifdef CONFIG_DRM_FBDEV_EMULATION
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev); void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
void tegra_fb_output_poll_changed(struct drm_device *drm); void tegra_fb_output_poll_changed(struct drm_device *drm);
#endif #endif
extern struct platform_driver tegra_dc_driver; 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_hdmi_driver;
extern struct platform_driver tegra_dsi_driver;
extern struct platform_driver tegra_dpaux_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_gr2d_driver;
extern struct platform_driver tegra_gr3d_driver; extern struct platform_driver tegra_gr3d_driver;
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/console.h>
#include "drm.h" #include "drm.h"
#include "gem.h" #include "gem.h"
...@@ -413,3 +415,25 @@ void tegra_drm_fb_exit(struct drm_device *drm) ...@@ -413,3 +415,25 @@ void tegra_drm_fb_exit(struct drm_device *drm)
tegra_fbdev_exit(tegra->fbdev); tegra_fbdev_exit(tegra->fbdev);
#endif #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) ...@@ -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) static void tegra_bo_put(struct host1x_bo *bo)
{ {
struct tegra_bo *obj = host1x_to_tegra_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_unlocked(&obj->gem);
drm_gem_object_unreference(&obj->gem);
mutex_unlock(&drm->struct_mutex);
} }
static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt) 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, ...@@ -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) static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
{ {
struct tegra_bo *obj = host1x_to_tegra_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); drm_gem_object_reference(&obj->gem);
mutex_unlock(&drm->struct_mutex);
return bo; return bo;
} }
...@@ -408,12 +402,9 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, ...@@ -408,12 +402,9 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
struct drm_gem_object *gem; struct drm_gem_object *gem;
struct tegra_bo *bo; struct tegra_bo *bo;
mutex_lock(&drm->struct_mutex);
gem = drm_gem_object_lookup(drm, file, handle); gem = drm_gem_object_lookup(drm, file, handle);
if (!gem) { if (!gem) {
dev_err(drm->dev, "failed to lookup GEM object\n"); dev_err(drm->dev, "failed to lookup GEM object\n");
mutex_unlock(&drm->struct_mutex);
return -EINVAL; return -EINVAL;
} }
...@@ -421,9 +412,7 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, ...@@ -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); *offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
drm_gem_object_unreference(gem); drm_gem_object_unreference_unlocked(gem);
mutex_unlock(&drm->struct_mutex);
return 0; return 0;
} }
......
...@@ -173,7 +173,7 @@ struct tegra_sor { ...@@ -173,7 +173,7 @@ struct tegra_sor {
struct clk *clk_dp; struct clk *clk_dp;
struct clk *clk; struct clk *clk;
struct tegra_dpaux *dpaux; struct drm_dp_aux *aux;
struct drm_info_list *debugfs_files; struct drm_info_list *debugfs_files;
struct drm_minor *minor; struct drm_minor *minor;
...@@ -273,7 +273,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, ...@@ -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); SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);
tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 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) if (err < 0)
return err; return err;
...@@ -288,7 +288,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, ...@@ -288,7 +288,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
pattern = DP_TRAINING_PATTERN_1; 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) if (err < 0)
return err; return err;
...@@ -309,7 +309,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, ...@@ -309,7 +309,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2; 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) if (err < 0)
return err; return err;
...@@ -324,7 +324,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor, ...@@ -324,7 +324,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
pattern = DP_TRAINING_PATTERN_DISABLE; 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) if (err < 0)
return err; return err;
...@@ -1044,8 +1044,8 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force) ...@@ -1044,8 +1044,8 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force)
struct tegra_output *output = connector_to_output(connector); struct tegra_output *output = connector_to_output(connector);
struct tegra_sor *sor = to_sor(output); struct tegra_sor *sor = to_sor(output);
if (sor->dpaux) if (sor->aux)
return tegra_dpaux_detect(sor->dpaux); return drm_dp_aux_detect(sor->aux);
return tegra_output_connector_detect(connector, force); return tegra_output_connector_detect(connector, force);
} }
...@@ -1066,13 +1066,13 @@ static int tegra_sor_connector_get_modes(struct drm_connector *connector) ...@@ -1066,13 +1066,13 @@ static int tegra_sor_connector_get_modes(struct drm_connector *connector)
struct tegra_sor *sor = to_sor(output); struct tegra_sor *sor = to_sor(output);
int err; int err;
if (sor->dpaux) if (sor->aux)
tegra_dpaux_enable(sor->dpaux); drm_dp_aux_enable(sor->aux);
err = tegra_output_connector_get_modes(connector); err = tegra_output_connector_get_modes(connector);
if (sor->dpaux) if (sor->aux)
tegra_dpaux_disable(sor->dpaux); drm_dp_aux_disable(sor->aux);
return err; return err;
} }
...@@ -1128,8 +1128,8 @@ static void tegra_sor_edp_disable(struct drm_encoder *encoder) ...@@ -1128,8 +1128,8 @@ static void tegra_sor_edp_disable(struct drm_encoder *encoder)
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to power down SOR: %d\n", err); dev_err(sor->dev, "failed to power down SOR: %d\n", err);
if (sor->dpaux) { if (sor->aux) {
err = tegra_dpaux_disable(sor->dpaux); err = drm_dp_aux_disable(sor->aux);
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to disable DP: %d\n", err); 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) ...@@ -1196,7 +1196,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
struct tegra_sor *sor = to_sor(output); struct tegra_sor *sor = to_sor(output);
struct tegra_sor_config config; struct tegra_sor_config config;
struct drm_dp_link link; struct drm_dp_link link;
struct drm_dp_aux *aux; u8 rate, lanes;
int err = 0; int err = 0;
u32 value; u32 value;
...@@ -1209,20 +1209,14 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder) ...@@ -1209,20 +1209,14 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
if (output->panel) if (output->panel)
drm_panel_prepare(output->panel); drm_panel_prepare(output->panel);
/* FIXME: properly convert to struct drm_dp_aux */ err = drm_dp_aux_enable(sor->aux);
aux = (struct drm_dp_aux *)sor->dpaux; 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); err = drm_dp_link_probe(sor->aux, &link);
if (err < 0) { if (err < 0) {
dev_err(sor->dev, "failed to probe eDP link: %d\n", dev_err(sor->dev, "failed to probe eDP link: %d\n", err);
err); return;
return;
}
} }
err = clk_set_parent(sor->clk, sor->clk_safe); err = clk_set_parent(sor->clk, sor->clk_safe);
...@@ -1434,60 +1428,51 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder) ...@@ -1434,60 +1428,51 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
value |= SOR_DP_PADCTL_PAD_CAL_PD; value |= SOR_DP_PADCTL_PAD_CAL_PD;
tegra_sor_writel(sor, value, SOR_DP_PADCTL0); tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
if (sor->dpaux) { err = drm_dp_link_probe(sor->aux, &link);
u8 rate, lanes; 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(aux, &link); err = drm_dp_link_power_up(sor->aux, &link);
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to power up eDP link: %d\n", dev_err(sor->dev, "failed to power up eDP link: %d\n", err);
err);
err = drm_dp_link_configure(aux, &link); err = drm_dp_link_configure(sor->aux, &link);
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to configure eDP link: %d\n", dev_err(sor->dev, "failed to configure eDP link: %d\n", err);
err);
rate = drm_dp_link_rate_to_bw_code(link.rate); rate = drm_dp_link_rate_to_bw_code(link.rate);
lanes = link.num_lanes; lanes = link.num_lanes;
value = tegra_sor_readl(sor, 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_MASK;
value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate); value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
tegra_sor_writel(sor, value, SOR_CLK_CNTRL); tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
value = tegra_sor_readl(sor, SOR_DP_LINKCTL0); value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK; value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
value |= SOR_DP_LINKCTL_LANE_COUNT(lanes); value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
value |= SOR_DP_LINKCTL_ENHANCED_FRAME; 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++) { for (i = 0; i < link.num_lanes; i++) {
unsigned long lane = SOR_DP_TPG_CHANNEL_CODING | unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
SOR_DP_TPG_SCRAMBLER_GALIOS | SOR_DP_TPG_SCRAMBLER_GALIOS |
SOR_DP_TPG_PATTERN_NONE; SOR_DP_TPG_PATTERN_NONE;
value = (value << 8) | lane; value = (value << 8) | lane;
} }
tegra_sor_writel(sor, value, SOR_DP_TPG); tegra_sor_writel(sor, value, SOR_DP_TPG);
err = tegra_sor_dp_train_fast(sor, &link); err = tegra_sor_dp_train_fast(sor, &link);
if (err < 0) { if (err < 0)
dev_err(sor->dev, "DP fast link training failed: %d\n", dev_err(sor->dev, "DP fast link training failed: %d\n", err);
err);
}
dev_dbg(sor->dev, "fast link training succeeded\n"); dev_dbg(sor->dev, "fast link training succeeded\n");
}
err = tegra_sor_power_up(sor, 250); err = tegra_sor_power_up(sor, 250);
if (err < 0) if (err < 0)
...@@ -1961,9 +1946,9 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) ...@@ -1961,9 +1946,9 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
/* production settings */ /* production settings */
settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000); settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);
if (IS_ERR(settings)) { if (!settings) {
dev_err(sor->dev, "no settings for pixel clock %d Hz: %ld\n", dev_err(sor->dev, "no settings for pixel clock %d Hz\n",
mode->clock * 1000, PTR_ERR(settings)); mode->clock * 1000);
return; return;
} }
...@@ -2148,7 +2133,7 @@ static int tegra_sor_init(struct host1x_client *client) ...@@ -2148,7 +2133,7 @@ static int tegra_sor_init(struct host1x_client *client)
int encoder = DRM_MODE_ENCODER_NONE; int encoder = DRM_MODE_ENCODER_NONE;
int err; int err;
if (!sor->dpaux) { if (!sor->aux) {
if (sor->soc->supports_hdmi) { if (sor->soc->supports_hdmi) {
connector = DRM_MODE_CONNECTOR_HDMIA; connector = DRM_MODE_CONNECTOR_HDMIA;
encoder = DRM_MODE_ENCODER_TMDS; encoder = DRM_MODE_ENCODER_TMDS;
...@@ -2199,8 +2184,8 @@ static int tegra_sor_init(struct host1x_client *client) ...@@ -2199,8 +2184,8 @@ static int tegra_sor_init(struct host1x_client *client)
dev_err(sor->dev, "debugfs setup failed: %d\n", err); dev_err(sor->dev, "debugfs setup failed: %d\n", err);
} }
if (sor->dpaux) { if (sor->aux) {
err = tegra_dpaux_attach(sor->dpaux, &sor->output); err = drm_dp_aux_attach(sor->aux, &sor->output);
if (err < 0) { if (err < 0) {
dev_err(sor->dev, "failed to attach DP: %d\n", err); dev_err(sor->dev, "failed to attach DP: %d\n", err);
return err; return err;
...@@ -2249,8 +2234,8 @@ static int tegra_sor_exit(struct host1x_client *client) ...@@ -2249,8 +2234,8 @@ static int tegra_sor_exit(struct host1x_client *client)
tegra_output_exit(&sor->output); tegra_output_exit(&sor->output);
if (sor->dpaux) { if (sor->aux) {
err = tegra_dpaux_detach(sor->dpaux); err = drm_dp_aux_detach(sor->aux);
if (err < 0) { if (err < 0) {
dev_err(sor->dev, "failed to detach DP: %d\n", err); dev_err(sor->dev, "failed to detach DP: %d\n", err);
return err; return err;
...@@ -2399,14 +2384,14 @@ static int tegra_sor_probe(struct platform_device *pdev) ...@@ -2399,14 +2384,14 @@ static int tegra_sor_probe(struct platform_device *pdev)
np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0); np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);
if (np) { 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); of_node_put(np);
if (!sor->dpaux) if (!sor->aux)
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
if (!sor->dpaux) { if (!sor->aux) {
if (sor->soc->supports_hdmi) { if (sor->soc->supports_hdmi) {
sor->ops = &tegra_sor_hdmi_ops; sor->ops = &tegra_sor_hdmi_ops;
} else if (sor->soc->supports_lvds) { } else if (sor->soc->supports_lvds) {
......
...@@ -10,6 +10,7 @@ host1x-y = \ ...@@ -10,6 +10,7 @@ host1x-y = \
mipi.o \ mipi.o \
hw/host1x01.o \ hw/host1x01.o \
hw/host1x02.o \ hw/host1x02.o \
hw/host1x04.o hw/host1x04.o \
hw/host1x05.o
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
...@@ -538,6 +538,8 @@ EXPORT_SYMBOL(host1x_driver_register_full); ...@@ -538,6 +538,8 @@ EXPORT_SYMBOL(host1x_driver_register_full);
void host1x_driver_unregister(struct host1x_driver *driver) void host1x_driver_unregister(struct host1x_driver *driver)
{ {
driver_unregister(&driver->driver);
mutex_lock(&drivers_lock); mutex_lock(&drivers_lock);
list_del_init(&driver->list); list_del_init(&driver->list);
mutex_unlock(&drivers_lock); mutex_unlock(&drivers_lock);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "hw/host1x01.h" #include "hw/host1x01.h"
#include "hw/host1x02.h" #include "hw/host1x02.h"
#include "hw/host1x04.h" #include "hw/host1x04.h"
#include "hw/host1x05.h"
void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r) void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
{ {
...@@ -87,7 +88,17 @@ static const struct host1x_info host1x04_info = { ...@@ -87,7 +88,17 @@ static const struct host1x_info host1x04_info = {
.sync_offset = 0x2100, .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[] = { static struct of_device_id host1x_of_match[] = {
{ .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
{ .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, }, { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, },
{ .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, }, { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
{ .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, }, { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
...@@ -212,6 +223,11 @@ static struct platform_driver tegra_host1x_driver = { ...@@ -212,6 +223,11 @@ static struct platform_driver tegra_host1x_driver = {
.remove = host1x_remove, .remove = host1x_remove,
}; };
static struct platform_driver * const drivers[] = {
&tegra_host1x_driver,
&tegra_mipi_driver,
};
static int __init tegra_host1x_init(void) static int __init tegra_host1x_init(void)
{ {
int err; int err;
...@@ -220,28 +236,17 @@ static int __init tegra_host1x_init(void) ...@@ -220,28 +236,17 @@ static int __init tegra_host1x_init(void)
if (err < 0) if (err < 0)
return err; return err;
err = platform_driver_register(&tegra_host1x_driver); err = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
if (err < 0)
goto unregister_bus;
err = platform_driver_register(&tegra_mipi_driver);
if (err < 0) if (err < 0)
goto unregister_host1x; bus_unregister(&host1x_bus_type);
return 0;
unregister_host1x:
platform_driver_unregister(&tegra_host1x_driver);
unregister_bus:
bus_unregister(&host1x_bus_type);
return err; return err;
} }
module_init(tegra_host1x_init); module_init(tegra_host1x_init);
static void __exit tegra_host1x_exit(void) static void __exit tegra_host1x_exit(void)
{ {
platform_driver_unregister(&tegra_mipi_driver); platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
platform_driver_unregister(&tegra_host1x_driver);
bus_unregister(&host1x_bus_type); bus_unregister(&host1x_bus_type);
} }
module_exit(tegra_host1x_exit); module_exit(tegra_host1x_exit);
......
/*
* 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;
}
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment